Sometimes I define a function that shadows an executable and tweaks its arguments or output. So the function has the same name as the executable, and I need a way how to run the executable from the function without calling the function recursively. For example, to automatically run the output of fossil diff through colordiff and less -R I use:

function fossil () {
    local EX=$(which fossil)
    if [ -z "$EX" ] ; then
        echo "Unable to find 'fossil' executable." >&2
        return 1
    if [ -t 1 ] && [ "$1" == "diff" ] ; then
        "$EX" "$@" | colordiff | less -R
    "$EX" "$@"

If I'd be sure about the location of the executable, the I could simply type /usr/bin/fossil. Bash recognizes that / means the command it's an executable, not a function. But since I don't know the exact location, I have to resort to calling which and checking the result. Is there a simpler way?

  • 1
    You say, “Bash recognizes that / means the command is an executable, not a function.”  Strictly speaking, that’s not true.  In what I believe to be a horrible (and undocumented) design decision, bash allows function names to contain slashes.  The slashes simply cause /usr/bin/fossil to be a different string from fossil, so, when you say /usr/bin/fossil, it doesn’t try to run the fossil function. – G-Man Jul 11 '18 at 18:40

Use the command shell builtin:

bash-4.2$ function date() { echo 'at the end of days...'; }

bash-4.2$ date
at the end of days...

bash-4.2$ command date
Mon Jan 21 16:24:33 EET 2013

bash-4.2$ help command
command: command [-pVv] command [arg ...]
    Execute a simple command or display information about commands.

    Runs COMMAND with ARGS suppressing  shell function lookup, or display
    information about the specified COMMANDs.  Can be used to invoke commands
    on disk when a function with the same name exists.
  • 2
    One more options is to escape the command \date. – jordanm Jan 21 '13 at 15:47
  • 4
    @jordanm, that works only for aliases. The question was about functions. pastebin.com/TgkHQwbb – manatwork Jan 21 '13 at 15:54

Gert's answer made me realize that one can use nice for the purpose too (I actually had it in one of my scripts without realizing it):

$ function date() { echo 'at the end of days...'; }
$ date
at the end of days...
$ nice -n0 date
Mon Jan 21 16:45:21 CET 2013

It's less elegant than the other answers, but in some circumstances it could be an useful option.

  • You may want to expand this to include a similar alternative: `which date`. – Eliah Kagan Jan 22 '13 at 3:10
  • 1
    @EliahKagan The problem with `which something` is that if there is no something executable, unfortunate things can happen. For example if echo is missing then `which echo` /bin/rm preciousFile does something very different than intended. – Petr Pudlák Jan 22 '13 at 8:39

In scripts, the #! line often use /bin/env bash to run the bash command based on the path. (It might differ for some utilities). This should work here as well...

(The command alternative should also work, but might be dependant on a specific shell) (It works on the Bourne Shell on Solaris, but it actually runs /bin/command in that case, which it is a shell built-in on Bash)

Both /bin/command and /bin/env is listed in SUS, so all compliant implementations should have it.

  • Thanks for pointing out env. I was in doubts which answer should I accept, but since the question is about bash, its built-in command is the best solution. – Petr Pudlák Jan 21 '13 at 15:43
  • 1
    On my Linux there is no command executable, but command also works in dash, ksh and zsh. So I assume it is a shell builtin not only in bash. pastebin.com/fi3gyNse – manatwork Jan 21 '13 at 16:08
  • It is not a buildin on Solaris 10 Bourne (That is also available as heirloom-sh). The advantages of an executable with a known path is that it can't be overwritten by a function. – Gert van den Berg Jan 22 '13 at 7:25
  • (The absence of /bin/command might explain why scripts use /bin/env after the hash-bang if they do not want to hard-code the shell path) – Gert van den Berg Jan 24 '13 at 12:17

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.