2010-09-01 85 views
1

注意:我以爲我使用bash,但/ bin/sh鏈接到/ bin/dash,它有這個奇怪的exec問題。如何找到dash-exec命令的PID

我在Linux上有一個簡單的bash shell腳本,用於啓動服務器進程(我沒有編寫或控制),並希望bash shell腳本將啓動的進程的PID輸出到pidfile。

問題是,bash-exec命令不會用啓動的服務器進程替換它自己的進程!

所以:

echo $$ | cat > /var/run/launched-server.pid 

這並不工作,因爲文件中的PID將是慶典的不是服務器進程。如果服務器進程退出bash,則可能無法退出,而將愚蠢的啓動腳本放在進程列表中。

有誰知道一種方式來使用bash(或者幾許?),這樣:

  1. 這可能嗎?
  2. 啓動服務器服務器進程的PID將在我的pidfile中?
  3. 確保啓動服務器存在時bash腳本將會死掉,並且不會在進程列表中留下閒置的shell進程?

編輯: 這從bash reference manual片段是用...

exec 
      exec [-cl] [-a name] [command [arguments]] 

如果提供的命令,它取代了殼,而無需創建一個新的進程。如果提供了-l選項,那麼shell會在傳遞給命令的第零個參數的開始處放置一個破折號。這是登錄程序的功能。 -c選項使命令在空白環境下執行。如果提供了-a,那麼shell將名稱作爲命令的第零個參數。如果沒有指定命令,重定向可能會影響當前的shell環境。如果沒有重定向錯誤,則返回狀態爲零;否則返回狀態不爲零。


編輯2: 這是腳本(消毒):

#!/bin/sh 

# this is where the server expects to run its services for Daemontools 
SERVICE_DIR='/var/service'; 

# kill stdout, stderr, stdin 
exec </dev/null 
exec >/dev/null 
exec 2>/dev/null 

logger -ip daemon.debug -- stdout, stderr, stdin redirected to /dev/null 

if [ -d $SERVICE_DIR ]; then 
    # sanitized... 
    logger -ip daemon.debug -- services and supervisors exited 
else 
    logger -ip daemon.err -- $SERVICE_DIR does not exist, exiting 
    exit 1; 
fi 

if [ -d /var/run/pid ]; then 
    echo $$ | cat > /var/run/pid/launched-server.pid 
    logger -ip daemon.debug -- creating launched-server pidfile 
fi 

# start the server process 
logger -ip daemon.info -- launching server on $SERVICE_DIR 
exec /usr/local/bin/launched-server 

而且有些ps輸出,也許更清楚了嗎?

[email protected]: ~/dev $ ps ax | grep launched-server 
13896 pts/1 S+  0:00 /bin/sh ./server_boot 
13905 pts/1 S+  0:00 launched-server /var/service 
13938 pts/2 R+  0:00 grep --color=auto launched-server 
+0

沒有必要使用'cat':'echo $$>/var/run/pid /已啓動server.pid' – 2010-09-01 15:45:08

+0

@ Dennis-Williamson - 好,趕快,謝謝。 – Petriborg 2010-09-01 16:00:13

回答

1

您的配送是否包含start-stop-daemon(8)?非常有用的小工具,它專門用於從shell腳本啓動守護進程。 (當然,守護進程活得比的shell腳本,所以它可能不是一個完美的匹配 - 這取決於你爲什麼希望shell活得比你的守護進程)。

或者,更簡單的東西:

莫非你的問題可以通過bash的exec命令解決?它代替你向我要什麼程序來執行shell進程:

#!/bin/bash 

echo $$ > /tmp/pidfile 
exec /bin/sleep 60 

$ ./show_exec.sh 
[nothing happens] 

而且,在另一個shell:

$ cat pidfile 
24686 
$ ps auxw | grep 24686 
sarnold 24686 0.0 0.0 9728 816 pts/1 S+ 04:53 0:00 /bin/sleep 60 
+0

其中一個問題是,腳本超出了守護進程,而不是其他方式:-)它可能是一個簡單的問題,我只是混淆起來.. – Petriborg 2010-09-01 12:01:19

+0

雖然你的答案不直接給我一個解決方案在bash-每次說,我不得不說,啓動 - 停止守護進程是現貨,是一個偉大的小軟件。我已經用bash的exec來「解決」了我的問題。 – Petriborg 2010-09-01 14:53:19

2

我現在意識到了真正的問題是什麼:

通過使用#!/bin/sh我沒有調用bash,而是破折號。

Dash的exec是exec問題的shell。如果我從一開始就使用#!/bin/bash,它會按預期工作。