Bash 可以使用xargs链接命令
我想在调用curl的ea之间进行睡眠:Bash 可以使用xargs链接命令,bash,xargs,Bash,Xargs,我想在调用curl的ea之间进行睡眠: ssh someone@somehost "cd /export/home/someone && find . -name '*' -print| xargs -n1 curl -u someone:password ftp://somehost/tmp/ -vT" 我不确定能不能做到。已经尝试了几十种排列方式。可以在开始/结束时睡觉,但不能在中间休息。 非常感谢您可以在其中使用循环 ssh someone@somehost "for i
ssh someone@somehost "cd /export/home/someone && find . -name '*' -print| xargs -n1 curl -u someone:password ftp://somehost/tmp/ -vT"
我不确定能不能做到。已经尝试了几十种排列方式。可以在开始/结束时睡觉,但不能在中间休息。
非常感谢您可以在其中使用循环
ssh someone@somehost "for i in `ls`; do curl -u someone:password ftp://somehost/tmp/ -vT ; sleep 10;done"
xargs只接受一个命令。您需要使用单个命令来完成两件事 试一试 或者(要使用“普通”位置参数,需要手动填写
$0
)
您可以使用子shell而不是
xargs
:
ssh someone@somehost 'cd /export/home/someone && find . -name "*" -print| (while read file; do curl -u someone:password ftp://somehost/tmp/ -vT "$file"; sleep 10; done)'
请注意,我还翻转了单引号和双引号,以便本地shell不会试图解释
$file
这个问题的有趣部分是在卷发之间获得睡眠,而不是在卷发序列的开始或结束
如果您没有太多的文件,对于某些值“太多”[注1]
我将查找
标准从-name*
(将匹配所有文件和目录)更改为-type f
,它将只匹配常规文件
上面的命令行通过使用find
调用(使用--exec
)显式子shell(bash-c
)将大量文件名作为参数传递给它({}+
)。(之所以使用。
是因为bash-c脚本的第一个参数被视为$0
,而不是$1
。提供给bash-c
的脚本只需使用便利函数doit
(如果您想使用不同的命令,可以很容易地重新定义该函数)
您可能并不真正需要find
,因为您实际上并不关心递归匹配,在这种情况下,您可以将其简化一点。此外,在bash4中,您可以使用***
进行递归全局搜索,尽管***
也将匹配子目录,因此您需要过滤掉这些子目录
下面是一个bash 4示例:
doit() { curl -u someone:password ftp://somehost/tmp/ -vT; }
shopt -s globstar
sleep=
for f in **; do if [[ -f $f ]]; then
$sleep
doit "$f"
sleep="sleep 2"
fi done
注意事项:
不幸的是,文件的最大数量取决于系统,并且取决于参数和环境变量可用的内存量(因此取决于环境变量的总大小)。在我的系统(Ubuntu)上,文件名的最大值约为128 KB,除非使用很长的文件名,否则可能是几千个文件。如果超过此限制,则bash-c
调用将执行多次,并且在第二次和后续调用之前不会有休眠,这意味着每几千个文件中就有一个文件将在没有事先休眠的情况下上载。另一方面,2000个文件的睡眠时间加起来超过一个小时,所以我认为这一限制不大可能适用
如果您有GNU并行,您可以运行:
ssh someone@somehost "cd /export/home/someone && find . -name '*' -print |
parallel -j1 'sleep 10;curl -u someone:password ftp://somehost/tmp/ -vT'
所有新计算机都有多核,但大多数程序本质上是串行的,因此不会使用多核。但是,许多任务是非常可并行的:
- 在许多文件上运行相同的程序
- 对文件中的每一行运行相同的程序
- 对文件中的每个块运行相同的程序
GNU Parallel是一个通用的并行程序,它使得在同一台机器上或在您有ssh访问权的多台机器上并行运行作业变得非常容易
如果您有32个不同的作业要在4个CPU上运行,并行化的直接方法是在每个CPU上运行8个作业:
GNU Parallel会在完成时生成一个新进程—使CPU保持活动状态,从而节省时间:
安装
个人安装不需要root访问权限。通过执行以下操作,可在10秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅
了解更多信息
请参阅更多示例:
观看介绍视频:
浏览本教程:
注册电子邮件列表以获得支持:您是否可以不执行第一个命令;睡眠10;第二个命令
或第一个命令&&sleep 10 |第二个命令
如果必须使用管道?为什么需要睡眠?另外,它看起来像find/export/home/someone-execcurl-usomeone:password-vT{}ftp://somehost/tmp/
也可以。如果您使用的是bash
4,您甚至不需要find
:shopt-s globstar;curl-u someone:password-vT/export/home/someone/***
让shell为您提供它<代码>用于i in*代码>。我可能过度解释了这个相当电报式的问题,但我的印象是,他们不想在开始或结束时睡觉,只是在两者之间。@rici我认为你过度解释了这个请求。我认为问题的关键在于,他们可以在系列的开始或结束时睡眠,但不能在调用之间睡眠(以在请求之间产生延迟,如wget-w
),而不是在开始/结束时睡眠是不可接受的。但你的解释肯定要困难得多。
doit() { curl -u someone:password ftp://somehost/tmp/ -vT; }
shopt -s globstar
sleep=
for f in **; do if [[ -f $f ]]; then
$sleep
doit "$f"
sleep="sleep 2"
fi done
ssh someone@somehost "cd /export/home/someone && find . -name '*' -print |
parallel -j1 'sleep 10;curl -u someone:password ftp://somehost/tmp/ -vT'
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash