在 PATH 中运行与现有函数同名的可执行文件

在 PATH 中运行与现有函数同名的可执行文件

有时我定义一个函数来隐藏可执行文件并调整其参数或输出。因此该函数与可执行文件具有相同的名称,我需要一种如何从函数运行可执行文件而不递归调用该函数的方法。例如,要自动运行fossil diffthrough的输出colordiffless -R我使用:

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" "$@" | colordiff | less -R
        return
    fi
    "$EX" "$@"
}

如果我确定可执行文件的位置,我只需键入/usr/bin/fossil. Bash 认为这/意味着该命令是可执行文件,而不是函数。但由于我不知道具体位置,所以我只能打电话which确认结果。有没有更简单的方法?

答案1

使用command内置的 shell:

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

在脚本中,该#!行经常用于/bin/env bash根据路径运行 bash 命令。 (对于某些实用程序来说可能有所不同)。这在这里也应该起作用......

command替代方案也应该有效,但可能依赖于特定的 shell)(它适用于 Solaris 上的 Bourne Shell,但它实际上/bin/command在这种情况下运行,它是 Bash 上内置的 shell)

/bin/command和都/bin/env在 SUS 中列出,因此所有合规实施都应该包含它。

答案3

格特的回答让我意识到人们nice也可以用于这一目的(实际上我在我的一个脚本中已经有了它,但没有意识到):

$ 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

它不如其他答案那么优雅,但在某些情况下它可能是一个有用的选择。

相关内容