[英]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
在這里沒有做任何有用的事情,例如printf
或echo
或其他做不到的事情。 您可能將ls
作為獲取文件名列表的工具,但是在這種情況下, 在運行命令之前 ,通配符表達式file_list*.dat
會擴展為文件列表。 ls
要做的就是看每個文件,對自己說“是的,那是一個文件”,然后打印出來。 echo
可以以更少的開銷執行相同的操作。 但是,使用ls
或echo
,如果任何文件名包含空格,引號或其他有趣的字符,則輸出可能是不明確的。 某些版本的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.