我正在尝试编写一个脚本,它使用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")'
该脚本主要工作,但它跳过第一个文件每次命令运行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 -c
或bash -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_name
是a
, argument
是b
argument
是c
因此,在命令字符串$0
将扩展到a
, $1
到b
, $2
到c
, $@
特殊参数将扩展到bc
。
所以,如果你想在命令字符串中使用command_name
,请参考特殊参数零,即$0
。