亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Linux?Shell任務(wù)控制的實(shí)現(xiàn)示例

 更新時(shí)間:2024年01月09日 10:55:42   作者:恒友成  
本文主要介紹了Linux?Shell任務(wù)控制的實(shí)現(xiàn)示例,包括向腳本發(fā)送信號(hào)、修改腳本的優(yōu)先級(jí)以及在腳本運(yùn)行時(shí)從暫停切換到運(yùn)行模式,感興趣的可以了解一下

通常情況下運(yùn)行腳本的方式就是以實(shí)時(shí)模式在命令行界面上直接運(yùn)行,除此之外還有很多其他的運(yùn)行腳本的方式,如后臺(tái)運(yùn)行,定時(shí)運(yùn)行等等。除運(yùn)行方式外,還可以對(duì)腳本程序的運(yùn)行進(jìn)行控制,包括向腳本發(fā)送信號(hào)、修改腳本的優(yōu)先級(jí)以及在腳本運(yùn)行時(shí)從暫停切換到運(yùn)行模式。

1)信號(hào)

Linux利用信號(hào)與運(yùn)行在系統(tǒng)中的進(jìn)程進(jìn)行通信,可以通過對(duì)腳本進(jìn)行編程,使其在收到特定信號(hào)時(shí)執(zhí)行特定命令。

信號(hào)描述
1SIGHUP掛起進(jìn)程
2SIGINT終止進(jìn)程
3SIGQUIT停止進(jìn)程
9SIGKILL無條件終止進(jìn)程
15SIGTERM盡可能終止進(jìn)程
17SIGSTOP無條件停止進(jìn)程,但不是終止進(jìn)程
18SIGTSTP停止或暫停進(jìn)程,但不終止進(jìn)程
19SIGCONT繼續(xù)運(yùn)行停止的進(jìn)程

默認(rèn)情況下,交互式shell終端本身的進(jìn)程會(huì)忽略收到的任何 SIGQUIT (3) 和 SIGTERM (5) 信號(hào),因此其不會(huì)被意外終止。

如果bash shell收到了 SIGHUP 信號(hào),比如當(dāng)要離開一個(gè)交互式shell時(shí),它就會(huì)退出。但在退出之前,它會(huì)將 SIGHUP 信號(hào)傳給所有由該shell所啟動(dòng)的進(jìn)程。

通過鍵盤生成信號(hào)

Ctrl+C組合鍵會(huì)生成 SIGINT 信號(hào),并將其發(fā)送給當(dāng)前在shell中運(yùn)行的所有進(jìn)程。

Ctrl+Z組合鍵會(huì)生成一個(gè) SIGTSTP 信號(hào),停止shell中運(yùn)行的任何進(jìn)程。這樣可以在進(jìn)程運(yùn)行期間暫停進(jìn)程,而無需終止它。這樣可以在不終止進(jìn)程的情況下使用戶深入腳本內(nèi)部一窺究竟。

停止進(jìn)程會(huì)讓程序繼續(xù)保留在內(nèi)存中,并能從上次停止的位置繼續(xù)運(yùn)行。

要想啟動(dòng)停止的進(jìn)程可以使用fgbg在前臺(tái)和后臺(tái)啟動(dòng)

$ sleep 100
# ^Z
# [1]+  已停止               sleep 100

方括號(hào)中的數(shù)字是shell分配的作業(yè)號(hào) (job number)。

可以用 ps 命令來查看已停止的作業(yè)。

$ ps -l
# F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
# 0 T  1001  116014  113239  0  80   0 -  2791 do_sig pts/0    00:00:00 sleep

在 S 列中(進(jìn)程狀態(tài)), ps 命令將已停止作業(yè)的狀態(tài)為顯示為 T 。這說明命令要么被跟蹤,要么被停止了。

在有已停止作業(yè)存在的情況下退出shell會(huì)終止已停止作業(yè)。

trap 命令捕獲信號(hào)

trap命令允許用戶來指定shell腳本要監(jiān)視并從shell中攔截的Linux信號(hào)。當(dāng)腳本收到了 trap 命令中列出的信號(hào),會(huì)執(zhí)行用戶指定的操作。

