Bourne tutorial



Yüklə 478,18 Kb.
Pdf görüntüsü
səhifə9/20
tarix08.10.2017
ölçüsü478,18 Kb.
#3721
1   ...   5   6   7   8   9   10   11   12   ...   20

Then execute "chmod +x rename" and you have a new UNIX program. If you want to add some simple

syntax checking to this script, using the techniques I discussed earlier, change the last line to read:

mv ${1?"missing: original filename"} ${2?"missing new filename"}

This isn't very user friendly. If you do not specify the first argument, the script will report:

rename: 1: missing: original filename

As you can see, the missing variable, in this case "1," is reported, which is a little confusing. A second way to

handle this is to assign the positional variables to new names:

#!/bin/sh

# rename: - rename a file

# Usage: rename oldname newname

oldname=$1

newname=$2

mv ${oldname:?"missing"} ${newname:?"missing"}

Click here to get file: 

rename.sh

This will report the error as follows:

rename: oldname: missing

Notice that I had to add the colons before the question mark. Earlier I mentioned how the question mark tests

for undefined parameters, while the colon before the question mark complains about empty parameters as

well as undefined parameters. Otherwise, the mv command might have complained that it had insufficient

arguments.

The Bourne shell can have any number of parameters. However, the positional parameters variables are

limited to numbers 1 through 9. You might expect that $10 refers to the tenth argument, but it is the

equivalent of the value of the first argument with a zero appended to the end of the value. The other variable

format, ${10}, ought to work, but doesn't. The Korn shell does support the ${10} syntax, but the Bourne

shell requires work-arounds. One of these is the shift command. When this command is executed, the first

argument is moved off the list, and lost. Therefore one way to handle three arguments follows:

#!/bin/sh

arg1=$1;shift;

arg2=$1;shift;

arg3=$1;shift;

echo first three arguments are $arg1 $arg2 and $arg3

The shift command can shift more than one argument; The above example could be:

#!/bin/sh

arg1=$1

arg2=$2


arg3=$3;shift 3

echo first three arguments are $arg1 $arg2 and $arg3

This technique does make it easier to add arguments, but the error message is unfriendly. All you get is

"cannot shift" as an error. The proper way to handle syntax errors requires a better understanding of testing

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

24 of 66

11/21/2011 12:03 PM




and branching, so I will postpone this problem until later.

$0 - Scriptname

There is a special positional parameter, at location zero, that contains the name of the script. It is useful in

error reporting:

echo $0: error

will report "rename: error" when the rename script executes it. This variable is not affected by the shift

command.

$* - All positional parameters

Another work-around for the inability for specifying parameters 10 and above is the "$*" variable. The "*" is

similar to the filename meta-character, in that it matches all of the arguments. Suppose you wanted to write a

script that would move any number of files into a directory. If the first argument is the directory, the following

script would work:

#!/bin/sh

# scriptname: moveto

# usage:

# moveto directory files.....

directory=${1:?"Missing"};shift

mv $* $directory

Click here to get file: 

moveto.sh

If this script was called "moveto" then the command

moveto /tmp *

could easily move hundreds of files into the specified directory. However, if any of the files contain a space in

the name, the script would not work. There is a solution, however, using the $@ variable.

$@ - All positional parameters with spaces

The "$@" variable is very similar to the the "$*" variable. Yet, there is a subtle, but important distinction. In

both cases, all of the positional parameters, starting with $1, are listed, separated by spaces. If there are

spaces inside the variables, then "$@" retains the spaces, while "$*" does not. An example will help. Here is a

script, called EchoArgs, that echoes its arguments:

#!/bin/sh

# Scriptname: EchoArgs

# It echoes arguments

#First - make sure we are using the Berkeley style echoes

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

25 of 66


11/21/2011 12:03 PM


PATH=/usr/ucb:$path;export PATH

E="echo -n"

# echo the name of the script

${E} $0:


# now echo each argument, but put a space

# before the argument, and place single quotes

# around each argument

${E} " '${1-"?"}'"

${E} " '${2-"?"}'"

${E} " '${3-"?"}'"

${E} " '${4-"?"}'"

${E} " '${5-"?"}'"

${E} " '${6-"?"}'"

${E} " '${7-"?"}'"

echo

Click here to get file: 



EchoArgs.sh

Second, here is a script that tests the difference:

#!/bin/sh

EchoArgs $*

EchoArgs $@

EchoArgs "$*"

EchoArgs "$@"

Click here to get file: 

TestEchoArgs.sh

Now, let's execute the script with arguments that contain spaces:

./TestEcho "a b c" 'd e' f g

The script outputs the following:

./EchoArgs: 'a' 'b' 'c' 'd' 'e' 'f' 'g'

./EchoArgs: 'a' 'b' 'c' 'd' 'e' 'f' 'g'

./EchoArgs: 'a b c d e f g' '?' '?' '?' '?' '?' '?'

./EchoArgs: 'a b c' 'd e' 'f' 'g' '?' '?' '?'

As you can see, $* and $@ act the same when they are not contained in double quotes. But within double

quotes, the $* variable treats spaces within variables, and spaces between variables the same. The variable

$@ retains the spaces. Most of the time $* is fine. However, if your arguments will ever have spaces in them,

then the $@ is required.

$# - Number of parameters

The "$#" variable is equal to the number of arguments passed to the script. If newscript returned $# as a

results, then both

newscript a b c d

Bourne Shell Tutorial

http://www.grymoire.com/Unix/Sh.html

26 of 66

11/21/2011 12:03 PM




Yüklə 478,18 Kb.

Dostları ilə paylaş:
1   ...   5   6   7   8   9   10   11   12   ...   20




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©www.genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə