reponse=42On utilise le caractère $
echo $reponseread nom_variableL’utilisateur doit saisir une chaîne de caractères et terminer par la
touche Entrée
Affichage:
echo $nom_variableDemande avec message:
$ read -p "saisir une valeur: " valeur
saisir une valeur: hello
$ echo $valeur
helloPour vérifier une condition avant d’exécuter une commande, on utilise la structure syntaxique suivante:
if CONDITION
then
COMMANDE
fi#/bin/bash
if grep laurent /etc/passwd
then
echo OK
fifichier=/tmp
if [[ -e $fichier ]]
then
echo "le fichier existe"
fifichier=/tmp
if [[ ! -e $fichier ]]
then
echo "Le fichier n'existe pas"
fiif CONDITION
then
COMMANDE_SI_CONDITION_VRAIE
else
COMMANDE_SI_CONDITION_FAUSSE
fi#/bin/bash
if grep laurent /etc/passwd
then
echo OK
else
echo KO
fifichier=/tmp/nexistepas
if [[ -e $fichier ]]
then
echo "le fichier existe"
else
echo "Le fichier n'existe pas"
fiLa commande help test donne tous les opérateurs
utilisables dans une condition de type [[ ... ]]
\$ echo Des chose \
> sur plusieurs lignes
Des chose sur plusieurs lignes## Ceci est un commentaire
echo "Message" # Ceci est aussi un commentairecat /etc/passwd |\
# Redirige cat vers grep
grep www-data"Citation partielle (ie interprétée)
$ echo "$reponse=.*"
42.*'Citation complète (non interprétée)
$ echo '$reponse=.*'
$reponse=.*$ echo $'\n\nJe suis la dernière ligne'
Je suis la dernière ligne
$ echo '\n\nJe suis la dernière ligne';Permet de mettre plusieurs commandes sur une même ligne
echo salut ; echo les gens$ echo bonjour ; echo salut
bonjour
salut
$ for i in 1 2 3 ; do echo $i ; done
1
2
3
$ for i in 1 2 3 do echo $i ; done
bash: syntax error near unexpected token `done'Astuce: Utiliser la combinaison de touches ctrlX puis ctrlE
ANSI-C Quoting (Bash Reference Manual)
:: > un_fichier: >> info_connexion$ if [[ -f nexistepas ]] ; then
:
else
echo Aucun fichier
fi
Aucun fichierL’intérêt de déclarer les variables est notamment
declare -i nombre#!/bin/bash
set -euo pipefail
declare -i nombre
nombre=4
nombre=$nombre/2
echo "nombre = $nombre" # Affiche 2
# Non déclarée
autre=6
autre=$autre/2
echo "autre = $autre" # Affiche 6/2#!/bin/bash
set -euo pipefail
declare -i nombre
# Tentative d'affectation d'une chaîne
nombre="quatre" # Erreur: unbound variabledeclare -i x y zUtilisation :
$ x=2
$ y=x+9
$ echo $y
11
readonly constante=1declare -r constante=1constante=3Cette instruction instruction provoque une erreur:
constante: readonly variable
Déclaration d’une variable exportée:
declare -x variable_exporteeVoici un programme correctement déclaré:
#!/bin/bash
set -euo pipefail
echo $variable_exportee
echo "Fin du programme"$ ./var_export
./var_export: line 4: variable_exportee: unbound variableSi on exporte la variable depuis le Shell:
$ export variable_exportee=45
$ ./var_export
45
Fin du programmeSuppression de la variable exportée
unset variable_exportee
$ ./var_export
./var_export: line 4: variable_exportee: unbound variableAjout de la déclaration:
#!/bin/bash
set -euo pipefail
declare -x variable_exportee
echo $variable_exportee
echo "Fin du programme"$ ./var_export
Fin du programmedeclare -a fichiersCréons un ensemble de fichiers:
$ touch {a..f}.txtLa bonne manière de définir le tableau avec l’expansion:
$ fichiers=(*)| 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| a.txt | b.txt | c.txt | d.txt | e.txt | f.txt |
Voir le paragraphe Mauvaise méthode d’affectation d’un tableau
$ fichiers=*
$ echo $fichiers
a.txt b.txt c.txt d.txt e.txt f.txtBien que cela ait semblé fonctionner, ce qui suit montre que ce n’est pas le cas:
$ echo "$fichiers"
*
$ echo "${fichiers[0]}"
*
$ echo "${fichiers[1]}"
$ echo "${fichiers[2]}"
$ echo "${fichiers[@]}" # Tous les éléments du tableau
*$ echo "${fichiers[0]}"
a.txt
$ echo "${fichiers[1]}"
b.txt$ echo "${fichiers[@]}" # Tous les éléments du tableau
a.txt b.txt c.txt d.txt e.txt f.txt$ echo ${#fichiers[@]}
6On utilise le symbole : :
:$ echo ${fichiers[@]:3:2}
d.txt e.txtIFS et les tableauxModifier cette variable permet de gérer correctement les noms de fichiers avec des espaces
La variable IFS doit de préférence être déclarée comme
suit:
export IFS=$'\n\t'forfor i in ${!fichiers[@]}
do
echo "fichiers[$i]: ${fichiers[$i]}"
doneforfor ((i=0; i<${#fichiers[@]}; i++))
do
echo "fichiers[$i]: ${fichiers[$i]}"
done$* et $@$* et $@
#!/bin/bash
echo "Using \"\$*\":"
for a in "$*"; do
echo $a;
done
echo -e "\nUsing \$*:"
for a in $*; do
echo $a;
done
echo -e "\nUsing \"\$@\":"
for a in "$@"; do
echo $a;
done
echo -e "\nUsing \$@:"
for a in $@; do
echo $a;
doneRessources:
declare | grep nom_tableautraiter_info(){
declare reference="${1}"
declare cible="${2}"
declare option="${3}"
if [[ -z "${reference}" ]] ; then
echo "Reference est vide"
echo "Envoi dans ${cible} sans référence avec ${option}"
else
echo "Envoi dans ${cible} depuis ${reference} avec ${option}"
fi
}traiter_info "data123" "cible principale" "attention"traiter_info "" "cible principale" "attention"declare -f nExistePas > /dev/null || ( echo "Fonction nExistePas non déclarée" >&2 ; exit 2 )traiter_info ()
{
declare reference="${1}";
declare cible="${2}";
declare option="${3}";
if [[ -z "${reference}" ]]; then
echo "Reference est vide";
echo "Envoi dans ${cible} sans référence avec ${option}";
else
echo "Envoi dans ${cible} depuis ${reference} avec ${option}";
fi
}La portée d’une variable peut être réduite à la fonction dans laquelle elle est déclarée:
# Portée
portee_limitee(){
declare variable_locale="Je suis limitée"
}
portee_non_limitee(){
variable_locale_visible="Je suis accessible partout"
}
portee_limitee
portee_non_limitee
echo ${variable_locale_visible} # Affiche: Je suis accessible partout
echo ${variable_locale} # Erreur: variable_locale: unbound variableCeci est une pratique recommandée lors de l’utilisation de fonctions
declare -fIl ne s’agit pas de déclaration ici mais d’une vérification
declare -f ma_fonctionLe code d’erreur renvoyé est