18

以下は失敗し、理由がわかりません。

$ echo "#!"

以下も同じエラーメッセージで失敗します。

$ echo "\#!"

エラーメッセージ:

-bash: !": event not found

なぜ失敗するのですか?echo代わりにどのように行う必要がありますか?

4

5 に答える 5

21

!文字は、スタイルの履歴拡張に使用されますcsh

この機能を使用しない場合、set +o histexpand(aka set +H)はこの動作をオフにします。スクリプトではオフになっていますが、インタラクティブに使用できるようになっていることがよくあります。set +o histexpandそのような場合、私の個人的な推奨事項は、あなたに追加することによってそれを永久にオフにすることです.bash_profile(または.bashrcあなたが持っていない場合.bash_profile;これは私が括弧に収めようとするよりも複雑です)。

回避策として、何らかの理由でこのレガシー機能をオフにして忘れることができない、またはしたくない場合はcsh、二重引用符の代わりに一重引用符を使用できます。もちろん、それらの異なるセマンティクスを念頭に置いてください。たとえば、引用符と変数補間を組み合わせる必要がある場合は、次のように変更できます。

echo "#!$SHELL"  # oops, history expansion breaks this

の中へ

 echo '#!'"$SHELL"

(隣接する一重引用符と二重引用符の文字列に注意してください。シェルがこれで完了すると、引用符が削除され、文字列#!が変数の値の横にSHELLスペースなしで出力されます)または他のいくつかの文字列次のような一般的な回避策

 printf '#!%s\n' "$SHELL"
于 2012-08-05T11:48:23.040 に答える
9

デフォルトでは、bashはcsh互換性のあるhistory-expansionをサポートしています。

バッシュで

echo #!

#コメントを開始するときに、改行のみを出力します。

echo "#!"

これ#は、で始まる文字列の一部です"。このような文字列は、特殊文字がないかbashによって引き続き検査されます。 !他のテキストが後に続く場合は、特殊文字です。

-bash: !": event not found

この場合、bashは、!"トークンがシェル履歴内の。で始まる前のコマンドを参照することを想定していますが、コマンドを"検出しません。すべてそれ自体では、!この動作をトリガーしません。

$ echo \# !
# !

$ echo fee ! fie
fee ! fie

ついに、

$ echo !echo

2行を生成し、最初の行はシェルによって印刷され、上記のパターンがどのように展開されるかを示します。

echo echo '# !'

2行目は、展開されたコマンドを実行した結果です。echo#!


関連項目:HistoryExpansionのBashマニュアルページ

于 2012-08-05T12:06:21.003 に答える
5
echo '#!'

基本的に、二重引用符(")、別名「弱い引用符」を使用すると、Bashは変数の置換など、文字列に対していくつかの奇妙なことを行います。シングル(')別名「強い引用符」では、文字列は文字通りに解釈されます。

引用のより詳細な説明については、たとえばここを参照してください。

于 2012-08-05T11:50:08.957 に答える
4

別の回避策は、「!」の後に余分なスペースを置くことです。:

# echo "#! "
#!
于 2016-06-10T06:27:08.443 に答える
2

私の場合、すべてのコマンドが機能しています。多分あなたはあなたの環境を指定することができます。

$ echo "\#\!"
\#\!
$ echo "#!"
echo "#"
#
$ echo "#!"
echo "#"
#
$ echo $BASH_VERSION
3.2.48(1)-release
于 2012-08-05T11:50:19.740 に答える