2016年4月25日 星期一

Bash的影分身術:Fork

一個人工作時,即使工作很多也只能夠一個人處理。但對一個在跑的程式來說,可以開許多分身(叫做子程式),每個分身都可以各自去處理不同的事情。這個開分身的方式叫做fork。這邊提供一個簡單的例子,測試在Bash下面使用Fork

首先編寫一個程式fork.sh如下,權限設定成可執行:

  #!/bin/sh

  show_the_pid_and_sleeptime()
  {
      sleep $1
      echo 'end Job' $1 '$PPID='$PPID '$$='$$ '$!='$!
  }

  for i in `seq 5`
  do
     show_the_pid_and_sleeptime $i &
  done

  echo 'Program name is' $0', whose PID is' $$
  CPIDs=`pgrep -P $$`
  echo 'Children PIDs are' $CPIDs

  wait

這個程式的會產生五個分身,Job 1會睡1秒鐘、Job 2會睡2秒鐘、...、最後一個Job 5會睡5秒鐘,睡醒後會印出來程序的一些相關資訊。執行後的結果會類似下面

$ ./fork.sh 
Program name is ./fork.sh, whose PID is 25594
Children PIDs are 25596 25597 25598 25600 25602
end Job 1 $PPID=13209 $$=25594 $!=
end Job 2 $PPID=13209 $$=25594 $!=25596
end Job 3 $PPID=13209 $$=25594 $!=25597
end Job 4 $PPID=13209 $$=25594 $!=25598
end Job 5 $PPID=13209 $$=25594 $!=25600

這些內容代表的意思是
  • $PPID 執行fork.sh的那個Shell的process ID
  • $$ fork.sh這個程式的process ID
  • $! fork.sh的影分身在執行的時候,上一個分身的process ID
在這邊看到Job1沒有上一個分身的process ID,而Job 2裡面顯示的$!是Job 1的process ID。我還不知道如何在影分身(子程序)裡面看到影分身的process ID。

Fork的威力很大,可以來拿做炸彈,在Bash中這個炸彈只要13個字元  :(){ :|:& };:


2016-Apr-25 反制Fork bomb的方法

使用ulimit限制max user processes,參考下面的指令
  • ulimit -a:看檔案系統與程式的限制,參考鳥哥的文章
  • ulimit -u 1024:限制單一使用者最多可以跑1024個processes
如果是系統管理者,則可以去修改/etc/security/limits.conf這個檔案(參考鳥哥說明)。要注意裡面用到group的資訊的話,要把usernames加到/etc/group裡面。


_EOF_

沒有留言:

張貼留言