Jak wyświetlić bieżącą wartość zmiennej środowiskowej?

24

Kiedy sprawdzę środowisko mojego systemu, pojawi się wiele zmiennych środowiskowych. Jak mogę po prostu wyszukać konkretną zmienną?

Książka, którą czytam, mówi:

Czasami liczba zmiennych w twoim środowisku staje się dość duża, tak bardzo, że nie chcesz widzieć wszystkich wartości wyświetlanych, gdy jesteś zainteresowany tylko jedną. W takim przypadku możesz użyć echopolecenia, aby wyświetlić bieżącą wartość zmiennej środowiskowej.

Jak to zrobić w terminalu Linux?

iLearnSlow
źródło

Odpowiedzi:

25

Właśnie:

echo "$VARIABLENAME"

Na przykład dla zmiennej środowiskowej $HOMEużyj:

echo "$HOME"

Co następnie drukuje coś podobnego do:

/home/username

Edycja : zgodnie z komentarzem Stéphane Chazelas , może być lepiej, jeśli użyjesz printenvzamiast echo:

printenv HOME
chaos
źródło
4
Zapomniałeś cytatów (chyba że sugerujesz składnię zsh lub rc / es). echojest złym wyborem polecenia, ponieważ mogłoby przekształcić zawartość zmiennej. Wyśle zawartość parametru powłoki o tej samej nazwie. To nie jest taka sama w przypadku korzystania z Bourne shell lub env vars jak 1, *na przykład. I nie można użyć tego podejścia do zmiennych env, których nazwa nie jest poprawna jako nazwa zmiennej powłoki.
Stéphane Chazelas,
5
Zauważ też, że jeśli istnieje kilka pozycji środowiska o tej samej nazwie (OK, przypadek patologiczny), to, który dostaniesz, zależy od powłoki (zwykle albo pierwsza, albo ostatnia). printenv VARwyświetli je wszystkie (przynajmniej dla implementacji GNU).
Stéphane Chazelas,
9

Wykonując:

printenv

Zobaczysz wszystkie zmienne środowiskowe. Aby uzyskać więcej informacji, możesz spojrzeć na:

https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps

Svetlin Tonchev
źródło
2
Aby zbliżyć się do odpowiedzi na pytanie, printenv variablenamewyświetli się tylko zmienna nazwana; np. printenv  HOMEzrobi mniej więcej to samo echo  "$HOME".
G-Man mówi „Przywróć Monikę”
5

Ważne jest, aby zrozumieć, że każdy proces ma swój własny zestaw zmiennych środowiskowych.

Kiedy proces wywołuje fork()wywołanie systemowe, tworzony jest drugi proces ( dziecko ) identyczny z pierwszym ( rodzicem ) (ta kopia obejmuje środowisko, które znajduje się tuż nad stosem (lub tuż poniżej, w zależności od tego, jak myślisz o stosach :-)- ale w UNIX / Linux stos rośnie w dół od wysokich adresów).

Zwykle proces potomny wywołuje wówczas wywołanie execve()systemowe, które wyrzuca wszystko z jego (wirtualnej) pamięci i rekonstruuje go z sekcji kodu i danych w określonym pliku binarnym.

Jednak, gdy rekonstruuje stos, kopiuje execve()najpierw środowisko i ciągi argumentów przekazane na stos (w tej kolejności), przed wywołaniem main()funkcji (duża część pracy jest wykonywana w crt0kodzie bootstrap po execve()powrocie (do wpisu) punkt określony w pliku binarnym)).

W execve()bibliotece C znajdują się opakowania dla wywołania systemowego, które przekażą bieżące środowisko (tj. Kopię środowiska nadrzędnego ), zamiast wywołującego go (tak więc dziecko odziedziczy środowisko nadrzędne) - patrz environ(7).

Spróbuj uruchomić (jako root) polecenie ps axeww | less... pokaże to środowisko dla wszystkich procesów! Interesującym jest proces id 1 (tj. initProces - pierwszy proces utworzony przez jądro w czasie rozruchu).

