Bashスクリプトの一部のコードは、実際にset -- env
実際のコマンドを使用してプログラムを呼び出すことがわかりました。たとえば、次のようになります。
set -- env GOPATH=/some/path go build ${PACKAGE}
これの根拠は何ですか?以前と同じですか?
env GOPATH=/some/path go build ${PACKAGE}
答え1
set -- env GOPATH=/some/path go build ${PACKAGE}
これはプログラムを呼び出しません(まあ、組み込みを呼び出すset
がenv
、またはは呼び出さないgo
)。位置引数(など、まとめてリストと呼ばれる)を次の単語に設定して、ifが文字列になるようにし$1
ます。$2
"$@"
--
$PACKAGE
hello world
$ PACKAGE='hello world'
$ set -- env GOPATH=/some/path go build ${PACKAGE}
$ i=1; for param in "$@"; do printf '$%d = "%s"\n' "$i" "$param"; i=$((i+1)); done
$1 = "env"
$2 = "GOPATH=/some/path"
$3 = "go"
$4 = "build"
$5 = "hello"
$6 = "world"
つまり、toを介して$1
パラメータを$6
後続の値に設定し、orを--
実行しません。env
go
誰かが言うなら
"$@"
これコマンドが実行されます。 "$@"
位置パラメータ(別紙参照)に展開されます。
たとえばbash
、これは名前付き配列の値を設定するのと同じです。
array=( env GOPATH=/some/path go build ${PACKAGE} )
これもやっていないenv
かgo
。
後で使用
"${array[@]}"
コマンドラインが実行されます。
"$@"
と中の二重引用符は"${array[@]}"
意図的で重要です。二重引用符がない場合、これらのリストの要素は空白の別々の単語に分割されます(上記の文字列が引用符なしで2つに分割されるhello world
ように${PACKAGE}
)、シェルは結果の単語Wildcardにファイル名も実行します。