Instead of waiting for slow commands to finish, I'd like to run them in the background. However, when they finish running and print to stdout, I get (where █
represents my cursor) this:
$ slowcmd &
$ cmd_output
█
- There is no prompt string before my cursor.
- and
slowcmd
can be any slow command (For the stuff I've tried, I just saidalias slowcmd='sleep 1 && echo cmd_output'
)
Whereas I'd like something like this:
$ slowcmd && redrawPromptString &
$ cmd_output
$ █
Where after the command's output, a new Prompt String is printed out for me.
What I can do to make redrawPromptString
do what I want? I've tried clear
, kill $$
to send a ^C
to the terminal, and finally printf "^C"
(of course that didn't work). I'm running bash. (GNU bash, version 3.2.57).
Best Answer
Use
redraw-current-line
function ofbind
builtin. First check if it's already bound maybe:I've never seen it bound by default, so you will probably need to bind it. Pick a key combination, let's say Ctrl+Y. Check if it's already taken:
Empty output means the combination is unused. If so, let's bind
redraw-current-line
to it:Now, whenever a background process messes with your command line, hit Ctrl+Y. Then your prompt will be redrawn along with whatever command you have just partially typed (if any), so you can continue as if nothing happened.
To make the binding permanent you could add the above command to your
~/.bashrc
, but don't. The right approach is to modify~/.inputrc
(for user) or/etc/inputrc
(system-wide). This way any program that usesreadline(3)
library will obey. The line to add to either file looks like this:But if you create
~/.inputrc
anew, make sure its first line says$include /etc/inputrc
. This is because up to this pointreadline
has used/etc/inputrc
and maybe your workflow relies on what's in this file. From now on, the library will use your~/.inputrc
instead; the line$include /etc/inputrc
makes it parse the system-wide file as well.For more info see
help bind
andman 3 readline
.