Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a jobscount() function:

jobscount() {
   local stopped='$(jobs -s | wc -l | tr -d " ")'
   local running='$(jobs -r | wc -l | tr -d " ")'
   echo -n "${running}r/${stopped}s"

I use this function in my $PS1:

PS1=" \w $(jobscount) \$ "

The only problem is if there is no background process running or there is no stopped jobs, this function uselessly occupies $PS1 space. What I want is if either of the stopped or running value is more than 0, only then it shows up.

share|improve this question
Related question. – jw013 Mar 20 '13 at 15:40
Is the tr -d ' ' necessary? – jw013 Mar 20 '13 at 15:44
@jw013 It was for me, perhaps gnu wc is different, but on OS X each output column is separated by 7 spaces - including before the first. – Ollie Ford May 17 at 0:02

First of all, I suggest to fix your quoting. You current function does not output useful data when run stand-alone from the command prompt.

Then add a condition, using the OR list separator, before the echo:

jobscount() {
  local stopped=$(jobs -sp | wc -l)
  local running=$(jobs -rp | wc -l)
  ((running+stopped)) && echo -n "${running}r/${stopped}s "

PS1=' \w $(jobscount)\$ '

I also suggest to add -p to the jobs calls so they output only process PIDs. Otherwise a yes $'foo\nbar' & command, listed on 2 lines, would be counted twice.

share|improve this answer
Here is what happens. 1. When I remove the quotes around them, the function don't work (there is always 0r/0s). 2. After adding ((running+stopped)) &&, I get bash: ((: $(jobs -rp | wc -l): syntax error: operand expected (error token is "$(jobs -rp | wc -l)") as error when opening a new terminal. – Santosh Kumar Mar 20 '13 at 15:58
Works for me: pastebin.com/vQtW9qJC . Have you noticed that I changed both the function (removed single quotes) and the PS1 (changed double quotes to single ones)? – manatwork Mar 20 '13 at 16:09
Your solution works correct if I start bash with --norc and paste the function online. The result is total different if I put that in my .bashrc file. – Santosh Kumar Mar 20 '13 at 16:39
I tried it both directly from the command line and from my .bashrc. I had no issues. By the way, I put it at the very end of my .bashrc to make sure nothing alters the prompt after it. Do you have other PS1 assignments there? If yes, post them so we can suggest a way to make all your prompt features compatible. – manatwork Mar 20 '13 at 16:46

I'm using a variant of this to show the exit code only if it's non-zero:

PS1=' \w $(running=$(jobscount); [ "${running:-0}" -eq 0 ] || printf %s "$running") \$ '

The code inside will run every time the prompt is displayed.

share|improve this answer

Since you're running this at every prompt, it's worth saving a few external calls.

To show the count only if there are background jobs, check the numbers and don't print anything if they're all 0.

Run jobs -p to get just the process IDs, it's easier to parse reliably.

jobscount() {
  set $(jobs -rp)
  set $# $(jobs -sp)
  set $1 $(($#-1))
  if [ $1 -ne 0 ] || [ $2 -ne 0 ]; then echo "${1}r/${2}s"; fi
PS1=' \w $(jobscount) \$ '

By the way, note the quotes around the right-hand side when assigning to PS1. With double quotes, the function is called when you set the variable. You need to use single quotes, so that the value of PS1 contains the text $(jobscount) and the function is called each time the prompt is displayed.

You can save one fork by using PROMPT_COMMAND to set a variable instead of using a function's output.

set_jobscount () {
  set $(jobs -rp)
  set $# $(jobs -sp)
  set $1 $(($#-1))
  if [ $1 -ne 0 ] || [ $2 -ne 0 ]; then
PS1=' \w ${jobscount} \$ '

As usual it's simpler (if cryptic-looking) in zsh.

precmd () {
  if [[ $jobscount == r0/s0 ]]; then jobscount=; fi
setopt prompt_subst
PS1='… ${jobscount} …'
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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