Jak mogę przekierować wyjście `time` i wydać polecenie do tego samego potoku?


24

Załóżmy, że mam plik binarny o nazwie foo.

Jeśli chcę przekierować wyjście foodo jakiegoś innego procesu bar, mógłbym pisać ./foo | bar.

Z drugiej strony, jeśli chciałem timefoo i przekierować wyjście z timeMógłbym pisać time (./foo) | bar.

Moje pytanie brzmi: w jaki sposób mogę przykleić wyjście timedo końca fooi przepuścić przez tę samą rurę ?

Poniższe rozwiązanie nie jest tym, czego szukam, ponieważ uruchamia dwa oddzielne wystąpienia procesu bar, podczas gdy chcę pojedynczego udostępnionego potoku, do pojedynczego wystąpienia bar.

time (./foo | bar)  | bar

Dla każdego, kto jest ciekawy, powodem, dla którego nie chce się uruchamiać dwóch instancji, barjest to, że barmoże to być klient sieciowy i chcę, aby informacje o taktowaniu były wysyłane do serwera jako część tego samego http POSTkomunikatu co wynik procesu.


odpowiedział tutaj, nieco lepsza odpowiedź: stackoverflow.com/questions/13356628/…
JDS 20'18

Odpowiedzi:


29

Jeśli zrozumiem, o co prosisz, zrobię to. Używam polecenia ls ~i teejako stand-in dla ./fooi bar, ale z ogólnej postaci, co chcesz, to:

$ ( time ./foo ) |& bar

UWAGA: Wyjście z timejest już dołączane na końcu dowolnego wyjścia ./foo, po prostu robi się to na STDERR. Aby przekierować go przez potok, musisz połączyć STDERR ze STDOUT. Możesz użyć jednego |&lub drugiego, 2>&1aby to zrobić.

$ ( time ./foo ) |& bar

-or-

$ ( time ./foo ) 2>&1 | bar

Przykład

$ ( time ls . ) |&  tee cmd.log
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s

A oto zawartość pliku cmd.logwyprodukowanego przez tee.

$ more cmd.log 
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s

Zauważ, że ta składnia nie działa dla BASH.
jvriesem

1
@jvriesem wszystkie przykłady pochodzą z bash
slm

9

timedomyślnie wysyła dane wyjściowe do stderr zamiast stdout. Musisz tylko przekierować to tam, gdzie chcesz.

Mówisz „Z drugiej strony, gdybym chciał timesfałszować i przekierować dane wyjściowe time, mogłem pisać time (./foo) | bar”. ale to w rzeczywistości jest nieprawidłowe. W takim przypadku wynik czasu będzie nadal wyświetlany na konsoli, przekierowywane będzie tylko standardowe wyjście.

Możesz przekierować stderr w szczególności za pomocą:

(time foo) 2>&1 | bar

lub wszystkie rury z:

(time foo) |& bar

Nawiasy są potrzebne do poprawnego działania.


0

Odkryłem, że działa to w systemie Solaris. (time ls) &> file


1
Nie różni się to od żadnego z istniejących rozwiązań
roaima
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.