5

シェルスクリプトのこの行がわかりません。while ステートメントには、$ を設定する 'test' または [ ] または [[ ]] 式は必要ありませんか? 1または0に?どうやって

while IFS= read -r -d $'\0'; do ...; done

それを行う?ここでの構文を理解する助けがあれば大歓迎です。

4

4 に答える 4

4

シェルスクリプトのこの行がわかりません。while ステートメントには、$ を設定する 'test' または [ ] または [[ ]] 式は必要ありませんか? 1または0に?[声明]はどのようにそれを行うのですか?

-dandパラメータについては誰もが答えていますが、 andについてのIFS=あなたの質問には誰も答えていません。test[[..]]

すべての標準的な Unix コマンドは、成功するとゼロの値を返し、終了するとゼロ以外の値を返します。whileandステートメントは、そのif値を使用して、ループを続行するかどうかを決定します。

次のことをするとします。

$ touch foo.txt   #Create a "foo.txt" file
$ ls foo.txt
foo.txt
$ echo $?
0
$

lsコマンドが終了時にゼロを返したことに注意してください。これを試してください:

$ rm foo.txt
$ ls foo.txt
ls: foo.txt: No such file or directory
$ echo $?
1
$

foo.txt存在しない場合、コマンドlsは終了時に 1 を返します。

ifおよびwhileコマンドはその上で動作します。

別のターミナル ウィンドウに移動し、foo.txtファイルを作成します。次に、元のウィンドウに戻って、これを試してください。

$ while ls foo.txt > /dev/null
> do
> echo "The file foo.txt exists"
> sleep 2
> done
The file foo.txt exists
The file foo.txt exists
The file foo.txt exists
...

while は 2 秒ごとにループfoo.txtし、ステートメントの存在を確認して出力します。次に、2 番目のターミナル ウィンドウに戻り、foo.txt. 最初のターミナル ウィンドウに戻ると、whileループが終了したことがわかります。

で同じことができますif

$ if ls foo.txt > /dev/null
> then
>     echo "foo.txt exists"
> else
>     echo "Whoops, it's gone!"
> fi

このifステートメントは、foo.txt が存在するか、Whoops, it's gone! のいずれかを出力します。foo.txtと呼ばれるファイルがディレクトリに存在するかどうかによって異なります。

コマンドの終了値が返されることに注意してifください。テストの必要はまったくありません。while

では、なぜ、、、testおよび[...]構文[[...]]なのでしょうか。

$fooが に等しいかどうかを調べたいとしましょう$bar。そこでtest出番です。これを試して:

$ foo=42
$ bar=42
$ test "$foo" -eq "$bar"
$ echo $?
0
$ bar=0
$ test "$foo" -eq "$bar"
$ echo $?
1

test コマンドが行うのは、真のテストではゼロを返し、偽のテストではゼロ以外の値を返すことだけです。これにより、 andステートメントでtestコマンドを使用できます。ifwhile

$ if test $foo -eq $bar
> then
>     echo "foo is equal to bar"
> else
>     echo "foo and bar are different"
> fi
foo and bar are different
$

それで、何[...]ですか?

$ ls -il /bin/test /bin/[
10958 -rwxr-xr-x  2 root  wheel  18576 May 28 22:27 /bin/[
10958 -rwxr-xr-x  2 root  wheel  18576 May 28 22:27 /bin/test

その最初の列はinodeです。2 つのファイルが同じinodeを持つ場合、それらはハード リンクされ、同じファイルを参照します。私のシステムでは、どちらも 18,576 バイトであることに注意してください。

これは、コマンド自体[を実行する別の方法です。testこれらの行はどちらも同じです。

if test $foo -eq $bar
if [ $foo -eq $bar ]

[、シェル スクリプトの見栄えを良くするために作成されました。ただし、その下では、使用できるtestゼロまたはゼロ以外の値を返すコマンドをif実行していwhileます。

ちなみに、Kornshell と BASH では、 と はどちらもシェル[test組み込まれています。ただし、それらは同じ組み込みコマンドを参照します。

これ[[...]]は、Kornshell で最初に登場したテストの特別バージョンです。パターン マッチの使用が可能になり、コマンドを実行する別のプロセスが生成されないため、少し高速になりますtest

于 2013-08-13T20:28:48.807 に答える