Die Wahl des Titels Ihrer Frage ist etwas verwirrend.
pushd/ popd, eine cshvon bashund kopierte Funktion zsh, ist eine Möglichkeit, einen Stapel gespeicherter Verzeichnisse zu verwalten.
pushd /some/dir
Verschiebt das aktuelle Arbeitsverzeichnis auf einen Stapel und ändert dann das aktuelle Arbeitsverzeichnis (und druckt dann, /some/dirgefolgt vom Inhalt dieses Stapels (durch Leerzeichen getrennt).
popd
druckt den Inhalt des Stapels (wieder durch Leerzeichen getrennt) und wechselt dann zum obersten Element des Stapels und entfernt es vom Stapel.
(Beachten Sie auch, dass einige Verzeichnisse dort mit ihrer ~/xoder ihrer ~user/xNotation dargestellt werden).
Wenn der Stack derzeit /aund hat /b, ist das aktuelle Verzeichnis /hereund Sie führen:
pushd /tmp/whatever
popd
pushdwird gedruckt /tmp/whatever /here /a /bund popdausgegeben /here /a /b, nicht /tmp/whatever. Das ist unabhängig von der Verwendung der Befehlssubstitution oder nicht. popdkann nicht verwendet werden, um den Pfad des vorherigen Verzeichnisses abzurufen, und im Allgemeinen kann seine Ausgabe nicht nachbearbeitet werden (siehe das $dirstackoder $DIRSTACKArray einiger Shells für den Zugriff auf die Elemente dieses Verzeichnisstapels).
Vielleicht möchten Sie:
pushd "$(mktemp -d)" &&
popd &&
rmdir "$OLDPWD"
Oder
cd "$(mktemp -d)" &&
cd - &&
rmdir "$OLDPWD"
Allerdings würde ich verwenden:
tmpdir=$(mktemp -d) || exit
(
cd "$tmpdir" || exit # in a subshell
# do what you have to do in that tmpdir
)
rmdir "$tmpdir"
Auf jeden Fall pushd "$(mktemp -d)"läuft nicht pushdin einer Subshell. In diesem Fall konnte das Arbeitsverzeichnis nicht geändert werden. Das mktempläuft in einer Unterschale. Da es sich um einen separaten Befehl handelt, muss er in einem separaten Prozess ausgeführt werden. Es schreibt seine Ausgabe in eine Pipe und der Shell-Prozess liest sie am anderen Ende der Pipe.
ksh93 kann den separaten Prozess vermeiden, wenn der Befehl eingebaut ist, aber selbst dort handelt es sich immer noch um eine Subshell (eine andere Arbeitsumgebung), die dieses Mal emuliert wird, anstatt sich auf die separate Umgebung zu verlassen, die normalerweise durch Forking bereitgestellt wird. Zum Beispiel ist in ksh93, a=0; echo "$(a=1; echo test)"; echo "$a"keine Gabel beteiligt, sondern echo "$a"gibt immer noch aus 0.
Wenn Sie die Ausgabe von mktempin einer Variablen speichern möchten, während Sie sie gleichzeitig pushdmit übergeben zsh, können Sie Folgendes tun:
pushd ${tmpdir::="$(mktemp -d)"}
Mit anderen Bourne-ähnlichen Muscheln:
unset tmpdir
pushd "${tmpdir=$(mktemp -d)}"
Oder um die Ausgabe $(mktemp -d)mehrmals zu verwenden, ohne sie explizit in einer Variablen zu speichern, können Sie zshanonyme Funktionen verwenden:
(){pushd ${1?} && cd - && rmdir $1} "$(mktemp -d)"
trapHandler das Verzeichnis bereinigen, falls der Prozess durch ein Signal ausgelöst wird.