Shell Script

11 Script Control

트리스탄1234 2022. 8. 15. 05:56
728x90
반응형

1. Signal processing

Linux has signals that can be used on more than 30 systems. Among them, common signals are described in the table below.

Basically, the bash shell ignores sigquit(3) and sigterm(15) and processes SIGHUP(1) and sigint(2). When the bash shell receives a SIGHUP, it delivers the SIGHUP signal and SIGINT to all processes running in the shell. And the Linux kernel suspends the shell on the CPU at shell processing time and sends a sign signal to notify all processes started by this shell. The default behavior of shell scripts is to ignore these signals when they are received. However, when writing the shell script, you can make these received signals to be processed according to the situation.

Create a signal

In Linux, these signals of a simple key combination can stop or terminate running programs..

interrupting a process

You can create a SIGINT signal with the Ctrl + C key combination and send it to the process currently running in the shell. So let's do a test. First, let's try to terminate the shell 100 seconds before the sleep 100 command with the Ctrl + C keys while the shell is paused for 100 seconds.

$ sleep 100
^C
$

Pausing a process

Instead of killing the process with Ctrl + C, you can also stop the process. Using the Ctrl + Z key combination will stop the process currently running in the shell. This key combination creates a SIGSTP signal and passes it to the process. Let's try a test below.

$ sleep 100
^Z
[1]+ stopped sleep 100 ==>Shows hung processes. [
$ exit ==> Enter the exit command to exit the shell.
exit
There is a job that is stopped. ==> Shell warns that there is a stopped job
$ ps au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2004 0.0 0.0 17216 1416 tty1 Ss+ 08:29 0:00 /sbin/agetty --noclear tty1 linux
hyo 11246 0.0 0.0 24180 4904 pts/2 Ss 14:54 0:00 bash
hyo 16417 0.0 0.0 8568 800 pts/2 T 19:18 0:00 sleep 100
hyo 16447 0.0 0.0 38644 3208 pts/2 R+ 19:20 0:00 ps au
If you really want to end the stopped job here, you can enter the exit command once more or use the kill command as below to create and deliver a SIGKILL signal.
$ kill -9 16417
반응형

 

Trapping SIGNALS

Rather than having the shell script ignore signals, you can also make specific actions happen when specific signals are raised. I am using the trap command. How to use is as follows

trap commands signals. ==> In commands, you can define the commands to be executed when the signal defined in signale is received. Let's take a look at the example below.

#!/bin/bash
# testing output in a background job
trap "echo Haha" SIGINT SIGTERM ==> When SIGTERM and SIGINT signals are received, echo
statement is executed
echo "This is a test program"
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 10
count=$[ $count + 1 ]
done
echo "This is the end of the test program"
$./test ==> Execute the script and press Ctrl + C keys in the middle to create signt
This is a test program
Loop #1
Haha ==> It is output when you press Ctrl + C keys.
Loop #2
Loop #3
Haha
Loop #4
Loop #5
Loop #6
Loop #7
Haha
Loop #8
Loop #9
Loop #10
This is the end of the test program
$

Trapping a Script exit

Traps can also be used by using the exit signal when the script is terminated after execution. Let's take a look at the example below.

#!/bin/bash
# trapping the script exit
trap "echo byebye" EXIT ==> When the script is finished after execution, byebye is output.
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 3
count=$[ $count + 1 ]
done
if run this
$./test
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
byebye
$

Removing a trap

It is possible to operate by using the trap signal and then remove the trap at a specific location so that when a signal occurs, the shell script ignores the signal. You can use a dash (-) as shown below. Let's look at an example below

#! /bin/bash
# exit trap
trap "echo byebye" EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 3
count=$[ $count + 1]
done
trap - EXIT
echo "escape from EXIT"
If you run it, the escape from EXIT statement is displayed without outputting byebye.
$ ./test1
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
escape from EXIT
$ gedit test1

2. Running scripts in background mode

If you run the script in the foreground, nothing can be done while the script is running. So, you can run a specific script in the background.

run in the background

Running a script in the background is simple. Just add an M percent (&) sign after the script name. You can use it like the example below.

$ ./test1 &
[1] 19555
$ This is test program
Loop #1
Loop #2

 

Running multiple background jobs

$ ./test1 &
[2] 8216 ==>excute Job id and PID
Loop #1
Loop #3
hyowon@hyowon-800G5M-800G5W:~$ ./test1 & ==>run the same script
[3] 8219
hyowon@hyowon-800G5M-800G5W:~$
Loop #2
$ ps au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1483 6.4 3.2 621752 264520 tty7 Ssl+ 07:45 5:33 /usr/lib/xorg/X
root 2548 0.0 0.0 17216 1768 tty1 Ss+ 07:45 0:00 /sbin/agetty --
hyowon 6368 0.0 0.0 24080 5172 pts/2 Ss 08:42 0:00 bash
hyowon 8207 0.0 0.0 13820 2960 pts/2 S 09:10 0:00 /bin/bash ./test1
hyowon 8216 0.0 0.0 13820 2996 pts/2 S 09:10 0:00 /bin/bash ./test1
hyowon 8219 0.0 0.0 13820 3056 pts/2 S 09:10 0:00 /bin/bash ./test1
hyowon 8221 0.0 0.0 8568 676 pts/2 S 09:10 0:00 sleep 3
hyowon 8222 0.0 0.0 8568 660 pts/2 S 09:10 0:00 sleep 3
hyowon 8223 0.0 0.0 8568 664 pts/2 S 09:10 0:00 sleep 3
hyowon 8224 0.0 0.0 38644 3340 pts/2 R+ 09:10 0:00 ps au
hyowon@hyowon-800G5M-800G5W:~$ Loop #3
Loop #5
Loop #3
Loop #4
escape from EXIT
Loop #4
Loop #5
Loop #5
escape from EXIT
escape from EXIT
[1] 완료 ./test1
[2]- 완료 ./test1
[3]+ 완료 ./test1

As shown above, if the same script is executed multiple times, Job ID and PID are assigned in the background each time it is executed.

3. Running the script without a console

Scripts running in the background are tied to the session of the terminal. In other words, when you log off from the terminal or close the terminal, all scripts running in the background are also terminated. If you want the script to run in the background even when the terminal is closed or logged out, use the nohup command.

Using the nohup command prevents the SIGHUP signal from being sent to the process. This feature prevents the sighup signal from being sent to the process when the terminal is shut down, which is passed to the background process.

To execute it, use the nohup command in front of the script name as shown below.

$ nohup ./test1 &
[1] 19831
$ nohup: appending output to `nohup.out’
$
$ cat nohup.out
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
escape from EXIT

Scripts run with nohup will ignore the sighup signal generated by the terminal, and STDOUT and STDERR will also be disconnected from the terminal monitor. And it redirects STDOUT and STDERR to the nohup.out file and saves all output messages and error messages in the file.

Note that if you run multiple scripts with nohup in the same terminal, all output messages are saved in the same file, so it can be confusing.

4. Job Control

Terminating, re-executing, or stopping a stopped process using a signal is called Job Control.

viewing jobs

The way to inquire about the currently running job is to use the job command. Let's look at an example below.

# Test job control
echo "This is a test program $$"
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 10
count=$[ $count + 1 ]
done
echo "This is the end of the test program"
After running it, press Ctrl + Z to stop it.
$ ./test2
This is a job control test 11395
Loop #1
Loop #2
^Z ===>Stop that script with Ctrl + Z
[1]+ stopped ./test2
$ ./test2 > test2out & ===>excute test2 in background mode
[2] 11430
$ jobs ===>If you look up the job
[1]+ stopped ./test2 ===> + display default job
[2]- 실행중 ./test2 > test2out & ==> - display next default job
$

Below is a description of the options of the jobs command.

The following is an example showing the change of the default job.

$ ./test4
This is a test program 29075
Loop #1
Ctrl + Z
[1]+ Stopped ./test4
$ ./test4
This is a test program 29090
Loop #1 ./test4
Ctrl + Z
[2]+ Stopped
$ ./test4
This is a test program 29105
Loop #1 ./test4
Ctrl + Z
[3]+ Stopped
$ jobs -l
[1] 29075 Stopped
[2]- 29090 Stopped
[3]+ 29105 Stopped ==> 디폴트 잡
$ kill -9 29105 ==> 디폴트잡 종료
$ jobs -l
[1]- 29075 Stopped
[2]+ 29090 Stopped ==> 새로운 디폴트 잡

Restarting stopped jobs

The stopped job can be re-executed using the bg command. How to use it in the background You can use it in the form of bg job number, or in the foreground, use it in the format of fg job number.

$ bg 2
[2]+ ./test4 &
Loop #2
$ Loop #3
Loop #4
$ jobs
[1]+ Stopped ./test4
[2]- Running ./test4 &
$ Loop #6
Loop #7
Loop #8
Loop #9
Loop #10
This is the end of the test program
[2]- Done ./test4
$
forground 인 경우
$ jobs
[1]+ Stopped ./test2
$ fg 1
./test4
Loop #2
Loop #3

5. Using the NICE command

The Linux kernel allocates CPU usage time for each process's scheduling priority and processes it. Basically, all processes in Linux have the same priority. The scheduling priority available in Linux can be set to -20 (high_ ~ 20 (low). The command to change the priority is the nice command.

nice command

Let's see an example of using the nice command to adjust the priority.

$ nice -n 10 ./test2 &
==> Adjust the priority of test2 with nice command
$ ps al
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
4 0 1483 1399 20 0 648720 294892 - Ssl+ tty7 17:59 /usr/lib/xorg/Xorg -core :0 -seat seat0 -a
4 0 2548 1 20 0 17216 1680 - Ss+ tty1 0:00 /sbin/agetty --noclear tty1 linux
0 1000 6368 6363 20 0 24252 5336 wait Ss pts/2 0:00 bash
0 1000 13951 6368 30 10 13820 2992 wait SN pts/2 0:00 /bin/bash ./test2
0 1000 13952 13951 30 10 8568 756 hrtime SN pts/2 0:00 sleep 10
4 1000 13953 6368 20 0 30196 1460 - R+ pts/2 0:00 ps al
Let's increase the priority this time.
# nice -n -20 ./test2 &
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
4 0 1483 1399 20 0 651888 297896 ep_pol Ssl+ tty7 19:06 /usr/lib/xorg/Xorg -core :0 -seat seat0 -a
4 0 2548 1 20 0 17216 1680 poll_s Ss+ tty1 0:00 /sbin/agetty --noclear tty1 linux
0 1000 6368 6363 20 0 24252 5336 wait Ss pts/2 0:00 bash
0 1000 14031 6368 20 0 4504 712 wait S pts/2 0:00 sh -
4 0 14034 14031 20 0 55668 3580 wait S pts/2 0:00 su
4 0 14035 14034 20 0 22560 3876 wait S pts/2 0:00 bash
4 0 14054 14035 0 -20 13820 3048 wait S< pts/2 0:00 /bin/bash ./test2
0 0 14055 14054 0 -20 8568 652 hrtime S< pts/2 0:00 sleep 10
4 0 14057 14035 20 0 30196 1468 - R+ pts/2 0:00 ps al

Using the renice command

The nice command changes the priority when executing a script and makes it run. You must use the reenice command for running scripts. The following is an example of changing the priority using renice.

$./test2 > test2out &
$renice 10 -p 29504
==> -p displays the process ID and the number after it specifies the pid number to change

The renice command has the following restrictions.

■ Users can only adjust the priority of processes they own.

■ Users can only lower priority adjustments.

■ The root user can adjust all processes and all priorities.

6. Execute the script at a fixed time

Linux supports the scheduling function to run the script at a specific time. There are three ways to do this.

■ Using the at command

■ Using the batch command

■ Using cron tables

1) Using the at command.

You can run a script in the foreground at a specific time by using the at command, and you can also run a script in the background at a specific time using the atd command. The atd command checks the /var/spoool/at folder every 60 seconds and checks the script to be executed. ​ The command format is as follows.

at [-f filename] time

The supported formats for time and date are as follows.

■ Standard hour and minute format (10:15)

■ AM/PM format (10:15PM)

■ Specific time ( now, noon, midnight, or teatime (4PM))

■ Standard date format (MMDDYY, MM/DD/YY, or DD.MM.YY)

■ Character format (Jul 4 or Dec 25)

■ Custom Format

- Now + 25 minutes

- 10:15PM tomorrow

- 10:15 + 7 days

If jon is specified using the at command, the job is stored in a queue. There are a total of 26 queues in this queue, and the priority of each queue is different. In order of precedence, a is highest and z is lowest. Basically, all jobs are stored in a queue.

Query job output

When a job is executed in Linux, the output and error messages related to the job are not output to the monitor, and messages related to STDOUT and STDERR are sent to the user's e-mail. Let's look through an example.

#!/bin/bash
# testing the at command
time=`date +%T`
echo "This script ran at $time"
echo "This is the end of the script" >&2
$ date
Sat Nov 3 12:06:04 EST 2007
$ at -f test5 12:07
warning: commands will be executed using /bin/sh
job 6 at 2007-11-03 12:07
$ mail
Mail version 8.1.1 6/6/93. Type ? for help.
"/var/spool/mail/rich": 1 message 1 new
>N 1 rich@testbox Sat Nov 3 12:07 14/474 "Output from your job " &
Message 1:
From rich Sat Nov 3 12:07:00 2007
Delivered-To: rich@testbox
Subject: Output from your job
6
Date: Sat, 3 Nov 2007 12:07:00 -0500 (EST)
From: rich@testbox (Rich)
To: undisclosed-recipients:;
This script ran at 12:07:00
This is the end of the script
&

Query pending job information

The atq command shows a list of jobs waiting in the system. Let's take a look at the example below.

$ at -f test5 10:15
warning: commands will be executed using /bin/sh
job 7 at 2007-11-04 10:15
$ at -f test5 4PM
warning: commands will be executed using /bin/sh
job 8 at 2007-11-03 16:00
$ at -f test5 1PM tomorrow
warning: commands will be executed using /bin/sh
job 9 at 2007-11-04 13:00
$ atq
7 2007-11-04 10:15 a
8 2007-11-03 16:00 a
9 2007-11-04 13:00 a
$

Deleting Registered Jobs

You can delete the job to be canceled after inquiring the job waiting to be executed above. You can use the atrm command, and how to use it is as follows.

$ atrm 8 ==> The number after the command is the number of the job to be deleted.
$ atq
7
2007-11-04 10:15 a
9
2007-11-04 13:00 a
$

2) Using Batch Job

Batch job is similar to at, but the important difference is that when the system load is high, the batch job has a function to delay the job to be executed when the load is reduced (less than 80%). The command format is:

batch [-f filename] [time]

Using cron tables

The cron table is very useful when you need to repeatedly run a script on a specific day of the week or at a specific time on a specific day of each month. How to use is as follows.

usage phrase

min hour dayofmonth month dayofweek command

For example, if you need to run a script every day at 10:15, you can register it in the cron table as follows.

15 10 * * * command ==> where * stands for every day, every month, every week

If you need to run the script at 4:15 PM on Mondays, you can use it as follows.

15 16 * * 1 command

Here, dayof week can be expressed as a number from 0 (Sunday) to 6 (Sunday), or it can be expressed as mon and thu wed.

Here, if you look at the example of running the script at 12:00 on the 1st of every month, you can use it as follows.

00 12 1 * * command

Finally, looking at one more example, if you need to run it at 12:00 on the last day of every month, you can use the following syntax.

00 12 * * * if [ `date +%d -d tomorrow` = 01 ] ; then ; command

Creating cron tables

Each user in the system will have a cron table for each user. After registering the script in the cron table for each user, you can use and inquire. When making a query, you can use the -ㅣ option to search as follows. When registering, use the -e option to register.

$ crontab -l
no crontab for rich
$

7. Start script automatically at boot time or when user starts Bash Shell

You can set a script to be started automatically when the Linux system is booted or when the user starts the Bash Shell.

Autostart script on boot Most

Linux systems provide a local startup file to automatically run scripts. The location of these files is slightly different for each type of Linux, please refer to the table below for these locations. If you add a script to be automatically executed to these files, Linux runs the script when booting. However, when registering the script, the full path where the script exists must be entered.

[Local Startup file 위치]

Automatically run a script when running the shell

If a script is registered in the .bash profile file in the user's home directory, the script is automatically executed when the user logs in, and the .bashrc file is a file that automatically executes the script whenever the shell is executed..

728x90
반응형

'Shell Script' 카테고리의 다른 글

13 Using Graphic in Script  (1) 2022.08.17
12 Making Function  (5) 2022.08.16
10 Data Expression  (2) 2022.08.13
9. User data input processing  (1) 2022.08.13
8 Detailed Structed Shell Command  (1) 2022.08.12