[{"data":1,"prerenderedAt":661},["ShallowReactive",2],{"\u002Fblog\u002F2026-09-30-favorite-command-history":3},{"id":4,"title":5,"body":6,"category":645,"coverImage":646,"date":647,"description":12,"extension":648,"meta":649,"navigation":225,"path":650,"seo":651,"status":652,"stem":653,"tags":654,"__hash__":660},"blog\u002Fblog\u002F2026-09-30-favorite-command-history.md","Wie du nie wieder einen nützlichen Befehl vergisst",{"type":7,"value":8,"toc":637},"minimark",[9,13,16,21,29,56,72,103,113,129,133,140,169,184,188,197,404,426,430,433,467,474,478,481,490,602,616,620,633],[10,11,12],"p",{},"Ist es dir auch schonmal so gegangen wie mir? Du hattest irgendwann in der\nVergangenheit ein ganz bestimmtes Problem und weißt noch, dass du es damals\nmithilfe eines ganz bestimmten Shell-Befehls lösen konntest? Möglicherweise ein\nBefehl, den du dir über einen längeren Trial-and-Error-Prozess mühsam\nerarbeitet hast? Du durchstöberst mittels Ctrl + r deine Command History, aber\nmusst schließlich feststellen, dass der Befehl schon zu weit zurückliegt (über\ndas History-Limit) oder du gar dein Terminal vor kurzem neu aufsetzen musstest\nund damit alle deine alten Befehle futsch sind.",[10,14,15],{},"Damit ist jetzt Schluss. Ich möchte dir in diesem Beitrag eine Möglichkeit\nzeigen, wie du nie wieder einen nützlichen Befehl verlierst.",[17,18,20],"h2",{"id":19},"fuzzy-finder","Fuzzy Finder",[10,22,23,24,28],{},"Doch bevor wir beginnen, empfehle ich dir zunächst, einen sogenannten Fuzzy\nFinder für die Befehlszeile zu installieren. Er wird dir die Suche nach deinen\nvergangen Befehlen unheimlich erleichtern, vor allem wenn du dich nur noch\nunscharf (",[25,26,27],"em",{},"fuzzy",") an den gesuchten Befehl erinnerst.",[10,30,31,32,36,37,39,40,43,44,47,48,55],{},"Es gibt unzählige solcher Command Line Fuzzy Finder. Ich selbst nutze ein Tool\nnamens ",[33,34,35],"code",{},"fzf"," und kann dieses nur wärmstens empfehlen. In den meisten\nLinux-Distributionen ist ",[33,38,35],{}," über den jeweiligen Paketmanager (",[33,41,42],{},"apt",", ",[33,45,46],{},"dnf",",\netc.) verfügbar. Um es auf Windows\u002FMac zum Laufen zu bekommen oder die Binary\nselber zu bauen, verweise ich an der Stelle auf die ",[49,50,54],"a",{"href":51,"rel":52},"https:\u002F\u002Fgithub.com\u002Fjunegunn\u002Ffzf#installation",[53],"nofollow","umfangreiche\nInstallationsanleitung",".",[10,57,58,59,61,62,67,68,71],{},"Sobald ",[33,60,35],{}," erfolgreich installiert wurde, gilt es nur noch, das Tool in die\nShell zu integrieren. Im Falle der ",[49,63,66],{"href":64,"rel":65},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fbash\u002F",[53],"GNU\nBash"," muss einfach nur folgende Zeile an\nden Inhalt deiner ",[33,69,70],{},"~\u002F.bashrc"," angefügt werden:",[73,74,79],"pre",{"className":75,"code":76,"language":77,"meta":78,"style":78},"language-bash shiki shiki-themes github-light github-dark","eval \"$(fzf --bash)\"\n","bash","",[33,80,81],{"__ignoreMap":78},[82,83,86,90,94,97,100],"span",{"class":84,"line":85},"line",1,[82,87,89],{"class":88},"sj4cs","eval",[82,91,93],{"class":92},"sZZnC"," \"$(",[82,95,35],{"class":96},"sScJk",[82,98,99],{"class":88}," --bash",[82,101,102],{"class":92},")\"\n",[10,104,105,106,109,110,112],{},"Nachdem du deine Shell neu geladen hast (z. B. über ",[33,107,108],{},"source ~\u002F.bashrc",") sollte\n",[33,111,35],{}," bereits funktionieren. Prüfe es, indem du Ctrl + r drückst, während sich\nder Cursor in der Befehlszeile befindet. Es sollte in etwa so aussehen:",[114,115,116,124],"figure",{},[10,117,118],{},[119,120],"img",{"alt":121,"src":122,"title":123},"netrw in Action","\u002Fimg\u002Fblog\u002Ffzf-initial.jpg","fzf in Action",[125,126,127],"figcaption",{},[10,128,123],{},[17,130,132],{"id":131},"favoriten-speichern","Favoriten speichern",[10,134,135,136,139],{},"Jetzt legen wir eine neue Datei im Home-Verzeichnis an. Diese soll als eine Art\nLesezeichen-Speicher fungieren. Ich nenne sie sinngemäß ",[33,137,138],{},"~\u002F.bash_favorites",".\nImmer wenn dir ein Befehl begegnet, von dem du denkst, dass er in Zukunft\nnochmal nützlich sein könnte, schreibst du ihn in diese Datei. Das muss nicht\nimmer sofort sein. Oft erkennt man erst ein paar Tage später, dass ein\nbestimmter Befehl nützlich war. Sofern deine History groß genug eingestellt\nist, solltest du den Befehl schnell finden. Zum Testen schreiben wir erstmal\nfolgendes in die Datei:",[73,141,143],{"className":75,"code":142,"language":77,"meta":78,"style":78},"# Rekursiv nach Warnungen und Fehlern suchen und dabei Git-Verzeichnisse ignorieren\ngrep -RInE --exclude-dir=.git 'ERROR|WARN' .\n",[33,144,145,151],{"__ignoreMap":78},[82,146,147],{"class":84,"line":85},[82,148,150],{"class":149},"sJ8bj","# Rekursiv nach Warnungen und Fehlern suchen und dabei Git-Verzeichnisse ignorieren\n",[82,152,154,157,160,163,166],{"class":84,"line":153},2,[82,155,156],{"class":96},"grep",[82,158,159],{"class":88}," -RInE",[82,161,162],{"class":88}," --exclude-dir=.git",[82,164,165],{"class":92}," 'ERROR|WARN'",[82,167,168],{"class":92}," .\n",[10,170,171,172,175,176,179,180,183],{},"Es empfiehlt sich, oberhalb des Befehls einen kurzen Kommentar zu schreiben,\nwelcher den Befehl beschreibt. Bei einem Befehl wie diesem ist das besonders\nhilfreich: Er durchsucht das aktuelle Verzeichnis rekursiv nach ",[33,173,174],{},"ERROR"," oder\n",[33,177,178],{},"WARN",", ignoriert dabei ",[33,181,182],{},".git","-Verzeichnisse und zeigt zusätzlich Dateinamen\nund Zeilennummern an. So erschließt sich auch später noch, welche Aufgabe der\nBefehl löst und warum die einzelnen Optionen darin stehen.",[17,185,187],{"id":186},"history-und-favoriten-vereinen","History und Favoriten vereinen",[10,189,190,191,193,194,196],{},"Nun ist es an der Zeit, die von dir kurierten, nützlichen Befehle schnell\nerreichbar zu machen. Hierfür müssen wir folgendes unterhalb des ersten\n",[33,192,89],{},"-Statements in der ",[33,195,70],{}," einfügen:",[73,198,200],{"className":75,"code":199,"language":77,"meta":78,"style":78},"__fzf_history_with_favorites__() {\n    local selected\n\n    selected=$(\n        {\n            history | tac | sed -E 's\u002F^ +[0-9]+ +\u002F\u002F'\n            grep -vE '^[[:space:]]*(#|$)' \"$HOME\u002F.bash_favorites\" 2>\u002Fdev\u002Fnull\n        } |\n            awk '!seen[$0]++' |\n            fzf --no-preview --query \"$READLINE_LINE\"\n    ) || return\n\n    READLINE_LINE=$selected\n    READLINE_POINT=${#READLINE_LINE}\n}\n\nbind -x '\"\\C-r\": __fzf_history_with_favorites__'\n",[33,201,202,211,220,227,239,245,268,295,304,316,336,348,353,364,381,387,392],{"__ignoreMap":78},[82,203,204,207],{"class":84,"line":85},[82,205,206],{"class":96},"__fzf_history_with_favorites__",[82,208,210],{"class":209},"sVt8B","() {\n",[82,212,213,217],{"class":84,"line":153},[82,214,216],{"class":215},"szBVR","    local",[82,218,219],{"class":209}," selected\n",[82,221,223],{"class":84,"line":222},3,[82,224,226],{"emptyLinePlaceholder":225},true,"\n",[82,228,230,233,236],{"class":84,"line":229},4,[82,231,232],{"class":209},"    selected",[82,234,235],{"class":215},"=",[82,237,238],{"class":209},"$(\n",[82,240,242],{"class":84,"line":241},5,[82,243,244],{"class":209},"        {\n",[82,246,248,251,254,257,259,262,265],{"class":84,"line":247},6,[82,249,250],{"class":88},"            history",[82,252,253],{"class":215}," |",[82,255,256],{"class":96}," tac",[82,258,253],{"class":215},[82,260,261],{"class":96}," sed",[82,263,264],{"class":88}," -E",[82,266,267],{"class":92}," 's\u002F^ +[0-9]+ +\u002F\u002F'\n",[82,269,271,274,277,280,283,286,289,292],{"class":84,"line":270},7,[82,272,273],{"class":96},"            grep",[82,275,276],{"class":88}," -vE",[82,278,279],{"class":92}," '^[[:space:]]*(#|$)'",[82,281,282],{"class":92}," \"",[82,284,285],{"class":209},"$HOME",[82,287,288],{"class":92},"\u002F.bash_favorites\"",[82,290,291],{"class":215}," 2>",[82,293,294],{"class":92},"\u002Fdev\u002Fnull\n",[82,296,298,301],{"class":84,"line":297},8,[82,299,300],{"class":209},"        } ",[82,302,303],{"class":215},"|\n",[82,305,307,310,313],{"class":84,"line":306},9,[82,308,309],{"class":96},"            awk",[82,311,312],{"class":92}," '!seen[$0]++'",[82,314,315],{"class":215}," |\n",[82,317,319,322,325,328,330,333],{"class":84,"line":318},10,[82,320,321],{"class":96},"            fzf",[82,323,324],{"class":88}," --no-preview",[82,326,327],{"class":88}," --query",[82,329,282],{"class":92},[82,331,332],{"class":209},"$READLINE_LINE",[82,334,335],{"class":92},"\"\n",[82,337,339,342,345],{"class":84,"line":338},11,[82,340,341],{"class":209},"    ) ",[82,343,344],{"class":215},"||",[82,346,347],{"class":215}," return\n",[82,349,351],{"class":84,"line":350},12,[82,352,226],{"emptyLinePlaceholder":225},[82,354,356,359,361],{"class":84,"line":355},13,[82,357,358],{"class":209},"    READLINE_LINE",[82,360,235],{"class":215},[82,362,363],{"class":209},"$selected\n",[82,365,367,370,372,375,378],{"class":84,"line":366},14,[82,368,369],{"class":209},"    READLINE_POINT",[82,371,235],{"class":215},[82,373,374],{"class":209},"${",[82,376,377],{"class":215},"#",[82,379,380],{"class":209},"READLINE_LINE}\n",[82,382,384],{"class":84,"line":383},15,[82,385,386],{"class":209},"}\n",[82,388,390],{"class":84,"line":389},16,[82,391,226],{"emptyLinePlaceholder":225},[82,393,395,398,401],{"class":84,"line":394},17,[82,396,397],{"class":96},"bind",[82,399,400],{"class":88}," -x",[82,402,403],{"class":92}," '\"\\C-r\": __fzf_history_with_favorites__'\n",[10,405,406,407,409,410,413,414,416,417,419,420,422,423,425],{},"Die Funktion ",[33,408,206],{}," führt deine ",[33,411,412],{},"history"," mit deinen\nEinträgen aus ",[33,415,138],{}," zusammen. Dabei werden leere Zeilen und\nKommentare aus der Favoriten-Datei entfernt sowie doppelte Einträge aus beiden\nQuellen zusammengeführt. Anschließend wird die Liste an ",[33,418,35],{}," übergeben. Über\ndie Tastenkombination Ctrl + r kannst du ab sofort deine History inklusive\nFavoriten per Fuzzy Finder durchsuchen (Sourcen nicht vergessen). Du solltest\njetzt den ",[33,421,156],{},"-Befehl aus unserem Beispiel in den ",[33,424,35],{},"-Vorschlägen\nwiederfinden.",[17,427,429],{"id":428},"history-richtig-einstellen","History richtig einstellen",[10,431,432],{},"Bevor ich es vergesse: prüfe mal, wie deine History eingestellt ist. Oft wird\nsie standardmäßig auf 1000 oder gar 500 Einträge begrenzt. In den Anfängen von\nLinux war Speicher oft begrenzt, weshalb man die Größe der Command History\nebenfalls möglichst gering gehalten hat. Heutzutage ist Speicher kein\nlimitierender Faktor mehr. Ich habe meine History wie folgt eingestellt:",[73,434,436],{"className":75,"code":435,"language":77,"meta":78,"style":78},"HISTCONTROL=erasedups\nHISTFILESIZE=5000\nHISTSIZE=5000\n",[33,437,438,448,458],{"__ignoreMap":78},[82,439,440,443,445],{"class":84,"line":85},[82,441,442],{"class":209},"HISTCONTROL",[82,444,235],{"class":215},[82,446,447],{"class":92},"erasedups\n",[82,449,450,453,455],{"class":84,"line":153},[82,451,452],{"class":209},"HISTFILESIZE",[82,454,235],{"class":215},[82,456,457],{"class":92},"5000\n",[82,459,460,463,465],{"class":84,"line":222},[82,461,462],{"class":209},"HISTSIZE",[82,464,235],{"class":215},[82,466,457],{"class":92},[10,468,469,470,473],{},"Die Einstellung ",[33,471,472],{},"erasedups"," sorgt dafür, dass Befehle, die bereits in deiner\nHistory enthalten sind, gar nicht erst gespeichert werden.",[17,475,477],{"id":476},"über-git-repo-persistieren","Über Git-Repo persistieren",[10,479,480],{},"Vielleicht fragst du dich jetzt: Wieso erhöhen wir das History-Limit nicht\neinfach auf eine Million? Nun ja, der Hauptgrund ist, dass deine History höchst\nfragil ist. Wenn dein Betriebssystem auf einmal schlapp macht und all deine\nDateien unzugänglich oder gelöscht sind, ist auch deine History meist im Eimer.\nBetrachte die Command History eher wie deinen Suchverlauf im Browser. Dieser\nwird ja hin und wieder auch mal geleert.",[10,482,483,484,489],{},"Damit dir dasselbe nicht mit deinen Befehlsfavoriten passiert, kannst du sie\nzunächst mittels eines Git-Repositorys versionieren und über Tools wie ",[49,485,488],{"href":486,"rel":487},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fstow\u002F",[53],"GNU\nStow"," symlinken. Das funktioniert dann z.\nB. so:",[73,491,493],{"className":75,"code":492,"language":77,"meta":78,"style":78},"# Aufsetzen des Git Repos\nmkdir -p ~\u002Fpersonal_setup\u002Fbash_favorites\ncd ~\u002Fpersonal_setup\ngit init -b main\n\n# Verschieben der bereits erstellten Favoriten-Datei in das richtige Verzeichnis\nmv ~\u002F.bash_favorites ~\u002Fpersonal_setup\u002Fbash_favorites\u002F\n\n# Favoriten versionieren\ngit add bash_favorites\u002F.bash_favorites\ngit commit -m \"Add bash favorites\"\n\n# Jetzt werden die Favoriten in dein Home-Verzeichnis gesymlinked\nstow bash_favorites\n",[33,494,495,500,511,519,533,537,542,553,557,562,572,585,589,594],{"__ignoreMap":78},[82,496,497],{"class":84,"line":85},[82,498,499],{"class":149},"# Aufsetzen des Git Repos\n",[82,501,502,505,508],{"class":84,"line":153},[82,503,504],{"class":96},"mkdir",[82,506,507],{"class":88}," -p",[82,509,510],{"class":92}," ~\u002Fpersonal_setup\u002Fbash_favorites\n",[82,512,513,516],{"class":84,"line":222},[82,514,515],{"class":88},"cd",[82,517,518],{"class":92}," ~\u002Fpersonal_setup\n",[82,520,521,524,527,530],{"class":84,"line":229},[82,522,523],{"class":96},"git",[82,525,526],{"class":92}," init",[82,528,529],{"class":88}," -b",[82,531,532],{"class":92}," main\n",[82,534,535],{"class":84,"line":241},[82,536,226],{"emptyLinePlaceholder":225},[82,538,539],{"class":84,"line":247},[82,540,541],{"class":149},"# Verschieben der bereits erstellten Favoriten-Datei in das richtige Verzeichnis\n",[82,543,544,547,550],{"class":84,"line":270},[82,545,546],{"class":96},"mv",[82,548,549],{"class":92}," ~\u002F.bash_favorites",[82,551,552],{"class":92}," ~\u002Fpersonal_setup\u002Fbash_favorites\u002F\n",[82,554,555],{"class":84,"line":297},[82,556,226],{"emptyLinePlaceholder":225},[82,558,559],{"class":84,"line":306},[82,560,561],{"class":149},"# Favoriten versionieren\n",[82,563,564,566,569],{"class":84,"line":318},[82,565,523],{"class":96},[82,567,568],{"class":92}," add",[82,570,571],{"class":92}," bash_favorites\u002F.bash_favorites\n",[82,573,574,576,579,582],{"class":84,"line":338},[82,575,523],{"class":96},[82,577,578],{"class":92}," commit",[82,580,581],{"class":88}," -m",[82,583,584],{"class":92}," \"Add bash favorites\"\n",[82,586,587],{"class":84,"line":350},[82,588,226],{"emptyLinePlaceholder":225},[82,590,591],{"class":84,"line":355},[82,592,593],{"class":149},"# Jetzt werden die Favoriten in dein Home-Verzeichnis gesymlinked\n",[82,595,596,599],{"class":84,"line":366},[82,597,598],{"class":96},"stow",[82,600,601],{"class":92}," bash_favorites\n",[10,603,604,605,608,609,612,613,615],{},"Anschließend kannst du das Repo über eine Git-Hosting-Plattform deiner Wahl\npersistieren (zum Beispiel mit ",[33,606,607],{},"git remote add origin ..."," und ",[33,610,611],{},"git push -u origin main","). Je nach dem, wie sensibel die Befehle in deiner\n",[33,614,138],{}," sind, solltest du ein privates Repository verwenden: Auch\nShell-Befehle können Passwörter, Tokens oder andere vertrauliche Informationen\nenthalten.",[17,617,619],{"id":618},"tldr","tl;dr",[10,621,622,623,625,626,628,629,632],{},"Mit ",[33,624,35],{}," wird deine Shell-History zu einer komfortablen, durchsuchbaren\nBefehlssammlung. Besonders hilfreiche Befehle kannst du zusätzlich mit kurzen\nKommentaren in ",[33,627,138],{}," festhalten und gemeinsam mit deiner History\nüber ",[33,630,631],{},"Ctrl + r"," wiederfinden. Ein großzügiges History-Limit verhindert, dass\nBefehle zu schnell verschwinden, während ein Git-Repository deine Favoriten\nauch über einen Systemwechsel oder Datenverlust hinaus bewahrt. So entsteht mit\nwenig Aufwand ein persönliches, dauerhaft verfügbares Nachschlagewerk für die\nKommandozeile.",[634,635,636],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":78,"searchDepth":153,"depth":153,"links":638},[639,640,641,642,643,644],{"id":19,"depth":153,"text":20},{"id":131,"depth":153,"text":132},{"id":186,"depth":153,"text":187},{"id":428,"depth":153,"text":429},{"id":476,"depth":153,"text":477},{"id":618,"depth":153,"text":619},"Essay","\u002Fimg\u002Fblog\u002Ffzf-favorites.jpeg","2026-09-30","md",{},"\u002Fblog\u002F2026-09-30-favorite-command-history",{"title":5,"description":12},"published","blog\u002F2026-09-30-favorite-command-history",[77,655,656,657,658,659],"shell","software","produktivitaet","tools","mastery","WM6mPHeYguTFn9iF2xLn5VFCDcOWkcA6YyxJoHwtmO0",1790932822514]