问题描述
我今天在玩别名,我注意到在使用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
时,你有什么理由不能使用别名?
最佳解决方案
将以下行添加到您的~/.bashrc
:
alias sudo='sudo '
Aliases allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the alias and unalias builtin commands.
The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The characters ‘/’, ‘$’, ‘`’, ‘=’ and any of the shell metacharacters or quoting characters listed above may not appear in an alias name. The replacement text may contain any valid shell input, including shell metacharacters. The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias ls to “ls -F”, for instance, and Bash does not try to recursively expand the replacement text. If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion.
(强调我的)。 Bash只检查一个命令的第一个单词作为别名,之后的任何单词都不检查。这意味着在像sudo ll
这样的命令中,只有第一个字(sudo
)被bash检查作为别名,ll
被忽略。我们可以通过在别名的末尾添加空格来告诉bash检查别名后面的下一个单词(即sudo
)。
次佳解决方案
我为它写了一个Bash函数,用于阴影sudo
。
它会检查给定命令是否有别名,并在此情况下运行别名命令而不是使用sudo
的文本命令。
这是我的功能one-liner:
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
文件中,不要忘记提供它或重新启动您的终端会话以应用更改。
第三种解决方案
别名是用户特定的 – 您需要在/root/.bashrc
中定义它们
第四种方案
@Alvins答案是最短的一个。毫无疑问! 🙂
不过,我想到了一个命令行解决方案,可以在sudo中执行别名命令,而无需使用alias
命令重新定义sudo
。
这是我对那些可能感兴趣的人的建议:
解决方案
type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo
例子
在ll
命令的情况下
type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo
Explanation
当有别名时(例如:ll
),命令type -a
将返回别名表达式:
$type -a ll
ll is aliased to `ls -l'
使用grep
,您可以在该情况下选择重音符`和撇号’之间的文本ls -l
并且xargs
执行所选文本ls -l
作为sudo
的参数。
是的,有点长,但完全干净;-)不需要重新定义sudo
作为别名。