Bash
為什麼內置時間在管道中不起作用?
我有以下範例腳本:
#!/usr/bin/env bash sleep 5 printf "times cmd: " times printf "pipeline: " times | ( read user sys; echo $user; ) printf "head: " times | head -n1 printf "times cmd again: " times
具有以下輸出:
$ ./test.sh times cmd: 0m0.003s 0m0.005s 0m0.001s 0m0.001s pipeline: 0m0.000s head: 0m0.000s 0m0.000s times cmd again: 0m0.003s 0m0.006s 0m0.003s 0m0.004s
問題是,為什麼
times
命令在與管道一起使用時會重置時間?有沒有辦法避免它以解析值?
在管道中,所有命令都在子 shell 中執行。
times
報告外殼及其子外殼所花費的時間,但不報告其父外殼所花費的時間。您可以嘗試替換程序:
times > >( head -n1 ) times > >( read user sys ; echo $user )
這是我們正在談論的外殼的問題。
在這個外殼上,我得到:
$ times 0m9.805s 0m3.372s 39m29.072s 0m15.537s
因為它已經執行了一段時間。
但是,子 shell 將報告零:
$ ( times ) 0m0.000s 0m0.000s 0m0.000s 0m0.000s
並且,由於管道在其每個部分的子外殼中執行:
$ sleep 10 | times 0m0.000s 0m0.000s 0m0.000s 0m0.000s
如果您執行上面的命令,您應該會
times
立即看到輸出(因為它不依賴於管道)並且 shell 提示符會在 10 秒後返回。解決方法?
留在“這個”外殼中:
$ times > >(read user sys; echo "$user")
那麼,為什麼需要時間?可以
time
或更強大的功能/usr/bin/time
為您工作嗎?使用時間:
$ TIMEFORMAT="%R;%U;%S"; time { sleep 1; } 1.001;0.000;0.000 $ TIMEFORMAT="%U"; time { sleep 1; } #### If you only want user. 0.000
將幾個過程括在大括號中:
$ time { wc /etc/hosts; sleep 2; } 21 115 327 /etc/hosts real 0m2.003s user 0m0.000s sys 0m0.000s
使用更強大的外部
time
(遺憾的是它只適用於外部執行檔):$ /usr/bin/time wc /etc/hosts 21 115 327 /etc/hosts 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 534maxresident)k 0inputs+0outputs (0major+109minor)pagefaults 0swaps