xargs sh -c跳过第一个参数

我正在尝试编写一个脚本,它使用findxargs将大文件中的旧文件归档。 这是行:

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")' 

该脚本主要工作,但它跳过第一个文件每次命令运行1000个文件,我似乎无法弄清楚为什么。

这里是另一个例子(我试着玩简单的命令来看看会发生什么:

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

 $ echo abcdef| xargs -n 2 echo "$@" ab cd ef $ echo abcdef| xargs -n 3 echo "$@" abc def 

另一方面,如果我想每次打印每一组时,我都会添加sh -c来添加一串命令:

 $ echo abcdef| xargs -n 2 sh -c 'echo "$@"; sleep 1;' b d f $ echo abcdef| xargs -n 3 sh -c 'echo "$@"; sleep 1;' bc ef 

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

任何想法可能会发生在这里?

提前致谢! 让我知道如果你需要任何额外的信息,我很乐意提供。

sh -cbash -c第一个参数是脚本的名字,例如$0 ,当你使用$@时不打印。

例子:

 echo abcdef| xargs -n 3 bash -c 'echo "$0 $@"' abc def 

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

 echo abcdef| xargs -n 3 bash -c 'echo "$@"' _ abc def 

即使以你的sleep为例,它也能正常工作:

 echo abcdef| xargs -n 3 bash -c 'echo "$@"; sleep 1' _ abc def 

在Shell命令语言中@ 特殊参数

从一个开始扩展到位置参数。

sh命令的调用方式如下:

 sh -c[OPTIONS] command_string [command_name [argument...]] 

-c选项的文档:

从command_string操作数读取命令。 根据剩下的参数操作数,依次从command_name操作数的值和位置参数( $1$2等)中设置特殊参数0的值(请参见特殊参数)。

例如,在以下命令中:

 sh -c 'tar czvf arch.tar.gz $@' abc 
  • command_string'tar czvf arch.tar.gz $@'
  • command_namea
  • 第一个argumentb
  • 第二个argumentc

因此,在命令字符串$0将扩展到a$1b$2c$@特殊参数将扩展到bc

所以,如果你想在命令字符串中使用command_name ,请参考特殊参数零,即$0