コマンドecho
に私が提供したフルテキストは含まれていません。たとえば、これを行うと:
$ echo ' echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` '
次のように出力されます。
echo PARAM=` grep $ARG /var/tmp/setfile | awk {print } `
私のechoコマンドの一重引用符()は'
含まれていません。二重引用符に切り替えると、次のようになります。
$ echo " echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` "
echo
まったく何も出力しません!最初の例では一重引用符を省略し、2番目の例では何も出力しないのはなぜですか?入力した内容を正確に出力するにはどうすればよいですか?
ベストアンサー1
あなたのシェルは、およびを'
含む引用符が"
到着する前に解釈されていますecho
。私は通常私の主張が不要であっても応答に二重引用符を使用します。
$ echo "Hello world"
Hello world
したがって、最初の例では、出力に文字通り引用符を含めるには、エスケープする必要があります。
$ echo \'Hello world\'
'Hello world'
または、すでに引用符で囲まれたパラメータに使用する必要があります(ただし、同じ種類の引用符ではありません。そうでなければ、とにかくエスケープする必要があります)。
$ echo "'Hello world'"
'Hello world'
$ echo '"Hello world"'
"Hello world"
2番目の例では、文字列の途中でコマンド置換を実行します。
grep $ARG /var/tmp/setfile | awk {print $2}
で始まるものも$
シェルによって排他的に扱われます。つまり、シェルはそれを変数として扱い、その値に置き換えます。これらの変数のどれもシェルに設定されていない可能性が高いため、実際には実行されます。
grep /var/tmp/setfile | awk {print}
引数が1つしか表示されないため、引数が検索grep
中のパターンであり、データを読み取る必要がある場所がstdinであると仮定して、入力を待つのをブロックします。そのため、2番目のコマンドが中断されたようです。
引数を一重引用符で囲むとこれは発生しません(これが最初の例がほぼ成功した理由です)、目的の出力を取得する1つの方法は次のとおりです。
echo \'' echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` '\'
二重引用符で囲むこともできますが、sをエスケープして$
シェルがそれを変数に解析しないようにし、バックティックをエスケープしてシェルがすぐにコマンド置換を実行しないようにする必要があります。
echo "' echo PARAM=\` grep \$ARG /var/tmp/setfile | awk '{print \$2}' \` '"