next up previous contents
Nästa: 6.4 Startfiler Upp: 6. Skalet Bash Förra: 6.2 De första programmen

6.3 Miljön

Antag att vi har gett en viss variabel ett värde. Om vi sedan startar ett nytt program, känner det då till variabelns värde? Låt oss prova! Vi ger följande program namnet arv:

#!/bin/bash
echo "Variabeln TEST har värdet <$TEST>."
Sedan ger vi variabeln TEST värdet definierad, och kör därefter arv.$ TEST=definierad
$ arv
Variabeln TEST har värdet <>.
$
Nej, utskriften visar att vårt program inte känner till värdet av TEST. För att variabeln ska gå i arv till programmet måste vi först exportera den:$ export TEST
$ arv
Variabeln TEST har värdet <definierad>.
$
Kommandot export TEST exporterar variabeln TEST. När vi sedan kör programmet arv, så känner det till värdet av TEST.

Man kan ge kommandot printenv (eller export utan argument) för att ta reda på vilka variabler som är exporterade:$ printenv
TEST=definierad
HOSTNAME=fafner
MANPATH=/usr/man:/usr/X11R6/man:/usr/local/man
PS1=\$
USER=göran
MACHTYPE=i486-debian-linux-gnu
LC_MESSAGES=sv_SE
LC_TIME=sv_SE
LOGNAME=göran
SHLVL=1
SHELL=/bin/bash
HOSTTYPE=i486
OSTYPE=linux-gnu
TERM=linux
HOME=/home/göran
PATH=/home/göran/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.
$

Men vad är det för mening med att exportera variabler? Vi besvarar denna fråga genom att ge ett exempel. I utskriften ovan ser vi att variabeln LC_TIME är markerad för export. Variabeln anger vilka konventioner vi vill att datumangivelser ska följa. Variabeln påverkar bland andra programmet date. Det nuvarande värdet av LC_TIME är sv_SE, som står för ''svenska i Sverige''. Men vi ändrar nu värdet till da_DK och anropar date:$ LC_TIME=da_DK
$ date
søn feb 22 12:13:38 CET 1998
$
Effekten blev att dagens datum skrevs på danskt vis i stället för svenskt. Vi provar nu värdet de_AT, ''tyska i Österrike'':$ LC_TIME=de_AT
$ date
Son Feb 22 12:13:52 CET 1998
$
Denna gång fick vi utskriften på tyska. Genom att exportera variabler kan man överföra information till diverse program. Därigenom slipper man förmedla informationen via en massa argument varje gång programmen anropas.

Med process menas en programkörning. Om en process startar en annan process, så sägs den förra processen vara förälder till den senare, och den senare processen sägs vara barn till den förra. Om vi kör igång ett program från Bash, så är alltså Bashprocessen förälder till den nya programkörningen.

När en process startas, får den något som kallas för dess miljö. Miljön är en uppsättning variabler med definierade värden. Man skulle kunna säga att miljön är processens arvsanlag eller gener, för miljön går i arv från föräldraprocess till barnprocess. Det är inte så att det finns en enda miljö som är gemensam för alla program, utan varje process har som sagt en egen miljö som den tilldelas (ärver) av föräldern då den startas.

Vad som sker när vi exporterar en variabel i skalet är helt enkelt att variabeln placeras i miljön. Om vi sedan startar ett nytt program från Bash, så kopieras miljön till den nya programkörningen. Därför är samtliga exporterade variabler tillgängliga för de program vi startar.

Om ett Bash-skal ärver några miljövariabler från sin föräldraprocess, så gör Bash-skalet genast egna variabler som motsvarar dessa miljövariabler. Varje miljövariabel är alltså samtidigt en vanlig variabel, en så kallad skalvariabel, i Bash.

 Det finns några miljövariabler, som kallas för lokaler, som används för att definiera vilket språk och vilka kulturella konventioner man vill att programmen ska hålla sig till. En av lokalerna är LC_TIME. De andra heter LC_MESSAGES, LC_COLLATE, LC_CTYPE, LC_NUMERIC och LC_MONETARY. Om man vill att datorn ska använda det svenska språket såsom det talas i Sverige, och följa svenska konventioner, så ska man sätta dessa till sv_SE. Om variabeln LC_ALL har något värde, så används detta i stället för de enskilda lokalernas värden. Om varken LC_ALL eller någon av lokalerna har något värde, så används i stället värdet av variablen LANG.

För att ta bort namn från miljön ska man anropa export med flaggan -n:$ export -n LC_TIME
$ date
Sun Feb 22 18:29:46 CET 1998
$
Efter kommandot export -n LC_TIME är variabeln LC_TIME inte längre en del av miljön. Därför kunde date inte se dess värde, och vi fick utskriften på engelska.

Kommandot export namn=värde har samma effekt som namn=värde; export namn.$ export LC_ALL=sv_SE
$ date
sön feb 22 18:32:53 CET 1998
$

Nedan definierar vi två variabler och markerar den ena för export. Därefter startar vi ett nytt Bashskal i syfte att undersöka ifall de båda variablerna ärvs. Det nya skalet markeras med en inramning. Ett sådant ''skal i skalet'' kallas för ett subskal. Det kan liknas vid en ''berättelse i berättelsen'', något som ofta förekommer på film.$ NAMN='Göran Andersson'
$ ADRESS=goran_a@sslug.dk
$ export ADRESS
$ bash

$ echo "Namnet är <$NAMN>"
Namnet är <>
$ echo "Adressen är <$ADRESS>"
Adressen är <goran_a@sslug.dk>
$ exit
exit
$ Over ser vi att variabeln ADRESS, som exporterats till miljön, ärvdes. Variabeln NAMN, som inte var en del av miljön, var däremot odefinierad i det nya skalet.

Antag att en process, tex ett nytt Bash-skal som ovan, har ärvt en viss variabel från föräldern genom miljön. Antag vidare att variabeln ändras i den nya processen. Påverkas då motsvarande variabel hos föräldern? Nej, processen har ju sin egen miljö som är helt fristående från förälderns miljö. Mänskliga gener går i arv från föräldrar till barn men inte omvänt; förälderns gener påverkas inte ifall barnets gener senare förändras. Detsamma gäller för olika processer och deras miljöer, vilket följande exempel understryker:$ pwd
/home/göran
$ PS1='vad nu? '
vad nu? bash

vad nu? echo "Prompten är <$PS1>"
Prompten är <vad nu? >
vad nu? PS1='befall: '
befall: ADRESS=eva@turangalila.se
befall: cd /etc
befall: pwd
/etc
befall: exit
exit
vad nu? echo "$NAMN <$ADRESS>"
Göran Andersson <goran_a@sslug.dk>
vad nu? PS1='\$ '
$ pwd
/home/göran
$
Ovan ändras värdet av PS1, och sedan startas ett nytt skal. Värdet av PS1 ärvs uppenbarligen. Sedan ändras PS1 och ADRESS, och det nya skalet avslutas. Hos föräldern har varken PS1 eller ADRESS påverkats. Att den nuvarande katalogen ändrades i subskalet påverkade inte heller vad som var den nuvarande katalogen i det ursprungliga skalet. Om man har två skal igång samtidigt (tex på två olika virtuella terminaler) och exporterar en variabel i det ena skalet, så blir den inte därmed synlig i det andra skalet.


next up previous contents
Nästa: 6.4 Startfiler Upp: 6. Skalet Bash Förra: 6.2 De första programmen
Goran Andersson
1999-03-08