2011-06-01 81 views
6

獲得一個後臺進程ID後臺進程獲取一個PID容易被去從提示符下執行:從運行作爲另一個用戶

$ my_daemon & 
$ echo $! 

但如果我要運行它像一個不同的用戶是什麼:

su - joe -c "/path/to/my_daemon &;" 

現在我該如何捕獲my_daemon的PID?

+2

對於我而言,這看起來非常穩定;這是一個關於shell編程的問題,因此在SO的職責範圍內。 – 2011-06-01 06:52:37

回答

12

簡潔 - 有很多難度。

您必須安排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殼退出)

警告:好的理論 - 未經測試的代碼...

+0

真棒回答。我或許可以通過這個來獲得:'su - joe -c「/ path/to/my_daemon&echo \ $!> /tmp/su.joe。$$」'轉義$!在'my_daemon&'後面也沒有分號。我會稍微玩一下。 – Dex 2011-06-01 06:55:55

+0

請務必在$!後添加空格或者shell可能會奇怪地解釋這個。 – 2013-12-12 00:35:41

-1

這裏是我的解決方案

su oracle -c "/home/oracle/database/runInstaller" & 
pid=$(pgrep -P $!) 

移出

  • pgrep -P $! - 獲取父pid的子進程$!
+0

爲什麼這是低調的?兩行簡潔的代碼,不使用tmp文件。 – koola 2013-12-05 14:20:05

-1

我在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變量來提醒自己下次看劇本時我正在做什麼。

0

這裏介紹的方法不適用於我。以下是我所做的:

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` 
相關問題