time
écrit dans stderr
, donc on pourrait supposer que l'ajout 2>&1
à la ligne de commande devrait acheminer sa sortie vers stdout
. Mais cela ne fonctionne pas:
test@debian:~$ cat file
one two three four
test@debian:~$ time wc file > wc.out 2>&1
real 0m0.022s
user 0m0.000s
sys 0m0.000s
test@debian:~$ cat wc.out
1 4 19 file
Seulement avec des parenthèses, cela fonctionne:
test@debian:~$ (time wc file) > wc.out 2>&1
test@debian:~$ cat wc.out
1 4 19 file
real 0m0.005s
user 0m0.000s
sys 0m0.000s
Pourquoi des parenthèses sont-elles nécessaires dans ce cas? Pourquoi n'est-il pas time wc
interprété comme une seule commande?
io-redirection
shell-builtin
loup-revo-chats
la source
la source
time
s'agit du mot clé shell ou/usr/bin/time
. Il peut y avoir plusieurs ensembles de descripteurs impliqués ici (ceux du shell et ceux attachés à untime
processus). Et n'oublions pas ceux qu'implique le()
sous - shell. (en attente d'un spécialiste bash : p)Réponses:
Dans
ksh
,bash
etzsh
,time
n'est pas une commande (intégrée ou non), c'est un mot réservé dans la langue commefor
ouwhile
.Il est utilisé pour chronométrer un pipeline 1 .
Dans:
Vous avez une syntaxe spéciale qui indique au shell d'exécuter cette ligne de tuyau:
Et rapportez des statistiques de synchronisation pour cela.
Dans:
C'est la même chose, vous chronométrez la
cmd > output 2> error
commande et les statistiques de chronométrage vont toujours sur le stderr du shell.Vous avez besoin:
Ou:
Pour que le stderr du shell soit redirigé vers
timing-output
avant que la construction de temps (encore une fois, pas de commande ) soit utilisée (ici pour le tempscmd > output 2> error 3>&-
).Vous pouvez également exécuter cette
time
construction dans un sous - shell dont le stderr est redirigé:Mais ce sous-shell n'est pas nécessaire ici, vous n'avez besoin que de stderr pour être redirigé au moment où la
time
construction est invoquée.La plupart des systèmes ont également une
time
commande. Vous pouvez l'invoquer en désactivant letime
mot clé. Tout ce que vous avez à faire est de citer ce mot-clé, car les mots-clés ne sont reconnus comme tels que lorsqu'ils sont littéraux.Mais attention, le format peut être différent et le stderr des deux
time
etcmd
sera fusionnéerror-and-timing-output
.De plus, la
time
commande, contrairement à latime
construction, ne peut pas chronométrer les pipelines ou les commandes ou fonctions composées ou les commandes intégrées au shell ...S'il s'agissait d'une commande intégrée, elle pourrait peut-être chronométrer les invocations de fonctions ou les commandes intégrées, mais elle ne pourrait pas chronométrer les redirections ou les pipelines ou les commandes composées.
1 Notez qu'il
bash
existe (ce qui peut être considéré comme) un bogue par lequeltime (cmd) 2> file
(mais pastime cmd | (cmd2) 2> file
par exemple) redirige la sortie de synchronisation versfile
la source
time
c'est un mot-clé, pas un shell intégré.'time'
l'exécutable - plus pratique que d'écrire/usr/bin/time
(ou mêmecommand time
:-)).\time
.Il n'y a pas de commande nommé
time wc
,time
etwc
sont séparés mot dans la coquille.Maintenant, il y a souvent deux programmes distincts nommés
time
, l'un est un mot-clé shell, un autre est une commande externe . Dans les shells quitime
est un mot-clé shell, lorsque vous tapeztime wc ...
, le shell a utilisé son mot-clétime
au lieu de l' utilitaire de temps externe .Lorsque le shell utilise un
time
mot clé, il n'a pas besoin de fork () un nouveau processus, latime
norme actuelle et l'erreur standard ne sont pas modifiées. La partie redirection dans:affecte
wc
uniquement.Lorsque vous utilisez la commande composée
(list)
:le shell s'exécutait à l'
time wc file
intérieur d'un sous-shell,(time wc file)
était considéré comme une seule commande, et la partie de redirection affecte sa sortie standard et son erreur standard, qui incluent désormais les deuxtime
etwc
.Vous pouvez faire le même effet, sans avoir à forger un nouveau processus en utilisant une autre forme de commande de regroupement
{list;}
:Si vous utilisez externe
time
, vous ne rencontrez pas ce problème, car il a été exécuté dans un nouveau processus:la source
time
et/usr/bin/time
? Les exécutables sont-ils appelés fonctionnellement de la même manière?Parce
time
que vous exécutez est intégré à bash. Bash le traite d'une manière si spéciale.Si vous utilisez un vrai
time
binaire, il agira exactement de la façon dont vous vous y attendez:Bien que la sortie de cette époque soit un peu différente:
la source
time cmd > output
fois lacmd > output
commande, ettime foo | bar
foisfoo | bar
.Ce n'est pas
time
cela qui écrit les informations de temps. Le programme intégrétime
fait écrire au shell ceci une fois la commande terminée. Mais la redirection affecte uniquement la commande.Dans le
(time ...)
cas où la redirection est appliquée à l'ensemble du sous-shell.la source
Parce que le temps est un shell intégré, il écrit dans le stderr du shell , plutôt que dans le stderr de la commande.
L'utilisation de parenthèses force la commande entière dans un shell enfant dont stderr peut être redirigé.
l'utilisation de crochets produit un résultat similaire sans réellement démarrer un sous-shell
(oui, vous avez besoin du point-virgule)
la source