Vraag Wat is het verschil tussen set, export en env en wanneer moet ik elk gebruiken?


Af en toe zal ik een bash-script bashen en het valt me ​​op dat er een paar manieren zijn om een ​​variabele in te stellen:

key=value
env key=value
export key=value

Wanneer je in een script of een enkele opdracht zit (bijvoorbeeld, ik zal vaak een variabele koppelen met een Wine launcher om het juiste Wine-voorvoegsel in te stellen) lijken deze volledig uitwisselbaar, maar dat kan zeker niet het geval zijn.

Wat is het verschil tussen deze drie methoden en kun je me een voorbeeld geven van wanneer ik ze specifiek zou willen gebruiken?

Absoluut gerelateerd aan Wat is het verschil tussen `VAR = ...` en `export VAR = ...`? maar ik wil weten hoe env past hier ook in, en enkele voorbeelden die de voordelen van elk laten zien, zouden ook leuk zijn :)


92
2017-10-24 09:34


oorsprong


Let daar op export key=value is uitgebreide syntaxis en mag niet worden gebruikt in draagbare scripts (d.w.z. #! /bin/sh). - Simon Richter


antwoorden:


Laten we een specifiek voorbeeld beschouwen. De grep commando gebruikt een omgevingsvariabele genaamd GREP_OPTIONS om standaardopties in te stellen.

Nu. Gezien het dossier test.txt bevat de volgende regels:

line one
line two

het uitvoeren van het commando grep one test.txt zal terugkeren

line one

Als je grep uitvoert met de -v optie, retourneert het de niet-overeenkomende lijnen, dus de uitvoer zal zijn

line two

We zullen nu proberen om de optie in te stellen met een omgevingsvariabele.

  1. Omgevingsvariabelen ingesteld zonder export wordt niet geërfd in de omgeving van de opdrachten die u aanroept.

    GREP_OPTIONS='-v'
    grep one test.txt
    

    Het resultaat:

    line one
    

    Uiteraard de optie -v is niet geslaagd voor grep.

    U wilt dit formulier gebruiken wanneer u alleen een variabele instelt voor de shell die u wilt gebruiken, bijvoorbeeld in for i in * ; do je wilt niet exporteren $i.

  2. De variabele wordt echter doorgegeven aan de omgeving van die specifieke opdrachtregel, dus u kunt het doen

    GREP_OPTIONS='-v' grep one test.txt
    

    waardoor het verwachte resultaat wordt geretourneerd

    line two
    

    U gebruikt dit formulier om tijdelijk de omgeving van dit specifieke exemplaar van het gelanceerde programma te wijzigen.

  3. Door een variabele te exporteren, wordt de variabele overgenomen:

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

    komt nu terug

    line two
    

    Dit is de meest gebruikelijke manier om variabelen in te stellen voor gebruik van later gestarte processen in een shell

  4. Dit gebeurde allemaal in bash. export is een bash ingebouwd; VAR=whatever is bash-syntaxis. env, aan de andere kant, is een programma op zichzelf. Wanneer env wordt genoemd, volgende dingen gebeuren:

    1. Het bevel env wordt uitgevoerd als een nieuw proces
    2. env wijzigt de omgeving, en
    3. roept de opdracht die als argument werd opgegeven. De env proces wordt vervangen door de command werkwijze.

    Voorbeeld:

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

    Deze opdracht start twee nieuwe processen: (i) env en (ii) grep (in feite vervangt het tweede proces de eerste). Vanuit het oogpunt van de grep proces, het resultaat is precies hetzelfde als hardlopen

    GREP_OPTIONS='-v' grep one test.txt
    

    U kunt dit idioom echter gebruiken als u zich buiten bash bevindt of als u geen andere shell wilt starten (bijvoorbeeld wanneer u de id gebruikt). exec() familie van functies in plaats van de system() noemen).

Aanvullende opmerking over #!/usr/bin/env

Dit is ook de reden waarom het idioom #!/usr/bin/env interpreterwordt gebruikt in plaats van #!/usr/bin/interpreter. env vereist geen volledig pad naar een programma, omdat het de execvp() functie die doorzoekt PATH variabele zoals een shell dat doet, en dan vervangt  zichzelf door de opdracht run. Het kan dus worden gebruikt om uit te zoeken waar een tolk (zoals perl of python) op het pad 'zit'.

Het betekent ook dat door het huidige pad te wijzigen, u kunt bepalen welke python-variant wordt aangeroepen. Dit maakt het volgende mogelijk:

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

in plaats van Caliber te lanceren, zal dit resulteren in

I am an evil interpreter!

92
2017-10-24 10:21



Waarom werkt GREP_OPTIONS = '- v' grep one test.txt? Ik dacht dat het een puntkomma nodig had na '-v' (maar ik heb het geprobeerd en het werkt inderdaad.) - Joe
Omdat met een puntkomma, het wordt geïnterpreteerd als twee afzonderlijke bash-opdrachten; de eerste stelt de variabele in (zonder deze te exporteren) en de tweede start met een omgeving waarin de variabele niet wordt geëxporteerd. Zonder de puntkomma is dit echter één opdracht (grep), voorafgegaan door het instellen van een lokale omgeving. - January
Lichte correctie: in stap 4 waar je bent env GREP_OPTIONS grep one test.txt, Ik denk dat dat eigenlijk wel zou moeten zijn env GREP_OPTIONS='-v' grep one test.txt - yshavit
Waar komen alle variabelen uit env vandaan komen? Ik bedoel, wanneer je een nieuwe shell opent, heb je altijd een paar variabelen. Dus sommige programma's moeten hebben exportEn die, toch? - Pithikos
@Pithikos Omgevingsvariabelen worden ingesteld door "sourcing an environment." Standaard zal bash een basbrc voor het hele systeem (of profile.d of bash_profile) gebruiken. Vervolgens wordt uw gebruiker ~ / .bashrc (en / of ~ / .bash_profile) gevonden. Elk van deze bestanden kan bash-opdrachten bevatten om andere scripts te genereren, zodat u uiteindelijk omgevingsvariabelen van overal kunt krijgen. - Eric