sudo为什么忽略别名?


22

我正在运行Ubuntu 10.04,并upstart用于守护程序管理。我的企业应用程序作为守护程序运行,由于各种特权,必须作为root用户运行。例如:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

我想介绍一个alias将这些命令缩写为:

alias startapp='sudo start my-application-long-ID'

并以它的方式运行它startapp,但我希望别名中没有sudo。

alias startapp='start my-application-long-ID'

使用时不sudo startapp返回,返回sudo: startapp: command not found

但是,当我添加别名时:

alias sudo='sudo '

sudo startapp 现在可以使用,但我仍然好奇sudo为什么忽略别名。


你跑了source ~/.bashrc吗?这将更新.bashrc文件并使新别名可用吗?
manu 2014年

@manu是的,我做到了
两栖游戏

Answers:


35

我从这里看到以下信息。

使用sudo时,请使用别名扩展(否则sudo会忽略您的别名)

alias sudo='sudo '

这里不解释的原因。

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


6

别名和功能在外壳中定义。Sudo是一个外部程序。所以sudo看不到别名,函数或shell内置函数,只看到外部命令。

别名是备用命令名称,因此外壳程序仅在命令位置扩展它们,而不是在它们作为命令参数时扩展它们。Zsh支持全局别名,全局别名可以在命令行的任何位置扩展,因此最好谨慎使用,因为即使在别名没有意义的情况下,也存在意外扩展它们的风险。

您可以告诉sudo调用shell :sudo sh -c '…shell command here…'。但是,您通常的别名在该shell命令中将不可用,因为它们通常存储在诸如~/.bashrc或的文件中,而该文件~/.zshrc只能由交互式shell读取。

alias sudo='sudo 'Ramesh提出的,使shell在之后扩展别名sudo


1
alias sudo='sudo 'ZSH 是否也适用?
CMCDragonkai

2
@CMCDragonkai是
吉尔斯(

1

适用于zsh用户的解决方案

在bash和zsh中,以空格结尾的别名将使Shell别名扩展下一个单词。这允许类似以下内容的别名扩展myalias

alias 'sudo=sudo '
sudo myalias

不幸的是,当您的别名中包含一个以上的单词时(例如,sudo -u someone。),这种情况就消失了。但是,您可以滥用zsh的“全局别名”功能来在命令中的任何位置手动扩展别名。

alias -g '$= '

这将创建一个全局别名$(可以使用任何单词),该别名以空格结尾。这会使zsh扩展下一个单词作为常规命令别名。由于别名扩展为空格,因此不会将其视为参数。这样可以进行以下工作。

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

$如果您有复杂的命令嵌套,甚至可以在一个命令行上多次使用。我发现它足够有用,可以在zshrc中永久保留,但是别名足够简单,可以定义何时需要使用它。


0

我只是在这里给出了一个替代答案而没有sudo使用别名重新定义。

您的情况是:

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

一站式,无额外的外壳,无别名重新定义。;-)


等等,我明白了,您正在使用xargs该功能删除引号,而使用grep删除该行的开头=。有点聪明,但可能没有必要。eval "sudo $(alias aliasname | cut -d= -f2-)"可能会更好- xargs不一定总能正确处理报价,而且报价可能不止一个=
mikeserv

@mikeserv很抱歉,您没有收到它;-) xargs不要去除引号。是grep从引号之间获取已解析的命令。您知道会type -a alias_name返回类似的信息alias_name is aliased to command_within_quotes。顺便说一句我已经试过你的命令,并没有在我的Ubuntu :-(工作是它的回归。type -aLinux版本之间的不同(我怀疑它)?
loved.by.Jesus

我知道这有什么typebash。但是,您知道引号是加倍的吗?您是否尝试过使用包含单引号的别名?无论如何,您对我的东西不起作用是正确的-您需要eval "sudo sh -c "$(...eval "'sudo $(alias alias_name| cut -d\' -f2-)"。事情是aliases基本上是预先安排的evals- alias实用程序指定输出其内容,以便可以将其安全地重新输入到shell中。我猜你xargs是实现扁平化空白了吗?请小心一点,好吗?
mikeserv
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.