使用 sudo 时别名不可用

使用 sudo 时别名不可用

我今天正在玩别名,我注意到在使用时别名似乎不可用sudo

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

使用时不能使用别名的原因是什么sudo

答案1

将以下行添加到您的~/.bashrc

alias sudo='sudo '

来自bash 手册

别名允许将字符串替换为简单命令的第一个单词。shell 维护一个别名列表,可以使用 alias 和 unalias 内置命令设置和取消设置这些别名。

检查每个简单命令的第一个单词(如果没有引号)是否有别名。如果是,则该单词将被别名的文本替换。字符 '/'、'$'、'`'、'=' 以及上面列出的任何 shell 元字符或引号字符都不能出现在别名中。替换文本可以包含任何有效的 shell 输入,包括 shell 元字符。替换文本的第一个单词会进行别名测试,但与正在扩展的别名相同的单词不会再次扩展。这意味着可以将 ls 别名为“ls -F”,而 Bash 不会尝试递归扩展替换文本。如果别名值的最后一个字符是空格或制表符,则还会检查别名后面的下一个命令字是否进行别名扩展

(重点是我加的)。Bash
只检查命令的第一个字是否为别名,不检查其后的任何字。这意味着在类似 的命令中, bash 只检查sudo ll第一个字( )是否为别名,其余的字将被忽略。我们可以通过在别名值的末尾添加一个空格来告诉 bash 检查别名后的下一个字(即)。sudollsudo

答案2

我为它编写了一个 Bash 函数来隐藏sudo

它检查我是否有给定命令的别名,并sudo在这种情况下运行别名命令而不是文字命令。

这是我的单行功能:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

或者格式很好:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

您可以将其附加到您的.bashrc文件中,但不要忘记随后获取它或重新启动您的终端会话以应用更改。

答案3

别名是用户特定的 - 您需要在/root/.bashrc

答案4

我有另一个不错的解决方案,它也增加了一点信任:

使用 bash 完成功能sudo在按下 Tab 键时自动用其别名替换后面的单词。

将其保存为/etc/bash_completion.d/sudo-alias.bashcomp,它将在交互式 shell 启动时自动加载:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

然后登录到一个新的终端,就可以了。

相关内容