Als je meer efficiëntie wilt bij het uitvoeren van opdrachten in de terminal, kan je verschillende opdrachten na elkaar en/of simultaan laten uitvoeren.
Wanneer twee opdrachten gescheiden door een ; worden beide opdrachten na elkaar uitgevoerd.
dany@pindabook:~> ls; sleep 1; date; sleep 1; df
Afbeeldingen bin Bureaublad Documenten Downloads Muziek onedrive OneDrive Openbaar Sjablonen Video's
vr 29 jun 2018 14:04:46 CEST
Bestandssysteem 1K-blokken Gebruikt Beschikbaar Geb% Aangekoppeld op
devtmpfs 4029160 0 4029160 0% /dev
tmpfs 4037356 0 4037356 0% /dev/shm
tmpfs 4037356 9880 4027476 1% /run
tmpfs 4037356 0 4037356 0% /sys/fs/cgroup
/dev/sda4 82042776 7444840 70387252 10% /
/dev/sda2 262144 57616 204528 22% /boot/efi
/dev/sda7 153906204 25860992 120204192 18% /usr/home/Documents
tmpfs 807468 24 807444 1% /run/user/1000
De sleep 1
opdracht doet niets anders dan 1 seconde wachten, waardoor je zeer goed merkt dat de opdrachten na elkaar worden uitgevoerd.
Soms mag de tweede opdracht, pas uitgevoerd worden als de eerste opdracht succesvol was.
dany@pindabook:~> mkdir /tmp/data && cd /tmp/data
dany@pindabook:/tmp/data>
Eerst wordt de map data aangemaakt in de /tmp map en pas als de map data succesvol is aangemaakt, wordt deze betreden. Om dit te testen herhalen we de opdracht:
dany@pindabook:/tmp/data>cd
dany@pindabook:~>mkdir /tmp/data && cd /tmp/data
mkdir: kan map ‘/tmp/data’ niet aanmaken: Bestand bestaat al dany@pindabook:~>
Door het falen van de mkdir opdracht, blijven we in dezelfde map werken. M.a.w. de cd opdracht wordt niet uitgevoerd. De logische AND operatie controleert of de voorgaande opdracht succesvol werd afgewerkt en voert de daaropvolgende opdracht pas uit als dat zo is. Het na elkaar uitvoeren van opdrachten zonder logische AND kan zware gevolgen hebben, een voorbeeld:
dany@pindabook:~>cd /tmp/data
dany@pindabook:/tmp/data>touch 1.txt; touch 2.txt; touch 3.txt
dany@pindabook:/tmp/data>ls
1.txt 2.txt 3.txt dany@pindabook:/tmp/data>cd /tmp/data1; rm -rf *
-bash: cd: /tmp/data1: Bestand of map bestaat niet dany@pindabook:/tmp/data>ls
dany@pindabook:/tmp/data>
De opdrachten cd /tmp/data1; rm -rf *
werden allebei uitgevoerd met catastrofale gevolgen.
Door het mislukken van de cd opdracht, werden alle bestanden in de huidige map gewist, wat niet de bedoeling was.
Hetzelfde voorbeeld met de logische AND operatie:
dany@pindabook:/tmp/data>touch 1.txt; touch 2.txt; touch 3.txt
dany@pindabook:/tmp/data>ls
1.txt 2.txt 3.txt dany@pindabook:/tmp/data>cd /tmp/data1 && rm -rf *
-bash: cd: /tmp/data1: Bestand of map bestaat niet dany@pindabook:/tmp/data>ls
1.txt 2.txt 3.txt dany@pindabook:/tmp/data>
De inhoud van de map werd niet verwijderd, omdat de map /tmp/data1 niet bereikbaar was.
M.a.w. de rm -rf *
opdracht werd niet uitgevoerd omdat de cd /tmp/data1
opdracht mislukt was.
In andere gevallen mag de tweede opdracht enkel uitgevoerd worden als de eerste niet succesvol was. In zo'n gevallen gebruiken we de logische OR operatie.
dany@pindabook:/tmp/data> [ -d /tmp/data1 ] || mkdir /tmp/data1
dany@pindabook:/tmp/data>
We maken de map enkel aan als deze nog niet bestaat.
De opdracht [ -d /tmp/data1 ]
test of de map /tmp/data1 bestaat, indien dit niet zo is, wordt deze aangemaakt.
dany@pindabook:/tmp/data> cat /tmp/data/1.txt > /dev/null && echo "Bestand kan geopend worden" || echo "Bestand kan niet geopend worden"
Bestand kan geopend worden dany@pindabook:/tmp/data>cat /tmp/data1/1.txt > /dev/null && echo "Bestand kan geopend worden" || echo "Bestand kan niet geopend worden"
cat: /tmp/data1/1.txt: Bestand of map bestaat niet Bestand kan niet geopend worden
Naargelang de inhoud van een bestand gelezen kan worden of niet, wordt een gepast bericht weergegeven.
Tijd om wat op te ruimen:
dany@pindabook:/tmp/data>[ -d /tmp/data1 ] && rm -r /tmp/data1 || echo "Map bestaat niet"
dany@pindabook:/tmp/data>[ -d /tmp/data1 ] && rm -r /tmp/data1 || echo "Map bestaat niet"
Map bestaat niet
Alles samen:
dany@pindabook:/tmp/data>[[ $PWD = "/tmp/data" ]] && { echo "Eerst verlaten we de map."; cd; } || { echo "Daarna kan die gewist worden."; rm -r /tmp/data/; }
Eerst verlaten we de map. dany@pindabook:~>[[ $PWD = "/tmp/data" ]] && { echo "Eerst verlaten we de map."; cd; } || { echo "Daarna kan die gewist worden."; rm -r /tmp/data/; }
Daarna kan die gewist worden. dany@pindabook:~>ls /tmp/data*
ls: kan geen toegang krijgen tot '/tmp/data*': Bestand of map bestaat niet
Let bij deze opdrachten dat opdrachten die omgeven zijn door accolades een groep vormen en dus steeds samen (na elkaar) uitgevoerd worden. De spaties na de eerste accolade en de kommapunt met spatie voor de afsluitende accolade zijn verplicht.
Om verschillende opdrachten tegelijkertijd uit te voeren, moet je ze in de achtergrond opstarten. Of m.a.w. de opdrachten parallel starten.
dany@pindabook:~>sleep 60 &
[1] 3699 dany@pindabook:~>sleep 120 &
[2] 3725 dany@pindabook:~>sleep 90 &
[3] 3726 dany@pindabook:~>jobs
[1] Wordt uitgevoerd sleep 60 & [2]- Wordt uitgevoerd sleep 120 & [3]+ Wordt uitgevoerd sleep 90 &
De ampersand na de sleep opdrachten zorgt ervoor dat deze in de achtergrond opgestart worden.
Dat merk je meteen doordat de prompt onmiddellijk terug verschijnt waardoor je een tweede en zelfs een derde (enz.) opdracht in de achtergrond kunt opstarten.
Met de jobs
opdracht kan je opvragen welke opdrachten nog op de achtergrond werken en welke reeds afgewerkt zijn.
dany@pindabook:~> jobs
[1] Klaar sleep 60
[2]- Klaar sleep 120
[3]+ Klaar sleep 90
Ook in scripts kan je dit gebruiken om bijvoorbeeld functies parallel te starten.
#!/bin/bash # Onze op de achtergrond werkende functie achtergrond(){ echo "Doorloop $1..." sleep 1 } # 5 keer uitvoeren for i in {1..5} do achtergrond $i & # Voer een functie in de achtergrond uit done ## Alle achtergrondfuncties worden uitgevoerd ## met wait wachten we tot alle achtergrondfuncties voltooid zijn ## daarna krijg je het bericht Klaar wait echo "Klaar"
Bij het uitvoeren merk je enkel een vertraging na het starten van de vijf parallelle functies.
dany@pindabook:~>chmod +x achtergrond.sh
dany@pindabook:~>./achtergrond.sh
Doorloop 1... Doorloop 2... Doorloop 3... Doorloop 5... Doorloop 4... Klaar
Om verschillende bestanden in een tekstbestand (lijst.txt) parallel met wget te downloaden. Een voorbeeldlijst:
https://images.wallpaperscraft.com/image/vase_letter_flowers_123287_1920x1080.jpg https://images.wallpaperscraft.com/image/jackal_grass_dark_123286_1920x1080.jpg https://images.wallpaperscraft.com/image/pier_sunset_lake_123285_1920x1080.jpg https://images.wallpaperscraft.com/image/drops_glass_surface_123284_1920x1080.jpg https://images.wallpaperscraft.com/image/mountains_stones_tourist_123283_1920x1080.jpg https://images.wallpaperscraft.com/image/film_negative_glare_123282_1920x1080.jpg https://images.wallpaperscraft.com/image/woman_magician_magic_123280_1920x1080.jpg https://images.wallpaperscraft.com/image/poppies_field_sunset_123279_1920x1080.jpg https://images.wallpaperscraft.com/image/monkey_primate_branch_123278_1920x1080.jpg https://images.wallpaperscraft.com/image/headphones_audio_style_123277_1920x1080.jpg https://images.wallpaperscraft.com/image/trees_bw_branches_123276_1920x1080.jpg https://images.wallpaperscraft.com/image/man_forest_smoke_123275_1920x1080.jpg
Om ook het laatste bestand te downloaden, moet deze lijst eindigen met een lege regel. En het parallel downloadscript:
#!/bin/bash # De download functie achtergrond(){ wget -q "$1" } while IFS= read -r url do achtergrond "$url" & done < lijst.txt wait echo "Alle bestanden zijn binnen."
Bij het uitvoeren van het script, krijgen we:
dany@pindabook:~>chmod +x wget_parallel.sh
dany@pindabook:~>./wget_parallel.sh
Alle bestanden zijn binnen. dany@pindabook:~>ls -l *.jpg
-rw-r--r-- 1 dany users 953372 28 jun 15:05 drops_glass_surface_123284_1920x1080.jpg -rw-r--r-- 1 dany users 901171 28 jun 14:45 film_negative_glare_123282_1920x1080.jpg -rw-r--r-- 1 dany users 770111 28 jun 14:30 headphones_audio_style_123277_1920x1080.jpg -rw-r--r-- 1 dany users 404783 28 jun 15:10 jackal_grass_dark_123286_1920x1080.jpg -rw-r--r-- 1 dany users 828167 28 jun 14:25 man_forest_smoke_123275_1920x1080.jpg -rw-r--r-- 1 dany users 816218 28 jun 14:35 monkey_primate_branch_123278_1920x1080.jpg -rw-r--r-- 1 dany users 974004 28 jun 14:50 mountains_stones_tourist_123283_1920x1080.jpg -rw-r--r-- 1 dany users 880438 28 jun 15:05 pier_sunset_lake_123285_1920x1080.jpg -rw-r--r-- 1 dany users 1182467 28 jun 14:40 poppies_field_sunset_123279_1920x1080.jpg -rw-r--r-- 1 dany users 1437145 28 jun 14:30 trees_bw_branches_123276_1920x1080.jpg -rw-r--r-- 1 dany users 815417 28 jun 15:10 vase_letter_flowers_123287_1920x1080.jpg -rw-r--r-- 1 dany users 663532 28 jun 14:45 woman_magician_magic_123280_1920x1080.jpg
Hoewel de ingebouwde bash mogelijkheden om functies en opdrachten op de achtergrond uit te voeren voor de meeste toepassingen zullen volstaan, zullen sommige ontwikkelaars tegen beperkingen oplopen. Voor wie meer wil, is er GNU parallel. De installatie van GNU parallel verloopt in openSUSE Leap 15 als volgt:
dany@pindabook:~>parallel
If 'parallel' is not a typo you can use command-not-found to lookup the package that contains it, like this: cnf parallel dany@pindabook:~>cnf parallel
Het programma 'parallel' kan gevonden worden in de volgende pakketten: * gnu_parallel [ pad: /usr/bin/parallel, installatiebron: zypp (repo-oss) ] * moreutils-parallel [ pad: /usr/bin/parallel, installatiebron: zypp (repo-oss) ] Try installing with: sudo zypper installdany@pindabook:~> sudo zypper install gnu_parallel
[sudo] wachtwoord voor root: Gegevens van opslagruimte laden... Lezen van geïnstalleerde pakketten... Pakketafhankelijkheden oplossen... Het volgende NIEUWE pakket zal worden geïnstalleerd: gnu_parallel 1 nieuw te installeren pakket. Totale downloadgrootte: 282,4 KiB. Reeds in de cache: 0 B. Na de bewerking zal aanvullend 650,8 KiB worden gebruikt. Doorgaan? [j/n/...? alle opties tonen] (j): pakket gnu_parallel-20180422-lp150.1.1.noarch wordt opgehaald (1/1), 282,4 KiB (650,8 KiB uitgepakt) Ophalen: gnu_parallel-20180422-lp150.1.1.noarch.rpm .........................................................................[gereed] Controleren op conflicten tussen bestanden: .................................................................................[gereed] (1/1) Installeren van: gnu_parallel-20180422-lp150.1.1.noarch ...............................................................[gereed]
De volgende opdracht zondert de bestandsnamen uit de URL's in de lijst af en comprimeert de zo gevonden JPG-bestanden met gzip:
dany@pindabook:~>cat lijst.txt | sed 's/.*\///' | parallel gzip --best
dany@pindabook:~>ls -l *.jpg.gz
-rw-r--r-- 1 dany users 953255 28 jun 15:05 drops_glass_surface_123284_1920x1080.jpg.gz -rw-r--r-- 1 dany users 901021 28 jun 14:45 film_negative_glare_123282_1920x1080.jpg.gz -rw-r--r-- 1 dany users 769840 28 jun 14:30 headphones_audio_style_123277_1920x1080.jpg.gz -rw-r--r-- 1 dany users 403365 28 jun 15:10 jackal_grass_dark_123286_1920x1080.jpg.gz -rw-r--r-- 1 dany users 828156 28 jun 14:25 man_forest_smoke_123275_1920x1080.jpg.gz -rw-r--r-- 1 dany users 816199 28 jun 14:35 monkey_primate_branch_123278_1920x1080.jpg.gz -rw-r--r-- 1 dany users 974010 28 jun 14:50 mountains_stones_tourist_123283_1920x1080.jpg.gz -rw-r--r-- 1 dany users 880040 28 jun 15:05 pier_sunset_lake_123285_1920x1080.jpg.gz -rw-r--r-- 1 dany users 1181100 28 jun 14:40 poppies_field_sunset_123279_1920x1080.jpg.gz -rw-r--r-- 1 dany users 1423849 28 jun 14:30 trees_bw_branches_123276_1920x1080.jpg.gz -rw-r--r-- 1 dany users 814830 28 jun 15:10 vase_letter_flowers_123287_1920x1080.jpg.gz -rw-r--r-- 1 dany users 663516 28 jun 14:45 woman_magician_magic_123280_1920x1080.jpg.gz
De oplettende lezer merkt al vlug dat reeds gecomprimeerde jpg-bestanden nogmaals comprimeren weinig zin heeft. De volgende opdracht verwijderd alle gedownloade gecomprimeerde bestanden op de lijst:
dany@pindabook:~> for f in `cat lijst.txt`; do rm `basename ${f}.gz`; done;
Het parallel downloaden van de bestanden opgesomd in lijst.txt met de parallel opdracht:
dany@pindabook:~>cat lijst.txt | parallel -j 4 wget -q {}
dany@pindabook:~>ls -l *.jpg
-rw-r--r-- 1 dany users 953372 28 jun 15:05 drops_glass_surface_123284_1920x1080.jpg -rw-r--r-- 1 dany users 901171 28 jun 14:45 film_negative_glare_123282_1920x1080.jpg -rw-r--r-- 1 dany users 770111 28 jun 14:30 headphones_audio_style_123277_1920x1080.jpg -rw-r--r-- 1 dany users 404783 28 jun 15:10 jackal_grass_dark_123286_1920x1080.jpg -rw-r--r-- 1 dany users 828167 28 jun 14:25 man_forest_smoke_123275_1920x1080.jpg -rw-r--r-- 1 dany users 816218 28 jun 14:35 monkey_primate_branch_123278_1920x1080.jpg -rw-r--r-- 1 dany users 974004 28 jun 14:50 mountains_stones_tourist_123283_1920x1080.jpg -rw-r--r-- 1 dany users 880438 28 jun 15:05 pier_sunset_lake_123285_1920x1080.jpg -rw-r--r-- 1 dany users 1182467 28 jun 14:40 poppies_field_sunset_123279_1920x1080.jpg -rw-r--r-- 1 dany users 1437145 28 jun 14:30 trees_bw_branches_123276_1920x1080.jpg -rw-r--r-- 1 dany users 815417 28 jun 15:10 vase_letter_flowers_123287_1920x1080.jpg -rw-r--r-- 1 dany users 663532 28 jun 14:45 woman_magician_magic_123280_1920x1080.jpg
Of met:
dany@pindabook:~>for f in `cat lijst.txt`; do rm `basename ${f}`; done;
dany@pindabook:~>parallel -j 4 wget -q {} < lijst.txt
dany@pindabook:~>ls -l *.jpg
-rw-r--r-- 1 dany users 953372 28 jun 15:05 drops_glass_surface_123284_1920x1080.jpg -rw-r--r-- 1 dany users 901171 28 jun 14:45 film_negative_glare_123282_1920x1080.jpg -rw-r--r-- 1 dany users 770111 28 jun 14:30 headphones_audio_style_123277_1920x1080.jpg -rw-r--r-- 1 dany users 404783 28 jun 15:10 jackal_grass_dark_123286_1920x1080.jpg -rw-r--r-- 1 dany users 828167 28 jun 14:25 man_forest_smoke_123275_1920x1080.jpg -rw-r--r-- 1 dany users 816218 28 jun 14:35 monkey_primate_branch_123278_1920x1080.jpg -rw-r--r-- 1 dany users 974004 28 jun 14:50 mountains_stones_tourist_123283_1920x1080.jpg -rw-r--r-- 1 dany users 880438 28 jun 15:05 pier_sunset_lake_123285_1920x1080.jpg -rw-r--r-- 1 dany users 1182467 28 jun 14:40 poppies_field_sunset_123279_1920x1080.jpg -rw-r--r-- 1 dany users 1437145 28 jun 14:30 trees_bw_branches_123276_1920x1080.jpg -rw-r--r-- 1 dany users 815417 28 jun 15:10 vase_letter_flowers_123287_1920x1080.jpg -rw-r--r-- 1 dany users 663532 28 jun 14:45 woman_magician_magic_123280_1920x1080.jpg
Dit bewijst nogmaals dat wie in een terminal werkt, efficiënt en nauwkeurig werkt. De mogelijkheden van terminalopdrachten kennen geen grenzen, ons toepassingsvermogen misschien wel.