深いプッシュスタックを拡張するより良い方法はありますか?

深いプッシュスタックを拡張するより良い方法はありますか?

Bashスクリプトで次のことが発生する状況が時々発生します。

pushd /tmp
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
pushd redis-stable
make
sudo make install
popd; popd

重要なビットは 2 つのpushds で、popd2 つの連続した一致する s で終わります。最後の文章はいつも私を悩ませます。スタックから任意の数のアイテムを取り出し、元のディレクトリに戻す意図を表現するより良い方法が必要になるようです。

popd +nBashのマニュアルページを検索し、パラメータ-nのバリエーションを試しましたが、彼らがすることは排除だけのようです。一つアイテムは毎回スタックから削除されます。これは私が望むものではありません。アイテムの数に関係なく、ディレクトリスタックを展開して以前の状態に戻そうとします。

OLDPWD=$(pwd)どこかに保存したパラダイムに切り替えることなく、cd $OLDPWD最終的にこれを行うより良い方法はありますか?

ベストアンサー1

スクリプトでこのディレクトリを使用することは危険のために問題になります。popd元のディレクトリに戻らず、同じ名前のディレクトリに戻ります。元のディレクトリが移動された場合、スクリプトは途中で場所を切り替えます。これは遠隔リスクのように見えるかもしれませんが、近いうちにそのようなことが起こります。〜するこれが起こると、スクリプトユーザーはあなたを呪います。

一時的に別のディレクトリで実行する場合は、最善の方法はサブシェルでスクリプトの対応する部分を実行することです。

( set -e
  cd "${TMPDIR:-/tmp}"
  wget -q http://download.redis.io/redis-stable.tar.gz
  tar xzf redis-stable.tar.gz
  cd redis-stable
  make
  sudo make install
)

たとえば、ここでは必要ありませんが、サブシェルが適切ではない同様の状況で役に立つ可能性がある代替案を紹介します。たとえば、いくつかの変数を設定して使用したい場合は、ディレクトリで使用できます。

実際には別のディレクトリに切り替える必要がない場合、または単一のコマンド期間中にのみ別のディレクトリに切り替える必要があるかもしれません。 GNUツールを使用している場合tarとその両方をディレクトリに切り替えるための引数をmakeサポートしています。-Cスクリプトがこのディレクトリを作成することを考えると、元のディレクトリとは異なり、その場所が移動されないと仮定するのが合理的です。

set -e
: "${TMPDIR:=/tmp}"
wget -q -O "$TMPDIR/redis-stable.tar.gz" http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz -C "$TMPDIR"
make -C "$TMPDIR/redis-stable"
sudo make -C "$TMPDIR/redis-stable" install

別のディレクトリに切り替えるオプションがないコマンドでは、より狭いサブシェルを使用できます。

set -e
: "${TMPDIR:=/tmp}"
( cd "$TMPDIR"
  wget -q http://download.redis.io/redis-stable.tar.gz
  tar xzf redis-stable.tar.gz -C "$TMPDIR"
)
( cd "$TMPDIR/redis-stable"
  make
  sudo make install
)

前後に切り替える必要がある場合、複数の呼び出しに比べて明確な改善点は、戻りたくないpopdディレクトリに電話するのではなく、戻りたいときに呼び出すことです。cdcdpushd

set -e
pushd "${TMPDIR:-/tmp}"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
popd

pushdしかし、私は and をまったく使用しないことをお勧めしますpopd。これは対話型の使用のために設計されており、スクリプトでは何よりも混乱する傾向があります。現在のディレクトリの場所を保存するには、変数に保存します。これはスクリプトを読みやすくするため、読者はpopd呼び出しがどこに戻るのかを知る必要はありません。

set -e
original_directory="$PWD"
cd "${TMPDIR:-/tmp}"
wget -q http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
cd "$original_directory"

おすすめ記事