1*63d4e48fSSadaf Ebrahimi#!/bin/sh 2*63d4e48fSSadaf Ebrahimi# 3*63d4e48fSSadaf Ebrahimi# This script takes a filename as input and writes the current date to the 4*63d4e48fSSadaf Ebrahimi# file. If the file already exists, it will not be overwritten unless the '-f' 5*63d4e48fSSadaf Ebrahimi# (or '--force') flag is given. 6*63d4e48fSSadaf Ebrahimi# 7*63d4e48fSSadaf Ebrahimi# This script demonstrates several types of shFlags functionality. 8*63d4e48fSSadaf Ebrahimi# - declaration of the FLAGS_HELP variable to customize the help output 9*63d4e48fSSadaf Ebrahimi# - direct calling of the flags_help() function for script controlled usage 10*63d4e48fSSadaf Ebrahimi# output 11*63d4e48fSSadaf Ebrahimi# - handling of non-flag type command-line arguments that follow the flags 12*63d4e48fSSadaf Ebrahimi# 13*63d4e48fSSadaf Ebrahimi# Try the following: 14*63d4e48fSSadaf Ebrahimi# $ ./write_date.sh now.out 15*63d4e48fSSadaf Ebrahimi# $ cat now.out 16*63d4e48fSSadaf Ebrahimi# 17*63d4e48fSSadaf Ebrahimi# $ ./write_date.sh now.out 18*63d4e48fSSadaf Ebrahimi# $ cat now.out 19*63d4e48fSSadaf Ebrahimi# 20*63d4e48fSSadaf Ebrahimi# $ ./write_date.sh -f now.out 21*63d4e48fSSadaf Ebrahimi# $ cat now.out 22*63d4e48fSSadaf Ebrahimi 23*63d4e48fSSadaf Ebrahimi# Source shFlags. 24*63d4e48fSSadaf Ebrahimi. ../shflags 25*63d4e48fSSadaf Ebrahimi 26*63d4e48fSSadaf Ebrahimi# Configure shFlags. 27*63d4e48fSSadaf EbrahimiDEFINE_boolean 'force' false 'force overwriting' 'f' 28*63d4e48fSSadaf EbrahimiFLAGS_HELP="USAGE: $0 [flags] filename" 29*63d4e48fSSadaf Ebrahimi 30*63d4e48fSSadaf Ebrahimidie() { 31*63d4e48fSSadaf Ebrahimi [ $# -gt 0 ] && echo "error: $@" 32*63d4e48fSSadaf Ebrahimi flags_help 33*63d4e48fSSadaf Ebrahimi exit 1 34*63d4e48fSSadaf Ebrahimi} 35*63d4e48fSSadaf Ebrahimi 36*63d4e48fSSadaf Ebrahimi# Parse the command-line. 37*63d4e48fSSadaf EbrahimiFLAGS "$@" || exit 1 38*63d4e48fSSadaf Ebrahimieval set -- "${FLAGS_ARGV}" 39*63d4e48fSSadaf Ebrahimi 40*63d4e48fSSadaf Ebrahimi# Check for filename on command-line. 41*63d4e48fSSadaf Ebrahimi[ $# -gt 0 ] || die 'filename missing.' 42*63d4e48fSSadaf Ebrahimifilename=$1 43*63d4e48fSSadaf Ebrahimi 44*63d4e48fSSadaf Ebrahimi# Redirect STDOUT to the file ($1). This seemingly complicated method using exec 45*63d4e48fSSadaf Ebrahimi# is used so that a potential race condition between checking for the presence 46*63d4e48fSSadaf Ebrahimi# of the file and writing to the file is mitigated. 47*63d4e48fSSadaf Ebrahimiif [ ${FLAGS_force} -eq ${FLAGS_FALSE} ] ; then 48*63d4e48fSSadaf Ebrahimi [ ! -f "${filename}" ] || die "file \"${filename}\" already exists." 49*63d4e48fSSadaf Ebrahimi # Set noclobber, redirect STDOUT to the file, first saving STDOUT to fd 4. 50*63d4e48fSSadaf Ebrahimi set -C 51*63d4e48fSSadaf Ebrahimi exec 4>&1 >"${filename}" # This fails if the file exists. 52*63d4e48fSSadaf Ebrahimielse 53*63d4e48fSSadaf Ebrahimi # Forcefully overwrite (clobber) the file. 54*63d4e48fSSadaf Ebrahimi exec 4>&1 >|"${filename}" 55*63d4e48fSSadaf Ebrahimifi 56*63d4e48fSSadaf Ebrahimi 57*63d4e48fSSadaf Ebrahimi# What time is it? 58*63d4e48fSSadaf Ebrahimidate 59*63d4e48fSSadaf Ebrahimi 60*63d4e48fSSadaf Ebrahimi# Restore STDOUT from file descriptor 4, and close fd 4. 61*63d4e48fSSadaf Ebrahimiexec 1>&4 4>&- 62*63d4e48fSSadaf Ebrahimi 63*63d4e48fSSadaf Ebrahimiecho "The current date was written to \"${filename}\"." 64