Bash

哪個程式碼在 bash 和 zsh 中都可以使用 time 關鍵字工作(使用內置函式)?

  • January 21, 2020

通常在 bash 中time cmd對許多類型的(s) 執行以下操作:cmd

$ time true
real    0m0.000s
user    0m0.000s
sys     0m0.000s

可以更改輸出格式(甚至可以更改為帶有 time -p 的 posix 格式):

$ TIMEFORMAT='real %R'; time true
real 0.000

但是 zsh 不報告簡單命令的時間(也可以嘗試time echo):

% time true

將命令轉換為管道會報告其他內容:

$ zsh -c 'time echo yes | cat'
yes
echo yes  0.00s user 0.00s system 26% cpu 0.001 total
cat  0.00s user 0.00s system 85% cpu 0.002 total

可以強制 shell 使用 subshel​​l 給出時間輸出(…)

$ zsh -c 'time ( true )'
( true; )  0.00s user 0.00s system 26% cpu 0.005 total

但這不適用於{…}, 也不適用於以下內置函式for

$ zsh -c 'time { for i in $(seq 100); do ls; done >/dev/null; }'

zsh 的時間怎麼能在沒有 subshel​​l 的情況下接受簡單的命令。

或者,一個更簡單的問題:

有沒有辦法使用 time 關鍵字編寫在 ksh、bash、zsh 中工作的程式碼?

time不計時命令。 Single Unix Specification的基本原理

使用術語實用程序而不是command來強調不能直接使用 shell 複合命令、管道、特殊內置程序等這一事實。

SUS還指出,time特殊內置命令的結果是未定義的,並且它在用於除簡單命令以外的任何東西(在管道或命令組上)時的結果是未指定的。

這是因為time不需要特殊的 shell 語法,也不需要內置命令。並且在第一次標準化時是否有很大的變化,現在變化很大。

  • 在 Almquist 和 (Heirloom) Bourne shell 中,time既不是保留字也不是內置命令。它是一個外部命令,因此不能應用於除簡單命令之外的任何內容。BSD 上的外部time命令使用wait4()庫函式從核心返回的程序使用資訊,如果要對 shell 內置命令和管道進行計時,則要求被計時的程序是 shell。因此,諸如time bindkey找不到要執行的實用程序之類time echo的事情,以及諸如時間操作外部 echo命令而不是 shell 內置命令之類的事情。
  • 在 C shell 中,time是一個內置命令,不能應用於除簡單命令以外的任何內容。 time通過查看wait4()庫函式的結果來工作,這需要子程序等待。因此,C shelltime 總是派生一個子程序,即使對於其他內置命令也是如此。你會發現像time bindkey -v什麼都沒有,因為它們是在子程序中執行的time
  • 在 Korn 和 Bourne Again shell 中,time是 shell 語法中的保留字,可應用於管道。這些 shell 不使用wait4()庫函式返回的子程序使用資訊,而是通過將呼叫的命令括起來getrusage()並進行減法計算時間。
  • 在 Z shell 中,time是 shell 語法中的保留字,可應用於管道。Z shell 確實使用wait4()庫函式從核心返回的程序使用資訊,但不強制對內置命令進行分叉。因此,當沒有派生子程序時,它不會報告任何內容(就像內置命令一樣true);但反過來說,time set -o vi實際上取得了一些成就。

正如其基本原理所述,單一 Unix 規範措辭寬鬆,以允許所有各種行為。它指向計時外殼內置命令存在問題的方向。

引用自:https://unix.stackexchange.com/questions/562790