これまで、私は次のように"\""
二重引用符を印刷してきました。
$ x="abc def"
$ echo "x=\"$x\""
x="abc def"
しかし、この動作は定義されていないようですか?
~のためecho
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html(XSI互換システムの追加仕様を無視すると)バックスラッシュは完全に未定義の動作につながります。
標準出力に書き込まれる文字列。最初のオペランドが-nの場合、またはオペランドに<backslash>文字が含まれている場合、結果は実装に従って定義されます。
このページはprintf
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html主にファイル形式記号を表します。https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html#tag_05これもサポートされていません\"
。
次の2つの方法はどうですか?明示的にPOSIXに準拠していますか?
接続
'
と"
文字列$ x="abc def" $ printf x=%s\\n '"'"$x"'"' x="abc def"
8進値の使用
"
:$ x="abc def" $ printf x=\\42%s\\42\\n "$x" x="abc def"
代替は何ですか?
ベストアンサー1
はい、この動作(使用法\"
)はPOSIXのecho
どこにでもコマンドに対して定義されていません。これがechoの代わりにprintfを使用する理由の1つです。読んでくださいなぜprintfがechoより優れているのですか?。
もちろん、ここではいくつかの説明が必要です。
A\"
は実装定義それだけの場合オペランドエコ。
ここで言葉の定義はどれほど重要ですか?コマンドラインに書き込む内容は何度も読んで修正してからユーティリティにオペランドとして提供。私たちがコマンドライン引数(「単語」)と呼ぶことは、シェルによってさまざまな方法に変換されます。最後の変更の1つは「引用符の削除」です。結局これが結果だったらオペランドContainsは、\"
「echo
正しい」と見なされるすべてのタスクを実行する権利があります。
コマンドラインがオペランドとecho '\"'
ORecho "\\\""
で連結されている場合、\"
結果は実装に従って定義されます。
あなたの例x="abc def"; echo "x=\"$x\""
は次のとおりですいいえ実装によって定義されます。 echoによって受信されたオペランドはですx="abc def"
。しかし、変数の内容によって異なりますx
。
そのようなことを防ぐために可能質問オペランドが何であれ、出力はPOSIXとして定義されているため、無制限のprintfを使用する必要があります。
したがって、二重引用符を印刷する一般的な解決策は、printfコマンドのフォーマット部分にそれを置くことです。
$ printf 'x="%s"\n' "$x"
x="abc def"
一重引用符を印刷する必要がある場合は、引用符を変更するか、「引用符の終了 - 一重引用符を入れる - 引用符を再開」という一般的なトリックを使用する必要があります。
$ printf 'x='\''%s'\''\n' "$x"
x='abc def'
または:
$ printf "x='%s'"'\n' "$x"
x='abc def'
あるいは、より良い方法は、単一引用符を二重引用符で囲まれた文字列に切り替えることです。
$ printf 'x=%s\n' "'$x'"
x='abc def'
\ddd
しかし、そうです。 printf は 8 進数をサポートしているので、次のものを使用することddd
もできます。
$ printf 'x=\042%s\042\n' "$x"
x="abc def"
上記のソリューションはすべて有効なPOSIX構成です。 1つを選択してください。