内部にヘビーヒートトラップ「Greg's Wiki」で次の引用を見つけました。
実際、
echo
ここでこのコマンドを使用することは絶対に安全ではありません。-n
たとえば、変数に含まれる場合、echo
印刷するデータではなくオプションと見なされます。変数値を印刷する絶対に信頼できる唯一の方法は、次の方法を使用することですprintf
。printf "%s\n" "$foo"
しかし、私が入力したとき:
var="-n Hello"
echo "$var"
うまく機能し、オプションとして説明されていませんが、私が引用したソースから絶対に安全にするには、-n
この機能を使用する必要があると言う理由を理解できません。printf
答え1
あなたの例では、「偶然に」うまく動作します。その理由はこれだ
- パラメータを1つだけ提供しました
echo
。 - 提案されているように変数を参照しました。
つまり、「単語」の間のスペースを含む文字列だけがecho
コマンドライン引数と見なされます。-n Hello
今echo
(まあ、いくつかのs)はオプションを認識しますが、文字列は認識しないようにecho
プログラムされているので、オプションであると仮定します。-n
-n<space>Hello
オペランド- つまり、「現状のまま」印刷したい文字列です(おそらく\
シーケンスが拡張された状態で)。
使用したことがある場合
echo $var
引用符がなく、デフォルト値がある場合は$IFS
空白$var
に分割され、次のようecho
に表示されます。二つ議論: -n
-オプションとして解釈されます- そしてHello
。
これは意味するこの場合、シェル変数を正しく引用することは、echo
オペランドがオプションとして解釈される状況が不注意に発生するのを防ぐ解決策です。
しかし:
リンクされたソースの例は、「グローバル拡張」()を介してファイルのリストを印刷することです
*.zip
。ここで変数は〜しなければならない引用符なしで使用されるため、この保護は常に使用できるわけではありません。参照変数は、次の状況でのみ有用です。噴射
echo
オプションパラメータが表示されます。。印刷したいパラメータが-n
最初から単一のパラメータである場合、引用は役に立ちません。たとえば、printの文字列配列を収集し、文字列の
echo
1つが次のオプション引数でもある状況を考えてみますecho
。arguments=( "-n" "Hello" )
その後、変数を正しく参照しても
echo "${arguments[@]}"
最初のトークンは
echo
まだ-n
オペランドではないオプションと見なされます。複数の変数を引数としてecho
渡し、最初の変数がorの場合も同様です-n
。ここでも変数を引用することは役に立ちません。一般に、プログラムが次の形式のパラメータを受け入れる場合は、引用さえ役に立ちません。
-oValue
。仮想的な状況では、
my_formula_renderer
数学式をフォーマットし、オプションの引数を受け入れるプログラムを使用してください。次に、次の式を組版するとします。-sfontsize
-sqrt(a^2 + b^2)
./my_formula_renderer "-sqrt(a^2+b^2)"
プログラムに終了オプションの解析指定子がない場合は、上記の式のデフォルトのフォントサイズを使用するのではなく、フォントサイズの組版「
--
なし」を使用したいとします。qrt(a^2+b^2)
;
-s
などの他の数式要素の間に明示的な空白がある場合でも役に立ちません。先行スペースがある「フォントサイズ」"-s +2t +u^2"
と誤って解釈された可能性があります(参照+2t +u^2
たとえば、この質問これが問題になります。)プログラムが単一文字オプションの「クラスタリング」を許可する場合も同様です。
たとえば、@Stéphane Chazelasが指摘したように、
echo
文字列はoptionsとの接続として解釈される可能性があるため、その文字列を-neEenennne
印刷しようとすると予期しない方法で失敗したり動作したりする可能性があります。-n
-e
-E
echo
オプション処理に加えて、
echo
(一部のバージョンではデフォルトでオプションが有効になっている場合をecho
含む一部)などが改行、バックスラッシュ、バックスペース文字に拡張されます。bash
xpg_echo
\n
\\
\b
バックスラッシュを含めることができる蓄積文字列を出力するために使用することはできません。。
TL/DR
核心は、あなたが引用したソースに「絶対」という言葉があり、echo
それが具体的に指す事実である。ほとんどの場合はecho
大丈夫でしょう。しかし、盲目的に依存し始めると(近いうちに)何かが起こるecho
か、実際にはもっと重要な別のプログラムになります。「オペランド」パラメータとして意図したものを誤って「オプション」パラメータとして誤って解釈する、通常はシェル変数として渡すとき。