Jeśli chcesz spojrzeć na środowisko dla określonego procesu (i wiesz, że jest to identyfikator procesu), spróbuj uruchomić komendę cat /proc/<PID>/environ(zastępując <PID>go identyfikatorem procesu).

Zauważ, że jeśli proces ma wystarczającą liczbę uprawnień, może przepisać własny stos, co może utrudnić ustalenie, jakie jest jego środowisko - na wyjściu ps zobaczysz niektóre takie procesy demonów.

Ale w końcu cały ten wafel sprowadza się do tego, co powiedział @chaos powyżej, jeśli chcesz spojrzeć na bieżącą wartość konkretnej zmiennej środowiskowej w procesie powłoki, po prostu użyj polecenia (wbudowanego) echo "$<NAME>"(zastępując <NAME>ją nazwą zmienna środowiskowa, którą jesteś zainteresowany) ... pamiętaj, że ta sama zmienna może mieć inną wartość lub może nie istnieć w innym procesie.

Murray Jensen
źródło
1
(1) Należy pamiętać, że eopcja psi /proc/…/environplik specjalny mogą nie istnieć we wszystkich systemach. (2) AFAIK, każdy proces uniksowy ma uprawnienia do przepisywania stosu i modyfikowania zmiennych środowiskowych. (3) Aby uzyskać więcej dyskusji, zobacz Do kogo należą zmienne środowiskowe? (w przypadku superużytkownika ).
G-Man mówi „Przywróć Monikę”
Miałem w głowie, że niektóre systemy miały sposób, aby zapobiec nieuprzywilejowanemu procesowi „ukrycia” argumentów wiersza poleceń i środowiska, np. Przed uruchomieniem roota ps… ale teraz, kiedy zaznaczyłeś ten punkt, nie pamiętam, dlaczego ja myślałem, że.
Murray Jensen
@MurrayJensen zgodnie z niektórymi dyskusjami na temat wysoko głosowanego pytania, które zadałem na temat „curl” ukrywania swoich argumentów w ps - w POSIX nie jest określone, czy ps zwraca argumenty, jak pierwotnie przekazano do procesu, czy kopię, którą proces mógł zmodyfikować po nim zaczął się. Niektóre systemy (chyba Solaris?) Pokazują oryginalne argumenty bez względu na wszystko. (Oto link.) To mogło być to, o czym myślałeś. :)
Wildcard
Bingo! Tak, oczywiście Solaris robi to „poprawnie” :-) Dzięki za odświeżenie ...
Murray Jensen
1

Możesz uzyskać to, czego szukasz export:

export | grep HOME

Pokaże zawartość $HOMEzmiennej.

Darth Egregious
źródło
1

jeśli musisz ustawić wiele wariacji:

  ( set -o posix ; set ) | sort >~/vars.before

po ich ustawieniu:

  ( set -o posix ; set ) | sort >~/vars.after

niż wyświetlić, co zostało ustawione:

  comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'

W ten sposób wkrótce znajdziesz się w pracy z wieloma zestawami zmiennych powłoki wstępnie zdefiniowanych w plikach cnf, które w połączeniu z tmux uczynią cię mistrzem zarządzania konfiguracją w środowiskach powłoki:

  # ---------------------------------------------------------
  # cat cnf/qto.dev.host-name.cnf
  # [MainSection]
  # postgres_db_name     = dev_qto
  # postgres_db_host     = host-name
  #
  # call by: doParseCnfEnvVars cnf/qto.dev.host-name.cnf
  # ---------------------------------------------------------
  doParseCnfEnvVars(){

     cnf_file=$1;shift 1;
     test -z "$cnf_file" && echo " you should set the cnf_file !!!"

     INI_SECTION=MainSection

     ( set -o posix ; set ) | sort >~/vars.before

     eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
        -e 's/#.*$//' \
        -e 's/[[:space:]]*$//' \
        -e 's/^[[:space:]]*//' \
        -e "s/^\(.*\)=\([^\"']*\)$/export \1=\"\2\"/" \
        < $cnf_file \
        | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`

     # and post-register for nice logging
     ( set -o posix ; set ) | sort >~/vars.after

     echo "INFO added the following vars from section: [$INI_SECTION]"
     comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
  }
Yordan Georgiev
źródło