獲得一個後臺進程ID後臺進程獲取一個PID容易被去從提示符下執行:從運行作爲另一個用戶
$ my_daemon &
$ echo $!
但如果我要運行它像一個不同的用戶是什麼:
su - joe -c "/path/to/my_daemon &;"
現在我該如何捕獲my_daemon的PID?
獲得一個後臺進程ID後臺進程獲取一個PID容易被去從提示符下執行:從運行作爲另一個用戶
$ my_daemon &
$ echo $!
但如果我要運行它像一個不同的用戶是什麼:
su - joe -c "/path/to/my_daemon &;"
現在我該如何捕獲my_daemon的PID?
簡潔 - 有很多難度。
您必須安排su'd shell將子PID寫入文件,然後選擇輸出。鑑於它將是'joe'創建文件而不是'dex',這增加了另一層複雜性。
最簡單的解決方案可能是:
su - joe -c "/path/to/my_daemon & echo \$! > /tmp/su.joe.$$"
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$ # Probably fails - joe owns it, dex does not
下一個解決方案包括使用備用文件描述符 - 數字3
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>/tmp/su.joe.$$
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$
如果你擔心中斷等(和你應該be),那麼你也陷阱:
tmp=/tmp/su.joe.$$
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>$tmp
bg=$(<$tmp)
rm -f $tmp
trap 0 1 2 3 13 15
(捕獲的信號是HUP,IN T,QUIT,PIPE和TERM - 加0殼退出)
警告:好的理論 - 未經測試的代碼...
真棒回答。我或許可以通過這個來獲得:'su - joe -c「/ path/to/my_daemon&echo \ $!> /tmp/su.joe。$$」'轉義$!在'my_daemon&'後面也沒有分號。我會稍微玩一下。 – Dex 2011-06-01 06:55:55
請務必在$!後添加空格或者shell可能會奇怪地解釋這個。 – 2013-12-12 00:35:41
這裏是我的解決方案
su oracle -c "/home/oracle/database/runInstaller" &
pid=$(pgrep -P $!)
移出
pgrep -P $!
- 獲取父pid的子進程$!
爲什麼這是低調的?兩行簡潔的代碼,不使用tmp文件。 – koola 2013-12-05 14:20:05
我在Linux上採用了上述解決方案,但必須添加睡眠以使子進程有機會啓動。
su - joe -c "/path/to/my_daemon > /some/output/file" &
parent=$!
sleep 1
pid=$(pgrep -P $parent)
在bash運行,它不會像pid=$(pgrep -P $!)
,但如果我的!
後添加一個空格這是確定:pid=$(pgrep -P $!)
。我堅持使用額外的$parent
變量來提醒自己下次看劇本時我正在做什麼。
這裏介紹的方法不適用於我。以下是我所做的:
PID_FILE=/tmp/service_pid_file
su -m $SERVICE_USER -s /bin/bash -c "/path/to/executable $ARGS >/dev/null 2>&1 & echo \$! >$PID_FILE"
PID=`cat $PID_FILE`
對於我而言,這看起來非常穩定;這是一個關於shell編程的問題,因此在SO的職責範圍內。 – 2011-06-01 06:52:37