bashは手動で二重引用符を入力します(https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html)状態:
有効にすると、「!」が二重引用符内に表示され、バックスラッシュでエスケープされない限り、履歴拡張が実行されます。前の「!」のバックスラッシュは削除されません。
なぜ特別なケースがありますか!
?たとえば、aをエスケープすると、$
出力にバックスラッシュが表示されません(例:echo "\$"
->$
とecho "\!"
->比較\!
)。
!
二重引用符の中にテキストだけを入れるにはどうすればよいですか?
この問題に対する1つの制限は、bash呼び出し形式を簡単に操作できないことです。私の言葉は、単一の二重引用符文字列を使用してコマンドを実行するのに止まったことです。
my-command "a string I generate in an external program that may contain !"
文字列の生成方法を制御できますが、コマンドラインから分割することはできません(たとえば、このようなものは"part1"\!"part2"
私には適していません)。
ベストアンサー1
!
isを使って文字列を印刷するいいえ引用符がない場合、または一重引用符で囲まれている場合は、C文字列またはスクリプト内で問題が発生します。
$ echo hello\!world 'hello!world' $'hello!world'
hello!world hello!world hello!world
$ echo 'echo "hello!world"' >file
$ bash file
hello!world
このスクリプト例は、histexpandがデフォルトで設定されていない特別なケースです。したがって、histexpandを無効にすると(単にorset +o histexpand
とshopt -ou histexpand
同じset +H
)、同じ効果を持ち、履歴の拡張を回避できます。
しかし、文字列を複数の部分に分割せずに(デフォルト)対話型シェルで二重引用符で囲まれた文字列を使用するように要求しています。まあ、どうですか?
$ a='!'
$ echo "hello${a}world"
hello!world
歴史についてなぜ?。
なぜ特別な場合があるのでしょうか! ?
ほとんどのASCII文字はいいえ特殊(内部"
):
$ printf '%s\n' "\a\b\c\d\e\f...\z \!\@\#\% \$a \`date\` \\"
\a\b\c\d\e\f...\z \!\@\#\% $a `date` \
関連テキストソースman bash
:文字を二重引用符で囲むと、履歴拡張が有効になっている場合は、$、`、\、!を除く引用符内のすべての文字のリテラル値が保持されます。
これは古代のシェルで二重引用符内のバックスラッシュがどのように機能するかです。POSIX仕様反映:
<バックスラッシュ>は、次のいずれかの文字が続く場合に特殊文字として扱われる場合にのみ、エスケープ文字としての特別な意味を維持する必要があります(エスケープ文字(バックスラッシュ)を参照)。
$ `` \ <改行>