#!/usr/bin/env が NAME=VALUE で中断されます。

#!/usr/bin/env が NAME=VALUE で中断されます。

私はshebangの意味が何であるかを理解しようとしています。

次のスクリプトを作成できます。

#!/usr/bin/env bash

if [ -z "$FOO" ]
then
    echo "No FOO"
else
    echo "$FOO"
fi

私の環境ではなく$FOO、などのように実行すると予想通り「No FOO」が印刷されます。./foo.shbash foo.shenv bash foo.sh

もちろんFOO=bar ./foo.sh、これを実行して印刷することもできますbar

マニュアルenvページでは、次のような呼び出しを提供します。

env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]

次のように使用できます。

$ env FOO=bar bash foo.sh
bar

ただし、shebangでこの構文を使用しようとすると、次のようになります。

#!/usr/bin/env FOO=bar bash

if [ -z "$FOO" ]
then
    echo "No FOO"
else
    echo "$FOO"
fi

その後、./foo.sh無期限に中断され、実行されません。

誰でも私にこれを説明できますか? Shebangが発生した場合は、コマンドをコピーし、引数リストの末尾にスクリプトパスを追加して実行すると仮定しましたが、この動作はそうではないことを意味します。

答え1

ほとんどのシステムは最大一つshebang 行のインタプリタパスの後の引数です。 1 つ以上のアイテムを提供する場合、動作はシステムによって異なります。

Linuxでは、インタプリタの後のすべてのエントリ(前後にスペースやタブなし)が単一の引数として渡されます。だから叫んで:

#! /usr/bin/env FOO=bar bash

システムはおよびパラメータを/usr/bin/env使用して呼び出します。これにより、スクリプトがパラメータ(環境内)ではなくその環境で再実行され、無限ループが発生します。FOO=bar bash/path/to/the/scriptenvFOO=bar bashbash/path/to/the/scriptFOO=bar

env最新バージョンのFreeBSDやGNUを含むいくつかの実装は、この制限を解決するために独自に分割するenvように指示されるかもしれません。-S

存在する

#! /usr/bin/env -S FOO=bar bash

単一の"-S FOO=bar bash"引数はまだ渡されますが、オプションの引数は分割され、別の引数として呼び出されたかのenvように動作します。env" FOO=bar bash"-SFOO=barbash

よりGNUenvマニュアルまたはFreeBSDenvマニュアル分割の実行方法の詳細。

関連情報