如何通过sudo传递别名


32

我有一个别名,可以将一些参数传递给我经常使用的工具。有时我自己跑,有时在sudo下跑。不幸的是,当然,sudo无法识别别名。

有没有人暗示如何通过别名?

在这种情况下,调试时我有很多perl选项:

alias pd='perl -Ilib -I/home/myuser/lib -d'

有时,我必须以root用户身份调试工具,因此,不要运行:

pd ./mytool --some params

我需要在sudo下运行它。我尝试了很多方法:

sudo eval $(alias pd)\; pd ./mytool --some params
sudo $(alias pd)\; pd ./mytool --some params
sudo bash -c "$(alias pd)\; pd ./mytool --some params"
sudo bash -c "$(alias pd); pd ./mytool --some params"
sudo bash -c eval\ "$(alias pd)\; pd ./mytool --some params"
sudo bash -c eval\ "'$(alias pd)\; pd ./mytool --some params'"

我希望有一种简洁的好方法来确保我当前的pd别名得到充分使用(以防以后需要调整),尽管我的某些尝试根本不够简洁。我的最后一招是将其放入shell脚本中,并将其放置在sudo能够找到的地方。但是有时别名很方便,所以这是不得已的方法。

Answers:


50

可以在Archlinux-Wiki中找到一个非常优雅的解决方案:

alias sudo='sudo '
# whitespace ---^

用于将所有别名传递给sudo

资料来源:http : //wiki.archlinux.org/index.php/Sudo#Passing_aliases


16
这是一个很棒的把戏!出于好奇,bash手册页中别名部分的解释:A trailing space in value causes the next word to be checked for alias substitution when the alias is expanded.
Russell Davis

1
这确实应该是公认的答案。
AdrianFrühwirth'13

遗憾的是,这不适用于功能。
Ciro Santilli新疆改造中心法轮功六四事件

2
注意:假设你需要传递一个选项sudo一遍,同时希望保持该sudo-passthrough伎俩在同一时间。甚至可以做到这一点:要再次使用选项,请使用\sudo。反斜杠将覆盖别名。(许多人似乎对此一无所知)。这样,您甚至可以(危险!)删除文件而不会发出任何警告,只需键入即可覆盖在中alias rm='rm -i'通常指定的文件。.bash-aliases\rm file-to-delete
语法错误

11

我不清楚您要做什么。我可以看到两种方式:

正确的方式

alias pd='sudo perl -Ilib -I/home/myuser/lib -d'

然后执行pd ./mytool将以root身份执行调试命令,但仍保留sudo的好处(审计跟踪,而不是在root shell之外操作)。

例:

insyte $ alias sid ='sudo id'
insyte $ sid
uid = 0(root)gid = 0(root)组= 0(root)

简单的方法

将别名添加到root,.bashrcsudo -i在sudo到root时使用。

root#echo'alias fb =“ echo foo bar”'>> /root/.bashrc
root#退出
出口
insyte $须藤-i
根#fb
富吧

4

仅具有两个别名并使用一个变量

我看不到使用awk或的原因,cut除非仅定义一次核心别名以使其更易于修改。如果是这种情况,则可以使用:

# ... in .bashrc ...
pd='perl -Ilib -I/home/myuser/lib -d'
alias pd="$pd"
alias spd="sudo $pd"

这是制作别名对的简单函数,例如上面的一对:

mkap () {
    alias $1=$2
    alias s$1="sudo $2"
}

使用方法:

mkap pd 'perl -Ilib -I/home/myuser/lib -d'
mkap ct 'cat'

现在你有pdspdctsct

$ ct /etc/shadow
cat: /etc/shadow: Permission denied
$ sct /etc/shadow
[sudo] password for dennis:
root:[censored]...
$ alias
alias ct='cat'
alias pd='perl -Ilib -I/home/myuser/lib -d'
alias sct='sudo cat'
alias spd='sudo perl -Ilib -I/home/myuser/lib -d'

4

我希望我可以将两个答案标记为“正确”。我结合了Insyte嗯嗯,有见地的帖子的正确方法,与Bill Weiss的awk(或cut)解决方案相结合,提出了以下建议:

alias spd="sudo $(alias pd | cut -d\' -f2)"

现在,我将其放入.bashrc之类的shell函数中,然后为我希望以root用户身份运行的所有别名创建“ s”版本。

更新:稍微修改了丹尼斯·威廉姆森的简单功能,使其更易于使用:

 salias()
 {
   local a c
   a=$(echo "$1" | cut -f1 -d=)
   c=$(echo "$1" | cut -f2- -d=)
   alias $a="$c"
   alias s$a="sudo $c"
 }

这意味着我只需要在整个命令前加上“ s”即可。代替:

alias pd='perl -Ilib -I/home/myuser/lib -d'

我只是在前面添加。

salias pd='perl -Ilib -I/home/myuser/lib -d'

我完成了。当然,计算机可以做更多的工作,但这就是计算机的用途。:-)

谢谢!


您可以(或应该能够)将事物标记为已接受,这有点像将它们标记为正确:)
Bill Weiss

正确-我想将两个答案标记为正确:-P
Tanktalus

3
为什么没有Slizzered的答案?alias sudo="sudo "完美的作品。
trusktr 2012年


3

简单地破解一个包含您的选项的脚本,然后将其放在常规帐户和root路径的文件夹之一中,难道不是很容易吗?确实不需要太多脚本。

#!/bin/bash
exec perl -Ilib -I/home/myuser/lib -d $*

实际上,它必须是“ $ @”而不是$ *,这就是我通常尝试避免使用此功能的部分原因。;-)它的工作原理是,仅浪费一堆相对于其所包含内容的磁盘空间。
Tanktalus

3

这很粗糙,但是可以在这里工作:

houdini@clanspum:~/ > alias fb
fb='echo foo bar'
houdini@clanspum:~/ > alias fb | awk -F\' '{print $2}'
echo foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print $2}')"
foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print $2}') a b c"
foo bar a b c
houdini@clanspum:~/ > fb
foo bar
houdini@clanspum:~/ > fb a b c
foo bar a b c

我在此处粘贴了不完整的解决方案,然后进行了修改以进行修复。当前一个是对的。免费投票给第一人发表评论,以解释发生了什么事:)
Bill Weiss

我希望有一种比awk更简单的方法,但有时希望!=现实;-)显然,“ cut -f2 -d \'”的效果与awk一样好,并且要短一些。
Tanktalus

是的,削减会奏效,我总是会忘记它。
比尔·魏斯

3

在您喜欢的别名和命令中添加“ sudo”前缀~/.bashrc例如:

#a regular alias
alias pd='perl -Ilib -I/home/myuser/lib -d'

#sudofy (command id, alias pd - add others to this list)
for cmd in id pd;
      do alias "s$cmd"="sudo $cmd";
done;

那是行不通的-那是我从那里开始的。你试过了吗?
Tanktalus

好的概念。我认为alias sudo="sudo "比较容易。
trusktr 2012年

3

如几次发布,在“ .bashrc”中执行:

别名sudo ='sudo'

原因在'man bash'和'help alias'中进行了解释:

别名:别名[-p] [名称[=值] ...]定义或显示别名。

Without arguments, `alias' prints the list of aliases in the reusable
form `alias NAME=VALUE' on standard output.

Otherwise, an alias is defined for each NAME whose VALUE is given.
**A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded.**

1

您想要这样的东西:

(alias; echo "exec < /dev/tty") | sudo bash  -i

我可能是错的,但ISTR bash -i(i =交互式)仅是v4.0。因此,在仍然bash运行v3 的旧服务器上,这很可能会失败。但是请证明我错了,任何人,继续;)
语法

@syntaxerror-您记得错了。-i是Bourne Shell,请参阅:pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html
geocar

哇,没想到这么快就收到一个6岁以上的帖子了。。。是的,我可能#!/bin/bash -i在shebang之后就把它弄糊涂了,这显然是不一样的(?)。长话短说,historybash脚本中使用(而不是在“实时”命令行中使用)需要该-i选项,而我无法在bash安装了“仅” v3 的服务器上工作。这是事实。
语法错误

1

我不知道这在生产盒上是否最明智,但我在本地使用

alias sudo="sudo -E"

-E(保留环境)选项将覆盖sudoers(5)中的env_reset选项。仅当匹配命令具有SETENV标记或在sudoers(5)中设置了setenv选项时,此选项才可用。


-1

您可以在命令前将别名添加到root的.bashrc还是只通过sudo执行.bashrc?

sudo (. ~yourlogin/.bashrc; pd ./mytool --some params)

1
嗯,这甚至​​都不起作用。实际上,它与我上面尝试过的某些东西相当接近,但与实际的shell / sudo语法相去甚远。
Tanktalus
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.