Od czasu do czasu uruchamiam wiersz poleceń bash w następujący sposób:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
Aby uruchomić some_command
kilka razy z rzędu - w tym przypadku 10 razy.
Często some_command
jest to łańcuch poleceń lub potok.
Czy jest na to bardziej zwięzły sposób?
let ++n
zamiastn=$((n+1))
(3 mniej znaków).zsh
marepeat 10 do some_command; done
.sh: 1: [[: not found
.Odpowiedzi:
Lub jako jedna linijka dla tych, którzy chcą łatwo kopiować i wklejać:
źródło
for (n=0;n<k;n++))
może być lepszy; Podejrzewam,{1..k}
że zmaterializuje łańcuch ze wszystkimi liczbami całkowitymi oddzielonymi spacjami.n=15;for i in $(seq -f "%02g" ${n});do echo $i; done 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
Używając stałej:
Używanie zmiennej (może obejmować wyrażenia matematyczne):
źródło
x=10
for ((n=0; n < $x; n++));
for run in {1..10}; do echo "on run $run"; done
n
ustawiono już określoną wartość?for (( ; n<10; n++ ))
robi praca / edit: chyba najlepiej użyć jednego z innych odpowiedzi, takich jakwhile (( n++...
jedenKolejny prosty sposób na włamanie:
uruchom echo 20 razy.
Zauważ,
seq 20 | xargs -Iz echo "Hi there z"
że wyświetli się:źródło
seq 20
)seq 20 | xargs -I{} echo "Hi there {}"
z
nie jest to dobry symbol zastępczy, ponieważ jest tak powszechny, że może być zwykłym tekstem w tekście polecenia. Zastosowanie{}
będzie lepsze.seq
? więc po prostu wydrukowałbyHi there
20 razy (bez numeru)? EDYCJA: wystarczy użyć,-I{}
a następnie nie mieć żadnych{}
w poleceniuIIIII
wtedy ładnie wygląda na przykład:seq 20 | xargs -IIIIII timeout 10 yourCommandThatHangs
Jeśli używasz powłoki zsh:
Gdzie 10 to liczba powtórzeń polecenia.
źródło
repeat 10 { !! }
Korzystając z GNU Parallel możesz:
Jeśli nie chcesz, aby liczba była argumentem, i uruchamiaj tylko jedno zadanie na raz:
Obejrzyj film wprowadzający, aby zapoznać się z krótkim wprowadzeniem: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Przejrzyj samouczek ( http://www.gnu.org/software/parallel/parallel_tutorial.html ). Wiersz poleceń z miłością za to.
źródło
-j1 -N0
które wyłączają równoległość ????some_command
1000 razy szeregowo bez argumentów? I: Czy możesz wyrazić to krócejparallel -j1 -N0 some_command ::: {1..1000}
?repeat.sh repeatcount some_command
. Do implementacji w skrypcie powłoki, którego mógłbym użyćparallel
, gdyby był już zainstalowany na komputerze (prawdopodobnie nie byłby). Lub mogę skłaniać się ku xargsom, ponieważ wydaje się to być najszybsze, gdy przekierowanie nie jest potrzebnesome_command
.parallel -N0 -j1 --retries 4 --results outputdir/ some_command
Prosta funkcja w pliku konfiguracyjnym bash (
~/.bashrc
często) może działać dobrze.Nazwij to tak.
źródło
do ${*:2}
dodałem eval,do eval ${*:2}
aby upewnić się, że zadziała w przypadku uruchamiania poleceń, które nie zaczynają się od plików wykonywalnych. Na przykład, jeśli chcesz ustawić zmienną środowiskową przed uruchomieniem polecenia takiego jakSOME_ENV=test echo 'test'
.xargs
jest szybki :W nowoczesnym 64-bitowym systemie Linux zapewnia:
Ma to sens, ponieważ
xargs
polecenie jest pojedynczym rodzimym procesem, który odradza/usr/bin/true
polecenie wiele razy, zamiast pętlifor
iwhile
interpretowanych w Bash. Oczywiście działa to tylko dla jednego polecenia; jeśli musisz wykonać wiele poleceń w każdej iteracji w pętli, będzie to tak samo szybkie, a może szybsze, niż przekazywaniesh -c 'command1; command2; ...'
do xargsMożna
-P1
to również zmienić, powiedzmy,-P8
aby spawnować 8 procesów równolegle, aby uzyskać kolejny duży wzrost prędkości.Nie wiem, dlaczego GNU równolegle jest tak wolne. Myślałem, że będzie to porównywalne z xargs.
źródło
Inna forma Twojego przykładu:
źródło
Po pierwsze możesz zawinąć to w funkcję:
Nazwij to tak:
źródło
tr
Tu wprowadza w błąd i to działa na wyjściumanytimes
, nieecho
. Myślę, że powinieneś usunąć go z próbki.xargs i seq pomogą
widok :
źródło
Zwróć uwagę na podkreślenie zamiast używania zmiennej.
źródło
_
jest to nazwa zmiennej.Jeśli możesz robić to okresowo, możesz uruchomić następującą komendę, aby uruchomić ją co 1 sekundę w nieskończoność. Możesz wprowadzić inne niestandardowe kontrole, aby uruchomić je n razy.
watch -n 1 some_command
Jeśli chcesz mieć wizualne potwierdzenie zmian, dołącz
--differences
przedls
poleceniem.Według strony podręcznika OSX jest też
Strona podręcznika Linux / Unix można znaleźć tutaj
źródło
Rozwiązałem tę pętlę, w której powtórzenie jest liczbą całkowitą reprezentującą liczbę pętli
źródło
Jeszcze inna odpowiedź: użyj rozwinięcia parametru dla pustych parametrów:
Testowane na Centos 7 i MacOS.
źródło
Wszystkie istniejące odpowiedzi wydają się wymagać
bash
i nie działają ze standardowym BSD UNIX/bin/sh
(np. Wksh
OpenBSD ).Poniższy kod powinien działać na każdym BSD:
źródło
Trochę naiwne, ale tak zwykle pamiętam z głowy:
Bardzo podobny do odpowiedzi @ Joe-Koberg. Jego jest lepszy, zwłaszcza jeśli potrzebujesz wielu powtórzeń, tylko trudniej mi zapamiętać inną składnię, ponieważ w ostatnich latach nie używam
bash
dużo. Mam na myśli, że przynajmniej nie do pisania skryptów.źródło
Plik skryptu
i wynik poniżej
źródło
Co powiesz na alternatywną formę
for
wymienioną w (bashref) Looping Constructs ?źródło
Pętle są prawdopodobnie właściwym sposobem na zrobienie tego, ale jest fajna alternatywa:
echo -e {1..10}"\n" |xargs -n1 some_command
Jeśli potrzebujesz numeru iteracji jako parametru do wywołania, użyj:
echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @
Edytować: słusznie skomentowano, że powyższe rozwiązanie będzie działać płynnie tylko przy prostych uruchomieniach poleceń (bez potoków itp.). zawsze możesz użyć
sh -c
bardziej skomplikowanych rzeczy, ale nie warto.Inną metodą, której zwykle używam, jest następująca funkcja:
rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}
teraz możesz to nazwać:
rep 3 10 echo iteration @
Pierwsze dwie liczby określają zakres.
@
Będą tłumaczone na liczbę iteracji. Teraz możesz używać tego również z rurami:rep 1 10 "ls R@/|wc -l"
z poda liczbę plików w katalogach R1 .. R10.
źródło
rep 1 2 touch "foo @"
nie utworzy dwóch plików „foo 1” i „foo 2”; raczej tworzy trzy pliki „foo”, „1” i „2”. Może istnieć sposób na poprawne cytowanie za pomocąprintf
i%q
, ale trudne będzie uzyskanie dowolnej sekwencji słów poprawnie cytowanych w jednym ciągu, który należy przekazaćsh -c
.rep
w twoim.bashrc
, kolejne wywołania stają się o wiele bardziej zwięzłe.