10

Consider the simple script hello:

#!/bin/bash

echo 'hello world!'

Now from bash if I try to run this in the background:

$ hello &
[1] 12345
$ hello world!
█ <--- prompt is stuck here until I hit enter!
[1]+ Done
$ █ <--- prompt back to normal

What I would rather see:

$ hello &
[1] 12345
[1]+ hello world!
[1]+ Done
$ █ <--- prompt normal the whole time

How can I change the behavior?

13

It's a matter of timing: bash launches the hello command in the background, then it displays a prompt to let you enter a new command, then the background command prints some output. When you enter the next command line (an empty command line, if you just press Enter), bash displays the notification that the background job has finished, then the next prompt.

You may want to experiment with a script that starts with sleep 3 and start typing just after launching the script in the background, to see what's happening at a pace you can follow.

You can make bash notify you immediately when a background job terminates by setting the notify option with set -b. Then you'll see:

$ set -b
$ hello &
[1] 12345
$ hello world!
[1]+ Done

Bash doesn't redraw the prompt in this case. You're still editing a command line on the prompt line that appeared before the background job printed hello world!. You can redraw the current line by pressing Esc 1 Ctrl+L. You may want to bind the command redraw-current-line to a more convenient key; for example, to have Ctrl+L redraw the current line and Ctrl+Alt+L clear the screen, add the following lines to your ~/.inputrc:

"\C-l": redraw-current-line
"\e\C-l": clear-screen

I don't know of a way to make bash redraw the prompt line automatically. Zsh does it by default.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.