我偶尔会像这样运行bash命令行:

n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done

在一行中运行some_command多次——在本例中为10次。

通常some_command实际上是一个命令链或管道。

有没有更简洁的方法呢?


当前回答

脚本文件

bash-3.2$ cat test.sh 
#!/bin/bash

echo "The argument is  arg: $1"

for ((n=0;n<$1;n++));
do
  echo "Hi"
done

下面是输出

bash-3.2$  ./test.sh 3
The argument is  arg: 3
Hi
Hi
Hi
bash-3.2$

其他回答

使用常量:

for ((n=0;n<10;n++)); do
    some_command; 
done

使用变量(可以包括数学表达式):

x=10; for ((n=0; n < (x / 2); n++)); do some_command; done

如果你的范围有一个变量,使用seq,像这样:

count=10
for i in $(seq $count); do
    command
done

简单:

for run in {1..10}; do
  command
done

或者作为一行程序,供那些想要轻松复制和粘贴的人使用:

for run in {1..10}; do command; done

bash配置文件中的一个简单函数(~/。Bashrc经常)可以很好地工作。

function runx() {
  for ((n=0;n<$1;n++))
    do ${*:2}
  done
}

这样叫它。

$ runx 3 echo 'Hello world'
Hello world
Hello world
Hello world

脚本文件

bash-3.2$ cat test.sh 
#!/bin/bash

echo "The argument is  arg: $1"

for ((n=0;n<$1;n++));
do
  echo "Hi"
done

下面是输出

bash-3.2$  ./test.sh 3
The argument is  arg: 3
Hi
Hi
Hi
bash-3.2$

Xargs速度很快:

#!/usr/bin/bash
echo "while loop:"
n=0; time while (( n++ < 10000 )); do /usr/bin/true ; done

echo -e "\nfor loop:"
time for ((n=0;n<10000;n++)); do /usr/bin/true ; done

echo -e "\nseq,xargs:"
time seq 10000 | xargs -I{} -P1 -n1 /usr/bin/true

echo -e "\nyes,xargs:"
time yes x | head -n10000 |  xargs -I{} -P1 -n1 /usr/bin/true

echo -e "\nparallel:"
time parallel --will-cite -j1 -N0 /usr/bin/true ::: {1..10000}

在现代64位Linux上,给出:

while loop:

real    0m2.282s
user    0m0.177s
sys     0m0.413s

for loop:

real    0m2.559s
user    0m0.393s
sys     0m0.500s

seq,xargs:

real    0m1.728s
user    0m0.013s
sys     0m0.217s

yes,xargs:

real    0m1.723s
user    0m0.013s
sys     0m0.223s

parallel:

real    0m26.271s
user    0m4.943s
sys     0m3.533s

这是有意义的,因为xargs命令是一个单独的本机进程,多次生成/usr/bin/true命令,而不是在Bash中解释的for和while循环。当然,这只适用于单个命令;如果你需要在每次循环迭代中执行多个命令,它将和传递sh -c 'command1;command2;...'到xargs

也可以将-P1改为-P8,以并行生成8个进程,从而获得另一个巨大的速度提升。

我不知道GNU并行为什么这么慢。我本以为它可以与xargs相媲美。