Een belangrijk onderdeel van het leren werken met Ubuntu, en Linux distributies in het algemeen, is het verkrijgen van vaardigheid in het werken in de shell omgeving. Hoewel de grafische desktop omgevingen zoals GNOME die bij Linux worden geleverd een gebruikersvriendelijke interface bieden voor het besturingssysteem, biedt de shell omgeving in de praktijk veel meer mogelijkheden, flexibiliteit en automatisering dan ooit kan worden bereikt met grafische desktop tools. De shell-omgeving biedt ook een manier voor interactie met het besturingssysteem wanneer een desktop-omgeving niet beschikbaar is; een veel voorkomende gebeurtenis bij het werken met een server-gebaseerd besturingssysteem zoals Ubuntu of een beschadigd systeem dat niet volledig wil opstarten.

Het doel van dit hoofdstuk is daarom een overzicht te geven van de standaard shell omgeving op Ubuntu (specifiek de Bash shell).

1.1 Wat is een Shell?

De shell is een interactieve commando-interpreter omgeving waarbinnen commando’s kunnen worden getypt op een prompt of in een bestand kunnen worden ingevoerd in de vorm van een script en uitgevoerd. De oorsprong van de shell kan worden teruggevoerd tot de begindagen van het UNIX-besturingssysteem. In feite was in de begindagen van Linux, vóór de introductie van grafische desktops, de shell de enige manier voor een gebruiker om met het besturingssysteem te communiceren.

In de loop der jaren is een verscheidenheid aan shell-omgevingen ontwikkeld. De eerste veelgebruikte shell was de Bourne shell, geschreven door Stephen Bourne bij Bell Labs.

Een andere vroege creatie was de C shell die qua syntax overeenkomsten vertoonde met de C Programmeertaal en gebruiksvriendelijke verbeteringen introduceerde, zoals command-line editing en geschiedenis.

De Korn shell (ontwikkeld door David Korn bij Bell Labs) is gebaseerd op kenmerken van zowel de Bourne shell als de C shell.

De standaard shell op Ubuntu is de Bash shell (afkorting voor Bourne Again SHell). Deze shell, die zijn leven begon als een open source versie van de Bourne shell, is ontwikkeld voor het GNU Project door Brian Fox en is gebaseerd op mogelijkheden van zowel de Bourne shell als de C shell.

1.2 Toegang krijgen tot de Shell

Vanuit de GNOME desktop omgeving, kan de shell prompt benaderd worden vanuit een Terminal venster door de Activities optie in de bovenste balk te selecteren, Terminal in de zoekbalk in te voeren en op het Terminal icoon te klikken.

Wanneer op afstand wordt ingelogd op een Ubuntu server, bijvoorbeeld met SSH, krijgt de gebruiker ook een shell prompt te zien. Details over het benaderen van een server op afstand met SSH worden behandeld in het hoofdstuk “SSH sleutel-gebaseerde authenticatie configureren op Ubuntu”. Bij het opstarten van een server-gebaseerd systeem waarop geen desktop omgeving is geïnstalleerd, wordt de commandoregel onmiddellijk geopend nadat de gebruiker de login procedure op de fysieke console terminal of remote login sessie heeft voltooid.

1.3 Commando’s invoeren op de prompt

Commando’s worden ingevoerd op de shell commando prompt door simpelweg het commando in te typen en op de Enter toets te drukken. Sommige commando’s voeren taken in stilte uit, maar de meeste zullen een vorm van uitvoer laten zien voordat ze terugkeren naar de prompt. Het ls commando kan bijvoorbeeld gebruikt worden om de bestanden en mappen in de huidige werkdirectory weer te geven:

$ ls

Desktop Documents Downloads Music Pictures Public Templates Videos

De beschikbare commando’s zijn of in de shell zelf ingebouwd, of bevinden zich op het fysieke bestandssysteem. De locatie van een commando op het bestandssysteem kan worden achterhaald met het welke commando. Om bijvoorbeeld te weten te komen waar het ls-commando zich op het bestandssysteem bevindt:

