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