Bashで動作する保存されたスクリプトから「Echo!!」を聞くことはできません。

Bashで動作する保存されたスクリプトから「Echo!!」を聞くことはできません。

簡単に書くつもりです。以前に(誤って)英語以外のレイアウトで書かれたコマンドを取得し、すべてを正しいシンボルに変換して実行するスクリプト。私はそれを使用していますヘビーストライク 4.3.11

私の現在のコードは次のとおりです(私はプログラマーではなく、一般的な使いやすさのためにこれを学びようとしています)。

echo !! | sed -e "y/first-set-of-symbols/second-set-of-symbols/" | bash

問題は、ファイルからスクリプトを実行すると、次のような結果が出ることです。bash:行1:!!:コマンドが見つかりません「しかし、コマンド全体をコピーして貼り付けると、期待どおりに機能します。スクリプトファイルのエコー部分を「echo test-command」のように変更すると、スクリプトを実行したときと同じ動作が行われます。

誰かが私が理由を理解するのを助けることができますか?ここではスクリプトが動作しませんか?それが必要なのでしょうか?

私はまた、私がやろうとしていることをより良い/より効率的な/よりエレガントな方法で行う方法についてのどんな提案でも開いています。

(私はtrを使用していません。Unicodeでは動作しないようです。少なくとも私にはまったく動作しません。)

答え1

この!!ショートカットは対話型セッションでのみ機能します。他のすべてのケースでは、一対のリテラル文字として扱われます。

どうなるかを見るには、これをコピーして貼り付けてください。

cat >/tmp/pling.sh <<x
#!/bin/bash
echo hello, world
echo you said !!
x

# Now make the file executable
chmod a+x /tmp/pling.sh

# Now run it
/tmp/pling.sh

答え2

コマンド履歴はスクリプトでは有効になりません。有効になっていても、スクリプトはそれを呼び出した対話型シェルの履歴にアクセスできません。

スクリプトを書くのではなく、tiを関数にしてください.bashrc

evalまた、別々のbashインスタンスでコマンドを実行する代わりに、組み込みコマンドを使用して同じコンテキスト(特に同じシェル変数)で実行する必要があります。

履歴拡張方法は、単純なコマンドでのみ機能します。特殊文字を含むコマンドは、構文エラーやその他の予期しない動作を引き起こします。組み込み関数を使用してfcプログラムで履歴にアクセスします。

reexecute () {
  eval "$(fc -l -1 | sed …)"
}

関連情報