Chcę time
polecenia składającego się z dwóch oddzielnych poleceń z jednym wyjściem potokowym do drugiego. Weźmy na przykład dwa poniższe skrypty:
$ cat foo.sh
#!/bin/sh
sleep 4
$ cat bar.sh
#!/bin/sh
sleep 2
Jak mogę time
zgłosić czas foo.sh | bar.sh
(i tak, wiem, że fajka nie ma tutaj sensu, ale to tylko przykład)? Działa zgodnie z oczekiwaniami, jeśli uruchamiam je sekwencyjnie w podpowłoce bez instalacji:
$ time ( foo.sh; bar.sh )
real 0m6.020s
user 0m0.010s
sys 0m0.003s
Ale nie mogę go uruchomić podczas instalacji:
$ time ( foo.sh | bar.sh )
real 0m4.009s
user 0m0.007s
sys 0m0.003s
$ time ( { foo.sh | bar.sh; } )
real 0m4.008s
user 0m0.007s
sys 0m0.000s
$ time sh -c "foo.sh | bar.sh "
real 0m4.006s
user 0m0.000s
sys 0m0.000s
Przeczytałem podobne pytanie ( Jak uruchomić czas na wielu poleceniach ORAZ zapisać czas wyjściowy do pliku? ), A także wypróbowałem samodzielny time
plik wykonywalny:
$ /usr/bin/time -p sh -c "foo.sh | bar.sh"
real 4.01
user 0.00
sys 0.00
To nawet nie działa, jeśli utworzę trzeci skrypt, który uruchamia tylko potok:
$ cat baz.sh
#!/bin/sh
foo.sh | bar.sh
A potem czas, że:
$ time baz.sh
real 0m4.009s
user 0m0.003s
sys 0m0.000s
Co ciekawe, nie wydaje się, że time
kończy się natychmiast po wykonaniu pierwszego polecenia. Jeśli zmienię bar.sh
na:
#!/bin/sh
sleep 2
seq 1 5
I time
znowu spodziewałem się, że time
wydruk zostanie wydrukowany przed, seq
ale nie jest to:
$ time ( { foo.sh | bar.sh; } )
1
2
3
4
5
real 0m4.005s
user 0m0.003s
sys 0m0.000s
Wygląda na to, time
że nie liczy czasu wykonania bar.sh
pomimo oczekiwania na zakończenie przed wydrukowaniem raportu 1 .
Wszystkie testy zostały uruchomione w systemie Arch i przy użyciu wersji bash 4.4.12 (1). Mogę użyć bash tylko do projektu, który jest częścią tego, więc nawet jeśli zsh
jakaś inna potężna powłoka może go obejść, nie będzie to dla mnie realnym rozwiązaniem.
Jak mogę uzyskać czas potrzebny na uruchomienie zestawu potoków? A skoro już to robimy, dlaczego to nie działa? Wygląda na to, że time
natychmiast kończy działanie, gdy tylko zakończy się pierwsze polecenie. Czemu?
Wiem, że mogę uzyskać indywidualne czasy za pomocą czegoś takiego:
( time foo.sh ) 2>foo.time | ( time bar.sh ) 2> bar.time
Ale nadal chciałbym wiedzieć, czy jest możliwe, aby całość czasu zaplanować jako pojedynczą operację.
1 To nie wydaje się być problemem z buforem, próbowałem uruchomić skrypty z, unbuffered
a stdbuf -i0 -o0 -e0
liczby były nadal drukowane przed time
wyjściem.