我正在尝试改进 zsh 点文件的执行,并且需要对子脚本的执行进行计时。我的代码中有一段.zshrc
如下所示的代码:
typeset -U config_files
config_files=($DOTFILES/**/*.zsh)
for file in ${(M)config_files}
do
source file
done
我想做的是这样的:
for file in ${(M)config_files}
do
\time -f %E source file
done
但不幸的是,我得到的答复是这样的:
time: cannot run source: No such file or directory
我哪里做错了?
答案1
source
是内置命令,而不是外部命令,因此使用外部命令time
来计时没有意义。请执行以下任一操作:
TIMEFMT=%E
for file in ${(M)config_files}
do
time (source file)
done
或者:
for file in ${(M)config_files}
do
\time -f %E zsh -c 'source "$1"' zsh "$file"
done
在前者中,子外壳是必要的,因为:
附加说明:应用于当前 shell 中执行的任何构造的 time 内置命令将被默默忽略。因此,尽管在语法上可以在 time 关键字后立即放置一个打开的花括号或 repeat-loop 等,但您不会获得任何时间统计信息。您必须改用括号来强制使用子 shell,然后对其进行计时。
在后一种情况下,您将为每个文件启动一个新的 zsh 实例。因此,在这两种情况下,都无法轻松地对依赖脚本进行计时(即,一个配置文件执行了另一个配置文件所需的操作或以某种方式影响了另一个配置文件)。或者,您可以time
在每个源之后保存输出,这将为您提供累积计时:
TIMEFMT=%E
{time} 2> times
for file in ${(M)config_files}
do
source file
{time} 2>> times
done
然后您可以使用awk
或其他方法来获取单独的时间:
awk 'NR != 1 {print $0 - prev} {prev = $0; getline}' times
答案2
我看了看man time
命令,注意到
Users of the bash shell need to use an explicit path in order to run
the external time command and not the shell builtin variant. On system
where time is installed in /usr/bin, the first example would become
所以我猜你应该提供时间路径。请注意,我没有使用 zsh 的经验