I'd like to be able to keep statistics on which programs I run the most through bash. Is there any way to insert some sort of hook into bash so that it logs everything it execs?
Note that looking through the bash history file isn't good enough. I can print out the first token from each line of the history, but that doesn't get pipelines and process substitution. I'd like the following:
$ ls /usr/bin/* | fgrep $(echo grep)
to log that ls
, fgrep
, and echo
were each run once. And the following:
$ for file in /usr/bin/*; do stat $file; echo $file; done
should note that stat
and echo
were run. Since for
is a bash flow control statement, it wouldn't be logged.
It's debatable whether shell built-ins and functions should be logged (maybe just logged with a note about what they were). It's also debatable whether stat
and echo
should be logged once or however many times the loop runs in the above example. But I could work with the output whichever way was easiest.
Running bash with -x
shows that it does have some internal mechanism to hook into the exec
process and log what's happening. Is there any other way to get in there?
Best Answer
As a first cut at it,
for non-smoketest use you'd have to redirect stderr to some logger pipe, or litter some poor directory somewhere with files using strace's
-o
, maybe-o ~/commandtraces/$(date +%Y%m%d%H%M%S).$$
To do it for all interactive shells I'm thinking you'd need a guard variable in your
.bashrc
to avoid recursion.