$ which ls alias ls='ls --color=auto' /usr/bin/ls

Het ls-commando bevindt zich duidelijk in de map /usr/bin. Merk ook op dat er een alias is geconfigureerd, een onderwerp dat later in dit hoofdstuk wordt behandeld. Het gebruik van het which commando om het pad te vinden naar commando’s die in de commandoregel zijn ingebouwd zal resulteren in een bericht dat aangeeft dat het uitvoerbare bestand niet kan worden gevonden. Als u bijvoorbeeld probeert de locatie te vinden van het commando history (dat in de shell is ingebouwd en niet als uitvoerbaar bestand op het bestandssysteem staat), krijgt u uitvoer zoals hieronder:

$ which history/usr/bin/which: no history in (/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)

1.4 Informatie krijgen over een commando

Veel van de commando’s die in de Linux-shell beschikbaar zijn, kunnen in het begin nogal cryptisch lijken. Om gedetailleerde informatie te vinden over wat een commando doet en hoe het te gebruiken, kunt u het man commando gebruiken met de naam van het commando als argument. Bijvoorbeeld, om meer te weten te komen over de opdracht pwd:

$ man pwd

Wanneer de bovenstaande opdracht wordt uitgevoerd, wordt een gedetailleerde beschrijving van de opdracht pwd weergegeven. Veel commando’s geven ook aanvullende informatie wanneer ze worden uitgevoerd met de commandoregeloptie -help:

$ wc --help

1.5 Bash Command-line Editing

Eerdere shellomgevingen boden geen enkele vorm van regelbewerkingsmogelijkheden. Dit betekende dat als je een fout zag aan het begin van een lange opdrachtregel die je aan het typen was, je alle volgende tekens moest verwijderen, de fout moest corrigeren en vervolgens de rest van het commando opnieuw moest invoeren. Gelukkig biedt Bash een breed scala aan opties voor het bewerken van de opdrachtregel, zoals in de volgende tabel is aangegeven:

Key Sequence Action
Ctrl-b of Linkerpijl Verplaats de cursor een positie terug
Ctrl-f of Pijl-rechts Verplaats de cursor een positie vooruit
Wissen Verwijder het teken dat zich onder de cursor
Backspace Teken links van de cursor verwijderen
Ctrl-_ Erdere wijziging ongedaan maken (kan worden herhaald om alle eerdere wijzigingen ongedaan te maken)
Ctrl-a Verplaats de cursor naar het begin van de regel
Ctrl-e Verplaats de cursor naar het einde van de regel
Meta-f of Esc dan f Verplaats cursor een woord vooruit
Meta-b of Esc dan b Verplaats cursor een woord terug
Ctrl-l Het scherm wissen van alles behalve het huidige commando
Ctrl-k Verwijder tot het einde van de regel vanaf de huidige cursorpositie
Meta-d of Esc dan d Wissen naar einde van huidig woord
Meta-DEL of Esc dan DEL Wissen naar begin van huidig woord
Ctrl-w Verwijder vanaf de huidige cursorpositie naar de vorige witruimte

Tabel 9-1

1.6 Werken met de shell Geschiedenis

Naast functies voor het bewerken van de commandoregel, biedt de Bash-shell ook ondersteuning voor de commandoregelgeschiedenis. Een lijst van eerder uitgevoerde commando’s kan worden bekeken met de opdracht history:

$ history1ps2ls3ls –l /4ls5man pwd6man apropos

Met Ctrl-p (pijltje naar boven) en Ctrl-n (pijltje naar beneden) kunt u bovendien heen en weer bladeren door eerder ingevoerde commando’s. Wanneer het gewenste commando uit de geschiedenis wordt weergegeven, drukt u op de Enter-toets om het uit te voeren.

Een andere mogelijkheid is het invoeren van het teken ‘!’ gevolgd door de eerste paar tekens van het commando dat moet worden herhaald, gevolgd door de Enter-toets.

1.7 Filename Shorthand

Veel shellcommando’s nemen een of meer bestandsnamen als argumenten. Om bijvoorbeeld de inhoud van een tekstbestand met de naam list.txt weer te geven, wordt het commando cat als volgt gebruikt:

$ cat list.txt

Op vergelijkbare wijze kan de inhoud van meerdere tekstbestanden worden weergegeven door alle bestandsnamen als argumenten op te geven:

$ cat list.txt list2.txt list3.txt list4.txt

In plaats van elke naam in te typen, kan pattern matching worden gebruikt om alle bestanden op te geven met namen die aan bepaalde criteria voldoen. Zo kan het jokerteken ‘*’ worden gebruikt om bovenstaand voorbeeld te vereenvoudigen:

$ cat *.txt

Het bovenstaande commando geeft de inhoud weer van alle bestanden die eindigen op een .txt-extensie. Dit kan verder worden beperkt tot alle bestandsnamen die beginnen met list en eindigen op .txt:

$ cat list*.txt

Zelfstandige teken-overeenkomsten kunnen worden opgegeven met het teken “?”:

$ cat list?.txt

1.8 Bestandsnaam- en padaanvulling

In plaats van het intypen van een volledige bestandsnaam of pad, of het gebruik van patroonvergelijking om het aantal typen te verminderen, biedt de commandoregel de functie bestandsnaamaanvulling. Om bestandsnaam completie te gebruiken, typ de eerste paar karakters van de bestands- of padnaam in en druk dan tweemaal op de Esc toets. De commandoregel vult dan de bestandsnaam voor je aan met het eerste bestand of pad in de directory dat overeenkomt met de tekens die je hebt ingevoerd. Om een lijst van mogelijke overeenkomsten te krijgen, drukt u op Esc = na het invoeren van de eerste paar karakters.

1.9 Input en Output Redirection

Zoals eerder vermeld, voeren veel shell commando’s informatie uit wanneer ze worden uitgevoerd. Standaard gaat deze uitvoer naar een apparaatbestand met de naam stdout, wat in wezen het terminalvenster of de console is waarin de shell draait. Omgekeerd neemt de shell invoer op van een apparaatbestand met de naam stdin, wat standaard het toetsenbord is.

Uitvoer van een commando kan worden omgeleid van stdout naar een fysiek bestand op het bestandssysteem met behulp van het teken ‘>’. Om bijvoorbeeld de uitvoer van een ls-commando om te leiden naar een bestand met de naam files.txt, is het volgende commando nodig:

$ ls *.txt > files.txt

Als het voltooid is, bevat files.txt de lijst met bestanden in de huidige directory. Op dezelfde manier kan de inhoud van een bestand in een opdracht worden ingevoerd in plaats van stdin. Om bijvoorbeeld de inhoud van een bestand om te leiden als invoer voor een commando:

$ wc –l < files.txt

Het bovenstaande commando geeft het aantal regels weer dat het bestand files.txt bevat.

Het is belangrijk op te merken dat de ‘>’-omleidingoperator een nieuw bestand maakt, of een bestaand bestand afkapt als deze wordt gebruikt. Om aan een bestaand bestand toe te voegen, gebruikt u de ‘>>’-operator:

$ ls *.dat >> files.txt

Naast standaarduitvoer biedt de shell ook standaard foutuitvoer met stderr. Terwijl de uitvoer van een commando naar stdout wordt gestuurd, worden foutmeldingen die door het commando worden gegenereerd, naar stderr gestuurd. Dit betekent dat als stdout naar een bestand wordt gestuurd, foutmeldingen nog steeds in de terminal verschijnen. Dit is in het algemeen het gewenste gedrag, hoewel stderr desgewenst ook kan worden omgeleid met de operator ‘2>’:

$ ls dkjfnvkjdnf 2> errormsg

Na voltooiing van het commando wordt in het bestand errormsg een foutmelding opgenomen dat het bestand met de naam dkjfnvkjdnf niet kon worden gevonden.

Zowel stderr als stdout kunnen naar hetzelfde bestand worden omgeleid met behulp van de operator &>:

$ ls /etc dkjfnvkjdnf &amp;&gt; alloutput

