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