Aby wyjść z pętli bash. BASH: opis pętli for, while, till i przykłady użycia

A teraz przyszła kolej na piąty temat cyklu. W nim będę nadal przyglądał się strukturom kontrolnym powłoki bash. Poprzedni post dotyczył instrukcji warunkowych. Teraz czas na takie integralne struktury językowe, jak instrukcje pętli. Pętle, podobnie jak warunki, są narzędziami zapewniającymi kontrolę nad kolejnością wykonywania poleceń.
Bash obsługuje pętle for, while, till i select. Przyjrzyjmy się teraz bliżej każdemu z nich.

instrukcja pętli for

Ogólna składnia instrukcji for wygląda następująco:

dla zmiennej
Do
lista poleceń
zrobione

Pętla for w bashu różni się znacznie od pętli for w językach programowania, takich jak C czy PHP. Więc jeśli jesteś programistą C, musisz przyzwyczaić się do tych różnic, aby się nie pomylić.
W wyniku podstawienia szablonu otrzymuje się listę słów. W każdej iteracji zmienna przyjmuje każdą kolejną wartość z tej listy i wykonywane są polecenia między do i done. Iteracje kończą się, gdy słowa na liście zostaną wyczerpane.
$ za dzień w Pon. Wt. Śr. Czw. Pt. Wykonaj echo „Dziś $dzień”.
Zarezerwowane słowa instrukcji for można również zapisać w jednym wierszu, tak jak to było w poprzednim poście dotyczącym instrukcji if. Aby to zrobić, umieść „;”. Przepiszmy poprzedni przykład z myślą o tej funkcji:
$ za dzień w pon. wt. śr. czw. pt.; wykonaj echo "Dzisiaj jest $dzień"; zrobione
Brak konstruktu jest równoznaczny z zapisaniem [e-mail chroniony] O parametrze [e-mail chroniony] powiedział w.

Instrukcja pętli while

Ogólna składnia instrukcji while jest następująca:

podczas gdy lista1
Do
lista2
zrobione

Lista1 jest wykonywana jako pierwsza. Jeśli się powiedzie, tj. zwróci kod zero, sterowanie przechodzi do listy2. Iteracje są kontynuowane, aż wynik wykonania list1 stanie się niezerowy. Na przykład:
i=10 podczas gdy [ $i -gt 0 ]; wykonaj echo $i i=$(($i-1)) gotowe; echo „koniec”

dopóki instrukcja pętli

Ogólna składnia instrukcji till jest następująca:

do listy1
Do
lista2
zrobione

Lista1 jest wykonywana jako pierwsza. Jeśli to się nie powiedzie, to znaczy z niezerowym kodem powrotu, sterowanie przechodzi do listy2. Iteracje są kontynuowane, aż wynik wykonania list1 stanie się zerem. Na przykład:
i=10 do [ $i -lt 0 ]; wykonaj echo $i i=$(($i-1)) gotowe; echo „koniec”

wybierz instrukcję pętli

Ogólna składnia instrukcji select jest następująca:

wybierz zmienną
Do
lista
zrobione

