shell script: How to determine if I'm in the background?
I've just spent one hell of a time trying to find the best code for a
shell script to determine if it is running in the background. I need this
for a cd backup script that will pause for keyboard input if it is run
from the command line, but should go ahead if invoked by cron.
I was surprised to realize that this turns out to be a little more
complicated than I thought it should be. After STFWing and RTFMing of the
bash man page I came up with a series of three tests (existence of an
attached tty, availability of file descriptor 0, and process group ID
being equal to the terminal process group ID for any process called by
the script), the failure of any of which would mean the we're in the
background. I think perhaps the last one should be enough, though...
The first 2 tests are clearly not enough.
I'd very much like to hear from anybody who might have faced the same
problem and learn of possibly simpler alternative solutions. I enclose
the code below.
Grateful for your comments.
#!/bin/bash
#==============================================================================
# Determine if we're running in the foreground or background
# Variables: FGBGTEST (result, "F" or "B")
# FGBGTEST_{TTY,FD0,ID} FGBGTEST_COMM
# FGBGTEST_{TTY,FD0,ID}_RES FGBGTEST_ID_{PG,TG}
#
# ----- TEST ATTACHED TTY -----
FGBGTEST_TTY_RES="$(tty)"
FGBGTEST_TTY=F ; [ "$FGBGTEST_TTY_RES" == "not a tty" ] && FGBGTEST_TTY=B
#
# ----- TEST STANDARD INPUT -----
FGBGTEST_FD0=F ; FGBGTEST_FD0_RES="input from fd0"
[ -t 0 ] || { FGBGTEST_FD0=B ; FGBGTEST_FD0_RES="no $FGBGTEST_FD0_RES" ; }
#
# ----- TEST PGID=TGID -----
FGBGTEST_COMM="ps ax o pgrp,tpgid,cmd"
FGBGTEST_ID_RES=$(eval "$FGBGTEST_COMM" | grep -e "$FGBGTEST_COMM" | grep -v -e "grep")
FGBGTEST_ID_PG=$(echo $FGBGTEST_ID_RES | sed -e "s/^\([^ ]*\).*$/\1/g")
FGBGTEST_ID_TG=$(echo $FGBGTEST_ID_RES | sed -e "s/^[^ ]* *\([^ ]*\).*$/\1/g")
FGBGTEST_ID=B ; [ $FGBGTEST_ID_PG -eq $FGBGTEST_ID_TG ] && FGBGTEST_ID=F
#
# ----- RESULT (ANY TEST WITH "B" MEANS WE'RE IN THE BACKGROUND) -----
FGBGTEST=F
[ $FGBGTEST_TTY == B -o $FGBGTEST_FD0 == B -o $FGBGTEST_ID == B ] && FGBGTEST=B
#==============================================================================
--
Carlos Sousa
http://vbc.dyndns.org/
Reply to: