使用最大参数循环执行命令

时间:2017-08-08 15:01:00

标签: arrays shell loops command-line-arguments

我有一个程序可以同时处理~256个文件(编辑:命令行参数号给出的限制);我必须在我拥有的许多文件上执行它(超过100k)。

要做到这一点,现在,我正在使用一个简单的循环,为每个文件一个一个地调用我的程序。

FILESLIST="$(find /folder/where/the/files/are/ -name '*.xml' 2>/dev/null)"
FILESTAB=($FILESLIST)

for f in "${FILESTAB[@]}"
do
    ./myProgram $f || break
done

但是为了提高我的进程速度,我需要每次使用多个单独文件的程序,如下所示:

./myProgram path/to/file1.xml path/to/file2.xml ...

我想到了类似的事情,但我找不到一个好主意(见评论):

FILESLIST="$(find /folder/where/the/files/are/ -name '*.xml' 2>/dev/null)"
FILESTAB=($FILESLIST)

while [ ${#FILESTAB[@]} -gt 256 ]
do
    ListOf256FilesNames=$FILETAB[0:256]        # << My problem is to do this
    FILETAB=$FILETAB[256:end] # shifting array # <<   and do this too

    ./myProgram $ListOf256FilesNames  # << this works supposing the 2 lines before works
done

./myProgram $FILESTAB  # do the work for remaining files

是否有类似我想做的工作,或者您是否有任何想法以其他方式做到这一点?

1 个答案:

答案 0 :(得分:1)

假设您的真正的目标是避免超出您的操作系统环境变量和参数的最大允许空间量,那么您最好不要让{{1} }或find这样做对你有用。 (当你在一个批处理中获得一堆异常长的文件名时,这也可以避免无意中发生,或者当你的名字真的很短并且可能更多时,通过运行额外的进程来浪费CPU)。

最佳实践:让xargs做分部

与每个文件名运行一个命令的find不同,-exec ... {} ... \;将尽可能多的参数放在每个命令行上。这是自2007年以来符合POSIX标准。

-exec ... {} +

替代方案:GNU find /folder/where/the/files/are -name `*.xml` -exec ./myProgram '{}' +

使用xargsfind -0以与旧工具兼容的方式提供可比较的功能:

xargs -0

如果确实想要告诉find /folder/where/the/files/are -name `*.xml` -print0 | xargs -0 ./myProgram 每个调用传递的参数不超过256个,那么你可以创建xargs

次优:究竟是什么被要求

xargs -n 256 -0 ./myProgram