Jak sprawdzić, czy plik istnieje w skryptach Linux Bash?
Opublikowany: 2022-08-18Jeśli skrypt Linux Bash opiera się na obecności pewnych plików lub katalogów, nie może po prostu zakładać, że tak. Musi sprawdzić, czy na pewno są obecne. Oto jak to zrobić.
Nie zakładaj niczego
Kiedy piszesz skrypt, nie możesz zakładać, co jest, a czego nie ma na komputerze. Jest to podwójnie prawdziwe, jeśli skrypt będzie rozpowszechniany i uruchamiany na wielu różnych komputerach. Prędzej czy później skrypt zostanie uruchomiony na komputerze, który nie spełnia Twoich założeń, a skrypt zakończy się niepowodzeniem lub będzie działał nieprzewidywalnie.
Wszystko, co cenimy lub tworzymy na komputerze, jest przechowywane w pliku o określonym formacie, a wszystkie te pliki znajdują się w katalogu. Skrypty mogą odczytywać, zapisywać, zmieniać nazwy, usuwać i przenosić pliki i katalogi — wszystko to, co możesz zrobić w wierszu poleceń.
Zaletą, jaką masz jako człowiek, jest to, że możesz zobaczyć zawartość katalogu i wiesz, czy plik istnieje, czy nie – lub czy oczekiwany katalog w ogóle istnieje. Jeśli skrypt zawodzi podczas manipulowania plikami, może to mieć poważne i szkodliwe skutki.
Bash zapewnia kompleksowy zestaw testów, których można użyć do wykrywania plików i katalogów oraz testowania wielu ich atrybutów. Włączenie ich do skryptów jest łatwe, ale korzyści pod względem niezawodności i precyzyjnej kontroli są znaczne.
POWIĄZANE: Jak używać testów warunkowych z podwójnym nawiasem w systemie Linux
Zakres badań
Łącząc instrukcję if z odpowiednim testem z dużej kolekcji testów plików i katalogów, możemy łatwo określić, czy plik istnieje, czy jest wykonywalny, zapisywalny i wiele więcej.
- -b : Zwraca prawdę, jeśli plik jest blokowym plikiem specjalnym.
- -c : Zwraca prawdę, jeśli plik jest znakiem specjalnym.
- -d : Zwraca prawdę, jeśli „plik” jest katalogiem.
- -e : Zwraca prawdę, jeśli plik istnieje.
- -f : Zwraca prawdę, jeśli plik istnieje i jest zwykłym plikiem.
- -g : Zwraca prawdę, jeśli plik ma ustawione uprawnienia
setgid
(chmod g+
). - -h : Zwraca prawdę, jeśli plik jest dowiązaniem symbolicznym.
- -L : Zwraca prawdę, jeśli plik jest dowiązaniem symbolicznym.
- -k : Zwraca prawdę, jeśli ma ustawiony bit Sticky (
chmod +t
). - -p : Zwraca prawdę, jeśli plik jest nazwanym potokiem.
- -r : Zwraca prawdę, jeśli plik jest czytelny.
- -s : Zwraca prawdę, jeśli plik istnieje i nie jest pusty.
- -S : Zwraca prawdę, jeśli plik jest gniazdem.
- -t : Zwraca prawdę, jeśli deskryptor pliku jest otwarty w terminalu.
- -u : Zwraca prawdę, jeśli plik ma ustawione uprawnienia
setuid
(chmod u+
). - -w : Zwraca prawdę, jeśli plik jest zapisywalny.
- -x : Zwraca prawdę, jeśli plik jest wykonywalny.
- -O : Zwraca prawdę, jeśli należy do Ciebie.
- -G : Zwraca prawdę, jeśli należy do twojej grupy.
- -N : Zwraca prawdę, jeśli plik został zmodyfikowany od czasu ostatniego odczytu.
- ! : Logiczny operator NOT.
- && : Operator logiczny AND.
- || : Operator logiczny OR.
Lista zaczyna się od -b
, ponieważ test -a
jest przestarzały i zastąpiony testem -e
.
POWIĄZANE: Jak korzystać z SUID, SGID i Sticky Bits w systemie Linux
Korzystanie z testów w skryptach
Ogólna instrukcja testu if
jest prostą konstrukcją skryptową. Porównanie wewnątrz podwójnych nawiasów „ [[ ]]
” wykorzystuje test -f
w celu określenia, czy istnieje zwykły plik o tej nazwie.
Skopiuj tekst tego skryptu do edytora i zapisz go w pliku o nazwie „script1.sh” i użyj chmod
, aby uczynić go wykonywalnym.
#!/kosz/bash jeśli [[ -f $1 ]] następnie echo "Plik $1 istnieje." w przeciwnym razie echo "Nie można znaleźć pliku $1." fi
Musisz przekazać nazwę pliku do skryptu w linii poleceń.
chmod +x skrypt1.sh
Musisz to zrobić z każdym skryptem, jeśli chcesz wypróbować inne przykłady z artykułu.
Wypróbujmy skrypt na prostym pliku tekstowym.
./script1.sh plik-testowy.txt
Plik istnieje i skrypt poprawnie zgłasza ten fakt. Jeśli usuniemy plik i spróbujemy ponownie, test powinien zakończyć się niepowodzeniem, a skrypt powinien nam to zgłosić.
./script1.sh plik-testowy.txt
W rzeczywistej sytuacji skrypt musiałby podjąć odpowiednie działania. Być może oznacza to błąd i zatrzymuje się. Może tworzy plik i kontynuuje. Może skopiować coś z katalogu kopii zapasowej, aby zastąpić brakujący plik. Wszystko zależy od przeznaczenia scenariusza. Ale przynajmniej teraz skrypt jest w stanie podjąć decyzję na podstawie wiedzy, czy plik jest obecny, czy nie.
Flaga -f
sprawdza, czy plik jest obecny i jest „zwykłym” plikiem. Innymi słowy, nie jest to coś, co wydaje się być plikiem, ale nim nie jest, na przykład plik urządzenia.
Użyjemy ls, aby sprawdzić, czy plik „/dev/random” istnieje, a następnie zobaczymy, co zrobi z niego skrypt.
ls -lh /dev/losowe
./skrypt /dev/losowy
Ponieważ nasz skrypt testuje zwykłe pliki, a „/dev/random” jest plikiem urządzenia, test nie powiedzie się. Bardzo często, aby dotrzeć do sedna tego, czy plik istnieje, musisz uważnie wybrać test, którego używasz, lub musisz użyć kilku testów.
To jest „script2.sh”, który testuje zwykłe pliki i pliki urządzeń znakowych.
#!/kosz/bash jeśli [[ -f $1 ]] następnie echo "Plik $1 istnieje." w przeciwnym razie echo "Brak pliku $1 lub nie jest to zwykły plik." fi jeśli [[ -c $1 ]] następnie echo "Plik $1 jest plikiem urządzenia znakowego." w przeciwnym razie echo "Brak pliku $1 lub nie jest to plik specjalny." fi
Jeśli uruchomimy ten skrypt na pliku urządzenia „/dev/random”, pierwszy test zakończy się niepowodzeniem, czego oczekujemy, a drugi test zakończy się sukcesem. Rozpoznaje plik jako plik urządzenia.
./script2.sh /dev/losowo
W rzeczywistości rozpoznaje go jako plik urządzenia znakowego . Niektóre pliki urządzeń są plikami urządzeń blokowych. W obecnej sytuacji nasz skrypt sobie z tym nie poradzi.
./script2.sh /dev/sda
Możemy użyć operatora logicznego OR
i dołączyć kolejny test w drugiej instrukcji if. Tym razem, niezależnie od tego, czy plik jest plikiem urządzenia znakowego, czy plikiem urządzenia blokowego, test zwróci true. To jest „script3.sh”.
#!/kosz/bash jeśli [[ -f $1 ]] następnie echo "Plik $1 istnieje." w przeciwnym razie echo "Brak pliku $1 lub nie jest to zwykły plik." fi jeśli [[ -c $1 || -b $1]] następnie echo "Plik $1 jest plikiem znakowym lub blokowym." w przeciwnym razie echo "Brak pliku $1 lub nie jest to plik specjalny." fi
Ten skrypt rozpoznaje zarówno pliki urządzeń znakowych, jak i urządzenia blokowe.
./script3.sh /dev/losowo
./script3.sh /dev/sda
Jeśli ważne jest dla Ciebie rozróżnienie pomiędzy różnymi typami plików urządzeń, możesz użyć zagnieżdżonych instrukcji if
. To jest „script4.sh”.
#!/kosz/bash jeśli [[ -f $1 ]] następnie echo "Plik $1 istnieje." w przeciwnym razie echo "Brak pliku $1 lub nie jest to zwykły plik." fi jeśli [[ -c $1 ]] następnie echo "Plik $1 jest plikiem urządzenia znakowego." w przeciwnym razie jeśli [[ -b $1 ]] następnie echo "Plik $1 jest plikiem urządzenia blokowego." w przeciwnym razie echo "Brak pliku $1 lub nie jest to plik urządzenia." fi fi
Ten skrypt rozpoznaje i kategoryzuje zarówno pliki urządzeń znakowych, jak i urządzenia blokowe.
./script4.sh /dev/losowo
./script4.sh /dev/sda
Używając operatora logicznego AND możemy przetestować kilka cech jednocześnie. To jest „script5.sh”. Sprawdza, czy plik istnieje, a skrypt ma do niego uprawnienia do odczytu i zapisu.
#!/kosz/bash if [[ -f $1 && -r $1 && -w $1 ]] następnie echo "Plik $1 istnieje i mamy uprawnienia do odczytu/zapisu." w przeciwnym razie echo "Brakuje pliku $1, a nie zwykłego pliku lub nie możemy do niego czytać/zapisywać." fi
Uruchomimy skrypt na pliku, który należy do nas i do root
.
./script5.sh .bashrc
./script5.sh /etc/fstab
Aby sprawdzić istnienie katalogu, użyj testu -d
. To jest „script6.sh”. Jest to część skryptu kopii zapasowej. Pierwszą rzeczą, jaką robi, jest sprawdzenie, czy katalog podany w wierszu poleceń istnieje, czy nie. Używa logicznego operatora NOT
!
w teście instrukcji if
.
#!/kosz/bash jeśli [[ ! -d $1 ]] następnie echo "Tworzenie katalogu kopii zapasowej:" $1 mkdir $1 jeśli [[ ! $? -równ 0 ]] następnie echo "Nie udało się utworzyć katalogu kopii zapasowej:" $1 Wyjście fi w przeciwnym razie echo "Katalog kopii zapasowej istnieje." fi # kontynuuj tworzenie kopii zapasowej pliku echo "Tworzenie kopii zapasowej do: "$1
Jeśli katalog nie istnieje, tworzy go. Jeśli pliki tworzenia katalogu, skrypt kończy działanie. Jeśli utworzenie katalogu powiedzie się lub katalog już istnieje, skrypt kontynuuje wykonywanie operacji tworzenia kopii zapasowych.
Uruchomimy skrypt, a następnie za pomocą ls
i opcji -d
(katalog) sprawdzimy, czy istnieje katalog kopii zapasowej.
./script6.sh Dokumenty/kopia zapasowa projektu
ls -d Dokumenty/kopia zapasowa projektu
Katalog kopii zapasowej został utworzony. Jeśli ponownie uruchomimy skrypt, powinien zgłosić, że katalog jest już obecny.
./skrypt6.sh
Skrypt odnajduje katalog i przechodzi do wykonania kopii zapasowej.
Testuj, nie zakładaj
Wcześniej czy później założenia doprowadzą do złych rzeczy. Najpierw przetestuj i odpowiednio zareaguj.
Wiedza to potęga. Użyj testów, aby dać skryptom wiedzę, której potrzebują.
POWIĄZANE: Jak pozwolić skryptom Linuksa wykryć, że działają w maszynach wirtualnych?