Bourne tutorial



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

and

newscript "a b c" 'd e' f g

would report 4. The command

shift $#


"erases" all parameters because it shifts them away, so it is lost forever.

$$ - Current process ID

The variable "$$" corresponds to the process ID of the current shell running the script. Since no two

processes have the same identification number, this is useful in picking a unique temporary filename. The

following script selects a unique filename, uses it, then deletes it:

#!/bin/sh

filename=/tmp/$0.$$

cat "$@" | wc -l >$filename

echo `cat $filename` lines were found

/bin/rm $filename

Click here to get file: 

CountLines0.sh

Another use of this variable is to allow one process to stop a second process. Suppose the first process

executed


echo $$ >/tmp/job.pid

A second script can kill the first one, assuming it has permissions, using

kill -HUP `cat /tmp/job.pid`

The kill command sends the signal specified to the indicated process. In the above case, the signal is the

hang-up, or HUP signal. If you logged into a system from home, and your modem lost the connection, your

shell would receive the HUP signal.

I hope you don't mind a brief discourse into signals, but these concepts are closely related, so it is worth while

to cover them together. Any professional-quality script should terminate gracefully. That is, if you kill the

script, there should be no extra files left over, and all of the processes should quit at the same time. Most

people just put all temporary files in the /tmp directory, and hope that eventually these files will be deleted.

They will be, but sometimes the temporary files are big, and can fill up the /tmp disk. Also some people don't

mind if it takes a while for a script to finish, but if it causes the system to slow down, or it is sending a lot of

error messages to the terminal, then you should stop all child processes of your script when your script is

interrupted. This is done with a trap command, which takes one string, and any number of signals as an

argument. Therefore a script that kills a second script could be written using:

#!/bin/sh

# execute a script that creates /tmp/job.pid

newscript &

trap 'kill -HUP `cat /tmp/job.pid`' 0 HUP INT TERM

Bourne Shell Tutorial

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

27 of 66


11/21/2011 12:03 PM


# continue on, waiting for the other to finish

Signals are a very crude form of inter-process communication. You can only send signals to processes running

under your user name. HUP corresponds to a hang-up, INT is an interrupt, like a control-C, and TERM is the

terminate command. You can use the numbers associated with these signals if you wish, which are 1, 2, and

15. Signal number zero is special. It indicates the script is finished. Therefore setting a trap at signal zero is a

way to make sure some commands are done at the end of the script. Signal 1, or the HUP signal, is generally

considered to be the mildest signal. Many programs use this to indicate the program should restart itself. Other

signals typically mean stop soon (15), while the strongest signal (9) cannot be trapped because it means the

process should stop immediately. Therefore if you kill a shell script with signal 9, it cannot clean up any

temporary files, even if it wanted to.

$! - ID of Background job

The previous example with $$ requires the process to create a special filename. This is not necessary if your

script launched the other script. This information is returned in the "$!" variable. It indicates the process ID of

the process executed with the ampersand, which may be called an asynchronous, or background process.

Here is the way to start a background process, do something else, and wait for the background job to finish:

#!/bin/sh

newscript &

trap "kill -TERM $!" 0 1 2 15

# do something else

wait $!


I used the numbers instead of the names of the signals. I used double quotes, so that the variable $! is

evaluated properly. I also used the wait command, which causes the shell to sleep until that process is

finished. This script will run two shell processes at the same time, yet if the user presses control-C, both

processes die. Most of the time, shell programmers don't bother with this. However, if you are running several

processes, and one never terminates (like a "tail -f)" then this sort of control is required. Another use is to

make sure a script doesn't run for a long time. You can start a command in the background, and sleep a fixed

about of time. If the background process doesn't finish by then, kill it:

#!/bin/sh

newscript &

sleep 10


kill -TERM $!

The $! variable is only changed when a job is executed with a "&" at the end. The C shell does not have an

equivalent of the $! variable. This is one of the reasons the C shell is not suitable for high-quality shell scripts.

Another reason is the C shell has a command similar to trap, but it uses one command for all signals, while

the Bourne shell allows you to perform different actions for different signals.

The wait command does not need an argument. If executed with no arguments, it waits for all processes to be

finished. You can launch several jobs at once using

#!/bin/sh

job1 &

pid=$!


job2 &

Bourne Shell Tutorial

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

28 of 66


11/21/2011 12:03 PM


Yüklə 478,18 Kb.

Dostları ilə paylaş:
1   ...   6   7   8   9   10   11   12   13   ...   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ə