Podstawową ideą jest to, że VAR=VALUE some-commandustawia VARsię VALUEna wykonanie some-commandkiedy some-commandjest zewnętrznym poleceniem i nie robi się to bardziej wymyślne. Jeśli połączysz tę intuicję z pewną wiedzą na temat działania powłoki, w większości przypadków powinieneś znaleźć właściwą odpowiedź. Odniesieniem do POSIX są „Proste polecenia” w rozdziale „Język poleceń powłoki” .
Jeśli some-commandjest poleceniem zewnętrznym , VAR=VALUE some-commandjest równoważne z env VAR=VALUE some-command. VARjest eksportowany w środowisku some-command, a jego wartość (lub brak wartości) w powłoce się nie zmienia.
Jeśli some-commandjest funkcją , to VAR=VALUE some-commandjest równoważne VAR=VALUE; some-command, tj . Przypisanie pozostaje na miejscu po powrocie funkcji, a zmienna nie jest eksportowana do środowiska. Powodem tego jest konstrukcja powłoki Bourne'a (a następnie zgodność wsteczna): nie miała możliwości zapisywania i przywracania wartości zmiennych wokół wykonywania funkcji. Brak eksportowania zmiennej ma sens, ponieważ funkcja jest wykonywana w samej powłoce. Jednak ksh (w tym zarówno ATT ksh93, jak i pdksh / mksh), bash i zsh implementują bardziej użyteczne zachowanie, które VARjest ustawiane tylko podczas wykonywania funkcji (jest również eksportowane). W ksh odbywa się to, jeśli funkcja jest zdefiniowana za pomocą składni kshfunction NAME …, nie jeśli jest zdefiniowany ze standardową składnią NAME (). W bash odbywa się to tylko w trybie bash, a nie w trybie POSIX (po uruchomieniu z POSIXLY_CORRECT=1). W zsh odbywa się to, jeśli posix_builtinsopcja nie jest ustawiona; ta opcja nie jest ustawiona domyślnie, ale jest włączona przez emulate shlub emulate ksh.
Jeśli some-commandjest wbudowane, zachowanie zależy od typu wbudowanego. Specjalne wbudowane zachowują się jak funkcje. Specjalne wbudowane to te, które muszą zostać zaimplementowane w powłoce, ponieważ wpływają na powłokę stanu (np. Wpływają na breakprzepływ sterowania, cdwpływają na bieżący katalog, setwpływają na parametry pozycyjne i opcje…). Inne wbudowane funkcje są wbudowane tylko dla wydajności i wygody (głównie - np. Funkcja bash printf -vmoże być zaimplementowana tylko przez wbudowane) i zachowują się jak polecenie zewnętrzne.
Przypisanie odbywa się po rozwinięciu aliasu, więc jeśli some-commandjest to alias , rozwiń go najpierw, aby znaleźć, co się stanie.
Zauważ, że we wszystkich przypadkach przypisanie jest wykonywane po przeanalizowaniu wiersza poleceń, w tym wszelkich podstawień zmiennych w samym wierszu poleceń. Tak var=a; var=b echo $vardrukuje a, ponieważ $varjest oceniane przed przypisaniem. I w ten sposób IFS=. printf "%s\n" $varużywa starej IFSwartości do podziału $var.
Omówiłem wszystkie typy poleceń, ale jest jeszcze jeden przypadek: gdy nie ma polecenia do wykonania , tj. Jeśli polecenie składa się tylko z przypisań (i ewentualnie przekierowań). W takim przypadku przypisanie pozostaje na miejscu . VAR=VALUE OTHERVAR=OTHERVALUEjest równoważne z VAR=VALUE; OTHERVAR=OTHERVALUE. Więc po IFS=. arr=($var), IFSpozostaje ustawiony na .. Ponieważ można użyć $IFSw przypisaniu arrz oczekiwaniem, że ma już swoją nową wartość, sensowne jest, aby nowa wartość parametru IFSbyła używana do rozszerzenia $var.
Podsumowując, możesz użyć tylko IFSdo tymczasowego podziału pola:
- uruchamiając nową powłokę lub podpowłokę (np.
third=$(IFS=.; set -f; set -- $var; echo "$3")jest to skomplikowany sposób, z third=${var#*.*.}wyjątkiem tego, że zachowują się inaczej, gdy wartość parametru varzawiera mniej niż dwa .znaki);
- w ksh,
IFS=. some-functiongdzie gdzie some-functionjest zdefiniowane za pomocą składni ksh function some-function …;
- w bash i zsh, o
IFS=. some-functionile działają one w trybie macierzystym, a nie w trybie zgodności.
IFSpozostaje ustawiony na.” Eek. Po przeczytaniu pierwszej części ma to sens, ale zanim opublikowałem to pytanie, nie spodziewałbym się tego.