我有一个在 bash 中获取的脚本。它可以做各种各样的事情,并保留$PWD
我在采购它之前的状态。
pushd ~/.dotfiles >/dev/null || exit 1
# Do various things
popd >/dev/null || exit 1
该脚本在 zsh 中也(大部分)运行良好,但是当我从该~/.dotfiles
位置获取它时,在获取它之后我最终会进入前一个位置$OLDPWD
。
pushd
如果当前位置已经相同,zsh 似乎会忽略该行,因此popd
命令会转到$OLDPWD
脚本来源之前的位置。
有没有办法阻止 zsh 忽略“冗余”pushd
命令,同时保持脚本与 bash 兼容?
我的 中确实有以下内容.zshrc
,但当我取消设置它们时也会发生这种情况:
setopt AUTO_PUSHD PUSHD_SILENT PUSHD_IGNORE_DUPS
答案1
pushd
旨在popd
方便交互。它们在脚本中既不可靠也不有用。
你看到的效果是pushd_ignore_dups
,默认情况下关闭,但您显然已在配置中启用。
pushd
和的另一个潜在问题popd
是您需要确保确实成对调用它们。popd
在错误路径上意外省略 a 的风险很高,这会导致到处混乱。
在要获取的辅助脚本中,通常根本不应该更改当前目录。只需在各处使用绝对路径即可。
如果您确实想更改当前目录,请使用该cd
命令。将旧的当前目录保存在变量中。
# instead of pushd...
foo_old_pwd=$PWD
cd /foo/directory
# instead of popd...
cd "$foo_old"
这适用于所有 Bourne 风格的 shell(甚至是那些没有实现pushd
and 的shell popd
),并且永远不会恢复错误的目录。
但是,任何基于退出目录并返回目录的代码都会在一种异常情况下中断:如果您无权更改回原始目录。当进程失去权限后,可能会发生这种情况。
答案2
你需要一个if-then-else来自你实际的答案。
if [ $PWD == ~/.dotfiles ]
then nopopd=true
else pushd ~/.dotfiles >/dev/null || exit 1
fi
# Do various things
[[ ! $nopopd == true ]] && popd >/dev/null || exit 1
请注意
- 这是未经测试的
- 不确定您是否仍然需要或条件 (
||
)pushd
符合 - 阅读吉尔斯的回答
答案3
我已经尝试过这个,这似乎有效,但我想知道其他更好的方法,因为它看起来非常可怕:
[[ $PWD == ~/.dotfiles ]] && nopopd=true
pushd ~/.dotfiles >/dev/null || exit 1
# Do various things
[[ ! $nopopd == true ]] && popd >/dev/null || exit 1
更新不,这实际上不起作用,因为终端在~/.dotfiles
目录中时会关闭。