Dlaczego nie eksportować zmiennych w tym samym wierszu, który je przypisujesz?


44

Od Jaki jest ostatni argument poprzedniego polecenia?

shellcheck mówi ci, żebyś nie eksportował zmiennych w tym samym wierszu, który je przypisałeś.

Zastanawiałem się dlaczego?

Czy ta sama rada dotyczy alias, declare, export, local, readonly, i typeset?




9
Omawiana reguła shellcheck to SC2155. Całkiem dobra dokumentacja znajduje się na wiki shellcheck .
phunehehe

3
Również niektóre starsze powłoki nie zaakceptowałyby exporti nie przydzieliłyby razem. Na przykład Heirloom Bourne Shell wyświetla błąd „foo = 2 nie jest identyfikatorem”.
Dennis Williamson,

Odpowiedzi:


54

Problemem jest to, że w Bash każde polecenie ma tylko jeden kod wyjścia. Po export foo="$(false)"wyjściu kod wyjścia falsejest po prostu odrzucany. Jeśli zamiast tego zrobisz

foo="$(false)"
export foo

pierwsze nieudane polecenie może zostać wykonane, na przykład przez errexitustawienie.

Zadeklarowanie i przypisanie literału łańcuchowego, takie jak export foo='bar', oczywiście, nie powoduje tego problemu. Ale zmiana jest jedyną stałą w rozwoju oprogramowania i po prostu dobrym sposobem na utrzymanie takich oświadczeń w przyszłości poprzez ich podzielenie.

Oprócz wspomnianych poleceń specyficznych dla zadania, w jednym zadaniu jest także wiele poleceń, takich jak foo="$(false)$(true)". Zobacz pipefailw man bashna kolejną taką pułapkę.

Kolejną rzeczą do zapamiętania jest to, że sekwencja deklaracji i przydziału jest czasami istotna. Na przykład będziesz chciał zadeklarować zmienne przed przypisaniem ich. (Niestety nie można zadeklarować zmiennych przed przypisaniem ich po raz pierwszy).local readonly


Więc jeśli ustawiasz zmienną z literału i nie ma kodu wyjścia do odrzucenia, nie ma nic złego w robieniu tego wszystkiego w jednym wierszu.
Monty Harder

1
Jeśli chodzi o ten błąd kontroli stanu, nie. Ponieważ skreślone teraz odpowiedzi znalazły się w połowie między nimi, powłoka Bourne'a nie obsługiwała składni przypisania export, więc przez kilka lat otrzymywano mądrość na temat robienia tego, jeśli czyimś tłumaczem prawdopodobnie była powłoka Bourne'a.
JdeBP

@JdeBP, zwróć uwagę, że powłoka Bourne'a obsługuje foo=$(cmd) export foo, ale z tym samym zastrzeżeniem, że cmdstatus wyjścia został utracony (ale spowodował zamknięcie powłoki, jeśli się nie powiedzie set -e).
Stéphane Chazelas

To było objęte moim pierwszym zdaniem.
JdeBP
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.