Archive for October 24th, 2007

Bash Tip: Closing File Descriptors

Bash, CLI, Linux, Software Development | Posted by apokalyptik
Oct 24 2007

I recently found that you can close bash file descriptors fairly easily, it goes like this:

    exec 0>&- # close stdin
    exec 1>&- # close stdout
    exec 2>&- # close stderr

Which makes it easy to daemonize things using only bash (lets face it there are times when you JUST don’t need anything more than a simple bash script, you just need it backgrounded/daemonized). Take this example of a daemon that copies any new files created in a directory to another place on the filesystem

#!/bin/bash
 
##
## Shell Daemon For: Backup /root/
## (poorly coded, quick and dirty, example)
##
 
PIDFILE="/var/run/rootmirror.pid"
LOGFILE="/log/log/rootmirror-%Y-%m-%d.log"
NOHUP="/usr/bin/nohup"
CRONOLOG="/usr/bin/cronolog"
case $1 in
start)
    exec 0>&- # close stdin
    exec 1>&- # close stdout
    exec 2>&- # close stderr
    $NOHUP $0 run | $CRONOLOG $LOGFILE >> /dev/null &
    ;;
stop)
    /bin/kill $(cat $PIDFILE)
    ;;
run)
    pgrep -f "$0 $1" > $PIDFILE
    while [ true ]; do
        event=$(inotifywait -q -e close_write --format "%f" /root/)
        ( cp -v "/root/$event" "/var/lib/rootmirror/$event" )&
    done
    ;;
*)
    echo "$0 [ start | stop ]"
    exit 0
    ;;
esac

One especially nice detail here is that this wont hang while exiting your SSH session after you start it up (a big pet peeve of mine).