Come leggere e impostare variabili ambientali e di shell su Linux

Introduzione

Quando si interagisce con il proprio server attraverso una sessione di shell, ci sono molte informazioni che la shell compila per determinare il suo comportamento e l’accesso alle risorse. Alcune di queste impostazioni sono contenute nelle impostazioni di configurazione e altre sono determinate dall’input dell’utente.

Un modo in cui la shell tiene traccia di tutte queste impostazioni e dettagli è attraverso un’area che mantiene chiamata ambiente. L’ambiente è un’area che la shell costruisce ogni volta che avvia una sessione e che contiene variabili che definiscono le proprietà del sistema.

In questa guida, discuteremo come interagire con l’ambiente e leggere o impostare le variabili ambientali e di shell in modo interattivo e attraverso i file di configurazione.

Come funzionano l’ambiente e le variabili ambientali

Ogni volta che una sessione di shell si genera, ha luogo un processo per raccogliere e compilare le informazioni che dovrebbero essere disponibili al processo della shell e ai suoi processi figli. Ottiene i dati per queste impostazioni da una varietà di diversi file e impostazioni sul sistema.

L’ambiente fornisce un mezzo attraverso il quale il processo di shell può ottenere o impostare impostazioni e, a sua volta, passarle ai suoi processi figli.

L’ambiente è implementato come stringhe che rappresentano coppie chiave-valore. Se vengono passati più valori, sono tipicamente separati da due punti (:). Ogni coppia sarà generalmente simile a questa:

KEY=value1:value2:...

Se il valore contiene spazi bianchi significativi, si usano le virgolette:

KEY="value with spaces"

Le chiavi in questi scenari sono variabili. Possono essere di due tipi, variabili ambientali o variabili di shell.

Le variabili ambientali sono variabili che sono definite per la shell corrente e sono ereditate da qualsiasi shell o processo figlio. Le variabili ambientali sono usate per passare informazioni nei processi che sono generati dalla shell.

Le variabili di shell sono variabili che sono contenute esclusivamente nella shell in cui sono state impostate o definite. Sono spesso usate per tenere traccia di dati effimeri, come la directory di lavoro corrente.

Per convenzione, questi tipi di variabili sono solitamente definiti usando tutte le lettere maiuscole. Questo aiuta gli utenti a distinguere le variabili ambientali in altri contesti.

Stampa delle variabili di shell e ambientali

Ogni sessione di shell tiene traccia delle proprie variabili di shell e ambientali. Possiamo accedervi in diversi modi.

Possiamo vedere una lista di tutte le nostre variabili ambientali usando i comandi env o printenv. Nel loro stato predefinito, dovrebbero funzionare esattamente allo stesso modo:

  • printenv

Questo è abbastanza tipico dell’output di entrambi printenv e env. La differenza tra i due comandi è solo apparente nella loro funzionalità più specifica. Per esempio, con printenv, è possibile richiedere i valori delle singole variabili:

  • printenv SHELL
Output
/bin/bash

D’altra parte, env permette di modificare l’ambiente in cui i programmi vengono eseguiti passando una serie di definizioni di variabili in un comando come questo:

  • env VAR1="value" command_to_run command_options

Siccome, come abbiamo imparato sopra, i processi figli tipicamente ereditano le variabili ambientali del processo padre, questo vi dà la possibilità di sovrascrivere i valori o aggiungere ulteriori variabili per il figlio.

Come potete vedere dall’output del nostro comando printenv, ci sono parecchie variabili ambientali impostate attraverso i nostri file di sistema e processi senza il nostro input.

Queste mostrano le variabili ambientali, ma come possiamo vedere le variabili di shell?

Il comando set può essere usato per questo. Se digitiamo set senza alcun parametro aggiuntivo, otterremo una lista di tutte le variabili di shell, variabili ambientali, variabili locali e funzioni di shell:

  • set

Questa è solitamente una lista enorme. Probabilmente vorrete convogliarla in un programma di paginazione per gestire più facilmente la quantità di output:

  • set | less

La quantità di informazioni aggiuntive che riceviamo indietro è un po’ opprimente. Probabilmente non abbiamo bisogno di conoscere tutte le funzioni bash che sono definite, per esempio.

Possiamo pulire l’output specificando che set dovrebbe operare in modalità POSIX, che non stamperà le funzioni della shell. Possiamo eseguire questo in una sub-shell in modo che non cambi il nostro ambiente corrente:

  • (set -o posix; set)

Questo elencherà tutte le variabili ambientali e di shell che sono definite.

