Les fichiers pour les exercices sont à placer dans un dossier nommé
bash-parametres
(sauf mention contraire).
$1
, $2
, $3
,
…Ce sont les paramètres positionnels.
Lors de l’appel d’un programme, ils prennent les valeurs données en argument.
Par exemple, créer un fichier nommé affichage-param
et y
ajouter la ligne ‘echo $1 $2 $3’ :
$ touch affichage-param
$ chmod +x affichage-param
$ echo 'echo $1 $2 $3' >> affichage-param
Le contenu du fichier est donc:
$ cat affichage-param
echo $1 $2 $3
L’appel en passant les paramètres a
, b
et
cdef
donne:
$ ./affichage-param a b cdef
a b cdef
$1
est remplacé par le premier paramètre (ici
a
)$2
est remplacé par le deuxième paramètre (ici
b
)$3
est remplacé par le troisième paramètre (ici
cdef
)… et ainsi de suite.
Voir le chapitre Positional Parameters
dans le manuel de
bash
Illustration du problème:
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
shift
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
$ ./affichage-param a b c d e f g h i j k l m n o p q
a b c d e f g h i a0
b c d e f g h i j b0
c d e f g h i j k c0
d e f g h i j k l d0
e f g h i j k l m e0
f g h i j k l m n f0
g h i j k l m n o g0
Modifions le
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
while (( $# ))
do
echo "Nombre de param: $#"
echo $1
shift
done
Ce qui donne à l’exécution:
$ ./affichage-param a b c d e f g h i j k l m n o p q
a b c d e f g h i a0
Nombre de param: 16
b
Nombre de param: 15
c
Nombre de param: 14
d
Nombre de param: 13
e
Nombre de param: 12
f
Nombre de param: 11
g
Nombre de param: 10
h
Écrire un programme nommé convertir_param
qui prend en
paramètre une liste de fichiers .md
et qui les transforme
en fichier .html
(par exemple un fichier A.md
permet de générer un fichier A.html
)
Le programme devra respecter les contraintes suivantes:
Écrire un programme nommé txt_simple
qui permet de
générer une image d’une lettre passée en paramètre.
Le programme doit utiliser la commande convert
(ou
magick
dans les versions plus récentes) du logiciel
imagemagick
.
Les instructions sur les polices de caractères disponibles sont données ici: image manipulation - With ImageMagick, how can you see all available fonts? - Stack Overflow
Les instructions sur comment générer le texte sont données ici: Text Handling – ImageMagick Examples
Pour sélectionner aléatoirement une police de caractères:
convert -list font | grep Font: | cut -c 9- | xargs shuf -n1 -e
Écrire un programme genere_lettres
qui génère dans le
dossier caché ~/.lettres
chacune des lettres de l’alphabet
avec des polices de caractères différentes.
Utiliser la liste des polices données par la commande :
convert -list font | grep Font: | less
Chaque lettre doit avoir une police différente.
Écrire un programme genere_texte
qui génère une image
d’un texte à partir des images de lettres placées dans le dossier caché
~/.lettres
.
Le texte passé en paramètre doit être utilisé pour générer l’image, en parcourant chaque lettre du texte.
Utiliser la liste des polices données par la commande :
convert -list font | grep Font: | less
Chaque lettre doit avoir une police différente.
Les instructions comment parcourir une chaîne de caractère en bash sont données ici: How to perform a for loop on each character in a string in Bash? - Stack Overflow
Les instructions pour assembler des images côte à côte sont données ici: imagemagick - Merge Images Side by Side (Horizontally) - Stack Overflow
Il arrive parfois qu’utiliser certaines polices de caractères génère des images vides.
Déterminer une méthode pour trouver comment identifier quelles sont les polices générant des images vides.
Créer un fichier nommé image_polices
pour mettre en
application cette méthode.
Utiliser l’option -v
de la commande grep
pour filtrer les polices à utiliser dans le programme de
genere_lettres_ameliore
(qui est une amélioration du
programme genere_lettres
dans lequel les polices générant
du texte vide ne seront pas utilisées).
case
#!/bin/bash
mode_verbeux=false
while (( $# ))
do
case "$1" in
-d)
shift
dossier_a_traiter="$1"
;;
-v)
mode_verbeux=true
;;
-h)
echo "Afficher l'aide"
;;
esac
shift
done
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
On ajoute ce code pour vérifier que le paramètre
dossier_a_traiter
a été renseigné:
if [[ -z $dossier_a_traiter ]]
then
echo "ERREUR: vous devez préciser le dossier à traiter avec l'option -d" >&2
exit 2
fi
Voici le programme traiter_dossier
:
#!/bin/bash
mode_verbeux=false
while (( $# ))
do
case "$1" in
-d)
shift
dossier_a_traiter="$1"
;;
-v)
set -x
mode_verbeux=true
;;
-h)
echo "Afficher l'aide"
;;
esac
shift
done
if [[ -z $dossier_a_traiter ]]
then
echo "ERREUR: vous devez préciser le dossier à traiter avec l'option -d" >&2
exit 2
fi
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
Le script suivant fonctionne même sans paramètre. On souhaite bloquer
son exécution si aucun paramètre dossier_a_traiter
n’est
passé.
#!/bin/bash
mode_verbeux=false
while (( $# ))
do
case "$1" in
-d)
shift
dossier_a_traiter="$1"
;;
-v)
mode_verbeux=true
;;
-h)
echo "Afficher l'aide"
;;
esac
shift
done
if [[ -z $dossier_a_traiter ]]
then
echo "ERREUR: vous devez préciser le dossier à traiter avec l'option -d" >&2
exit 2
fi
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
ls -l $dossier_a_traiter| awk 'BEGIN{compteur = 0} $1 != "total" && $5 <= 0 {compteur++} END {print compteur}'
Ce qui donne:
#!/bin/bash
mode_verbeux=false
while (( $# ))
do
case "$1" in
-d)
shift
dossier_a_traiter="$1"
;;
-v)
mode_verbeux=true
;;
-h)
echo "Afficher l'aide"
;;
esac
shift
done
if [[ -z "$dossier_a_traiter" ]]
then
echo "ERREUR: vous devez préciser le dossier à traiter avec l'option -d" >&2
exit 2
fi
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
ls -l $dossier_a_traiter| awk 'BEGIN{compteur = 0} $1 != "total" && $5 <= 0 {compteur++} END {print compteur}'
#!/bin/bash
mode_verbeux=false
while (( $# ))
do
case "$1" in
-d)
shift
dossier_a_traiter="$1"
;;
-v)
mode_verbeux=true
;;
-h)
echo "Afficher l'aide"
exit 0
;;
esac
shift
done
if [[ -z "$dossier_a_traiter" ]]
then
echo "Veuillez passer en paramètre un dossier à traiter avec l'option -d" >&2
exit 1
fi
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
ls -l $dossier_a_traiter| awk 'BEGIN{compteur = 0} $1 != "total" && $5 <= 0 {compteur++} END {print compteur}'
Les fichiers pour cette partie sont à placer dans le dossier
bash-parametres/traitement
Le nom du fichier est traiter_dossier
(ajouter des commentaires dans le code pour indiquer la partie de la question que vous traitez)
$ ./traiter_dossier -h
Afficher l'aide
echo "dossier_a_traiter=$dossier_a_traiter"
echo "mode_verbeux=$mode_verbeux"
L’objectif est de modifier ce script pour qu’il supprime le dossier à traiter s’il ne contient que des fichiers vides.
awk
peut resservir)xargs
ou
for
peuvent être utilisés)Dans le programme suivant, un fichier doit être passé en paramètre.
Si l’option -t
ou l’option -s
est choisie,
une action est réalisée.
#!/bin/bash
mode_verbeux=false
option_stat=0
option_type=0
while (( $# ))
do
case "$1" in
-f)
shift
fichier_a_traiter="$1"
;;
-v)
set -x
mode_verbeux=true
;;
-t)
option_type=1
;;
-s)
option_stat=1
;;
-h)
echo "Afficher l'aide"
;;
esac
shift
done
if [[ -z "$fichier_a_traiter" ]]
then
echo "ERREUR: vous devez préciser le fichier à traiter avec l'option -f" >&2
exit 2
fi
if [[ ! -e "$fichier_a_traiter" ]]
then
echo "ERREUR: le fichier $fichier_a_traiter n'exite pas" >&2
exit 2
fi
if [[ "$option_stat" = 1 ]]
then
stat "$fichier_a_traiter"
fi
if [[ "$option_type" = 1 ]]
then
if [[ -d "$fichier_a_traiter" ]]
then
echo "C'est un dossier"
fi
if [[ -f "$fichier_a_traiter" ]]
then
echo "C'est un fichier régulier"
fi
fi
Lire et comprendre le programme précédent.
Ajouter au programme traiter_dossier
la vérification de
l’existence du dossier.
Si le dossier n’existe pas, le programme doit afficher un message et s’arrêter
Les commandes suivantes peuvent vous aider à trouver comment faire cette vérification:
help test
man test
man bash
Une fois cette vérification faite, le programme doit afficher le nombre de fichiers présents (fichiers ou dossiers) à l’intérieur de ce dossier ainsi que la taille occupée sur le disque.
Rappel: apropos
est une commande permettant de chercher,
par exemple, l’espace utilisé sur le disque (en lui passant un paramètre
approprié comme par exemple disk
ou space
)
Ajouter au programme précédent les options suivantes:
-u
permet d’afficher l’utilisation de l’espace disque
par le dossier passé en paramètre-s
permet d’afficher le résultat de la commande
stat
pour le dossier passé en paramètre-n
permet d’afficher le nombre de fichiers et
sous-dossiers présent dans le dossier en paramètre (le nombre d’éléments
affichés par la commande ls
)getopt
getopt
Placée au début d’un script, la commande suivante :
getopt -l "file:,verbose,type,stat,help" -o "f:vtsh" -- "$@"
Affichage en fonction des paramètres passés ($@
):
./info_fichier --file traiter_dossier -s
getopt
affichera
--file 'traiter_dossier' -s --
./info_fichier -f traiter_dossier -s fichier1 fichier2
getopt
affichera
-f 'traiter_dossier' -s -- fichier1 fichier2
Si on passe une option non acceptée, on aura un message d’erreur:
./info_fichier -f traiter_dossier -s fichier1 fichier2 -y
getopt: invalid option -- 'y'
getopt prend en paramètres deux chaînes qui permettent de définir les options acceptées.
Les définitions d’option sont séparées par des virgules
,
-l
--
verbose
indique que l’option
--verbose
est acceptable-o
-
v
indique que l’option -v
est
acceptableLes options suivies d’un :
indiquent à
getopt
que l’option reçoit un paramètre supplémentaire.
file:
: permet de gérer --file param1
où
param1
est associé à l’option --file
f:
: permet de gérer -f param1
où
param1
est associé à l’option -f
Grâce à la sortie de getopt
, on peut redéfinir les
arguments du Shell courant:
options=$(getopt -l "file:,verbose,type,stat,help" -o "f:vtsh" -- "$@")
eval set -- "$options"
options=$(getopt -l "file:,verbose,type,stat,help" -o "f:vtsh" -- "$@")
if [[ $? != 0 ]]
then
# On peut afficher ici un message d'erreur supplémentaire
# voire l'aide de la commande
exit 7
fi
eval set -- "$options"
#!/bin/bash
options=$(getopt -l "file:,verbose,type,stat,help" -o "f:vtsh" -- "$@")
if [[ $? != 0 ]]
then
exit 7
fi
echo $options
eval set -- "$options"
mode_verbeux=false
option_stat=0
option_type=0
while :
do
case "$1" in
-f|--file)
shift
fichier_a_traiter="$1"
;;
-v | --verbose)
set -x
mode_verbeux=true
;;
-t)
option_type=1
;;
-s)
option_stat=1
;;
-h)
echo "Afficher l'aide"
;;
--)
shift
break
;;
esac
shift
done
if [[ -z "$fichier_a_traiter" ]]
then
echo "ERREUR: vous devez préciser le dossier \
à traiter avec l'option -d" >&2
exit 2
fi
if [[ ! -e "$fichier_a_traiter" ]]
then
echo "ERREUR: le fichier $fichier_a_traiter n'exite pas" >&2
exit 2
fi
## Dernier étage
if [[ "$option_stat" = 1 ]]
then
stat "$fichier_a_traiter"
fi
if [[ "$option_type" = 1 ]]
then
if [[ -d "$fichier_a_traiter" ]]
then
echo "C'est un dossier"
fi
if [[ -f "$fichier_a_traiter" ]]
then
echo "C'est un fichier régulier"
fi
fi
echo "---------------------------------"
ls -d $@
Créer un programme nommé execdossier
qui permettra
d’exécuter un ensemble de fichiers placés dans un dossier.
Le dossier sera le paramètre obligatoire.
Si ce dossier existe, le programme doit:
-s
, deux
possibilités.0
(-s
présent)-s
absent)