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