Czy jest jakaś zaleta / wada inicjowania wartości zmiennej bash w skrypcie przed kodem głównym lub zmiennymi lokalnymi w funkcji przed przypisaniem jej wartości rzeczywistej?
Czy muszę zrobić coś takiego:
init()
{
name=""
name=$1
}
init "Mark"
Czy istnieje ryzyko, że zmienne zostaną zainicjowane wartościami śmieci (jeśli nie zostaną zainicjowane) i że będzie to miało negatywny wpływ na wartości zmiennych?
name = ""; name = argv[1];
? Czy to nie jest tak samo bezcelowe?Odpowiedzi:
Przypisanie pustego łańcucha do zmiennej nie przynosi korzyści, a następnie natychmiastowe przypisanie do niego innego łańcucha zmiennej. Przypisanie wartości do zmiennej powłoki całkowicie zastąpi poprzednią wartość.
Według mojej wiedzy nie ma żadnego zalecenia, które mówi, że powinieneś jawnie inicjować zmienne do pustych łańcuchów. W rzeczywistości może to w niektórych okolicznościach maskować błędy (błędy, które w innym przypadku byłyby widoczne, gdyby działały pod
set -u
, patrz poniżej).Nieuzbrojona zmienna, nieużywana od początku skryptu lub jawnie rozbrojona przez uruchomienie na niej
unset
polecenia, nie będzie miała wartości. Wartość takiej zmiennej będzie niczym. Jeśli"$myvariable"
użyjesz jako , otrzymasz ekwiwalent""
i nigdy nie dostaniesz „śmieciowych danych”.Jeśli opcja powłoki
nounset
jest ustawiona za pomocą albo,set -o nounset
alboset -u
odwołanie się do zmiennej nieustawionej spowoduje, że powłoka wygeneruje błąd (i powłoka nieinteraktywna zakończy działanie):lub w
bash
:Zmienne powłoki zostaną zainicjowane przez środowisko, jeśli nazwa zmiennej odpowiada istniejącej zmiennej środowiskowej.
Jeśli spodziewasz się, że używasz zmiennej, która może być zainicjowana przez środowisko w ten sposób (i jeśli jest niepożądana), możesz jawnie ją rozbroić przed główną częścią skryptu:
który również usunąłby ją jako zmienną środowiskową, lub możesz po prostu zignorować jej wartość początkową i po prostu nadpisać ją przypisaniem (co spowodowałoby również zmianę wartości zmiennej środowiskowej).
Nigdy nie natrafisz na niezainicjowane śmieci w zmiennej powłoki (chyba że, jak wspomniano, śmieci już istniały w zmiennej środowiskowej o tej samej nazwie).
źródło
unset
ting) przed uruchomieniem jakiegoś rodzajufor
lubwhile
pętli, aby ustawić ją na obliczoną wartość, jeśli istnieje jakakolwiek szansa, że pętla faktycznie nie uruchomi się z powodu niespełnienia warunków; a zmienna mogła zostać ustawiona na inną wartość w środowisku odziedziczonym przez skrypt. Ale prawdopodobnie lepiej jest umieścić wszystko w amain()
i zdefiniować zmienne jakolocal
.:
${myvariable-defaultvalue}
Edycja : Ups, najwyraźniej deklaracja różni się od inicjalizacji. W każdym razie zostawię to tutaj, aby nowicjusze, tacy jak ja, mogli wyciągnąć wnioski z mojego błędu.
Zaletą deklarowania zmiennych lokalnych w funkcji jest to, że można łatwo skopiować kod.
Powiedzmy na przykład, że mam funkcję:
Jeśli chcę przekształcić go w skrypt, po prostu ignoruję
local
instrukcję i kopiuję wszystko inne:Gdyby deklaracja i przypisanie znajdowały się w tym samym wierszu, musiałbym ręcznie edytować
local
część przed przekształceniem jej w skrypt:W tym przykładzie nie jest to wielka sprawa, ale jeśli masz do czynienia z większymi, bardziej złożonymi funkcjami, może to być bardziej bolesne.
źródło