web-dev-qa-db-ja.com

$ {param:= value}はどういう意味ですか?

Z-Shellのユーザーズガイド で以下を読みました:

「true」の同義語は「:」です。このフォームでは、副作用はあるが使用すべきではない引数を与えるためによく使用されます。

: ${param:=value}

これは、すべてのBourne Shell派生物で一般的なイディオムです。パラメータ展開では、$paramは、前に空だった場合は値valueが与えられ、それ以外の場合はそのままになります。それがパラメーター展開の唯一の理由だったので、:を使用して引数を無視します。実際、シェルはコマンドラインを構築します—コロン、その後に$paramの値が何であれ、割り当てが発生したかどうかにかかわらず、コマンドが実行されます。たまたま、「:」は与えられた引数に気付かない。

分かりません。 :trueを意味しますが、式には2つのコロンがあります。ささいな質問として、なぜこのイディオムはすべてのボーンシェル派生物でそんなに使われているのですか?それはどんな目的に役立ちますか?

注:このイディオムがbashzsh

ありがとう

35

これをバラバラに分解してみましょう。

このコードは、いくつかの引数を指定してコマンド:を実行します。コマンド:は何もせず、引数を無視します。したがって、引数で発生する副作用を除いて、コマンドライン全体は何も実行しません。

構文${parameter_name:=value}は、ash、bash、ksh、zshを含むすべての非骨董品のBourneスタイルのシェルに存在します。必要に応じて、パラメーターをデフォルトに設定します。に相当します

if [ -z "$parameter_name" ]; then parameter_name=value; fi
… ${parameter_name}

つまり、parameter_nameが設定されていないか、空の値に設定されている場合は、指定された値に設定します。次に、新しいパラメーター値を使用してコマンドを実行します。バリアント${parameter_name=value}があります。これは、パラメーターが空の場合はパラメーターを空のままにし、パラメーターが設定されていない場合は指定された値のみを使用します。

この構文は POSIX仕様 の「パラメータ展開」と、ダッシュ、bash、ksh、zshのマニュアルに記載されています。

この構文にはバリエーションがあり、特に${parameter_name:-value}を使用すると、パラメーターに割り当てずに、この拡張のデフォルト値のみを使用できます。

要約すると、: ${parameter_name:=value}は簡潔な記述方法です

if [ -z "$parameter_name" ]; then parameter_name=value; fi

:はtrueを意味しない-おそらくwhile :を考えているかもしれませんが、その式でさえ「true」を意味するのではなく、単に評価されるだけです(実際、それは単にnullコマンド、またはnoop)。

このパラメーター展開(${x:=y})は、「 x y を割り当てる x は未設定または空であり、 y "に展開されます。

$ echo "${foo:=bar}"
bar
$ foo=baz
$ echo "${foo:=bar}"
baz
$ foo=
$ echo "${foo:=bar}"
bar
$ echo "${foo}"
bar

Bash Hackers wikiには、パラメーター拡張についての優れた記事 here があります。

:が使用されるのは、コマンドの他の部分が評価されている間は、それらが実行されないためです(:はnullコマンドであるため)。したがって、${x:=y}は他に影響を与えずにその機能を実行します。たとえば、最初に:がなかった場合、というコマンドを実行しようとします。 y

:bashのヘルプページは次のとおりです:

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
11
Chris Down

最初の_:_はコマンドであり、「ヌープ」または「操作なし」と呼ばれます。マンページで述べたように、これは引数の評価によく使用されます。

2番目の_:_は変数展開の修飾子です-技術的には_:=_です。言われたように、これは値がない場合に値を設定します。

慣用的には、環境変数のデフォルト値が必要な場合は、この構文を使用できます。たとえば、cron(8)を介してプログラムを実行する場合、環境は設定されず、シェルのドットファイルは実行されません。したがって、いくつかのデフォルトを設定する必要があるかもしれません。

_: ${Java_HOME:=/usr/local/jdk-1.6.0_28}
_

その後、「設定して忘れる」ことができます(デフォルトのjvmが変更されるまで)。

3
Arcege