Środowisko nie jest tak magiczne, jak mogłoby się wydawać. Powłoka przechowuje ją w pamięci i przechodzi do execve()
wywołania systemowego. Proces potomny dziedziczy go jako wskaźnik tablicy o nazwie environ
. Z strony execve
podręcznika:
STRESZCZENIE
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
argv
to tablica ciągów argumentów przekazanych do nowego programu.
Zgodnie z konwencją pierwszy z tych ciągów powinien zawierać nazwę pliku powiązaną z wykonywanym plikiem. envp
jest tablicą ciągów, zwykle o postaci klucz = wartość, które są przekazywane jako środowisko do nowego programu.
Strona environ(7)
oferuje również wgląd:
STRESZCZENIE
extern char **environ;
OPIS
Zmienna environ
wskazuje na tablicę wskaźników na ciągi zwane „środowiskiem”. Ostatni wskaźnik w tej tablicy ma wartość NULL
. (Ta zmienna musi zostać zadeklarowana w programie użytkownika, ale jest zadeklarowana w pliku nagłówkowym, <unistd.h>
jeśli pliki nagłówkowe pochodzą z libc4 lub libc5, a jeśli pochodzą z glibc i zdefiniowano _GNU_SOURCE.) Ta tablica ciągów jest dostępna dla proces wywołany przez exec (3), który rozpoczął proces.
Obie strony GNU są zgodne ze specyfikacją POSIX
exec(3)
rodziny (tj. Ci, którzy nie pasują do exec * v) przechodzą ** environment pod przykryciem.exec*e
warianty, które jawnie przekazują env, zamiast domyślnie używaćenviron
zmiennej globalnej.v
„Wektor” oznacza i odnosi się do argumentów polecenia przekazywane jako matrycy (raczej niż „liście” (funkcja zmiennej długości))execve
jest połączeniem systemu i wszystkie inneexec*
funkcje libc opakowania na nim.Po prostu źle to zrobisz:
SOME_NAME=value
tworzy zmienną powłoki (w większości powłok).export SOME_NAME=value
tworzy zmienną środowiskową. Na lepsze na gorsze, większość powłok Unix / Linux / * BSD używa identycznej składni w dostępie do zmiennych środowiskowych i zmiennych powłoki.W pewnym szerszym znaczeniu „środowisko” to tylko informacja, która towarzyszy wykonywaniu programu. W programach C, można znaleźć identyfikator procesu z
getpid()
połączenia w programie Shell należałoby użyć zmiennej dostępu:$$
. Identyfikator procesu jest tylko częścią środowiska programu. Uważam, że termin „środowisko” pochodzi z niektórych bardziej teoretycznych zagadnień informatycznych, takich jak modelowanie wykonania programu. Modele wykonania programu mają środowisko „, które zawiera powiązania między zmiennymi a ich wartościami”.I ta ostatnia, silniejsza definicja jest tym, czym jest „środowisko” dla powłok Unix / Linux / * BSD: związek między nazwami („zmiennymi”) i ich wartościami. W przypadku większości powłok w stylu uniksowym wszystkie wartości są ciągami znaków, chociaż nie jest to tak ściśle prawdziwe, jak kiedyś. Ksh, Zsh i Bash mają teraz zmienne maszynowe. Nawet definicje funkcji powłoki mogą być eksportowane.
Użycie środowiska odrębnego od zmiennych zwykłej powłoki obejmuje
fork/exec
metodę uruchomienia nowego procesu używanego przez wszystkie Uniksy. Kiedy jesteśexport
parą nazwa / wartość, ta para nazwa / wartość będzie obecna w środowisku nowych plików wykonywalnych, uruchamianych przez powłokę za pomocąexecve(2)
wywołania systemowego (zwykle po znakufork(2)
, z wyjątkiem sytuacji, gdyexec
użyto polecenia powłoki).Po an
execve()
,main()
funkcja nowego pliku binarnego ma swoje argumenty wiersza poleceń, środowisko (przechowywane jako tablica wskaźników zakończonych znakiem NULL dovar=value
łańcuchów, patrzenviron(7)
strona man). Inny odziedziczony stan obejmujeulimit
ustawienia, bieżący katalog roboczy i wszelkie otwarte deskryptory plików, dla których programexecve()
wywołujący nie miał ustawionego FD_CLOEXEC. Bieżący stan tty (włączony echo, tryb raw itp.) Można również uznać za część stanu wykonania odziedziczonego przez nowo opracowanyexec
proces.Zobacz
bash
opis środowiska wykonawczego w podręczniku dla prostych poleceń (innych niż funkcje wbudowane lub powłoki).Środowisko uniksowe różni się od co najmniej niektórych innych systemów operacyjnych: „leksyki” VMS można zmienić w procesie potomnym, a zmiana ta była widoczna w obiekcie nadrzędnym. VMS
cd
w procesie potomnym wpłynie na katalog roboczy rodzica. Przynajmniej w niektórych okolicznościach, a moja pamięć może mnie zawodzić.Niektóre zmienne środowiskowe są dobrze znane
$HOME
,$PATH
,$LD_LIBRARY_PATH
i innych. Niektóre są konwencjonalne dla danego systemu programowania, dzięki czemu powłoka nadrzędna może przekazywać do programu wiele informacji specjalnych, takich jak określony katalog tymczasowy lub identyfikator użytkownika i hasło, które się nie wyświetlająps -ef
. Proste programy CGI dziedziczą wiele informacji z serwera WWW na przykład poprzez zmienne środowiskowe.źródło
SOME_NAME=value command
ustawi zmienną środowiskową SOME_NAME dla tego wywołania polecenia. Mylące wydaje się, że nie ustawia zmiennej powłoki o tej samej nazwie.SOME_NAME=value command
zachowujesz się wbrew oczekiwaniom, jest to, że jest to specjalna składnia oznaczająca „dodaj SOME_NAME do środowiska przekazanego do komendy, ale w żaden inny sposób nie zmieniaj zmiennych tej powłoki”.fork()
ed, ale do otrzymania (kopie) zmiennych powłoki.Zmienne środowiskowe w swojej najbardziej surowej formie to tylko zestaw par nazwa / wartość. Jak opisano w bash man page (
man 1 bash
) w sekcji ENVIRONMENT:W praktyce pozwala zdefiniować zachowanie wspólne lub unikalne dla programów wywoływanych z obecnej powłoki. Na przykład podczas używania
crontab
lubvisudo
można zdefiniowaćEDITOR
zmienną środowiskową, aby zdefiniować inny edytor inny niż domyślnie używany przez system. To samo można powiedzieć oman
poleceniu, które patrzy na twojePAGER
środowisko, aby dowiedzieć się, z jakiego programu stronicującego należy korzystać do wyświetlania wyników strony podręcznika.Sporo poleceń unixowych odczytuje środowisko i zależnie od tego, co jest tam ustawione, zmienia ich wyjście / przetwarzanie / działanie w zależności od nich. Niektóre są udostępniane, niektóre są unikalne dla programu. Większość stron podręcznika zawiera informacje o tym, jak zmienna środowiskowa wpływa na opisywany program.
Inne praktyczne ilustracje dotyczą np. Systemów z kilkoma instalacjami Oracle na tej samej platformie. Przez ustawienie
ORACLE_HOME
cały zestaw poleceń Oracle (wczytanych zePATH
zmiennej środowiskowej) następnie pobiera ustawienia, definicje, mapowania i biblioteki z tego katalogu najwyższego poziomu. To samo dotyczy innych programów, takich jak Java z jegoJAVA_HOME
zmienną środowiskową.bash sam ma wiele zmiennych środowiskowych, które mogą zmienić zachowanie różnych rzeczy z historii (
HISTSIZE
,HISTFILE
itp), wielkość ekranu (COLUMNS
), zakończenie zakładki (FIGNORE
,GLOBIGNORE
) Ustawienia regionalne i kodowania znaków / dekodowania (LANG
,LC_*
), szybka (PS1
..PS4
), oraz itd. (ponownie szukaj wiedzy na stronie podręcznika użytkownika bash).Możesz także pisać skrypty / programy korzystające z własnych niestandardowych zmiennych środowiskowych (do przekazywania ustawień lub zmiany funkcjonalności).
źródło
„Zmienne środowiskowe” to zestaw dynamicznych nazwanych wartości, które mogą wpływać na zachowanie zachodzących procesów na komputerze.
Są częścią środowiska operacyjnego, w którym działa proces. Na przykład działający proces może zapytać o wartość zmiennej środowiskowej TEMP, aby znaleźć odpowiednią lokalizację do przechowywania plików tymczasowych, lub zmienną HOME lub USERPROFILE, aby znaleźć strukturę katalogów należącą do użytkownika uruchamiającego proces.
Więcej informacji tutaj → http://en.wikipedia.org/wiki/Environment_variable .
Wszystko, co chcesz wiedzieć o zmiennych środowiskowych ... ↑
źródło
Ta odpowiedź wymaga nieco doświadczenia w skryptowaniu powłoki i znajomości terminów zmienna, wartość, podstawianie zmiennych, monit, echo, jądro, powłoka, narzędzie, sesja i proces.
Zmienna (envar) to zestaw globalnych zdefiniowanych zmiennych, które może mieć wpływ na sposób, w jaki dana procesy będą zachowywać się w systemie operacyjnym komputera.
1. Przykładowe wprowadzenie:
Zastępujemy envary literami
$
ai wielkimi literami . Na przykład:$PS1
.Możemy wydrukować envar w ten sposób:
$PS1
przechowuje wartość monitu Unix. Powiedz, że jego natywnymi wartościami są\u
\w
$
.\u
oznacza (obecnego) użytkownika,\w
oznacza katalog roboczy,$
jest obramowanie monitu.Tak więc, jeśli robimy:
echo $PS1
widzimy wartości\u
,\w
plus znak dolara w końcu.Moglibyśmy zmienić zachowanie Unixa w tym kontekście, jeśli zmienimy wartości tej envory. Na przykład:
Teraz monit wygląda następująco (zakładając, że katalog roboczy nosi nazwę „John”):
W ten sam sposób, w jaki moglibyśmy to zrobić
PS1="Hello, I'm your prompt >"
,echo $PS1
przyniosą:W Bash 4.xx możemy wydrukować WSZYSTKIE envary w systemie za pomocą
env
polecenia. Sugeruję wykonanieenv
w terminalu i przyjrzenie się wynikowi.2. W jaki sposób te dane są pokazywane i przetwarzane:
Terminal sesji pozwala nam dostosować envary, które nadchodzą z Bash.
Powyższe zmiany są zwykle tymczasowe i oto dlaczego:
Każda sesja (która nie jest podsesją) jest unikalna, a kilka procesów może być uruchomionych jednoznacznie w tym samym czasie (każda z własnym zestawem envarów), ale zwykle istnieje dziedziczenie od sesji 0 do sesji 1 i wyższych.
Zmiany, które wprowadzamy w jednym procesie, są dla niego unikalne i przestaną obowiązywać, jeśli zamkniemy go bez zapisania go w jakiś sposób.
Jak więc zapisać te zmiany:
Istnieje kilka rodzajów sposobów przechowywania zmian envar, w zależności od wybranego zakresu. Oto różne zakresy (poziomy) takich zmian:
Gdzie są przechowywane dane envar:
Unix składa się z 3 głównych warstw: jądra, powłoki i narzędzi. AFAIK każda powłoka ma własne envary, które są zbudowane głównie lub wyłącznie w powłoce.
Specyficzna lokalizacja, w której się globalnie zmienić te zazwyczaj
/etc/profile
choć możemy również zrobić w.bashrc
oczywiście.3. Tworzenie nowych envars:
Możemy tworzyć nowe envary i oto jest sposób; od wersji Bash 4.xx nie ma natywnej enavar o nazwie
MESSAGE
(jak powiedziano, envary są zwykle pisane wielkimi literami).stworzy go dla nas, a teraz, jeśli napiszemy echo
$MESSAGE
, otrzymamyhello world!
.Jeśli wykonamy
bash
w bieżącej sesji roboczej (okno), zaczniemy nową podsekcję bash i nie będziemy już działać w pierwotnym procesie, chyba że wykonamyexit
.Uwaga: W systemach operacyjnych z emulatorem terminali (takich jak Ubuntu Desktop) podsekcja zwykle działa w tym samym oknie, ale nowa sesja w innym oknie nie jest podsesją istniejącej (jest to proces sąsiedni ) .
Uwaga: Nie używaj specjalnych znaków w wartościach envar, takich jak! albo nie zostaną uratowani.
Eksportowanie envara z oryginalnej sesji do wszystkich podsesji:
Nadal możemy używać envara utworzonego w pierwszej sesji, również w drugiej, bez rejestrowania go w plikach conf na poziomie użytkownika lub globalnym (patrz następujące dane). Oto jak to zrobić:
Przejdź do oryginalnej sesji (w bieżącym oknie lub w innym) i wykonaj:
podczas eksportowania nie używaj
$
znaku.Jest teraz eksportowany do wszystkich podsesji. Jeśli wykonasz
echo $MESSAGE
sesję podrzędną, niezależnie od tego, czy pochodzi ona od użytkownika, czy inna, zostanie ona wydrukowana.Zauważ, że wewnętrzne zmienne Shell, takie jak
PS1
nie powinny być eksportowane, ale jeśli chcesz je wyeksportować z dowolnego powodu i nie pojawiają się, nie wykonujbash
późniejexport
, ale raczejbash –norc
.4. Envar $ PATH:
$PATH
to środowisko, które użytkownicy najczęściej zmieniają najbardziej.Jeśli my
echo $PATH
, zobaczymy ten strumień:Wydrukowane wartości tego envaru są oddzielone dwukropkami (:) tam, ale oto potencjalnie wygodniejszy sposób (są to te same wartości):
Są to katalogi, których należy szukać, gdy uruchamiamy narzędzie.
Wykonując
which echo
, uzyskamy lokalizację jego pliku - na przykład możemy zobaczyć, że istnieje/bin/echo
.Na tej podstawie nie musimy wpisywać echa envar, aby wyświetlić wartości evnar. Możemy również wykonać:
Envar będzie nadal wykonywany, na przykład:
Daje nam
Tak jak:
Daje nam
Uwaga: w
$HOME
skrócie~
.Relacje system-$ PATH i możliwa interakcja użytkownika:
W Bash 4.xx, kiedy używamy narzędzia bez pełnej ścieżki, system użyje wszystkich 6 wartości wymienionych powyżej
$PATH
envar. Tak więc zacznie się/user/local/bin
i będzie śledził całą zawartość w poszukiwaniuecho
pliku wykonywalnego.W takim przypadku zatrzyma się na
/bin/echo
, w którym w tym przypadku znajduje się plik wykonywalny.Dlatego głównym powodem, dla którego możemy dostosować
$PATH
envar, jest instalowanie plików wykonywalnych, które nie mieszczą się w żadnej z jego wartości natywnych.Po zainstalowaniu takich plików wykonywalnych powinniśmy odpowiednio ustawić ich
$PATH
wartość, a następnie moglibyśmy z nimi pracować.5. Dodatek - rozszerzenie
$PATH
:Możemy
export $PATH
rozbić pod sesje (w tym rozszerzenia bash, takie jak WP-CLI dla WordPress lub Drush dla Drupal) w ten sposób:Spowoduje to dodanie nowej wartości
/home/John
do$PATH
, a następnie w prawo potem, to załącza żadnych wartości rodzimych do niego (z prawej po dwukropku), które są przechowywane zgodnie ze składnią$PATH
.Taką stałą zmianę można wykonać w odpowiednim skrypcie, zwykle pod
/etc/profile
i pod nazwą.bashrc
.źródło
!
niedziałającej wartości zmiennej środowiskowej, która znajduje się tuż pod przykładem pokazującym, że działa, fałszywe pojęcie podsesji, dość dziwna rada co robić po wyeksportowaniu zmiennej powłoki i fałszywym pojęciu globalnych zmiennych środowiskowych.warning about ! in an environment variable value not working that is right below an example showing it working
? Proszę przykład.quite bizarre advice about what to do after exporting a shell variable
, co dokładnie masz na myśli?false notion of global environment variables
, co dokładnie masz na myśli?