Есть ли лучший способ выполнить команду N раз в Bash? - PullRequest
257 голосов
/ 17 сентября 2010

Иногда я запускаю командную строку bash, например:

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

Для запуска some_command несколько раз подряд - в данном случае 10 раз.

Часто some_command - это действительно цепочка команд или конвейер.

Есть ли более лаконичный способ сделать это?

Ответы [ 19 ]

5 голосов
/ 13 ноября 2014
for _ in {1..10}; do command; done   

Обратите внимание на подчеркивание вместо использования переменной.

3 голосов
/ 07 ноября 2016

Если вы делаете это периодически, вы можете запустить следующую команду, чтобы запускать ее каждую 1 секунду в течение неопределенного времени.Вы можете установить другие пользовательские проверки для запуска n раз.

watch -n 1 some_command

Если вы хотите получить визуальное подтверждение изменений, добавьте --differences до ls command.

Согласно справочной странице OSX, есть также

Опция --cumulative делает подсветку «закрепленной», отображая текущее отображение всех позиций, которые когда-либо менялись.Параметр -t или --no-title отключает заголовок, показывающий интервал, команду и текущее время в верхней части экрана, а также следующую пустую строку.

Linux / Unixman-страницу можно найти здесь

2 голосов
/ 19 мая 2017

Я решил с помощью этого цикла, где repeat - целое число, представляющее номер цикла

repeat=10
for n in $(seq $repeat); 
    do
        command1
        command2
    done
1 голос
/ 06 июля 2017

Немного наивно, но это то, что я обычно вспоминаю на макушке:

for i in 1 2 3; do
  some commands
done

Очень похоже на ответ @ joe-koberg.Его лучше, особенно если вам нужно много повторений, мне сложнее запомнить другой синтаксис, потому что в последние годы я не часто использую bash.Я имею в виду не для сценариев, по крайней мере.

1 голос
/ 18 января 2017

Еще один ответ: используйте расширение параметров для пустых параметров:

# calls curl 4 times 
curl -s -w "\n" -X GET "http:{,,,}//www.google.com"

Проверено на Centos 7 и MacOS.

1 голос
/ 23 декабря 2016

Все существующие ответы требуют bash и не работают со стандартным BSD UNIX /bin/sh (например, ksh в OpenBSD ).

Приведенный ниже код должен работать на любом BSD:

$ echo {1..4}
{1..4}
$ seq 4
sh: seq: not found
$ for i in $(jot 4); do echo e$i; done
e1
e2
e3
e4
$
0 голосов
/ 10 февраля 2017

Файл скрипта

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$
0 голосов
/ 17 сентября 2010

Как насчет альтернативной формы for, упомянутой в (bashref) Looping Constructs ?

0 голосов
/ 12 сентября 2013

Для циклов, вероятно, правильный способ сделать это, но вот забавная альтернатива:

echo -e {1..10}"\n" |xargs -n1 some_command

Если вам нужен номер итерации в качестве параметра для вашего вызова, используйте:

echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @

Редактировать: Было справедливо отмечено, что приведенное выше решение будет работать гладко только с простыми командами (без конвейеров и т. Д.). Вы всегда можете использовать sh -c, чтобы делать более сложные вещи, но это того не стоит.

Другой метод, который я обычно использую, это следующая функция:

rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}

теперь вы можете назвать это как:

rep 3 10 echo iteration @

Первые два числа дают диапазон. @ будет переведено на номер итерации. Теперь вы можете использовать это и с трубами:

rep 1 10 "ls R@/|wc -l"

с указанием количества файлов в каталогах R1 .. R10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...