Als de uitvoering is voltooid, bevat het alloutput-bestand zowel een lijst met de inhoud van de map /etc als de foutmelding over de poging om een niet-bestaand bestand in de lijst op te nemen.

1.10 Werken met pijpen in de Bash Shell

Naast het omleiden van I/O, staat de shell ook toe dat uitvoer van een commando direct als invoer in een ander commando wordt gepijpt. Een pipe-bewerking wordt bereikt door het teken ‘|’ tussen twee of meer commando’s op een opdrachtregel te plaatsen. Om bijvoorbeeld het aantal processen te tellen dat op een systeem draait, kan de uitvoer van het ps-commando worden doorgepiped naar het wc-commando:

$ ps –ef | wc –l

Er is geen limiet aan het aantal pipe-bewerkingen dat op een commandoregel kan worden uitgevoerd. Om bijvoorbeeld het aantal regels in een bestand te vinden dat de naam Smith bevat:

$ cat namesfile | grep Smith | wc –l

1.11 Aliassen configureren

Naarmate u vaardiger wordt met de shell-omgeving, zult u waarschijnlijk merken dat u vaak commando’s met dezelfde argumenten uitvoert. U zult bijvoorbeeld vaak het commando ls gebruiken met de opties l en t:

$ ls –lt

Om het typen van een commando te verminderen, is het mogelijk om een alias te maken die overeenkomt met het commando en de argumenten. Om bijvoorbeeld een alias aan te maken die de letter l gebruikt om het ls -lt commando uit te voeren, wordt het volgende statement gebruikt:

$ alias l="ls –lt"

Door l in te voeren op de commando prompt wordt het originele statement uitgevoerd.

1.12 Omgevingsvariabelen

Omgevingsvariabelen van de shell bieden tijdelijke opslag van gegevens en configuratie-instellingen. De shell zelf stelt een aantal omgevingsvariabelen in die door de gebruiker kunnen worden gewijzigd om het gedrag van de shell aan te passen. Een lijst met momenteel gedefinieerde variabelen kan worden verkregen met het commando env:

$ envSSH_CONNECTION=192.168.0.19 61231 192.168.0.28 22MODULES_RUN_QUARANTINE=LD_LIBRARY_PATHLANG=en_US.UTF-8HISTCONTROL=ignoredupsHOSTNAME=demo-pc.ebookfrenzy.comXDG_SESSION_ID=15MODULES_CMD=/usr/share/Modules/libexec/modulecmd.tclUSER=demoENV=/usr/share/Modules/init/profile.shSELINUX_ROLE_REQUESTED=PWD=/home/demoHOME=/home/demoSSH_CLIENT=192.168.0.19 61231 22SELINUX_LEVEL_REQUESTED= ...

De meest nuttige omgevingsvariabele is misschien wel PATH. Deze bepaalt in welke mappen de shell naar commando’s zoekt die op de opdrachtprompt zijn ingevoerd, en in welke volgorde dat gebeurt. De PATH omgevingsvariabele voor een gebruikersaccount op een nieuw geïnstalleerd Ubuntu systeem zal waarschijnlijk als volgt zijn geconfigureerd:

$ echo $PATH/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/ bin:/usr/local/sbin:/usr/sbin

Een andere nuttige variabele is HOME die de home directory van de huidige gebruiker specificeert. Als u bijvoorbeeld wilt dat de shell ook naar opdrachten zoekt in de scripts-map in uw thuismap, dan wijzigt u de PATH-variabele als volgt:

$ export PATH=$PATH:$HOME/scripts

De huidige waarde van een bestaande omgevingsvariabele kan worden weergegeven met het commando echo:

$ echo $PATH

U kunt uw eigen omgevingsvariabelen maken met het commando export. Bijvoorbeeld:

$ export DATAPATH=/data/files

Een handige truc om de uitvoer van een commando aan een omgevingsvariabele toe te wijzen, is het gebruik van aanhalingstekens (`) rond het commando. Om bijvoorbeeld de huidige datum en tijd toe te wijzen aan een omgevingsvariabele met de naam NOW:

$ export NOW=`date`$ echo $NOWTue Apr 2 13:48:40 EDT 2020

Als er omgevingsvariabelen of aliasinstellingen zijn die u elke keer dat u de shell-omgeving opent moet configureren, kunnen deze worden toegevoegd aan een bestand in uw thuismap met de naam .bashrc. Het volgende .bashrc bestand is bijvoorbeeld geconfigureerd om de DATAPATH omgevingsvariabele en een alias in te stellen:

# .bashrc # Source global definitionsif ; then . /etc/bashrcfi # User specific environmentPATH="$HOME/.local/bin:$HOME/bin:$PATH"export PATH # Uncomment the following line if you don't like systemctl's auto-paging feature:# export SYSTEMD_PAGER= # User specific aliases and functionsexport DATAPATH=/data/filesalias l="ls -lt"

1.13 Shell Scripts Schrijven

Tot nu toe hebben we ons uitsluitend gericht op het interactieve karakter van de Bash shell. Met interactief bedoelen we het handmatig één voor één invoeren van commando’s op de prompt en het uitvoeren ervan. In feite is dit maar een klein deel van wat de shell kan. Ongetwijfeld een van de krachtigste aspecten van de shell is de mogelijkheid om shellscripts te maken. Shell scripts zijn in wezen tekstbestanden met reeksen statements die binnen de shell omgeving kunnen worden uitgevoerd om taken uit te voeren. Naast de mogelijkheid om commando’s uit te voeren, biedt de shell veel van de programmeerconstructies zoals for en do loops en if statements die je redelijkerwijs zou verwachten te vinden in een scripttaal.

Een gedetailleerd overzicht van shell scripting valt helaas buiten het bestek van dit hoofdstuk. Er zijn echter vele boeken en webbronnen gewijd aan shell scripting die het onderwerp veel meer recht doen dan we hier ooit zouden kunnen hopen te bereiken. In deze sectie geven we daarom slechts een klein voorproefje van shell scripting.

De eerste stap in het maken van een shell script is het maken van een bestand (in dit voorbeeld noemen we het simple.sh) en het volgende als eerste regel toe te voegen:

#!/bin/sh

De #! wordt de “shebang” genoemd en is een speciale reeks tekens die aangeeft dat het pad naar de interpreter die nodig is om het script uit te voeren het volgende item op de regel is (in dit geval de sh executable die zich in /bin bevindt). Dit zou bijvoorbeeld ook /bin/csh of /bin/ksh kunnen zijn als een van beide de interpreter zou zijn die u wilt gebruiken.

De volgende stap is het schrijven van een eenvoudig script:

#!/bin/shfor i in *do echo $idone

Alles wat dit script doet is alle bestanden in de huidige directory doorlopen en de naam van elk bestand weergeven. Dit kan worden uitgevoerd door de naam van het script als argument aan sh door te geven:

$ sh simple.sh

Om het bestand uitvoerbaar te maken (zodat het niet meer aan het sh commando hoeft te worden doorgegeven) kan het chmod commando worden gebruikt:

$ chmod +x simple.sh

Als de execute bit op de permissies van het bestand is gezet, kan het direct worden uitgevoerd. Bijvoorbeeld:

$ ./simple.sh

1.14 Samenvatting

In dit hoofdstuk van Ubuntu Essentials hebben we een korte tour gemaakt door de Bash shell omgeving. In de wereld van grafische desktop omgevingen is het makkelijk te vergeten dat de ware kracht en flexibiliteit van een besturingssysteem vaak alleen kan worden benut door onder de gebruikersvriendelijke desktop interface te gaan en een shell omgeving te gebruiken. Bovendien is bekendheid met de shell een noodzaak wanneer server-gebaseerde systemen moeten worden beheerd en onderhouden waarop de desktop niet is geïnstalleerd of wanneer wordt geprobeerd een systeem te repareren dat zodanig is beschadigd dat de desktop of Cockpit interface niet meer wil opstarten.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.