Verwenden von xargs, um in ein Verzeichnis zu wechseln

27

Fühle mich jetzt wie ein Idiot. Warum geht das nicht?

echo "/some/directory/path" | xargs -n1 cd
Ian Lotinsky
quelle

Antworten:

21

Die Pipe führt xargs in einem Unterprozess aus, und xargs führt cd in einem Unterprozess aus. Änderungen in einem Unterprozess werden nicht an den übergeordneten Prozess weitergegeben.

Ignacio Vazquez-Abrams
quelle
Das macht durchaus Sinn. Vielen Dank, dass Sie einem Unix-Neuling geholfen haben.
Ian Lotinsky
3
Sie können den gewünschten Effekt erzielen, indem Sie Anführungszeichen verwenden: cd `echo "/some/directory/path" | cut -d\ -f1` (Beachten Sie, dass ich 'cut' hinzugefügt habe, um Leerzeichen aufzuteilen und das erste Element wie xargs zu greifen.)
Slartibartfast
5
Eigentlich xargskann nicht ausgeführt werden, cdda es aus der Not einer Schale builtin und xargskann nur freistehende ausführbare Dateien ausführen. Was Sie gesagt haben, gilt jedoch für Unterprozesse.
Bis auf weiteres angehalten.
/ usr / bin / cd ist definitiv ein frei stehender dokumentierter Unix-Befehl, zumindest unter Solaris.
Juli
Verwenden von @Slartibartfast für automatisch generierte Pfade: cd `port file libcudd | sed -e 's/\/Portfile//'` (normalerweise lange, die Sie nicht manuell verarbeiten möchten, wie dieser MacPorts Portfile-Speicherort).
Ioannis Filippidis
23

Der Befehl cdist ein integrierter Befehl, da die Informationen zum aktuellen Verzeichnis an einen Prozess gebunden sind und nur der integrierte Shell- Befehl das aktuelle Verzeichnis der ausgeführten Shell ändern kann.

Es gibt zwei Probleme mit Ihrem Code:

  1. xargskann nicht ausgeführt werden, cdda cdes sich um einen integrierten Befehl handelt und xargsnur ausführbare Dateien ausgeführt werden können.
  2. Selbst wenn Sie cdeinen Unterprozess ausführen , der von aufgerufen xargswird, hat dies keine Auswirkungen auf den übergeordneten Prozess, wie oben erläutert.

Die Lösung besteht darin, eine Sub-Shell cdauszuführen, in der Sie Befehle im neuen aktuellen Verzeichnis ausführen können.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
parpa
quelle
ls | xargs ...In diesem Beispiel ist das nicht sinnvoll . Es sollte den Wert für übergeben werden $0, wieecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky
IMO wäre eine bessere Lösung: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Roman M