test commando

getallen

-eq = gelijk aan
-ne <> niet gelijk aan
-gt > groter dan
-ge >= groter of gelijk aan
-lt < kleiner dan
-le <= kleiner of gelijk aan
      

strings


-z string1  = 0 Heeft string1 de lengte 0?
-n string1
string1
 <> 0 Heeft string1 een lengte ongelijk 0?
string1 = string2 string1 = string2 zijn de strings gelijk?
string1 != string2 string1 <>string2 zijn de strings ongelijk?


files

-b block-special file?
-c character-special file?
-e bestaat file?
-d bestaat file en is het een directorie?
-f bestaat file en is het regular file?
-L
-h
bestaat file en is het symbolic link?
-r bestaat file en mag ik het lezen
-w heb ik schrijfrechten op de file (of moet het zijn bestaat de file en heb ik schrijfrechten)
-x heb ik execute rechten voor deze file (of moet het zijn bestaat de file en heb ik execute-rechten)
-g bestaat file en is set-gid bit aan
-u bestaat file en staat uid-bit aan
-s bestaat file en is lengte >0
-o bestaat de file en ben ik owner
-G bestaat de file en behoort hij tot mijn groep

Logische operatoren bij test
-a        Logische and
-o        Logische or
!           Logische not
\(   \)    stukken groeperen



test ....
[ .. ]
[[ expressie ]]

Selectie commando's
commando uitslag exit code
grep tekst gevonden 0
tekst niet gevonden 1


Selectie commandoExit waarde <cmd1>wordt uitgevoerd
<cmd1> && <cmd2> = 0 => <cmd2>
<cmd1> || <cmd2> <> 0=> <cmd2>

if
if voorwaarde
then
else
fi

of

if voorwaarde ; then .... ; else  .....; fi

case
case <opties> in
<optie 1> )<acties>;;
<optie 2>|<opties 3> )<acties die voor zowel optie 2 als optie 3 moet worden uitgevoerd>;;
<optie 4> )<acties>;<acties>;;
*) )<acties voor als er een onbekend opties is>;;
esac

Loop commando's


while
while voorwaarde do; actie;done

of
while voorwaarde
do
acties
done

