Results 1 to 8 of 8

Thread: Korte uitleg: Handige gereedschappen bij shell scripts.

  1. #1
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    25,143

    Default Korte uitleg: Handige gereedschappen bij shell scripts.

    Korte uitleg: Handige gereedschappen bij shell scripts.

    Bij het schrijven van shell scrips (en we nemen bash als voorbeeld), blijkt dat aan de ene kant veel programmeertaal constructies zoals if ... then ... else en loops, beschikbaar zijn, maar veel hulproutines, zoals andere talen die ter beschikking stellen, ontbreken. Dat komt omdat allerlei handige akties door losse programma's (gereedschappen/tools) kunnen worden gedaan. Dit alles volgens het Unix principe: maak geen honderdkoppige monsters, maar maak een tool dat één ding kan en dan heel erg goed kan.

    Het nadeel hiervan is dat die tools niet in de man pagina van bash staan. Ze hebben natuurlijk wel ieder zelf een man pagina, maar hoe weet je dat ze bestaan en waar ze goed voor zijn. Daarom wil ik hier een lijstje presenteren van tools en waar ze handig voor zijn. Je moet daarbij bedenken dat veel van deze tools bij verstek lezen van stdin en uitvoeren naar stdout. Ze zijn dus bij uitstek geschikt om met pipes aan elkaar te koppelen. Ik zal daar ook voorbeelden van geven.

    Vergeet niet om de man pagina van een tool te bestuderen. Ik geeft hieronder alleen hints. Je zult zelf de details moeten uitvinden.

    SHELL BUILTIN COMMANDS

    Deze zijn eigenlijk niet het onderwerp van deze Korte uitleg omdat ze in de man pagina van bash zijn te vinden. Maar bekijk die lijst dan ook eens. Er zitten o.a. de commando's in om van de terminal (stdin) te lezen (read en readarray) en er (stdout) naar te schrijven (echo en printf). En met redirect en pipes zijn dat dus de meest gebruikte commando's om gegevens naar en van je script te sturen.

    grep

    Leest een aantal regels tekst en filtert deze op inhoud.
    Voorbeeld: om uit de mounttabel alleen die regels te filteren die een mount van een echt mass-storage apparaat geven:
    Code:
    henk@boven:~> mount | grep '^/dev'
    /dev/sda2 on / type ext4 (rw,relatime,data=ordered)
    /dev/sda3 on /home type ext4 (rw,relatime,data=ordered)
    henk@boven:~>
    Let op het "pattern" dat hier wordt gebruikt. Het wordt uitgebreid beschreven in man grep onder Regular Expressions. Veel mogelijkheden, en niet altijd makkelijk te overzien. Ook is het het beste om het door quoting van shell interpretatie af te schermen.

    Nog een combinatie met een bash loop:
    Code:
    henk@boven:~> mount | grep '^/dev' | while read DEV X MP X; do echo $MP "ligt op" $DEV; done
    / ligt op /dev/sda2
    /home ligt op /dev/sda3
    henk@boven:~>
    tr

    Vervangt of verwijdert tekens uit text:
    Code:
    henk@boven:~> mount | grep '^/dev' | tr -d '()' | tr ',' ' '
    /dev/sda2 on / type ext4 rw relatime data=ordered
    /dev/sda3 on /home type ext4 rw relatime data=ordered
    henk@boven:~
    cut

    Knipt stukjes uit regels en laat die zien. Het volgende laat de velden 3 en 5 zien waarbij de velden gescheiden zijn door spaties:
    Code:
    henk@boven:~/test> mount |  grep '^/dev' | cut -d ' ' -f 3,5
    / ext4
    /home ext4
    henk@boven:~/test>
    head / tail

    Laat het begin (head) of het eind (tail) van een aantal regels zien. Het aantal kun je opgeven, dus voor de laatste vijf regels van dmesg:
    Code:
    henk@boven:~/test> dmesg | tail -n 5
    [   50.896609] Bluetooth: BNEP filters: protocol multicast
    [   50.896628] Bluetooth: BNEP socket layer initialized
    [   60.757940] fuse init (API version 7.22)
    [  599.860654] perf samples too long (2506 > 2500), lowering kernel.perf_event_max_sample_rate to 50000
    [ 3367.565707] perf samples too long (5003 > 5000), lowering kernel.perf_event_max_sample_rate to 25000
    henk@boven:~/test>
    Handig is ook een + voor het aantal regels. Dat geeft de eerste regel van waar tot het eind wordt doorgegeven. Daarmee kun je dus de kopregel(s) uit een lijst verwijderen:
    Code:
    henk@boven:~/test> ps
      PID TTY          TIME CMD
    23087 pts/2    00:00:00 bash
    23674 pts/2    00:00:00 ps
    henk@boven:~/test> ps | tail -n +2
    23087 pts/2    00:00:00 bash
    23677 pts/2    00:00:00 ps
    23678 pts/2    00:00:00 tail
    henk@boven:~/test>
    wc

    Telt het aantal regels, woorden en tekens dat langskomt. Dus:
    Code:
    henk@boven:~/test> wc -l /etc/passwd
    35 /etc/passwd
    henk@boven:~/test>
    laat zien dat er 35 gebruikers in /etc/passwd zijn geconfigureerd.

    sed

    De stream editor. In tegenstelling tot een interactieve editor voert deze editor de opgegeven wijzigingscommando's uit op de langskomende regels.
    Code:
    henk@boven:~/test> sed -e 's/#.*$//' -e '/^[       ]*$/d' /etc/resolv.conf
    search xs4all.nl
    nameserver 194.109.6.66
    nameserver 194.109.9.99
    nameserver 194.109.104.104
    henk@boven:~/test>
    Hier zijn twee sed akties (aangegeven door -e):
    1. In iedere regel worden alle strings die beginnen met een # tot aan het eind van de regel weggegooid.
    2. Iedere regel die alleen spaties en tabs bevat (er staat en spatie en een tab tussen de [ en de ]) wordt verwijderd.


    Let op. Er zijn wel veel configuratiebestanden waarin een # commentaar aangeeft, maar dat is beslist niet altijd zo!

    Er zijn veel mogelijkheden in sed om regels te selecteren en om akties op de geselecteerde regels uit te voeren. Neem de tijd om de documentatie te bekijken en dingen uit te proberen.

    awk

    Nog veel uitgebreider is awk. Eigenlijk is dit een complete programmeertaal om akties op regels uit te voeren. Sommigen zweren erbij omdat het "alles kan". Als je er eenmaal handig in bent is kennelijk de neiging om awk dan ook voor alles te gebruiken, ook in plaats van de hierboven genoemde gereedschappen. En zelf in plaats van veel shell constructies.

    Een kwestie van smaak.

    sort

    Soms is het nodig/handig om regels te sorteren. Het programma sort heeft natuurlijk een logische naam en waarschijnlijk had je al uit jezelf geprobeerd of dat bestaat als je het nodig had. Maar ik vermeld het toch maar.

    Behalve simpel op ASCII sorteren kan ook op velden gesorteerd worden en zijn vele combinaties mogelijk.

    Handig is vaak ook de -u optie, die als er meer regels hetzelfde zijn, er slechts één doorlaat.

    cmp

    Vergelijkt twee bestanden en geeft de verschillen aan. In een script is het handig omdat de returncode 0 is bij gelijkheid en 1 bij ongelijkheid. Gebruik je dan de -s optie om de uitvoer te onderdrukken.

    Er is een vergelijkbaar tool diff, maar dat is beter geschikt om interactief verschillen in text bestanden te vinden (bijv. waarin verschillen twee versies van een configuratie bestand).
    Last edited by hcvv; 20-Oct-2016 at 02:41.
    Henk van Velden

  2. #2
    Join Date
    Jun 2008
    Location
    Groningen, Netherlands
    Posts
    19,846
    Blog Entries
    14

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Ik heb onlangs pv (pipeviewer) herontdekt. Voorheen maakte ik mijn USB installatie sticks zo:
    Code:
    dd if=openSUSE-Versie.iso of=/dev/sdX bs=4M
    Dat heeft als nadeel dat je op geen enkel moment kunt zien "hoever-ie er mee is".
    Nu doe ik 't zo:
    Code:
    pv openSUSE-Versie.iso | dd of=/dev/sdX
    Doordat er in openSUSE een aantal opties default aan staan, zie ik niet alleen een simpele voortgangs"balk", maar ook de snelheid waarmee naar USB geschreven wordt en een ETA (Expected Time of Arrival .).


    En awk, da's voor mij vroeger onder UNIX. Het is waar, Henk, met awk kan alles. Jaren niet gebruikt, maar ik vond 't makkelijker om wat complexere dingen met awk te doen dan met bijv. sed.
    ° Appreciate my reply? Click the star and let me know why.

    ° Perfection is not gonna happen. No way.

    https://en.opensuse.org/openSUSE:Board#Members
    http://en.opensuse.org/User:Knurpht
    http://nl.opensuse.org/Gebruiker:Knurpht

  3. #3
    Join Date
    Jun 2008
    Location
    Groningen, Netherlands
    Posts
    19,846
    Blog Entries
    14

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Nog één: diff. Heel handig als je het veschil tussen bestanden wilt zien, of de uitkomst ervan wilt gebruiken, bijv
    Code:
    diff log-van-gisteren log-van-eergisteren > gisteren-gedaan
    Het commando zet het verschil tussen een logbestand van gisteren en het logbestand van eergisteren in het bestand gisteren-gedaan.
    ° Appreciate my reply? Click the star and let me know why.

    ° Perfection is not gonna happen. No way.

    https://en.opensuse.org/openSUSE:Board#Members
    http://en.opensuse.org/User:Knurpht
    http://nl.opensuse.org/Gebruiker:Knurpht

  4. #4
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    25,143

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Quote Originally Posted by Knurpht View Post
    Nog één: diff. Heel handig als je het veschil tussen bestanden wilt zien, of de uitkomst ervan wilt gebruiken, bijv
    Code:
    diff log-van-gisteren log-van-eergisteren > gisteren-gedaan
    Het commando zet het verschil tussen een logbestand van gisteren en het logbestand van eergisteren in het bestand gisteren-gedaan.
    Omdat ik voornamelijk tools heb gegeven die binnen scripts handig zijn te gebruiken, heb ik voor cmp en niet voor diff gekozen. Misschien moet ik diff erbij vermelden, maar dan niet direct voor gebruik in scripts.
    Henk van Velden

  5. #5
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    25,143

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Quote Originally Posted by Knurpht View Post
    Ik heb onlangs pv (pipeviewer) herontdekt. Voorheen maakte ik mijn USB installatie sticks zo:
    Code:
    dd if=openSUSE-Versie.iso of=/dev/sdX bs=4M
    Dat heeft als nadeel dat je op geen enkel moment kunt zien "hoever-ie er mee is".
    Nu doe ik 't zo:
    Code:
    pv openSUSE-Versie.iso | dd of=/dev/sdX
    Doordat er in openSUSE een aantal opties default aan staan, zie ik niet alleen een simpele voortgangs"balk", maar ook de snelheid waarmee naar USB geschreven wordt en een ETA (Expected Time of Arrival .).


    En awk, da's voor mij vroeger onder UNIX. Het is waar, Henk, met awk kan alles. Jaren niet gebruikt, maar ik vond 't makkelijker om wat complexere dingen met awk te doen dan met bijv. sed.
    pv is kennelijk leuk voor interactief gebruik (en voor mensen die niet gewoon iets kunnen starten en dan iets leuks gaan doen tot het klaar is ), mar pv maakt het volgens mij juist ongeschikt on in een script te gebruiken. En daar zijn de genoemde tools voor.
    Henk van Velden

  6. #6
    Join Date
    Jun 2008
    Location
    Groningen, Netherlands
    Posts
    19,846
    Blog Entries
    14

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    En natuurlijk hoort echo er ook bij. Toen ik begon met scripten leerde ik om eerst maar elk commando ook te laten echoën. Later nog veel gebruikt, ook om bijv. te loggen
    Een voorbeeldje in een primitief backup script:
    Code:
    #! /bin/bash
    echo "Starten backup"
    echo "Backup gestart" >> /var/log/backup`date`
    cp -r -v -p /home /disk/home-backup
    echo "Backup klaar"
    echo "Backup klaar >> /var/log/backup`date`
    stuurt tekst zowel naar 't scherm als naar een logbestand met een datumtoevoeging. Nooit zo gebruiken, kijk eerst met "man date" hoe je 't een beetje netjes kunt doen.
    ° Appreciate my reply? Click the star and let me know why.

    ° Perfection is not gonna happen. No way.

    https://en.opensuse.org/openSUSE:Board#Members
    http://en.opensuse.org/User:Knurpht
    http://nl.opensuse.org/Gebruiker:Knurpht

  7. #7
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    25,143

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Quote Originally Posted by Knurpht View Post
    En natuurlijk hoort echo er ook bij. Toen ik begon met scripten leerde ik om eerst maar elk commando ook te laten echoën. Later nog veel gebruikt, ook om bijv. te loggen
    Een voorbeeldje in een primitief backup script:
    Code:
    #! /bin/bash
    echo "Starten backup"
    echo "Backup gestart" >> /var/log/backup`date`
    cp -r -v -p /home /disk/home-backup
    echo "Backup klaar"
    echo "Backup klaar >> /var/log/backup`date`
    stuurt tekst zowel naar 't scherm als naar een logbestand met een datumtoevoeging. Nooit zo gebruiken, kijk eerst met "man date" hoe je 't een beetje netjes kunt doen.
    Ik heb ook echo niet opgenomen omdat het gewoon een onderdeel (build-in) van bash is. Het uitgangspunt van de ze Korte uitleg is om dingen aan te reiken die NIET in de bash man page zijn te vinden, ook niet zo logisch van naam zijn dat je ze niet onmiddelijk vindt met man logische-naam (maar ik heb sort, volgens mij zo'n logische naam toch gemoemd). Bovendien moeten ze gereedschap zijn dat hard nodig is om shell scripts (die vaak over tekstverwerking gaan) te kunnen schrijven. Net zoals je in een technisch-wetenschappelijke programmeertaal subroutines voor sinus, cosinus, enz. nodig hebt.

    Ik zit nu te broeden op een Korte uitleg met commando's om informatie te krijgen over hardware en software op je systeem. Ook daarvoor geldt: volgens je gevoel moeten ze bestaan, maar hoe zouden ze die dingen genoemd hebben? Als je de naam eenmaal weet kom je met de man page wel verder. Maar wat is de naam??????????
    Henk van Velden

  8. #8
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    25,143

    Default Re: Korte uitleg: Handige gereedschappen bij shell scripts.

    Ik heb enkele wijzigingen aangebracht:
    • verwezen naar de sectie SHEL BUILTIN COMMANDOS (en dus naar read en echo);
    • diff vermeld als alternatief voor cmp speciaal voor text bestanden (hoewel diff bij niet textbestanden ongeveer reageert zoals cmp) en voor interactief gebruik.
    Henk van Velden

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •