bashからインポートされたスクリプトがあります。それはすべての種類のタスクを実行し、$PWD
購入する前の状態を維持します。
pushd ~/.dotfiles >/dev/null || exit 1
# Do various things
popd >/dev/null || exit 1
スクリプトはzshでも(ほとんど)うまく機能しますが、その~/.dotfiles
場所からインポートしたときにインポートした後、以前の場所に移動します$OLDPWD
。
pushd
zsh は、現在の位置がすでに同じ場合はその行を無視しているように見えるため、popd
コマンドは$OLDPWD
スクリプトソースの前の位置に移動します。
pushd
スクリプトをbashと互換性のあるままにしながら、zshが「冗長」コマンドを無視するのを防ぐ方法はありますか?
私のファイルには次のものがありますが、.zshrc
設定を解除してもこの現象が発生します。
setopt AUTO_PUSHD PUSHD_SILENT PUSHD_IGNORE_DUPS
答え1
pushd
相互作用を促進するように設計されていますpopd
。スクリプトでは信頼できず、便利ではありません。
あなたが見る効果はpushd_ignore_dups
、これはデフォルトではオフになっていますが、設定で有効になっているようです。
pushd
andのもう1つの潜在的な問題は、popd
実際にペアで呼び出す必要があることです。popd
誤ったパスから誤ってaを省略すると、あちこちで混乱を引き起こす危険性が高くなります。
インポートするヘルパースクリプトでは通常、現在のディレクトリをまったく変更しないでください。どこでも絶対パスを使用してください。
現在のディレクトリを本当に変更するには、このcd
コマンドを使用します。以前の現在のディレクトリを変数に保存します。
# instead of pushd...
foo_old_pwd=$PWD
cd /foo/directory
# instead of popd...
cd "$foo_old"
pushd
これはすべてのBourneスタイルのシェル(および実装されていないシェルを含むpopd
)で機能し、無効なディレクトリは決して復元されません。
ただし、ディレクトリを終了してそのディレクトリに戻ることに基づいているすべてのコードは、1つの例外、つまり元のディレクトリに戻す権限がない場合は中断されます。これは、プロセスが権限を失ったときに発生する可能性があります。
答え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
満たされているかわからない - Gilesの回答を読む
答え3
私はこれを試してみましたが、これはうまくいくようですが、かなり怖いように見えるので、他のより良い方法を知りたいです。
[[ $PWD == ~/.dotfiles ]] && nopopd=true
pushd ~/.dotfiles >/dev/null || exit 1
# Do various things
[[ ! $nopopd == true ]] && popd >/dev/null || exit 1
修正する~/.dotfiles
いいえ、ディレクトリ内に端末が閉じているため、実際には機能しません。