Possiamo tentare di confrontare questo output con l’output dei comandi env o printenv per cercare di ottenere una lista di sole variabili di shell, ma questo sarà imperfetto a causa dei diversi modi in cui questi comandi forniscono informazioni:

  • comm -23 <(set -o posix; set | sort) <(env | sort)

Questo probabilmente includerà ancora alcune variabili ambientali, a causa del fatto che il comando set emette valori quotati, mentre i comandi printenv e env non quotano i valori delle stringhe.

Questo dovrebbe comunque darvi una buona idea delle variabili ambientali e di shell che sono impostate nella vostra sessione.

Queste variabili sono usate per ogni sorta di cose. Forniscono un modo alternativo per impostare valori persistenti per la sessione tra i processi, senza scrivere le modifiche su un file.

Variabili ambientali e di shell comuni

Alcune variabili ambientali e di shell sono molto utili e vengono citate abbastanza spesso.
Queste sono alcune comuni variabili ambientali che incontrerete:

  • SHELL: Questo descrive la shell che interpreterà qualsiasi comando digitato. Nella maggior parte dei casi, questo sarà bash per default, ma altri valori possono essere impostati se si preferiscono altre opzioni.
  • TERM: Questo specifica il tipo di terminale da emulare quando si esegue la shell. Diversi terminali hardware possono essere emulati per diversi requisiti operativi. Di solito non c’è bisogno di preoccuparsene.
  • USER: L’attuale utente loggato.
  • PWD: La directory di lavoro corrente.
  • OLDPWD: La directory di lavoro precedente. Questa viene conservata dalla shell per poter tornare alla directory precedente eseguendo cd -.
  • LS_COLORS: Questo definisce i codici colore che sono usati per aggiungere opzionalmente output colorato al comando ls. Questo è usato per distinguere diversi tipi di file e fornire maggiori informazioni all’utente a colpo d’occhio.
  • MAIL: Il percorso della casella di posta dell’utente corrente.
  • PATH: Una lista di directory che il sistema controllerà quando cerca i comandi. Quando un utente digita un comando, il sistema controllerà le directory in questo ordine per l’eseguibile.
  • LANG: La lingua corrente e le impostazioni di localizzazione, inclusa la codifica dei caratteri.
  • HOME: La home directory dell’utente corrente.
  • _: Il più recente comando precedentemente eseguito.

In aggiunta a queste variabili ambientali, alcune variabili di shell che vedrete spesso sono:

  • BASHOPTS: La lista delle opzioni che sono state utilizzate quando bash è stata eseguita. Questo può essere utile per scoprire se l’ambiente della shell funzionerà nel modo desiderato.
  • BASH_VERSION: La versione di bash in esecuzione, in forma leggibile dall’uomo.
  • BASH_VERSINFO: La versione di bash, in output leggibile dalla macchina.
  • COLUMNS: Il numero di colonne larghe che sono usate per disegnare l’output sullo schermo.
  • DIRSTACK: Lo stack di directory che sono disponibili con i comandi pushd e popd.
  • HISTSIZE: Numero di linee della cronologia dei comandi consentite in memoria.
  • HOSTNAME: L’hostname del computer in questo momento.
  • IFS: Il separatore di campo interno per separare gli input sulla linea di comando. Per impostazione predefinita, questo è uno spazio.
  • PS1: La definizione primaria del prompt dei comandi. Questo è usato per definire l’aspetto del tuo prompt quando inizi una sessione di shell. Il PS2 è usato per dichiarare prompt secondari per quando un comando si estende su più linee.
  • SHELLOPTS: Opzioni della shell che possono essere impostate con l’opzione set.
  • UID: L’UID dell’utente corrente.

Impostare le variabili di shell e ambientali

Per capire meglio la differenza tra le variabili di shell e ambientali, e per introdurre la sintassi per impostare queste variabili, faremo una piccola dimostrazione.

Creare le variabili di shell

Inizieremo definendo una variabile di shell nella nostra sessione corrente. Questo è facile da realizzare; abbiamo solo bisogno di specificare un nome e un valore. Aderiremo alla convenzione di tenere tutte le maiuscole per il nome della variabile, e la imposteremo su una semplice stringa.

  • TEST_VAR='Hello World!'

Qui, abbiamo usato le virgolette poiché il valore della nostra variabile contiene uno spazio. Inoltre, abbiamo usato le virgolette singole perché il punto esclamativo è un carattere speciale nella shell bash che normalmente si espande nella cronologia bash se non viene evaso o messo tra virgolette singole.

