
戻るまでに時間のかかるコマンドを実行し、その実行後に別のコマンドを実行したいが、事前に計画していなかったとします。
Ctrl + Zを押して送信するオプションがあることは知っていますfg && otherCommand
。ただし、これには 2 つの大きな欠陥があります。
command1 && command2
最初のコマンドが異なるコマンドの組み合わせ (または)である場合は機能しません。command1; command2
その場合、最初に送信された行の後続のコマンドは実行されないためです。- 次のコマンドを入力している間、最初のコマンドの実行は停止します。これらの厄介な 30 秒のコマンドでは、次のコマンドの入力に費やす時間が、残りの実行時間のすべてではないにしても、かなりの部分を占めます。
また、1 つのコマンドの実行中に次のコマンドを入力して送信することもできることも知っていますEnter。ただし、これにも 2 つの大きな欠陥があります。
- 最初に実行するコマンドが から読み取る場合は機能しません
stdin
。 - 最初に実行したコマンドが出力を生成する場合、入力した内容を確認することはできません。
特別な端末エミュレーターや複数の端末を使用して、1 つのコマンドの実行中にさらに多くのコマンドをキューに入れる簡単な方法はありますか?
答え1
Ctrl+を押してZすぐに を実行しますbg
。これにより、現在のコマンドがバックグラウンドで実行され続けます。その後、 を使用して現在のコマンドの後にfg && otherCommand
スケジュールを設定できます。otherCommand
これを簡単にするために、空のコマンドラインでCtrl+を押すとZシェルで実行されるように設定しました。bg
zsh では、フォアグラウンド プロセスをより迅速に拒否するにはどうすればよいでしょうか?そしてコマンドライン アプリをバックグラウンドに直接送信するにはどうすればよいですか?; bash の最新バージョンで同じことが簡単にできるかどうかは確認していません。
答え2
名前付きパイプを作成できます (これは一度実行する必要があります)。
mkfifo ~/myfifo
次に、ターミナル (ターミナル A と呼びます) から次のように言うことができます。
exec 10< ~/myfifo
パイプの読み取り側をファイル記述子 10 に割り当てるには、2 より大きい任意の数値を使用できます (そのため、別のコマンドで必要な場合は、標準入力、出力、およびエラーが引き続き使用可能になります)。
次に、別の端末 (端末 B と呼びます) から次のように言うことができます。
cat - > ~/myfifo
ターミナル A への接続を完了し、プロンプトを返します。このコマンドは、標準入力から入力した内容をパイプに書き込みます。次に、ターミナル A に次のように入力できます。
while read -u10 -r LINE; do eval "$LINE"; done
したがって、ターミナル B に入力したコマンドが実行されます。read
コマンドはファイル記述子 10 から行を読み取り、. を使用して実行しますeval
。eval
これにより、変数のエクスポートなどのシェル コマンドを実行できます。
ターミナル A が開いている限り、Ctrl + C でループを中断してコマンドを再度入力し、後でループを再開してキュー内の残りのコマンドの実行を開始できます。
fg && yourscript
exec コマンドと while コマンドはシェルスクリプトに組み込むことができるため、最初にパイプ モードを有効にするのを忘れた場合でも、Ctrl + Z を使用してパイプ モードを有効にすることができます 。
答え3
答え4
編集:私は質問を誤解していましたが、以下のテクニックは、bash スクリプトでコマンドを実行する場合 (つまり、単一の PID を持つ場合) に役立つ可能性があります。
これは、command1 が有用な出力を印刷していて、それが完了したら別のシェルで別のプロセスを開始したい場合 (つまり、command1 をバックグラウンドで実行したくない場合) に私が使用する方法です (Linux の場合)。
tail --pid=$command1_pid -f /dev/null; command2
$command1_pid
終了を待っているプロセスのPIDはどこですか
(最初にここで見つけたと思います:https://stackoverflow.com/a/41613532/1676393。その他の役立つ詳細については、こちらをご覧ください。たとえば、Darwin (macOS) で動作するバージョンなど)
ステップバイステップ:
- Ctrl+でコマンド1を停止Z
- を実行し
ps
、コマンド1に対応するプロセスを探し、そのPIDを見つける - 次に、と入力してcommand1のプロセスを再起動し
fg
、新しいシェルで上記のコマンドを実行します。
このように、古いシェルで command1 が実行されると、新しいシェルで command2 が開始されます。