Make bash use external `time` command rather than shell built-in
You can use the command
shell built-in to bypass the normal lookup process and run the given command as an external command regardless of any other possibilities (shell built-ins, aliases, etc.). This is often done in scripts which need to be portable across systems, although probably more commonly using the shorthand \
(as in \rm
rather than command rm
or rm
, as especially the latter may be aliased to something not known like rm -i
).
$ time
real 0m0.000s
user 0m0.000s
sys 0m0.000s
$ command time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
[--portability] [--format=format] [--output=file] [--version]
[--quiet] [--help] command [arg...]
$
This can be used with an alias, like so:
$ alias time='command time'
$ time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
[--portability] [--format=format] [--output=file] [--version]
[--quiet] [--help] command [arg...]
$
The advantage of this over e.g. alias time=/usr/bin/time
is that you aren't specifying the full path to the time
binary, but instead falling back to the usual path search mechanism.
The alias
command itself can go into e.g. ~/.bashrc or /etc/bash.bashrc (the latter is global for all users on the system).
For the opposite case (forcing use of the shell built-in in case there's an alias defined), you'd use something like builtin time
, which again overrides the usual search process and runs the named shell built-in. The bash man page mentions that this is often used in order to provide custom cd
functionality with a function named cd
, which in turn uses the builtin cd
to do the real thing.
There is a shortcut in bash to sidestep keywords, without having to specify a path or use another builtin like command
: Escape it with a backslash.
=^_^= izkata@Izein:~$ time
real 0m0.000s
user 0m0.000s
sys 0m0.000s
=^_^= izkata@Izein:~$ \time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
[--portability] [--format=format] [--output=file] [--version]
[--quiet] [--help] command [arg...]
Personally, I find this more readable and safer, as this is possible:
=^_^= izkata@Izein:~$ alias command=echo
=^_^= izkata@Izein:~$ command time
time
The general solutions for built-ins (for example test) are [1]:
use
env
(all shells)$ env test external test
disable the builtin (only bash and zsh):
$ test 1 = 1 && echo "yes" yes $ enable -n test ### for bash. Re-enable with "enable test". $ disable test ### for zsh. Re-enable with "enable test". $ test external test
use any slash
/
to call the command (all shells):$ test 1 = 1 && echo "yes" yes $ ~/bin/test external test
make an alias (fails inside a bash script, except if
shopt -s expand_aliases
is used):$ alias test='~/bin/test' ### remove with 'unalias test'. $ test external test
But time is not a builtin.
The word time
is a "Reserved word", not a command and neither a built-in.
That enable this solutions:
Quote the word. This does not work with built-ins.
Many forms of quoting work:\time
"time"
'time'
ti\me
ti"me"
, etc.$ time real 0m0.000s user 0m0.000s sys 0m0.000s $ \time Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose] [--portability] [--format=format] [--output=file] [--version] [--quiet] [--help] command [arg...]
This is useful to bypass an alias. Even if
test
is aliased,\test
will execute the PATHed command (or the builtin if it has not been disabled).Use the builtin
command
(this does not work with built-ins):$ command time
As above for built-ins, using any slash
/
works:$ /usr/bin/time
As above for built-ins, an alias also work here:
$ alias time='command time' $ alias time='/usr/bin/time'
[1] Lets assume there is an external executable in ~/bin/test
that prints "external test". And further: lets assume that ~/bin
is ahead of /bin
in the active PATH.