trap命令的格式:

trap commands signals

示例,

#!/bin/bash

trap "echo 'Ctrl-C Pressed'" SIGINT

echo This is a test

c=1
while [ $c -le 5 ]
do
    echo "Loop #$c"
    sleep 1
    c=$[ $c + 1 ]
done

執(zhí)行,

$ ./test.sh 
# This is a test
# Loop #1
# Loop #2
# ^CCtrl-C Pressed
# Loop #3
# Loop #4
# Loop #5

上面腳本中trap 命令會(huì)在每次檢測(cè)到 SIGINT 信號(hào)時(shí)捕獲這些信號(hào),阻止用戶用bash shell組合鍵Ctrl+C來停止程序。

除了在shell腳本中捕獲中斷信號(hào),也可以在shell腳本退出時(shí)捕獲退出信號(hào)EXIT。以在shell完成任務(wù)時(shí)執(zhí)行特定的命令。

#!/bin/bash

trap "echo 'Running Finished.'" EXIT

echo This is a test

c=1
while [ $c -le 5 ]
do
    echo "Loop #$c"
    sleep 1
    c=$[ $c + 1 ]
done

執(zhí)行,

$ ./test.sh 
# This is a test
# Loop #1
# Loop #2
# Loop #3
# Loop #4
# Loop #5
# Running Finished.

要修改移除捕獲,在腳本中的不同位置進(jìn)行不同的捕獲處理,只需重新使用帶有新選項(xiàng)的 trap 命令

#!/bin/bash

trap "echo 'Caught SIGINT'" SIGINT

echo "This is first caughtion of SIGINT"

c=1
while [ $c -le 3 ]
do
    echo "Loop #$c"
    sleep 1
    c=$[ $c + 1 ]
done

trap "echo 'Redefine SIGINT '" SIGINT
echo "This is Mutated caughtion of SIGINT"
sleep 10

執(zhí)行,

$ ./test.sh
# This is first caughtion of SIGINT
# Loop #1
# ^CCaught SIGINT
# Loop #2
# Loop #3
# This is Mutated caughtion of SIGINT
# ^CRedefine SIGINT

修改了信號(hào)捕獲之后,腳本處理信號(hào)的方式就會(huì)發(fā)生變化。如果一個(gè)信號(hào)是在捕獲被修改前接收到的,那么腳本仍然會(huì)根據(jù)最初的 trap 命令進(jìn)行處理。

想刪除已設(shè)置好的捕獲,只需要在 trap 命令與希望恢復(fù)默認(rèn)行為的信號(hào)列表之間加上兩個(gè)破折號(hào)即可。

trap -- SIGINT

2)在后臺(tái)運(yùn)行腳本

直接在命令行界面運(yùn)行shell腳本,腳本在運(yùn)行時(shí),沒法在終端會(huì)話里做別的事情。

在用 ps 命令時(shí),會(huì)看到運(yùn)行在Linux系統(tǒng)上的一系列不同進(jìn)程。這些進(jìn)程顯然都不是運(yùn)行在當(dāng)前的終端顯示器上的,這種模式稱為在后臺(tái)運(yùn)行進(jìn)程。在后臺(tái)模式中,進(jìn)程運(yùn)行時(shí)不會(huì)和終端會(huì)話上的 STDIN 、 STDOUT 以及 STDERR 關(guān)聯(lián)。

命令后加 & 符

前面介紹過,以后臺(tái)模式運(yùn)行shell腳本,只要在命令后加個(gè) & 符就行。

$ ./test.sh &
# [1] 118347

方括號(hào)中的數(shù)字是shell分配給后臺(tái)進(jìn)程的作業(yè)號(hào)。下一個(gè)數(shù)是Linux系統(tǒng)分配給進(jìn)程的進(jìn)程ID(PID)。當(dāng)后臺(tái)進(jìn)程結(jié)束時(shí),它會(huì)在終端上顯示出一條消息:

# [1]+  已完成               ./test.sh

