Вибір назви вашого питання трохи заплутаний.
pushd/ popd, cshфункція, скопійована на bashта zsh, є способом управління стеком запам’ятованих каталогів.
pushd /some/dir
висуває поточний робочий каталог на стек, а потім змінює поточний робочий каталог (а потім друкує, /some/dirа потім вміст цього стека (розділений пробілом).
popd
друкує вміст стеку (знову ж таки, розділений пробіл), а потім змінює верхній елемент стека і виводить його зі стека.
(також майте на увазі, що деякі каталоги будуть представлені там зі своїми позначеннями ~/xабо ~user/xпозначеннями).
Отже, якщо стек на даний момент є /aі /b, поточний каталог є /hereі ви працюєте:
pushd /tmp/whatever
popd
pushdбуде друкувати /tmp/whatever /here /a /bі popdвиводить /here /a /b, не /tmp/whatever. Це незалежно від використання підстановки команд чи ні. popdне може бути використаний для отримання шляху попереднього каталогу, і загалом його вихід не може бути оброблений після публікації (див. $dirstackабо $DIRSTACKмасив деяких оболонок, хоча для доступу до елементів цього стека каталогу)
Можливо, ви хочете:
pushd "$(mktemp -d)" &&
popd &&
rmdir "$OLDPWD"
Або
cd "$(mktemp -d)" &&
cd - &&
rmdir "$OLDPWD"
Хоча я б використав:
tmpdir=$(mktemp -d) || exit
(
cd "$tmpdir" || exit # in a subshell
# do what you have to do in that tmpdir
)
rmdir "$tmpdir"
У будь-якому випадку, pushd "$(mktemp -d)"він не працює pushdв передпласті. Якби це зробити, він не міг би змінити робочий каталог. Це те, mktempщо працює в нижній частині. Оскільки це окрема команда, вона повинна запускатися в окремому процесі. Він записує свій вихід на трубу, а процес оболонки зчитує його на іншому кінці труби.
ksh93 може уникнути окремого процесу, коли команда вбудована, але навіть там, як і раніше, це підзарядка (інше робоче середовище), яка цього разу емулюється, а не покладається на окреме середовище, яке зазвичай забезпечується розгортанням. Наприклад, у ksh93, a=0; echo "$(a=1; echo test)"; echo "$a"жодна форка не задіяна, але все одно echo "$a"виводиться 0.
Тут, якщо ви хочете зберегти висновок mktempзмінної у той самий час, коли ви передаєте її pushd, з zsh, ви можете зробити:
pushd ${tmpdir::="$(mktemp -d)"}
З іншими снарядами, схожими на Борна:
unset tmpdir
pushd "${tmpdir=$(mktemp -d)}"
Або використовувати висновок $(mktemp -d)кілька разів без явного зберігання його в змінній, ви можете використовувати zshанонімні функції:
(){pushd ${1?} && cd - && rmdir $1} "$(mktemp -d)"
trapобробник може очистити каталог, якщо процес буде викликаний сигналом.