Outils du site

Il y a des fanatiques de sang-froid: ce sont les juges qui condamnent la mort ceux qui n'ont d'autre crime que de ne pas penser comme eux; et ces juges-là sont d'autant plus coupables, d'autant plus dignes de l'exécration du genre humain, que, n'étant pas dans un accés de fureur comme les Clément, les Chastel, les Ravaillac, les Damiens, il semble qu'ils pourraient écouter la raison. [Voltaire]

04-linux:20-bash:10-scripting

Ceci est une ancienne révision du document !


Scripting

Parametres

http://www.commentcamarche.net/faq/5444-bash-les-parametres

Variables spéciales
$0 Contient le nom du script tel qu'il a été invoqué
$* L'ensembles des paramètres sous la forme d'un seul argument
$@ L'ensemble des arguments, un argument par paramètre
$# Le nombre de paramètres passés au script
$? Le code retour de la dernière commande
$$ Le PID su shell qui exécute le script
$! Le PID du dernier processus lancé en arrière-plan

Il est possible d'affecter directement des paramètres au shell grâce à la commande set.

set param1 param2 param3

initialisera automatiquement les paramètres positionnels “$1,$2,$3” avec les valeurs “param1,param2,param3”, effaçant de ce fait les anciennes valeurs si toutefois elles existaient.

Les paramètres “#,* et @” sont mis à jours en conséquence.

$ set 1 2 voila 3
$ echo $*
1 2 voila 3
$ set a b
$ echo $*
a b

Quoting

single quotes ' ... '

La quote préserve tout le contenu. Interdit de mette une quote même avec “\” en deux quotes

$ echo -e '$var = $* '
$var = $*

double quotes " ... "

les doubles quotes “ … ” préservent tout le contenu à l'exception des caractères ‘$’, ‘`’ et ‘\’.

backquotes ` ... `

`ls` peut aussi s'écrire $(ls)

Déréférencement

“If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion.”

$ a=letter
$ letter=z
$ echo $a
letter
$ echo ${!a}
z

http://www.tldp.org/LDP/abs/html/ivr.html

Testing

Opérateur double parenthèses (( ... ))

The (( ... )) construct permits arithmetic expansion and evaluation. In its simplest form, a=$(( 5 + 3 ))

$ echo $((5+6))
11

$ a=10
$ (( t = a<45?7:11 ))
$ echo $t
7

Opérateur double crochets [[ ... ]]

L'opérateur [[ ... ]] est plus troublant que [ … ]. (Cf. http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS)

http://tldp.org/LDP/abs/html/comparison-ops.html Operators comparison

Integer comparison

Opérateurs autorisés entre [ ] : -eq, -ne, -gt, -ge, -lt, -le

Opérateurs autorisés entre (( )) : <, <=, >, >=

$ a=3
$ b=4
$ [ $a -lt $b ] && echo true
true
$ [ $a -gt $b ] && echo true

$[ $a -eq $b ] && echo true

$ [ $a -ne $b ] && echo true
true
$ (( $a < $b )) && echo true
true
$ (( $a > $b )) && echo true

Test si une variable est un entier

$ v=toto
$ [[ $v = +([0-9]) ]] && echo $v entier || echo $v pas entier
toto pas entier
$ v=3
$ [[ $v = +([0-9]) ]] && echo $v entier || echo $v pas entier
3 entier

String comparison

Opérateurs autorisés entre [] : =, ==, !=, \>, \<

Opérateurs autorisés entre [[]] : <, >, -z, -n

$ c=''
$ [[ -n $c ]] && echo c is not null
$ [[ -z $c ]] && echo c is null
c is null
The == comparison operator behaves differently within a double-brackets test than within single brackets.

[[ $a == z* ]] # True if $a starts with an “z” (pattern matching).

[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ] # File globbing and word splitting take place.

[ “$a” == “z*” ] # True if $a is equal to z* (literal matching).

Attention :

  • “=” doit être entouré d'espaces
  • Note that the “<” and “>” need to be escaped within a [ ] construct.

String manipulation

String length

${#string} ou

expr length $string

$ str="abCDefGH"
$ echo ${#str}
8
$ echo $(expr length $str)
8

Length of matching substring at beginning of string

expr match “$string” '$substring' ou

expr “$string” : '$substring'

$substring est une regexp

$ str="abCDefGH"
$ echo `expr match "$str" 'ab[A-Z]*'`
4
$ echo `expr "$str" : 'ef[A-Z]*'`  # no match at beginning
0
$ echo `expr "$str" : 'ab[A-Z]*'`  # match at beginning
4

Index

expr index $string $substring

$ str="abCDefGH"
$ echo `expr index "$str" ef`
4

String extraction

${string:position[:length]}

$ str="abCDefGH"
# Index from beginning
$ echo ${str:4}
efGH
$ echo ${str:4:2}
ef
# index from end
$ echo ${str:-4}  # not OK
abCDefGH
$ echo ${str:(-4)}
efGH
$ echo ${str: -4} 
efGH
$ echo ${str:(-4):3}
efG

Extraction depuis le début avec une regexp :

expr match “$string” '\($substring\)' ou

expr “$string” : '\($substring\)'

$ str="abCDefGH"
 $ echo `expr "$str" : '\(.*f\)'`
abCDef

Extraction depuis la fin avec une regexp :

expr match “$string” '.*\($substring\)'

expr “$string” : '.*\($substring\)'

$ str="abCDefGH"
echo `expr "$str" : '.*\(.*f.*\)'`
fGH

Remplacement de pattern

On peut remplacer un pattern une ou plusieurs fois grâce aux / :

$ echo ${var}
/etc/ssmtp/ssmtp.conf
$ echo ${var/ss/--}
/etc/--mtp/ssmtp.conf
$ echo ${var//ss/--}
/etc/--mtp/--mtp.conf

Suppression de pattern

See http://spin.atomicobject.com/2014/02/16/bash-string-maniuplation/

Les caractères spéciaux # and % permettent de supprimer des sous-chaînes de caractères :

  • # supprime la correspondance la plus courte depuis le début de la chaîne. Gauche –> droite.
  • ## supprime la correspondance la plus longue depuis le début de la chaîne. Gauche –> droite.
  • % supprime la correspondance la plus courte depuis la fin de la chaîne. Droite –> Gauche.
  • %% supprime la correspondance la plus longue depuis la fin de la chaîne. Droite –> Gauche.

Exemple :

$ echo $str
aB-Ba--AAbb
# Supprime du début de la chaîne jusqu'au premier '-' rencontré inclus.
$ echo ${str#*-}
Ba--AAbb
# Supprime du début de la chaîne jusqu'au dernier '-' rencontré inclus.
$ echo ${str##*-}
AAbb
# Supprime depuis la fin de la chaîne jusqu'au premier '-' rencontré inclus.
$ echo ${str%-*}
aB-Ba-
# Supprime depuis la fin de la chaîne jusqu'au dernier '-' rencontré inclus. 
$ echo ${str% %-*} *** Pas d'espace entre les deux '%'
aB

Formatting

Formater un nombre avec séparateur de milliers

C'est loin d'être trivial !!!

Avec SED :

$ num=4568
$ echo $num | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'
4,568
$ echo $num | sed ':a;s/\B[0-9]\{3\}\>/ &/;ta'
4 568

En positionnant la locale :

$ export LC_NUMERIC="fr_FR.UTF-8"
$  printf "%'d\n" 12345678
12 345 678
le ' ' qui apparait n'est pas un “espace”. –> peut poser problème si parsing …

Variante :

$  LC_NUMERIC=en_US printf "%'.f\n" 123456789
123,456,789

Formater une date

$ date +%F-%T
2014-09-30-11:02:44
date +%Y\/%m\/%d
2014/09/30
$ date +%Y\-%m\-%d\-%Hh%Mmn%S
2014-10-01-11h26mn53
$ date +%A\ %d\ %B\ %Y
mardi 30 septembre 2014

Formater une durée en hh:mm:ss

$ date -u -d @200 +%H:%M:%S
00:03:20

Try - Catch

Pas de “Try catch” en Bash, mais des solutions …

{ # this is my bash try block

    command1 &&
    #save your output

} || { # this is catch block
    # save log for exception 
}
if ...
else
fi

Array

# déclarer un tableau
ticketArray=()
ticketArray=(un deux trois)

# Afficher tous les élements du tableau
echo "ticketArray: ${ticketArray[@]}"

# Afficher 1 élément du tableau
echo "ticketArray[0]: ${ticketArray[0]}"

# ajouter 1 élément au tableau
ticketArray+=(NewItem)

# ajouter plusieurs éléments au tableau
ticketArray+=(NewItem1 item2 item3)

# Supprimer 1 élément du tableau
unset ticketArray(1)
echo ${ticketArray[@]}

# boucler sur le tableau
for item in "${ticketArray[@]}"
do
  echo -e " -  $item"
done

Incrément

$ var=1
$ var=$((var+1)) ; echo "var=$var"
var=2
$ ((var=var+1))  ; echo "var=$var"
var=3
$ ((var+=1)) ; echo "var=$var"
var=4
$ ((var++)) ; echo "var=$var"
var=5
$ let "var=var+1" ; echo "var=$var"
var=6
$ let "var+=1"  ; echo "var=$var"
var=7
$ let "var++" ; echo "var=$var"
var=8
(( ... )) est la commande d'évaluation arithmétique.

Commandes dans une variable

http://mywiki.wooledge.org/BashFAQ/050

L'usage de la commande eval est a limiter au maximum car elle pose des problèmes de sécurité : elle permet l'injection de code.
Dernière modification : 2019/09/14 00:54