System operacyjny : Ubuntu 16.04.3
Powłoka : Bash 4.3.48
Wiem, że można tymczasowo zmienić zawartość zmiennej jak w var=value command
, prawdopodobnie jest IFS= read -r var
to najbardziej znaczący przypadek.
I dzięki wiki Grega , rozumiem też:
# Why this
foo() { echo "$var"; }
var=value foo
# And this does work
var=value; echo "$var"
# But this doesn't
var=value echo "$var"
To, co wymyka się mojemu zrozumieniu, to:
$ foo() { echo "${var[0]}"; }
$ var=(bar baz) foo
(bar baz)
O ile mi wiadomo (i zgodnie z logiką poprzednich przykładów), powinien drukować bar
, a nie (bar baz)
.
Czy to mi się tylko zdarza? Czy to jest zamierzone zachowanie i czegoś mi brakuje? Czy to błąd?
export var=(foo bar); echo "${var[0]}"
drukujefoo
, nie(foo bar)
.export
go pokazuje:declare -ax var=([0]="foo" [1]="bar")
export i_am_array=(foo bar); /usr/bin/env | grep i_am_array
daje tutaj żadnego wyniku.foo() { declare -p var; } ; var=(bar baz) foo
dajedeclare -x var="(bar baz)"
potwierdzenie, że jest traktowany jako ciąg, a nie tablicaOdpowiedzi:
Ogólnie dzwoniąc:
gdzie
cmd
funkcja nie jest przenośna.Z
bash
, to działa tylko dla zmiennych skalarnych (ix=(...)
parsowanych jako tablica, ale przypisanych jako skalar) i istnieje szereg problemów z zasięgiem, jeśli to zrobisz, zksh93
iyash
, to działa, ale definicja zmiennej pozostaje później. Za pomocąmksh
pojawia się błąd składniowy. W powłoce Bourne'a w ogóle nie działało, nawet w przypadku zmiennych skalarnych.Zauważ również, że nawet w przypadku zmiennych skalarnych, to, czy zmienna zostanie ostatecznie wyeksportowana w ramach funkcji (to znaczy przekazana do wykonywanych poleceń) różni się w zależności od powłoki (w bash, yash, mksh, zsh, ale nie w ksh, popiół).
Działa tylko tak, jak można się spodziewać
zsh
. Zauważ, żezsh
indeksy tablic zaczynają się od 1.źródło
To nie tylko błąd, ale wydaje się, że jest to niezaimplementowana funkcja bez żadnych planów. Ten post z listy mailingowej z 2014 roku ma od twórcy:
Korzystając z najnowszego repozytorium git dla Bash, można to zrobić w
variables.c
:Sugerowanie, że cokolwiek tam jest, nie jest kompletne.
źródło
execve()
jest zaangażowane wywołanie systemowe. Poszukajzsh
powłoki obsługującej funkcje wywołujące tymczasowo ustawioną tablicę.my_var=one func_bar
:). Czy możemy powiedzieć, żeexport
jest to korzystne dla środowiska, a zatem eksport jest wykorzystywany tutaj, pod maską? Spójrz na moją odpowiedź, dodałem kod demonstracyjny.Z
man bash
sekcji BŁĘDY (wersjabash
4.3):Następny kod pokazuje, że zmienna tymczasowa istnieje w środowisku, tylko gdy funkcja jest uruchomiona. Po zakończeniu funkcji zmienna tymczasowa znika.
Powiązana informacja:
VAR=VALUE some-command
budowy.źródło