通過./test.sh &命令將腳本放在后臺(tái)運(yùn)行還存在兩個(gè)問題,一個(gè)是當(dāng)前bash shell終端關(guān)閉時(shí)后臺(tái)運(yùn)行中的進(jìn)程仍然會(huì)被終止,第二個(gè)時(shí)放入后臺(tái)的腳本輸出仍然會(huì)顯示在顯示器上,會(huì)與新輸入命令的輸入混淆在一起

運(yùn)行多個(gè)后臺(tái)作業(yè)時(shí),通過 ps 命令,可以看到
所有腳本處于運(yùn)行狀態(tài)。

 ./test.sh &
 ./test.sh &
$ ps
# F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
# 0 S  1001  118703  118697  0  80   0 -  3178 do_wai pts/3    00:00:00 test.sh
# 0 S  1001  118707  118703  0  80   0 -  2791 hrtime pts/3    00:00:00 sleep
# 0 S  1001  118714  118697  0  80   0 -  3178 do_wai pts/3    00:00:00 test.sh
# 0 S  1001  118718  118714  0  80   0 -  2791 hrtime pts/3    00:00:00 sleep

使用nohub命令

當(dāng)需要在終端會(huì)話中啟動(dòng)shell腳本,然后讓腳本一直以后臺(tái)模式運(yùn)行到結(jié)束,且終端會(huì)話退出仍不影響腳本運(yùn)行時(shí),前面介紹的&符號(hào)的方式就不適合了,這時(shí)需要使用nohub命令。

nohup 命令運(yùn)行的后臺(tái)任務(wù)會(huì)阻斷所有發(fā)送給該進(jìn)程的 SIGHUP信號(hào),這可以在退出終端會(huì)話時(shí)阻止進(jìn)程退出。

nohup 命令的格式:

$ nohup ./test.sh &
# [1] 119226
# nohup: 忽略輸入并把輸出追加到'nohup.out'

由于 nohup 命令會(huì)解除終端與進(jìn)程的關(guān)聯(lián),進(jìn)程也就不再同 STDOUT 和 STDERR 聯(lián)系在一起。
為了保存該命令產(chǎn)生的輸出, nohup 命令會(huì)自動(dòng)將 STDOUT 和 STDERR 的消息重定向到一個(gè)名為
nohup.out的文件中。值得注意的是,當(dāng)在同個(gè)目錄同時(shí)啟動(dòng)多個(gè)nohub命令時(shí),會(huì)輸出到同一個(gè)nohub.out文件中。

3)作業(yè)控制

jobs 命令可以查看分配給shell的作業(yè)。

通過test.sh啟動(dòng)兩個(gè)作業(yè),

$ ./test.sh
# This is first caughtion of SIGINT
# Loop #1
# ^Z
# [1]+  已停止
$ ./test.sh > test.out &
# [2] 119480
$ jobs
# [1]+  已停止               ./test.sh
# [2]-  運(yùn)行中               ./test.sh > test.out &

要想查看作業(yè)的PID,可以在 jobs 命令中加入 -l 選項(xiàng)。jobs 命令輸出中的加號(hào)和減號(hào)的含義是帶加號(hào)的作業(yè)會(huì)被當(dāng)做默認(rèn)作業(yè),在使用作業(yè)控制命令時(shí),如果未在命令行指定任何作業(yè)號(hào),該作業(yè)會(huì)被當(dāng)成作業(yè)控制命令的操作對(duì)象。當(dāng)前的默認(rèn)作業(yè)完成處理后,帶減號(hào)的作業(yè)成為下一個(gè)默認(rèn)作業(yè)。任何時(shí)候都只有一個(gè)帶加
號(hào)的作業(yè)和一個(gè)帶減號(hào)的作業(yè)。在前面介紹的重新啟動(dòng)停止的作業(yè)的命令fg/bg不帶參數(shù)時(shí),啟動(dòng)的就是+號(hào)對(duì)應(yīng)的作業(yè)。

更多jobs命令的選項(xiàng)參數(shù),可以通過命令jobs --help查看。

4)調(diào)度優(yōu)先級(jí)

