Sie dürfen keinen Aliasnamen mit Leerzeichen haben. Um mit Aliases das zu tun, was Sie möchten, müssen Sie diese Eigenschaft nutzen:
Wenn der Wert des Alias, der das Wort ersetzt, in einem <Leerzeichen> endet, überprüft die Shell das nächste Befehlswort auf Alias-Ersetzung. Dieser Vorgang wird fortgesetzt, bis ein Wort gefunden wird, das kein gültiger Alias ist oder ein Aliaswert nicht mit einem <Leerzeichen> endet.
( source ), so cd
und fortlaufend ...
werden als Aliase aufgelöst.
Sie brauchen Aliase wie diese:
cd='cd ' ...='../..' ....='../../..' # and so on
Wenn Sie jedoch ein Verzeichnis mit dem Namen ls
und die Eingabe erhalten cd ls
, ls
neigen Sie auch dazu, einen Alias zu ersetzen. Wenn ls
ein Alias ist, wird dies fehlschlagen.
Pure Alias Ansatz ist daher falsch. Diese Funktion erfüllt (verwenden Sie es ohne die obigen Aliase):
cd() { if [ "$#" -eq 0 ]; then command cd elif [ "$(printf '%s' "$1" | wc -l)" -eq 0 ]; then command cd "$(printf '%s' "$1" | sed '/^\.\.\+$/ ')"; else command cd "$1" fi }
sed
holt das Argument an die Funktion und ändert es, wenn es aus zwei oder mehr Punkten besteht; Das Werkzeug entfernt den ersten Punkt und ersetzt jeden Punkt (der übrig bleibt) durch ../
.
Es gibt zusätzliche Logik:
[ "$#" -eq 0 ]
erlaubt die Sohle cd
(ohne Argumente) so zu arbeiten, wie sie sollte. [ "$(printf '%s' "$1" | wc -l)" -eq 0 ]
ist zu verhindern sed
mehrzeiligen Verzeichnisnamen (zB zu ändern, foo<newline>.....
die ist ein gültiger Name). Beachten Sie, dass bei normalen Namen (die keine Zeilenumbrüche enthalten) wc -l
Rückgaben enthalten 0
(nicht 1
, POSIX betrachtet eine "Zeile" nicht, ohne die Zeilenumbrüche zu beenden), daher testen wir es mit 0
.
Und es gibt eine Eigenart:
- Bei
s|..|.|
den ersten beiden Punkten handelt es sich nicht um wörtliche Punkte, sondern um reguläre Ausdrücke. Man kann sagen, dass es sein sollte, s|\.\.|.|
aber es /^\.\.\+$/
stellt sicher, dass es in der Zeile nur Punkte gibt. Gleiches gilt für den ersten Punkt s|.|../|g
.