!
履歴拡張を使用すると、次のエラーが発生することがわかります。
$ echo "Hello!Tim"
bash: !Tim: event not found
しかし、コマンドをスクリプトに入れてスクリプトを実行しても問題ありません。
$ cat myscript
echo "Hello!Tim"
$ bash myscript
Hello!Tim
なぜそんなことですか? bashのマニュアルに理由が記載されていますか?
ベストアンサー1
はい、履歴拡張はデフォルトで対話型シェルでのみ有効になります。
シェルスクリプトに対してこれを有効にするには、次のようにします。
set -H
対話型シェルで無効にするには、次のようにします。
set +H
現在の履歴拡張が有効になっていることを確認するには、次のコードの一部の形式を使用します。
case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
シェル講座を教え始めながら、マニュアルをよく読んでみました。広く「インタラクティブシェル」が実際に何を意味するのかを確認してください。これは渦巻き模様の質問なので、いくつかの問題を解決します。
シェルには多くのオプションがあります。これらのオプションのいくつかは、シェルが制御端末で起動されると(またはなどを使用して以下を参照)、異なる方法で-i
初期化されます。
シェルのすべてのオプションは個別に変更できます。
「対話型シェル」は、正確に定義しようとすると欺瞞的な用語です。 実際にはオプション設定のコレクションにすぎません。
どの設定がシェルをインタラクティブにするかについての質問は答えられません。これは正確に同じ哲学的な質問テセウスの船。
対話型シェルを起動しましたが、履歴拡張を無効にしてflag --noediting
、set --norc
、close offexpand_aliases
などを使用している場合、シェルはどのような意味で対話型ですか?それとも、いつ相互作用が中断されますか?この質問には答えられません。
実際、「インタラクティブ」は、さまざまなシェルオプションのコレクションに便利なラベルです。また「非対話型」です。同じです。それぞれの動作を個別に変更できる動作の集まりです。
結論:シェルは、「非対話型」で始まるときと「対話型」で始まるときとは異なる動作をします。この用語を正確に定義してください。起動後とても愚かです。動作を理解するには、シェルの各個別のオプションを見てください。
私は自分の研究に加えて、このサイトに広く公開していることを忘れていました。