2016-08-08 46 views
1

我想在固定數量的處理器上動態運行一些進程。我想將輸出打印到每個進程的唯一文件,但是xargs沒有使用就地文件名爲每個進程創建單獨的文件時出現問題。發送命令輸出到一個獨特的文件在Bash中使用xargs

的bash腳本調用csh腳本並低於:

$ cat temp | xargs -P 8 % csh '%'.csh >& '%'.log 

如果溫度是csh命令名稱的文本文件。

我的問題是,xargs需要%.log字面上和不斷覆蓋文件的過程寫入它,而不是根據需要單獨的.log文件。

我運行該腳本$ bash run.bash &

回答

0

一般情況下,使用字符串替換替換到代碼是一個壞主意 - 在你的情況,如果你有一個腳本惡意的名稱,該名稱可以用來運行任意命令。 (當然,你正在執行這個腳本,但是在純粹處理數據和輸出文件名的情況下也是如此 - 所以最好養成一種健壯的方法)。

傳遞名稱作爲參數的腳本,而不是代他們到腳本(如xargs會做,如果你加入-I-J參數固定的用法:

# best-practice approach: run a completely fixed shell script, passing arguments on 
# its command line. 
xargs -P 8 -n 1 \ 
    sh -c 'for x; do csh "${x}.csh" >"${x}.log" 2>&1; done' _ 

你請注意,有一個sh -c實例被調用:這是必需的,因爲xargs本身不理解shell操作,例如重定向;如果您想要執行重定向,則需要一個shell才能執行。


現在,讓我們多一點到,爲什麼你的原碼的表現,因爲它沒有:

xargs -P 8 % csh '%'.csh >& '%'.log 

... 第一執行重定向到%.log然後運行命令

xargs -P 8 % csh '%'.csh 

xargs沒有機會取代%.log因爲該重定向是在命令完全運行之前由封裝外殼執行的。

+0

感謝您的詳細解答。 –

+0

@WillPhilpott,如果這可以解決您的問題,請考慮點擊答案旁邊的複選框以標記已回答的問題。 –

0

使用GNU並行它看起來像這樣:

cat temp | parallel -P 8 'csh {}.csh >& {}.log' 

如果你有8個內核,你甚至可以做:

cat temp | parallel 'csh {}.csh >& {}.log' 

GNU並行報價{}從而不會被執行惡意輸入。

相關問題