你如何正确设置别名 sudo='nocorrect sudo '?

Mik*_*H-R 6 linux sudo zsh

直到最近我alias sudo='sudo '在我的.zshrc档案中。今天我在尝试时遇到了这个错误sudo mv

?  ~  sudo mv nginx.conf.orig nginx.conf.orig2
sudo: nocorrect: command not found
Run Code Online (Sandbox Code Playgroud)

现在谷歌搜索我发现这似乎与一些前缀为 的命令有关nocorrect,我可以用alias sudo='nocorrect sudo'.

但是,当我尝试将别名设置alias sudo='nocorrect sudo '为允许自己使用其他别名时,问题就出现了。我还确保我的 su 正在使用这里提到的 zsh 。

?  ~  alias sudo='nocorrect sudo '            
?  ~  sudo mv nginx.conf.orig nginx.conf.orig2
sudo: nocorrect: command not found
?  ~  alias sudo='nocorrect sudo'                           
?  ~  sudo mv nginx.conf.orig nginx.conf.orig2
?  ~  su
Password: 
michaelarch# ps -p $$
  PID TTY          TIME CMD
25831 pts/1    00:00:00 zsh
Run Code Online (Sandbox Code Playgroud)

有没有人对如何解决这个问题有任何建议?

编辑:alias sudo='sudo '允许您在 sudo 命令中使用别名,示例见下文。

?  ~  alias cat='echo hello'     
?  ~  echo goodbye > example.txt
?  ~  cat example.txt           
hello example.txt
?  ~  sudo cat example.txt 
goodbye
?  ~  alias sudo='sudo '
?  ~  sudo cat example.txt
hello example.txt
Run Code Online (Sandbox Code Playgroud)

有关我的外壳的更多信息:

?  ~  sudo chsh                               
Changing shell for root.
New shell [/usr/bin/zsh]:    
?  ~  unalias sudo; alias sudo='nocorrect sudo '
?  ~  echo $SHELL; which sudo                   
/usr/bin/zsh
sudo: aliased to nocorrect sudo 
?  ~  sudo mv nginx.conf.orig2 nginx.conf.orig  
sudo: nocorrect: command not found
?  ~  which mv
mv: aliased to nocorrect mv
Run Code Online (Sandbox Code Playgroud)

mpy*_*mpy 6

该行为可通过以下方式重现:

alias sudo='nocorrect sudo '
alias mv='nocorrect mv '
Run Code Online (Sandbox Code Playgroud)

因此,执行sudo mv foo bar此操作时将扩展为

nocorrect sudo nocorrect mv foo bar
Run Code Online (Sandbox Code Playgroud)

并抛出错误,因为nocorrect是 shell 保留字,无法由 sudo 处理。

mv 别名被扩展的原因是您定义alias sudo='nocorrect sudo '了一个尾随空白,这在之后启用别名扩展。如果没有尾随空白,这个例子可以工作,但是你完全失去了在 sudo 之后使用别名的能力。

通常在 sudo 之后进行别名扩展的解决方法,但为了防止在与 sudo 一起使用时sudo mv转义mv命令时出现错误:

sudo \mv foo bar
Run Code Online (Sandbox Code Playgroud)

这可以防止 mv 的别名扩展。


Mik*_*H-R 6

好的,我已经研究了一段时间并在 zsh 邮件列表中找到了一些东西。似乎没有一个“银弹”解决方案,而是一堆不同的解决方案,它们可以做不同的事情。我将发布我所做的事情(这有点像警察),但也会探索其他方法及其问题。我个人会去:

?  ~  alias sudo='sudo '
?  ~  alias nsudo='nocorrect sudo'
Run Code Online (Sandbox Code Playgroud)

编辑:

我现在要和

sudo \mv foo bar
Run Code Online (Sandbox Code Playgroud)

对于@mpy 在备用答案中描述的我需要这个的情况。

/编辑

因为它可以让我在大多数时间使用别名,当他们抱怨因为别名不正确时我可以使用,nsudo这样我就不会不小心破坏我的文件。

更好的方法来自 zsh 邮件列表。我似乎发现了两个线程。其中1999年在这里(这是问题,请参见后续起坐,尤其是这一个解决了noglob问题,我不能确定它是否解决了nocorrect以及(不noglob nocorrect暗示?否则我不认为是这样,请评论)

alias sudo='my_sudo '

function my_sudo {
    while [[ $# > 0 ]]; do
        case "$1" in
        command) shift ; break ;;
        nocorrect|noglob) shift ;;
        *) break ;;
        esac
    done
    if [[ $# = 0 ]]; then
        command sudo zsh
    else
        noglob command sudo $@
    fi
}
Run Code Online (Sandbox Code Playgroud)

从我的问题中满足我的两个要求:

?  ~  alias cat='echo hello'     
?  ~  echo goodbye > example.txt
?  ~  sudo cat
hello
?  ~  sudo mv example.txt2 example.txt
Run Code Online (Sandbox Code Playgroud)

似乎这在 2008年再次出现邮件列表中,解决方案如下:

alias sudo='noglob do_sudo '
function do_sudo
{
    integer glob=1
    local -a run
    run=( command sudo )
    if [[ $# -gt 1 && $1 = -u ]]; then
        run+=($1 $2)
        shift ; shift
    fi
    (($# == 0)) && 1=/bin/zsh
    while (($#)); do
        case "$1" in
        command|exec|-) shift; break ;;
        nocorrect) shift ;;
        noglob) glob=0; shift ;;
        *) break ;;
        esac
    done
    if ((glob)); then
        PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $~==*
    else
        PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $==*
    fi
}
Run Code Online (Sandbox Code Playgroud)

这似乎做了很多我承认不完全理解的事情。这似乎忽略了自动更正(如作者所述)。