0

If I had a sleep command or something else slowing down execution of .bashrc, I can profile it to see the slow parts like this:

$ 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

with other options for higher precision using GNU date.

But suppose I have a large bash history file, something like this:

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

Now the shell startup is also slow (about four seconds on my machine), but I can't see where the time is being spent, only that it's some time after the last command of the .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

The best guess I can think of is to run this:

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

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

then add the last line of the .bashrc:

HISTFILE=/dev/null

and run again:

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

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

although I'm not entirely sure this measures only the time spent processing the history file.

(Note: if you try this for yourself, it is highly important to remember to remove the last line of the .bashrc once the timing is complete!)

This is of particular interest to me because I have for several years enabled unlimited history in my .bashrc and have noticed the startup time of new interactive shells has been impacted; by more than 300 ms, if the timing above is accurate.

1

I do not see a reason not to trust your measurement.

But you can run bash through strace; then you see in which order the files are opened:

$ 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

I don't know why the fg is necessary. Maybe that is something in my shell config that sends the shell to the background.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.