Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 08/05/2013, à 14:42

Le Barde

(RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Bonjour à tous,
J'ai ça dans une variable :

SAVE_COMMAND="for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest }; done"

Dans mon script je fais :

echo "$SAVE_COMMAND"
sh -c $SAVE_COMMAND || exit 1

Ça me renvoie :

for dir in /home/dev /home/.emacs; do { rsync -rltgoDv --del --ignore-errors --force $dir /home/adrien/dev/abt/tmp/ }; done
dir: 1: dir: Syntax error: Bad for loop variable

Autres tests :

$ eval $SAVE_COMMAND || exit 1
bin/abt: 1: eval: Syntax error: "done" unexpected (expecting "}")
$ $SAVE_COMMAND || exit 1
bin/abt: 183: bin/abt: for: not found

1) Quelle est la bonne façon pour exécuter la commande qui dans la variable ?
2) La boucle for est-elle correcte ?

Merci d'avance !

Dernière modification par Le Barde (Le 08/05/2013, à 18:05)

Hors ligne

#2 Le 08/05/2013, à 15:10

Watael

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

salut,

utiliser une variable pour stocker une commande "complexe" est une mauvaise idée,
utilise une fonction.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#3 Le 08/05/2013, à 15:15

Hizoka

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

au pire tu envoie la variable dans un fichier puis tu exécutes celui-ci.


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#4 Le 08/05/2013, à 15:15

Yannou90

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Bonjour

SAVE_COMMAND='for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest }; done'
echo "$SAVE_COMMAND"
$SAVE_COMMAND

Dernière modification par Yannou90 (Le 08/05/2013, à 15:16)

Hors ligne

#5 Le 08/05/2013, à 15:22

pingouinux

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Bonjour,
Essaye ceci :

SAVE_COMMAND="for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest ;}; done"
sh -c "$SAVE_COMMAND" || exit 1

Hors ligne

#6 Le 08/05/2013, à 15:23

Le Barde

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Bonjour et merci pour vos réponses !

@Yannou90 :

Yannou90 a écrit :
SAVE_COMMAND='for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest }; done'
echo "$SAVE_COMMAND"
$SAVE_COMMAND

Non, je veux que $dirs_orig_table et $dirs_dest soient remplacés, et ça me donne de toute façon

bin/abt: 183: bin/abt: for: not found

@Watael : Pourquoi une mauvaise idée ? En fait, j'ai une fonction qui a pour but de créer une commande en chaîne de caractères. Cette chaîne peut ensuite aller dans un crontab, un anacron, ou être exécutée directement. Comment faire autrement sinon ?

@Hizoka : Je vais essayer.

Hors ligne

#7 Le 08/05/2013, à 15:26

Le Barde

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

@pingouinux : Bonjour,

pingouinux a écrit :
SAVE_COMMAND="for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest ;}; done"
sh -c "$SAVE_COMMAND" || exit 1

Avec le point-virgule en plus et le sh -c "$truc" ça ne fonctionne pas non plus :

for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest ;}; done
bin/abt: 183: bin/abt: for: not found

Hors ligne

#8 Le 08/05/2013, à 15:36

Watael

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

pourquoi ? tu l'illustres très bien.

En fait, j'ai une fonction qui a pour but de créer une commande en chaîne de caractères.

ça veut dire quoi «en chaîne de caractère» ?
comment fonctionne cette fonction ? ^^


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#9 Le 08/05/2013, à 17:33

Le Barde

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Watael a écrit :

pourquoi ? tu l'illustres très bien.

En fait, j'ai une fonction qui a pour but de créer une commande en chaîne de caractères.

ça veut dire quoi «en chaîne de caractère» ?
comment fonctionne cette fonction ? ^^

Petites explications !

En réalité, c'est un script qui permet de planifier les sauvegardes, de manière plus automatisée qu'en faisant des crontabs à la main. On définit les emplacements à archiver, où les archiver et de quelle manière (avec des fichiers de configuration, tout comme ceux d'apache / Nginx, avec des répertoires conf/places-available et conf/places-enabled). On définit aussi dans les configurations comment préparer l'archivage (avec un tar, un rsync, un git-commit, ...).

À l'appel de mon script :

$ abt update

Cela va chercher toutes les configurations dans les fichiers de conf, et met à jour les crontabs et autres anacrons pour que l'exécution se fasse comme prévu au moment opportun.

Du coup, le crontab a besoin d'une commande à exécuter (dernier champ).

J'ai la fonction suivante, qui prépare la commande à exécuter :

get_place_save_command() {
    # Get origin directories into a sequence
    dirs_orig_table="`echo \"$DIRS_ORIG\" | sed 's/\(,\)/ /g'`"
    #log "dirs_orig_table = $dirs_orig_table" # for debug

    # If DIRS_DEST is null, get SEND_DEST_DIR
    [ -z "$DIRS_DEST" ] && dirs_dest=$SEND_DEST_DIR || \
        dirs_dest=$DIRS_DEST
    
    case "$PACKAGING" in
        rsync)
            # If there is only one destination, the command is
            # quite simple. The number of directories is
            # the number of commas plus one.
            if [ `echo $DIRS_ORIG | grep -c ","` -eq 0 ]; then
                SAVE_COMMAND="rsync -rltgoDv --del --ignore-errors --force $DIRS_ORIG $dirs_dest"
            else
                SAVE_COMMAND="for dir in $dirs_orig_table; do { rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest ;}; done"
            fi
            ;;
        git)
            log "$file: Packaging using Git not yet implemented."
            return 1
            ;;
        svn)
            log "$file: Packaging using SVN not yet implemented."
            return 1
            ;;
        duplicity)
            log "$file: Packaging using Duplicity not implemented. Try Rsync instead."
            return 1
            ;;
        *)
            log "$file: Unknown packaging $PACKAGING. Exiting."
            return 1
    esac
}

Cette fonction définit la commande à exécuter/planifier, enregistrée dans SAVE_COMMAND. Cette commande est ensuite ajoutée à un crontab, anacron ou un initrc pour être exécutée périodiquement.

Mais je veux que mon script puisse aussi déclencher directement l'archivage des données, d'où mon besoin d'exécuter cette commande depuis le script.

er

Hors ligne

#10 Le 08/05/2013, à 17:56

Watael

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

case "$PACKAGING" in
        rsync)
            # If there is only one destination, the command is
            # quite simple. The number of directories is
            # the number of commas plus one.
            if [ `echo $DIRS_ORIG | grep -c ","` -eq 0 ]; then
                save_function() {
                   rsync -rltgoDv --del --ignore-errors --force $DIRS_ORIG $dirs_dest
                }
            else
                save_function() {
                   for dir in $dirs_orig_table; do rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest; done
                }
            fi
            ;;
#...

je ne suis pas certain que la boucle soit nécessaire, et que rsync ne puisse pas faire ça tout seul.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#11 Le 08/05/2013, à 18:01

Le Barde

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Je m'en suis sorti !
Comme la boucle for ne contient qu'un seule appel de fonction, j'ai retiré les parenthèses :

SAVE_COMMAND="for dir in $dirs_orig_table ; do rsync -rltgoDv --del --ignore-errors --force \$dir $dirs_dest ; done"

L'appel est fait comme ceci :

sh -c "$SAVE_COMMAND" || exit 1

Voici ce que ça donne :

for dir in /home/adrien/.emacs /home/adrien/texte ; do rsync -rltgoDv --del --ignore-errors --force $dir /home/adrien/dev/abt/tmp/ ; done
sending incremental file list

sent 80 bytes  received 12 bytes  184.00 bytes/sec
total size is 31  speedup is 0.34
sending incremental file list

sent 27795 bytes  received 249 bytes  56088.00 bytes/sec
total size is 14009061  speedup is 499.54

Merci à tous pour votre aide salutaire !

EDIT : Merci Watael, ça a l'air tout à fait sympa comme solution également !

Dernière modification par Le Barde (Le 08/05/2013, à 18:04)

Hors ligne

#12 Le 08/05/2013, à 18:04

Hizoka

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

si c'est resolu, precise le dans le titre smile


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#13 Le 08/05/2013, à 18:04

Le Barde

Re : (RÉSOLU) sh : exécution d'une commande dans une variable - boucle for

Tout à fait :-)

Hors ligne