xargs sh -c 跳过第一个参数
xargs sh -c skipping the first argument
我正在尝试编写一个使用 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 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
另一方面,如果每次打印每组都想休眠,我加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
看到第一项是如何被跳过的了吗?
对这里可能发生的事情有什么想法吗?
提前致谢!如果您需要任何额外信息,请告诉我,我很乐意提供。
sh -c
或 bash -c
的第一个参数是脚本的名称,即 [=15=]
,当您使用 $@
:
时不会打印出来
示例:
echo a b c d e f| xargs -n 3 bash -c 'echo "[=10=] $@"'
a b c
d e f
要解决此问题,您可以将 _
作为脚本的虚拟名称传递,然后它应该可以工作:
echo a b c d e f| xargs -n 3 bash -c 'echo "$@"' _
a b c
d e f
即使使用您的 sleep
示例也能正常工作:
echo a b c d e f| xargs -n 3 bash -c 'echo "$@"; sleep 1' _
a b c
d e f
在Shell命令语言中@
special parameter
Expands to the positional parameters, starting from one.
sh
命令的调用形式如下:
sh -c[OPTIONS] command_string [command_name [argument...]]
来自 -c
选项的文档:
Read commands from the command_string operand. Set the value of special parameter 0
(see Special Parameters) from the value of the command_name
operand and the positional parameters (</code>, <code>
, and so on) in sequence from the remaining argument operands.
例如,在下面的命令中:
sh -c 'tar czvf arch.tar.gz $@' a b c
command_string
是 'tar czvf arch.tar.gz $@'
,
command_name
是 a
,
- 第一个
argument
是b
- 第二个
argument
是c
因此,在命令字符串中 [=27=]
将扩展为 a
,</code> 将扩展为 <code>b
,</code> 将扩展为 <code>c
,并且$@
特殊参数将扩展为 b c
.
因此,如果要在命令字符串中使用command_name
,请参考特殊参数零,即[=27=]
。
我正在尝试编写一个使用 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 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
另一方面,如果每次打印每组都想休眠,我加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
看到第一项是如何被跳过的了吗?
对这里可能发生的事情有什么想法吗?
提前致谢!如果您需要任何额外信息,请告诉我,我很乐意提供。
sh -c
或 bash -c
的第一个参数是脚本的名称,即 [=15=]
,当您使用 $@
:
示例:
echo a b c d e f| xargs -n 3 bash -c 'echo "[=10=] $@"'
a b c
d e f
要解决此问题,您可以将 _
作为脚本的虚拟名称传递,然后它应该可以工作:
echo a b c d e f| xargs -n 3 bash -c 'echo "$@"' _
a b c
d e f
即使使用您的 sleep
示例也能正常工作:
echo a b c d e f| xargs -n 3 bash -c 'echo "$@"; sleep 1' _
a b c
d e f
在Shell命令语言中@
special parameter
Expands to the positional parameters, starting from one.
sh
命令的调用形式如下:
sh -c[OPTIONS] command_string [command_name [argument...]]
来自 -c
选项的文档:
Read commands from the command_string operand. Set the value of special parameter
0
(see Special Parameters) from the value of thecommand_name
operand and the positional parameters (</code>, <code>
, and so on) in sequence from the remaining argument operands.
例如,在下面的命令中:
sh -c 'tar czvf arch.tar.gz $@' a b c
command_string
是'tar czvf arch.tar.gz $@'
,command_name
是a
,- 第一个
argument
是b
- 第二个
argument
是c
因此,在命令字符串中 [=27=]
将扩展为 a
,</code> 将扩展为 <code>b
,</code> 将扩展为 <code>c
,并且$@
特殊参数将扩展为 b c
.
因此,如果要在命令字符串中使用command_name
,请参考特殊参数零,即[=27=]
。