スクリプトの履歴拡張は無効になっていますか?


9

次のエラーは!履歴の拡張に使用されたことが原因であると理解しています。

$ echo "Hello!Tim"
bash: !Tim: event not found

ただし、コマンドをスクリプトに入れてスクリプトを実行しても問題はありません。

$ cat myscript
echo "Hello!Tim"
$ bash myscript 
Hello!Tim

何故ですか?bashマニュアルに理由が記載されていますか?


1
いい質問だ、簡単に言えば。非常によくやりました!
ワイルドカード2017

私がここで読んでいることに基づいて:gnu.org/software/bash/manual/html_node/History-Interaction.htmlスクリプトで機能させるには、ある種のshopt修飾子を使用する必要があると思います。それはあなたが探している答えではありません。
jesse_b 2017

ユースケースは何ですか?以前の履歴を拡張する、どのようなスクリプトを実行しますか?または、スクリプトから以前のコマンドを展開しますか?
Jeff Schaller

@JeffSchaller、正の数を含むスクリプトでの数値履歴の拡張は本当に悪い考えのように聞こえますが、!!または!-2(負/相対の履歴数)または類似のユースケースを簡単に想像できました。主にそれらは他の方法でより良く解決されますが、それはシェルがどのように機能するかについて(そしてあなたが感嘆符をエスケープする必要がある/しない必要があるとき!)それでも良い質問です。
ワイルドカード2017

回答:


12

はい。履歴の拡張は、対話型シェルに対してのみデフォルトで有効になっています。

シェルスクリプトで有効にするには、次のように記述します。

set -H

対話型シェルでこれを無効にするには、次のように記述します。

set +H

履歴の拡張が現在有効になっているかどうかを判断するには、次のコードのなんらかの形式を使用します。

case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac

シェルクラスの指導を開始するにあたり、私はマニュアルを徹底的に掘り下げ、「インタラクティブシェル」が実際に何であるかを確立しようとしました。これはワールプールの質問なので、いくつかの問題を解決しましょう。

シェルには多くのオプションがあります。これらのオプションの一部は、シェルが制御端末を持っている場合(または-i、何とか何とか、以下を参照)で開始されると、さまざまな方法で初期化されます。

シェルのオプションはすべて個別に変更できます。

「インタラクティブシェル」は、正確に定義しようとする場合の誤解を招く用語です。 これは実際にはオプション設定のコレクションにすぎません。

どの設定がシェルをインタラクティブにするかどうかについての質問に答えることは不可能です。それはとんでもないことになります。それは正確に同じ哲学的問題テセウスの船

インタラクティブシェルを起動したが、履歴の展開を無効にした場合、--noeditingフラグを使用したり、設定--norcしたりexpand_aliases、オフにしたりするなどの場合、インタラクティブなシェルはどのような意味ですか?または、いつインタラクティブでなくなるのですか?これらの質問には答えられません。

真実は、「インタラクティブ」は、さまざまなシェルオプションのコレクションの便利なラベルにすぎないということです。同様に「非インタラクティブ」。同じこと; それぞれを個別に変更できる動作のコレクションです。

結論:シェルは、「対話式」で起動したときと「非対話式」で起動したときの動作が異なります。起動後にこれらの用語を正確に定義しようとするのはばかげています。シェルの個々のオプションを見て、その動作を理解してください。


自分の研究に加えて、このサイトに広範囲に投稿したことを忘れていました。


ありがとう。マニュアルでは、の「対話型シェルの場合、このオプションはデフォルトでオンになっています」とだけ表示されますset -H。「履歴の拡張は、対話型シェルに対してのみデフォルトで有効になっている」というのはおそらくあなたの推測です。
Tim

@ティム、私の答えの残りを見てください。マニュアルのその文章は非常に滑りやすいものであり、「対話型シェルとは何か」に対する答えを得ようとしています。マンページから出るのはまるでまるで話しているようなものです。それはどこにも行きません。
ワイルドカード2017

:あなたが言うことができることは、次のコードスニペットは、常に履歴展開は現在のシェルで有効になっているかどうかを示すことであるcase $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
ワイルドカード

@ティム、ところで、それが私の「推論」だとはどういう意味かわかりませんset -H。それがの明確な意味だからです。それがhistexpandオプションです。
ワイルドカード2017

1
スクリプトでこれを試しましたが、無効にされていることをスクリプトからset -o history確認した後、私もそうするまで機能しませんでしたset -o
Daniel C. Sobral
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.