一個 GNU 並行作業隊列腳本
我在 GitHub 上找到了一個腳本,我對它進行了一些修改,以適應我試圖在隊列中執行的程序的需要。
但是它不起作用,我不確定為什麼。它實際上從未將作業回顯到隊列文件。
這是 GitHub 頁面的連結:
https://gist.github.com/tubaterry/c6ef393a39cfbc82e13b8716c60f7824
這是我修改的版本:
#!/bin/sh END="END" true > queue tail -n+0 -f queue | parallel -j 16 -E "$END" while read i; do echo "command [args] > ${i%.inp}.log 2> ${i%.inp}.err" > queue done < "jobs.txt" echo "$END" >> queue echo "Waiting for jobs to complete" while [ "$(pgrep 'perl /usr/local/bin/parallel' | grep -evc 'grep' | tr -d " ")" -gt "0" ]; do sleep 1 done touch killtail mv killtail queue rm queue
我唯一能想到的是,其中一個步驟在 OpenBSD 上沒有按預期執行。但我重新安排了一個步驟,一切都執行沒有錯誤,但它只送出一個作業。更改
tail -n+0 -f queue | parallel -j 16 -E "$END"
在第一個 while 循環之後移動並更改true > queue
為,touch queue
因為我不太確定是什麼true > queue
意思。任何幫助,將不勝感激。
編輯:
我有一個 jobs.txt 文件,其中填充了輸入文件到我計劃執行的命令的路徑。jobs.txt 中的文件將是命令的參數之一,然後我將計算結果輸出到日誌文件,並將任何錯誤輸出到錯誤文件。
我的期望是每個作業將被添加到隊列中,並且並行將執行多達 16 個作業,每個核心一個作為命令的參數之一是每個計算使用一個核心。這將一直持續到它到達由 -E 參數表示的“END”以並行。
正如所寫,從jobs.txt 到隊列沒有任何迴聲。我會再試一次>>
我對原始腳本中的很多事情提出了質疑。我改變了我確定的東西,但我對某些功能感到非常困惑,並決定保持原樣。
我不清楚的其中一件事是 tail -n+0
我不知道那在做什麼
編輯2:
$ {PROGRAM} $ {工作}.inp $ {NCPU} > $ {JOB}.log 2> ${JOB}.err
$ {JOB} is a reference to anywhere between 1 and ∞ calculations depending on how many I need to do at a given time. Currently, jobs.txt has 374 individual tests that I need to run. $ {PROGRAM} 是獲取參數的軟體 $ {JOB}.inp and calculates accordingly. $ {NCPU} 是我希望每個作業使用多少個核心;目前我正在嘗試在 16 核處理器上串列執行每個作業。
目標是在不輸入完整命令的情況下將盡可能多的計算排隊。我只想生成一個列表
find calculations -name '*.inp' -print > jobs.txt
,然後執行一個腳本,如 SerialRun.sh 或 ParallelRun.sh 並讓它產生結果。根據不同的使用者選擇如何組織他們的工作,作業可能嵌套在許多不同的目錄中,這種使用 find 的方法使我能夠非常快速地送出作業並將結果生成到正確的路徑。隨著每次計算完成,我可以在系統繼續執行測試的同時分析數據。腳本很可能過於復雜。我正在尋找一個作業隊列系統,並找到了成為 GNU Parallel 項目的 nqs。我找不到很多並行隊列作業的範例,但在 GitHub 上遇到了該腳本並決定試一試。我對它的編寫方式有很多問題,但我對並行性的理解不足以質疑它。
我認為為它建立一個隊列應該比這更簡單一些。
編輯3:
也許正確的方法是這樣做:
while read i; do command "$i" > "${i%.inp}".log 2> "${i%.inp}".err | parallel -j 16 done < "jobs.txt"
那行得通嗎?
您不需要這個複雜
parallel
的腳本,可以自己做任何事情。只需使用或您選擇的任何其他工具.inp
從文件列表中刪除副檔名,然後將基本名稱輸入如下:sed``parallel
sed 's/\.inp//' jobs.txt | parallel -j 16 "${PROGRAM} {}.inp > {}.log 2> {}.err"
這假設您的文件名沒有空格或換行符,如果有,您需要在帶引號的命令中引用它們:
sed 's/\.inp//' jobs.txt | parallel -j 16 "${PROGRAM} '{}.inp' > '{}.log' 2> '{}.err'"
該
{}
符號是並行基本功能的一部分,描述man parallel
如下:{} 輸入行。
此替換字元串將替換為從輸入源讀取的完整行。輸入源通常是標準輸入(標準輸入),但也可以用
--arg-file
、:::
或給出::::
。所以它只是被你傳遞給並行的任何東西所取代,在這種情況下,文件名列表及其副檔名被
sed
.或者,您可以使用
{.}
which is:{.} 不帶副檔名的輸入行。
此替換字元串將被刪除副檔名的輸入替換。如果輸入行包含 . 在最後一個 / 之後,最後一個 。直到字元串的末尾將被刪除並且 {.} 將被剩餘的替換。例如 foo.jpg 變成 foo,subdir/foo.jpg 變成 subdir/foo,sub.dir/foo.jpg 變成 sub.dir/foo,sub.dir/bar 仍然是 sub.dir/bar。如果輸入行不包含 . 它將保持不變。
替換字元串 {.} 可以使用 –extensionreplace 更改
有了這個,你甚至不需要
jobs.txt
文件。如果您的所有文件都在同一個目錄中,您可以執行以下操作:parallel -j 16 "${PROGRAM} {.}.inp > {.}.log 2> {.}.err" ::: *.inp
或者,要使其遞歸地進入子目錄,假設您正在使用
bash
,您可以執行以下操作:shopt -s globstar parallel -j 16 "${PROGRAM} {.}.inp > {.}.log 2> {.}.err" ::: **/*.inp