xargs sh -c 跳过第一个参数

Gui*_*des 4 linux bash shell find xargs

我正在尝试编写一个脚本,该脚本使用 find 和 xargs 将旧文件归档到一个大目录中。这是行:

find /tmp/messages/ -mtime +9 -print0 | xargs -x -t -0 -n 1000 sh -c 'tar rPf /tmp/backup.tar "$@" && rm -f "$@"; sleep 1 && echo Finished one loop: $(date +"%T")'
Run Code Online (Sandbox Code Playgroud)

该脚本主要工作,但每次运行 1000 个文件的命令时它都会跳过第一个文件,我似乎无法弄清楚原因。

这是另一个示例(我尝试使用更简单的命令来查看会发生什么:

如果我只使用 echo 和 xargs,我可以有效地运行一个命令:

$ echo a b c d e f| xargs -n 2 echo "$@"
a b
c d
e f
$ echo a b c d e f| xargs -n 3 echo "$@"
a b c
d e f
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我每次打印每组都想睡觉,则添加 sh -c 以添加一串命令:

$ echo a b c d e f| xargs -n 2 sh -c 'echo "$@"; sleep 1;'
b
d
f
$ echo a b c d e f| xargs -n 3 sh -c 'echo "$@"; sleep 1;'
b c
e f
Run Code Online (Sandbox Code Playgroud)

看看第一个项目是如何被跳过的?

关于这里会发生什么的任何想法?

提前致谢!如果您需要任何额外信息,请告诉我,我很乐意提供。

anu*_*ava 5

sh -c或 的第一个参数bash -c是脚本的名称,即$0在您使用时不会打印$@:

例子:

echo a b c d e f| xargs -n 3 bash -c 'echo "$0 $@"'
a b c
d e f
Run Code Online (Sandbox Code Playgroud)

要解决此问题,您可以_作为脚本的虚拟名称传递,然后它应该可以工作:

echo a b c d e f| xargs -n 3 bash -c 'echo "$@"' _
a b c
d e f
Run Code Online (Sandbox Code Playgroud)

即使使用您的sleep示例,它也能正常工作:

echo a b c d e f| xargs -n 3 bash -c 'echo "$@"; sleep 1' _
a b c
d e f
Run Code Online (Sandbox Code Playgroud)

  • @SenthilAKumar:使用`echo abcdef| xargs sh -c '对于我;回显“$i”;完成'_` (2认同)