W wyniku podstawienia szablonu otrzymuje się listę słów. Operator dodaje do tych słów numery seryjne i wyprowadza cały zestaw do standardowego strumienia błędów. Brak konstruktu jest równoznaczny z zapisaniem [e-mail chroniony] Następnie wyświetlany jest monit i odczytywana jest linia ze standardowego strumienia wejściowego. Jeśli łańcuch zawiera liczbę odpowiadającą dowolnemu słowu z listy, to zmienna otrzymuje tę liczbę jako swoją wartość. Jeśli nie znaleziono odpowiedniego słowa, wartość zmiennej staje się łańcuchem pustym. Następnie wykonywana jest lista poleceń i iteracja jest kontynuowana do momentu znalezienia znaku końca pliku w wierszu wejściowym lub do napotkania przerwania lub powrotu na liście poleceń.
Polecenia break i return służą do kontrolowania postępu pętli. Polecenie break przerywa wykonanie pętli, natomiast return zwraca kod wyniku (zero lub niezerowy).
Instrukcja select jest przydatna do tworzenia menu numerowanych. Na przykład w katalogu ~/temp znajdują się 3 pliki: proto.txt, file.txt i readme. Przykład fragmentu skryptu, który umożliwia szybkie przejrzenie dowolnego z nich.
echo "Wybierz plik do wyświetlenia:" wybierz plik w ~/temp/* Zakończ; zrób if [-f plik $]; następnie kot plik $; inaczej złamać; dobrze zrobione
Uruchamiając ten skrypt, zobaczymy na ekranie:
Wybierz plik do wyświetlenia:
1) /home/istergul/temp/file.txt
2) /home/istergul/temp/proto.txt
3) /home/istergul/temp/readme
4) Wyjdź

W następnym temacie przyjrzymy się podstawieniom parametrów warunkowych. Czekam na Twoje komentarze.

W tym wykładzie kontynuujemy poznawanie grzmotnąć. Chcę przypomnieć, że rozważamy te elementy grzmotnąć aby pomóc nam zrozumieć skrypty system operacyjny. Takimi elementami z pewnością są cykle i funkcje. Jeśli ktoś studiował programowanie, to nie będzie miał trudności ze zrozumieniem tych zagadnień.

dla pętli

Cykl Do V grzmotnąć ma dwa rodzaje. Rozważ najpierw wersję klasyczną Do. Ogólny pogląd jest następujący:

Między elementami Do I W ustawiana jest zmienna, która z kolei przyjmuje wartość z sekwencji wartości podanych pomiędzy W I Do. Między Do I zrobione istnieją polecenia, które są wykonywane za każdym razem, gdy zmienna zmienia swoją wartość. Pętla zatrzymuje się, gdy zmienna przyjmuje ostatnią wartość w sekwencji. Wartości w sekwencji są oddzielone spacją.

A oto praktyczny przykład:

Kolejność wartości można określić na różne sposoby. Jawnie - jak w powyższym przykładzie lub za pomocą innych zmiennych lub za pomocą specjalnych poleceń. Spójrzmy na kilka przykładów. Ponieważ wartości są oddzielone spacją, każda zmienna zawierająca ciąg znaków ze spacjami może być używana jako takie wartości:

Wynik będzie taki sam jak w pierwszym przykładzie.

Jeśli chcesz określić sekwencję liczb, możesz użyć polecenia nast i mechanizm zastępczy. Zespół nast zwraca sekwencję wartości liczbowych na ekran. Składnia jest prosta i będzie jasna na podstawie poniższego przykładu:

Wynik:

Wróćmy do drugiego rodzaju. Do. Często w skryptach można znaleźć tak zwaną opcję C-like Do, który jest używany w pętlach opartych na liczbach. Spójrzmy na przykład:

Pętla jest wykonywana, gdy sprawdzany warunek w wyrażeniu jest prawdziwy. Gdy tylko wyrażenie zwróci wartość false, pętla zostaje zakończona.

Praktyczny przykład:

#!/bin/bash
i=1
podczas gdy [ $i -lt 7 ]
Do
echo $i
niech i=i+1
zrobione

W naszym przykładzie sprawdzamy, czy zmienna I mniejszy niż (-lt), liczba 7, a jeśli tak, to wyświetlana jest wartość zmiennej. Wyrażenie niech i=i+1, zwiększa zmienną o jeden, sprawdza ponownie i tak dalej. let mówi tłumaczowi, że argumenty powinny być traktowane jako wartości liczbowe. Ten wiersz można zapisać jako niech i++(wariant podobny do c). Gdy liczba zostanie zwiększona o więcej niż jeden, można ją zapisać jako: niech i+=2- w tym przypadku I będzie rosnąć w krokach co 2. Innym sposobem na zwiększenie zmiennej jest użycie wbudowanego kalkulatora (działa tylko z liczbami całkowitymi). Dostęp do kalkulatora można uzyskać za pomocą podwójnych nawiasów: i=$(($i+1)) lub przez kwadrat: i=$[$i+1] Możesz także użyć kalkulatora w wierszu poleceń:

W przypadku pętli należy uważać, aby nie skorzystać z opcji pętli nieskończonej. Przy okazji do debugowania grzmotnąć scripts, możesz zmienić pierwszą linię na #!/bin/bash -x lub uruchom skrypt za pomocą polecenia bash-x:

[e-mail chroniony]:~/linux$ bash -x ./testfor.sh
+ i=1
+ „[„ 1 -gt 5 „]”
+ echo i=1
i=1
+ niech i=i+1
+ ‘[‘ 2 -gt 5 ‘]”
+ echo i=2
i=2
+ niech i=i+1
+ „[„ 3 -gt 5 „]”
+ echo i=3
i=3
+ niech i=i+1
+ „[„ 4 -gt 5 „]”
+ echo i=4
i=4
+ niech i=i+1
+ „[„ 5 -gt 5 „]”
+ echo i=5
i=5
+ niech i=i+1
+ „[„ 6 -gt 5 „]”

Pamiętaj, aby poćwiczyć pisanie małych skryptów, aby lepiej zrozumieć, jak działają pętle grzmotnąć.

Funkcje w bashu

Funkcje obowiązują w grzmotnąć bardzo szeroki. Funkcje są opisywane na dwa sposoby: za pomocą słowa kluczowego funkcjonować, i bez tego.

Pierwszy sposób:

funkcja nazwa_funkcji
{
Ciało funkcyjne
}

Drugi sposób:

nazwa_funkcji()
{
Ciało funkcyjne
}

Funkcja jest wywoływana z nazwy w dowolnym miejscu skryptu, ale dopiero po opisie samej funkcji. Do funkcji można również przekazywać parametry, które po wywołaniu (nazwie) funkcji określane są spacją. Rozważ przykładowy skrypt grzmotnąć:

#!/bin/bash
elementarz funkcyjny
{
jeśli [ $# -ne 0 ]
Następnie
lokalne a=1
echo "Liczba przekazanych parametrów - $#"
dla mnie w [e-mail chroniony]
Do
echo "$ a-ty parametr— $i"
niech ++
zrobione
powrót 0
w przeciwnym razie
echo "Nie podano parametrów"
powrót 1
fi
}
echo "Wywołanie funkcji z parametrami:"
podkład a b c
echo $?
echo "Wywołanie funkcji bez parametrów:"
Elementarz
echo $?

W ten przykład biorąc pod uwagę funkcję o nazwie Elementarz. Wywołanie funkcji z parametrami: podkład a b c i bez parametrów: Elementarz. W ciele funkcji wszystkie konstrukcje powinny być ci znane, z wyjątkiem $# , $i I [e-mail chroniony] .$# - zwraca liczbę parametrów przekazanych do funkcji. W naszym przykładzie będzie to liczba 3 .[e-mail chroniony] zwraca wszystkie parametry w jednym wierszu. W przykładzie tak by było a b c. I przez $1 , $2 , $3 itp. możesz uzyskać dostęp do każdego parametru indywidualnie. $? - zawiera kod wykonania ostatniego polecenia. W naszym przykładzie kod wykonania funkcji.

Funkcja może również powrócić wartość numeryczna za pomocą słowa kluczowego powrót. Z reguły zwracają 0, jeśli funkcja zakończyła się bez błędów, lub wartość różną od zera, jeśli coś poszło nie tak. W przykładzie w przypadku wywołania funkcji z parametrami zwracana jest wartość 0, a jeśli funkcja została wywołana bez parametrów, zwracany jest kod 1.

Wszystko, co dotyczy przekazywania parametrów do funkcji, działa dokładnie tak samo w przypadku skryptu. Możesz także przekazać parametry do skryptu i manipulować nimi w ten sam sposób, używając $#, [e-mail chroniony], $N. Z tej samej kategorii i opcji - $0 - która zwraca nazwę polecenia, które uruchomiło skrypt. Jeśli skrypt został uruchomiony na polecenie ./skrypt.sh, potem echo $0 zwróci wartość ./skrypt.sh, a jeśli na komendę /home/igor/linux/script.sh, wtedy wartość zostanie zwrócona /home/igor/linux/script.sh.

Jedną z podstawowych zasad administrowania systemem można wyrazić w następujący sposób: jeśli często musisz robić to samo, napisz skrypt i pozwól mu pracować za Ciebie. Jeśli musisz kilka razy wykonać jakąś akcję w skrypcie, powinieneś użyć cykle. W GNU Bash możesz tworzyć pętle za pomocą konstrukcji Do, chwila I dopóki.

Jeśli kiedykolwiek interesowałeś się programowaniem, prawdopodobnie znasz już te konstrukcje. Jeśli tak jak ja studiujesz grzmotnąć Jeśli nie masz za sobą żadnego doświadczenia w programowaniu, użycie pętli może nie być wystarczająco oczywiste, aby je zrozumieć. Zacznijmy od zdefiniowania różnic między różnymi typami pętli, a następnie przejdźmy do przykładów.

Cykl Do ma na celu powtarzanie czynności, aż wszystkie zostaną zakończone. Wyobraź sobie na przykład, że masz katalog obrazów i musisz je przekonwertować z jednego formatu na inny. Możesz użyć pętli Do wraz z programem konwertować z opakowania ImageMagick(lub inny program), na przykład w celu konwersji obrazów z formatu JPEG do formatu PNG. Lub, na przykład, może być konieczne przekonwertowanie wielu plików dźwiękowych z MP3 V OGG Vorbis.

Cykl chwila służy do powtarzania czynności Do widzenia wykonane (jest PRAWDA) jakiś warunek. Cykl dopóki działa trochę inaczej: wykonuje akcję dopóki do momentu spełnienia warunku. Możesz więc np. skontrować i wykonać akcję dopóki dopóki jego wartość nie osiągnie 10. Przyjrzyjmy się temu bardziej szczegółowo na przykładach.

Zacznijmy od pętli Do. Jego format to:

Dla i w $(polecenie); wykonaj polecenie $i; zrobione

Jeśli używasz pętli Do w skrypcie lepiej sformatować go w ten sposób:

#!/bin/bash dla i w $(polecenie); wykonaj polecenie $i gotowe

Na przykład, jeśli musisz to zrobić kopie zapasowe wszystkie pliki HTML w katalogu, możesz użyć następującego polecenia:

Dla i w $(ls *html); do cp $i $i.bak; zrobione

Spowoduje to utworzenie zmiennej lokalnej $i, polecenie jest wykonywane ls*html, którego wynikiem będą dane inicjujące wartość zmiennej $i przy każdej iteracji pętli (w naszym przykładzie będzie to lista plików zwrócona przez polecenie ls, jeden dla każdej iteracji). Następnie wykonywane jest polecenie cp, do którego wśród parametrów przekazywana jest zmienna $i.

Ktoś mógłby zapytać, czy używanie litery jest obowiązkowe "I" jako nazwa zmiennej? NIE. Możesz użyć dowolnego prawidłowego grzmotnąć nazwa zmiennej. Oczywiście lepiej jest używać bardziej znaczących nazw zmiennych w skryptach, jak np $wejście Lub $html.

Podałem bardzo krótki i prosty przykład użycia pętli Do. Zamiast wykonywania polecenia w bloku Do,używać Echo aby zobaczyć parametry przekazane do niego. Jest to bardzo przydatna praktyka na etapie testowania skryptów, jak również dobry sposób pomóc ci lepiej zrozumieć twoją pracę Do.

póki i do

Rozważmy teraz konstrukcje chwila I dopóki. Ponadto użyjemy trochę instrukcji warunkowych basha. W naszym przykładzie użyjemy ich do określenia, na przykład, czy wartość zmiennej jest większa, czy mniejsza od liczby X; czy plik istnieje i czy jest katalogiem. Warunków można również użyć do określenia, na przykład, czy plik jest czytelny lub czy ma bit GID w swoich uprawnieniach.

Spróbujmy zrobić coś prostego, na przykład utworzyć kilka pustych plików. W życiu jest mało prawdopodobne, aby było to dla ciebie przydatne, ale jako przykład, to jest właśnie to.

#!/bin/bash i=0 podczas gdy [ $i -lt 22 ] dotknij $i i=$[$i+1] gotowe

Ten skrypt utworzy 22 pliki o nazwach od 0 do 21. Pętla będzie działać do Do widzenia wartość zmienna $i mniej ( -lt) 22.

Teraz pozbądźmy się wygenerowanych plików za pomocą pętli dopóki:

#!/bin/bash i=0 do [ $i -eq 22 ] do rm $i i=$[$i+1] gotowe

Tutaj wymieniliśmy chwila NA dopóki, aw wyrażeniu warunkowym zastąpiliśmy "mniej" (-lt) NA "równa się" (-równ). W ten sposób nasz skrypt będzie działał tak długo, jak wartość $i nie osiągnie 22. I zamiast dotykać używaliśmy rm usuwać pliki zamiast je tworzyć. Proste, prawda?

Pętle to niezwykle wygodna rzecz przy pisaniu dowolnych programów czy skryptów, a raczej niezbędna. Pozwalają nam wykonać określony fragment kodu określoną liczbę razy. Oczywiście bash ma kilka rodzajów pętli. Opiszemy cykle na, na, podczas, do. Chociaż for in i for są uważane za różne składnie tej samej instrukcji, moim zdaniem różnią się one od siebie bardziej niż while from till.

Pętla z licznikiem dla in:

Cykl dla w to pętla z licznikiem. Blok kodu znajdujący się w ciele pętli jest powtarzany tyle razy, ile jest wartości na liście operatora for in, przy czym przy każdym powtórzeniu zmienna licznika (tutaj nazywa się var, ale oczywiście można nazwij to jak chcesz) ma wartość następnego elementu listy.
Jeśli słowo kluczowe do znajduje się w tym samym wierszu co słowo for, to po liście argumentów (przed do) należy wstawić średnik.
Każdy z elementów<список>może zawierać wiele argumentów. Jest to przydatne podczas przetwarzania grup parametrów. W tym przypadku, aby wymusić parsowanie każdego z argumentów w<списке>, musisz użyć instrukcji set
Możesz użyć zmiennej jako listy w pętli for.
W<списке>dla pętli można używać nazw plików, które z kolei mogą zawierać symbole wieloznaczne. Może to być bardzo przydatne podczas pracy z dużą liczbą plików.
Jeśli<список>nie jest określony w pętli for, to zmienna jest używana w takiej postaci, w jakiej została użyta [e-mail chroniony]- lista argumentów wiersza poleceń.
Podczas tworzenia listy argumentów w pętli for można zastosować podstawianie poleceń.
Wyjście pętli można przekierować ze stdout do pliku lub gdzie indziej (więcej o tym dowiesz się analizując przekierowanie I/O).

Składnia:
dla var w<список>
Do
<выполняемые команды>
zrobione

Przykład:
dla nazw w nazwa1 nazwa2 nazwa3 nazwa4
Do
echo nazw $
zrobione

Instrukcja pętli Do ma inny sposób pisania - bardzo podobny do składni operatora for w języku C. W takim przypadku podczas inicjalizacji liczników ustawiane są wartości początkowe zmiennych lub jednej zmiennej i po każdym przejściu pętli warunek jest sprawdzany, jeśli sprawdzenie zwróci wartość true, rozpoczyna się następny przebieg pętli. w bloku<приращение счётчиков>wartość naszych liczników zmiennej musi się koniecznie zmienić (niekoniecznie w górę) tak, że przy sprawdzaniu warunku prędzej czy później dostaniemy wartość kłamstwa, inaczej pętla nigdy się nie skończy. Bardzo wygodna i co najważniejsze znana opcja, jeśli jakaś operacja wymaga powtórzenia określonej liczby razy.

Z podobną składnią:
Do ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
Do
<выполняемые команды>
zrobione

Przykład:
dla ((zmienna=1; zm<= LIMIT ; var++))
Do
echo $zm
zrobione

pętla while:

Jest to dość prosta konstrukcja sprawdzająca stan za operatorem chwila a jeśli ten warunek jest prawdziwy, wykonuje blok poleceń znajdujących się między słowami do i done, a następnie ponownie przechodzi do sprawdzania warunku. Jeśli sprawdzenie zwróci wartość false, pętla się kończy i wykonywane są następujące polecenia: zrobione. Należy to zapewnić<проверка условия>zależał od kodu działającego w pętli, w przeciwnym razie, jeśli wynik sprawdzenia się nie zmieni, otrzymasz nieskończoną pętlę.
Standardowe wejście, dla pętli while, może zostać przekierowane do pliku za pomocą polecenia redirect< в конце цикла.

Składnia:
chwila<Проверка условия>
Do
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
zrobione

Przykład:
podczas gdy [ $var0 -eq 100 ]
Do
echo $zm
var++
zrobione

Operator chwila może mieć wiele warunków. Jednak dopiero ostatni z nich przesądza o możliwości kontynuacji cyklu. W takim przypadku składnia instrukcji pętli będzie inna niż zwykle.
Składnia(Powtarzam jeszcze raz, że tylko ostatni warunek wpływa na wykonanie pętli) :
chwila
<условие1>
<условие2>

<условиеN>
Do
<выполняемые команды - тело цикла>
zrobione

do pętli:

Operator dopóki bardzo podobny do while, również ocenia warunek, ale wykonuje ciało pętli, jeśli wynik obliczeń jest fałszywy. Może się to wydawać dziwne, ale dopóki nie ocenia warunku przed pierwszą iteracją pętli, na przykład podczas, a nie po niej. Podobnie jak w przypadku pętli for/in, umieszczając słowo kluczowe do w tym samym wierszu, co deklarację pętli, należy wstawić znak „;” przed zrobieniem.
Podobnie jak w poprzednim przypadku należy pamiętać, że warunek musi zależeć od operacji w ciele pętli, inaczej nasz skrypt nigdy się nie skończy.

Składnia:
dopóki<Проверка условия>
Do
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
zrobione

Przykład:
till [ $var0 -gt 100] # Warunek jest sprawdzany na początku iteracji.
Do
echo $zm
var--
zrobione

Na razie chyba wystarczy. :)

  • Z powrotem
  • Do przodu

Nowe artykuły:

  • Wykrywanie sieci nie włącza się w systemie Windows 7/8/2008/2012
  • Błąd: Uruchomienie tej aplikacji nie powiodło się, ponieważ nie mogła znaleźć lub załadować „windows” wtyczki platformy Qt.
  • Konfigurowanie automatycznego ponownego uruchamiania procesów roboczych serwer rphost.exe 1C 8.3
  • Jak zmniejszyć rozmiar dziennika transakcji (.ldf) w MS SQL 2008/20012

    MS SQL, jak każdy porządny przemysłowy DBMS, wraz z bazą danych przechowuje logi transakcji, które pozwalają na cofnięcie stanu...

5

Twój skrypt jest zakodowany w niebezpieczny sposób.

Po pierwsze, zakładam, że używasz powłoki Bash, ponieważ zaznaczyłeś ją za pomocą „/ bash” i „/ for”.

W mojej odpowiedzi zacytuję ten świetny przewodnik po Bash, który jest prawdopodobnie najlepszym źródłem do nauki Bash.

1) Nigdy nie używaj Command Substitution , out Lub miły, bez cudzysłowów. Jest tu duży problem: użycie niecytowanego rozwinięcia do podzielenia danych wyjściowych na argumenty.

Mówiąc konkretnie, to $(find$ DIRWORK -type d -name work) i $(find$ DIR -type f) zostaną poddane Word Splitting , więc jeśli find znajdzie plik ze spacjami w nazwie, tj. wynik Bash przekaże 2 argumenty do polecenia for w celu iteracji, tj. jeden dla „pliku” i jeden dla „nazwy”. W takim przypadku chcesz mieć nadzieję, że otrzymasz „plik: brak takiego pliku lub katalogu” i „nazwa: brak takiego pliku lub katalogu”, zamiast potencjalnie je uszkodzić, jeśli istnieją.

2) Zgodnie z konwencją, zmienne środowiskowe (PATH, EDITOR, SHELL, ...) i wewnętrzne zmienne powłoki (BASH_VERSION, RANDOM, ...) są pisane wielkimi literami. Wszystkie inne nazwy zmiennych muszą być pisane małymi literami. Ponieważ w nazwach zmiennych rozróżniana jest wielkość liter, ta konwencja pozwala uniknąć przypadkowej redefinicji zmiennych środowiskowych i wewnętrznych.

To jest bezpieczniejsza wersja twojego skryptu, której polecam zamiast tego:

My_home="/root/mydir" my_dir=" $my_home/var" dir_work="$ my_home/Local" podczas gdy IFS= read -r -d "" f; do # Domyślam się, że chcesz również zignorować stderr; # stąd pochodzi 2>&1. if lsof -n " ​​$f" | grep "" > /dev/null 2> then echo "hej , „Teraz jestem bezpieczniejszy!” dobrze zrobione< <(find "$ dir_work" -type f -print0) while IFS= read -r -d "" f; do echo "2" done < <(find "$dir_work" -type d -name "work" -print0)

Jak widać, zmienna IFS jest ustawiona na wartość pustą, co uniemożliwia readowi obcinanie początkowych i końcowych spacji z łańcucha. polecenie read używa pustego łańcucha (-d "") jako separatora do odczytu, dopóki nie osiągnie \ 0. find musi być odpowiednio m, więc używa opcji -print0, aby oddzielić swoje dane za pomocą \ 0 zamiast nowej linii, co zaskakująco i złośliwie może być częścią nazwy pliku. Podział takiego pliku na \n na dwie części złamie nasz kod.

Poprzednia odpowiedź, która stwierdza, że ​​znajdź ... | podczas gdy odczytana nazwa; Do ...; done powinno być użyte do odczytania find s, wynik również może być zły. Pętla while jest wykonywana w nowej podpowłoce z kopią zmiennych skopiowanych z rodzica. Ta kopia jest następnie używana do wszystkiego, co chcesz. Po zakończeniu pętli while kopia podpowłoki zostanie odrzucona, a oryginalne zmienne rodzica nie zostaną zmienione.

Jeśli zamierzasz zmienić niektóre zmienne w tej pętli while i użyć ich później w elemencie nadrzędnym, rozważ użycie bezpieczniejszego skryptu, który zapobiegnie utracie danych.

0

„Nigdy nie używaj zastępowania poleceń jakiegokolwiek rodzaju bez cudzysłowów”. To tylko czepianie się, ale możliwe jest użycie zastępowania poleceń bez cudzysłowów, gdy ustawiasz zmienną: „coś = $ (nazwa podstawowa” nazwa pliku ze spacjami „)”. - Smith Jan 22 kwietnia 13 2013-04-22 21:43:10

2

Dla i w $(znajdź$ DIRWORK -wpisz d -nazwa praca); wykonaj echo „2” gotowe

będzie pierwszym, który wykona tę linię

Znajdź pracę $DIRWORK -typ d -nazwa

poczekaj, aż find zakończy wykonywanie, a następnie weź dane wyjściowe i umieść je z powrotem w pętli for

For i na wyjściu find; wykonaj echo „2” gotowe

dopiero wtedy rozpocznie się wykonywanie pętli for.

Więc jeśli find zajmuje dużo czasu, aby zakończyć pętlę for, musi długo czekać, zanim będzie mógł się rozpocząć.

Wypróbuj interaktywnie polecenia znajdowania tymczasowego

$ czas znajdź $DIRWORK -typ d -nazwa praca

i zobaczyć, jak długo to potrwa.

Pamiętaj też, że nie powinieneś używać pętli for do iteracji po nazwach plików. Użyj pętli while z read , tak jak poniżej:

Znajdź $ DIRWORK -typ d -nazwa praca | podczas gdy odczytana nazwa; wykonaj echo „2” gotowe

Bonus: wykonuje pętlę while równolegle z find . Oznacza to, że pętla while wykona jedną iterację, gdy tylko find wyświetli jedną linię. Nie musisz czekać na zakończenie wykonywania funkcji find.

mob_info