2010-10-01 10 views
7

Je lance mon propre script pour transférer les bases de données dans des fichiers tous les soirs.
Je voulais compter le temps (en secondes) qu'il faut pour vider chaque base de données, donc j'essayais d'écrire quelques fonctions pour m'aider à y arriver, mais j'ai des problèmes.Minuteur simple pour mesurer les secondes d'une opération à effectuer

Je ne suis pas un expert en écriture de script à bash, donc si je le fais tout à fait faux, dites-le simplement et, idéalement, suggérez une alternative, s'il vous plaît.

est ici le script:

#!/bin/bash 

declare -i time_start 

function get_timestamp { 
     declare -i time_curr=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%s"` 
     echo "get_timestamp:" $time_curr 
     return $time_curr 
} 

function timer_start { 
     get_timestamp 
     time_start=$? 
     echo "timer_start:" $time_start 
} 

function timer_stop { 
     get_timestamp 
     declare -i time_curr=$? 
     echo "timer_stop:" $time_curr 
     declare -i time_diff=$time_curr-$time_start 

     return $time_diff 
} 

timer_start 
sleep 3 
timer_stop 
echo $? 

Le code devrait vraiment être tout à fait explicite. Les commandes echo sont uniquement destinées au débogage.
je me attends à la sortie soit quelque chose comme ceci:

$ bash timer.sh 
get_timestamp: 1285945972 
timer_start: 1285945972 
get_timestamp: 1285945975 
timer_stop: 1285945975 
3 

Maintenant, ce n'est pas le cas malheureusement. Ce que je reçois est:

$ bash timer.sh 
get_timestamp: 1285945972 
timer_start: 116 
get_timestamp: 1285945975 
timer_stop: 119 
3 

Comme vous pouvez le voir, la valeur var locale time_curr reçoit de la commande est un horodatage valide, mais le retour de cette valeur l'amène à changer à un nombre entier compris entre 0 et 255.

Quelqu'un peut-il m'expliquer pourquoi cela se produit?

PS. C'est évidemment mon script de test de minuterie sans aucune autre logique.


MISE À JOUR Juste pour être parfaitement clair, je veux que ce soit une partie d'un script bash très similaire à this one, où je veux mesurer chaque cycle de la boucle.

À moins bien sûr que je peux le faire avec time, alors s'il vous plaît suggérer une solution.

+2

Vous n'avez pas besoin d'utiliser 'date' pour cela. Bash a une variable '$ SECONDS' qui est automatiquement mise à jour et indique le nombre de secondes depuis le démarrage du script (ou du shell). Il est même réglable et continuera d'augmenter automatiquement. –

+0

Dennis, c'est la solution la plus simple que je puisse trouver et c'est exactement ce que je cherchais. Si vous mettez cela comme une aswer je vais l'accepter avec joie. –

+0

http://unix.stackexchange.com/questions/53841/how-to-use-a-timer-in-bash –

Répondre

3

est utilisé pour contenir le statut de sortie d'une commande et ne peut contenir qu'une valeur comprise entre 0 et 255. Si vous passez un code de sortie en dehors de cette plage (disons, dans recevez une valeur dans cette plage et définissez $? en conséquence.

Pour contourner ce problème, vous pouvez simplement définir une valeur différente dans votre fonction bash:

function get_timestamp { 
     declare -i time_curr=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%s"` 
     echo "get_timestamp:" $time_curr 
     get_timestamp_return_value=$time_curr 
} 

function timer_start { 
     get_timestamp 
     #time_start=$? 
     time_start=$get_timestamp_return_value 
     echo "timer_start:" $time_start 
} 

... 
+1

En alternative à une variable "globale", echo peut être utilisé pour "renvoyer" une valeur. Les deux techniques sont utiles et votre choix dépend de vos besoins. –

21

Vous n'avez pas besoin de faire tout cela. Il suffit de lancer time <yourscript> dans le shell.

+0

Question mise à jour. –

+0

Placez les commandes de la boucle dans un autre script, puis exécutez: time other_script –

0

Je crois que vous devriez pouvoir utiliser la fonction "temps" existante. Après la mise à jour à la question: C'était le morceau de script de votre lien qui faisait une boucle for.

# dump each database in turn 
for db in $databases; do 
    echo $db 
    $MYSQLDUMP --force --opt --user=$USER --password=$PASSWORD 
    --databases $db > "$OUTPUTDIR/$db.bak" 
done 

Vous pouvez extraire la partie intérieure de la boucle dans un nouveau script (appeler dump_one_db.sh) et faire dans la boucle:

# dump each database in turn 
    for db in $databases; do 
     time dump_one_db.sh $db 
    done 

Assurez-vous d'écrire la sortie du temps contre le nom de la base de données dans un fichier.

+0

Mise à jour de la question. –

0

Cela se produit parce que les codes de retour doivent être entre 0-255. Vous ne pouvez pas renvoyer un nombre arbitraire. Si vous continuez à refuser d'utiliser la fonction intégrée time et à lancer la vôtre, modifiez vos fonctions pour qu'elles répercutent leur empreinte et utilisez une extension de processus ($()) pour saisir la valeur.