DEV Community

loading...

Add background jobs to your shell prompt

chhajedji profile image chinmay chhajed ・3 min read

If you know what are background processes, you can directly proceed to see Setting the prompt.

Background processes

Whenever we execute a time taking command, we don't see the prompt till the time command finishes. For example, when we execute sleep 5s, shell will do nothing for 5 seconds but wait for the command (sleep) to finish. After 5 seconds, we will see the prompt again.

Many times, commands are not worthy to wait till they finish their processing. For example, when you are compiling a project and it takes about a minute to complete. You can run the build in background by using & at the end of command and you will be notified when background job is completed.

chinmay@CC-T480:~$ sleep 5 &
[1] 3683711
chinmay@CC-T480:~$ # After 5 seconds when we press Enter
[1]+  Done                    sleep 5
chinmay@CC-T480:~$ 
Enter fullscreen mode Exit fullscreen mode

Here what we did was put sleep 5 task in background and we got the background process ID that is 3683711. After 5 or more seconds when we enter a new command just press Enter, we see that the background job sleep 5 is completed by seeing Done sleep 5.

When building a project we can send the build process in background and while waiting for it to complete, we can do some other task. If we are using make to build a project and it takes about a minute to complete, we can use make >/dev/null 2>&1 & to build in background and not display any info/error logs while also making the shell prompt usable to give other commands.

We can also stop a process by hitting Ctrl-Z and this will also send the task in background. But in this case, task will not run in background but will be stopped until resumed by command fg in same terminal. We can see the background tasks by command jobs.

03:26:34 $ sleep 10
^Z
[1]+  Stopped                 sleep 10
03:26:36 $ jobs
[1]+  Stopped                 sleep 10
03:26:38 $ fg
sleep 10
03:26:45 $ jobs
03:26:47 $ 
Enter fullscreen mode Exit fullscreen mode

Another common use of sending task to background is while using vim or other terminal based editor. When we need to run some commands in terminal, we can just hit ctrl-z in normal mode and vim will be stopped. This way we can have our terminal prompt for running commands. When done with terminal, we can switch back to vim by fg command.

Setting the prompt

Bash prompt can be set by setting the environment variable PS1. We will update this variable to get number of background jobs in our prompt.

If we see manual page for bash, we can see that it says we can use \j to show number of jobs

\j     the number of jobs currently managed by the shell
Enter fullscreen mode Exit fullscreen mode

But most of the times we have 0 jobs running in background and displaying a 0 every time is not so tidy approach.

We can use a simple bash command to print the jobs in the prompt if they are more than 0.

[ \j -gt 0 ] && echo \j
Enter fullscreen mode Exit fullscreen mode

Here \j is the number of background jobs. What we are doing is checking if it's greater than 0, if yes, then print (echo) in the prompt else not.

A simple shell prompt including the current directory and number of background processes can be like

chinmay@CC-T480:~/Downloads$ PS1="\w\$([ \j -gt 0 ] && echo [\j]) $ "
~/Downloads $ sleep 10
^Z
[1]+  Stopped                 sleep 10
~/Downloads[1] $ sleep 15
^Z
[2]+  Stopped                 sleep 15
~/Downloads[2] $ vi

[3]+  Stopped                 vi
~/Downloads[3] $ jobs
[1]   Stopped                 sleep 10
[2]-  Stopped                 sleep 15
[3]+  Stopped                 vi
~/Downloads[3] $ fg 2
sleep 15
~/Downloads[2] $ fg 1
sleep 10
~/Downloads[1] $ fg
vi
~/Downloads $ 
Enter fullscreen mode Exit fullscreen mode

Here the number of background processes will be listed inside square brackets.

Checkout designing a minimal bash prompt.

Discussion (0)

pic
Editor guide