Prawidłowe analizowanie zmiennej i cytowania w Bash
- 4402
- 443
- Natan Cholewa
Nieprawidłowe cytowanie w oryginalnym kodzie źródłowym może łatwo prowadzić do błędów, gdy dane wejściowe przez użytkowników nie są zgodne z oczekiwaniami lub nie jednolite. Z czasem, gdy zmieniają się skrypty bash, nieprzewidziany efekt uboczny niepoprawnie cytowanej zmiennej może prowadzić do błędu nawet w skądinąd nietkniętym kodzie. Jest to jeszcze ważniejsze w przypadku aplikacji związanych z bezpieczeństwem, które mogą być podatne na próby hakowania. Dowiedz się, jak prawidłowo cytować i od samego początku analizować/sprawdzić się walidację i unikaj wielu z tych problemów! Zacznijmy…
W tej serii samouczków się nauczysz:
- Jak poprawnie zacytować zmienne bash
- Zastrzeżenia i wyniki niepoprawnego cytowania
- Jak zapewnić, że wartości zmienne są tym, czym powinny być
- Jak sprawdzić, czy wartość zmiennych i opartych na numerze i tekst
Zastosowane wymagania i konwencje oprogramowania
Kategoria | Wymagania, konwencje lub wersja oprogramowania |
---|---|
System | Niezależny od rozkładu Linuksa |
Oprogramowanie | Wiersz poleceń Bash, system oparty na Linuksie |
Inny | Wszelkie narzędzie, które nie jest zawarte w skorupce Bash domyślnie można zainstalować za pomocą za pomocą sudo apt-get instal instal narzędzie (lub mniam zamiast apt-get) |
Konwencje | # - Wymaga wykonywania Linux -Commands z uprawnieniami root bezpośrednio jako użytkownik root lub za pomocą sudo Komenda$-Wymaga wykonania Linux-commands jako zwykłego niepewnego użytkownika |
Przykład 1: Cytuj te zmienne!
O ile nie pracujesz z wartościami numerycznymi, a nawet w takim przypadku, mądrze jest zawsze zacytować zmienne tekstowe podczas sprawdzania równości itp. Spójrzmy na przykład:
$ Var1 = "a"; if [$ var1 == "a"]; Następnie echo „Tak!';; Fi Tak! $ Var1 =; if [$ var1 == "a"]; Następnie echo „Tak!';; FI BASH: [: ==: Oczekiwano Unary Operator
Najpierw ustawiliśmy Var1
do wartości A
a następnie sprawdziłem, czy Var1
równy A
. To zadziałało i możemy pomyśleć, że nasz kod jest w porządku i pozostawić go w naszym skrypcie. Jednak jakiś czas później i po wielu zmianach kodu, zaczynamy widzieć Bash: [: ==: Oczekiwany operator Unary
- Nieco tajemnicza wiadomość informująca, że jest coś nie tak z naszym kodem.
Powód jest pokazany w drugim przykładzie. Jeśli jakoś nasza zmienna jest pusta, ja.mi. nie został ustawiony prawidłowo (lub został usunięty od czasu ustawienia), wówczas otrzymamy błąd, ponieważ Bash skutecznie to odczytuje; Jeśli [== "a"]
co jest stwierdzeniem, które nie ma większego sensu i nie oblicza.
Jeśli właściwie cytowaliśmy naszą zmienną z podwójnymi cytatami ("
), tak się nie stało:
$ Var1 =; if ["$ var1" == "a"]; Następnie echo „Tak!';; fi $
Tym razem Bash przeczytaj stwierdzenie jako Jeśli ["" == "a"]
- stwierdzenie łatwiejsze na oczach, jak i kompilator Bash. Żadne wyjście nie jest generowane, ponieważ wyraźnie pusty ciąg nie równa się literie A
.
Przykład 2: Wykonanie nieco dalej
Kiedy już przez chwilę będziesz pracował z Bash, nauczysz. Jednym z takich idiomów jest - nazwijmy to przywilejem (i z pewnością jest to wygoda!) - aby móc cytować zmienne numeryczne, nawet jeśli wykonywana jest operacja numeryczna:
$ Var1 = 13; if ["$ var1" -eq 13]; Następnie echo „Tak!';; Fi Tak! $ Var1 = 7; if ["$ var1" -eq 13]; Następnie echo „Tak!';; fi
Mimo że var1 jest ustawiony na wartość liczbową, Bash zaakceptuje "
cytując wokół var1 i prawidłowo daj wynik instrukcji IF za pomocą jest równy
(I.mi. -Eq
) Operacja porównawcza.
Jednak nie dotarliśmy jeszcze do pełnego koła, ponieważ następujące wciąż zawodzą;
$ Var1 =; if ["$ var1" -eq 13]; Następnie echo „Tak!';; Fi Bash: [::: oczekiwane wyrażenie całkowitego
Tym razem oczekuje się wyrażenia liczb całkowitych, ale pusta zmienna (i.mi. „”
został przekazany), a to z pewnością nie jest numeryczne. Czy istnieje sposób, aby to naprawić? Jasne:
Przykład 3: Sprawdzanie długości zerowej
$ Var1 =; if [-n "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; fi $ var1 = 13; if [-n "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Fi Tak!
Tutaj używamy kontroli przed -N
co oznacza że Ciąg nie ma długości zerowej. Można to również zamienić na odwrotność, używając ! -z
Gdzie -z
oznacza Ciąg ma długość zeru i !
neguje to samo, ja.mi. odwraca wynik:
$ Var1 =; Jeśli [ ! -Z "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; fi $ var1 = 13; Jeśli [ ! -Z "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Fi Tak! $ Var1 = 7; Jeśli [ ! -Z "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; fi $
Dodaliśmy również = 7
Przykład tutaj, aby pokazać, jak Jeśli
Instrukcja poprawnie. Zawsze testuj swoje Jeśli
stwierdzenia i warunki w różnych sytuacjach, przypadkach użycia i ogólnych wyjątków (złe wartości, brak wartości, wartości nieparzystych itp.) Jeśli chcesz upewnić się, że Twój kod będzie wolny od błędów.
Przykład 4: prawie pełna kontrola
W ostatnim przykładzie wciąż jest wad. Zrobiłeś to? Zasadniczo, jeśli przekazujemy wartości tekstowe do ciągu, lub Jeśli
Oświadczenie wciąż zawodzi:
$ Var1 = "a"; Jeśli [ ! -Z "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Fi Bash: [: A: Oczekiwana ekspresja liczb całkowita
Można to pokonać za pomocą subshell, Grep
, i niektóre wyrażenia regularne. Aby uzyskać więcej informacji na temat wyrażeń regularnych, zobacz naszą regexps Bash dla początkujących z przykładami i zaawansowaną regex Bash z przykładami artykułów. Aby uzyskać więcej informacji na temat bash subshells, zobacz nasze subshells Linux dla początkujących z przykładami i zaawansowanymi subshellami Linux z przykładami artykułów.
Składnia nie jest zbyt złożona:
$ Var1 = 7; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; fi $ var1 = 13; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Fi Tak! $ Var1 = "a"; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; fi $
Świetnie. Tutaj sprawdzamy zawartość Var1
być numerycznym za pomocą GREP -O
(tylko grep; i.mi. GREP tylko część dopasowana przez ciąg wyszukiwania, który w tym przypadku jest wyrażeniem regularnym). Wybieramy dowolne liczbę z postaci z 0-9
i to jeden lub więcej razy (Jak wskazuje \+
kwalifikator do [0-9]
Zakres selekcji). Następnie staramy się to dopasować Grep dopasowana tylko część Tekst na oryginalnej zmiennej. Czy to samo? Jeśli tak, to nasza zmienna składa się tylko z liczb.
Kiedy rozszerzamy nasz zewnętrzny Jeśli
stwierdzenie nieco zawierające w przeciwnym razie
klauzula, która powie nam, czy zmienna nie jest numeryczna, a kiedy próbujemy przekazać 'A'
Jako dane wejściowe widzimy, że różne dane wejściowe są poprawnie analizowane;
$ Var1 = 7; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Else Echo „Zmienna, a nie numeryczna!';; fi $ var1 = 13; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Else Echo „Zmienna, a nie numeryczna!';; Fi Tak! $ Var1 = "a"; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Else Echo „Zmienna, a nie numeryczna!';; zmienna FI, a nie numeryczna!
Więc teraz mamy idealną linię do naszego kodu, nie? Nie… wciąż czegoś brakuje… czy widzisz co?
Przykład 5: Pełna kontrola
Czy widziałeś problem? Nie sprawdziliśmy jeszcze pustej zmiennej!
$ Var1 = "; if [" $ (echo "$ var1" | grep -o '[0-9] \+') "==" $ var1 "]; to if [" $ var1 „-eq 13]; wtedy echo„ tak!';; fi; Else Echo „Zmienna, a nie numeryczna!';; Fi Bash: [::: oczekiwane wyrażenie całkowitego
Auć. Ufam już, że rozumiesz, dlaczego regularnie wspominam w moich artykułach, aby zawsze sprawdzać tworzenie kodu w taki czy inny sposób. Jasne, Bash nadaje się do szybkiego i łatwego skryptów, ale jeśli chcesz upewnić się, że wszystko będzie działać poprawnie podczas zmiany skryptów lub dodania dodatkowego kodu, będziesz chciał upewnić się, że testy, wejścia i wyjścia są czyste i wyraźnie zdefiniowane. Poprawka jest łatwa:
$ Var1 = "; jeśli [ ! -Z "$ var1" -a "$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Następnie jeśli ["$ var1" -eq 13]; Następnie echo „Tak!';; fi; Else Echo „Zmienna, a nie numeryczna!';; zmienna FI, a nie numeryczna!
Tutaj, za pomocą pięści Jeśli
Instrukcja, dodajemy dodatkowy warunek dla zmiennej Var1
żeby nie (!
) być zmienną o zerowej długości. Działa to dobrze, biorąc pod uwagę bieżącą konfigurację jako drugą część pierwszego Jeśli
stwierdzenie może nadal kontynuować niezależnie od treści Var1
.
Wniosek
W tym artykule przyjrzeliśmy się, jak prawidłowo zacytować i analizować/ocenić zmienne, i zbadaliśmy, jak skomplikowaliśmy napisanie idealnej zmiennej sprawdzania kodu bash. Uczenie się, jak robić te rzeczy prawidłowo od samego początku, znacznie ograniczy ilość możliwych błędów, które można wprowadzić przez przypadek.
Ciesz się i podwójnie cytuj te zmienne! 🙂
Powiązane samouczki Linux:
- Lista najlepszych narzędzi Kali Linux do testowania penetracji i…
- Obsługa danych wejściowych użytkownika w skryptach Bash
- Zagnieżdżone pętle w skryptach Bash
- Wprowadzenie do automatyzacji, narzędzi i technik Linuksa
- Advanced Bash Regex z przykładami
- Samouczek debugowania GDB dla początkujących
- Mastering Bash Script Loops
- Specjalne zmienne bash z przykładami
- Wyrażenia regularne Pythona z przykładami
- Jak używać bash subshells w środku, jeśli instrukcje