デフォルトでbash履歴置換がまだ有効になっているのはなぜですか?[閉まっている]


17

なぜbashがデフォルトで履歴置換をまだ有効にしているのか知っていますか?.bashrcset +H長年にわたってこの機能を取り入れてきましたが、他の人たちはまだこの機能に噛まれています。

ほぼすべての人がコピーアンドペースト機能を備えた端末を使用しておりreadlineライブラリコンパイルされたbash 履歴の置換が対話型シェルでのみデフォルトで有効になっていることを考えると、この機能使用する理由は本当にありますか?すべてのシェルでデフォルトで無効になっている場合でも、既存のスクリプトは破損しません。

履歴置換が壊れている理由がわからない場合は、これを試してください。

$ set +H # disable feature history substitution
$ echo "WTF???!?!!?"
WTF???!?!!?
$ set -H # enable feature history substitution
$ echo "WTF???!?!!?"
echo WTF???echo WTF???!?!!?
WTF???echo WTF???!?!!?

(それはすべてのスクリプトのために、デフォルトでは無効と機能を実行する前に結果を確認するために存在していた場合、明らかな特徴は、大きな問題がありますshopt -s histverify。)

こちらもご覧ください:


16
あなたは人々が履歴置換を使用しないと考えているようです。毎日使っています。私は速く従うことを見つけるls -l foo/bar/baz/weeble.cppless !$よりリコールコマンドおよび編集それ。
マーティンボナーはモニカをサポートしています

2
@MartinBonnerだから、あなたはそれを有効にすることができます。問題は、なぜそれがまだ存在するのかではなく、デフォルトで有効になっている理由についてです
バーマー

5
@Barmar:もちろん。しかし、私のポイントは、質問が前提になっているという仮定に挑戦することでした。
マーティンボナーはモニカをサポートします

5
あなたの推論に従えば、エスケープや引用を必要とするものはすべてデフォルトで無効にされるはずです。を含むURLをエスケープまたは引用する必要があるのはなぜ&ですか?を含むファイル名をエスケープまたは引用する必要があるのはなぜ?ですか?これが問題だと思う人のためのUIがあります。
-jcaron

3
!$は1日に数回使用していますが、!!かなり頻繁に使用しています。他の履歴置換をあまり使用しないことを認めなければなりませんが、何年も使用してきたシェルのデフォルトの動作が突然変更された場合、私は間違いなく不満に思うでしょう。
-jcaron

回答:


32

既にに精通している場合はbash、このシェルに特別な他の文字を処理するよりも、履歴置換パターンを扱う方があまり噛み付かない可能性があります。ただし、シェルになじみがないか、履歴置換機能を使用したことがない場合、無害な一重引用符または二重引用符で囲まれた文字列がトリガーされると、明らかに驚くでしょう。

履歴置換が有効になっている対話型シェルでは、!文字は特殊文字とほとんど同じように$特殊です。つまり\、単一引用符で囲まれた文字列でエスケープされている場合を除きます。

対照的に$を通じて、ヒストリ置換は、ここでは、文書に膨張しない、と彼らは行指向であるため、彼らはさらになります (別途スキャンしたときにその行で)置換は引用符で囲まれていないコンテキストまたは二重引用符で囲まれたコンテキスト内にあるライン上で起こります。詳細については、このバグレポートを参照してください

機能に「主要な問題」があるためではなく、シェルのコマンド履歴機能は必要ないため、非対話型シェル(スクリプト)では履歴置換は無効になっています。スクリプトでは、すべてのコマンドを保存する$HISTFILEことは意味がありません。また、履歴の置換も同様にスクリプトで信頼したいものではありません。

対話型シェルでデフォルトで有効にするかどうかは議論の余地があります(ただし、ここでの議論がbash開発者にとって重要であるとは完全に確信していませんが)。ほとんどのbashユーザーは履歴の展開で問題を抱えていると思われるようですが、あなたも私も、それらを使用するのがどれほど一般的かを知りません。

Unixシェルを使用すると、個人のニーズや好みに合わせてシェルの動作を変更できます。すべての対話型シェルの履歴置換をオフにしたい場合set +Hは、~/.bashrcファイルで使用していることを続行するか、bash開発者にデフォルトを変更するよう働きかけます(これは役立つよりも多くの人々を混乱させ混乱させるでしょう) )。


