簡體   English   中英

使用xargs在帶有參數的多個輸入列表上運行bash腳本

[英]Using xargs to run bash scripts on multiple input lists with arguments

我試圖在多個文件列表上運行腳本,同時還並行傳遞參數。 我有file_list1.dat,file_list2.dat,file_list3.dat。 我想運行接受3個參數的script.sh:arg1、arg2、arg3。

對於一個運行,我會這樣做:

sh script.sh file_list1.dat $arg1 $arg2 $arg3

我想針對所有文件列表並行運行此命令。

我的嘗試:

Ncores=4
ls file_list*.dat | xargs -P "$Ncores" -n 1 [sh script.sh [$arg1 $arg2 $arg3]]

這將導致錯誤:-P選項的數字無效。 我認為此命令的順序是錯誤的。

我的第二次嘗試:

echo $arg1 $arg2 $arg3 | xargs ls file_list*.dat | xargs -P "$Ncores" -n 1 sh script.sh

但這會導致錯誤:xargs:ls:被信號13終止

關於使用xargs將參數傳遞給bash腳本的正確語法的任何想法?

我不確定我確切了解您想要做什么。 是否可以並行執行這些命令?

sh script.sh $arg1 $arg2 $arg3 file_list1.dat
sh script.sh $arg1 $arg2 $arg3 file_list2.dat
sh script.sh $arg1 $arg2 $arg3 file_list3.dat
...etc

如果是正確的話,這應該可以工作:

Ncores=4
printf '%s\0' file_list*.dat | xargs -0 -P "$Ncores" -n 1 sh script.sh "$arg1" "$arg2" "$arg3"

您的版本中的兩個主要問題是,您將“ Ncores”作為文字字符串傳遞(而不是使用$Ncores獲取變量的值),並且在命令和參數周圍使用了[ ] (只是任何相關的Shell語法)。 我還在所有變量引用周圍添加了雙引號(通常是一種很好的做法),並使用了printf '%s\\0' (和xargs -0 )而不是ls

為什么我用printf代替ls 因為ls在這里沒有做任何有用的事情,例如printfecho或其他做不到的事情。 您可能將ls作為獲取文件名列表的工具,但是在這種情況下, 運行命令之前 ,通配符表達式file_list*.dat會擴展為文件列表。 ls要做的就是看每個文件,對自己說“是的,那是一個文件”,然后打印出來。 echo可以以更少的開銷執行相同的操作。 但是,使用lsecho ,如果任何文件名包含空格,引號或其他有趣的字符,則輸出可能是不明確的。 某些版本的ls試圖通過在引號或帶有有趣字符的文件名周圍添加一些內容來“修復”此問題,但這可能與xargs解析其輸入的方式匹配(或完全不匹配)(如果確實發生)。

但是printf '%s\\0'是明確且可預測的-它打印每個字符串(在這種情況下為文件名),后跟一個NULL字符,這正是xargs -0用作輸入的內容,因此不會出現混淆或錯誤解析的機會。

好吧,好吧,這是一種極端的情況:如果沒有任何匹配的文件,通配符模式將按字面意義通過,並且最終將嘗試使用未擴展的字符串“ file_list * .dat”運行腳本作為爭論。 如果要避免這種情況,請在此命令前使用shopt -s nullglob (然后再使用shopt -u nullglob以返回正常模式)。

哦,還有一件事: sh script.sh並不是運行腳本的最佳方法。 在開始時給腳本一個適當的shebang行(如果僅使用基本的shell功能,則為#!/bin/sh如果使用任何bashisms則為 #!/bin/bash#!/usr/bin/env bash ),然后運行它與./script.sh

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM