Je pris cela comme casse-tête et que vous voulez montrer le résultat de mon déroutante:
D'abord, je bidouillé avec la mesure du temps. Le date +%s.%N
(que je n'avais pas réalisé avant) était d'où je suis parti. Malheureusement, il semble que l'évaluation arithmétique de bash
ne semble pas prendre en charge les points flottants. Ainsi, j'ai choisi quelque chose d'autre:
$ START=$(date +%s.%N)
$ awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$START') }' /dev/null
8.059526s
$
Ceci est suffisant pour calculer la différence de temps.
Ensuite, j'ai confirmé ce que vous avez déjà décrit: l'invocation de sous-shell empêche l'utilisation de variables shell. Ainsi, j'ai pensé à l'endroit où je pourrais stocker l'heure de début qui est globale pour les sous-shells mais assez locale pour être utilisée simultanément dans plusieurs shells interactifs. Ma solution est temp. fichiers (au /tmp
). Pour fournir un nom unique je suis venu avec ce modèle: /tmp/$USER.START.$BASHPID
.
$ date +%s.%N >/tmp/$USER.START.$BASHPID ; \
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$BASHPID)') }' /dev/null
cat: /tmp/ds32737.START.11756: No such file or directory
awk: cmd. line:1: BEGIN { printf("%fs", 1491297723.111219300 -) }
awk: cmd. line:1: ^syntax error
$
Damn! Encore une fois je suis coincé dans le problème de sous-shell. Pour venir autour, je défini une autre variable:
$ INTERACTIVE_BASHPID=$BASHPID
$ date +%s.%N >/tmp/$USER.START.$INTERACTIVE_BASHPID ; \
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)') }' /dev/null
0.075319s
$
Prochaine étape: violon cela avec PS0
et PS1
. Dans un puzzle similaire (SO: How to change bash prompt color based on exit code of last command?), j'ai déjà maîtrisé le "citant l'enfer". Ainsi, je devrais être capable de le faire à nouveau:
$ PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")'
$ PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1"
0.118550s
$
Ahh. Ça commence à marcher. Ainsi, il n'y a qu'un seul problème - pour trouver le bon script de démarrage pour l'initialisation de INTERACTIVE_BASHPID
. J'ai trouvé ~/.bashrc
qui semble être le bon pour cela, et que j'ai déjà utilisé dans le passé pour d'autres personnalisations personnelles.
Donc, mettre tous ensemble - ce sont les lignes que j'ai ajouté à mon ~/.bashrc
:
# command duration puzzle
INTERACTIVE_BASHPID=$BASHPID
date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}"
PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")'
PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1"
La 3ème ligne (la commande date
) a été ajouté pour résoudre un autre problème. Commentez-le et commencez un nouveau bash interactif pour découvrir pourquoi.
Un aperçu de mon xterm Cygwin bash où j'ai ajouté les lignes ci-dessus pour ./~bashrc
:
Notes:
Je considère que ce plutôt comme solution à un casse-tête d'un « grave productif " Solution. Je suis sûr que ce genre de mesure du temps prend beaucoup de temps. La commande time
peut fournir une meilleure solution: SE: How to get execution time of a script effectively?. Cependant, c'était une bonne leçon pour pratiquer le bash ...
N'oubliez pas que ce code pollue votre répertoire /tmp
avec un nombre croissant de petits fichiers. Nettoyez le /tmp
de temps en temps ou ajoutez les commandes appropriées pour le nettoyage (par exemple ~/.bash_logout
).