web-dev-qa-db-ja.com

bash履歴で一連のコマンドを実行するためのショートカットはありますか?

historyに次の簡単な例があるとします。

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

コマンドを実行したい場合777879 1つのコマンドで、このためのショートカットはありますか?私はもう試した !77 !78 !79は、これらをすべて1行に配置して実行します。

20
MrDuk

編集: fixコマンドツールfc を使用して、POSIX準拠の方法でこれを行うことができます:

fc 77 79

これにより、バッファー内のコマンド77から79でエディター(おそらくvi)が開きます。保存して終了すると(:x)、コマンドが実行されます。


それらを編集したくなくて、どのコマンドを呼び出しているかが確実にわかっている場合は、次のコマンドを使用できます。

fc -e true 77 79

これはtrueを「エディター」として使用してコマンドを編集するため、何も変更せずに終了し、コマンドはそのまま実行されます。


元の回答:

以下を使用できます。

history -p \!{77..79} | bash

これは、現在の実行環境にのみ存在するエイリアス、関数、または変数を使用していないことを前提としています。もちろん、これらは起動中の新しいシェルでは使用できません。


より良い解決策(コメントで私に思い出させてくれたMichael Hoffmanに感謝)は次のとおりです。

eval "$(history -p \!{77..79})"

evalが実際に適切である非常にまれなケースの1つです。


こちらもご覧ください:

28
Wildcard

簡単な答え:!77 !78 !79の代わりに、

  • !77; !78; !79と入力して、実行しようとしているように実行します—コマンド77、次にコマンド78、次にコマンド79を無条件に実行します。
  • !77 && !78 && !79と入力してコマンド77を実行し、成功したかどうかを確認します。そして、コマンド77が成功した場合は、コマンド78を実行します。そして、コマンド78が成功した場合は、コマンド79を実行します。

少し賢い答え(端末タイプのウィンドウの場合):

  • 次に入力するコマンドのコマンド番号を特定します。
    • これをプロンプトに含めることは可能です。これは、\!PS1に含めることによると思います。
    • または、履歴リストを見てください。最後のエントリが82 historyの場合、次のコマンドは83です。
  • 83−77 = 6を引きます。
  • !-6と入力します。これにより、コマンド77が再実行されます。
  • !-6を選択し、コピーして貼り付けます。コマンド77(./generator.sh)の再実行はコマンド83だったので、コマンド84になり、!-6はコマンド78を再実行します。
  • 必要に応じて、!-6の貼り付けを繰り返します。