Comando printenv in Linux: leggere variabili e stato di uscita

printenv NOME stampa il valore di una variabile d’ambiente; senza nomi, printenv mostra tutte le coppie nome-valore ricevute dal processo. Non modifica le variabili e non mostra quelle che esistono soltanto nella shell senza essere esportate.

Questa guida usa la versione GNU Coreutils, comune su Linux. Per verificare l’implementazione disponibile, controllate type -a printenv e printenv --version: alcune shell o altri sistemi possono offrire varianti proprie. printenv serve per leggere i valori, mentre env prepara l’ambiente di un programma.

Che cos'è il comando printenv?

Un programma riceve dal processo padre un insieme di variabili d’ambiente. Printenv legge il proprio ambiente e invia i dati sullo standard output, cioè l’uscita normale del programma, che potete visualizzare nel terminale o collegare a una pipeline.

Una variabile non esportata rimane interna alla shell: il programma esterno printenv non può leggerla. Il comando export stabilisce quali variabili della shell saranno trasmesse ai programmi successivi.

Sintassi di base

printenv [options] [variable...]

Nella sintassi, options e variable sono segnaposto facoltativi. Senza nomi, l’output contiene righe NOME=valore; la seconda forma seguente le ordina per renderle più facili da consultare.

printenv
printenv | sort

L’ambiente completo può contenere token di autenticazione, password e dati di accesso. Consultatelo localmente; prima di condividere risultati o registrarli, eliminate gli elementi riservati. Quando possibile, interrogate soltanto i nomi necessari.

Leggere una o più variabili

printenv HOME
printenv PATH
printenv LANG

Con un nome viene stampato soltanto il valore, senza il prefisso NOME=. HOME indica normalmente la directory personale, PATH i percorsi di ricerca degli eseguibili e LANG l’impostazione locale di base. Se una variabile manca, quel comando non stampa nulla e restituisce 1. Potete anche chiedere più nomi:

printenv HOME SHELL USER

GNU printenv elabora i nomi nell’ordine indicato, ma non produce una riga sostitutiva per quelli assenti. Se manca SHELL, per esempio, non potete associare con sicurezza la seconda riga al secondo nome soltanto contando le righe. Anche un valore che contiene un fine riga può occupare più righe: per una lettura automatica usate i delimitatori NUL descritti sotto.

Interpretare lo stato di uscita

GNU printenv restituisce 0 se trova tutte le variabili richieste, 1 se ne manca almeno una e 2 per altri errori, tra cui un’opzione non valida o un errore di scrittura. Il controllo seguente verifica la presenza di APP_ENV senza mostrarne il valore; il ramo else indica un controllo non riuscito e non distingue da solo l’assenza della variabile da ogni possibile errore del comando.

if printenv APP_ENV >/dev/null; then
  printf '%s\n' 'APP_ENV presente nell’ambiente'
else
  printf '%s\n' 'APP_ENV assente o controllo non riuscito'
fi

Una variabile esportata con valore vuoto esiste comunque e soddisfa il controllo. La presenza non prova che il valore sia non vuoto o valido per l’applicazione: per questa distinzione servono anche controlli sul contenuto, evitando di stampare eventuali segreti.

Distinguere variabili della shell e variabili esportate

Eseguite questa prova in una sessione Bash di esercizio. unset APP_MODE elimina un eventuale valore e attributo export precedenti; senza questa precauzione, riassegnare una variabile già esportata ne conserverebbe l’attributo. Printf stampa development, mentre printenv non stampa nulla e restituisce 1.

unset APP_MODE
APP_MODE=development
printf '%s\n' "$APP_MODE"
printenv APP_MODE
export APP_MODE
printenv APP_MODE

Dopo export, printenv stampa development e termina con 0. La modifica vale per i programmi che questa shell avvierà da quel momento; non aggiorna automaticamente processi già in esecuzione. Al termine della prova, unset APP_MODE rimuove la variabile di esercizio.

Leggere PATH una directory per riga

Su Linux, PATH è una lista di directory separata da due punti. Questo comando richiede tr e presenta una directory per riga:

printenv PATH | tr ':' '\n'

Un elemento vuoto in PATH, all’inizio, alla fine o tra due separatori consecutivi, rappresenta la directory corrente nella ricerca degli eseguibili. Valutate se questa scelta è voluta e affidabile. È una vista di lettura: il comando non modifica PATH. La suddivisione testuale non conserva in modo univoco eventuali caratteri di fine riga nei nomi delle directory.

Separare i valori con NUL usando -0

printenv -0
printenv --null

-0, o --null, termina ogni elemento con un byte nullo, detto NUL, invece di un fine riga. I valori dell’ambiente possono contenere fine riga ma non NUL: questo separatore consente quindi di riconoscere gli elementi senza ambiguità. L’output è destinato a programmi che comprendono NUL, non a una visualizzazione ordinaria nel terminale.

env MULTILINE=$'prima\nseconda' printenv -0 MULTILINE | while IFS= read -r -d '' item; do
  printf '%q\n' "$item"
done

Per provare il caso concreto senza stampare tutto l’ambiente, il blocco precedente crea soltanto per il comando una variabile MULTILINE contenente prima, un fine riga e seconda. Richiede Bash: read -d '' legge fino a NUL, IFS= evita la separazione in parole e -r conserva le barre rovesciate. Il formato Bash %q rende il valore leggibile con gli escape, per esempio $'prima\nseconda', anziché spezzarlo in due record. Non eseguite automaticamente come codice shell il testo letto da una fonte non affidabile.

