web-dev-qa-db-ja.com

bashで、どうやって感嘆符をエスケープするのですか?

私はbzr commit -m "It works!"のようなことをしたいのです。 bzr commit -m "It works\!"を実行することで感嘆符をエスケープすることができます。しかし、それから私のコミットメッセージはバックスラッシュを含みます。まだバックスラッシュを無視しながら、どうやって感嘆符をエスケープするのですか?

179
Matthew

コミットメッセージの変数を拡張するのにbashに依存しないので、代わりに一重引用符を使うことができます。一重引用符で囲まれた文字列はbashによって展開されません。

bzr commit -m 'This does work!' 
150

二重引用符と感嘆符が必要な場合は、別の方法があります。

echo "It's broken"'!'

!が行末になくてもこれは機能します。

例えば:

echo "hello there"'!'" and goodbye"

おまけ:ShやBashのanytextを(sedの助けを借りて)エスケープするのにも同じようなテクニックが使えます: この答え の最初のオプションを見てください。さらに、もしあなたがbash-completionがインストールされていれば、おそらくあなたは quote()関数 availableをすでに利用可能にしているでしょう。

151
jwd

履歴展開をオフにする:

set +H

または

set +o histexpand

通常履歴展開を使用しない場合は、これらのコマンドの1つを~/.bashrcに追加できます。

Bash 4.3は 特別な場合 を追加しました:

履歴拡張文字も、二重引用符で囲まれた文字列の中で閉じている二重引用符の直前にある場合、引用符として扱われます。

65

二重引用符( ")の代わりに一重引用符( ')を使用します。一重引用符は、その中のものの解釈をすべてオフにします。

bzr commit -m 'It works!'
12
KeithB

私は今、もう1つの方法を見つけました。少なくともechoing文字列(センテンス)を感嘆符で区切って使用する方法です。これは、Bash histexpandの前後で、多かれ少なかれ最終的に実行され、コーディングには少し時間がかかります。

http://www.ascii-code.com/ にリストされているように、感嘆符の16進数は21なので、\x21をあなたの文字列の最後のecho -e $fooは、$foo自身の拡張エコー[すなわちfoo=$(echo -e "$foo")]にします。あなたが再びecho $fooしたときに得られるのは、最後に!がある文字列です。そして、どちらも変更する必要はありません。

Bash 4以降で確実に機能します。以前のバージョン、ymmv。

4
SilversleevesX