
私は bash スクリプトを読んでいますが、何が起こっているのか理解できません。
#!/bin/sh
[ x$1 = x ]
2行目では何が起こっていて、どういう[ x$1 = x ]
意味ですか?
答え1
は が空であるかどうかをチェックします$1
が、引用符で囲む必要があります ( と同じです[ -z "$1" ]
)。非常に古いシェルの中には空の文字列を適切に処理しないものもあったため、移植可能なスクリプトの作成者はこのチェック方法を採用しました。これは何十年も必要ではありませんでしたが、人々がまだそのように行っているため、今でもそのように行われています。
答え2
角括弧はテストしたがって、や類似のもの[ x$1 = x]
がない場合if
、構文的には問題ありませんが意味がありません。
x$1
これは、 が に展開される場合は true に評価されx
、それ以外の場合は false に評価されることを意図していますが、引用符で囲まれていないため、$1
が (例) "hey x" の場合、シェルは と認識しx = x
、この構造はまだ安全ではありません。
チェックの目的x = x
は、変数が空かどうかを判断することです。これを行うより一般的な方法は、引用符を使用することです。
if [ "$1" = "" ]; then
Bash テスト演算子-z
も-n
使用できますが、他の種類のシェルへの移植性は低くなります。1
引用符、または を使用する理由は、x$1
左側が何も展開されずに構文エラーにならないようにするためです。
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. 実際には、 はtest
スタンドアロン ユーティリティとして使用できますが、ほとんどのシェルでは組み込みとして実装されています。 と の違いを確認してくださいwhich test
。type test
GNU/Linux では、man test
は組み込みを参照すると主張していますが、(例) を呼び出すと、そのユーティリティは、や/usr/bin/test
など、マニュアル ページに記載されている機能を実装しているように見えます。-z
-n
答え3
[ x$1 = x ]
は でのみ意味を持ちます。これは、 とスクリプトの最初の引数zsh
の連結を と比較します。したがって、が空であるか指定されていない場合、コマンドは true を返します。x
x
[
$1
[ $1 = "" ]
は動作しません。なぜなら、 では、zsh
空の変数がリスト コンテキストで引用符で囲まれていない場合、空の引数ではなく引数なしとして展開されるため、 が$1
設定されていないか空の場合、コマンドは引数として、、空の文字列、[
のみを受け取りますが、これは意味をなさないからです。ただし、または は、POSIX シェルのように問題ありません。[
=
]
[ -z "$1" ]
[ "$1" = "" ]
Bourne のような/POSIX シェルでは、[ x$1 = x ]
意味がありません。これは、x
結果と、およびがコマンドの有効なテスト式を構成することを期待して、split+glob 演算子が何らかの方法でスクリプトの最初の引数=
のx
連結]
に適用されたものです[
。
たとえば、スクリプトに 1 つの" = x -o x ="
引数が渡された場合、は、、、、、、、、[
の引数を受け取ります。これらは、とを比較するものと理解され、 true を返します。[
x
=
x
-o
x
=
x
]
[
x
x
x
x
$1
の場合"* *"
、シェルは、[
現在のディレクトリ内で名前が で始まるファイルのリストx
( のグロブ展開x*
) をコマンドに渡し、次に隠しファイルでないファイルのリスト (展開*
) を渡します... これでは、の意味を理解できない可能性があります。 がワイルドカードまたは空白文字を含まない[
場合のみ、意味のある処理が行われます。$1
さて、次のようなコードが時々見つかります。
[ "x$1" = x ]
$1
空または未設定かどうかをテストするために使用されます。
空または未設定の変数をテストする通常の方法は次のとおりです。
[ -z "$1" ]
しかし、これは、Solaris 10 以前や一部の古いバージョン(0.5.4 まで)の Bourne シェルの組み込みのものなど、一部の (非 POSIX)実装の の一部の$1
値では失敗します。=
[
/bin/sh
dash
sh
これは、、、を[
認識し、を文字列に適用された単項演算子として理解するのではなく、二項演算子への引数が不足しているとエラーを報告している[
ためです。-z
=
]
=
-z
=
同様に、またはの場合、[ "$1" = "" ]
の一部の実装では は失敗します。[
$1
!
(
これらの shell/[
実装では:
[ "x$1" = x ]
は の値に関係なく常に有効なテストなので$1
、次のようになります。
[ "" = "$1" ]
そして:
[ -z "${1:+x}" ]
そして
case $1 in "") ...; esac
もちろん、引数が提供されていないことを確認したい場合は、次のようにします。
[ "$#" -eq 0 ]
つまり、スクリプトに渡される引数の数を確認します。
現在では、 はPOSIX によって明確に指定されており、準拠した実装[ -z "$var" ]
では失敗しないことに注意してください (は数十年にわたってそうでした)。したがって、POSIX sh またはスクリプトではこれに依存できるはずです。[
bash
[
bash
答え4
[ x$1 = x ]
$1
が未設定/null/空かどうかは真です。 以下
を試してください:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"