Running an executable in PATH with the same name as an existing function

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
    fi
    if [ -t 1 ] && [ "$1" == "diff" ] ; then
        "$EX" "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c9ed89">[email protected]</a>" | colordiff | less -R
        return
    fi
    "$EX" "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="96b2d6">[email protected]</a>"
}

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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.

Method 3

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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x