sh -$- myscript arg1 arg2
then if you typed "sh -x newscript," myscript would also see the "-x" option.
- - Bourne Shell hyphen option
I should mention that you can set options as well as positional parameters on the same set command. That is,
you can type
set -xvua a b c
There is another special option, that isn't really an option. Instead, it solves a special problem. Suppose you
want one of these parameters to start with a hyphen? That is, suppose you have the following script, called
myscript:
#!/bin/sh
# remember the old parameters
old=$@
set a b c
# $1, $2, $3 are changed.
# now - put them back
set $old
Looks simple. But what happens if you execute this script with the following arguments:
myscript -d abc
Can you see what will happen? You will get an error, when the system reports
-d: bad option(s)
The set command thinks the "-d" argument is a shell option. The solution is to set the special hyphen-hyphen
flag. This tells the shell that the rest of the arguments are not options, but positional parameters:
#!/bin/sh
# remember the old parameters
old=$@
set a b c
# $1, $2, $3 are changed.
# now - put them back, NOTE the change
set -- $old
Other options
There are three to five additional options that can be passed to the shell, but not changed with the set
command. The number of options depends on the version of the operating system and shell. The "$-" variable
will display some of these options. I'll discuss them individually.
C - Bourne Shell command option
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
35 of 66
11/21/2011 12:03 PM
The "-c" option is used if you want the shell to execute a command. This can be useful if you normally use
the C shell. Simply type
sh -c "command"
You can test if the Bourne shell "-a" option really does cause variables to be exported by typing:
sh -ac "a=1;env"
Since env prints all environment variables, you will see that variable "a" is indeed exported, and visible to the
external program env.
S - Bourne Shell shell-session option
When you use the shell interactively, the programs reads from standard input, not from a file. If you execute
the shell with no arguments, it normally behaves like this. That is,
echo "echo a" | sh
will echo "a," while
echo "echo a" | sh myscript
will ignore standard input. The "s" option forces the shell to read standard input for commands. That is,
echo "echo a" | sh -s myscript
never executes the script myscript. Instead, it echoes "a" like the first example.
I - Bourne Shell shell-interactive option
Normally, the shell checks standard input, and checks to see if it's a terminal or a file. If it is a terminal, then it
ignores the TERMINATE signal, which is associated with signal zero in the trap command. Also
INTERRUPT is ignored. However, if the shell is reading from a file, these signals are not ignored. The "-i"
option tells the shell to not ignore these traps.
R - Bourne Shell restricted shell option
Adding the "-r" option on some Solaris systems makes the shell a restricted shell, /usr/lib/rsh. See the rsh(1M)
manual page.
P - Bourne Shell privileged shell option
The "-p" option will not change the effective user and group to the real user and group.
unset
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
36 of 66
11/21/2011 12:03 PM
Once you export a variable, it becomes an environment variable. The only way to undo this is to use the unset
command, followed by the name of the variable. Therefore
export JUNK
unset JUNK
has no effect, and the two commands cancel.
Bourne Shell: Status, Pipes and branches
Suppose you have a directory for all local executables called /usr/local/bin. Also suppose this directory is
shared by more than one machine. No problem, as long as all of the machines are the same type. However, if
some are running Solaris, and others are running SunOS, you may have problems. Some executables only
work for certain types of architectures (like the public domain program called top). You may also have
different types of UNIX systems. This can be a real problem. One solution is to create a wrapper script that
calls the appropriate script for the machine. That is, suppose you had a directory called /usr/local/SunOS
/5.4/sun4m/bin that contains executables for Solaris 2.4 (SunOS 5.4). If you move the executable from
/usr/local/bin, and place it in the proper directory, and replaced it with a shell script that contained:
#!/bin/sh
/usr/local/`uname -s`/`uname -r`/`uname -m`/bin/`basename $0` "$@"
Your problem would be solved. Sort of. There are four problems with this script, or rather say, four ways to
improve the script.
Unnecessary process execution
The first problem is that the program uname is executed three times every time this script is executed. A
simple solution is to use environment variables. That is, if the environment variables are set, then there is no
need to execute the uname program:
#!/bin/sh -a
OS=${OS=`uname -s`}
REV=${REV=`uname -r`}
ARCH=${ARCH=`uname -m`}
CMD=`basename $0`
/usr/local/$OS/$REV/$ARCH/bin/$CMD "$@"
The "-a" Bourne shell option says to mark all modified variables for auto-export. This script tests three
environment variables, and if not defined, it sets these variables. You could, therefore, set these variables
once when you log in. Thereafter, the uname program need not be executed.
$@ versus ${1+$@}
Earlier, I suggested using "$@" to pass all arguments to another shell script. This works on current SunOS and
Solaris machines, but other UNIX systems might not work. If you think about what I've said about quoting for
a while, you should begin to see something magical is happening. If you take any other variables, and
surround it by double quotes, you will get one argument. If the variable has not been set, you will get one
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
37 of 66
11/21/2011 12:03 PM