正常情況下,shell指令碼中的命令是序列執行的,當一條命令執行完才會執行接下來的命令。比如下面這段**:
#!/bin/bash
for i in ;do
echo $i
done
echo "end"執行結果:
1234567
8910end可以看到,迴圈體中的「echo $i」命令是序列執行的。但是如果所執行的命令耗時比較長,這就會導致整個程式的執行時間非常長,甚至可能導致程式執行時卡在那裡,長時間失去響應。比如我們需要完成這樣乙個任務:編寫乙個指令碼,掃瞄192.168.80.0/24網路裡,當前**的主機有哪些,能ping通就認為**。要完成這個任務,編寫指令碼並不複雜,下面是寫好的**:
#!/bin/bash
for i in ;do
ip="192.168.80.$i"
ping -c 2 $ip &> /dev/null && echo $ip is up
done這裡對指令碼中使用的ping命令稍作說明。linux中的ping命令在執行後會連續不斷地發包,因而指令碼中的ping命令使用了「-c」選項,指定只發2次包,如果能收到響應,就認為目標主機**。這個指令碼在邏輯上並沒有問題,但是在執行後由於要對網路中的254個ip位址輪流執行ping命令,耗時非常長,而且此時的指令碼無法使用ctrl+c強制終止,只能使用ctrl+z轉入後台,然後再用kill命令強制結束程序。
[root@localhost ~]# bash ping.sh
192.168.80.1 is up
192.168.80.2 is up
^c^z
[1]+ 已停止 bash ping.sh
[root@localhost ~]# jobs -l #檢視後台工作任務
[1]+ 101100 停止 bash ping.sh
[root@localhost ~]# kill -9 101100 #強制結束程序
[root@localhost ~]#
[1]+ 已殺死 bash ping.sh實際上在這個指令碼中所迴圈執行的ping命令之間並沒有依賴關係,也就是說不必非要等到「ping 192.168.80.1」結束之後才能接著執行「ping 192.168.80.2」,所有的這些ping命令完全可以併發執行。如果是使用python,那麼可以借助於多執行緒技術來實現命令的併發執行,而shell不支援多執行緒,因而只能採用多程序的方式。具體的實現方法很簡單,就是在要併發執行的命令後面加上「&」,將其轉入後台執行,這樣就可以在執行完一條命令之後,不必等待其執行結束,就立即轉去執行下一條命令。我們還是以之前的**為例,在迴圈體中的echo命令之後加上「&」:
#!/bin/bash
for i in ;do
echo $i &
done
echo "end"執行結果:
[root@localhost ~]# bash test.sh
end[root@localhost ~]# 123
6748
9105可以看到,在併發執行時不能保證命令的執行順序,而且本應在整個迴圈執行結束之後再執行的echo "end"命令,卻在程式一開始就被執行了。所以在併發執行時,我們通常都需要保證在迴圈體中的所有命令都執行完後再向後執行接下來的命令,這時就可以使用 wait命令來實現。在shell中使用wait命令,相當於其它高階語言裡的多執行緒同步。下面對**進行改進,增加wait命令:
#!/bin/bash
for i in ;do
echo $i &
done
wait
echo "end"這樣執行結果就正常了:
[root@localhost ~]# bash test3.sh67
2348
91051
end了解了程式併發執行的原理之後,我們對ping指令碼也同樣進行改進:
#!/bin/bash
for i in ;do
ip="192.168.80.$i"
ping -c 2 $ip &> /dev/null && echo $ip is up &
done
wait此時指令碼的執行速度將大大提高:
[root@localhost ~]# bash ping.sh
192.168.80.10 is up
192.168.80.20 is up
192.168.80.2 is up
192.168.80.1 is up
192.168.80.135 is up因而當要迴圈執行的命令之間沒有依賴關係時,完全可以採用併發執行的方式,這樣可以大幅提高**執行效率。當然併發執行也有缺陷,就是當需要並行執行的命令數量特別多,特別是所執行的命令占用的系統資源非常多時,可能會將整個系統的資源全部耗盡,影響其它程式的執行,因而還可以借助其它技術來限制併發執行的程序數量,由於比較複雜,本文就不做介紹了。
轉 Shell指令碼中的多工併發執行
感謝yttitan 正常情況下,shell指令碼中的命令是序列執行的,當一條命令執行完才會執行接下來的命令。比如下面這段 bin bash for i in do echo i done echo end 執行結果 123 4567 8910end bin bash for i in do ip 1...
Linux Shell指令碼中的多工併發執行
實現乙個指令碼能夠使用ping檢測網路的連通性 可以同時檢測多個ip位址,並且將檢測結果輸出 正常情況下,shell指令碼中的命令是序列執行的,當一條命令執行完才會執行接下來的命令。例如 bin bash for i in do echo idone echo end 結果如下 123 4567 8...
Shell指令碼中的併發
主要記錄一下shell指令碼中的命令的併發和序列執行。預設的情況下,shell指令碼中的命令是序列執行的,必須等到前一條命令執行完後才執行接下來的命令,但是如果我有一大批的的命令需要執行,而且互相又沒有影響的情況下 有影響的話就比較複雜了 那麼就要使用命令的併發執行了。看下面的 bin bash f...