Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: shell function in the background?

On Wed, 2014-06-25 at 08:55 -0700, Bart Schaefer wrote:
> On Jun 25, 2014 9:34 AM, "Dave Yost" <Dave@xxxxxxxx> wrote:
> > Can a shell function tell if it’s part of a pipeline running in the
> background?
> That's a tricky question because all parts of a pipeline run "in the
> background" except for the last (first, in most shells other than zsh)
> command.  

Sorry to be pedantic here, but technically, a process group (and not a
process) is put in the foreground or the background.  Similarly, the
terminal control keys (ctrl-C, ctrl-Z, ctrl-\) deliver signals to entire
process group.

> So you're really asking whether the function can tell if some
> other process downstream of it has been put in the background.  
> There's no direct way to do that.

There is.  It's a little tricky, because you cannot and must not spawn
any subprocesses to do the detection, as zsh will create new process
group for the command and change the terminal controlling process group
as well for the duration of the command.

The following is Linux-specific as it uses /proc but it seems to work
for me:

        is_foreground() {        
          local a           
          a=(${(s: :)${"$(< /proc/self/stat)"##*\) }})
          if [[ $a[3] == $a[6] ]]
            return 0
            return 1

See man proc for the magic numbers.  $a[3] is the process group  (pgid
aka pgrp) and $a[6] is the controlling terminal process group id (tpgid)

> > I want to write a shell function that traps SIGCONT and does one thing or
> another thing depending on whether the function is CONTinuing in the
> background.

Please give a shot to the above.

> I'm not sure that would work for you anyway, because the timing of delivery
> of the signal to your function and to other jobs in the pipeline is not
> deterministic.  Also, because of vagaries of job control and memory
> management, the shell trap handler for CONT might not be called immediately.

That unfortunately still applies...

> Is there some other condition related to being in the background that you
> might test instead?  I.e. why does backgrounding require different behavior?

It can be handy to display/stop displaying a progress bar for example.

> > Furthermore, it’s not clear to me why a backgrounded function thinks its
> pid is the pid of the shell that spawned it.
> That's the way the $$ variable is defined by the standard and is how all
> Unix shells have always behaved.
> If you "zmodload zsh/system" the parameter $pid becomes available and has
> the value you want.

/proc/self as used above will always use the function's executing shell
pid and obviates the need for $pid.


Messages sorted by: Reverse Date, Date, Thread, Author