Opzioni supportate

Opzione Descrizione
-0, --null Termina ogni elemento con NUL anziché con un fine riga.
--help Mostra la guida e termina.
--version Mostra la versione del programma e termina.

Queste sono opzioni della versione GNU descritta qui. Controllate printenv --help sul sistema di destinazione: altre implementazioni possono differire. Anche tutti i programmi della pipeline devono saper trattare i delimitatori scelti.

Confrontare printenv, env, printf ed echo

Comando Che cosa legge Come usarlo
printenv NAME Variabile presente nell’ambiente ricevuto. Stampa il valore; lo stato distingue presenza e assenza.
env L’intero ambiente, se non è indicato un programma. Può anche preparare un ambiente modificato e avviare un programma.
printf '%s\n' "$NAME" Valore espanso dalla shell corrente. Mostra anche variabili non esportate; non ne prova l’esportazione.

echo "$NAME" può mostrare il valore espanso dalla shell, ma il trattamento di opzioni apparenti e barre rovesciate varia tra implementazioni. Negli script, printf '%s\n' "$NAME" rende esplicito il formato. Né printf né echo dimostrano da soli che NAME sia esportata.

Controllare un ambiente temporaneo

Con env potete controllare il valore che riceverebbe un singolo programma. Questi comandi non modificano APP_ENV o HTTP_PROXY nella shell padre:

env APP_ENV=staging printenv APP_ENV
env -u HTTP_PROXY printenv HTTP_PROXY

La prima riga stampa staging e restituisce 0. La seconda elimina HTTP_PROXY dall’ambiente del solo printenv: non stampa nulla e restituisce 1. Questo verifica la presenza della variabile, non il comportamento di un client di rete o l’assenza di altre variabili proxy.

Capire le differenze tra processi

L’ambiente appartiene a ciascun processo: non è una tabella globale unica del sistema. Un terminale, una sessione SSH (Secure Shell, per l’accesso remoto), un servizio systemd, un’attività pianificata con cron e un container possono ricevere valori differenti dai rispettivi processi padre e dalle impostazioni di avvio.

Per diagnosticare un problema, verificate i nomi necessari nello stesso contesto di utente, servizio o container in cui parte il programma. Una nuova shell aperta nello stesso container non riproduce necessariamente tutte le impostazioni del servizio. Confrontate anche i file e le opzioni di avvio: il valore visibile nel terminale non viene automaticamente trasferito a un servizio già avviato.

Proteggere i valori riservati

  • Non incollate l’ambiente completo in segnalazioni pubbliche o chat.
  • Nei sistemi di integrazione continua (CI), verificate quali valori vengono mascherati nei registri.
  • Richiedete soltanto le variabili utili alla diagnosi.
  • Se serve sapere soltanto se una variabile esiste, verificate lo stato di uscita senza mostrarne il valore.
  • L’ambiente non è un archivio segreto: i processi figli e gli strumenti di diagnostica autorizzati possono accedervi secondo le regole del sistema.

Problemi comuni

Il valore è impostato ma non compare

Controllate che la variabile sia stata esportata nella shell che avvia il programma, con export NOME. Verificate poi un nuovo processo figlio: esportarla in un terminale diverso non modifica il processo che state diagnosticando.

Una riga vuota indica una variabile assente?

Una variabile vuota produce un fine riga e stato 0; una variabile assente non produce dati e restituisce 1. Questo esperimento, in una sessione di prova, mostra prima il caso assente e poi quello vuoto:

unset EMPTY_VALUE
printenv EMPTY_VALUE
printf 'status=%s\n' "$?"

export EMPTY_VALUE=
printenv EMPTY_VALUE
printf 'status=%s\n' "$?"
unset EMPTY_VALUE

La variabile scompare dopo sudo

La politica di sudo può ricostruire o filtrare l’ambiente. Il manuale di sudoers descrive env_reset, env_keep ed env_check. Verificate con l’amministratore quali valori servono al comando e quali sono consentiti; non disabilitate globalmente i filtri per far coincidere l’ambiente con quello del terminale.

Domande frequenti

printenv mostra tutte le variabili della shell?

No. Il programma esterno vede l’ambiente ricevuto, non tutte le variabili interne di Bash. Per ispezionare una specifica variabile o un array di Bash potete usare declare -p NOME; evitate di condividere indiscriminatamente anche l’output di declare o set, che può contenere dati riservati.

Posso stampare insieme il nome e il valore di una variabile specifica?

printenv NAME stampa soltanto il valore. Per un rapporto leggibile potete comporre printf 'NAME=%s\n' "$(printenv NAME)", ma la sostituzione di comando rimuove tutti i fine riga finali e il successo di printf non prova che printenv abbia trovato NAME. Se dovete preservare i byte o distinguere gli errori, controllate separatamente lo stato di printenv e usate l’output delimitato da NUL.

È possibile modificare le variabili d'ambiente con printenv?

No. Printenv legge soltanto l’ambiente. Usate un’assegnazione e export per i programmi avviati dalla shell corrente, oppure env NOME=VALORE programma per una sola esecuzione.

Documentazione di riferimento