如何在 fish 中的别名中运行别名?

如何在 fish 中的别名中运行别名?

我别名sudoplease 带有空格

$ alias please='sudo '
$ please ll

我已经在 Fish 中尝试过这个,但是它不起作用:

$ alias please='sudo '
$ please ll
sudo: ll: command not found

答案1

这里的问题不是嵌套别名。这本身将工作,尽管(正如@muru 在评论中指出的那样)与 Bash 略有不同。例如:

$ alias a ls
$ alias b type
$ b a
a is a function with definition
# Defined via `source`
function a --wraps=ls --description 'alias a ls'
  ls $argv; 
end

sudoFish 别名的问题有两个方面:

  • 首先,为您的用户定义了一个别名,但是当您 时sudo,您不再是“您的用户”。里面的 fish 配置sudo是用户的配置root。不幸的是,Bash 优雅的附加“空格”解决方案对 Fish 不起作用。

  • Bash 的“尾随空格”解决方法是在将第二个别名传递给第一个别名之前对其进行扩展,但alias please='sudo '在 Fish 中不可用。例如,在前面的例子中,在 Bash 中,您可以使用alias b='type '强制扩展atols并运行type结果而不是别名

    在我看来,这绝对是 Bash 比 Fish 拥有(更)清晰解决方案的一个领域。

对于 Fish 来说,有几种可能的解决方法,但我认为它们都相当“黑客化”,甚至我自己的也是如此。

首先,正如我在 [这个 Stack Overflow 答案] 中提到的那样,您可以sudo按如下方式定义您的别名:

function please --wraps=sudo --description 'alias please sudo'
    if functions -q -- "$argv[1]"
        set cmdline (
            for arg in $argv
                printf "\"%s\" " $arg
            end
        )
        set -x function_src (string join "\n" (string escape --style=var (functions "$argv[1]")))
        set argv fish -c 'string unescape --style=var (string split "\n" $function_src) | source; '$cmdline
        command sudo -E $argv
    else
        command sudo $argv
    end
end

我可能需要一点时间才能记住我是如何得出这个结论的,所以我留下了一个带有解释的评论版本这里

虽然你可能考虑在 root 用户的 Fish 配置中定义别名,但请注意sudo运行外部命令,因此它仍然不会以这种方式运行别名,除非你询问新的 fish进程来运行它。例如:

$ sudo -s
$ alias -s ll "ls -l"
funcsave: wrote /root/.config/fish/functions/ll.fish
$ exit # back to normal user
$ sudo fish -c "ll"
$ sudo ll
sudo: ll: command not found
$ sudo fish -c "ll -n /"
total 1436
lrwxrwxrwx   1 0 0       7 Apr 23  2020 bin -> usr/bin
drwxr-xr-x   2 0 0    4096 Apr 23  2020 boot
...

相关内容