如何在仍然使用的同时增强内置 shell 功能

How to enhance a built in shell function while still using it

大多数时候我不仅喜欢查看特定命令的位置,还喜欢查看它是什么。 一个例子 which lsd 告诉我这个命令是有效的并且存在于 /usr/local/bin/lsd,但是更有趣的信息:它是一个 link 到 ../Cellar/lsd/0.16.0/bin/lsd 这告诉我它是一个管理的命令通过自制程序。

所以为了同时看到两者,我想创建一个别名。但是别名似乎不能很好地处理参数,甚至对于可能有效的简单命令,我也没有让它与内联命令执行一起使用,例如$(which )。 接下来我创建了一个 shell 函数来正确使用命令参数:

function dings() {
  command=`which `
  echo $command
  eval "$command --version" # might not be supported by all commands
  ll $command
}

这个函数有点像我想要的那样:

除了一件事:我必须记住函数名称并使用它而不是 which。 所以我尝试为该函数设置别名,但他产生了奇怪的东西,因为这会导致递归调用自身——这很糟糕。 由于这不是命令,我也不能使用它的确切位置来省略这个 "bug".

所以问题是:如何用我自己的函数替换内部 shell 函数 which 仍然使用默认值 which?

另外:我怎样才能显示所有找到的相关命令实例? 因此,就我而言,我的系统中有两个版本的 lsd。路径中的第一个是较旧的 brew 版本,路径中的第二个是 cargo 版本。

解决方案:

function which() {
    IFS='
'
    set -f
    for LINE in `type -a `; do
        COMMAND=`echo $LINE | cut -d ' ' -f 3`
        if [[ $COMMAND = /* ]]; then
            version=`$COMMAND --version 2>/dev/null` # might not work with all commands
            [[ -n "$version" ]] && version="($version)"
            echo " is $COMMAND $version"
            ll $COMMAND
        else
            echo $LINE
        fi
    done
}

你的问题的直接解决方案,"how can I select which which to use" 是内置的 command 来抑制 shell 函数查找:

which() {
    command which ""
    "" --version
    ll "$(command which "")"
}

这也避免了不必要的 eval 并且不使用临时变量。如果要避免 运行ning which 两次,可以使用临时变量,但不要将其泄漏到环境中:

which() {
    local whichpath
    whichpath=$(command which "")
    printf '%s\n' "$whichpath"
    "" --version
    ll "$whichpath"
}

但是您可以完全避免使用外部命令 which,而是使用内置命令 type

type() {
    local typepath
    typepath=$(command type -p "")
    printf '%s\n' "$typepath"
    "" --version
    ll "$typepath"
}

请注意,如果您使用它来查找不是可执行文件的内容,这将会中断。

或者,如果你真的想迷惑未来的自己,你可以调用函数 which,但在后台使用 type

which() {
    local typepath
    typepath=$(type -p "")
    printf '%s\n' "$typepath"
    "" --version
    ll "$typepath"
}

旁注:这使用 ll,一个别名,通常在非交互式 shells 中禁用(例如当 运行ning 脚本时);不过,在定义了 ll 的交互式会话中,它很可能是 运行。只知道如果你在脚本中使用它,你最好使用 ls -l 而不是 ll 别名。