nohup

問題引出:這幾天遇到一個問題,調用別人寫的nginx啊、logstash啊等等一些啓動腳本(如:nginx_start.sh)的時候,ps查看了一下進程,發現應用起來後,啓動腳本的進竟然也還在,看了一下腳本,裏面用nohup方法,理論上進程起來後,啓動腳本的進程不應該還在纔對,針對這個現象,自己做了一些測試。


一、模仿寫了一個nginx“啓動”腳本,如下:

#!/bin/bash

## 狀態信息
nginx_status()
{
    # 查看狀態
    if [ "x${pid}" != "x" ]; then
        echo "nginx (PID:$(echo -n ${pid})) is running..."
    else
        echo "nginx was stopped"
    fi
}

nginx_start()
{
    # 判斷是否已啓動
    [ "x${pid}" = "x" ] && nohup sleep 300 &
    sleep 1

    nginx_status
}

if [ "$USER" = "root" ]; then
    case $1 in
        start)
            nginx_start
            ;;
        status)
            nginx_status
            ;;
        *)
            echo "nothing"
    esac
else
    echo "User is $USER. You must be apps to run this script!"
fi

2、執行這個進程,出現如下的結果:啓動進程盡然還在。

pstree查看一下:


3、多次測試,排除了啓動腳本中sleep 1、後面調用nginx_status和最後的case的可能性。(這裏測試過程比較簡單,略)

4、多次測試,排除一些可能性後,再研究啓動腳本的寫法,

理論上來說,使用nohup &會進入後臺執行,並不會影響父進程的正常退出,爲了驗證這個,做了如下嘗試:

執行後發現:並不會出現啓動腳本的進程。


5、這樣,就把問題集中到了nohup &前面的語句了,仔細的想了一下,[ "x${pid}" = "x" ] && nohup sleep 300 &  這條語句,會不會是最後的&將命令放入後臺執行的時候失敗了,也就是會所這條語句並沒有像預想中的那樣進入後臺執行,即進入後臺“失敗”,沒有真正意義上的進入後臺,從而影響了父進程的正常退出,這裏只需要把sleep 300放入後臺進行就可以了,爲了排除前面可能帶來的干擾,做了如下測試:

結果發現:啓動腳本的進程沒有了,也就是說sleep 300放入後臺執行並沒有影響父進程的退出。


6、上面的測試中,進入後臺運行的程序都是需要執行一定時間或者是一直在執行的(引出這些測試的例子就是這種類型),那麼如果是進入後臺執行的程序很快就能執行完,結果會怎樣?

運行結果:並沒有發現啓動腳本的進程


二、總結:

個人總結:查看一下資料後,個人覺得原因可能如下:nohup  &的執行依賴於前面[ "x${pid}" = "x" ] 的執行結果爲真,即進入後臺的程序依賴了父進程的一些資源,例如文件資源等,所以在子進程(後臺進程)沒有運行結束之前(文中模仿的就是進入後臺的子進程還在運行中),這些依賴的資源沒有被釋放,導致父進程無法正常退出,一旦子進程執行完後(文中sleep 300後)依賴的父進程的資源釋放後,父進程正常退出。

求其他高見。謝謝




















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章