コマンドが異なる動作をする前に、デフォルト値に変数を設定しますか?

コマンドが異なる動作をする前に、デフォルト値に変数を設定しますか?

代替デフォルト値に変数を設定することは有効です。フォロー注文する:

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
production
$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
staging

しかし、変数を設定してみてください直前これを使用するコマンドは異なる動作をします。

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
staging

2番目の例が異なる動作をする理由は何ですか?

答え1

最初のバージョンをより明確にするために、セミコロンを改行文字に置き換えます。

APP_ENV="${APP_ENV:-production}"
echo $APP_ENV

ライン1は、シェルがライン2を見る前に完全に実行されます。

1行目では$APP_ENV設定が同じですproduction

行2は変数にアクセスし、その値をechoコマンドに提供します。

これで、単一のコマンドバージョンは次のようになります。

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

まず、シェルはパラメータ拡張と(この場合は適用されません)、他の代替タイプに基づいてコマンドラインを拡張します。現在の値が$APP_ENV空であるため、次のように拡張されます。

APP_ENV="${:-production}" echo

拡張が実行されたら、このコマンド呼び出しでのみ使用さ$APP_ENVれるように変数を設定し、その値で呼び出します。ただし、環境に環境変数があることについては気にしません。何も含まないコマンドラインだけを見てください。だからエコーはありません。productionecho ""echo$APP_ENV

$APP_ENVこの場合、実際に設定されていることを証明する方法は次のとおりです。

$ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
APP_ENV=production

要約すると、パラメータ拡張が早すぎるため、2番目の例では想像どおりに機能しません。

答え2

;変数が初期化された後、aが欠落しているため、2番目の形式は動作が異なります。

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

しなければならない:

APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
                                ^ semicolon that's missing

まず、問題を解決してから質問を書き直してください。

関連情報