単純なスクリプトhello
について考えてみましょう。
#!/bin/bash
echo 'hello world!'
これをバックグラウンドで実行しようとすると、bashから次のようになります。
$ hello &
[1] 12345
$ hello world!
█ <--- Prompt is stuck here until I hit enter!
[1]+ Done
$ █ <--- Prompt back to normal
私がむしろ見たいもの:
$ hello &
[1] 12345
[1]+ hello world!
[1]+ Done
$ █ <--- Prompt normal the whole time
どうすれば動作を変更できますか?
タイミングの問題です。bashはバックグラウンドでhello
コマンドを起動し、新しいコマンドを入力するためのプロンプトを表示し、バックグラウンドコマンドが出力を出力します。次のコマンドライン(を押すだけの場合は空のコマンドライン)に入るとき Enter)、bashは、バックグラウンドジョブが終了したという通知を表示し、次に次のプロンプトを表示します。
sleep 3
で始まるスクリプトを試して、スクリプトをバックグラウンドで起動した直後に入力を開始して、フォローできるペースで何が起こっているかを確認することをお勧めします。
notify
オプションに set -b
を設定すると、バックグラウンドジョブが終了したときにbashにすぐに通知させることができます。次に、次のように表示されます。
$ set -b
$ hello &
[1] 12345
$ hello world!
[1]+ Done
この場合、Bashはプロンプトを再描画しません。バックグラウンドジョブがhello world!
を出力する前に表示されたプロンプトラインのコマンドラインをまだ編集しています。を押すと、現在の線を再描画できます Esc1Ctrl+L。コマンドredraw-current-line
をより便利なキーにバインドすることをお勧めします。たとえば、 Ctrl+L 現在の線を再描画し、 Ctrl+Alt+L 画面をクリアし、~/.inputrc
に次の行を追加します。
"\C-l": redraw-current-line
"\e\C-l": clear-screen
Bashにプロンプト行を自動的に再描画させる方法がわかりません。 Zshはデフォルトでそれを行います。