5

次のコードを含むシェル スクリプトがあります。

dir=sample
`mkdir $dir`
`cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt`
`cd $dir`

cdバック クォーテーションで囲まれたコマンドの最後の行ではcd、対応するディレクトリにアクセスできませんでした。しかし、逆引用符を削除すると、cd. 私が疑問に思っていたのはcd、バッククォートでうまくいかなかったのはなぜですか?

4

2 に答える 2

13

あなたが走ったとき:

`mkdir $dir`

シェルは最初mkdir $dirにサブシェルでコマンドを実行し、その (標準) 出力をキャプチャしてから、キャプチャした文字列をコマンドとして実行しました。幸い、出力は空だったので、2 番目のステップでは何も実行されませんでした。

その後、実行したとき:

`cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt`

コピーはサブシェルで実行され、出力がキャプチャされて実行されました。繰り返しますが、出力は空だったので、実行の第 2 フェーズは何もしませんでした。

次に、実行しました:

`cd $dir`

もう一度、cd操作はサブシェルで実行され、現在の作業ディレクトリを変更した後に終了しましたが、親シェルには影響しません (これは DOS.batコマンド ファイルではなく Unix です)。前と同様に、cdコマンドの出力がキャプチャされて実行されましたが、出力が空だったため、実行するものは何もありませんでした。

本質的に、逆引用符は、実際に行っているほど広範囲には使用しません。

次のように書くだけで十分です。

dir=sample
mkdir $dir
cp /home/bhavya/workspace/UnetStack/logs/log-0.txt $dir/log.txt
cd $dir
...other activity in the new directory...

これがスクリプト内にある場合、スクリプトを実行する通常の方法では、元のディレクトリに親シェルが残ることに注意してください。元のシェルに影響を与える方法があります — コマンドについて調べます.(または、コマンドでbash調べますsource。検索しやすいです)。

通常は、$(...)データを取得するために逆引用符 (より適切には表記法) を使用します。例えば:

gcc_lib_dir=$(dirname $(dirname $(which gcc)))/lib

最も内側のコマンドはwhich gcc; それは生じるかもしれません/usr/gcc/v4.7.1/bin/gcc。内側dirnameは降伏し/usr/gcc/v4.7.1/binます。外側の dirname が生成され/usr/gcc/v4.7.1ます。追加され/lib

gcc_lib_dir=/usr/gcc/v4.7.1/lib

$(...)これは、 がバッククォート表記よりも優れている理由も示しています。

gcc_lib_dir=`dirname \`dirname \\\`which gcc\\\`\``/lib

それは正しく理解するのが難しく、入力するのが難しいです!

于 2012-08-20T06:33:19.813 に答える
5

逆引用符は、サブシェル内でコマンドを実行します。サブシェルはディレクトリを変更しましたが、これをスクリプトのシェルに反映する方法はありません。

于 2012-08-20T06:24:11.247 に答える