
linux 和 unix 屬于多任務的作業系統,也就是說一個系統在同一時間段内能運作多重任務(程序)。在這個新的部落格系列,我将會列出相關的 linux 和 unix 作業(job)控制的指令,你可以通過這些指令在 bash 或 korn 還有 posix shell 下實作執行多重任務。
<a target="_blank"></a>
作業控制不隻是能夠停止/挂起(stop/suspend)正在執行的程序(指令),也可以繼續/喚醒(continue/resume)執行你需要的每一個程序。這完全可以用你的作業系統和 bash/ksh 之類的 shell 或 posix shell 完成。
bash / korn shell,或者是 posix shell 提供給了作業控制的環境。
你的 shell 會留有一張目前作業的表單,稱為作業表。當你鍵入指令時,shell 會給它配置設定一個 jobid(也稱作 jobspec)。一個 jobid 或 jobspec隻是很小的整數數值。
我要運作一個名為 xeyes 的指令,它會在螢幕上顯示兩個橢圓的眼睛,輸入: $ xeyes &
輸出樣例:
fig.01: 在背景運作 xeyes 指令
我使用&符号讓一個 job 在背景運作。shell 會列印一行資訊類似如下:
[1] 6891
在這個例子中,有兩個數字輸出,分别表示:
6891 : 作業1的程序id。
我在多執行一些 job:
## 啟動一個文本編輯器,x 的系統負載顯示,和 sleep 指令 ##
gedit /tmp/hello.c &
xload &
sleep 100000 &
$ jobs
$ jobs -l
輸出如下:
[1] 9379 running xeyes &
[2] 9380 running gedit /tmp/hello.c &
[3]- 9420 running xload &
[4]+ 9421 running sleep 100000 &
簡要描述如下:
字段
值
描述
示例
1
[1]
jobid 或 job_spec - 工作号要與fg, bg, wait, kill和其他shell指令一起使用。你必須在工作号字首添加一個百分号:(%)。
加号 (+) 辨別着預設的或是現在的作業。
減号 (-) 辨別着前一個作業。
%1
fg %1
kill %2
2
9379
程序 id - 系統自動為每個程序建立并配置設定地獨有的身份标志号。
kill 9379
3
running
狀态 - 關于作業的狀态:
running - 該 作業正在運作,還沒有被外部信号挂起。
stopped - 該作業已經被挂起。
n/a
4
xeyes &
command - 由shell給出的指令。
script &
firefox url&
你也可以用 ps 命名列出目前系統正在運作的程序:
$ ps
kill -s stop pid
animated gif 01: 挂起 ping 指令作業
## ping 指令的作業号的值為5 ##
fg %5
我也可以規定指令行開端符合字元串"ping"的作業[譯注:不能出現不明确的字元串,例如如果背景有兩個 vim 程序而你敲入 fg %vim 會報錯。]:
## %string ##
fg %ping
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=3 ttl=53 time=265 ms
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=4 ttl=53 time=249 ms
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=5 ttl=53 time=267 ms
^c
# yum -y update &>/root/patch.log &
然而,由于一些原因(例如,過載問題)我決定停止這個作業20分鐘:
# kill -s stop %yum
[7]+ stopped yum -y update &>/root/patch.log &
用 bg 重新開機停止在背景的 yum 程序
# bg %7
或者:
# bg %yum
[7]+ yum -y update &>/root/patch.log &
# kill %7
或者
# kill 程序id
[7]+ terminated yum -y update &>/root/patch.log &
~/scripts/www/pdfwriter.py --profile=faq --type=clean --header=logo\
--footer-left "nixcraft is git ul++++ w+++ c++++ m+ e+++ d-" \
--footer-right "page [of] of [total]" &
$ ~/scripts/www/pdfwriter.py --profile=faq .... &
$ disown
$ exit
$ nohup ~/scripts/www/pdfwriter.py --profile=faq .... &
為了查找最近在背景執行的(異步)指令的程序id,可使用 bash shell 的特殊參數 $!
$ gedit foo.txt &
$ echo "最近在背景執行的job 的pid - $!"
最近在背景執行的job 的pid - 9421
wait 指令會等候給予的程序id 或 作業id指定的程序,然後報告它的終止狀态。文法如下:
/path/to/large-job/command/foo &
wait $!
/path/to/next/job/that-is-dependents/on-foo-command/bar
這是我的一個工作腳本:
#!/bin/bash
# a shell script wrapper to create pdf files for our blog/faq section
########################################################################
# init() - must be run first
# purpose - create index file in $_tmp for all our wordpress databases
init(){
_php="/usr/bin/php"
_phpargs="-d apc.enabled=0"
_base="~/scripts"
_tmp="$_base/tmp"
_what="$1"
for i in $_what
do
[[ ! -d "$_tmp/$i" ]] && /bin/mkdir "$_tmp/$i"
$_php $_phpargs -f "$_base/php/rawsqlmaster${i}.php" > "$_tmp/$i/output.txt"
done
}
#####################################################
# without index file, we can out generate pdf files
init blog
###########################################################
# do not run the rest of the script until init() finished
## alright, create pdf files
~/scripts/www/pdfwriter.py --profile=blog --type=clean --header=logo\
--footer-right "page [of] of [total]"
指令
&
将作業置入背景
指令 &
%n
設定作業号為 n (數字)的作業
指令 %1
%word
引用指令行開端包含 word 的作業
指令 %yum
%?word
引用指令行包含 word 的作業
指令 %?ping
%%
%+
引用目前作業
kill %%
kill %+
%-
引用先前作業
bg %-
ctrl-z
kill -s stop jobid
挂起或停止作業
kill -s stop %ping
jobs
jobs -l
列出活動的作業
bg
将 作業置入背景
bg %1
bg %ping
fg
将作業置入前台
fg %2
fg %apt-get
運作下面的 type 指令找出給予指令是否屬于内部或外部的。
type -a fg bg jobs disown
輸出樣式:
fg is a shell builtin
fg is /usr/bin/fg
bg is a shell builtin
bg is /usr/bin/bg
jobs is a shell builtin
jobs is /usr/bin/jobs
disown is a shell builtin
在幾乎所有情況下,你都需要使用 shell 的内置指令。所有外部指令例如 /usr/bin/fg 或 /usr/bin/jobs 工作在一個不同的 shell 環境下,而不能用在父 shell 的環境下。
原文釋出時間為:2014-03-13
本文來自雲栖社群合作夥伴“linux中國”