help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: jobs built-in command and PROMPT_COMMAND


From: Greg Wooledge
Subject: Re: jobs built-in command and PROMPT_COMMAND
Date: Fri, 1 Oct 2021 09:22:33 -0400

On Fri, Oct 01, 2021 at 03:00:27PM +0200, Christoph Anton Mitterer wrote:
> a) In my PS1, I display the number of background jobs (\j), but only
> when there are any.
> So I have more or less something like:
> PS1='...$( [ -n "$(jobs)"] && printf '\j')...'

So many forks. :(

You can sidestep the prompt forks in most cases by using the value as
an array index, with a specially crafted array.  Here's a brief
example:

unicorn:~$ a=(zero one two three four)
unicorn:~$ PS1='${a[\j]} \h:\w\$ '
zero unicorn:~$ sleep 3 &
[1] 527769
one unicorn:~$ 
[1]+  Done                    sleep 3
zero unicorn:~$ 
zero unicorn:~$ 

You can make element zero the empty string, make element one "1 ", and
so on.  Then use ${a[\j]} with no space after it.  Or get more creative.

This is where we wish that the ternary ?: operator could return strings,
not just integers.  But since it can't, using an array of strings is the
next best thing.

Another common trick used in this situation is double-negation with the
arithmetic ! operator.  In a math context (such an array indexing), !!foo
evaluates to 0 if $foo is 0, or 1 if $foo is nonzero.  Then you can use an
array with only two elements, to get two different strings based on
whether $foo is zero or nonzero.  For example:

unicorn:~$ a=(none some)
unicorn:~$ PS1='${a[!!\j]} \h:\w\$ '
none unicorn:~$ sleep 3 &
[1] 528973
some unicorn:~$ sleep 4 &
[2] 528980
[1]   Done                    sleep 3
some unicorn:~$ 
some unicorn:~$ 
[2]+  Done                    sleep 4
none unicorn:~$ 

There are lots of things you can do with this trick.  Also, remember that
you can assign extra variables in the PROMPT_COMMAND, and then use those
variables in PS1.  All without forking.

> b) Every now and then it happens that I accidentally Ctrl-D to
> fast/often, while there are still some stopped background vi or so
> running, killing them.
> 
> AFAICS, there is no direct way in bash to prevent this (it would be
> nice if there was a feature, that ignores Ctrl-D, but *only* when there
> are running jobs).

I think you're looking for this:

              checkjobs
                      If set, bash lists the status of any stopped and running
                      jobs  before  exiting an interactive shell.  If any jobs
                      are running, this causes the exit to be deferred until a
                      second  exit is attempted without an intervening command
                      (see JOB CONTROL above).  The shell always postpones ex‐
                      iting if any jobs are stopped.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]