W rzeczywistości nie wiedziałem, że istnieją dwa różne typy zmiennych, do których mogę uzyskać dostęp z wiersza poleceń. Wiedziałem tylko, że mogę zadeklarować zmienne takie jak:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
lub dostęp do nich ze znakiem $, np .:
echo $foo
echo ${bar[1]}
lub używając wbudowanych zmiennych, takich jak:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Teraz słyszę, że istnieją dwa (przynajmniej?) Typy zmiennych: zmienne powłoki i zmienne środowiskowe.
- Jaki jest cel posiadania dwóch różnych typów?
- Skąd mam wiedzieć, jaki typ jest zmienna?
- Jakie są typowe zastosowania dla każdego z nich?
Odpowiedzi:
Zmienne środowiskowe to lista
name=value
par istniejących niezależnie od programu (powłoka, aplikacja, demon…). Zazwyczaj są dziedziczone przez procesy potomne (tworzone przez sekwencjęfork
/exec
): procesy potomne otrzymują własną kopię zmiennych rodzicielskich.Zmienne powłoki istnieją tylko w kontekście powłoki. Są one dziedziczone tylko w podpowłokach (tzn. Gdy skorupa jest rozwidlona bez
exec
operacji). W zależności od funkcji powłoki zmienne mogą być nie tylko prostymi ciągami, takimi jak środowiskowe, ale także tablicami, zmiennymi złożonymi, zmiennymi typowymi, takimi jak liczba całkowita lub zmiennoprzecinkowa itp.Kiedy powłoka się uruchamia, wszystkie zmienne środowiskowe, które dziedziczy od swojego rodzica, stają się również zmiennymi powłoki (chyba że są one niepoprawne jako zmienne powłoki i inne przypadki narożne, takie jak
IFS
resetowane przez niektóre powłoki), ale te odziedziczone zmienne są oznaczane jako eksportowane 1 . Oznacza to, że pozostaną one dostępne dla procesów potomnych z potencjalnie zaktualizowaną wartością ustawioną przez powłokę. Dotyczy to również zmiennych utworzonych pod powłoką i oznaczonych jako wyeksportowaneexport
słowem kluczowym.Nie można wyeksportować tablicy i innych zmiennych typu złożonego, chyba że ich nazwa i wartość mogą zostać przekonwertowane na
name=value
wzorzec lub gdy istnieje mechanizm specyficzny dla powłoki (np .:bash
funkcje eksportu w środowisku i niektóre egzotyczne powłoki inne niż POSIX, takie jakrc
ies
mogą eksportować tablice ).Główną różnicą między zmiennymi środowiskowymi a zmiennymi powłoki jest ich zakres: zmienne środowiskowe są globalne, podczas gdy niewyeksportowane zmienne powłoki są lokalne dla skryptu.
Zauważ też, że nowoczesne powłoki (przynajmniej
ksh
ibash
) obsługują trzeci zakres zmiennych powłoki. Zmienne utworzone w funkcjach zetypeset
słowem kluczowym są lokalne dla tej funkcji (sposób, w jaki funkcja jest deklarowana, włącza / wyłącza tę funkcjęksh
, a zachowanie trwałości jest różne pomiędzybash
iksh
). Zobacz /unix//a/28349/25941 Dotyczy to nowoczesne pociski podoba
ksh
,dash
,bash
i podobne. Starsze powłoki Bourne'a i powłoki inne niż Bournecsh
mają różne zachowania.źródło
execve()
wywołania systemowego, więc (zwykle) są używane do utrwalania danych w trakcie wykonywania innych poleceń (w tym samym procesie).IFS
w niektórych powłokach).rc
,es
może eksportować tablic używając kodowania adhoc.bash
irc
może również eksportować funkcje przy użyciu zmiennych środowiskowych (ponownie, używając specjalnego kodowania).ksh93
,typeset
ogranicza zakres jedynie funkcje zadeklarowane zefunction foo { ...; }
składni, a nie z Bourne (foo() cmd
składni) (i to statyczne scoping nie dynamiczny jak w innych powłok).Zmienne powłoki
Zmienne powłoki to zmienne, których zakres znajduje się w bieżącej sesji powłoki, na przykład w interaktywnej sesji powłoki lub skrypcie.
Możesz utworzyć zmienną powłoki, przypisując wartość do nieużywanej nazwy:
Zastosowanie zmiennych powłoki służy do śledzenia danych w bieżącej sesji. Zmienne powłoki zwykle mają nazwy z małymi literami.
Zmienne środowiska
Zmienna środowiskowa to zmienna powłoki, która została wyeksportowana. Oznacza to, że będzie ona widoczna jako zmienna, nie tylko w sesji powłoki, która ją utworzyła, ale także dla każdego procesu (nie tylko powłoki), który jest uruchamiany z tej sesji.
lub
Po wyeksportowaniu zmiennej powłoki, pozostaje ona wyeksportowana, dopóki nie zostanie rozbrojona lub dopóki jej „właściwość eksportu” nie zostanie usunięta („
export -n
in”bash
), więc zazwyczaj nie trzeba jej ponownie eksportować. Wyłączenie zmiennejunset
powoduje jej usunięcie (bez względu na to, czy jest to zmienna środowiskowa, czy nie).Tablice i asocjacyjne skróty w
bash
oraz inne powłoki nie mogą być eksportowane jako zmienne środowiskowe. Zmienne środowiskowe muszą być prostymi zmiennymi, których wartości są łańcuchami, i często mają nazwy składające się z wielkich liter.Wykorzystanie zmiennych środowiskowych służy do śledzenia danych w bieżącej sesji powłoki, ale także do umożliwienia każdemu rozpoczętemu procesowi uwzględnienia tych danych. Typowym tego przykładem jest
PATH
zmienna środowiskowa, która może być ustawiona w powłoce, a następnie używana przez dowolny program, który chce uruchomić programy bez podawania pełnej ścieżki do nich.Zbiór zmiennych środowiskowych w procesie jest często określany jako „środowisko procesu”. Każdy proces ma swoje własne środowisko.
Zmienne środowiskowe można tylko „przekazywać”, tj. Proces potomny nigdy nie może zmienić zmiennych środowiskowych w procesie macierzystym, a oprócz skonfigurowania środowiska dla procesu potomnego po uruchomieniu, proces macierzysty nie może zmienić istniejącego środowiska proces potomny.
Zmienne środowiskowe mogą być wyświetlane z
env
(bez żadnych argumentów). Poza tym wyglądają tak samo jak nieeksportowane zmienne powłoki w sesji powłoki. Jest to trochę wyjątkowe dla powłoki, ponieważ większość innych języków programowania zwykle nie miesza „zwykłych” zmiennych ze zmiennymi środowiskowymi (patrz poniżej).env
może być również użyty do ustawienia wartości jednej lub kilku zmiennych środowiskowych w środowisku procesu bez ustawiania ich w bieżącej sesji:Zaczyna
make
się to od zmiennej środowiskowejCC
ustawionej na wartośćclang
iCXX
ustawioną naclang++
.Może być również użyty do oczyszczenia środowiska dla procesu:
To się uruchamia,
bash
ale nie przenosi bieżącego środowiska do nowegobash
procesu (nadal będzie mieć zmienne środowiskowe, ponieważ tworzy nowe ze swoich skryptów inicjujących powłokę).Przykład różnicy
Inne języki
W większości języków programowania dostępne są funkcje biblioteczne, które umożliwiają pobieranie i ustawianie zmiennych środowiskowych. Zauważ, że ponieważ zmienne środowiskowe są przechowywane jako prosta relacja klucz-wartość, zwykle nie są one „zmiennymi” języka. Program może pobrać wartość (która jest zawsze ciągiem znaków) odpowiadającą kluczowi (nazwie zmiennej środowiskowej), ale będzie musiał następnie przekonwertować ją na liczbę całkowitą lub inny typ danych, jakiego oczekuje język.
W C, zmienne środowiska można uzyskać za pomocą
getenv()
,setenv()
,putenv()
iunsetenv()
. Zmienne utworzone za pomocą tych procedur są dziedziczone w ten sam sposób przez dowolny proces uruchamiany przez program C.Inne języki mogą mieć specjalne struktury danych do osiągnięcia tego samego, jak
%ENV
skrót w Perlu lubENVIRON
tablica asocjacyjna w większości implementacjiawk
.źródło
getenv()
,setenv()
,putenv()
iunsetenv()
. Zmienne utworzone za pomocą tych procedur są dziedziczone w ten sam sposób przez dowolny proces uruchamiany przez program C. Inne języki mogą mieć specjalne struktury danych dla tego samego, jak%ENV
w Perlu.exec*()
rodzina funkcji może również ustawić środowisko dla wykonywanego procesu.Zmienne powłoki są trudne do powielenia.
Zmienne środowiskowe można jednak powielać; są tylko listą, a lista może zawierać zduplikowane wpisy. Oto,
envdup.c
co możesz zrobić.Które możemy skompilować i uruchomić,
envdup
a następnie uruchomić,env
aby pokazać nam, jakie zmienne środowiskowe są ustawione ...Może to być przydatne tylko do znajdowania błędów lub innych dziwności w tym, jak dobrze radzą sobie programy
**environ
.Wygląda na to, że Python 3.6 ślepo przekazuje duplikaty (nieszczelna abstrakcja), podczas gdy Perl 5.24 nie. Co powiesz na muszle?
Boże, co się stanie, jeśli
sudo
tylko zdezynfekuje pierwszy wpis środowiska, a następniebash
uruchomi się z drugim? WitajPATH
lubLD_RUN_PATH
wykorzystaj. Czy twojasudo
(i wszystko inne ?) Załatała tę dziurę ? Exploity bezpieczeństwa nie są ani „anegdotyczną różnicą”, ani „błędem” w programie wywołującym.źródło
Zmienna jest jak zmiennej powłoki , ale to nie jest właściwy do muszli . Wszystkie procesy w systemach Unix mają pamięć zmienną środowiskową . Główna różnica między zmiennymi środowiskowymi a powłokowymi polega na tym, że system operacyjny przekazuje wszystkie zmienne środowiskowe powłoki do programów uruchamianych przez powłokę, podczas gdy do zmiennych powłoki nie można uzyskać dostępu za pomocą uruchamianych poleceń.
env –
Polecenie pozwala na uruchomienie innego programu w środowisku niestandardowym bez modyfikowania bieżącego. Jeśli zostanie użyte bez argumentu, wydrukuje listę bieżących zmiennych środowiskowych.printenv –
Polecenie drukuje wszystkie lub określone zmienne środowiskowe.set –
Polecenie ustawia lub usuwa zmienne powłoki. Jeśli zostanie użyta bez argumentu, wydrukuje listę wszystkich zmiennych, w tym zmiennych środowiskowych i zmiennych powłoki oraz funkcji powłoki.unset –
Polecenie usuwa powłoki i zmienne środowiskowe.export –
Polecenie ustawia zmienne środowiskoweźródło