可以使用xargs链接命令

时间:2014-09-19 14:51:25

标签: bash xargs

我想在卷曲的电话之间睡一觉:

ssh someone@somehost "cd /export/home/someone && find . -name '*' -print| xargs -n1 curl -u someone:password ftp://somehost/tmp/ -vT"

不确定是否可以完成。尝试了几十种排列。可以在开始/结束时睡觉,但不能在两者之间睡觉。 非常感谢

5 个答案:

答案 0 :(得分:3)

xargs接受一个命令。你需要让这个命令做两件事。

尝试

| xargs -n1 bash -c 'curl ... "$0"; sleep ##'

或(使用"普通"位置参数,您需要手动填写$0)。

| xargs -n1 bash -c 'curl ... "$1"; sleep 1' -

答案 1 :(得分:2)

这个问题的有趣部分是卷发之间的睡眠,而不是卷发序列的开始或结束。

如果您没有太多文件,那么某些值“太多”[注1]

find . -type f --exec bash -c '
    doit() { curl -u someone:password ftp://somehost/tmp/ -vT; }
    doit "$1"; for f in "${@:2}"; sleep 2; doit "$f"; done
    ' _ {} +

我将find条件从-name *(将匹配所有文件和目录)更改为-type f,这只会匹配常规文件。

上面的命令行使用find来调用(--exec)一个显式的子shell(bash -c),并将大量的文件名作为参数传递({} + )。 (_是因为bash -c script的第一个参数被视为$0,而不是$1。)提供给bash -c的脚本只是循环遍历其参数,使用便利功能doit(如果你想用不同的命令使用这个想法,你可以轻松地重新定义。)

你可能不需要find,因为你实际上并不关心递归匹配,在这种情况下你可以简化一点。另外,使用bash 4,你可以使用**进行递归通配,虽然**也会匹配子目录,所以你需要对它们进行过滤。

这是一个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

备注:

  1. 不幸的是,文件的最大数量取决于系统,并且取决于可用于参数和环境变量的内存量(因此取决于环境变量的总大小)。在我的系统(Ubuntu)上,最大值大约是128千字节的文件名,这可能是几千个文件,除非你使用很长的文件名。如果超过此限制,bash -c调用将被执行多次,并且在第二次和后续调用之前不会有睡眠,这意味着每隔几千个文件中的一个文件将在没有事先睡眠的情况下上传。另一方面,2000个文件的休眠时间超过一个小时,因此我认为这种限制很可能不适用。

答案 2 :(得分:0)

而不是xargs你可以使用子shell:

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

答案 3 :(得分:0)

如果你有GNU Parallel,你可以运行:

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访问权限的多台机器上并行运行作业。

如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:

Simple scheduling

GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:

GNU Parallel scheduling

<强>安装

个人安装不需要root访问权限。这可以在10秒内完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解详情

查看更多示例:http://www.gnu.org/software/parallel/man.html

观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel

答案 4 :(得分:-1)

你可以使用循环。

ssh someone@somehost "for i in `ls`; do curl -u someone:password ftp://somehost/tmp/ -vT ; sleep 10;done"