私は人生のほとんどをIPython Shellで過ごしているため、ターミナルコマンドの先頭に感嘆符を付けるという悪い癖があります。通常、これはエラーにつながるだけですが、場合によっては、何か悪いことが発生します。端末の!
機能を効果的に無効にできますか?そして、これはスクリプトに干渉する危険性がありますか?
対話型シェルでは、デフォルトで!
が履歴の展開に使用されます。シェルは!
に続くテキストに一致するコマンドを探し、それを実行します。 この回答 から bashで感嘆符(!)を使用できない? に示されているように、シェルは履歴の展開を無効にすることができます。
set +H
set -K
感嘆符によって駆動される履歴拡張を使用したくない場合は、これらをシェルの起動スクリプトに追加できます。
これらによって!
が無視されることはありませんが、履歴からのコマンドの実行は回避されます。 !command
は、!command
が存在しないと不満を言うでしょう。
シェルスクリプトはこれらの設定の影響を受けず、非インタラクティブな構成の独自のシェルを取得します(デフォルトでは履歴の展開は含まれません)。
使用しない場合!端末から、それを(私の場合)weraseのような、決して使用しない関数に割り当てることができます:
stty werase !
次に、入力するたびに! 、それは前の単語を消去するだけです。端末コマンドの最初に入力するだけの場合、これは効果がありません。
実際の感嘆符が必要な場合でも、CTRL-V(またはlnext
文字が何であれ)を前に付けて、引用符で囲んだりエスケープしたりすることで入力できます。
通常lnext
機能を使用しない場合は、代わりにlnext
を!
に再定義する方が便利な場合があります。感嘆符を2回入力することで感嘆符を入力できます(最初の引用符は2番目の引用符を引用します)。
stty lnext !
これがどのように機能するかの詳細な説明:
lnext
機能は次のとおりです。「次の文字を特別なものとして解釈しないでください。文字をそのまま入力として受け入れます」。 stty特殊文字の場合は、その特殊機能を適用せず、文字をそのまま使用してください。これには、lnext
関数に割り当てられた文字が含まれます。
デフォルトのlnext
文字はCTRL-Vです(ニーモニック:「逐語的」、例:次の文字を逐語的に入力)。ここでは、代わりにその関数を文字!
に再割り当てします。
lnext
が選択されるのは、ほとんどの場合(たとえば、次に入力する文字が通常の文字である場合)はその効果がないためです。行の先頭に誤って!
を入力した場合、次の文字はほとんどの場合通常の文字であり、特別なアクションはありません。そのため、引用/エスケープ(明示的に通常の文字として扱う)しても害はありません。 !
の後にa
を書き込むと、意味が「write a
」から同じことを行うより具体的な意味に変わります。:「write a
、それ以外はすべて無視し、実行してください!」
実際の!
文字を作成する場合は、そのlnext
機能を使用して引用できます。したがって、!!
と入力すると、単一の!
が入力されます。
zsh
シェルを使用している場合は、~/.zshrc
:
zmodload zsh/zselect
bang() {
zle self-insert
if [[ $CONTEXT = start && $LBUFFER =~ '^!+$' ]]; then
local -a old_region_highlight=($region_highlight)
region_highlight+=("0 $CURSOR fg=red,bg=white,bold,standout")
zle -R 'Will you please stop?!'
zselect -t 100 -r 0 < /dev/tty
region_highlight=($old_region_highlight)
LBUFFER=
fi
}
zle -N bang
bindkey '!' bang
したがって、1つ以上の!
編集バッファーの先頭で、それらを赤で強調表示し、メッセージを表示して削除します(1秒後、または何か他のタイプを入力した場合はそれよりも早く)。