Qual è la differenza tra set, export e env e quando dovrei usarli?

92

Ogni tanto butto fuori uno script bash e mi sembra che ci siano alcuni modi per impostare una variabile:

key=value
env key=value
export key=value

Quando sei all'interno di uno script o di un singolo comando (per esempio, io spesso incrocio una variabile con un lanciatore di Wine per impostare il giusto prefisso del vino) questi sembrano essere completamente intercambiabili ma sicuramente non può essere il caso.

Qual è la differenza tra questi tre metodi e puoi darmi un esempio di quando vorrei specificamente utilizzarli?

Definitivamente correlato a Qual è la differenza tra 'VAR = ...' e 'export VAR = ...'? ma voglio sapere in che modo env si adatta anche a questo, e alcuni esempi che mostrano i vantaggi di ciascuno sarebbero anche belli:)

    
posta Oli 24.10.2012 - 11:34

1 risposta

91

Consideriamo un esempio specifico. Il comando grep utilizza una variabile di ambiente chiamata GREP_OPTIONS per impostare le opzioni predefinite.

Ora. Dato che il file test.txt contiene le seguenti righe:

line one
line two

eseguendo il comando grep one test.txt restituirà

line one

Se esegui grep con l'opzione -v , restituirà le righe non corrispondenti, quindi l'output sarà

line two

Ora proveremo a impostare l'opzione con una variabile ambientale.

  1. Le variabili d'ambiente impostate senza export non saranno ereditate nell'ambiente dei comandi che stai chiamando.

    GREP_OPTIONS='-v'
    grep one test.txt
    

    Il risultato:

    line one
    

    Ovviamente, l'opzione -v non è stata passata a grep .

    Si desidera utilizzare questo modulo quando si imposta una variabile solo per la shell da utilizzare, ad esempio in for i in * ; do non si desidera esportare $i .

  2. Tuttavia, la variabile viene passata all'ambiente di quella particolare riga di comando, quindi puoi fare

    GREP_OPTIONS='-v' grep one test.txt
    

    che restituirà l'attesa

    line two
    

    Questo modulo viene utilizzato per modificare temporaneamente l'ambiente di questa particolare istanza del programma avviato.

  3. L'esportazione di una variabile fa sì che la variabile sia ereditata:

    export GREP_OPTIONS='-v'
    grep one test.txt
    

    ritorna ora

    line two
    

    Questo è il modo più comune di impostare le variabili per l'utilizzo dei processi avviati successivamente in una shell

  4. Questo è stato fatto tutto in bash. export è un builtin bash; VAR=whatever è la sintassi di bash. env , d'altra parte, è un programma in sé. Quando viene chiamato env , si verificano le seguenti condizioni:

    1. Il comando env viene eseguito come un nuovo processo
    2. env modifica l'ambiente e
    3. chiama il comando fornito come argomento. Il processo env è sostituito dal processo command .

    Esempio:

    env GREP_OPTIONS='-v' grep one test.txt
    

    Questo comando lancerà due nuovi processi: (i) env e (ii) grep (in realtà, il secondo processo sostituirà il primo). Dal punto di vista del processo grep , il risultato è esattamente uguale a quello in esecuzione

    GREP_OPTIONS='-v' grep one test.txt
    

    Tuttavia, puoi usare questo idioma se sei fuori da bash o non vuoi lanciare un'altra shell (ad esempio, quando stai usando la famiglia di funzioni exec() piuttosto che la chiamata system() ).

Nota aggiuntiva su #!/usr/bin/env

Questo è anche il motivo per cui viene usato l'idiom #!/usr/bin/env interpreter piuttosto che #!/usr/bin/interpreter . env non richiede un percorso completo per un programma, perché usa la funzione execvp() che ricerca attraverso la variabile PATH proprio come fa una shell, e quindi sostituisce stessa dal comando eseguito . Quindi, può essere usato per scoprire dove un interprete (come perl o python) "si siede" sul percorso.

Significa anche che modificando il percorso corrente puoi influenzare quale variante di python sarà chiamata. Questo rende possibile quanto segue:

echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
calibre

invece di lanciare Calibre, risulterà

I am an evil interpreter!
    
risposta data January 24.10.2012 - 12:21

Leggi altre domande sui tag