time
pisze do stderr
, więc można by założyć, że dodanie 2>&1
do wiersza poleceń powinno kierować jego wynik stdout
. Ale to nie działa:
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
Działa tylko z nawiasami:
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
Dlaczego w tym przypadku potrzebne są nawiasy? Dlaczego nie jest time wc
interpretowane jako jedno polecenie?
io-redirection
shell-builtin
wilko-rewo-koty
źródło
źródło
time
jest słowem kluczowym powłoki, czy/usr/bin/time
. Może być tu zaangażowanych kilka zestawów deskryptorów (powłoki i tych dołączonych dotime
procesu). I nie zapominajmy o tych sugerowanych przez()
podpowłokę. ( czekając na specjalistę od bash : p)Odpowiedzi:
W
ksh
,bash
azsh
,time
nie jest poleceniem (wbudowane lub nie), to słowo zarezerwowane w języku podobnegofor
lubwhile
.Służy do pomiaru czasu potoku 1 .
W:
Masz specjalną składnię, która każe powłoce uruchomić tę linię potoku:
I zgłoś dla niego statystyki czasowe.
W:
To ten sam, jesteś rozrządu na
cmd > output 2> error
komendę, a statystyki czasowe nadal iść na stderr przez powłokę.Potrzebujesz:
Lub:
Aby stderr powłoki został przekierowany,
timing-output
zanim zostanie użyta konstrukcja czasu (ponownie, nie polecenie ) (tutaj do czasucmd > output 2> error 3>&-
).Możesz także uruchomić tę
time
konstrukcję w podpowłoce , której przekierowanie stderr:Ale ta podpowłoka nie jest tutaj potrzebna, wystarczy stderr, aby zostać przekierowanym w momencie
time
wywołania konstrukcji.Większość systemów ma także
time
polecenia. Możesz je wywołać, wyłączająctime
słowo kluczowe. Wszystko, co musisz zrobić, to jakoś zacytować to słowo kluczowe, ponieważ słowa kluczowe są rozpoznawane jako takie tylko w dosłownym znaczeniu.Ale uwaga, format może być inny, a stderr obu
time
icmd
zostanie połączonyerror-and-timing-output
.Ponadto
time
polecenie, w przeciwieństwie dotime
konstrukcji, nie może mierzyć czasu potoków lub poleceń złożonych, funkcji lub wbudowanych powłok ...Gdyby było to polecenie wbudowane, mogłoby ono być w stanie określić czas wywołań funkcji lub poleceń wbudowanych, ale nie byłoby w stanie określić czasu przekierowań, potoków ani poleceń złożonych.
1 Zauważ, że
bash
ma (co można uznać za) błąd, przez którytime (cmd) 2> file
(ale nietime cmd | (cmd2) 2> file
na przykład) przekierowuje wyjście taktowania dofile
źródło
time
to słowo kluczowe, a nie wbudowana powłoka.'time'
z pliku wykonywalnego - wygodniejszego niż pisanie/usr/bin/time
(a nawetcommand time
:-)).\time
.Nie ma polecenia o nazwie
time wc
,time
iwc
są oddzielone słowo w skorupkach.Teraz często występują dwa osobne programy o nazwie
time
, jeden to słowo kluczowe powłoki, drugi to polecenie zewnętrzne . W powłokach, któretime
są słowem kluczowym powłoki, podczas pisaniatime wc ...
, powłoka używała swojego słowa kluczowegotime
zamiast zewnętrznego narzędzia czasu .Kiedy powłoka używa
time
słowa kluczowego, nie musi rozwidlać () nowego procesu, aktualnytime
standard i standardowy błąd nie są zmieniane. Część przekierowania w:dotyczy
wc
tylko.Gdy używasz polecenia złożonego
(list)
:powłoka działała
time wc file
w podpowłoce,(time wc file)
została uznana za pojedyncze polecenie, a część przekierowania wpływa na jej standardowe wyjście i standardowy błąd, które teraz obejmują zarównotime
iwc
.Możesz uzyskać ten sam efekt bez kosztów tworzenia nowego procesu, używając innej formy polecenia grupowania
{list;}
:Jeśli używasz zewnętrznego
time
, nie napotykasz tego problemu, ponieważ został uruchomiony w nowym procesie:źródło
time
a/usr/bin/time
? Czy pliki wykonywalne są wywoływane funkcjonalnie tak samo?Ponieważ
time
wykonywane jest wbudowane bash. Bash przetwarza to w specjalny sposób.Jeśli użyjesz prawdziwego
time
pliku binarnego, będzie on działał dokładnie tak, jak tego oczekujesz:Chociaż wynik tego czasu jest nieco inny:
źródło
time cmd > output
razycmd > output
polecenie itime foo | bar
czasyfoo | bar
.To nie jest tak,
time
że zapisuje informacje o czasie. Wbudowanetime
powoduje, że powłoka zapisuje to po zakończeniu polecenia. Ale przekierowanie wpływa tylko na polecenie.W
(time ...)
przypadku, gdy przekierowanie jest stosowane do całej podpowłoki.źródło
Ponieważ czas jest wbudowany w powłokę, zapisuje do stderr powłoki , a nie do stderr polecenia.
Użycie nawiasów powoduje, że całe polecenie staje się powłoką potomną, której stderr można przekierować.
użycie nawiasów klamrowych daje podobny wynik bez faktycznego uruchamiania podpowłoki
(tak, potrzebujesz średnika)
źródło