Running scripts is an inevitable situation during daily development.
When we need to run a script for a long time, we usually have two ways:
- use linux crontab to schedule tasks
- long-term script execution in terminal
The following mainly introduces the second case.
How to run a long-running script in the terminal.
Test script: test.sh
#! /bin/bash
num=1
while(( $num<=1000 ))
do
echo $num
let "num++"
sleep 5
done
Give test.sh file executable permissions
➜ chmod +x test.sh
The first method, run the script directly
➜ ./test.sh
1
2
3
The second method, run script with &
When running a job in the foreground, the terminal is occupied by the job.
You can add & after the command to run in the background.
➜ ./test.sh &
But in this way, when the script has a printout, this terminal throw will be occupied.
Therefore, we usually add redirects to write files to output files or /dev/null.
➜ ./test.sh > /dev/null 2>&1 &
➜ jobs
[1] + running ./test.sh > /dev/null 2>&1
#OR, redirect to output file
➜ ./test.sh > outfile.log 2>&1 &
[1] 7258
➜ tail -f outfile.log
1
2
...
2>&1 : means standard error is redirected to standard output. Since our standard output has been redirected to the outfile.log file, standard error is also output to the outfile.log file.
In the above two methods of running the script (test.sh) in the background, the script running in the background ends when you encounter exiting the current shell terminal.
This is because when the above two methods run the script (test.sh) in the background, the parent process of the script test.sh process is the current shell terminal process. When the current shell terminal is closed, the parent process exits and sends a hangup signal to all child processes , The child process will also exit after receiving the hangup.
The third method, using the linux nohup command
This way can really achieve long-term background running scripts, and is not affected by the terminal.
In terminal window 1, run the script using the nohup command, as follows:
➜ nohup ./test.sh > /dev/null 2>&1 &
[1] 12496
➜
➜ ps -ef | grep "test.sh" | grep -v grep
ylspirit 12496 12384 0 05:25 pts/2 00:00:00 /bin/bash ./test.sh
➜ jobs
[1] + running nohup ./test.sh > /dev/null 2>&1
➜
Close terminal 1.
Open terminal 2 and view test. sh is still running.
➜ ps -ef | grep "test.sh" | grep -v grep
ylspirit 12496 1 0 05:25 ? 00:00:00 /bin/bash ./test.sh
➜
The script test.sh can run without interruption in the background because we use nohup to ignore the hangup signal.
The fourth method, using the linux setsid command
Use the linux setsid command to run the script in a new session, which is not affected by the current shell terminal, and can also run the script in the background.
Run the script and exit the terminal.
➜ setsid ./test.sh > /dev/null 2>&1 &
[1] 2845
[1] + 2845 done setsid ./test.sh > /dev/null 2>&1
➜
➜ ps -ef | grep "test.sh" | grep -v grep
ylspirit 2849 1 0 06:13 ? 00:00:00 /bin/bash ./test.sh
➜ exit
Reopen a terminal, and you can see that the script running in the background is still there.
➜ ~ ps -ef | grep "test.sh" | grep -v grep
ylspirit 2849 1 0 06:13 ? 00:00:00 /bin/bash ./test.sh
➜ ~
shell built-in commands
During script execution, shell processes can be controlled using shell built-in commands:
- ctrl+z shortcut
Pause script - ctrl+c shortcut
End script - jobs
View the status of the tasks that have been started in the current shell environment - kill %number
Terminate script - bg %number
Script run in the background - fg %number
Switch script to foreground
“number” is the number in [] found using the jobs command, not pid
Pause script using ctrl+z shortcut
^Z
[1] + 5424 suspended ./test.sh
View jobs using jobs command
➜ jobs
[1] + suspended ./test.sh
Switch script to the foreground using the fg command
➜ fg %1
[1] - 5424 continued ./test.sh
25
26
Run script in background Using the bg command
# ctrl+z
^Z
[1] + 5424 suspended ./test.sh
➜ bg %1
[1] - 5424 continued ./test.sh
65
➜ 66
67
Terminate script
- Use kill %number command
➜ jobs
[1] + suspended ./test.sh
➜ kill %1
[1] + 6603 terminated ./test.sh
➜
- Use ctrl+c shortcut
Need to switch the script to the foreground and then use ctrl+c to terminate
➜ jobs
[1] + suspended ./test.sh
➜ fg %1
[1] + 6674 continued ./test.sh
2
3
^C
➜ jobs
➜
- Use kill pid command
➜ ./test.sh
1
2
3
4
^Z
[1] + 6833 suspended ./test.sh
➜ ps -ef | grep "test.sh" | grep -v grep
ylspirit 6833 5282 0 06:42 pts/2 00:00:00 /bin/bash ./test.sh
➜ kill -9 6833
[1] + 6833 killed ./test.sh
➜