Przewodnik dla początkujących do Shell Scripting 2: For Loops

Spisu treści:

Wideo: Przewodnik dla początkujących do Shell Scripting 2: For Loops

Wideo: Przewodnik dla początkujących do Shell Scripting 2: For Loops
Wideo: New ways to search: Late Night Spots 2024, Marsz
Przewodnik dla początkujących do Shell Scripting 2: For Loops
Przewodnik dla początkujących do Shell Scripting 2: For Loops
Anonim
Jeśli chcesz zbudować swój mandat geek, dołącz do nas na drugą część naszej serii skryptów powłoki. Mamy kilka poprawek, kilka poprawek do scenariusza z zeszłego tygodnia i przewodnik po pętli dla niewtajemniczonych.
Jeśli chcesz zbudować swój mandat geek, dołącz do nas na drugą część naszej serii skryptów powłoki. Mamy kilka poprawek, kilka poprawek do scenariusza z zeszłego tygodnia i przewodnik po pętli dla niewtajemniczonych.

Skrypt datecp ponownie odwiedzony

W pierwszej części naszego przewodnika po skryptach powłoki, stworzyliśmy skrypt, który skopiował plik do katalogu kopii zapasowej po dodaniu daty na końcu nazwy pliku.

Samuel Dionne-Riel wskazał w komentarzach, że istnieje znacznie lepszy sposób na obsługę naszych zmiennych referencyjnych.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

będzie działał zgodnie z założeniami, o ile zmienne rozszerzone nie zawierają spacji. Jeśli wywołasz swój skrypt w ten sposób:

datecp 'my old name' 'my new name'

rozszerzenie spowoduje polecenie:

cp my new name my old name.the_date

który ma 6 argumentów.

Aby poprawnie rozwiązać ten problem, ostatnia linijka skryptu powinna wyglądać następująco:

cp '$1' '$2.$date_formatted'

Jak widać, zmieniając linię naszego skryptu z:

cp -iv $1 $2.$date_formatted

do:

cp -iv “$1” “$2”.$date_formatted

zadba o ten problem, używając skryptu do plików, które mają spacje w nazwie. Samuel podkreśla również, że podczas kopiowania i wklejania kodu z tej strony (lub ogólnie Internetu) należy zastąpić właściwe kreski i cytaty dla "typowo lepszych", które często je zastępują. Będziemy także robić więcej, aby nasz kod był bardziej przyjazny dla kopiowania / wklejania.;-)

Inny komentator, Myles Braithwaite, zdecydował się rozwinąć nasz skrypt, aby data pojawiła się przed rozszerzeniem pliku. Zamiast tego

tastyfile.mp3.07_14_11-12.34.56

otrzymamy to:

tastyfile.07_14_11-12.34.56.mp3

co kończy się nieco wygodniejszym dla większości użytkowników. Jego kod jest dostępny na jego stronie GitHub. Rzućmy okiem na to, co on używa, aby rozdzielić nazwę pliku.

date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)

cp -iv $1 $file_name-$date_formatted.$file_extension

Zmieniłem nieco formatowanie, ale widać, że Myles deklaruje swoją funkcję daty w wierszu 1. W wierszu 2 używa jednak polecenia "echo" z pierwszym argumentem skryptu do wyprowadzenia nazwy pliku. Używa polecenia potoku, aby wziąć to wyjście i użyć go jako wejścia dla następnej części. Po potoku Myles wywołuje polecenie "awk", które jest potężnym programem do skanowania wzorców. Używając opcji -F, mówi polecenie, że następnym znakiem (po spacji) jest to, co zdefiniuje "separator pól". W tym przypadku jest to okres.

Teraz awk widzi plik o nazwie "tastyfile.mp3" jako złożony z dwóch pól: "tastyfile" i "mp3". Wreszcie używa

‘{print $NF}’

aby wyświetlić ostatnie pole. W przypadku, gdy twój plik ma wiele okresów - dzięki temu awk zobaczy wiele pól - wyświetli tylko ostatni, który jest rozszerzeniem pliku.