Ora abbiamo una variabile di shell. Questa variabile è disponibile nella nostra sessione corrente, ma non sarà passata ai processi figli.

Lo possiamo vedere cercando la nostra nuova variabile nell’output set:

  • set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

Possiamo verificare che questa non è una variabile ambientale provando la stessa cosa con printenv:

  • printenv | grep TEST_VAR

Nessun output dovrebbe essere restituito.

Prendiamo questa come un’opportunità per dimostrare un modo di accedere al valore di qualsiasi variabile di shell o ambientale.

  • echo $TEST_VAR
Output
Hello World!

Come potete vedere, fate riferimento al valore di una variabile precedendola con un segno $. La shell prende questo per significare che dovrebbe sostituire il valore della variabile quando la incontra.

Quindi ora abbiamo una variabile di shell. Non dovrebbe essere passata a nessun processo figlio. Possiamo generare una nuova shell bash dall’interno di quella attuale per dimostrare:

  • bash
  • echo $TEST_VAR

Se digitiamo bash per generare una shell figlia, e poi proviamo ad accedere al contenuto della variabile, non verrà restituito nulla. Questo è quello che ci aspettavamo.

Ritorna alla nostra shell originale digitando exit:

  • exit

Creazione di variabili ambientali

Ora, trasformiamo la nostra variabile di shell in una variabile ambientale. Possiamo farlo esportando la variabile. Il comando per farlo è opportunamente chiamato:

  • export TEST_VAR

Questo cambierà la nostra variabile in una variabile ambientale. Possiamo verificarlo controllando di nuovo il nostro elenco ambientale:

  • printenv | grep TEST_VAR
Output
TEST_VAR=Hello World!

Questa volta, la nostra variabile appare. Proviamo di nuovo il nostro esperimento con la nostra shell figlia:

  • bash
  • echo $TEST_VAR
Output
Hello World!

Grande! La nostra shell figlia ha ricevuto la variabile impostata dal suo genitore. Prima di uscire da questa shell figlia, proviamo ad esportare un’altra variabile. Possiamo impostare le variabili ambientali in un solo passo come questo:

  • export NEW_VAR="Testing export"

Testare che sia esportata come variabile ambientale:

  • printenv | grep NEW_VAR
Output
NEW_VAR=Testing export

Ora, usciamo di nuovo nella nostra shell originale:

  • exit

Vediamo se la nostra nuova variabile è disponibile:

  • echo $NEW_VAR

Non viene restituito nulla.

Questo perché le variabili ambientali sono passate solo ai processi figli. Non c’è un modo integrato per impostare le variabili ambientali della shell madre. Questo è un bene nella maggior parte dei casi e impedisce ai programmi di influenzare l’ambiente operativo da cui sono stati chiamati.

La variabile NEW_VAR è stata impostata come variabile ambientale nella nostra shell figlia. Questa variabile sarebbe stata disponibile a se stessa e a qualsiasi altra shell e processo figlio. Quando siamo usciti di nuovo nella nostra shell principale, quell’ambiente è stato distrutto.

Demoto e annullamento delle variabili

Abbiamo ancora la nostra variabile TEST_VAR definita come variabile ambientale. Possiamo cambiarla di nuovo in una variabile di shell digitando:

  • export -n TEST_VAR

Non è più una variabile ambientale:

  • printenv | grep TEST_VAR

Comunque, è ancora una variabile di shell:

  • set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

Se vogliamo disinserire completamente una variabile, sia di shell che ambientale, possiamo farlo con il comando unset:

  • unset TEST_VAR

Possiamo verificare che non sia più impostata:

  • echo $TEST_VAR

Non viene restituito nulla perché la variabile è stata impostata.

Impostare le variabili ambientali al login

Abbiamo già detto che molti programmi usano le variabili ambientali per decidere le specifiche di come operare. Non vogliamo dover impostare variabili importanti ogni volta che avviamo una nuova sessione di shell, e abbiamo già visto quante variabili sono già impostate al momento del login, quindi come possiamo creare e definire le variabili automaticamente?

Questo è in realtà un problema più complesso di quanto sembri inizialmente, a causa dei numerosi file di configurazione che la shell bash legge a seconda di come viene avviata.

La differenza tra le sessioni di login, non-login, interattive e non-interattive della shell

La shell bash legge diversi file di configurazione a seconda di come viene avviata la sessione.

Una distinzione tra le diverse sessioni è se la shell viene generata come sessione di login o non-login.

Una shell di login è una sessione di shell che inizia con l’autenticazione dell’utente. Se stai entrando in una sessione di terminale o attraverso SSH e ti autentichi, la tua sessione di shell sarà impostata come una shell di login.

Se inizi una nuova sessione di shell dall’interno della tua sessione autenticata, come abbiamo fatto chiamando il comando bash dal terminale, viene avviata una sessione di shell non-login. Non vi sono stati chiesti i vostri dettagli di autenticazione quando avete avviato la vostra shell bambina.

Un’altra distinzione che può essere fatta è se una sessione di shell è interattiva o non interattiva.

Una sessione di shell interattiva è una sessione di shell che è collegata ad un terminale. Una sessione di shell non interattiva è una sessione non collegata ad un terminale.

Così ogni sessione di shell è classificata come login o non-login e interattiva o non-interattiva.

Una normale sessione che inizia con SSH è solitamente una shell di login interattiva. Uno script eseguito dalla riga di comando è di solito eseguito in una shell non interattiva, non di login. Una sessione terminale può essere una qualsiasi combinazione di queste due proprietà.

Il fatto che una sessione di shell sia classificata come una shell di login o non-login ha implicazioni su quali file vengono letti per inizializzare la sessione di shell.

Una sessione iniziata come sessione di login leggerà prima i dettagli di configurazione dal file /etc/profile. Poi cercherà il primo file di configurazione della shell di login nella home directory dell’utente per ottenere i dettagli di configurazione specifici dell’utente.

Legge il primo file che può trovare tra ~/.bash_profile~/.bash_login, e ~/.profile e non legge nessun altro file.

Al contrario, una sessione definita come una shell senza login leggerà /etc/bash.bashrc e poi il file ~/.bashrc specifico dell’utente per costruire il suo ambiente.

Le shell non interattive leggono la variabile ambientale chiamata BASH_ENV e leggono il file specificato per definire il nuovo ambiente.

Implementare le variabili ambientali

Come potete vedere, ci sono una varietà di file diversi che di solito dovremmo guardare per mettere le nostre impostazioni.

Questo fornisce un sacco di flessibilità che può aiutare in situazioni specifiche in cui vogliamo certe impostazioni in una shell di login, e altre impostazioni in una shell non di login. Tuttavia, la maggior parte delle volte vogliamo le stesse impostazioni in entrambe le situazioni.

Fortunatamente, la maggior parte delle distribuzioni Linux configura i file di configurazione di login come sorgente dei file di configurazione non di login. Questo significa che è possibile definire le variabili ambientali che si desidera in entrambi all’interno dei file di configurazione non di login. Verranno quindi lette in entrambi gli scenari.

Di solito impostiamo variabili ambientali specifiche per l’utente, e di solito vogliamo che le nostre impostazioni siano disponibili sia nella shell di login che in quella di non login. Questo significa che il posto dove definire queste variabili è nel file ~/.bashrc.

Apri questo file ora:

  • nano ~/.bashrc

Questo probabilmente conterrà già un bel po’ di dati. La maggior parte delle definizioni qui sono per impostare le opzioni di bash, che non sono collegate alle variabili ambientali. Potete impostare le variabili ambientali proprio come fareste dalla linea di comando:

  • export VARNAME=value

Qualsiasi nuova variabile ambientale può essere aggiunta ovunque nel file ~/.bashrc, purché non sia posta nel mezzo di un altro comando o ciclo for. Possiamo quindi salvare e chiudere il file. La prossima volta che avviate una sessione di shell, la vostra dichiarazione di variabile ambientale sarà letta e passata all’ambiente della shell. Potete forzare la vostra sessione corrente a leggere il file ora digitando:

  • source ~/.bashrc

Conclusione

Le variabili ambientali e di shell sono sempre presenti nelle vostre sessioni di shell e possono essere molto utili. Sono un modo interessante per un processo genitore di impostare dettagli di configurazione per i suoi figli, e sono un modo di impostare opzioni al di fuori dei file.

Questo ha molti vantaggi in situazioni specifiche. Per esempio, alcuni meccanismi di distribuzione si basano su variabili ambientali per configurare le informazioni di autenticazione. Questo è utile perché non richiede di tenerle in file che possono essere visti da parti esterne.

Ci sono molti altri scenari, più banali, ma più comuni, in cui avrete bisogno di leggere o alterare l’ambiente del vostro sistema. Questi strumenti e tecniche dovrebbero darvi una buona base per fare queste modifiche e usarle correttamente.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *