Ich versuche cd
, einen von einem anderen Befehl an ihn umgeleiteten Verzeichnisnamen zu akzeptieren. Keine dieser Methoden funktioniert:
$ echo $HOME | cd
$ echo $HOME | xargs cd
Das funktioniert:
$ cd $(echo $HOME)
Warum funktioniert der erste Befehlssatz nicht, und gibt es andere, die auf diese Weise ebenfalls fehlschlagen?
shell
io-redirection
pipe
cd-command
Jhonathan
quelle
quelle
Antworten:
cd
ist kein externer Befehl - es ist eine in die Shell eingebaute Funktion. Es wird im Kontext der aktuellen Shell ausgeführt und nicht wie externe Befehle in einem Fork / Exec-Kontext als separater Prozess.Ihr drittes Beispiel funktioniert, da die Shell die Variable und die Befehlssubstitution vor dem Aufrufen des
cd
eingebauten Befehls erweitert, sodass diesercd
den Wert von${HOME}
als Argument erhält .POSIX - Systemen zu tun haben ein binäres
cd
- auf meinem FreeBSD - Maschine, es ist an/usr/bin/cd
, aber es tut nicht das, was Sie denken. Das Aufrufen der Binärdateicd
bewirkt, dass die Shell die Binärdatei aufteilt / ausführt, wodurch ihr Arbeitsverzeichnis in den von Ihnen übergebenen Namen geändert wird. Sobald dies jedoch der Fall ist, wird die Binärdatei beendet und der Forked / Exec'd-Prozess verschwindet. Sie kehren zu Ihrer Shell zurück, die sich noch in dem Verzeichnis befindet, in dem sie sich vor dem Start befand.quelle
cd
Befehl gut ist?cd
liest keine Standardeingabe. Deshalb funktioniert Ihr erstes Beispiel nicht.xargs
benötigt einen Befehlsnamen, dh einen Namen einer unabhängigen ausführbaren Datei.cd
muss ein in die Shell integrierter Befehl sein und hat keine Auswirkung (außer zu überprüfen, ob Sie in dieses Verzeichnis wechseln können und welche möglichen Nebenwirkungen dies für automountbare Verzeichnisse haben kann), wenn es sich um eine ausführbare Datei handelt. Deshalb funktioniert Ihr zweites Beispiel nicht.quelle
Neben der bestehenden guten Antwort ist auch zu erwähnen, dass eine Pipe einen neuen Prozess auslöst, der über ein eigenes Arbeitsverzeichnis verfügt. Daher funktioniert dies nicht:
Daher befinden Sie sich nicht mehr im Ordner /, nachdem die Shell von diesem Befehl zurückgekehrt ist.
quelle
a | b
, auch wenna
undb
sind gebautet mindestens ein dann nicht in dem Shell - Prozess laufen, aber es gibt keine Garantie , die das es ist. Zum Beispiel in AT & Tksh
,zsh
oderbash -O lastpipe
,b
wird in dem aktuellen Shell - Prozess ausgeführt, so dass Ihr Code , den Sie / es dauern würde.Zusätzlich zu den bereits gegebenen richtigen Antworten: Wenn Sie bash ausführen und herausfinden möchten , was ein "Befehl" wie cd ist , können Sie type verwenden
oder warum nicht:
während zum beispiel gnu time normalerweise schon in ihrer lieblingsdistribution enthalten ist:
Okey okey du hast die Idee, was zum Teufel ist dann Typ?
Hier ist ein Bash-Handbuch-Snippet:
quelle
Wie andere gesagt haben, wird es nicht funktionieren, da
cd
es sich um einen in die Shell eingebauten Befehl handelt, kein externes Programm, so dass es keine Standardeingabe gibt, in die Sie irgendetwas umleiten können.Aber selbst wenn es funktionieren würde, würde es nicht das tun, was Sie wünschen: Eine Pipe erzeugt einen neuen Prozess und leitet die Standardausgabe des ersten Befehls in die Standardeingabe des zweiten um, sodass nur der neue Prozess seine aktuelle Arbeitsweise ändert Verzeichnis; Dies konnte den ersten Prozess in keiner Weise beeinflussen.
quelle
read
ist normalerweise (immer?) eine eingebaute Shell. Es ist wahr, dasscd
stdin ignoriert, aber das liegt nicht daran, dass es ein Builtin ist.Eine weitere Option sind Backticks, bei denen die Standardausgabe eines Befehls als Befehlszeilenargument eines zweiten Befehls verwendet wird. Sie sind portabler als
$(...)
. Beispielsweise:oder allgemeiner;
Beachten Sie, dass die Verwendung von Backticks von der Shell abhängt, die den Befehl ausführt und die Ausgabe in der Befehlszeile ersetzt. Die meisten Muscheln unterstützen es.
quelle
$(...)
funktioniert. Ich halte es nicht für ratsam, Backticks zu empfehlen, da diese viel komplizierter und fehleranfälliger sind. (Siehe §3.5.4 "Befehlsersetzung" im Bash-Referenzhandbuch .)$(...)
auf einem System unterstützt werden, auf einem anderen jedoch nicht?$(…)
. Systeme ohne POSIX-Shell (dh mit einer echten Bourne-Shell) wären extrem alt. Sogar Systeme, bei denen/bin/sh
es sich um eine Bourne-Shell handelt und Sie einen anderen Pfad benötigen/usr/xpg4/bin/sh
, um eine POSIX-Shell zu erhalten, sind heutzutage selten. Das Empfehlen von Backticks für alle, die alte Unix-Boxen nicht professionell verwalten, ist ein Nachteil.