W linii 3 tworzy nową zmienną dla nazwy pliku i używa polecenia "basename" do odniesienia wszystkiego w 1 $ z wyjątkiem rozszerzenie pliku. Odbywa się to poprzez użycie podstawowej nazwy i podanie jej 1 $ jako argumentu, a następnie dodanie spacji i rozszerzenia pliku. Rozszerzenie pliku jest dodawane automatycznie ze względu na zmienną, która odwołuje się do wiersza 2. To, co można zrobić, to zrobić

tastyfile.mp3

i zamień go w

tastyfile

Następnie w ostatnim wierszu Myles ułożył polecenie, które wyprowadzi wszystko w odpowiedniej kolejności. Zauważ, że nie ma odniesienia do 2 $, drugiego argumentu dla skryptu. Ten konkretny skrypt skopiuje wymieniony plik do twojego bieżącego katalogu. Świetna robota Samuel i Myles!

Uruchamianie skryptów i $ PATH

W naszym artykule o podstawach wspominamy również, że domyślnie skrypty nie mogą być odwoływane jako polecenia. Oznacza to, że musisz wskazać ścieżkę skryptu, aby go uruchomić:

./script

~/bin/script

Ale umieszczając swoje skrypty w ~ / bin /, możesz po prostu wpisać ich nazwy z dowolnego miejsca, aby je uruchomić.

Komentatorzy spędzili trochę czasu na debacie nad poprawnością tego, ponieważ żadna nowoczesna dystrybucja Linuksa nie tworzy tego katalogu domyślnie. Ponadto, nikt nie dodaje go do zmiennej $ PATH domyślnie, co jest wymagane, aby skrypty działały jak polecenia. Byłem trochę zaskoczony, ponieważ po sprawdzeniu zmiennej $ PATH, komentatorzy mieli rację, ale wywoływanie skryptów nadal działało dla mnie. Dowiedziałem się, dlaczego: wiele nowoczesnych dystrybucji systemu Linux tworzy specjalny plik w katalogu domowym użytkownika -.profile.

Plik ten jest odczytywany przez bash (chyba że.bash_profile znajduje się w katalogu domowym użytkownika), a na dole znajduje się sekcja, która dodaje katalog ~ / bin / do zmiennej $ PATH, jeśli istnieje. Ta tajemnica zostaje wyjaśniona. W dalszej części serii będę nadal umieszczał skrypty w katalogu ~ / bin /, ponieważ są to skrypty użytkownika i powinny być uruchamiane przez użytkowników. I wydaje się, że naprawdę nie musimy ręcznie mieszać zmiennej $ PATH, aby wszystko działało.
Plik ten jest odczytywany przez bash (chyba że.bash_profile znajduje się w katalogu domowym użytkownika), a na dole znajduje się sekcja, która dodaje katalog ~ / bin / do zmiennej $ PATH, jeśli istnieje. Ta tajemnica zostaje wyjaśniona. W dalszej części serii będę nadal umieszczał skrypty w katalogu ~ / bin /, ponieważ są to skrypty użytkownika i powinny być uruchamiane przez użytkowników. I wydaje się, że naprawdę nie musimy ręcznie mieszać zmiennej $ PATH, aby wszystko działało.

Powtarzanie poleceń za pomocą pętli

Przejdźmy do jednego z najbardziej użytecznych narzędzi w aranżacji maniaków, aby poradzić sobie z powtarzającymi się zadaniami: pętlami. Dzisiaj będziemy omawiać pętle "dla".

Podstawowy zarys pętli for jest następujący:

for VARIABLE in LIST; do command1 command2 … commandn done

VARIABLE może być dowolną zmienną, chociaż najczęściej małe litery "i" są używane przez konwencję. LISTA to lista przedmiotów; możesz określić wiele elementów (oddzielając je spacją), wskazać zewnętrzny plik tekstowy lub gwiazdką (*) oznaczającą dowolny plik w bieżącym katalogu. Wymienione komendy są wcięte zgodnie z konwencją, więc łatwiej jest zobaczyć zagnieżdżanie - umieszczanie pętli w pętlach (dzięki czemu możesz zapętlić się podczas pętli).

Ponieważ listy używają spacji jako ograniczników - to znaczy, że spacja oznacza przejście do następnego elementu na liście - pliki, które mają spacje w nazwie, nie są zbyt przyjazne. Na razie trzymajmy się pracy z plikami bez spacji. Zacznijmy od prostego skryptu do wyświetlania nazw plików w bieżącym katalogu. Utwórz nowy skrypt w katalogu ~ / bin / zatytułowanym "Loopscript". Jeśli nie pamiętasz, jak to zrobić (w tym oznaczenie go jako pliku wykonywalnego i dodanie hashowania hash bang), zapoznaj się z naszym podstawowym artykułem dotyczącym skryptów bash.

W nim wprowadź następujący kod:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Po uruchomieniu skryptu należy po prostu uzyskać te elementy listy jako dane wyjściowe.
Po uruchomieniu skryptu należy po prostu uzyskać te elementy listy jako dane wyjściowe.
Całkiem proste, prawda? Zobaczmy, co się stanie, jeśli trochę zmienimy sytuację. Zmień swój skrypt, aby brzmiał tak:
Całkiem proste, prawda? Zobaczmy, co się stanie, jeśli trochę zmienimy sytuację. Zmień swój skrypt, aby brzmiał tak:

for i in *; do echo “$i” done

Po uruchomieniu tego skryptu w folderze należy uzyskać listę plików, które zawiera jako wynik.
Po uruchomieniu tego skryptu w folderze należy uzyskać listę plików, które zawiera jako wynik.
Teraz zmieńmy polecenie echo na coś bardziej użytecznego - powiedzmy polecenie zip. Mianowicie, dodamy pliki do archiwum. I, dostańmy kilka argumentów w miksie!
Teraz zmieńmy polecenie echo na coś bardziej użytecznego - powiedzmy polecenie zip. Mianowicie, dodamy pliki do archiwum. I, dostańmy kilka argumentów w miksie!

for i in $@; do zip archive “$i” done

Jest coś nowego! "$ @" To skrót od "1 $ 2 $ 3 … $ n". Innymi słowy, jest to pełna lista wszystkich podanych argumentów. Teraz zobacz, co się stanie, gdy uruchomię skrypt z kilkoma plikami wejściowymi.
Jest coś nowego! "$ @" To skrót od "1 $ 2 $ 3 … $ n". Innymi słowy, jest to pełna lista wszystkich podanych argumentów. Teraz zobacz, co się stanie, gdy uruchomię skrypt z kilkoma plikami wejściowymi.
Możesz zobaczyć, które pliki znajdują się w moim folderze. Uruchomiłem polecenie z sześcioma argumentami, a każdy plik został dodany do spakowanego archiwum o nazwie "archive.zip". Łatwo, prawda?
Możesz zobaczyć, które pliki znajdują się w moim folderze. Uruchomiłem polecenie z sześcioma argumentami, a każdy plik został dodany do spakowanego archiwum o nazwie "archive.zip". Łatwo, prawda?

Dla pętli są całkiem wspaniałe. Teraz możesz wykonywać funkcje wsadowe na listach plików. Na przykład możesz skopiować wszystkie argumenty skryptu do spakowanego archiwum, przenieść oryginały do innego folderu i automatycznie zabezpieczyć je przed skopiowaniem na komputer zdalny. Jeśli skonfigurujesz pliki kluczy z SSH, nie musisz nawet wpisywać swojego hasła, a nawet możesz nakazać skryptowi usunięcie pliku zip po jego przesłaniu!

Korzystanie z pętli for ułatwia wykonanie wielu akcji dla wszystkich plików w katalogu. Możesz zestawiać wiele różnych poleceń i bardzo łatwo użyć argumentów do utworzenia listy "w locie", a to tylko wierzchołek góry lodowej.

Skrypty Bash, czy masz jakieś sugestie? Czy zrobiłeś użyteczny skrypt, który używa pętli? Chcesz podzielić się swoimi przemyśleniami na temat serii? Zostaw kilka komentarzy i pomóż innym początkującym skryptom!

Zalecana: