# Bash script: options dans une fonction

**URL:** <https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347>\
**Category:** Programmation\
**Tags:** bash\
**Created:** [Avril 3, 2022, 5:58 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347 "2022-04-03T17:58:50Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 3, 2022, 5:58 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/1 "2022-04-03T17:58:50Z")

</div>

Bonjour,

voici réduite au minimum, la structure d’un script de sauvegarde.  
Le script fonctionne dans l’état où je vous le présente, mais à condition que le choix des options ne soit pas dans une fonction.  
Est-ce une erreur dans la structure de ce script, ou mon ambition n’est-elle pas adaptée à bash? (version 5)

Merci pour votre attention

```bash
#!/bin/bash --
#set -eu #o pipefail
MONHOME(){
}

# Configuration:
readonly EXCLUS="/usr/local/etc/excludeRsyncSeagate4t-bkp.txt"
readonly DevSeagate='/dev/mapper/seagateUSB4T-bkp'
# Si nécessaire, point de montage par ce script:
PTMONTAGE="/mnt/Seagate4T-bkp" 
# Source = tout (système inclu)
SOURCE="/"

# Variables de travail
readonly CeScript=$(basename "$0")
DATE=$(date +%F_%s | cut -b 1-11,17-21)

CONNEXION() {
# est-il connecté?
}

MONTER() {
# Découvrir ou creer le point de montage
# Options par défaults:
USBDIR="$MONTE"

INFOS() {
exit 0
}
 
SYNTAXE() {
    MESSAGE "Syntaxe de $CeScript"
    echo
    echo "$CeScript [options]"
    echo
    MESSAGE "Options:"
    echo "-d dry-run"
    echo "-o <liste> autres options de rsync"
    echo "-i infos sur ce script"
    echo "-h cet écran d'aide"
    exit 0
}

#--#OPTIONS() { # BUG: ça ne marche pas dans une fonction
# GESTION DES OPTIONS:
while getopts diho: option
do
  case "$option" in
          d ) OPTION='--dry-run'
                  ;;
          o ) OPTION="${OPTION} $OPTARG"
                  ;;
          i ) INFOS ; exit 0
                  ;;
          h ) SYNTAXE
              exit 0
                  ;;
          * ) MESSAGE "OPTION $OPTION non valide"
              exit 1
  esac
done
shift $((OPTIND-1))
#--#}

RSYNC() {
### Construction de la commande rsync:
DESTINATION="$MONTE"
time sudo rsync -auHAXCvv "$OPTION" --stats --exclude-from="$EXCLUS" "$SOURCE" "$DESTINATION"
}

DEMONTER() {
}

### Lancement du programme:
MONHOME # racine des données partagées selon le système 
CONNECTION # vérifie que le disque USB est connecté
MONTER # vérifie que le disque USB monté, sinon le monte
#--#OPTIONS
RSYNC # lancement de commande rsync, construite notamment en fonction des options
DEMONTER # Demande avant de démonter le disque USB.

```

---

<div class="post-metadata">

**Author:** ![Almtesh](https://www.debian-fr.org/user_avatar/www.debian-fr.org/almtesh/32/10312_2.png) [@Almtesh](https://www.debian-fr.org/u/Almtesh)\
**Post date:** [Avril 4, 2022, 7:52 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/2 "2022-04-04T07:52:52Z")

</div>

Bonjour,

Effectivement, en bash, les arguments d’une fonction utilisent les mêmes variables que les arguments de la commande.  
Tu peux probablement passer les arguments de la commande directement à une fonction en appelant la fonction avec la variable `$*` en paramètre, ça fonctionne à condition que les arguments de ta commande ne comporte pas d’espace en dehors de la séparation des arguments entre eux.

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 4, 2022, 8:23 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/3 "2022-04-04T08:23:17Z")

</div>

> ça fonctionne à condition que les arguments de ta commande ne comporte pas d’espace en dehors de la séparation des arguments entre eux.

C’est-à-dire que:  
`script_rsync -abcd`  
prendra en compte les options a,b,c et d

et  
` script _rsync -ab -c -d`

ne prendra en compte que les options a et b (ou/et renverra une erreur) ?

Merci Almtesh

---

<div class="post-metadata">

**Author:** ![Zargos](https://www.debian-fr.org/user_avatar/www.debian-fr.org/zargos/32/10889_2.png) [@Zargos](https://www.debian-fr.org/u/Zargos)\
**Post date:** [Avril 4, 2022, 9:00 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/4 "2022-04-04T09:00:43Z")

</div>

Bonjour,

dans une fonction, tu peux mettre tes variables localement à ta fonction par le mot `local`.  
Tu peu ainsi avoir:

```auto
var01="toto" # ma variable est globale

function mafonction {
    local varlocal01="128"

    var01=`echo $var01"="$varlocal01`
}

echo mafonction $var01

```

Ce n’est qu’un exemple vite fait.

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 4, 2022, 9:07 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/5 "2022-04-04T09:07:05Z")

</div>

Merci Zargos,  
cependant, je ne vois pas comment localiser la fonction peut résoudre ma question.

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 4, 2022, 9:08 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/6 "2022-04-04T09:08:26Z")

</div>

À partir de vos lumières, je ferai des essais dés que je pourrai m’y remettre.

---

<div class="post-metadata">

**Author:** ![Almtesh](https://www.debian-fr.org/user_avatar/www.debian-fr.org/almtesh/32/10312_2.png) [@Almtesh](https://www.debian-fr.org/u/Almtesh)\
**Post date:** [Avril 4, 2022, 6:40 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/7 "2022-04-04T18:40:34Z")

</div>

> [@josephtux](#):
>
> C’est-à-dire que:  
> `script_rsync -abcd`  
> prendra en compte les options a,b,c et d
> 
> et  
> ` script _rsync -ab -c -d`
> 
> ne prendra en compte que les options a et b (ou/et renverra une erreur) ?

En fait, je pense plutôt à un exemple du style :

```bash
script_rsync -abc '/home/almtesh/Mes Documents'

```

Là, le script est `script_rsync`, la première option est `-abc`, et la seconde est `/home/almtesh/Mes Documents`, si tu envoies ça à une fonction en utilisant la variable `$*`, tu obtiendras `-abc` en première option, `/home/almtesh/Mes` en deuxième option et `Documents` en troisième option à cause de l’espace dans la seconde option.  
C’est typiquement le genre de problème que tu peux rencontrer. Si tu as déjà lancé `scp` pour transférer des fichiers distants qui comportent des espaces, tu dois très bien comprendre de quoi je parle.

> [@Zargos](#):
>
> dans une fonction, tu peux mettre tes variables localement à ta fonction par le mot `local` .

En fait, le but ici est d’utiliser la variable pas locale pour récupérer les options de lancement du script et non celles de la fonction elle-même. Un peu genre :

```bash
function parse_args () {
	global $1
	
	if [x"$1" = "x-r"];then
		recursive=1
	else
		recursive=0
	fi

parse_args
if [$recursive -eq 1];then
	echo "Récursif"
else
	echo "Pas récursif"
fi

```

Je n’ai pas testé, mais je pense que c’est ça le concept…

---

<div class="post-metadata">

**Author:** ![Zargos](https://www.debian-fr.org/user_avatar/www.debian-fr.org/zargos/32/10889_2.png) [@Zargos](https://www.debian-fr.org/u/Zargos)\
**Post date:** [Avril 5, 2022, 12:11 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/8 "2022-04-05T12:11:52Z")

</div>

les arguments sont :  
$0 =\> nom du script  
$1…$xx =\> chacun des paramètres

Donc :

`script _rsync -ab -c -d`  
c’est:  
$0 = script\_rsync  
$1= -ab  
$2=-c  
$3=-d

---

<div class="post-metadata">

**Author:** ![Sputnik93](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/35a633/32.png) [@Sputnik93](https://www.debian-fr.org/u/Sputnik93)\
**Post date:** [Avril 5, 2022, 2:17 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/9 "2022-04-05T14:17:49Z")

</div>

Bonjour,

je n’ai pas tout compris au problème que tu as avec le parsing des options, mais si jamais `getopts` (la fonction builtin du shell) te pose problème, essaie `getopt` (sans s), qui est fourni avec le paquet `util-linux`, ça fait longtemps que je ne m’en suis pas servi, mais de mémoire il est plus souple que `getopts`, et permet notamment de parser des options au format long (comme `--paramètre valeur`)

La [page man de getopt](https://www.man7.org/linux/man-pages/man1/getopt.1.html)

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 8, 2022, 10:09 UTC](https://www.debian-fr.org/t/bash-script-options-dans-une-fonction/86347/10 "2022-04-08T10:09:09Z")

</div>

Bonjour,  
merci à tous.  
Si j’ai bien lu, le plus simple est de renoncer à mettre getopts dans une fonction. Le mieux semble dans ce cas l’ennemi du bien!
