Komfortables cd
Der Verzeichniswechsel mit dem cd-Kommando gehört zu den häufigsten Befehlen der täglichen Shell-Arbeit. Oft erreicht man sein Zielverzeichnis erst nach einer endlosen cd-Kaskade durch die einzelnen Unterverzeichnisse. Zwar hilft dabei die Tab-Taste, aber es geht noch komfortabler.
Die unten aufgelistete Bash-Funktion fcd (find change directory) ermöglicht es, ein beliebiges Verzeichnis lediglich unter Angabe des letzten Unterverzeichnisses zu erreichen. Da es im gesamten Verzeichnisbaum erwartungsgemäß mehrere gleichlautende Unterverzeichnisse gibt, bietet die Funktion eine interaktive Mehrfachauswahl.
Das Kommando sucht zweistufig: Zunächst nach exakten Treffern und falls dies zu keinem Ergebnis führt, nach dem Suchbegriff als Substring im Verzeichnisnamen. Die Suche ist aufgrund eines zuvor erzeugten Caches ausreichend performant.
Beispiele:
1. ein exakter Treffer
user@rechner:~> fcd rc3.d user@rechner:/etc/rc3.d>
2. mehrere exakte Treffer
user@rechner:/etc/rc3.d> fcd linux 1) /user/alsa/alsa-driver-1.0.17/include/linux 2) /usr/include/linux 3) /usr/lib/gcc/i486-linux-gnu/4.1/include/linux 4) /usr/lib/gcc/i486-linux-gnu/4.3/include-fixed/linux 5) /usr/lib/perl/5.10.0/linux 6) /usr/share/zsh/functions/Completion/Linux 7) /usr/src/linux-2.6.14.4/include/linux 8) /usr/src/linux-headers-2.6.26-2-686/include/linux 9) /usr/src/linux-headers-2.6.26-2-common/include/linux 10) /usr/src/modules/alsa-driver/include/linux #? 2 user@rechner:/usr/include/linux>
3. ein Substring-Treffer
user@rechner:/usr/include/linux> fcd voice user@rechner:/var/spool/asterisk/voicemail>
4. mehrere Substring-Treffer
user@rechner:/var/spool/asterisk/voicemail> fcd altern 1) /etc/alternatives 2) /var/lib/dpkg/alternatives #? 1 user@rechner:/etc/alternatives>
Und so funktioniert es:
Zunächst wird quasi als Cache eine Liste aller Verzeichnisse eines Rechners erstellt. Es bietet sich an, dies als regelmäßigen Cron-Job mit dem Namen »dirlocate« einzurichten:
#!/bin/bash find $HOME -type d 2> /dev/null | sort > /var/tmp/dirs
Natürlich kann man dieses find-Kommando nach eigenen Wünschen optimieren. Es bietet sich z.B. an, ein Backup-Verzeichnis auszunehmen:
find $HOME -type d -path backup -prune -o -print 2> /dev/null | sort > /var/tmp/dirs
Hinweis: Wir beschränken das find auf das Home-Verzeichnis, weil die Funktion keine ausreichende Sicherheit für die globale Benutzung oder Mehrbenutzersysteme hat.
Die eigentliche Bash-Funktion sieht dann wie folgt aus:
function fcd () { dirdat="/var/tmp/dirs" suche=$1 if [ -n "$suche" ]; then # Internal Field Separator wg. moegl. Leerzeichen in Verz.namen umbiegen IFSOLD=$IFS IFS=$(echo -en "\n\t"); # erste Suche nach exakten Treffern dirs=$(grep -i -E \/$suche$ $dirdat) set -f; set -- $dirs; set +f; anz=$# # grosszuegiger suchen, wenn kein Ergebnis if [ $anz -eq 0 ]; then dirs=$(grep -i -E \/.*$suche[^/]*$ $dirdat) set -f; set -- $dirs; set +f; anz=$# fi case $anz in 0) ;; 1) cd $dirs ;; *) select v in $dirs; do cd $v; break; done ;; esac IFS=$IFSOLD fi }