Bashで感嘆符(!)を使用できませんか?

Bashで感嘆符(!)を使用できませんか?

!curlコマンドを使用して、パスに感嘆符()を持つhttp urlにアクセスしようとしています。たとえば、

curl -v "http://example.org/!287s87asdjh2/somepath/someresource"

コンソールが応答しますbash: ... event not found

どうなりますか?感嘆符をエスケープする正しい構文は何ですか?

答え1

感嘆符は次の一部です。歴史的拡張バッシュから。使用するには必須です。一重引用符で囲む(例えば'http://example.org/!132':)。

\文字の前にバックスラッシュ()を使用して、文字を直接エスケープできます(例:)"http://example.org/\!132"。しかし、感嘆符の前のバックスラッシュは記録拡張を防ぎますが、バックスラッシュはいいえこの場合、一部のシェルが除去されます。したがって、curlURLの一部としてリテラルバックスラッシュを渡さないように単一引用符を使用することをお勧めします。

答え2

Danielの答えに加えて、使用しない場合は、履歴拡張を完全にオフにすることもできます。

set +H

または

set +o histexpand

(後者はbash互換オプションの代替名zshでも機能します。)histexpandbanghist

歴史的拡張が開始された(t)cshでは、変数に空の文字列を割り当てることで無効にできます$histchars

set histchars = ''

または:

set histchars

(失敗するunset histchars

これは、次の構文を使用しても機能を複製するbashとzshにも当てはまります。

histchars=

そこに。

bash((t)cshまたはzshとは対照的に)$histchars環境で見つかった変数は無視されないため、この変数をエクスポートすると発生する可能性があることに注意してください。

答え3

個人的に私は一重引用符を使用しますが、完全性のためにURLなので、!例えば。%21curl -v http://example.org/%21132

答え4

私は同じ問題があり、簡単な解決策は変数を使用することです。

E=!  
curl -v "http://example.org/${E}287s87asdjh2/somepath/someresource"

ここでの単純さは、(1)シェルとコマンドの間に移植可能であり、(2)エスケープ構文とASCIIコードを知る必要がないことです。

関連情報