Implémentation de l'exécution à sec dans les scripts bash

15

Comment pourrait-on implémenter une option de dry-run dans un script bash?

Je peux penser à encapsuler chaque commande dans un if et à faire écho à la commande au lieu de l'exécuter si le script s'exécute avec une exécution à sec.

Une autre façon serait de définir une fonction, puis de passer chaque appel de commande via cette fonction.

Quelque chose comme:

function _run () {
    if [[ "$DRY_RUN" ]]; then
        echo $@
    else
        $@
    fi
}

`_run mv /tmp/file /tmp/file2`

`DRY_RUN=true _run mv /tmp/file /tmp/file2`

Est-ce juste faux et il existe une bien meilleure façon de le faire?

Andrei Serdeliuc
la source
Ainsi, vous voulez imprimer ce que la commande fera (y compris les valeurs des $ VARIABLES) sans réellement exécuter la commande. J'utilise quelque chose comme votre _run()fonction, parfois avec 'set -xv', mais j'aimerais une meilleure façon.
Stefan Lasiewski
oui, exactement ça. Je me demande s'il n'y a pas de variable interne que vous pouvez définir dans bash afin que les commandes ne s'exécutent pas réellement, au lieu de les passer par une fonction
Andrei Serdeliuc
2
Il n'y a aucune raison pour que cette question ait été marquée wiki communautaire.
pause jusqu'à nouvel ordre.
Bash est une coquille. Il n'y a aucune raison pour qu'il fasse des courses à sec. Je ne pense pas qu'il existe une meilleure façon de procéder que vous ne l'avez déjà fait.
d -_- b

Réponses:

2

Voir BashFAQ / 050: J'essaie de mettre une commande dans une variable, mais les cas complexes échouent toujours! pour une discussion de ce sujet.

Bien que maintenant supprimée, la section Comment ajouter des capacités de test à un programme peut toujours être utile.

Dennis Williamson
la source
Pas une alternative, mais cela ressemble à une excellente ressource pour tester et travailler avec des programmes bash plus longs.
Andrei Serdeliuc
J'ai annulé la modification qui a ajouté une ancre à une partie particulière de la page liée, car le point de ma réponse, comme indiqué, est de lire la discussion dans son ensemble plutôt que de pointer vers une partie pratique spécifique. Le but de la page liée est généralement d'essayer d'éviter de placer des commandes à exécuter dans des variables car il y a beaucoup de gotchas.
pause jusqu'à nouvel ordre.
Il serait beaucoup plus utile que cette réponse résume les points saillants de cet article. Les réponses d'une ligne sont toujours de mauvaises réponses.
Mark Booth
4

Je voulais jouer avec la réponse de @Dennis Williamson. Voici ce que j'ai obtenu:

Run () {
    if [ "$TEST" ]; then
        echo "$*"
        return 0
    fi

    eval "$@"
}

Le eval "$@"est important ici, et vaut mieux que de le faire simplement $*. $@renvoie tous les paramètres et $*renvoie tous les paramètres sans espace / guillemet.

$ mkdir dir
$ touch dir/file1 dir/file2
$ FOO="dir/*"
$ TEST=true Run ls -l $FOO
ls -l dir/file1 dir/file2
$ Run ls -l $FOO
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file1
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file2
Stefan Lasiewski
la source