当参数列表太长时,如何正确使用“xargs”

时间:2009-03-25 22:28:26

标签: linux bash unix

有人可以给我一个在下面的操作中使用xargs的例子吗?

tar c $dir/temp/*.parse\
    | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma

我从bash“ / bin / tar:参数列表太长”中得到错误

我特意试图对大约4,500个文件进行LZMA压缩;所以这并不奇怪。我只是不知道如何修改上面使用xargs并摆脱错误!感谢。

5 个答案:

答案 0 :(得分:11)

扩展CristopheDs回答并假设你正在使用bash:

tar c --files-from <(find $dir/temp -maxdepth 1 -name "*.parse") | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma

xargs这里没有帮助的原因是它会在使用所有参数之前进行多次调用。这对您没有帮助,因为这将创建几个 tar档案,这是您不想要的。

答案 1 :(得分:10)

作为旁注:

始终,始终避免使用xargs(1)。它是一个破坏的工具,只有在使用-0选项时才有用。即便如此,使用find(1)的-exec选项或简单的for或while循环几乎总是更好。

为什么xargs如此糟糕?首先,它在空格上拆分输入,这意味着所有包含空格的文件名都会造成严重破坏。其次,尝试成为smartass,解析引用。当你在文件名上使用包含引号作为文件名的一部分时,只会导致更多的麻烦,例如歌曲:“我不想错过任何东西.mp3 ”。这只会使xargs呕吐并诅咒你严重引用其输入。不,你没有:它应该只知道引号不属于输入数据,它们属于shell脚本,并且xargs没有尝试解析它们的业务。

请注意,当您将-0传递给它时,xargs(1)不执行空格分割或引用解析。它执行正确的事情,它使用NULL字节来分隔文件名。但这意味着您需要为其提供使用NULL字节分隔文件名的输入(例如“ find -foo -print0 ”)。这让我们回过头来:最好只使用find的-exec:“ find -foo -exec bar {} + ”。

答案 2 :(得分:4)

使用find将“想要的”文件名传递给临时文件, 然后使用'--files-from'命令行选项使用tar。

修改

或将它们直接相互管道以避免临时文件。

所以:使用find列出想要的文件名| tar ... --files-from

答案 3 :(得分:4)

也许你想要这样的东西?

find $dir/temp/ -name '*.parse' -print0 | tar --null -T - -c | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma

答案 4 :(得分:0)

由于你在Linux上,你有GNU tar,你可以使用'-F -'或'--files-from'选项来读取文件名。

但是,您也可以使用:

- use-compress-program =“lzma -9”

指定要使用的压缩程序,并简单地将压缩文件名作为'tar'命令的目标文件。

在添加“-j”选项之前,这是“bzip2”压缩所必需的。