测量启动新的交互式 bash shell 时读取历史文件所花费的时间

测量启动新的交互式 bash shell 时读取历史文件所花费的时间

如果我有一个sleep命令或其他东西减慢了 的执行速度.bashrc,我可以对其进行分析以查看缓慢的部分,如下所示:

$ printf "set -x\nPS4='+\\\\t '\nexport  HISTFILE=empty\nsleep 4\ntrue\n" > mybashrc
$ > empty
$ time bash --rcfile mybashrc -i <<< exit
+ PS4='+\t '
+19:13:47 export HISTFILE=empty
+19:13:47 HISTFILE=empty
+19:13:47 sleep 4
+19:13:51 true
$ exit
+19:13:51 exit
exit

real    0m4.022s
user    0m0.010s
sys     0m0.010s

其他 选项 使用 GNU 获得更高的精度date

但是假设我有一个很大的 bash 历史文件,如下所示:

$ yes ls | head -n 9999999 > big-hist
$ du -sh big-hist
29M     big-hist

现在 shell 启动也很慢(在我的机器上大约四秒),但我看不到时间花在哪里,只是在.bashrc.

$ printf "set -x\nPS4='+\\\\t '\nexport HISTSIZE=-1\nexport HISTFILESIZE=-1\nexport HISTFILE=big-hist\ntrue\n" > mybashrc
$ time bash --rcfile mybashrc -i <<< exit
+ PS4='+\t '
+19:12:23 export HISTSIZE=-1
+19:12:23 HISTSIZE=-1
+19:12:23 export HISTFILESIZE=-1
+19:12:23 HISTFILESIZE=-1
+19:12:23 export HISTFILE=big-hist
+19:12:23 HISTFILE=big-hist
+19:12:23 true
$ exit
+19:12:27 exit
exit

real    0m4.184s
user    0m3.641s
sys     0m0.536s

我能想到的最好的猜测是运行这个:

$ time bash -i <<< exit
$ SHLVL=2 $ exit
exit

real    0m0.400s
user    0m0.326s
sys     0m0.075s

然后添加最后一行.bashrc

HISTFILE=/dev/null

并再次运行:

$ time bash -i <<< exit
$ exit
exit

real    0m0.081s
user    0m0.059s
sys     0m0.023s

尽管我不完全确定这仅测量处理历史文件所花费的时间。

(注意:如果您自己尝试此操作,请务必记住.bashrc 在计时完成后删除最后一行!)

这对我来说特别感兴趣,因为我已经有好几年了 已启用 无限的历史 在我中.bashrc ,我注意到新的交互式 shell 的启动时间受到了影响;如果上述计时准确的话,延迟超过 300 毫秒。

答案1

我看不出有什么理由不相信你的测量结果。

但你可以跑bash过去strace;然后您会看到文件打开的顺序:

$ strace -t -f -e trace=file bash -i <<<exit 2>&1 | grep -E 'open(at)?\(' ; fg
[...]
03:10:39 openat(AT_FDCWD, "/home/hl/.bashrc", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/home/hl/.DISPLAY", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
03:10:39 openat(AT_FDCWD, "/etc/inputrc", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/etc/inputrc.keys", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/etc/inputrc.keys", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/etc/inputrc.keys", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/home/hl/.inputrc", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/home/hl/.bash_history", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/home/hl/.bash_history", O_RDONLY) = 4
03:10:39 openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 4

我不知道为什么这fg是必要的。也许这是我的 shell 配置中将 shell 发送到后台的内容。

相关内容