2
@MikkoRantalainenあなたは、履歴の置換は大多数のbashユーザーが使用しているものではないと考えているようです。私たちのどちらもそれがどれほど一般的かを知らないと思います。これについて強く感じている場合は、bashメーリングリストに機能/バグリクエストを送信することをお勧めします。savannah.gnu.org/mail/?group=bash
Kusalanandaを

8
正しい。問題は実際には履歴の置換に関するものではなく、Bashの二重引用符は他の言語がこの用語を使用するという意味で実際には引用符ではなく、特別な種類の括弧のように機能するという事実に関するものです。@ MikkoRantalainen、Bashが特別な方法で解釈したくないものを重引用符で囲むのを習慣にしてください!
左辺約

5
@leftaroundabout解釈する意味によって異なります。ほとんどの言語は、出力用の文字列内の制御文字を解釈します(ただし、文字列を単にシャッフルするときのシェルとは異なり、許可されています)。Perlのクォートルールは、さらにシェルの(変数補間)とほとんど同じように機能します。1言語の1は現在で働いているものを覚えておくことができれば任意のプログラミング言語と同じように、それが役立ちます。
Kusalananda

5
私のポイントは、特殊文字を使用することはめったにないということです。逆に言うと... 通常のキャラクター!として使用することはめったにありません。まだ歴史を代用するためにそれを使用する人々の数によって。
-TripeHound

3
不適切な引用に責任をそらすための-1。ほとんどの Bourneのようなシェルやスクリプトで特別なもので!ないため、人々が合理的に学ぶことができる多くのパスがあります。でBourneのようなシェルに慣れましたが、歴史的な置換最初に出会ったのは、インタラクティブシェルで簡単なワンライナーを実行しようとしたときに噛まれたからです。Bourneのようなシェルの移植およびスクリプト使用に習熟している人は、を使用するときに少なくとも1回はBourneのようなシェルに噛まれることがよくあります。bash"$my_var some text!!"$my_var!!busybox ashbashbash
mtraceur

9

履歴置換は便利です。例を挙げる

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.

2
そう?便利だと思ったら、で有効にすることができます.bashrc
バーマー


3
@Barmarを使用し、それが役に立たない場合は、無効にすることができます。対称性の仕組みがおかしい。
ホッブズ

3
@hobbs存在することがわからない場合、それを無効にする方法を知っていますか?
バーマー

2
この回答は、この機能が有用な理由の1つを説明するのに適しています。私はOPを理解したいと思う理由は、この有用性がある十分な OP(および、そのような人々は、このstackexchangeに関連する質問のいくつかを尋ねるように他の人が、)この動作は驚くべき/予想外の発見にもかかわらず、この行動を正当化します。
mtraceur

4

社会的/文化的慣性。

私が述べた特徴は、かどうかについての意見をかけることなく、その角度からお答えするつもりですので、この質問は、どのように、人間作業の問題空間であるべきデフォルトでオンにする必要が。

まず、相手を理解してもらうために、機能をオフにするために邪魔にならないようにすることについて感じる不快感は、オンにするために邪魔にならなければならない場合に感じる不快感であることを考慮してください機能。

上記を、十分なbashユーザーがこの機能を使用するという事実と組み合わせると、デフォルトでその機能を削除するか無効にするかという提案は、デフォルトでその機能があることにすでに慣れている人々からの抵抗に見舞われます。

