Skip to main content

Forcing an 'added' alias to every command [Resolved]

Is it possible to forcibly add a timing alias (for lack of a better way to phrase it) to every command in bash?

For example, I would like to have a specific user who whenever a command is run, it is always wrapped either with date before and after, or time.

Is this possible, and, if so, how?

Question Credit: warren
Question Reference
Asked March 10, 2018
Posted Under: Unix Linux
4 Answers

Your options here are going to depend on your shell. In zsh there a convenient hook function called preexec() that is run right before any interactive shell commands. By creating a function with this name, you can cause things to be executed. You can also follow up with a function called precmd() which will run just before the next prompt is drawn, which will be right after your command finishes.

By creating this pair of functions, you can have whatever arbitrary commands you want run before and after whatever commands are issued at the prompt. You could use this to log shell usage, create locks, test the environment, or as in your example calculate time or resources spent while a command runs.

In this example, we will create ourselves a benchmark timestamp before running a command using preexec() then calculate the time spent executing the command using precmd() and output it before the prompt or log it away. Example:

preexec() {
   CMDSTART=$(date +%s%N)
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."

Note: For this particular example, there is an even easier builtin function. All you have to do is turn on runtime reporting in ZSH and it will do this automatically.

$ export REPORTTIME=0
$ ls -d
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

In a more practical implementation of preexec(), I use it see if the shell is running inside tmux or screen and, if so, to send information about the currently running command upstream to be displayed in the tab name.

Unfortunately in bash this little mechanism doesn't exist. Here is one man's attempt to replicate it. Also see Gilles's answer for similar nifty little hack.

credit: Jeff Schaller
Answered March 10, 2018

The easiest way would probably to set PROMPT_COMMAND. See Bash Variables:

If set, the value is interpreted as a command to execute before the printing of each primary prompt ($PS1).

For example, to avoid overwriting any existing prompt command, you could do:


credit: cjm
Answered March 10, 2018

csh/tcsh has the best support for this feature (and has always had it).

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

In other words, set time=1 will print out the time consumed (system, user, elapsed) by any command that took more than 1 second of cpu time. Plain set time will enable printing out the time for all commands.

credit: alexis
Answered March 10, 2018
Your Answer