web-dev-qa-db-ja.com

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

Curlコマンドを使用して、パスに感嘆符(!)が含まれるhttp URLにアクセスしようとしています。例えば:

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

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

ここで何が起こっているのですか?そして感嘆符をエスケープするための適切な構文は何でしょうか?

103
netbrain

感嘆符はbashの履歴拡張の一部です。使用するには、一重引用符で囲む必要があります(例:'http://example.org/!132')またはバックスラッシュ(\)文字の前(例:"http://example.org/\!132")。

二重引用符では、免責事項の前のバックスラッシュが履歴の展開を防ぐことに注意してください。ただし、このような場合、バックスラッシュは削除されません。したがって、単一引用符を使用することをお勧めします。これにより、URLの一部としてcurlにリテラルのバックスラッシュを渡さなくなります。

111
Daniel Pittman

ダニエルの回答と同様に、set +Hと一緒に使用しない場合は、履歴の展開を完全にオフにすることもできます。

68
Chris Down

私は個人的に単一引用符を使用しますが、完全を期すために、これはURLであるため、! なので %21、例: curl -v http://example.org/%21132

18

これもできます

curl -v "http://example.org/"'!'"287s87asdjh2/somepath/someresource"
または
curl -v "http://example.org/"\!"287s87asdjh2/somepath/someresource"

これは、bashが隣接する文字列を連結するため機能します。この方法は、シェルの展開が必要なものが他にある場合に特に役立ちます。そのため、文字列全体に一重引用符を使用できません。

curl -v 'http://example.org/!'"287s87asdjh2/${basepath}/someresource"

!文字は、コマンドラインプロンプトでの履歴の展開に使用されます。
これは、プロンプトでは問題になる可能性がありますが、シェルスクリプトファイルでは問題になる可能性があります。
あなたが見ることができるように、履歴の展開は二重引用符でさえ機能します。

13
mug896

私は同じ問題に遭遇しました、そして私の簡単な解決策は変数を使用することでした:

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

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

9
Prem

Bash 4.3以降、二重引用符を使用して履歴拡張文字を引用できるようになりました。

$ bash --version
GNU bash, version 4.3...
[...]
$ echo "Hello World!"
Hello World!
3
Flimm

Windowsでgit bashを使用している人にとっては、@ DanielPittmanから受け入れられた回答が機能します。ただし、円記号(\)をスラッシュ(/)に置き換える必要があります。

たとえば、UNIXでは次のようになります。

curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS\!ZR412543s'

Windowsの場合は、次のようになります(承認ヘッダー部分のスラッシュに注目)

curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS/!ZR412543s'

0
SamuelDev