问题标题的选择有些混乱。
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
不能用于获取前一个目录的路径,并且一般而言,其输出不能进行后处理(尽管访问该目录堆栈的元素,请参见某些shell 的$dirstack
or $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
在子shell中运行。如果确实如此,它将无法更改工作目录。那就是mktemp
在子shell中运行。由于它是单独的命令,因此必须在单独的进程中运行。它将输出写入管道,而shell进程在管道的另一端读取它的输出。
内置命令时,ksh93可以避免使用单独的进程,但是即使在此处,它仍然是一个子shell(不同的工作环境),这次可以对其进行仿真,而不是依赖于通常由分支提供的单独环境。例如,在ksh93
中a=0; echo "$(a=1; echo test)"; echo "$a"
,不涉及fork,但仍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
如果进程被信号戳,则处理程序可以清理目录。