web-dev-qa-db-ja.com

端末で先頭の感嘆符を無視させることはできますか? (ipythonのため、直感的に入力します)

私は人生のほとんどをIPython Shellで過ごしているため、ターミナルコマンドの先頭に感嘆符を付けるという悪い癖があります。通常、これはエラーにつながるだけですが、場合によっては、何か悪いことが発生します。端末の!機能を効果的に無効にできますか?そして、これはスクリプトに干渉する危険性がありますか?

24
Zorgoth

対話型シェルでは、デフォルトで!が履歴の展開に使用されます。シェルは!に続くテキストに一致するコマンドを探し、それを実行します。 この回答 から bashで感嘆符(!)を使用できない? に示されているように、シェルは履歴の展開を無効にすることができます。

  • バッシュ:set +H
  • Zsh:set -K

感嘆符によって駆動される履歴拡張を使用したくない場合は、これらをシェルの起動スクリプトに追加できます。

これらによって!が無視されることはありませんが、履歴からのコマンドの実行は回避されます。 !commandは、!commandが存在しないと不満を言うでしょう。

シェルスクリプトはこれらの設定の影響を受けず、非インタラクティブな構成の独自のシェルを取得します(デフォルトでは履歴の展開は含まれません)。

32
Stephen Kitt

使用しない場合!端末から、それを(私の場合)we​​raseのような、決して使用しない関数に割り当てることができます:

stty werase !

次に、入力するたびに! 、それは前の単語を消去するだけです。端末コマンドの最初に入力するだけの場合、これは効果がありません。

実際の感嘆符が必要な場合でも、CTRL-V(またはlnext文字が何であれ)を前に付けて、引用符で囲んだりエスケープしたりすることで入力できます。

通常lnext機能を使用しない場合は、代わりにlnext!に再定義する方が便利な場合があります。感嘆符を2回入力することで感嘆符を入力できます(最初の引用符は2番目の引用符を引用します)。

stty lnext !

これがどのように機能するかの詳細な説明:

lnext機能は次のとおりです。「次の文字を特別なものとして解釈しないでください。文字をそのまま入力として受け入れます」。 stty特殊文字の場合は、その特殊機能を適用せず、文字をそのまま使用してください。これには、lnext関数に割り当てられた文字が含まれます。

デフォルトのlnext文字はCTRL-Vです(ニーモニック:「逐語的」、例:次の文字を逐語的に入力)。ここでは、代わりにその関数を文字!に再割り当てします。

lnextが選択されるのは、ほとんどの場合(たとえば、次に入力する文字が通常の文字である場合)はその効果がないためです。行の先頭に誤って!を入力した場合、次の文字はほとんどの場合通常の文字であり、特別なアクションはありません。そのため、引用/エスケープ(明示的に通常の文字として扱う)しても害はありません。 !の後にaを書き込むと、意味が「write a」から同じことを行うより具体的な意味に変わります。:「write a、それ以外はすべて無視し、実行してください!」

実際の!文字を作成する場合は、そのlnext機能を使用して引用できます。したがって、!!と入力すると、単一の!が入力されます。

19

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秒後、または何か他のタイプを入力した場合はそれよりも早く)。

5