Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

La commande time

30 réponses
Avatar
Francois Lafont
Bonjour à tous,

Je suis sous sous Ubuntu 10.04 et mon shell est le bash.

1) Je souhaite mesurer le temps d'exécution d'une commande avec :
~$ time maCommande

Au lieu d'avoir en sortie les 3 lignes real+user+sys, je ne voudrais
avoir en sortie que la ligne real. Comment faut-il faire ?

J'avais pensé d'abord au naïf :
~$ time maCommande | grep real
mais ça ne marche pas car, si je comprends bien, dans ce cas time mesure
le temps d'exécution de la commande "maCommande | grep real" et ensuite
fait son travail, c'est-à-dire affiche les 3 lignes et non une seule.

2) Du coup, j'ai voulu chercher des infos sur time avec 'man time'. J'ai
vu plein d'options avec cette commande mais aucune ne marchaient. J'ai
fini par comprendre que le time que j'utilise dans 1) est une commande
interne de mon shell et que le time de 'man time' est /usr/bin/time, une
commande externe à mon shell.

Y a-t-il un moyen, via le shell, de savoir qui exactement (le time
interne ou /usr/bin/time) est utilisé lorsque je tape 'time XXX' ? Je
pensais au départ que 'which time' le faisait mais justement il
m'indique /usr/bin/time et j'ai pu lire que which ne s'occupait pas des
commandes interne au shell (which cd n'affiche rien). Je sais bien que
ce sont les commandes internes qui priment, mais je ne les connais pas
toutes. Est-ce que ça existe une commande du genre ci-dessous ?

~$ whichPourDeVrai time
commande interne time
~$ whichPourDeVrai
/usr/bin/pdflatex

Merci d'avance.


--
François Lafont

10 réponses

1 2 3
Avatar
Benoit Izac
Bonjour,

le 24/08/2010 à 20:46, Francois Lafont a écrit dans le message
<4c74137d$0$28557$ :

Si which n'a rien trouvé, c'est qu'il s'agit d'une commande interne.
Facile, non ? :)



C'est juste, si which ne trouve rien, c'est une commande interne. Mais
la réciproque n'est pas forcément vraie, en particulier avec time
justement. J'ai ça :

~$ which time
/usr/bin/time

Moi j'ai cru alors que lorsque je tapais "time XXXX", c'était forcément
/usr/bin/time qui était utilisée. Mais c'est faux car c'est la commande
time interne qui est utilisée. D'où ma question : quelle est la commande
qui permet de savoir qui est utilisé exactement quand je tape "time
XXXX". which ne répond pas à cette question là ? :-)



En plus de ce qui a été dit, une autre chose qui pourrait t'intéresser
est command(1).

$ command -v foo
devrait te sortir :
foo => built-in, fonction, mot réserve du shell
/path/to/foo => programme dans $PATH
alias foo='...' => alias
=> foo n'existe pas

$ command time le_super_programme
n'utilisera pas le time du shell.

--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 24/08/2010 à 21:34, Francois Lafont a écrit dans le message
<4c741eb2$0$18607$ :

[ ~]$ which time
...rien...



Ah, chez moi ça donne /usr/bin/time et je trouve que c'est bizarre
d'avoir un programme dans /bin qui porte le même le même nom qu'un mot
clé du shell.



Il y en a d'autres comme « [ », « echo », « false », « true », « [ »,
« test », etc.

Petite question subsidiaire :

~$ type time
time est un mot-clé du shell
~$ type cd
cd est une primitive du shell

C'est quoi la nuance entre 'mot-clé' et 'primitive' ?



Les mots clés c'est « if », « while », « ! », « done », etc. Ce sont des
mots qui change le comportement du shell lorsqu'ils sont les premiers
mots d'une commande.

if true
then
while false
do
time sleep 10
done
else
{ echo "hello" }
fi
Ici, tous les premiers mots sont des mots clés (reserved words selon
POSIX).

Les primitives (builtin) sont des commandes classiques que l'on trouve
dans le $PATH qui ont été implémentées au niveau du shell. Ça permet
d'éviter un fork à chaque appel.

--
Benoit Izac
Avatar
Erwan David
Francois Lafont écrivait :

Le 24/08/2010 21:51, Erwan David a écrit :

Dis déjà de quel shell tu parles...

sh, csh, ksh, tcsh, dash, zsh, bash ?
Ou un autre ?



Le bash, comme je l'indiquais dans mon tout premier message. ;-)



Toutes mes excuses, je n'avais pas fait le lien...

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Avatar
Nicolas George
Benoit Izac , dans le message , a écrit :
Il y en a d'autres comme « [ », « echo », « false », « true », « [ »,
« test », etc.



N'oublie pas « [ ».
Avatar
Benoit Izac
Bonjour,

le 24/08/2010 à 22:54, Francois Lafont a écrit dans le message
<4c743188$0$28588$ :

$ command -v foo
devrait te sortir :
foo => built-in, fonction, mot réserve du shell
/path/to/foo => programme dans $PATH
alias foo='...' => alias
=> foo n'existe pas



Merci pour l'info. Chez moi, j'ai ça :

~$ command -V time # là finalement c'est assez proche de type
time est un mot-clé du shell
~$ command -v time
time



