Introduction
Un script shell stocke des commandes dans un fichier afin de pouvoir répéter une tâche de manière cohérente. Les scripts fiables pour débutants indiquent explicitement leur interpréteur, protègent les expansions de variables avec des guillemets, valident les données saisies avant d'agir et renvoient un statut de sortie que les autres commandes peuvent interpréter.
Dans ce laboratoire, vous allez créer progressivement de petits scripts Bash. Vous exécuterez des scripts avec Bash et en tant que fichiers exécutables, utiliserez des variables et des arguments positionnels, lirez une saisie interactive, effectuerez des branchements avec if et des tests de fichiers, choisirez des codes de sortie, itérerez avec for et combinerez ces notions dans un simple résumé de journaux.
Créer et exécuter votre premier script
Dans cette étape, vous allez créer un script Bash, l'exécuter avec un interpréteur, puis le rendre directement exécutable.
Accédez à l'espace de travail du laboratoire :
cd /home/labex/project/shell-lab
Créez hello.sh avec un document here. La première ligne est un shebang qui sélectionne Bash lorsque le fichier est exécuté directement :
cat > hello.sh <<'EOF'
#!/bin/bash
echo "Hello from a Bash script"
pwd
EOF
Examinez le fichier avant de l'exécuter :
cat hello.sh
Passez explicitement le fichier à Bash. Cette commande fonctionne même avant l'ajout de la permission d'exécution :
bash hello.sh
Ajoutez la permission d'exécution et examinez le mode du fichier :
chmod u+x hello.sh
ls -l hello.sh
Exécutez le fichier depuis le répertoire courant. ./ fournit un chemin ; par défaut, le shell ne recherche pas automatiquement les commandes dans le répertoire courant :
./hello.sh
Utiliser des variables et des guillemets sûrs
Dans cette étape, vous allez affecter des variables, les développer et voir pourquoi les guillemets doubles protègent les valeurs contenant des espaces.
Créez un script avec deux variables :
cat > variables.sh <<'EOF'
#!/bin/bash
course="Linux for Noobs"
workspace="/home/labex/project/shell-lab"
echo "Course: $course"
echo "Workspace: $workspace"
printf 'Quoted argument count: %s\n' "$#"
printf 'First argument: %s\n' "${1:-not provided}"
EOF
Dans une affectation shell, aucun espace ne doit entourer =. Les guillemets doubles permettent l'expansion de $course tout en conservant Linux for Noobs comme une seule valeur.
Exécutez le script avec un argument contenant des espaces :
bash variables.sh "beginner learner"
La variable spéciale $# contient le nombre d'arguments positionnels et $1 contient le premier argument. ${1:-not provided} fournit une valeur de remplacement lorsque le premier argument est absent.
Enregistrez la sortie pour l'examiner :
bash variables.sh "beginner learner" > variable-output.txt
cat variable-output.txt
Valider les arguments positionnels
Dans cette étape, vous allez rendre un argument obligatoire, afficher une indication d'utilisation et renvoyer des statuts de sortie différents en cas d'échec et de réussite.
Créez greet-argument.sh :
cat > greet-argument.sh <<'EOF'
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: $0 NAME" >&2
exit 2
fi
name=$1
echo "Hello, $name"
exit 0
EOF
La commande de test [ ... ] vérifie si le nombre d'arguments est différent de un. >&2 envoie le texte d'utilisation vers la sortie d'erreur standard et exit 2 signale une utilisation incorrecte.
Exécutez le script sans argument, puis affichez immédiatement $?, le statut de sortie de la commande précédente :
bash greet-argument.sh
echo "missing argument status: $?"
Le statut attendu est 2. Exécutez ensuite le script correctement :
bash greet-argument.sh "Ada Lovelace"
echo "valid argument status: $?"
Enregistrez le message d'accueil obtenu :
bash greet-argument.sh "Ada Lovelace" > argument-greeting.txt
Lire une saisie interactive
Dans cette étape, vous allez inviter un utilisateur à saisir une valeur, lire une ligne en toute sécurité et gérer une saisie vide.
Créez ask-name.sh :
cat > ask-name.sh <<'EOF'
#!/bin/bash
read -r -p "Enter your name: " name
if [ -z "$name" ]; then
echo "A name is required" >&2
exit 1
fi
echo "Welcome, $name"
EOF
read -r lit une ligne sans traiter les barres obliques inverses de manière particulière. -p affiche une invite et -z vérifie si la valeur placée entre guillemets est vide.
Exécutez le script :
bash ask-name.sh
À l'invite, saisissez :
Grace Hopper
Vous devriez voir Welcome, Grace Hopper. Pour obtenir un résultat enregistré et reproductible, transmettez une ligne de saisie au même script :
printf 'Grace Hopper\n' | bash ask-name.sh > interactive-greeting.txt
cat interactive-greeting.txt
Effectuer des branchements avec des tests de fichiers
Dans cette étape, vous allez utiliser if, elif et else avec des tests de fichiers pour déterminer la nature d'un chemin.
Créez classify-path.sh :
cat > classify-path.sh <<'EOF'
#!/bin/bash
path=${1:-}
if [ -z "$path" ]; then
echo "Usage: $0 PATH" >&2
exit 2
elif [ -d "$path" ]; then
echo "directory: $path"
elif [ -f "$path" ]; then
echo "file: $path"
else
echo "missing: $path" >&2
exit 1
fi
exit 0
EOF
-d vérifie qu'il s'agit d'un répertoire et -f vérifie qu'il s'agit d'un fichier ordinaire. L'ordre est important : l'utilisation incorrecte est traitée avant le type du chemin.
Testez les trois résultats possibles pour le chemin :
bash classify-path.sh logs
bash classify-path.sh notes.txt
bash classify-path.sh missing.txt
echo "missing path status: $?"
Enregistrez ensemble les résultats obtenus avec succès. && n'exécute la deuxième commande que si la première réussit :
bash classify-path.sh logs > path-results.txt && bash classify-path.sh notes.txt >> path-results.txt
cat path-results.txt
Traiter plusieurs fichiers avec une boucle for
Dans cette étape, vous allez parcourir des fichiers journaux et compter les enregistrements correspondants dans chacun d'eux.
Créez count-errors.sh :
cat > count-errors.sh <<'EOF'
#!/bin/bash
log_dir=${1:-logs}
if [ ! -d "$log_dir" ]; then
echo "Log directory not found: $log_dir" >&2
exit 1
fi
for log_file in "$log_dir"/*.log; do
error_count=$(grep -c '^ERROR ' "$log_file" || true)
printf '%s errors=%s\n' "$(basename "$log_file")" "$error_count"
done
EOF
À chaque itération, la boucle affecte à log_file un chemin correspondant. Les guillemets autour de "$log_file" protègent les espaces, tandis que basename supprime le préfixe du répertoire. grep -c compte les lignes correspondantes ; || true empêche l'absence de correspondance d'interrompre un flux de travail strict plus vaste.
Exécutez la boucle et enregistrez sa sortie :
bash count-errors.sh logs | tee error-counts.txt
Vous devriez voir un résultat pour chaque fichier .log.
Combiner validation, boucles et statuts de sortie
Dans cette étape, vous allez créer un script réutilisable qui valide un répertoire, résume ses journaux et signale clairement la réussite ou l'échec.
Créez summarize-logs.sh :
cat > summarize-logs.sh <<'EOF'
#!/bin/bash
input_dir=${1:-}
output_file=${2:-}
if [ -z "$input_dir" ] || [ -z "$output_file" ]; then
echo "Usage: $0 INPUT_DIR OUTPUT_FILE" >&2
exit 2
fi
if [ ! -d "$input_dir" ]; then
echo "Input directory not found: $input_dir" >&2
exit 1
fi
: > "$output_file"
for log_file in "$input_dir"/*.log; do
lines=$(wc -l < "$log_file")
errors=$(grep -c '^ERROR ' "$log_file" || true)
printf '%s lines=%s errors=%s\n' "$(basename "$log_file")" "$lines" "$errors" >> "$output_file"
done
echo "Wrote summary to $output_file"
exit 0
EOF
La commande : > "$output_file" crée la destination ou la vide de manière sûre avant la boucle. Exécutez le script avec les deux arguments obligatoires :
chmod u+x summarize-logs.sh
./summarize-logs.sh logs log-summary.txt
echo "summary status: $?"
cat log-summary.txt
Testez le chemin d'échec avec un répertoire inexistant :
./summarize-logs.sh missing log-summary.txt
echo "missing directory status: $?"
Le statut de réussite doit être 0, tandis que le statut associé au répertoire inexistant doit être 1.
Résumé
Vous avez créé et exécuté des scripts Bash, utilisé des shebangs et des permissions, développé des variables protégées par des guillemets, lu des saisies positionnelles et interactives et renvoyé des statuts de sortie pertinents. Vous avez également effectué des branchements avec if/elif/else, testé des fichiers et des répertoires, parcouru des journaux avec for et combiné ces notions dans un outil réutilisable de création de résumés.
Ces notions fondamentales rendent les automatisations ultérieures plus faciles à lire, plus sûres à réexécuter et plus simples à évaluer pour d'autres commandes ou des tâches planifiées.



