Comando env in Linux: variabili e ambiente di un processo
env esegue un programma con variabili d’ambiente aggiunte, modificate o rimosse, senza cambiare quelle della shell chiamante. Senza un programma da avviare, mostra invece l’ambiente risultante; per leggere una sola variabile è più diretto usare printenv NOME.
Questa guida descrive soprattutto env dei GNU Coreutils, comune nelle distribuzioni Linux. Il comando esiste anche in altre implementazioni, ma opzioni come -C e -S richiedono una verifica sul sistema di destinazione.
Cos'è il comando env?
L’ambiente è un insieme di coppie nome-valore che un processo riceve dal processo padre. env parte dall’ambiente ereditato, lo modifica secondo le opzioni e poi avvia il programma. Le variabili possono essere ereditate anche dai processi figli di quel programma; la shell originale conserva il proprio ambiente.
Sintassi di base
env [options] [name=value]... [command [arguments]...]
Nella sintassi, i termini tra parentesi quadre sono facoltativi e command è un segnaposto. Senza un comando, env stampa tutte le variabili dell’ambiente risultante; la seconda forma seguente ne ordina le righe.
env
env | sort
L’ambiente può contenere token, password e altri dati riservati. Esaminate l’output localmente e rimuovete i dati sensibili prima di condividerlo in richieste di supporto o registri pubblici.
Impostare variabili d'ambiente per un singolo comando
Prima di eseguire i blocchi seguenti, aprite una directory di prova nuova e vuota: il primo blocco crea start.sh e names.txt, usati anche nelle sezioni successive. Servono una shell compatibile con POSIX, lo standard per le interfacce dei sistemi di tipo Unix, e i programmi cat, chmod, sort e printenv.
cat > start.sh <<'EOF'
#!/bin/sh
printf 'APP_ENV=%s\n' "${APP_ENV-non impostato}"
if [ "${DEBUG+x}" = x ]; then
printf 'DEBUG impostato: <%s>\n' "$DEBUG"
else
printf '%s\n' 'DEBUG non impostato'
fi
pwd
EOF
chmod +x start.sh
printf 'Carlo\nAlice\nBruno\n' > names.txt
env APP_ENV=production ./start.sh
env LC_ALL=C sort names.txt
Lo script stampa APP_ENV=production, lo stato di DEBUG e la directory corrente; sort stampa Alice, Bruno e Carlo su tre righe.
printenv APP_ENV
APP_ENV vale production soltanto per il programma avviato. Il controllo con printenv mostra l’eventuale valore già esportato dalla shell padre; se non esiste, non stampa nulla e restituisce stato 1. LC_ALL=C fissa tutte le categorie della localizzazione: usare soltanto LANG=C non prevale su un LC_ALL o LC_COLLATE ereditato. Potete passare più variabili allo stesso comando, come nel controllo seguente, che stampa i tre valori senza avviare un server.
env HOST=127.0.0.1 PORT=8080 DEBUG=1 /usr/bin/printenv HOST PORT DEBUG
Assegnazioni della shell e uso di env
Per un programma esterno, una shell in stile POSIX consente anche di anteporre direttamente le assegnazioni al comando. Con il file names.txt creato sopra, le due forme seguenti producono lo stesso elenco ordinato:
LC_ALL=C sort names.txt
env LC_ALL=C sort names.txt
Questa equivalenza riguarda l’ambiente di un programma esterno: un’assegnazione senza comando modifica invece la shell corrente, e funzioni o builtin speciali seguono regole proprie della shell. env offre inoltre opzioni per svuotare l’ambiente, eliminare variabili e cambiare directory. Non esegue direttamente funzioni, parole riservate o builtin della shell chiamante: per esempio, env cd /tmp non richiama il builtin cd. Per una sequenza della shell occorre avviare esplicitamente una shell con lo script desiderato.
Partire da un ambiente vuoto con -i
env -i /usr/bin/printenv
-i, o --ignore-environment, parte da un ambiente vuoto. Con il programma esterno printenv nell’esempio non deve comparire alcuna variabile. È utile per individuare dipendenze nascoste, ma rimuove anche PATH, HOME, le impostazioni locali e le variabili di autenticazione; il programma avviato può poi creare proprie variabili.
Potete reinserire soltanto i valori necessari. Nell’esempio seguente HOME="$HOME" copia il valore della shell chiamante: non cambia la sua directory personale. L’output di env contiene le tre assegnazioni indicate; l’ordine delle righe non è significativo.
env -i PATH=/usr/bin:/bin HOME="$HOME" LANG=C /usr/bin/env
Quando PATH è assente, la ricerca dei comandi dipende dall’implementazione e può usare un percorso predefinito: non è garantito né il fallimento né l’uso dei percorsi abituali. Per un risultato prevedibile scegliete un eseguibile con percorso assoluto, come sopra, oppure fornite un PATH verificato.
Rimuovere una variabile con -u
env -u APP_ENV ./start.sh
env --unset=DEBUG ./start.sh
-u nome, o --unset=nome, elimina soltanto la variabile indicata. Con start.sh creato prima, la prima riga stampa APP_ENV=non impostato; la seconda segnala DEBUG non impostato. Le altre variabili ereditate restano disponibili.
Impostare una variabile con una stringa vuota è diverso dal rimuoverla.
env DEBUG= ./start.sh
env -u DEBUG ./start.sh
Il nostro script rende visibile la distinzione: la prima riga stampa DEBUG impostato: <>, la seconda DEBUG non impostato. Il comportamento funzionale dipende dal programma che legge la variabile; un valore vuoto non equivale sempre al valore predefinito.
Cambiare directory con -C
mkdir -p prova-env
cp -- start.sh prova-env/start.sh
env -C ./prova-env ./start.sh
env --chdir=./prova-env APP_ENV=production ./start.sh
-C directory, o --chdir=directory, cambia directory prima di avviare il programma. Qui la copia di start.sh stampa un percorso che termina con /prova-env; nella seconda esecuzione riceve anche APP_ENV=production. La directory della shell chiamante rimane invariata. Se la directory non esiste o non è accessibile, env termina con errore senza avviare lo script. Questa opzione è un’estensione GNU: controllatene il supporto prima di usarla in script destinati ad altri sistemi. Non deducete la directory effettiva soltanto da una variabile PWD ereditata: il comando pwd nello script la verifica.
Opzioni di uso frequente
| Opzione | Descrizione |
|---|---|
-i, --ignore-environment |
Ignora l’ambiente ereditato e parte da un insieme vuoto. |
-u name, --unset=name |
Elimina la variabile indicata prima dell’esecuzione. |
-C directory, --chdir=directory |
Cambia directory prima di avviare il programma. |
-S string, --split-string=string |
Divide una stringa in argomenti, anche nello shebang se supportato. |
-0, --null |
Separa con un byte nullo le voci stampate, invece di usare un fine riga. |
Controllate env --version e env --help sul sistema che eseguirà lo script. Le opzioni lunghe e le estensioni elencate non sono garantite da tutte le implementazioni di env; il manuale GNU distribuito da Debian ne descrive il significato.
Usare /usr/bin/env nello shebang
Lo shebang è la prima riga che indica l’interprete di uno script eseguibile. Salvate il seguente esempio come check-env.py, con terminatori di riga LF:
#!/usr/bin/env python3
import os
print(os.environ.get("APP_ENV", "non impostato"))
Su un sistema di tipo Unix con /usr/bin/env e Python 3 installati, eseguite chmod +x check-env.py e poi ./check-env.py. Stampa non impostato se APP_ENV manca; env APP_ENV=production ./check-env.py stampa production. Env cerca python3 nel PATH: questo facilita l’uso di interpreti installati in posizioni diverse, ma può selezionare un programma inatteso se PATH non è affidabile. Per un servizio che richiede un interprete preciso, può essere preferibile il suo percorso assoluto verificato.
Passare opzioni all’interprete con -S
Con un’implementazione che supporta -S, env può dividere l’argomento dello shebang in nome dell’interprete e opzioni. Salvate questo secondo script come check-isolated.py, sempre con terminatori LF:
#!/usr/bin/env -S python3 -I
import sys
print(sys.flags.isolated)
Dopo chmod +x check-isolated.py, l’esecuzione ./check-isolated.py deve stampare 1, cioè la modalità isolata di Python è attiva. Secondo la documentazione di Python sull’opzione -I, questa modalità ignora le impostazioni PYTHON* e non aggiunge a sys.path la directory dello script né i pacchetti personali dell’utente. Non svuota però l’ambiente letto con os.environ e non sostituisce env -i. Il supporto di -S nello shebang dipende dal sistema: se manca, avviate python3 -I check-isolated.py oppure usate uno script di avvio con percorso e argomenti dell’interprete espliciti. Le opzioni di avvio come -I devono essere applicate prima dell’esecuzione del codice Python.
Variabili della shell ed export
Una variabile della shell non viene automaticamente esportata ai programmi esterni. Provate il blocco seguente in una sessione di prova: unset elimina un eventuale valore precedente di LOCAL_ONLY, così il primo controllo non eredita un attributo export già presente.
unset LOCAL_ONLY
LOCAL_ONLY=value
printenv LOCAL_ONLY
export LOCAL_ONLY
printenv LOCAL_ONLY
Il primo printenv non stampa nulla e restituisce 1; dopo export LOCAL_ONLY, il secondo stampa value e restituisce 0. Export modifica ciò che la shell passerà ai programmi successivi; env vede soltanto l’ambiente che riceve, non tutte le variabili interne della shell. Terminata la prova, unset LOCAL_ONLY rimuove la variabile di esercizio.
Confronto tra env e printenv
| Categoria | env |
printenv |
|---|---|---|
| Scopo principale | Avviare un programma con un ambiente modificato. | Leggere variabili d’ambiente. |
| Ambiente completo | Lo stampa se manca il comando. | Lo stampa se mancano nomi di variabili. |
| Una sola variabile | Non offre un argomento dedicato alla lettura del valore. | printenv APP_ENV legge direttamente il valore. |
| Aggiunta o rimozione | Sì, per l’ambiente del programma avviato. | No. |
| Avvio di programmi | Sì. | No. |
Precauzioni per la sicurezza e il funzionamento
- Evitate di registrare l’intero ambiente quando contiene credenziali, token o percorsi riservati.
- Scrivere un segreto direttamente in env NOME=VALORE programma può esporlo nella cronologia della shell o negli argomenti del processo.
- Con env -i possono mancare impostazioni relative a certificati, localizzazione e proxy: verificate i requisiti del programma.
- Uno shebang con /usr/bin/env dipende dal PATH: usate directory e interpreti affidabili.
- Per i servizi, preferite le impostazioni esplicite dell’ambiente offerte dal gestore dei servizi, quando disponibili.
Domande frequenti
Le variabili impostate con env rimangono nel terminale corrente?
No. env NOME=VALORE programma cambia l’ambiente del programma avviato, senza impostare o modificare la variabile nella shell padre. I processi figli del programma possono a loro volta ereditare quel valore.
Qual è la differenza tra env e export?
export contrassegna una variabile della shell per trasmetterla ai programmi avviati successivamente. env prepara invece l’ambiente di una singola esecuzione; è comodo per una prova temporanea o per rimuovere variabili prima di avviare un programma.
Perché un comando non viene trovato con env -i?
Controllate il percorso dell’eseguibile: -i rimuove anche PATH e il percorso predefinito usato in sua assenza può essere diverso da quello della sessione. Usate un percorso assoluto o fornite un PATH adeguato. GNU env distingue gli errori: 125 indica un errore di env, 126 un comando trovato ma non eseguibile, 127 un comando non trovato; se il programma parte, env restituisce normalmente il suo stato.




