如果我有一个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
但是假设我有一个很大的 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 发送到后台的内容。