<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 16.2 工作管理 (job control) 這個工作管理 (job control) 是用在 bash 環境下的,也就是說:“當我們登陸系統取得 bash shell 之后,在單一終端機接口下同時進行多個工作的行為管理 ”。舉例來說,我們在登陸 bash 后, 想要一邊復制文件、一邊進行數據搜尋、一邊進行編譯,還可以一邊進行 vim 程序撰寫! 當然我們可以重復登陸那六個命令行的終端機環境中,不過,能不能在一個 bash 內達成? 當然可以啊!就是使用 job control 啦! ^_^ ### 16.2.1 什么是工作管理? 從上面的說明當中,你應該要了解的是:“進行工作管理的行為中, 其實每個工作都是目前 bash 的子程序,亦即彼此之間是有相關性的。 我們無法以 job control 的方式由 tty1 的環境去管理 tty2 的 bash !” 這個概念請你得先創建起來,后續的范例介紹之后,你就會清楚的了解啰! 或許你會覺得很奇怪啊,既然我可以在六個終端接口登陸,那何必使用 job control 呢? 真是脫褲子放屁,多此一舉啊!不要忘記了呢,我們可以在 [/etc/security/limits.conf (第十三章)](../Text/index.html#limits) 里面設置使用者同時可以登陸的連線數,在這樣的情況下,某些使用者可能僅能以一個連線來工作呢! 所以啰,你就得要了解一下這種工作管理的模式了!此外,這個章節內容也會牽涉到很多的數據流重導向,所以,如果忘記的話, 務必回到[第十章 BASH Shell](../Text/index.html) 看一看喔! 由于假設我們只有一個終端接口,因此在可以出現提示字符讓你操作的環境就稱為前景 (foreground),至于其他工作就可以讓你放入背景 (background) 去暫停或運行。要注意的是,放入背景的工作想要運行時, 他必須不能夠與使用者互動。舉例來說, vim 絕對不可能在背景里面執行 (running) 的!因為你沒有輸入數據他就不會跑啊! 而且放入背景的工作是不可以使用 [ctrl]+c 來終止的! 總之,要進行 bash 的 job control 必須要注意到的限制是: * 這些工作所觸發的程序必須來自于你 shell 的子程序(只管理自己的 bash); * 前景:你可以控制與下達指令的這個環境稱為前景的工作 (foreground); * 背景:可以自行運行的工作,你無法使用 [ctrl]+c 終止他,可使用 bg/fg 調用該工作; * 背景中“執行”的程序不能等待 terminal/shell 的輸入(input) 接下來讓我們實際來管理這些工作吧! ### 16.2.2 job control 的管理 如前所述,bash 只能夠管理自己的工作而不能管理其他 bash 的工作,所以即使你是 root 也不能夠將別人的 bash 下面的 job 給他拿過來執行。此外,又分前景與背景,然后在背景里面的工作狀態又可以分為“暫停 (stop)”與“運行中 (running)”。那實際進行 job 控制的指令有哪些?下面就來談談。 * 直接將指令丟到背景中“執行”的 & 如同前面提到的,我們在只有一個 bash 的環境下,如果想要同時進行多個工作, 那么可以將某些工作直接丟到背景環境當中,讓我們可以繼續操作前景的工作!那么如何將工作丟到背景中? 最簡單的方法就是利用“ & ”這個玩意兒了!舉個簡單的例子,我們要將 /etc/ 整個備份成為 /tmp/etc.tar.gz 且不想要等待,那么可以這樣做: ``` [root@study ~]# tar -zpcf /tmp/etc.tar.gz /etc & [1] 14432 &lt;== [job number] PID [root@study ~]# tar: Removing leading `/' from member names # 在中括號內的號碼為工作號碼 (job number),該號碼與 bash 的控制有關。 # 后續的 14432 則是這個工作在系統中的 PID。至于后續出現的數據是 tar 執行的數據流, # 由于我們沒有加上數據流重導向,所以會影響畫面!不過不會影響前景的操作喔! ``` 仔細的瞧一瞧,我在輸入一個指令后,在該指令的最后面加上一個“ & ”代表將該指令丟到背景中, 此時 bash 會給予這個指令一個“工作號碼(job number)”,就是那個 [1] 啦!至于后面那個 14432 則是該指令所觸發的“ PID ”了!而且,有趣的是,我們可以繼續操作 bash 呢!很不賴吧! 不過,那么丟到背景中的工作什么時候完成?完成的時候會顯示什么?如果你輸入幾個指令后,突然出現這個數據: ``` [1]+ Done tar -zpcf /tmp/etc.tar.gz /etc ``` 就代表 [1] 這個工作已經完成 (Done) ,該工作的指令則是接在后面那一串命令行。 這樣了解了吧!另外,這個 & 代表:“將工作丟到背景中去執行”喔! 注意到那個“執行”的字眼!此外,這樣的情況最大的好處是: 不怕被 [ctrl]+c 中斷的啦! 此外,將工作丟到背景當中要特別注意數據的流向喔!包括上面的訊息就有出現錯誤訊息,導致我的前景被影響。 雖然只要按下 [enter] 就會出現提示字符。但如果我將剛剛那個指令改成: ``` [root@study ~]# tar -zpcvf /tmp/etc.tar.gz /etc & ``` 情況會怎樣?在背景當中執行的指令,如果有 stdout 及 stderr 時,他的數據依舊是輸出到屏幕上面的, 所以,我們會無法看到提示字符,當然也就無法完好的掌握前景工作。同時由于是背景工作的 tar , 此時你怎么按下 [ctrl]+c 也無法停止屏幕被搞的花花綠綠的!所以啰,最佳的狀況就是利用數據流重導向, 將輸出數據傳送至某個文件中。舉例來說,我可以這樣做: ``` [root@study ~]# tar -zpcvf /tmp/etc.tar.gz /etc &gt; /tmp/log.txt 2&gt;&1 & [1] 14547 [root@study ~]# ``` 呵呵!如此一來,輸出的信息都給他傳送到 /tmp/log.txt 當中,當然就不會影響到我們前景的作業了。 這樣說,您應該可以更清楚數據流重導向的重要性了吧!^_^ ![鳥哥的圖示](https://box.kancloud.cn/2016-05-13_5735736501917.gif "鳥哥的圖示") **Tips** 工作號碼 (job number) 只與你這個 bash 環境有關,但是他既然是個指令觸發的咚咚,所以當然一定是一個程序, 因此你會觀察到有 job number 也搭配一個 PID ! * 將“目前”的工作丟到背景中“暫停”:[ctrl]-z 想個情況:如果我正在使用 vim ,卻發現我有個文件不知道放在哪里,需要到 bash 環境下進行搜尋,此時是否要結束 vim 呢?呵呵!當然不需要啊!只要暫時將 vim 給他丟到背景當中等待即可。 例如以下的案例: ``` [root@study ~]# vim ~/.bashrc # 在 vim 的一般模式下,按下 [ctrl]-z 這兩個按鍵 [1]+ Stopped vim ~/.bashrc [root@study ~]# &lt;==順利取得了前景的操控權! [root@study ~]# find / -print ....(輸出省略).... # 此時屏幕會非常的忙碌!因為屏幕上會顯示所有的文件名。請按下 [ctrl]-z 暫停 [2]+ Stopped find / -print ``` 在 vim 的一般模式下,按下 [ctrl] 及 z 這兩個按鍵,屏幕上會出現 [1] ,表示這是第一個工作, 而那個 + 代表最近一個被丟進背景的工作,且目前在背景下默認會被取用的那個工作 (與 fg 這個指令有關 )!而那個 Stopped 則代表目前這個工作的狀態。在默認的情況下,使用 [ctrl]-z 丟到背景當中的工作都是“暫停”的狀態喔! * 觀察目前的背景工作狀態: jobs ``` [root@study ~]# jobs [-lrs] 選項與參數: -l :除了列出 job number 與指令串之外,同時列出 PID 的號碼; -r :僅列出正在背景 run 的工作; -s :僅列出正在背景當中暫停 (stop) 的工作。 范例一:觀察目前的 bash 當中,所有的工作,與對應的 PID [root@study ~]# jobs -l [1]- 14566 Stopped vim ~/.bashrc [2]+ 14567 Stopped find / -print ``` 如果想要知道目前有多少的工作在背景當中,就用 jobs 這個指令吧!一般來說,直接下達 jobs 即可! 不過,如果你還想要知道該 job number 的 PID 號碼,可以加上 -l 這個參數啦! 在輸出的信息當中,例如上表,仔細看到那個 + - 號喔!那個 + 代表默認的取用工作。 所以說:“目前我有兩個工作在背景當中,兩個工作都是暫停的, 而如果我僅輸入 fg 時,那么那個 [2] 會被拿到前景當中來處理”! 其實 + 代表最近被放到背景的工作號碼, - 代表最近最后第二個被放置到背景中的工作號碼。 而超過最后第三個以后的工作,就不會有 +/- 符號存在了! * 將背景工作拿到前景來處理:fg 剛剛提到的都是將工作丟到背景當中去執行的,那么有沒有可以將背景工作拿到前景來處理的? 有啊!就是那個 fg (foreground) 啦!舉例來說,我們想要將上頭范例當中的工作拿出來處理時: ``` [root@study ~]# fg %jobnumber 選項與參數: %jobnumber :jobnumber 為工作號碼(數字)。注意,那個 % 是可有可無的! 范例一:先以 jobs 觀察工作,再將工作取出: [root@study ~]# jobs -l [1]- 14566 Stopped vim ~/.bashrc [2]+ 14567 Stopped find / -print [root@study ~]# fg &lt;==默認取出那個 + 的工作,亦即 [2]。立即按下[ctrl]-z [root@study ~]# fg %1 &lt;==直接規定取出的那個工作號碼!再按下[ctrl]-z [root@study ~]# jobs -l [1]+ 14566 Stopped vim ~/.bashrc [2]- 14567 Stopped find / -print ``` 經過 fg 指令就能夠將背景工作拿到前景來處理啰!不過比較有趣的是最后一個顯示的結果,我們會發現 + 出現在第一個工作后! 怎么會這樣啊?這是因為你剛剛利用 fg %1 將第一號工作捉到前景后又放回背景,此時最后一個被放入背景的將變成 vi 那個指令動作, 所以當然 [1] 后面就會出現 + 了!了解乎!另外,如果輸入“ fg - ” 則代表將 - 號的那個工作號碼拿出來,上面就是 [2]- 那個工作號碼啦! * 讓工作在背景下的狀態變成運行中: bg 我們剛剛提到,那個 [ctrl]-z 可以將目前的工作丟到背景下面去“暫停”, 那么如何讓一個工作在背景下面“ Run ”呢?我們可以在下面這個案例當中來測試! 注意喔!下面的測試要進行的快一點!^_^ ``` 范例一:一執行 find / -perm /7000 &gt; /tmp/text.txt 后,立刻丟到背景去暫停! [root@study ~]# find / -perm /7000 &gt; /tmp/text.txt # 此時,請立刻按下 [ctrl]-z 暫停! [3]+ Stopped find / -perm /7000 &gt; /tmp/text.txt 范例二:讓該工作在背景下進行,并且觀察他!! [root@study ~]# jobs ; bg %3 ; jobs [1] Stopped vim ~/.bashrc [2]- Stopped find / -print [3]+ Stopped find / -perm /7000 &gt; /tmp/text.txt [3]+ find / -perm /7000 &gt; /tmp/text.txt & [1]- Stopped vim ~/.bashrc [2]+ Stopped find / -print [3] Running find / -perm /7000 &gt; /tmp/text.txt & ``` 看到哪里有差異嗎?呼呼!沒錯!就是那個狀態列~以經由 Stopping 變成了 Running 啰! 看到差異點,嘿嘿!命令行最后方多了一個 & 的符號啰! 代表該工作被啟動在背景當中了啦! ^_^ * 管理背景當中的工作: kill 剛剛我們可以讓一個已經在背景當中的工作繼續工作,也可以讓該工作以 fg 拿到前景來, 那么,如果想要將該工作直接移除呢?或者是將該工作重新啟動呢?這個時候就得需要給予該工作一個訊號 (signal) ,讓他知道該怎么作才好啊!此時, kill 這個指令就派上用場啦! ``` [root@study ~]# kill -signal %jobnumber [root@study ~]# kill -l 選項與參數: -l :這個是 L 的小寫,列出目前 kill 能夠使用的訊號 (signal) 有哪些? signal :代表給予后面接的那個工作什么樣的指示啰!用 man 7 signal 可知: -1 :重新讀取一次參數的配置文件 (類似 reload); -2 :代表與由鍵盤輸入 [ctrl]-c 同樣的動作; -9 :立刻強制刪除一個工作; -15:以正常的程序方式終止一項工作。與 -9 是不一樣的。 范例一:找出目前的 bash 環境下的背景工作,并將該工作“強制刪除”。 [root@study ~]# jobs [1]+ Stopped vim ~/.bashrc [2] Stopped find / -print [root@study ~]# kill -9 %2; jobs [1]+ Stopped vim ~/.bashrc [2] Killed find / -print # 再過幾秒你再下達 jobs 一次,就會發現 2 號工作不見了!因為被移除了! 范例二:找出目前的 bash 環境下的背景工作,并將該工作“正常終止”掉。 [root@study ~]# jobs [1]+ Stopped vim ~/.bashrc [root@study ~]# kill -SIGTERM %1 # -SIGTERM 與 -15 是一樣的!您可以使用 kill -l 來查閱! # 不過在這個案例中, vim 的工作無法被結束喔!因為他無法通過 kill 正常終止的意思! ``` 特別留意一下, -9 這個 signal 通常是用在“強制刪除一個不正常的工作”時所使用的, -15 則是以正常步驟結束一項工作(15也是默認值),兩者之間并不相同呦!舉上面的例子來說, 我用 vim 的時候,不是會產生一個 .filename.swp 的文件嗎? 那么,當使用 -15 這個 signal 時, vim 會嘗試以正常的步驟來結束掉該 vi 的工作, 所以 .filename.swp 會主動的被移除。但若是使用 -9 這個 signal 時,由于該 vim 工作會被強制移除掉,因此, .filename.swp 就會繼續存在文件系統當中。這樣您應該可以稍微分辨一下了吧? 不過,畢竟正常的作法中,你應該先使用 fg 來取回前景控制權,然后再離開 vim 才對~因此,以上面的范例二為例,其實 kill 確實無法使用 -15 正常的結束掉 vim 的動作喔!此時還是不建議使用 -9 啦!因為你知道如何正常結束該程序不是嗎? 通常使用 -9 是因為某些程序你真的不知道怎么通過正常手段去終止他,這才用到 -9 的! 其實, kill 的妙用是很無窮的啦!他搭配 signal 所詳列的信息 (用 man 7 signal 去查閱相關數據) 可以讓您有效的管理工作與程序 (Process),此外,那個 killall 也是同樣的用法! 至于常用的 signal 您至少需要了解 1, 9, 15 這三個 signal 的意義才好。 此外, signal 除了以數值來表示之外,也可以使用訊號名稱喔! 舉例來說,上面的范例二就是一個例子啦!至于 signal number 與名稱的對應, 呵呵,使用 kill -l 就知道啦(L的小寫)! 另外, kill 后面接的數字默認會是 PID ,如果想要管理 bash 的工作控制,就得要加上 %數字 了, 這點也得特別留意才行喔! ### 16.2.3 離線管理問題 要注意的是,我們在工作管理當中提到的“背景”指的是在終端機模式下可以避免 [crtl]-c 中斷的一個情境, 你可以說那個是 bash 的背景,并不是放到系統的背景去喔!所以,工作管理的背景依舊與終端機有關啦! 在這樣的情況下,如果你是以遠端連線方式連接到你的 Linux 主機,并且將工作以 & 的方式放到背景去, 請問,在工作尚未結束的情況下你離線了,該工作還會繼續進行嗎?答案是“否”!不會繼續進行,而是會被中斷掉。 那怎么辦?如果我的工作需要進行一大段時間,我又不能放置在背景下面,那該如何處理呢? 首先,你可以參考前一章的 [at](../Text/index.html#at) 來處理即可!因為 at 是將工作放置到系統背景, 而與終端機無關。如果不想要使用 at 的話,那你也可以嘗試使用 nohup 這個指令來處理喔!這個 nohup 可以讓你在離線或登出系統后,還能夠讓工作繼續進行。他的語法有點像這樣: ``` [root@study ~]# nohup [指令與參數] &lt;==在終端機前景中工作 [root@study ~]# nohup [指令與參數] & &lt;==在終端機背景中工作 ``` 有夠好簡單的指令吧!上述指令需要注意的是, nohup 并不支持 bash 內置的指令,因此你的指令必須要是外部指令才行。 我們來嘗試玩一下下面的任務吧! ``` # 1\. 先編輯一支會“睡著 500 秒”的程序: [root@study ~]# vim sleep500.sh #!/bin/bash /bin/sleep 500s /bin/echo "I have slept 500 seconds." # 2\. 丟到背景中去執行,并且立刻登出系統: [root@study ~]# chmod a+x sleep500.sh [root@study ~]# nohup ./sleep500.sh & [2] 14812 [root@study ~]# nohup: ignoring input and appending output to `nohup.out' &lt;==會告知這個訊息! [root@study ~]# exit ``` 如果你再次登陸的話,再使用 pstree 去查閱你的程序,會發現 sleep500.sh 還在執行中喔!并不會被中斷掉! 這樣了解意思了嗎?由于我們的程序最后會輸出一個訊息,但是 nohup 與終端機其實無關了, 因此這個訊息的輸出就會被導向“ ~/nohup.out ”,所以你才會看到上述指令中,當你輸入 nohup 后, 會出現那個提示訊息啰。 如果你想要讓在背景的工作在你登出后還能夠繼續的執行,那么使用 nohup 搭配 & 是不錯的運行情境喔! 可以參考看看!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看