'Time' çıktısını bir dosyaya yaz, neden parantez gerekiyor?


18

timeyazıyor için stderr, biri olduğu varsayılabilir, böylece ekleyerek 2>&1yönlendirmeniz gereken onun çıkışına komut satırına stdout. Ancak bu işe yaramaz:

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

Sadece parantez ile çalışır:

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

Bu durumda neden parantez gereklidir? Neden tek bir komut time wcolarak yorumlanmıyor ?


3
Sonuçların time, kabuk anahtar kelimesi olup olmamasına bağlı olarak değişeceğini unutmayın /usr/bin/time. Burada çeşitli tanımlayıcılar olabilir (kabuğun ve bir timesürece bağlı olanlar ). Ve ()alt kabuğun ima ettiği şeyleri unutmayalım . ( bir bash uzmanı bekliyor : p)
John WH Smith

Yanıtlar:


24

In ksh, bashve zsh, timebir komut (yerleşik veya değil), bu gibi dilde ayrılmış bir kelime değildir forya while.

Bir boru hattını zamanlamak için kullanılır 1 .

İçinde:

time for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

Kabuğa o boru hattını çalıştırmasını söyleyen özel bir sözdiziminiz var:

for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

Ve bunun için zamanlama istatistiklerini rapor edin.

İçinde:

time cmd > output 2> error

Bu, aynı konum oluyor zamanlamacmd > output 2> error komutu ve zamanlama istatistikler yine kabuk, standart hataya gidin.

Gerekenler:

{ time cmd > output 2> error; } 2> timing-output

Veya:

exec 3>&2 2> timing-output
time cmd > output 2> error 3>&-
exec 2>&3 3>&-

Kabuğun stderr'ının timing-outputzaman yapısından önce yeniden yönlendirilmesi için (yine komut değil ) (burada zaman zaman cmd > output 2> error 3>&-).

Bu timeyapıyı , stderr'sinin yeniden yönlendirildiği bir alt kabukta da çalıştırabilirsiniz :

(time cmd > output 2> error) 2> timing-output

Ancak bu alt kabuk burada gerekli değildir, sadece timeyapı çağrıldığında yönlendirilmek için stderr'a ihtiyacınız vardır .

Çoğu sistemde bir timekomut vardır. timeAnahtar kelimeyi devre dışı bırakarak bunu çağırabilirsiniz . Yapmanız gereken tek şey anahtar kelime olarak bir şekilde anahtar kelimenin sadece değişmez olarak tanındığını belirtmektir.

'time' cmd > output 2> error-and-timing-output

Ama biçimi farklıdır ve her ikisi stderr'si olabilir dikkat timeve cmdbirleştirilecek error-and-timing-output.

Ayrıca, timekomut, timeyapının aksine, boru hatlarını veya bileşik komutları veya işlevleri veya kabuk yerleşiklerini zamanlayamaz ...

Yerleşik bir komut olsaydı, işlev çağırmalarını veya yerleşikleri zamanlayabilir, ancak yeniden yönlendirmeleri veya boru hatlarını veya bileşik komutları zamanlayamazdı.


1 Not bash(NE olarak kabul edilebilir) bir hata , burada time (cmd) 2> file(ancak time cmd | (cmd2) 2> fileörneğin) zamanlama çıkış yönlendirirfile


Sık sık kafamı vurgulayarak timebunun bir kabuk yerleşimi değil, bir anahtar kelime olduğunu hatırlıyorum .
cuonglm

'time'Çalıştırmak için kullanma ipucu için teşekkürler - yazmaktan daha kullanışlı /usr/bin/time(hatta command time:-)).
alexis

@alexis de \time.
ctrl-alt-delor

7

Orada adlı herhangi bir komut var time wc, timeve wcayrılır sözcüğü kabukta.

Şimdi, çoğu zaman oradayız iki ayrı programı adında timebir kabuk anahtar kelimedir, başka bir harici komuttur . timeBir kabuk anahtar kelimesi olan kabuklarda , yazdığınızda time wc ...kabuk time, harici zaman yardımcı programı yerine anahtar sözcüğünü kullanır .

Kabuk timeanahtar sözcüğü kullandığında , yeni işlemin çatallanması () gerekmez , geçerli timestandart ve standart hata değiştirilmez. Yönlendirme bölümü:

time wc file > wc.out 2>&1

wcsadece etkiler .

Bileşik komut(list) kullandığınızda :

(time wc file) > wc.out 2>&1

Kabuk ran time wc filebir kabuktaki içinde, (time wc file)bir kabul edildi , tek bir komut ve yönlendirme parçası artık hem de onun standart çıktı ve standart hata, etkiler timeve wc.


Başka bir gruplama komutu kullanarak yeni işlem isteme maliyeti olmadan aynı etkiyi yapabilirsiniz {list;}:

{time wc file;} > wc.out 2>&1

Harici kullanıyorsanız time, yeni işlemde çalıştırıldığı için bu sorunla karşılaşmazsınız:

/usr/bin/time wc file > wc.out 2>&1

Kullanma arasında herhangi bir pratik fark var mı timeve /usr/bin/time? Yürütülebilir dosyalar işlevsel olarak aynı mı adlandırılıyor?
Hashim

2

Çünkü timeidam yapıyorsun. Bash bunu çok özel bir şekilde işler.

Gerçek timeikili kullanacaksanız , tam olarak beklediğiniz şekilde hareket edecektir:

/usr/bin/time wc file > wc.out 2>&1

Bu zamanın çıktısı biraz farklı olsa da:

 $ /usr/bin/time wc file > wc.out 
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata1900maxresident)k
0inputs+8outputs (0major+82minor)pagefaults 0swaps

9
Eğer bir yerleşik olsaydı, sorun olmazdı. Sorun, dilde bir anahtar kelime olmasıdır . time cmd > outputçarpı cmd > outputkomut ve time foo | barçarpı foo | bar.
Stéphane Chazelas

1

timeZaman bilgisini yazan şey bu değildir . Yerleşik time, komut tamamlandıktan sonra kabuğun bunu yazmasını sağlar. Ancak yeniden yönlendirme yalnızca komutu etkiler.

In (time ...)durumda yönlendirme bütün alt kabuğa uygulanır.


0

Zaman bir kabuk yerleşik olduğundan, yazar kabuk yerine komutun stderr'e daha 'ın stderr'e.

Parantez kullanmak tüm komutu stderr yönlendirilebilen bir çocuk kabuğuna zorlar.

Kıvırcık parantez kullanmak, aslında bir alt kabuk başlatmadan benzer bir sonuç üretir

  { time who ; } > /tmp/timwho >& /tmp/xx 

(evet, noktalı virgül gerekir)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.