Выбор названия вашего вопроса немного сбивает с толку.
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обработчик может очистить каталог, если процесс будет обработан сигналом.