web-dev-qa-db-ja.com

単一引用符内で変数を使用する方法

一重引用符に埋め込まれた二重引用符で属性を入力として受け取るアプリケーションがあります。たとえば、次の正しいコマンドを見てください。

command -p 'cluster="cl1"'

それを自動化するために、変数として$CLUSTERを使用してbashファイルを作成しました。私の命令はどうあるべきですか?つまり、cl1の代わりに何を配置すればよいですか。

上記のコマンドを変更すると、受け入れられなくなりますのでご注意ください。例:command -p "cluster=cl1"は使用できません

11

コマンドがコマンドラインで指定された引数に基づいて環境変数を設定している可能性があります。それはあなたができるかもしれません:

_CLUSTER=cl1; cluster=$CLUSTER command
_

...呼び出し時にその環境を設定します。

それ以外の場合、シェルは通常、引数を区切るか、シェルの解釈から他の特殊なシェル文字をエスケープします。さまざまなルールに基づいて、他の種類の中に(したがってエスケープ)異なる種類のシェル引用符を含めることができます。

  • _"''''"_-ソフトクォートされた文字列には、ハードクォートをいくつでも含めることができます。
  • _"\""_-_\_バックスラッシュは、_"_ soft-quoted文字列内の_"_ soft-quoteをエスケープできます。
    • このコンテキストでは、_\\_ backslashもそれ自体、_\$_ expansionトークン、および_\n_ ewlinesをエスケープしますが、それ以外は文字どおりに扱われます。
  • _"${expand} and then some"_-ソフトクォートされた文字列には、解釈されたシェル_$_ expansionを含めることができます。
  • _'"\'_-_'_ hard-quoted文字列には、_'_ hard-quote以外の文字を含めることができます。
  • _\_-引用符で囲まれていないバックスラッシュは、リテラル解釈のために次の文字をエスケープします-_\n_ ewlineを除いて、別のバックスラッシュも-
    • _\\n_ ewlineの場合、_\_バックスラッシュと_\n_ ewlineの両方が、結果として解釈されるコマンドから完全に削除されます。
  • _${parameter+expand "$parameter"}_-シェル展開から生じる引用符は、いくつかの特別な場合を除いて、区切り記号として機能することはほとんどありません。ここでは、これらについてさらに説明するつもりはありません。

どのアプリケーションもコマンドライン引数の引用符を解釈するのは奇妙だと思います。そのような慣行は、シェルでは少なくとも意味がありません。少なくとも、引用符の主な目的は、一般的に引数を区切ることです。ただし、呼び出し時には、引数は常に_\0NUL_文字を使用してすでに区切られていますであるため、引用符はあまり目的に役立ちません。

シェルでも、_-c_スイッチで呼び出された場合、通常は呼び出し引数の1つで引用符を解釈するだけで済みます。これは、最初のoperandが実際にはシェルスクリプトであることを示します呼び出し時に実行されます。これは2回評価入力の場合です。

そうは言っても、コマンドラインの引数を介してリテラル引用符を渡すために多くのことを行うことができます。例えば:

_CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
_

以前のコメントで述べたように、_"_で囲まれた展開内に_"_の引用符を含めることができます。

_CLUSTER=cl1; command -p "cluster=\"$CLUSTER\""
_

_"_引用符で囲まれた文字列内で_\_ backslashを使用して_"_をエスケープできます。

_CLUSTER=cl1; command -p cluster='"'"$CLUSTER"'"'
_

@jimmij 上記の注記 のように、希望する最終結果に到達するために、引用スタイルを交互に連結することができます。

_CLUSTER=cl1; ( set -f; IFS=; command -p cluster=\"$CLUSTER\" )
_

ファイル名生成と_$IFS_の両方の分割を無効にすることができます。これにより、_$expansion_を引用符で囲む必要がまったくなく、引用符のみを引用できます。これはおそらくやり過ぎです。

最後に、使用される可能性のある別のタイプのシェル引用があります。前述のように、シェルのスクリプトの_sh -c "$scriptlet"_形式は、コマンドラインでシェルのスクリプトを提供するためによく使用されます。引用符が他の引用符を含む必要がある場合など、_$scriptlet_が複雑になる場合-代わりにヒアドキュメントと_sh -s_を使用することがしばしば有利です。 operandsは、_-c_の場合と同じように定位置パラメーターに、さらにそのスクリプトをstdinから取得します。

コマンドがこのように引用符を解釈する必要がある場合は、ファイル入力で解釈できるとより良いと思います。例えば:

_CLUSTER=cl1
command --stdin <<-SCRIPT
    cluster="$CLUSTER"
SCRIPT
_

_<<here-document_の区切り文字を引用符で囲まないと、その内容はすべて_"_ soft-quoted-except that _"_ double-quotesとほぼ同じように扱われます。自分自身は特別に扱われません。したがって、上記をcatで実行すると、次のようになります。

_CLUSTER=cl1
cat <<-SCRIPT
        cluster="$CLUSTER"
SCRIPT
_

...印刷します...

_cluster="cl1"
_
8
mikeserv

似ている mikeserv と書いた:

_ CLUSTER='"cl1"'; command -p "cluster=$CLUSTER" 
_

「二重引用符」スペース/メタ文字を含むすべてのリテラルとevery展開:_"$var"_、"$(command "$var")"、_"${array[@]}"_、_"a & b"_。コードまたはリテラルには_'single quotes'_を使用します_$'s: 'Costs $5 US'_、_ssh Host 'echo "$HOSTNAME"'_。見る
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words

1
Gilles Quenot