Bash哪個程式碼在 bash 和 zsh 中都可以使用
哪個程式碼在 bash 和 zsh 中都可以使用 time
關鍵字工作(使用內置函式)?
通常在 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 使用 subshell 給出時間輸出
(…)
:$ 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 的時間怎麼能在沒有 subshell 的情況下接受簡單的命令。
或者,一個更簡單的問題:
有沒有辦法使用 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 規範措辭寬鬆,以允許所有各種行為。它指向計時外殼內置命令存在問題的方向。