また、bash多くの人々のためのデフォルトのシェルである(ないだけでデフォルトのログインやシステムシェル意味では、しかし、心理的な意味で)。シェルクォートの参照フレームがbashである場合、それが最初に学習したシェルである場合!、特殊なシェルキャラクターであるという事実は自然で自動的に感じられます(または、少なくとも最初に学習したとき、それは単にシェルの方法は、多くの人が受け入れる唯一の癖です。

考えてみると、多くのbashユーザーは、おそらく肯定的なコンテキストで履歴置換構文に遭遇します:最初に学習しているときに、それについて読んだり、誰かに見せたり、有用性を確認したりしますbash

それだけであなたが噛まれるだろうと、他のBourneのようなシェルの周辺世界から来る!特別なものあなたの最初に、あなたがこの機能を持っていなかったのシェルに使用している場合ので:これ負それを見るために傾斜しますあなたが急いで何かを成し遂げようとしているとき、それがあなたをねじ込むとき、それへの露出はあります。

TL; DR:ほとんどのユーザーは、おそらくデフォルトがどちらであるかをあまり気にしません。一部のユーザーはこの機能が好きであり、既にそのようになっているという強力な利点があります。それを克服します。


2
いいえ、他のシェルから来たときだけではありません。私はこの機能を何年bashも知っています!が、bash実装が壊れているためにシングルクォートが常に機能するとは限らないので、驚きに噛まれます。
フィリポス

@Philipposそれは恐ろしいことです(まあ、正確に恐ろしいことではありません...しかし、ある種の悲惨なネガティブクオリア)。これを指摘してくれてありがとう。それを統合する良い方法を考えたら、後でこの答えを再訪して、あなたのポイントを私の答えに役立てます。
mtraceur

2

デフォルトでbash履歴置換がまだ有効になっているのはなぜですか?

多くの人がそれを使用しており、インタラクティブなbashシェルを使用している人は、おそらく問題を回避するためのルールを知っている必要があり、一般にそれが痛い以上に役立つことに気付くでしょう。

私の.bashrcには長年セット+ Hが含まれていましたが、この機能にまだ噛まれている人もいます。

したがって、これは使用しない機能であり、大多数のユーザーが使用しないという意味ではありません。デフォルトの変更を申し立てることはできますが、A)をにする人の割合、B)自分のやり方を好む人の割合を調べる必要があります。いる人や嫌いな人は、おそらくすでに無効になっています。変更すると、新しいコンピューターでアカウントを取得するときに役立ちます。その人々のケアとは、それが好きです、彼らが将来的に取得し、彼らが使用するすべてのコンピュータとすべてのアカウントにその設定を更新しなければなりません。

ほぼ全員がコピーアンドペースト機能を備えた端末を使用していることを考えると

私の意見では不格好なオプション...

この機能を使用する理由は本当にありますか?すべてのシェルでデフォルトで無効にされている場合でも、既存のスクリプトは破損しません。

はい、人々はそれが便利だと感じています。以前はチャンネルを立ち上げて変更することができたのに、リモートコントロールを使用するのはどのような用途ですか?

(すべてのスクリプトでデフォルトで無効になっており、実行前に結果を検証する機能が存在する場合、明らかに機能に大きな問題があります:shopt -s histverify。)

履歴は実際にはスクリプトでは意味がありませんが、さらに重要なことに、セキュリティの問題を引き起こす可能性があります。あなたの場合、一重引用符を使用することで問題を回避できます。これが私にとって問題を引き起こしたことを覚えていないので、それが「主要な問題」を持っているとどのように言うことができるかわかりません。これはあなたにとって実際の問題を引き起こしましたか、それとも新しいコンピューターでデフォルトを設定しなければならないことに悩まされていましたか?

あなたが実際にお金を稼ぎたいなら、これでエスケープするか、単一引用符を使用する必要があることとどのように違うのかわかりません:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it

2
関連する質問(右の列)を参照してください。ほとんどの質問は偶然この機能にぶつかり、シェルが壊れていると仮定しています。私は誤って出力を引き起こす文字シーケンスを誤って使用したという事実のため、私はずっと前にこの機能について個人的に学びました。私は救われていただろうがshopt -s histverifyそれはデフォルトではオンになっていない。さらに、エラーメッセージが不可解(「イベントが見つかりません」)であり、それをトリガーする文字シーケンスがグーグル検索が難しいため、原因を自分で理解することは非常に困難です。
ミッコランタライネン

1
$特別な内部のような「普遍的な」シェル構文機能"..."はシェルについて最初に学ぶものの1つであるため、人々はこの機能に本当に噛まれます。一方、!特別な内部"..."(ただし、インタラクティブモードのみ)の事実はあまり知られていません。すぐに/目立つように教えられておらず、- bash特定です。また、Bourneのようなシェルは、ほとんどの場合、スクリプト内のテキストとインタラクティブなシェル上のテキストの対称性を持っているため、通常は、一方から他方へコペーストして同じように動作させることができます。唯一の例外の1つ。
mtraceur

1
私はそれが単一引用符エスケープまたは使用するよりも何が違うのですかが表示されないための真のzshシングル引用したときに、!いつもは、なくのために働くbashの実装が生成する場合には、予期しない結果が。あなたは、私たちはルールを知っているべきだと言います、まあ、あなたはそのリンクされたルールを知っていましたか?
フィリポス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.