調(diào)度優(yōu)先級(jí)決定了內(nèi)核分配給進(jìn)程的CPU時(shí)間。在Linux系統(tǒng)中,由shell啟動(dòng)的所有進(jìn)程的調(diào)度優(yōu)先級(jí)默認(rèn)都是相同的,都是0。調(diào)度優(yōu)先級(jí)是個(gè)整數(shù)值,從-?20(最高優(yōu)先級(jí))到+19(最低優(yōu)先級(jí))。

要改變一個(gè)shell腳本的優(yōu)先級(jí),可以通過 nice 命令做到。

nice命令

nice 命令允許你設(shè)置命令啟動(dòng)時(shí)的調(diào)度優(yōu)先級(jí)。要讓命令以更低的優(yōu)先級(jí)運(yùn)行,只要用 nice的 -n 命令行來指定新的優(yōu)先級(jí)即可。

$ nice -n 10 ./test.sh > test.out &
# [2] 120413
$ ps -p 120413 -o pid,ppid,ni,cmd
#     PID    PPID  NI CMD
#  120413  118697  10 /bin/bash ./test.sh

通過ps命令可以看到調(diào)度優(yōu)先級(jí)已經(jīng)被調(diào)整到了10。

nice 命令阻止普通系統(tǒng)用戶來提高命令的優(yōu)先級(jí),需要使用root權(quán)限。

renice 命令

renice命令用來改變系統(tǒng)上已運(yùn)行命令的優(yōu)先級(jí)。通過指定運(yùn)行進(jìn)程的PID來改變它的優(yōu)先級(jí)。

$ renice -n 10 -p 120756
# 120756 (process ID) 舊優(yōu)先級(jí)為 0,新優(yōu)先級(jí)為 10

5)定時(shí)運(yùn)行作業(yè)

Linux系統(tǒng)提供了多個(gè)在預(yù)選時(shí)間運(yùn)行腳本的方法: at 命令和 cron 表。

at

at 命令允許指定Linux系統(tǒng)何時(shí)運(yùn)行腳本,相當(dāng)于是預(yù)約執(zhí)行任務(wù)。

at 的守護(hù)進(jìn)程 atd 會(huì)以后臺(tái)模式運(yùn)行,檢查作業(yè)隊(duì)列來運(yùn)行作業(yè)。大多數(shù)Linux發(fā)行版會(huì)在啟動(dòng)時(shí)運(yùn)行此守護(hù)進(jìn)程。

