Skip to content

Instantly share code, notes, and snippets.

@amosshapira
Last active August 29, 2015 14:11
Show Gist options
  • Save amosshapira/e393c0875f5d35c844e1 to your computer and use it in GitHub Desktop.
Save amosshapira/e393c0875f5d35c844e1 to your computer and use it in GitHub Desktop.
Automatically trace output file of a background job
# The following Bash function will automatically pick up the stdout (and/or stderr,
# depending on command line options) of another Bash background job and tail it
# until the given job terminates.
#
# example usage:
# $ ls -R / &> ls.out & trc
# will run recursive "ls" in the background and redirect its output to a file
# then start "tail --pid <background job pid> -F <backgroun jobs' stdout file>"
#
# The default is to tail stdout (file descriptor "1") of the given job
# Default job spec is "%" ("current" job)
#
# Dependency:
# gnu tail available as "gtail", change to "tail" if required
# "lsof" - to fetch the file descriptors
if [ -n "$(which gtail)" ]
then
TAIL=gtail
else
TAIL=tail
fi
trc() {
trc_usage() {
echo "trc: [-e -o] [jobspec]
-e: tail stderr
-o: tail stdout (default if no flags)" >&2
}
local OPTIND f # argument processing vars
local ERR OUT JOBSPEC # options
ERR=0
OUT=0
while getopts "eoj:" f; do
case "$f" in
e)
ERR=1
;;
o)
OUT=1
;;
*)
trc_usage
return
;;
esac
done
shift $((OPTIND-1))
case "$#" in
0)
JOBSPEC=%
;;
1)
JOBSPEC="$1"
;;
*)
echo trc: Too many arguments >&2
trc_usage
return
;;
esac
if [[ $ERR == 0 ]]
then
OUT=1
fi
if [[ $OUT == 1 ]]
then
DESCS=1
fi
if [[ $ERR == 1 ]]
then
DESCS="$DESCS,2"
fi
FILENAMES="$(jobs -x lsof +w -d "$DESCS" -a -p "$JOBSPEC" -Fn0 2>/dev/null | \
sed -n -e '/^n\//s/^n//p' | sort -u)"
if [[ -z "$FILENAMES" ]]
then
echo trc: No file names found >&2
trc_usage
return
fi
jobs -x $TAIL --pid "$JOBSPEC" -F $FILENAMES
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment