Prawidłowe analizowanie zmiennej i cytowania w Bash

Prawidłowe analizowanie zmiennej i cytowania w Bash

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
Prawidłowe analizowanie zmiennej i cytowania w Bash

Zastosowane wymagania i konwencje oprogramowania

Wymagania oprogramowania i konwencje linii poleceń Linux
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