git bash 補完のコード、具体的には関数__gitcompは、 のようなパラメーター展開を使用します"${1-}"。これは に似ているよう"$1"です。違いはなんですか?
また、これはbashマニュアルのどこに記載されていますか?
git bash 補完のコード、具体的には関数__gitcompは、 のようなパラメーター展開を使用します"${1-}"。これは に似ているよう"$1"です。違いはなんですか?
また、これはbashマニュアルのどこに記載されていますか?
まず、 が、または${foo-bar}の値に展開されることを思い出してください。 ただし、 が設定されていない場合は ( が設定されていない場合は空の文字列に展開されます)に展開されます。この構文のより頻繁に使用されるバリアントがあり、これはifが設定されていないか空の場合に展開されます。(これはマニュアルで詳しく説明されています。 を検索し、上記の「コロンを省略すると、設定されていないパラメーターのみのテストになります。」という文に注意してください。)foo$foo${foo}foo${foo-bar}bar$foofoo${foo:-bar}barfoo:-
位置パラメータの場合、が設定されていない場合、つまり、位置パラメータの数が 1 未満の場合$1に${1-bar}展開されます。位置パラメータがまたはで変更されていない限り、これは現在の関数、または該当しない場合は現在のスクリプトを意味します。パラメータはありません。bar$1setshift
whenbarが空で${1-}あると、役に立たない複雑さのように見えます: 展開は の展開ですが、が設定$1されていない場合$1、展開は空であり、いずれにせよそうなります。使用のポイントは、 (別名)の${1-}下で、パラメーターが設定されていない場合はプレーンがエラーになり、設定されていない場合は常に空の文字列に正常に展開されることです。set -uset -o nounset$1${1-}$1
echo "${foo-default}"
foo が定義されている場合は $foo を出力し、foo が定義されていない場合は 'default' を出力します。だから私は結論付けます
"${1-}"
スクリプトの最初の引数が定義されていない場合は空です。
The Bash reference manual §3.5.3 Shell Parameter Expansion says:
When not performing substring expansion, using the form described below, Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.
${parameter:-word}If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
(Emphasis added.)
If the ${1-} appears inside double quotes in the shell script, it is really a not particularly useful way of writing "$1". If $1 is not defined, then both "${1-}" and "$1" expand to an empty argument; if $1 is defined but empty, they also both expand to an empty argument; and otherwise, even if $1 contains spaces, it appears as one argument to the called program.
If the ${1-} appears outside double quotes, then it still isn't useful: if $1 is undefined or empty, then the called program sees no argument (with either notation); if $1 is defined, then the called program sees one or more arguments based on the (split up) value of $1, or it sees no argument if $1 consists only of white space.
The notation really comes into its own when there is a value of some sort after the dash. For example:
localvar=${ENVVAR1:-${ENVVAR2:-/opt/software}}
This says 'if $ENVVAR1 is set to a non-empty value (including all blanks), use it; otherwise, look at $ENVVAR2 and if it is set to a non-empty value, use it; otherwise, use the value /opt/software'.
マニュアルのEXPANSION->へのイントロの詳細に実際に注意を払うことができました。展開ケース ( 、など)Parameter expansionのリストの前の最後の文は、「コロンを省略すると、設定されていないパラメーターのみのテストになる」と説明しています。が使用されている場合、これらのテストは unsetまたは nullのいずれかのパラメーターに対するものになります。:-:+:
そう:
$ unset malkovich
$ echo "${malkovich:-John} ${malkovich-Malkovich}"
John Malkovich
$ malkovich=
$ echo "${malkovich:-John} ${malkovich-Malkovich}"
John
$ echo "$malkovich"
$
話の教訓: マニュアル、RTFM をスキャンするだけではいけません。
一見すると、この答えは無関係に見えるかもしれません。echo "${malkovich-}"混乱した読者は、 の大文字と小文字を区別してから、 で使用されている元の形式を検討することをお勧めしecho "${1-}"ます。:-これは、コロンを省略できることを自分自身だけでなく、デフォルトのパラメーター展開の形式に精通している他の人にも説明するという点で、私の質問に対する答えです。
Gilles が指摘するように、は事実上、有効でない場合と"${1-}"同じです。その場合、変数が設定されていない場合のエラーを回避するために、デフォルト値の提供が必要です。コンテキストと構文の完全な説明については、Johnathan Lefler の回答を参照してください。"$1"set -u