Ist es möglich, den in der Kommandozeile eingebauten "cd" -Befehl zu überschreiben?

22

Fast jedes Mal, wenn ich auf meinem Computer (in diesem Fall unter Mac OS X 10.6.7) eine CD in ein anderes Verzeichnis starte (was bash ist), gebe ich sofort 'ls' ein, um das Inhaltsverzeichnis zu erhalten in diesem Verzeichnis. Ich versuche, eine Möglichkeit zu finden, 'cd' zu überschreiben, damit es in das angeforderte Verzeichnis wechselt und mir die Liste auf einen Schlag anzeigt.

Mit der folgenden Zeile in meinem ~ / .bash_profile konnte ich die Grundfunktionalität erreichen, nach der ich suche

function cl() { cd "$@"; ls -l; }

Das funktioniert wie erwartet. In das gewünschte Verzeichnis wechseln und mir dann den Inhalt anzeigen. Wenn ich auf ein Problem stoße, wird versucht, "cd" selbst zu überschreiben, anstatt einen neuen "cl" -Befehl zu erstellen.

Die folgenden Dinge tun nicht Arbeit

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

Ich habe auch mehrere andere Iterationen ausprobiert, die nicht aufgelistet sind, und einen Alias ​​erstellt, der auf die funktionierende Funktion 'cl' verweist. Nichts davon hat funktioniert.

Was ich in der Dokumentation gelesen habe, handelt von der Tatsache, dass 'cd' nicht als externer Befehl ausgeführt werden kann (was meiner Meinung nach die Art ist, wie die Funktion es verwenden müsste).

Also kann ich momentan meinen "cl" -Befehl verwenden und bekommen, was ich will, aber die Frage ist / bleibt:

Gibt es eine Möglichkeit, das Verhalten von 'cd' zu überschreiben, damit es in das angeforderte Verzeichnis wechselt und anschließend etwas anderes unternimmt?

Alan W. Smith
quelle

Antworten:

30

Folgendes sollte funktionieren:

function cd() { builtin cd "$@" && ls -l; }

Da sich die Funktion in einer einzelnen Zeile befindet, müssen Sie sicherstellen, dass sie ;wie oben beschrieben beendet wird, damit sie ordnungsgemäß funktioniert.

Gaff
quelle
Funktioniert nicht für einen parameterlosen Aufruf.
Daniel Beck
3
@DanielBeck - zumindest auf meinem Mac OS X (10.6.7) funktioniert dies problemlos mit einem parameterlosen Aufruf. Das Verhalten ist, dass es in das Ausgangsverzeichnis wechselt und dann die Liste dieses Verzeichnisses ausführt. Effektives Duplizieren der Funktionalität einer alten CD mit der neuen Funktion, die am Ende hinzugefügt wurde.
Alan W. Smith
2
@Alan Stimmt, ich habe das getestet, indem ich den Code ad-hoc in die Shell geschrieben habe. Es scheint das Verhalten von cd ""(zu dem, was diese Antwort auswerten sollte, ist anders als cd "$@"mit leer $@. Entschuldigung für die Verwirrung.
Daniel Beck
@ DanielBeck - keine Sorgen.
Alan W. Smith
2
Hinweis: Ich ändere dies in die akzeptierte Antwort, da es sich um eine präzise Antwort auf die Frage handelt. Die von @RichHomolka ist großartig, um den Principal anzusprechen, aber genau diese kann in Ihre ~ / .bash_profile-Datei eingefügt werden.
Alan W. Smith
10

Ich glaube, Sie stoßen auf eine Schleife. Ihre cdFunktion ruft auf cd, das ist ... die Funktion.

Sie müssen wissen, bei builtinwelchem ​​Schlüsselwort die Befehlssuche die in Bash enthaltenen Funktionen wie cd und nicht Ihre Funktion verwendet

function cd
{
    builtin cd "$1"
    : do something else
}

Der Aufruf /usr/bin/cdfunktioniert auch dann nicht, wenn ein solcher Befehl vorhanden ist.

Was würde passieren:

  • Meine Bash-Shell befindet sich in dir /bash/dir.
  • Ich führe einen Befehl aus /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdgeht zu dir /dir/for/cd.
  • /usr/bin/cd Ausgänge.
  • Bash ist immer noch aktiv /bash/dir, da der untergeordnete Prozess /usr/bin/cdden übergeordneten nicht beeinflussen kann.

Aliase sind auch einfache Textsubstitutionen. Sie können niemals Parameter haben.

Reiche Homolka
quelle
Schlage ich vor builtin cd $@ && ls; da sollte der cdaufruf gelingen damit alles andere sinn macht. Denken Sie auch an Sonderfälle wie cd(kein Argument).
Daniel Beck
Randnotiz: Ich habe versucht, dies als akzeptierte Antwort zu markieren, aber es sagt mir, dass ich noch 6 Minuten warten muss, bevor ich das tun kann. Ich wusste nicht, dass eine Verzögerung eingebaut ist, bevor Sie das tun können.
Alan W. Smith
@Alan Eine andere, bessere Lösung könnte sich in einem sehr vernünftigen Zeitraum ergeben (dh in den wenigen Minuten, die Sie warten müssen). Ich denke, deshalb gibt es eine systembedingte Verzögerung: Sie sollten Qualität der Geschwindigkeit vorziehen. Es sollte keine allzu große Unannehmlichkeit sein.
Daniel Beck
Und wir haben einen Gewinner. Das funktioniert wie ein Champion. Per @DanielBeck habe ich && zu einer einzigen Zeile zusammengefasst: function cd {builtin cd "$ @" && ls -l; }
Alan W. Smith
@DanielBeck - Ja, darüber mache ich mir keine Sorgen. Nur noch nie bemerkt. Ich kann die Logik darin sehen, hat mich nur ein wenig überrascht.
Alan W. Smith
6

Ich empfehle, die CD nicht zu überschreiben, da einige andere Skripte die CD-Funktion hijacken, zum Beispiel rvm. Es wäre besser, stattdessen einen anderen Namen wie 'd' zu wählen und nicht den Typ 'builtin' in Ihrer Funktion anzugeben. Andernfalls würde der Hijacker nicht funktionieren. Ich benutze den folgenden Code:

function d() { cd "$@" && ls;} 
Wen
quelle
Ich dachte, das würde nicht funktionieren, laut Frage des OP.
user305964