9 przykładów skryptów Bash, które pomogą Ci zacząć w systemie Linux

Opublikowany: 2022-07-05
Terminal Linux na ekranie laptopa.
fatmawati achmad zaenuri/Shutterstock.com

Jeśli zaczynasz od pisania skryptów Bash w systemie Linux, solidne zrozumienie podstaw zapewni ci dobrą pozycję. Stanowią podstawę głębszej wiedzy i wyższych umiejętności pisania skryptów.

Pamiętaj, uczyń swoje skrypty wykonywalnymi

Aby powłoka mogła wykonać skrypt, skrypt musi mieć ustawione uprawnienia pliku wykonywalnego. Bez tego twój skrypt jest tylko plikiem tekstowym. Dzięki niemu nadal jest to plik tekstowy, ale powłoka wie, że zawiera instrukcje i spróbuje je wykonać, gdy skrypt zostanie uruchomiony.

Cały sens pisania skryptów polega na tym, że się uruchamiają, więc pierwszym podstawowym krokiem jest dowiedzenie się, jak poinformować Linuksa, że ​​twój skrypt powinien być uważany za wykonywalny.

Polecenie chmod pozwala nam ustawić uprawnienia do plików. Uprawnienie do wykonywania można ustawić za pomocą flagi +x.

 chmod +x skrypt1.sh 

Tworzenie skryptu wykonywalnego

Musisz to zrobić w każdym ze swoich skryptów. Zastąp „script1.sh” nazwą swojego skryptu.

1. Co to za dziwna pierwsza linia?

Pierwsza linia skryptu mówi powłoce, który interpreter powinien zostać wywołany, aby uruchomić ten skrypt. Pierwsza linia musi zaczynać się od shebanga „#!”, znanego również jako hashbang. „#!” mówi powłoce, że ten wiersz zawiera ścieżkę i nazwę interpretera, dla którego został napisany skrypt.

Jest to ważne, ponieważ jeśli napisałeś skrypt do uruchomienia w Bash, nie chcesz, aby był on interpretowany przez inną powłokę. Prawdopodobne są niezgodności. Bash — podobnie jak większość powłok — ma swoje własne dziwactwa składni i funkcjonalności, których inne powłoki nie będą miały lub będą zaimplementowane w inny sposób.

Po uruchomieniu skryptu bieżąca powłoka otwiera skrypt i określa, której powłoki lub interpretera należy użyć do wykonania tego skryptu. Następnie uruchamia tę powłokę i przekazuje do niej skrypt.

 #!/kosz/bash

echo Działa w $SHELL

Pierwszy wiersz tego skryptu można odczytać jako „Użyj interpretera znajdującego się w /bin/bash, aby uruchomić ten skrypt”.

Jedyna linia w skrypcie zapisuje na ekranie terminala wartość przechowywaną w zmiennej środowiskowej $SHELL . Potwierdza to, że Bash został użyty do wykonania skryptu.

 ./skrypt1.sh 

Identyfikowanie powłoki, w której działa skrypt

W ramach pewnej sztuczki salonowej możemy zademonstrować, że skrypt jest przekazywany do dowolnego wybranego przez nas interpretera.

 #!/kosz/kot
Wszystkie wiersze tekstu są przekazywane do polecenia cat
i są drukowane w oknie terminala. To obejmuje
linia shebang.
 skrypt2.sh 

Uruchamianie skryptu przez przekazanie go do polecenia cat

Ten skrypt jest uruchamiany przez bieżącą powłokę i przekazywany do komendy cat . Polecenie cat „uruchamia” skrypt.

Pisząc swoje shebangs w ten sposób, zakładasz, że wiesz, gdzie znajduje się powłoka lub inny interpreter na docelowej maszynie. I w 99% przypadków jest w porządku. Ale niektórzy ludzie lubią zabezpieczać swoje zakłady i pisać swoje shebangs w ten sposób:

 #!/usr/bin/env bash

echo Działa w $SHELL
 skrypt3.sh 

Uruchamianie skryptu wyszukującego powłokę