C'est normal, -V est fait pour l'humain (non parsable) alors que la
sortie de -v est parfaitement définie :
A=foo
B=$(command -v "$A")
case "$B" in
/*) echo regular command in PATH ;;
"$A") echo shell builtin ;;
alias "$A"*) echo alias ;;
"") echo inexistant ;;
*) echo ARRGGGGHHHHHHH ;;
esac

$ command time le_super_programme
n'utilisera pas le time du shell.



Ok. Bon et bien entre command, type, which et whereis je suis paré. :-)



Tu peux rajouter aussi « whence » qui vient de ksh (donc dispo dans zsh).
command a été fait pour rassembler type, which et whence.

--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 24/08/2010 à 23:31, Nicolas George a écrit dans le message
<4c743a36$0$665$ :

Benoit Izac , dans le message , a écrit :
Il y en a d'autres comme « [ », « echo », « false », « true », « [ »,
« test », etc.



N'oublie pas « [ ».



T'inquiète pas. ;)

--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 24/08/2010 à 23:06, Francois Lafont a écrit dans le message
<4c74344f$0$13939$ :

Les primitives (builtin) sont des commandes classiques que l'on trouve
dans le $PATH qui ont été implémentées au niveau du shell. Ça permet
d'éviter un fork à chaque appel.



Mais pourtant, chez moi, les commandes "builtin" ne sont pas toutes dans
le $PATH.

~$ type cd
cd est une primitive du shell
~/Bureau$ sudo find / -type f -name "cd"
/usr/share/X11/xkb/symbols/cd
/usr/share/screen/utf8encodings/cd
/usr/share/zsh/help/cd



Forcément, si tu fork puis tu fais un cd, lorsque tu vas revenir, tu
n'auras pas beaucoup bougé.

~$ type read
read est une primitive du shell
~/Bureau$ sudo find / -type f -name "read"
/usr/share/zsh/help/read



SUS explique mieux que moi :
| The read utility historically has been a shell built-in. It was sepa‐
| rated off into its own utility to take advantage of the richer descrip‐
| tion of functionality introduced by this volume of
| IEEE Std 1003.1-2001.
|
| Since read affects the current shell execution environment, it is gen‐
| erally provided as a shell regular built-in. If it is called in a sub‐
| shell or separate utility execution environment, such as one of the
| following:
|
| (read foo)
| nohup read ...
| find . -exec read ... ;
|
| it does not affect the shell variables in the environment of the call‐
| er.

<http://www.opengroup.org/onlinepubs/009695399/utilities/read.html>

--
Benoit Izac
Avatar
Patrick Lamaizière
Francois Lafont :

C'est curieux que time envoie son résultat sur stderr, mais bon.



Non ça permet de séparer la sortie de la commande exécutée de la
sortie de time.
Avatar
Benoit Izac
Bonjour,

le 25/08/2010 à 00:10, Francois Lafont a écrit dans le message
<4c744356$0$2866$ :

Mais pourtant, chez moi, les commandes "builtin" ne sont pas toutes dans
le $PATH.

~$ type cd
cd est une primitive du shell
~/Bureau$ sudo find / -type f -name "cd"
/usr/share/X11/xkb/symbols/cd
/usr/share/screen/utf8encodings/cd
/usr/share/zsh/help/cd



Forcément, si tu fork puis tu fais un cd, lorsque tu vas revenir, tu
n'auras pas beaucoup bougé.



Je ne comprends pas trop ce que tu veux dire (je ne suis pas très calé
en Linux, déjà le mot fork ça me fait un peu peur). Tu disais que les
commandes builtin était dans le $PATH, je voulais juste montrer que sur
mon ordinateur la commande 'cd' (qui est builtin d'après ~$ type cd)
n'était pas dans mon $PATH.



Lorsque tu es dans ton shell et que tu exécutes une commande par exemple
/bin/ls, le shell va forker, c'est-à-dire créer un nouveau processus
dans lequel il va exécuter ta commande. Cette commande ne peut pas
modifier l'environnement de son père (qui est ton shell). Si la commande
est cd, tu vas changer de répertoire dans le processus qui exécute cd
mais lorsque cd se termine, tu reviens à ton shell et tu perds ce
changement.

Un exemple vaut mieux que de beaux discours :
$ pwd
/
$ echo $$
4209 # notre shell à pour PID 4209 et on est dans /
$ sh # on crée un nouveau shell
$ echo $$
29085 # un nouveau processus a été crée
$ pwd
/ # on conserve l'environnement du père
$ cd /tmp
$ pwd
/tmp # on a changé de répertoire
$ exit # on quitte le shell (celui avec 29085 comme PID)
exit
$ echo $$
4209 # on est bien revenu dans le précédent
$ pwd
/ # on a pas bougé...

--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 25/08/2010 à 00:49, Francois Lafont a écrit dans le message
<4c744c83$0$10144$ :

Un exemple vaut mieux que de beaux discours :



Merci pour cet exemple, c'est très clair et instructif pour moi. En
revanche je ne vois pas trop le rapport avec mon exemple de départ «~$
sudo find / -type f -name "cd"» qui était là simplement pour justifier
qu'il n'y avait pas de programme "cd" dans le $PATH. :-)



C'est que tu n'as toujours pas compris ce que je tente de t'expliquer :
une commande /bin/cd ne servirait à rien, elle ferait la même chose que
mon exemple précédent lorsque tu sors du deuxième shell (on a pas
bougé...).

Mais puisque tu y tiens tellement :
$ cat main.c
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
extern int errno;
int ret;

if (argc != 2)
return 1;
ret = chdir(argv[1]);
if (ret != 0)
fprintf(stderr, "%s %s: %s.n", argv[0], argv[1], strerror(errno));

return ret;
}
$ gcc -o cd main.c
Ensuite tu peux essayer :
$ ./cd /root
$ ./cd /usrbinlocal
$ ./cd /tmp

Note que tu auras le comportement attendu pour « ./cd . ».

--
Benoit Izac
1 2 3