To Index

 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
 

To Index