Outils du site

L'humour est une langue étrangère pour certains. Il faudrait ajouter des sous-titres. [Bedos ?]

04-linux:20-bash:10-scripting

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+=(item1)

# ajouter plusieurs éléments au tableau
ticketArray+=(item1 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:55