for
for heeft in voordeel. Mocht je bij ...... een lijst hebben die leeg is dan wordt de for lus niet doorlopen. Heeft ook als voordeel dat je bij vergelijkingen in de lus geen rekening hoeft te houden dat i leeg is.
for i in ...... ; do < commando('s)>;done
of
for i in ......
do
commandos
done

Functie en scope
function <functienaam> { commands; }

of

function <functienaam>
{
  commands
}

Als een variabele zonder typeset wordt aangemaakt (gewoon een waarde toekennen) dan is het een globale variabele. Maakt niet uit of dit gebeurt in een geneste functie of niet.
een typeset maakt een definitie van een variabele lokaal. Wordt de typeset binnen een functie gedaan dan is de variabele alleen bekend binnen deze functie of andere functie aangeroepen functies.
Een functie kan altijd worden aangeroepen. Ook als een functie wordt gedefinieerd binnen een nesting en vervolgens van buiten de nesting wordt aangeroepen.
Misschien een open deur. Er geldt op moment van aanroepen van een functie de dan bekende variabelen.

https://www.gnu.org/software/bash/manual/html_node/Shell-Functions.html
https://linuxize.com/post/bash-functions

Variabelen / Parameters

Positionele parameters

$* en $@ geven beide alle meegegeven parameters.

Met shift worden alle positionele parameters 1 plek naar links geschoven.

$*, een tekenreeks met de waarde van alle parameters
$#, het aantal positionele parameters
$@, alle positionele parameters (array)
$?, de laatste exit-status in de shell
If the $string parameter is "*" or "@", then this extracts a maximum of $length positional parameters, starting at $position.
echo ${*:2} # Echoes second and following positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters, starting at second.

Initialisatie

typeset

Indirect expansion
je krijgt niet de waarde van de genoemde parameter maar de waarde van de parameter waar de genoemde parameter naar verwijst.
Voorbeeld :
A=1;B=2;C=3
for i in A B C;do echo "${i} = ${!i};done
output:
A = 1
B = 2
C = 3

tekst

LET OP: Het is verstandig om tekst variabelen in parameterlijsten en vergelijkingen tussen &qout;´s te zetten voor het geval dat ze leeg zijn. Je kunt dan de volgende problemen krijgen.

String Manipulaties

 xx=1/2/3/4/5

Links weghalen (#) commando Voorbeeld output
kortste gedeelte (#) ${xx#patroon} ${xx#*/} 2/3/4/5
langste gedeelte (##) ${xx##patroon} ${xx##*/} 5
Rechts weghalen (%)
kortste gedeelte (%) ${xx%patroon} ${xx%/*} 1/2/3/4
langste gedeelte (%%) ${xx%%patroon} ${xx%%/*} 1
Lengte bepalen ${#xx} 9
`expr lenght $xx`
`expr "$xx":´.*´
Lengte van substring


Lengte bepalen 9
${#xx}
expr lenght $xx
expr "$xx":´.*´
Lengte van passende substring
expr match "$string" '$substring'
expr "$string" : '$substring'
Index
expr index $string $substring
Substring Extraction
${string:position}
${string:position:length} echo ${stringZ:7:3}
echo ${stringZ:(-4)}
expr substr $string $position $length
expr match "$string" '\($substring\)'
expr match "$string" '.*\($substring\)'
expr "$string" : '.*\($substring\)'
Substring Replacement
${string/substring/replacement}
${string//substring/replacement}
${string/#substring/replacement}
${string/%substring/replacement}

https://devhints.io/bash

Getallen

Rekenen met natuurlijke getallen (integers)
let x=x+1
LET OP : let kent maar 1 argument daarom moet alles achter let aan elkaar geschreven worden.
expr
$((..)) of ((..))
$((..))

((..))

Rekenen met floating point getallen

typeset -i

href="https://tldp.org/LDP/abs/html/special-chars.html"
https://www.cyberciti.biz/faq/bash-for-loop/
https://www.quora.com/In-shell-scripting-why-do-we-need-double-parentheses-when-we-need-to-enclose-some-expression
https://tldp.org/LDP/abs/html/dblparens.html
https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs


Debugging
output checken op verborgen /niet zichtbare karakters
cat -vet
of middels od

set -xv

Arrays
Kornshell:
Kent alleen 1 dimensionale arrays
Maximaal 1024 rijen per array
Een indexed array hoeft niet apart gedeclareerd te worden.

Bash:
Kent alleen 1 dimensionale arrays. Deze kunnen ook associated arrays zijn. Dat betekent dat de index geen getal is maar een verwijzing
Er is in principe geen maximum aan het aantal rijen.
Een associated array moet VERPLICHT eerst gedeclareerd worden voordat er waardes toegekend mogen worden.

De index variabele hoeft niet verplicht tussen ${} maar mag wel. Geldt volgens mij voor zowel een toekenning als wanneer een waarde uit het array wordt gebruikt.
Array_Met_Index()
{
  Index=0
  while read Line ; do
    Bash_Ar[Index]="${Line}"
    ((Index++))
  done < ${File}
}

Array_Zonder_Index()
{
  while read Line ; do
    Bash_Ar+=("${Line}")
  done < ${File}
}
declare -A Kleur
Kleur[ijsbeer]="wit"
Kleur[grizzly]="bruin"
Kleur[kodiak]="zwart"
Kleur=([ijsbeer]=wit [grizzly]=bruin [kodiak]=zwart)
echo ${Kleur[grizzly]}
bruin
echo "${Kleur[@]}"
wit zwart bruin
echo "${!Kleur[@]}"
ijsbeer kodiak grizzly
echo "${#Kleur[@]}"
3

Bash_Ar=(00 10 20 30 40 50 60 70 80 90)
echo ${Bash_Ar[@]}
00 10 20 30 40 50 60 70 80 90
echo "${!Bash_Ar[@]}"
0 1 2 3 4 5 6 7 8 9
echo "${#Bash_Ar[@]}"
10

NB: De regel : Bash_Ar[Index]="${Line}"
Mag ook geschreven worden als : Bash_Ar[${Index}]="${Line}"
Bij een toekenning aan een array mag de index variabele zowel met als zonder ${} om de index variabele. Netter is denk om zonder te doen gezien het feit dat hij links van de = staat.

NB 2: Bij een indexed array mag net zo als bij een associated array gebruik gemaakt worden van [index]=<waarde>. De volgende waarde wordt geplaatst op index+1. Zie onderstaand voorbeeld.
Je ziet bij indexen dat de indexen opschuiven
Toekenning
Bash_Ar=(00 [3]=10 20 30 40 50 60 70 80 90)
Printe alle waardes
echo ${Bash_Ar[@]}
00 10 20 30 40 50 60 70 80 90
Print alle indexen
echo "${!Bash_Ar[@]}"
0 3 4 5 6 7 8 9 10 11
Print aantal elementen
echo "${#Bash_Ar[@]}"
10
Richtlijnen voor shell programmeren : https://www.oracle.com/technetwork/articles/servers-storage-dev/kornshell-1523970.html
KSH script basics : https://www.well.ox.ac.uk/~johnb/comp/unix/ksh.html#functions


Test
test, [ .. ] [[ .. ]]

Commando-substitutie
$(..), `..`

Compound statement / Samengesteld commando
( .. ), { ..; }
LET OP: bij de {} is een ; of een nieuwe regel verplicht

Integer rekenen
$(( .. )), (( .. ))
Verschil tussen $(( .. )), (( .. ))
$(( .. )) geeft de waarde van de berekening terug. (( .. )) niet.
Wil je bijvoorbeeld alleen een teller ophogen dan moet (( .. )) anders krijg je dat de waarde van de teller als een commando wordt gezien en getallen kent hij niet als commando

https://askubuntu.com/questions/606378/when-to-use-vs-in-bash
https://unix.stackexchange.com/questions/286209/using-expr
http://old.linux800.be/lx-scr-info-rekenen.php
bc :
https://www.geeksforgeeks.org/bc-command-linux-examples/