Po uruchomieniu skryptu powłoka szuka lokalizacji nazwanej powłoki. Jeśli powłoka znajduje się w niestandardowej lokalizacji, tego typu podejście pozwala uniknąć błędów „złego interpretera”.

Nie słuchaj, on kłamie!

W Linuksie zawsze jest więcej niż jeden sposób, by oskórować kota lub udowodnić, że autor się myli. Aby być w pełni rzeczowym, istnieje sposób na uruchamianie skryptów bez rzucania się w oczy i bez powodowania ich wykonywania.

Jeśli uruchomisz powłokę, w której chcesz wykonać skrypt, i przekażesz skrypt jako parametr wiersza poleceń, powłoka uruchomi i uruchomi skrypt — niezależnie od tego, czy jest wykonywalny, czy nie. Ponieważ wybierasz powłokę w wierszu poleceń, nie ma potrzeby rzucania.

Oto cały skrypt:

 echo "Zostałem stracony przez" $SHELL

Użyjemy ls , aby zobaczyć, że skrypt naprawdę nie jest wykonywalny i uruchomimy Bash z nazwą skryptu:

 ls
 bash skrypt4.sh 

Uruchamianie skryptu, który nie ma ustawionych uprawnień do pliku wykonywalnego i nie ma strasznego

Istnieje również sposób, aby skrypt był uruchamiany przez bieżącą powłokę, a nie powłokę uruchamianą specjalnie w celu wykonania skryptu. Jeśli używasz polecenia source , które można skrócić do pojedynczej kropki „ . “, twój skrypt jest wykonywany przez twoją obecną powłokę.

Tak więc, aby uruchomić skrypt bez huku, bez uprawnień do pliku wykonywalnego i bez uruchamiania innej powłoki, możesz użyć jednego z tych poleceń:

 skrypt źródłowy4.sh
 . skrypt4.sh 

Uruchamianie skryptu w bieżącej powłoce

Chociaż jest to możliwe, nie jest zalecane jako ogólne rozwiązanie. Są wady.

Jeśli skrypt nie zawiera frajdy, nie możesz powiedzieć, dla której powłoki został napisany. Czy będziesz pamiętać za rok? Bez ustawienia uprawnień do wykonywania w skrypcie polecenie ls nie zidentyfikuje go jako pliku wykonywalnego ani nie użyje koloru do odróżnienia skryptu od zwykłych plików tekstowych.

POWIĄZANE: Wiersze poleceń: dlaczego ludzie nadal się nimi przejmują?

2. Drukowanie tekstu

Pisanie tekstu na terminalu jest powszechnym wymogiem. Trochę wizualnej informacji zwrotnej ma długą drogę.

W przypadku prostych wiadomości wystarczy polecenie echo . Pozwala na pewne formatowanie tekstu i pozwala również pracować ze zmiennymi.

 #!/kosz/bash

echo To jest prosty ciąg.
echo "To jest ciąg znaków zawierający 'pojedyncze cudzysłowy', więc jest opakowany w podwójne cudzysłowy."
echo "Wypisuje nazwę użytkownika:" $USER
echo -e "Opcja -e pozwala nam użyć\ndyrektyw formatujących\ndo podziału ciągu."
 ./skrypt5.sh 

Skrypt używający polecenia echo do pisania w oknie terminala

Polecenie printf daje nam większą elastyczność i lepsze możliwości formatowania, w tym konwersję liczb.

Ten skrypt drukuje tę samą liczbę przy użyciu trzech różnych podstaw liczbowych. Wersja szesnastkowa jest również sformatowana do drukowania wielkimi literami, z wiodącymi zerami i szerokością trzech cyfr.

 #!/kosz/bash

printf "Dziesiętny: %d, ósemkowy: %o, szesnastkowy: %03X\n" 32 32 32
 ./skrypt6.sh 

Skrypt używający printf do konwersji i formatowania liczb

Zauważ, że w przeciwieństwie do echo , musisz powiedzieć printf , aby rozpoczynał nową linię od tokena „ \n ”.

3. Tworzenie i używanie zmiennych

Zmienne umożliwiają przechowywanie wartości w programie oraz manipulowanie nimi i używanie ich. Możesz tworzyć własne zmienne lub używać zmiennych środowiskowych dla wartości systemowych.

 #!/kosz/bash

millennium_text="Lata od tysiąclecia:"

current_time=$( data '+%H:%M:%S' )
Todays_date=$( data '+%F' )
rok=$( data '+%Y' )

echo "Aktualny czas:" $current_time
echo "Dzisiejsza data:" $todays_date

years_since_Y2K=$(( rok - 2000 ))

echo $millennium_text $years_since_Y2K

Ten skrypt tworzy zmienną łańcuchową o nazwie millennium_text . Zawiera linię tekstu.

Następnie tworzy trzy zmienne liczbowe.

  • Zmienna current_time jest inicjowana do czasu wykonania skryptu.
  • Zmienna todays_date jest ustawiona na datę uruchomienia skryptu.
  • Zmienna year zawiera bieżący rok.

Aby uzyskać dostęp do wartości przechowywanej w zmiennej, poprzedź jej nazwę znakiem dolara „$”.

 ./skrypt7.sh 

Skrypt wykorzystujący zmienne do obliczania okresów czasu

Skrypt drukuje godzinę i datę, a następnie oblicza, ile lat minęło od tysiąclecia, i zapisuje to w zmiennej years_since_Y2K .

Na koniec wypisuje ciąg znaków zawarty w zmiennej millennium_text i wartość liczbową zapisaną w years_since_Y2K .

POWIĄZANE: Jak pracować ze zmiennymi w Bash

4. Obsługa danych wejściowych użytkownika

Aby umożliwić użytkownikowi wprowadzenie wartości, której użyje skrypt, musisz mieć możliwość przechwytywania danych wprowadzanych z klawiatury. Polecenie read Bash pozwala to zrobić. Oto prosty przykład.

 #!/kosz/bash

echo "Wprowadź liczbę i naciśnij \"Wprowadź\""
przeczytaj numer_użytkownika1;
echo "Wprowadź inną liczbę i naciśnij \"Wprowadź\""
przeczytaj numer_użytkownika2;

printf "Wpisałeś: %d i %d\n" $user_number1 $user_number2
printf "Dodane razem tworzą: %d\n" $((numer_użytkownika1 + numer_użytkownika2))

Skrypt prosi o dwie liczby. Są one odczytywane z klawiatury i przechowywane w dwóch zmiennych, user_number1 i user_number2 .

Skrypt wypisuje liczby w oknie terminala, dodaje je do siebie i wyświetla sumę.

 ./skrypt8.sh 

Przechwytywanie danych wejściowych użytkownika za pomocą polecenia odczytu

Podpowiedzi możemy połączyć z poleceniami read za pomocą opcji -p (podpowiedź).

 #!/kosz/bash

read -p "Wprowadź liczbę i naciśnij \"Enter\" " numer_użytkownika1;
read -p "Wprowadź inną liczbę i naciśnij \"Enter\" " numer_użytkownika2;

printf "Wpisałeś: %d i %d\n" $user_number1 $user_number2
printf "Dodane razem tworzą: %d\n" $((numer_użytkownika1 + numer_użytkownika2))

To sprawia, że ​​rzeczy są ładniejsze i łatwiejsze do odczytania. Skrypty, które są łatwe do odczytania, są również łatwiejsze do debugowania.

 ./skrypt9.sh 

Przechwytywanie danych wejściowych użytkownika za pomocą polecenia odczytu i opcji -p (podpowiedź)

Skrypt zachowuje się teraz nieco inaczej. Dane wejściowe użytkownika znajdują się w tym samym wierszu, co monit.

Aby przechwycić dane wejściowe z klawiatury bez wywoływania ich echem w oknie terminala, użyj opcji -s (cichy).

 #!/kosz/bash

read -s -p "Wprowadź swój tajny PIN i naciśnij \"Wprowadź\" " secret_PIN;

printf "\nCiii... to %d\n" $secret_PIN
 ./skrypt10.sh 

Przechwytywanie danych wejściowych użytkownika bez zapisywania ich w oknie terminala

Wartość wejściowa jest przechwytywana i przechowywana w zmiennej o nazwie secret_PIN , ale nie jest wyświetlana na ekranie, gdy użytkownik ją wpisuje . To, co z nim zrobisz, zależy od Ciebie.

5. Akceptacja parametrów

Czasami wygodniej jest zaakceptować dane wprowadzone przez użytkownika jako parametry wiersza poleceń, niż mieć skrypt czekający na dane wejściowe. Przekazywanie wartości do skryptu jest łatwe. Można się do nich odwoływać w skrypcie tak, jakby były jakąkolwiek inną zmienną.

Pierwszy parametr staje się zmienną $1 , drugi parametr staje się zmienną $2 i tak dalej. Zmienna $0 zawsze przechowuje nazwę skryptu, a zmienna $# zawiera liczbę parametrów podanych w wierszu poleceń. Zmienna $@ to ciąg znaków, który zawiera wszystkie parametry wiersza poleceń.

 #!/kosz/bash

printf "Ten skrypt nazywa się: %s\n" $0
printf "Użyłeś %d parametrów wiersza poleceń\n" $#

# pętla przez zmienne
dla param w "$@"; robić
  echo "$param"
Gotowe

echo "Parametr 2 to:" $2

Ten skrypt używa $0 i $# do wydrukowania niektórych informacji. następnie używa ?@ do pętli przez wszystkie parametry wiersza poleceń. Używa $2 , aby pokazać, jak uzyskać dostęp do pojedynczej, określonej wartości parametru.

 ./skrypt11.sh 

Używanie parametrów wiersza poleceń ze skryptem

Zawinięcie kilku słów w cudzysłów „”” łączy je w jeden parametr.

6. Odczytywanie danych z plików

Umiejętność odczytywania danych z pliku to świetna umiejętność. Możemy to zrobić w Bash za pomocą pętli while.

 #!/kosz/bash

Liczba linii=0

podczas gdy IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; robić

  ((Licznik Linii++))
  echo "Wiersz odczytu $LineCount: ${LinefromFile}"

gotowe < „1 USD”

Jako parametr wiersza poleceń przekazujemy nazwę pliku, który skrypt ma przetworzyć. Będzie to jedyny parametr, więc wewnątrz skryptu $1 będzie przechowywał nazwę pliku. Przekierowujemy ten plik do pętli while .

Jak przetwarzać wiersz po wierszu w skrypcie Linux Bash?
POWIĄZANE Jak przetwarzać wiersz po wierszu w skrypcie Linux Bash

Pętla while ustawia wewnętrzny separator pól na pusty łańcuch, używając przypisania IFS='' . Zapobiega to dzieleniu przez polecenie read linii w odstępach. Tylko powrót karetki na końcu wiersza jest uważany za prawdziwy koniec wiersza.

Klauzula [[ -n "${LinefromFile}" ]] uwzględnia możliwość, że ostatnia linia w pliku nie kończy się znakiem powrotu karetki. Nawet jeśli tak się nie stanie, ta ostatnia linia będzie obsługiwana poprawnie i traktowana jako zwykła linia zgodna z POSIX.

 ./script12.sh twinkle.txt 

Odczytywanie tekstu z pliku za pomocą skryptu

7. Korzystanie z testów warunkowych

Jeśli chcesz, aby Twój skrypt wykonywał różne akcje dla różnych warunków, musisz wykonać testy warunkowe. Składnia testu z dwoma nawiasami zapewnia — na początku — przytłaczającą liczbę opcji.

 #!/kosz/bash

cena = 1 USD

jeśli [[ cena -ge 15 ]];
następnie
  echo "Zbyt drogie."
w przeciwnym razie
  echo "Kup to!"
fi

Bash udostępnia cały zestaw operatorów porównania, które pozwalają określić takie rzeczy, jak to, czy plik istnieje, czy możesz z niego czytać, czy możesz w nim pisać i czy istnieje katalog.

Zawiera również testy numeryczne dla równych -qe , większych niż -gt , mniejszych lub równych -le ​​i tak dalej, chociaż można również użyć znanej notacji == , >= , <= .

 ./skrypt13.sh 13
 ./skrypt13.sh 14
 ./skrypt13.sh 15
 ./skrypt13.sh 16 

Uruchamianie skryptu z testem warunkowym

8. Potęga pętli for

Powtarzanie czynności w kółko najlepiej wykonać za pomocą pętli. Pętla for pozwala uruchomić pętlę wiele razy. Może to być do określonej liczby lub może trwać do momentu, gdy pętla przejdzie przez listę elementów.

 #!/kosz/bash

dla (( i=0; i<=$1; i++ ))
robić
  echo "pętla w stylu C:" $i
Gotowe

dla mnie w {1..4}
robić
  echo "Pętla For z zakresem:" $i
Gotowe

dla mnie w „zero” „jeden” „dwa” „trzy”
robić
  echo "Pętla For z listą słów:" $i
Gotowe

website="Jak geekować"

dla mnie w $website
robić
  echo "Pętla For ze zbiorem słów:" $i
Gotowe

Wszystkie te pętle są pętlami for , ale działają z różnymi typami instrukcji pętli i danych.

 ./skrypt14.sh 3 

Uruchamianie skryptu z czterema różnymi typami pętli for

Pierwsza pętla to klasyczna pętla for w stylu C. Licznik pętli i jest inicjowany na zero i zwiększany z każdym cyklem pętli. Chociaż wartość i jest mniejsza lub równa wartości przechowywanej w $1 , pętla będzie nadal działać.

Druga pętla działa przez zakres liczb od 1 do 4. Trzecia pętla działa na liście słów. Chociaż jest więcej słów do przetworzenia, pętla się powtarza.

Ostatnia pętla działa poprzez listę słów w zmiennej łańcuchowej.

9. Funkcje

Funkcje umożliwiają hermetyzację sekcji kodu w nazwane procedury, które można wywoływać z dowolnego miejsca w skrypcie.

Załóżmy, że chcielibyśmy, aby nasz skrypt, który odczytuje wiersze z pliku, wykonał jakiś rodzaj przetwarzania na każdym wierszu. Byłoby wygodnie mieć ten kod zawarty w funkcji.

 #!/kosz/bash

Liczba linii=0

funkcja count_words() {
  printf "%d słowa w linii %d\n" $(echo $1 | wc -w) $2
}

podczas gdy IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; robić

  ((Licznik Linii++))
  count_words "$LinefromFile" $LineCount

gotowe < „1 USD”

count_words "Nie ma tego w pętli" 99

Zmodyfikowaliśmy nasz program do odczytu plików, dodając funkcję o nazwie count_words . Jest zdefiniowany, zanim będziemy musieli go użyć.

Definicja funkcji zaczyna się od słowa function . Po nim następuje unikalna nazwa naszej funkcji, po której następuje nawias „ () ”. Treść funkcji znajduje się w nawiasach klamrowych „{}”.

Definicja funkcji nie powoduje wykonania żadnego kodu. Nic w funkcji nie jest uruchamiane, dopóki funkcja nie zostanie wywołana.

Funkcja count_words wypisuje liczbę słów w wierszu tekstu i numer wiersza. Te dwa parametry są przekazywane do funkcji, tak jak parametry są przekazywane do skryptu. Pierwszy parametr staje się zmienną funkcji $1 , a drugi parametr staje się zmienną funkcji $2 , i tak dalej.

Pętla while odczytuje każdy wiersz z pliku i przekazuje go do funkcji count_words wraz z numerem wiersza. Aby pokazać, że możemy wywołać funkcję z różnych miejsc w skrypcie, wywołujemy ją jeszcze raz poza pętlą while .

 ./script15.sh twinkle.txt 

Uruchamianie skryptu korzystającego z funkcji

Nie bój się krzywej uczenia się

Skrypty są satysfakcjonujące i przydatne, ale trudno się w nie wpaść. Gdy zdobędziesz za pasem kilka technik wielokrotnego użytku, będziesz w stanie stosunkowo łatwo pisać wartościowe skrypty. Następnie możesz przyjrzeć się bardziej zaawansowanej funkcjonalności.

Spaceruj, zanim zaczniesz biegać i poświęć trochę czasu, aby cieszyć się podróżą.

POWIĄZANE: 10 podstawowych poleceń systemu Linux dla początkujących