Documented in Volume 1 of the UNIX Programmers Manual.
On 4.2 systems, Bourne shell scripts start with:
#! /bin/sh
INVOCATION:
If the first character of argument zero is -, commands are read from
$HOME/.profile, if such a file exists. Commands are then read as
described below. The following flags are interpreted by the shell
when it is invoked:
-c string
If the -c flag is present, commands are read from string.
-s If the -s flag is present or if no arguments remain then commands
are read from the standard input. Shell output is written to file
descriptor 2.
-i If the -i flag is present or if the shell input and output are
attached to a terminal (as told by gtty) then this shell is interactive.
In this case the terminate signal SIGTERM (see sigvec(2)) is ignored
(so that 'kill 0' does not kill an interactive shell) and the
interrupt signal SIGINT is caught and ignored (so that wait is
interruptible). In all cases SIGQUIT is ignored by the shell.
FURTHER OPTIONS: (these flags can also be used with the set command):
-e If non interactive, exit immediately if a command fails.
-k All keyword arguments are placed in the environment for a
command, not just those that precede the command name.
-n Read commands but do not execute them.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
- Turn off the -x and -v options.
The current set of flags may be found in $-.
The following parameters are automatically set by the shell:
# The number of positional parameters in decimal.
- Options supplied to the shell on invocation or by set.
? The value returned by the last executed command in decimal.
$ The process number of this shell.
! The process number of the last background command invoked.
The following parameters are used but not set by the shell:
HOME The default argument (home directory) for the cd command.
PATH The search path for commands (see execution).
MAIL If this variable is set to the name of a mail file, the shell
informs the user of the arrival of mail in the specified file.
PS1 Primary prompt string, by default '$ '.
PS2 Secondary prompt string, by default '> '.
IFS Internal field separators, normally space, tab, and newline.
% repeat 10 /bin/sh -c "(ps; sleep 5)"
will do a ps and then wait 5 seconds. This will happen 10 times.
(Since repeat is a csh command, and since csh interprets parentheses
as part of a "for" construct, we must invoke the Bourne shell and pass
the multiple commands in parentheses. These are protected from csh by
means of the double-quotes. The -c option causes sh to use the quoted
string as a command.)
The following Bourne shell script will display the string,
"Merry Christmas" fifteen times:
#! /bin/sh # show 15 lines
COUNT=0
while test $COUNT -lt 15
do
echo "Merry Christmas."
COUNT=`expr $COUNT + 1`
done
#! /bin/sh # test for blank variables
# In Bourne shell scripts, to test for blank variables
# use the construct:
# if [ "x$FOO" = "x" ] ....
# also:
FOO=$1
case "$FOO"
in
'') echo ALL GONE;;
*) echo Something here;;
esac
From Bill Pfeifer, {ucbvax,decvax,ihnp4,allegra,uw-beaver,hplabs}
!tektronix!tekmdp!billp
The following Bourne shell script helps if you are fearful of
losing files:
"del" throws files into the waste basket. Files preceded by ","
are automagically removed after 7 days.
"undelete" pulls files out of the waste basket. If invoked
without an argument, both commands list the contents of the
waste basket.
#! /bin/sh # file backup technique
case $0 in
*del)
if test -z "$1"
then
ls -lus $HOME/.waste_basket
else
for i
do
echo -n "deleting "
tmp=`basename $i`
/bin/mv -i $i $HOME/.waste_basket/,$tmp
echo $i
done
fi;;
*undelete)
if test -z "$1"
then
ls -lus $HOME/.waste_basket
else
for i
do
echo -n "recovering "
tmp=`basename $i`
/bin/mv -i $HOME/.waste_basket/,$tmp $i
echo $i
done
fi;;
esac
From Bill Pfeifer, {ucbvax,decvax,ihnp4,allegra,uw-beaver,hplabs}
!tektronix!tekmdp!billp
The following Bourne shell script is useful if you want vi to
be more careful about overwriting files. It backs up file(s)
before editing them. Files preceded by "," are automagically
removed after 7 days.
#! /bin/sh # vi file backup technique
for i
do
if test -f $i
then
echo -n "backing up "
tmp=`basename $i`
/bin/cp -i $i $HOME/.vi_backup/,$tmp
echo $i
fi
done
/usr/ucb/vi $*
From: Dave (Maths @ Warwick University, UK)
Subject: program to repetitively display command on crt
Here follows a quite adequate display program written in /bin/sh shell
script. It could be shortened by making the syntax simpler or
removing checks for invalid syntax (half the program.)
#! /bin/sh # make a command execute repetitively
SLEEP=5
if test $# = 0
then
echo Usage: $0 [-seconds] command [command args]
exit
fi
if expr $1 : '-'[0123456789]>/dev/null
then
SLEEP=`echo $1|tail +2c`
shift
fi
if test $# = 0
then
echo Usage: $0 [-seconds] command [command args]
exit
fi
while true
do
clear
$*
sleep $SLEEP
done
PROBLEM: change a directory from a shell script so that once the
script is done, you are left in the new directory.
DISCUSSION:
When you execute the command file, a child process is set up.
The current directory *in the child process* is in fact getting changed,
but this does not effect the current directory in the parent process.
If you in fact want the command file to change the current directory in
the parent process (normally your login shell), you have to get the shell
to *not* set up a child process to execute the command file. In the
Bourne shell, this is done with the dot command, e.g.:
$ pwd
/usr
$ . shell_script include
$ pwd
/usr/include
$
This also applies if you want to set shell variables from
a command file.
The following script, when invoked by name, will cause 'more' to be
invoked and will then display the included text as if it were 'more'd'.
#! /usr/ucb/more +2
For help with UNIX, use Examplex.
UNIX classes are available at SDSU
The "example" command will give you examples of unix commands.
The commands:
apropos topic lists commands relevant to the topic
man command shows the manual for a command
.
.
.
From: ron@brl-tgr.ARPA (Ron Natalie )
Subject: Re: how many blocks are how old?
> Does anyone have any sort of utility that can be used on a filesystem
> to give you a run-down on file/block aging? I'd like to be able to
> run it on, say, /usr/spool, to let me know how many blocks are one day
> old, two days old, 30 days old, etc.
#! /bin/sh
if [ -z "$1" ]
then
echo Usage: ager days [dir]
exit 1
fi
if [ $2x = x ]
then
DIR="."
else
DIR="$2"
fi
find "$DIR" -atime +$1 -exec ls -sd {} \; | awk \
"BEGIN { sum = 0 } \
{ sum += \$1 } \
END { print sum }"
From: Ken Turkowski @ CADLINC, Menlo Park, CA
UUCP: {amd,decwrl,nsc,seismo,spar}!turtlevax!ken
ARPA: turtlevax!ken@DECWRL.ARPA
#! /bin/sh # parse command-line arguments
# ....................................................
#Hello, you hackers who enjoyed my previous standard C program,
#stdmain.c. I now bring you a standard /bin/sh script. It is
#basically an argument parser, and will accept arbitrary argument
#formats:
#
# % std -a -l -x -th0 -o outfile -
# % std -alxth0 -ooutfile
#
#and related permutations can parse as:
#
# -a
# -l
# -x
# -t with argument h0
# -o with argument outfile
# -
#
#just like stdmain.c. Convert all of your shell scripts now, so you
#don't need to remember whether the -o arument should be attached or
#not!
# Ken Turkowski @ CADLINC, Menlo Park, CA
#..........................................
#
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# std.sh
echo x - std.sh
cat > "std.sh" << '//E*O*F std.sh//'
#! /bin/sh
verbose=false
files=
for arg # Look for flags
do while true
do case $arg in
-) echo NULL FLAG; break ;;
-v*) verbose=true ;;
-o*) outfile=`expr $arg : '-.\(.*\)'` || outfile=UNKNOWN
break ;;
-*) echo Unknown flag: \"$arg\"
unkflag="$unkflag $arg"
break ;;
*) case UNKNOWN in
$outfile) outfile=$arg ;;
*) files="$files $arg" ;;
esac
break ;;
esac
arg=-`expr "$arg" : '-.\(.*\)'` || break
done
done
set x $files
shift
for arg # input file processing template
do
$verbose && echo processing file \"$arg\"
done
# The following is just for testing this standard script
echo '
Argument' analysis to $0:
echo Flags: -v = $verbose, -o = \"$outfile\"
echo Unknown flags: $unkflag
echo Files: $files
//E*O*F std.sh//
exit 0