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
#!/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.
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.
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.
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 :
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…
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)
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!