J'ai une commande de mot-clé bash time que je ne peux pas entièrement expliquer, mais cela fonctionne pour moi.
Mon objectif :
-
pour trouver le temps d'exécution d'un script python, qui prend une variable btw, à partir d'un script bash, et capture cette valeur.
-
également pour capturer la sortie du script python dans la même variable, pour une analyse de réussite ou d'échec.
Après avoir lu autour de moi, je me suis retrouvé avec cette commande, mais je ne suis pas entièrement capable de l'expliquer.
ttime=$( (TIMEFORMAT="%U^"; time /../myscript.py ${__myvar} 2>&1 )|& tr -d f)
Pouvez-vous expliquer pourquoi j'ai besoin de la deuxième commande tr -d f
dans le tube, pour que la valeur de temps soit ajoutée à la sortie de la commande,
Le choix de 'tr -d f' était entièrement arbitraire et n'affectera pas la sortie de mon script, std ou err, mais sans lui, ou une autre commande qui agit sur la sortie texte des scripts de manière mineure, je vois le retour du python sans l'heure ajoutée, pourquoi ?
Modifier :
La vraie question aurait dû être pourquoi le |& tr -d f
. nécessaire, et comme le dit Stephanie, c'est le |&qui permet aux timings trouvés dans le sterr du mot-clé time d'être passés dans la sortie du pipeline
La solution ressemble maintenant à :
ttime=$(TIMEFORMAT="%U^"; { time /../myscript.py ${__myvar} ; } 2>&1 )
Tutoriel sur le descripteur de champ :
http://wiki.bash-hackers.org/howto/redirection_tutorial
Réponse acceptée :
Dans bash
, comme dans ksh
, time
est un mot clé (non intégré) qui est utilisé pour chronométrer un pipeline (pas seulement une commande simple, il peut également chronométrer des commandes composées).
Dans time cmd 2> something
, nous chronométrons cmd 2> something
et imprimer la sortie sur stderr, mais sur le stderr d'origine.
Vous avez besoin de stderr redirigé avant le time
construction est invoquée. Ce que vous faites avec votre |&
qui redirige les stdout et stderr du sous-shell time
est exécuté, mais une façon beaucoup plus simple de le faire serait :
time=$(TIMEFORMAT="%U^"; { time cmd; } 2>&1)
Cela n'implique pas de sous-shell (ici, nous utilisons un groupe de commandes à la place) ni une commande supplémentaire.
Notez qu'avec bash
:
time=$(time (cmd) 2>&1)
arrive à travailler par accident. Je ne m'y fierais pas car cela pourrait changer dans les futures versions et ne fonctionnerait pas dans d'autres shells qui ont un time
mot-clé.
Si vous vouliez uniquement la sortie temporelle dans $time
(et non stdout ou stderr de la commande), vous feriez :
{ time=$(TIMEFORMAT="%U^"; { time cmd 2>&3 3>&-; } 2>&1); } 3>&1