2012-09-26 28 views
8

我們有一個自定義的C++守護進程應用程序,它會分叉一次。因此,我們在我們的暴發戶腳本在Ubuntu 12.04在做這和它完美的作品:如何在Upstart腳本的預啓動中設置環境變量?

expect fork 
exec /path/to/the/app 

但是現在我們需要在一個參數傳遞給我們的應用程序包含CPU的機器上數傳在其上運行:

cat /proc/cpuinfo | grep processor | wc -l 

我們的第一次嘗試是這樣的:

expect fork 
exec /path/to/the/app -t `cat /proc/cpuinfo | grep processor | wc -l` 

雖然啓動我們用正確的-t值的應用程序,新貴跟蹤錯誤的PID值,我假設,因爲這些貓,grep & wc在我們的應用程序之前命令exec中的所有啓動進程。

我也試過這個,甚至它不工作,我猜是因爲設置一個env var運行一個進程?新貴尚跟蹤錯誤的PID:

expect fork 
script 
    NUM_CORES=32 
    /path/to/the/app -t $NUM_CORES 
end script 

我也試過在ENV節這樣做,但顯然那些不運行的命令:

env num_cores=`cat /proc/cpuinfo | grep processor | wc -l` 

也試過在提前啓動這樣做,但ENV乏設置有沒有在EXEC節的任何值:

pre-start 
    NUM_CORES=32 
end script 

任何想法如何得到這個NUM_CORES設置不當,仍然得到新貴追蹤正確的PID爲我們的應用程序,一旦叉?

回答

16

這很尷尬。推薦的方法是在預啓動節中編寫一個env文件,然後將其源文件寫入腳本節。我知道,這很荒謬。

expect fork 

pre-start script 
    exec >"/tmp/$UPSTART_JOB" 
    echo "NUM_CORES=$(cat /proc/cpuinfo | grep processor | wc -l)" 
end script 

script 
    . "/tmp/$UPSTART_JOB" 
    /path/to/app -t "$NUM_CORES" 
end script 

post-start script 
    rm -f "/tmp/$UPSTART_JOB" 
end script 

我在預啓動時使用了exec行,因爲我通常有多個env變量,我不想重複重定向代碼。

這隻適用於因爲'。 '命令是一個內置的短劃線,因此不會產生過程。

+0

超級有用!有一件事:我認爲你仍然需要在腳本塊中使用「exec/path/to/app」,如果這是你之前需要的pid跟蹤。一旦我添加了「exec」,這對我來說非常合適。 –

+0

@ CodyA.Ray完全依賴於正在啓動的服務的分岔行爲。在我們的例子中,'expect daemon'可能是合適的。 – mpm

0

我會在 「腳本」 分配一個值之後添加

export NUM_CORES 

。我記得符號鏈接到非Bash shell的/ bin/sh可能會運行腳本,所以我會避免僅使用Bash構造。

Re:使用「env」節,它直接傳遞值並且不使用shell約定來處理它們。

2

根據zram-Config中的新貴配置:

script 
    NUM_CORES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/') 
    /path/to/the/app -t $NUM_CORES 
end script 
+0

問題在於'$()'分支了一個子進程(然後管道會導致另一個分叉),這會混淆fork跟蹤。如果你在實際的守護進程之前分叉了兩次以上,那麼舊版新貴不能跟蹤守護進程,然後重新生成將無法正常工作。這適用於zram-config,因爲它只運行一次,不需要重生,但它不是通用的。 :)這就是爲什麼@ mpm的答案是必要的。 – dannysauer

相關問題