プログラムを呼び出すためにset --envを使用するのはなぜですか?

プログラムを呼び出すためにset --envを使用するのはなぜですか?

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}

これはプログラムを呼び出しません(まあ、組み込みを呼び出すsetenv、またはは呼び出さないgo)。位置引数(など、まとめてリストと呼ばれる)を次の単語に設定して、ifが文字列になるようにし$1ます。$2"$@"--$PACKAGEhello 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を--実行しません。envgo

誰かが言うなら

"$@"

これコマンドが実行されます。 "$@"位置パラメータ(別紙参照)に展開されます。

たとえばbash、これは名前付き配列の値を設定するのと同じです。

array=( env GOPATH=/some/path go build ${PACKAGE} )

これもやっていないenvgo

後で使用

"${array[@]}"

コマンドラインが実行されます。

"$@"と中の二重引用符は"${array[@]}"意図的で重要です。二重引用符がない場合、これらのリストの要素は空白の別々の単語に分割されます(上記の文字列が引用符なしで2つに分割されるhello worldように${PACKAGE})、シェルは結果の単語Wildcardにファイル名も実行します。

関連情報