使用sudo时别名不可用


158

我今天在玩别名,发现在使用时别名似乎不可用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


您是否在/ root /的.bashrc中声明了这些别名
Luciano Facchinelli

2
@LucianoFacchinelli:/root/.bashrc通过sudo运行命令时不会被读取。
Flimm


@Flimm:那sudo -i呢?
Evi1M4chine

Answers:


249

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

alias sudo='sudo '

bash手册

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

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

(强调我的)。
Bash仅检查命令的第一个单词是否有别名,之后的任何单词都不会被检查。这意味着在诸如的命令中sudo llsudobash仅检查第一个单词()是否存在别名,将ll被忽略。sudo通过在别名值的末尾添加一个空格,我们可以告诉bash检查别名之后的下一个单词(即)。


18
相当不错的解决方案。
ulidtko 2011年

因此,从根本上讲,问题可以归结为以下事实:sudo只是以不检查别名的方式进行编程,因此找不到ll?
kemra102 2011年

2
阅读文档显然对很多人有利:-)
biocyberman

4
如果我使用sudo标志,这会中断sudo -H ll吗?
Mark E. Haase

1
@mehaase是的,我试过了,它坏了。
user31389

5

我为此写了一个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文件中,但不要忘了将其来源或稍后重新启动终端会话以应用更改。


如果这也适用于sudo -H ll,那就太好了。
uav

3

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


3
他们已经在/root/.bashrc下,所以这不是问题
kemra102'1

1
仅当您以root身份运行shell本身时(例如,使用sudo -sor或sudo -i(并且通过自身运行以获取根shell,而不是使用sudo -s command...or sudo -i command...形式)运行)或sudo bashsudo su,这种情况下的答案才是正确的启用了root登录并以这种方式拥有root shell。当非root用户sudo command...从自己的shell 运行时,别名扩展由他们自己的非root shell完成。sudo本身不会扩展别名,因此应用于问题中描述的情况时,此答案是错误的。
伊利亚·卡根

3

@Alvins答案是最短的答案。毫无疑问!:-)

但是我想到了一种命令行解决方案,可以在sudo执行别名命令,而无需sudo使用alias命令重新定义。

这是我对可能感兴趣的人的建议:

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

ll命令的情况下

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

说明

当您有别名(例如:)时,ll该命令type -a将返回别名表达式:

$type -a ll
ll is aliased to `ls -l'

grep在这种情况下,您可以选择重音符号“和”之间的文字ls -l

xargs执行所选文本ls -l作为的参数sudo

是的,更长一些,但完全干净;-)无需重新定义sudo别名。


3
如果使用alias内置功能,可能会更简单,因为它的输出更干净。alias ll输出alias ll='ls -ahlF'
muru

以下是结合@muru建议的版本:alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo
ACK_stoverflow,2016年

我认为原始问题的重点在于不必sudo -i首先运行别名命令而是立即执行该命令来节省工作。拥有如此复杂的命令会打败它。您可以只做前者,并且更快。
Evi1M4chine

1

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

sudo按下Tab键时,可使用bash补全功能自动将后面的单词替换为其别名。

将其另存为/etc/bash_completion.d/sudo-alias.bashcomp,它应该在交互式外壳启动时自动加载:

_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

然后登录到新终端,您应该一切顺利。


有一种方法可以获取别名列表,尤其是要完成的别名:compgen -a
muru

@muru:谢谢,但是在这种情况下,我需要值,而不是键。因此,输入的别名将被替换。键入别名(如中的sudo ll),按[TAB↹],脚本将ll在别名分配列表中找到,剪掉为其分配的内容,并将其插入。(所以您会得到例如sudo ls -lahvF --color=auto --time-style=long-iso。)
Evi1M4chine

0

我有一个不同的解决方案,您不需要将其添加sudo为别名。我运行Linux Mint 17.3,但它应该与Ubuntu非常相似。

当您是root用户时,.profile它将从其主目录运行。如果您不知道根目录下的主目录是什么,则可以使用以下命令进行检查:

sudo su
echo $HOME

如您所见,的所在地root/root/。检查其内容:

cd $HOME
ls -al

应该有一个.profile文件。打开文件并添加以下行:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

基本上,此bash脚本所做的是检查名为的文件.bash_aliases。如果文件存在,它将执行文件。

保存.profile文件并在中创建别名.bash_aliases。如果您已经准备好别名文件,则将文件复制到此位置

重新启动终端,您一切顺利!


0

票数最高的答案是一个很好的答案。但是,如果您键入sudo -i并提升到sudo提示符(#),则不会有您要使用的别名。

要在#提示符下使用您的别名(以及其他所有内容),请使用:

sudo cp "$PWD"/.bashrc /root/.bashrc

将“ $ PWD”自动扩展为“ / home / YOUR_USER_NAME”


0

@ WinEunuuchs2Unix:$PWD扩展到“当前工作目录”。我想你要$HOME

另外,在大多数情况下,最好是具有单独的根.bashrc文件。实际上,我会/root在用户的主目录(例如.bashrc_root)中将其创建为一个真实文件,并对其进行软链接,然后从用户的.bashrc文件中获取该文件。如果此特权用户帐户不再存在,则该根.bashrc文件仍可用于其他用户。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.