atd 守護(hù)進(jìn)程會(huì)檢查系統(tǒng)上的一個(gè)特殊目錄(通常位于/var/spool/at)來獲取用 at 命令提交的作業(yè)。默認(rèn)情況下, atd 守護(hù)進(jìn)程會(huì)每60秒檢查一下這個(gè)目錄。有作業(yè)時(shí), atd 守護(hù)進(jìn)程會(huì)檢查作業(yè)設(shè)置運(yùn)行的時(shí)間。如果時(shí)間跟當(dāng)前時(shí)間匹配, atd` 守護(hù)進(jìn)程就會(huì)運(yùn)行此作業(yè)。

at 命令的基本格式:

at [-f filename] time
  • -f 參數(shù)來指定用于讀取命令(腳本文件)的文件名。
  • time 參數(shù)指定了Linux系統(tǒng)何時(shí)運(yùn)行該作業(yè)。

at 命令能識(shí)別多種不同的時(shí)間格式:

  • 標(biāo)準(zhǔn)的小時(shí)和分鐘格式,比如22:15
  • AM/PM指示符,比如10:15 PM
  • 特定可命名時(shí)間,比如nownoon、midnight或者teatime(4 PM)
  • 通過不同的日期格式指定特定的日期
    • 標(biāo)準(zhǔn)日期格式,比如MMDDYY、MM/DD/YY或DD.MM.YY
    • 文本日期,比如Jul 4或Dec 25,加不加年份均可
    • 指定時(shí)間增量:當(dāng)前時(shí)間+25 min。
$ at -f test.sh  21:23
# warning: commands will be executed using /bin/sh
# job 3 at Mon Jan  8 21:23:00 2024

作業(yè)隊(duì)列的字母排序越高,作業(yè)運(yùn)行的優(yōu)先級(jí)就越低,nice值更高。默認(rèn)情況下, at 的作業(yè)會(huì)被提交到 a 作業(yè)隊(duì)列。如果想以更高優(yōu)先級(jí)運(yùn)行作業(yè),可以用 -q 參數(shù)指定不同的隊(duì)列字母。

在使用 at 命令時(shí),最好在腳本中對(duì) STDOUT 和 STDERR 進(jìn)行重定向

atq 命令可以查看系統(tǒng)中有哪些作業(yè)在等待。

$ atq
# 1	Mon Jan  8 21:17:00 2024 = rob
# 6	Tue Jan  9 20:24:00 2024 a rob
# 3	Mon Jan  8 21:23:00 2024 = rob
# 4	Tue Jan  9 20:24:00 2024 a rob
# 5	Tue Jan  9 20:24:00 2024 a rob

可以用 atrm 命令來刪除等待中的作業(yè)。

$ atrm 6
$ atq
# 1	Mon Jan  8 21:17:00 2024 = rob
# 3	Mon Jan  8 21:23:00 2024 = rob
# 4	Tue Jan  9 20:24:00 2024 a rob
# 5	Tue Jan  9 20:24:00 2024 a rob

定期執(zhí)行命令

at 命令可以在預(yù)設(shè)時(shí)間安排腳本執(zhí)行,但如果需要腳本在每天的同一時(shí)間運(yùn)行或是每周一次、每月一次就需要使用新方法。

Linux系統(tǒng)使用cron程序來安排要定期執(zhí)行的作業(yè)。 cron程序會(huì)在后臺(tái)運(yùn)行并檢查cron時(shí)間表,以獲知已安排執(zhí)行的作業(yè)。

可以使用crontab -e來編輯cron時(shí)間表:

$ crontab -e
# GNU nano 4.8                                 /tmp/crontab.hABXZo/crontab                                         
# # Edit this file to introduce tasks to be run by cron.
# # 
# # Each task to run has to be defined through a single line
# # indicating with different fields when the task will be run
# # and what command to run for the task

表中每一行表示一個(gè)定期執(zhí)行的任務(wù),其格式為:

# m h  dom mon dow   command

m表示分鐘,h表示小時(shí),dom表示幾號(hào),mon表示月份,dow表示星期幾,*`表示任意日期。

分別是:minute (m), hour (h), day of month (dom), month (mon),# and day of week (dow) or use '*' in these fields (for 'any')

示例:

# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/

表示每周一凌晨5點(diǎn)將home.tgz解壓到/home路徑中。

每月最后一天執(zhí)行的任務(wù)設(shè)置方式,

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

列出crontab中的任務(wù)

crontab -l

如果待執(zhí)行的腳本對(duì)精確的執(zhí)行時(shí)間要求不高,用預(yù)配置的cron腳本目錄會(huì)更方便。在/etc/路徑下有4個(gè)基本目錄:cron.hourly、daily、monthlyweekly。譬如,如果腳本需要每天運(yùn)行一次,只要將腳本復(fù)制到daily目錄,cron就會(huì)每天執(zhí)行它。

cron程序的唯一問題是它假定Linux系統(tǒng)是7×24小時(shí)運(yùn)行的,如果系統(tǒng)存在關(guān)機(jī)重啟,有可能會(huì)錯(cuò)誤定時(shí)任務(wù),處理這種情況最好是能在開機(jī)時(shí)檢查是否有錯(cuò)過的定時(shí)任務(wù),而cron并不會(huì)去檢查,很多Linux發(fā)行版還包含了anacron程序可以解決這個(gè)問題。

anacron程序只會(huì)處理位于cron目錄的程序,比如/etc/cron.monthly。它用時(shí)間戳來決定作業(yè)是否在正確的計(jì)劃間隔內(nèi)運(yùn)行了。每個(gè)cron目錄都有個(gè)時(shí)間戳文件,該文件位于/var/spool/anacron。

$ sudo cat /var/spool/anacron/cron.monthly
# 20240104

到此這篇關(guān)于Linux Shell任務(wù)控制的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Linux Shell任務(wù)控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論