Ik Van Linux

Variabelen


We hebben het net over de variabele PATH gehad. Dat is een mooi bruggetje om het even over variabelen te hebben. Variabelen heb je normaal gesproken alleen nodig wanneer je Bash scripts gaat schrijven. Een Bash script is een soort .BAT bestand onder DOS, maar dan heel veel krachtiger. Variabelen worden echter ook gebruikt om kleine instellingen te wijzigen. Een van die instellingen hebben we dus al gezien, PATH.

Variabelen "leven" zolang de shell leeft en zijn alleen in de huidige shell beschikbaar. Als je een tweede terminal opent zal die shell zijn eigen set variabelen hebben. En wanneer je de terminal sluit zijn de variabelen weer verdwenen.
En toch bestaan er reeds een aantal variabelen zodra je een nieuwe terminal opent. Kijk maar eens:

printenv
SHELL=/bin/bash
LC_ADDRESS=nl_NL.UTF-8
LC_NAME=nl_NL.UTF-8
SSH_AUTH_SOCK=/tmp/ssh-mwrEIAo44F/agent.3173
LC_MONETARY=nl_NL.UTF-8
PWD=/home/pi
LOGNAME=pi
XDG_SESSION_TYPE=tty
HOME=/home/pi
LANG=en_US.UTF-8
LC_PAPER=nl_NL.UTF-8
XDG_SESSION_CLASS=user
TERM=xterm-256color
LC_IDENTIFICATION=nl_NL.UTF-8
USER=pi
SHLVL=1
LC_TELEPHONE=nl_NL.UTF-8
LC_MEASUREMENT=nl_NL.UTF-8
XDG_SESSION_ID=c10
XDG_RUNTIME_DIR=/run/user/1000
SSH_CLIENT=10.6.1.107 48980 22
LC_ALL=en_US.UTF-8
PATH=/home/pi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
MAIL=/var/mail/pi
SSH_TTY=/dev/pts/0
LC_NUMERIC=nl_NL.UTF-8

Jouw lijstje kan natuurlijk anders zijn dan dat van mij. Ik heb ook expres een paar rommelig uitziende variabelen uit het lijstje gewist, om jou niet af te schrikken.

Als eerste valt op dat variabelen allemaal in hoofdletters geschreven zijn. Dat hoeft niet, maar op deze manier zijn ze gemakkelijker te onderscheiden van commando’s, die meestal in kleine letters geschreven worden. Let wel op, Linux is hoofdletter gevoelig. Dus ook voor variabele namen. De variabele USER is dus niet gelijk aan de variabele User.

Zoals je kunt zien is de variabel PATH ook aanwezig. En er zijn er nog meer waarvan je waarschijnlijk hun functie al wel kunt raden.

Je kunt een variabele gewoon aanpassen.

echo $HOME
HOME="/home"
echo $HOME
/home

Door bijvoorbeeld de HOME variabele aan te passen kun je met het cd commando, zonder iets er achter, meteen overschakelen naar die directory.
Het valt op dat je een dollarteken moet gebruiken om de inhoud van een variabele op te vragen. Maar als je een variabele definieert mag dat niet. Ook mogen er geen spaties rondom het = teken staan. Ik gebruik hier ook aanhalingstekens rond de string die ik aan de variabele wil toekennen. In bovenstaand voorbeeld hoeft dat niet perse, maar er zijn situaties waar dat wel nodig kan zijn. Baat het niet, dan schaadt het niet zullen we maar zeggen.
Variabelen kunnen alleen tekst bevatten. Dus ook getallen worden opgeslagen als tekst.
Experimenteer gerust met wat variabelen. Zodra je de huidige shell verlaat en een nieuwe opent is alles weer terug bij het oude en werkt alles weer, mocht je iets kapot gemaakt hebben.

Je kunt het printenv commando ook gebruiken om een variabele af te drukken.

printenv HOME
/home/pi

Environmental variabelen en normale variabelen

Tot nu toe hebben we alleen de environment (omgevings) variabele gezien.

OEIOEI="Een interessante website."
echo $OEIOEI
Een interessante website.
printenv OEIOEI

We maken hier een variabele aan met de naam OEIOEI, en plaatsen daar een string in. Met het echo commando kunnen we zien dat de variabele inderdaad de string bevat. Echter het printenv OEIOEI commando geeft geen antwoord.

De variabel OEIOEI is nu alleen nog maar een normale variabele. Je kunt die variabele gewoon gebruiken in de shell. Echter zal de variabele niet worden doorgegeven aan programma’s die door de shell gestart worden.
Normaal zal Bash alle bestaande environment variabelen doorgeven aan elk programma wat via Bash gestart wordt. Maar normale variabelen zijn en blijven alleen bekend in de huidige instantie van Bash.

export OEIOEI
printenv OEIOEI
Een interessante website.

Geëxporteerde variabelen kun je zo vaak wijzigen als je wilt. Je hoeft ze niet steeds opnieuw te exporteren. Exporteren betekent echter niet dat de variabele een herstart van de shell zal overleven. Hoe je dat doet zien we zo.

Je kunt een variabele exporteren en tegelijkertijd er een string aan toekennen in een enkel commando.

export LINUX="Is tof!"
printenv LINUX
Is tof!

Tenslotte kun je het systeem ook een environment variabele laten vergeten:

unset LINUX
printenv LINUX

Variabelen laten overleven

We hebben gezien dat een aantal variabelen reeds bestaan als je een terminal opent. Waar komen die vandaan?

Sommige worden gegenereerd door configuratie scripts, zoals /etc/bash.bashrc, /etc/profile en .bashrc . Het eerste bestand is een configuratiebestand voor Bash, wat voor elke gebruiker geldt. Het bestand /etc/profile doet ook zoiets, maar dan voor andere instellingen. Het bestand .bashrc, wat in je home directory staat, bevat jouw persoonlijke aanpassingen aan het systeem brede configuratie bestand.
In die bestanden, en waarschijnlijk ook nog andere bestanden, staan wat export opdrachten die verantwoordelijk zijn voor een deel van jouw environment variabelen.
Bij het starten van een nieuwe terminal worden deze bestanden ingelezen en daarmee wordt een deel van de environment variabelen ingesteld.

Een ander deel van de variabelen worden geërfd vanaf een vorige shell. Doe maar eens dit:

DOS="Is zeer beperkt."
echo $DOS
Is zeer beperkt.
export LINUX="Is hartstikke tof."
printenv LINUX
Is hartstikke tof.
bash
printenv LINUX
echo $DOS

Met het bash commando open je een nieuwe Bash shell. Die nieuwe Bash shell erft alle environment variabelen van de aanroepende shell. Dit gebeurt nadat alle configuratie bestanden gedraaid zijn. Hierdoor kan het zijn dat een georven variabele de inhoud van een van de configuratie variabelen alsnog overschrijft. Je zou kunnen zeggen dat de georven variabelen voorrang krijgen boven reeds bestaande variabelen.
In het voorbeeld hierboven worden twee variabelen aangemaakt, waarvan er slechts een geëxporteerd wordt. Die geëxporteerde variabele is daarom ook bekend in de nieuwe shell.
Gebruik het exit commando om terug te keren naar de aanroepende shell.

Nog een andere deel van de environment variabelen wordt automatisch ingesteld/gewijzigd door Bash of andere programma’s. Kijk maar eens naar PWD:

printenv PWD
/home/pi
cd /etc
printenv PWD
/etc

Het cd commando verplaatst je naar een andere directory en past ook meteen de variabele PWD (Present Working Directory) aan.

Source

Stel nu dat je zelf een scriptje wil schrijven waarmee voor jou interessante variabelen kunnen worden ingesteld. Dan heb je een kleine uitdaging. Het script wat je schrijft zal in een eigen shell draaien, en zodra het script eindigt wordt die shell gesloten. Daarmee worden alle variabelen gewist, ook de geëxporteerde variabelen.

Om dat op te lossen kun je het script (mijnvariabelen genaamd in dit voorbeeld) als volgt starten:

source mijnvariabelen

Een korter alternatief is:

. mijnvariabelen

Enkele geavanceerde toepassingen van variabelen

Je kunt de output van een programma laten opslaan in een variabele. Dit kan op twee manieren:

ROOTLIJST=$(ls -l /)
ETCLIJST=`ls -l /etc`

Beide manieren zijn gelijk. Mijn voorkeur is de $(...) schrijfwijze. Merk op dat de tweede manier gebruik maakt van de "backtick". Dit is dus niet een enkel aanhalingsteken, maar het tekentje wat meestal samen met het ~ teken op een toets aan de linker kant van het toetsenbord te vinden is.

Je kunt de inhoud van variabelen samenvoegen met andere tekst en andere variabelen.

VOORNAAM="San"
ACHTERNAAM="Bergmans"
echo "Mijn naam is $VOORNAAM $ACHTERNAAM."
Mijn naam is San Bergmans.
echo 'Mijn naam is $VOORNAAM $ACHTERNAAM.'
Mijn naam is $VOORNAAM $ACHTERNAAM.

Zie je het verschil tussen enkele en dubbele aanhalingstekens? Variabelen worden alleen vertaald wanneer je dubbele aanhalingstekens gebruikt.

Een alternatief voor het eerste echo commando is:

printf "Mijn naam is %s %s.\n" "$VOORNAAM" "$ACHTERNAAM"
Mijn naam is San Bergmans.

Telkens wanneer %s voorkomt in de eerste string wordt een volgende string genomen uit het lijstje met strings wat na die eerste string staat.