
我目前正在測試 gnu Parallel 以使用 bash 在多個伺服器之間分發比較命令。在其最基本的功能中,此比較命令需要兩個輸入進行比較(oracle 資料庫登入),並需要透過 -o 輸出檔案名稱。程式至少需要一項載入、儲存或直接上傳操作。
compare -o cmp.input1.input2.dat Input1 Input2
我有數千個這樣的輸入對,並建立一個包含所有組合的文件,以便每一行包含輸出文件名稱和程式所需的資料庫標識符
#test_parallel
-o cmp.input1.input2.dat Input1 Input2
-o cmp.input1.input3.dat Input1 Input3
-o cmp.input2.input3.dat Input2 Input3
[...]
並使用並行執行命令,但是比較命令失敗
parallel -a test_parallel "compare {}"
ERROR: No action specified for results (load, save or direct upload)
usage: compare [-u][-o <file>] query target
使用--dryrun
模式,這就是並行執行的內容:
compare -o\ cmp.input1.input2.dat\ Input1\ Input2
由於某種我不明白的原因,比較程式無法正確處理轉義的空白。在 bash 中執行此命令會產生完全相同的錯誤訊息。刪除 -o 標誌後的轉義符(我可以將 -o 移至並行命令)會導致“參數過多”錯誤。刪除所有轉義符會如預期執行命令。
是否可以告訴並行不在命令呼叫上列印轉義?我似乎在文檔中找不到任何內容,除了這是預期的預設行為,如圖所示parallel --shellquote
答案1
GNU Parallel 將輸入視為單一參數並以引號引起來,以便您可以安全地使用檔案名,例如:
My brother's 12" records costs 30$ each.txt
在您的情況下,您希望 shell 解析參數,因此空格將不被引用:
parallel -a test_parallel eval compare {}
或者你可以在空間上分割:
parallel --colsep ' ' -a test_parallel compare {1} {2} {3} {4}
但既然你想比較所有與所有,你可以做得更優雅:
parallel cmp -o ../out/cmp.{1}.{2} {1} {2} ::: Input* ::: Input*
這會將所有輸入*與所有輸入*進行比較。您--results
可以在目錄中獲得結構良好的輸出:
parallel --results out/ cmp {1} {2} ::: Input* ::: Input*
但如果你想cmp InputY InputX
在跑步後跳過跑步cmd InputX InputY
,那麼你可以這樣做:
parallel --results out/ cmp {=1' $arg[1] ge $arg[2] and $job->skip();' =} {2} ::: Input* ::: Input*
編輯:
20190722版本引入了該功能uq
。
parallel -a test_parallel compare {=uq=}
uq
是一個perl函數。呼叫時,GNU Parallel 將避免引用該替換字串。因此,您可以混合帶引號和不帶引號的替換字串:
parallel echo {} = {=uq=} ::: \$PWD
# You can change $_ if you want: uq() is a normal perl function
parallel echo {}ME = '{=uq(); $_.="ME"=}' ::: \$HO \$LOGNA