sudo 命令
2013-08-07 by dongnan
sudoers 文件
sudoers 文件用来指定用户特权的文本行的格式如下(等号两边的空白符是可选的)。
格式说明:
用户名(用户别名) 主机名(主机别名)=[(运行用户或是Runas_Alias)可选] [tag可选]  可以执行的命令(或Cmmd_Alias)
- user_list:指定该特权说明行适用的用户。这个列表可以包含用户名、组(以%开头)和用户别名。
- host_list:指定该特权说明行适用的主机。可以使用内置命令- alias ALL让该行适用于所有引用这个sudoers文件的系统。
- runas_list:指定当带着选项- -u调用- sudo时能够以哪些用户的身份来运行命令列表中的命令。必须用圆括号将该特权说明括起来。如果没有- runas_list的话,那么- sudo假设为- root。
- command_list:指定该特权说明行适用的命令工具。所有名称必须是绝对路径名。
举个栗子:
dongnan ALL=(ALL) /sbin/fdsik
表示允许用户dongnan可以从任何主机登录,并能够执行fdisk命令。
举个栗子
sudo 不同的环境变量
sudo -i && env > a
打开另一个终端:
sudo -s && env >b
比较环境变量:
diff ./a /home/dongnan/b
16c16
< PWD=/root
---
> PWD=/home/dongnan
21c21
< HOME=/root
---
> HOME=/home/dongnan
sudo 不输入密码
操作系统
Ubuntu 12.04.2 LTS
执行 sudo 要输入密码后才能获取 root 权限:
sudo -s
[sudo] password for zongming:
编辑文件
vim /etc/sudoers
# User privilege specification
root    ALL=(ALL:ALL) ALL
dongnan ALL=(ALL) NOPASSWD:ALL      # 单个用户
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo  ALL=(ALL:ALL) NOPASSWD:ALL    # 用户组
编辑完成后使用 :wq! 强制保存退出。
不输入密码即可获得权限:

sudo 免密指定执行某个命令
操作系统
Ubuntu 12.04.2 LTS
编辑配置文件:
vim /etc/sudoers
添加如下内容:
nagios  ALL=(ALL) NOPASSWD: /usr/sbin/conntrack
配置参数:
- nagios:用户名
- ALL=(ALL):主机与执行身份
- NOPASSWD:免密码
- command:执行的命令
sudo 组合命令的权限问题
sudo 后面的命令包含管道符号
sudo rpm -qa | grep subversion | awk '{print $1}'| xargs rpm --nodeps -e
-e _的时候报错,提示某个文件的锁无法打开。
问题分析:
- 用管道或者&&这样的符号连接的命令在LINUX系统中被认为是多条指令,并不是一条指令。
- 示例中使用方式实际上只赋予了 rpm -qa使用sudo权限,后面的grep、awk、xargs实 际上都没有sudo权限,这是为何不能执行成功的原因。
- 实际上只是最后 xargs rpm --nodeps -e这条命令需要删除rpm包的时候,才需要sudo权限。
解决方法
# 改变命令的执行方式为
rpm -qa | grep subversion | awk '{print $1}'| sudo xargs rpm --nodeps -e
# 改变命令的执行方式为
sudo bash -c "rpm -qa | grep subversion | awk '{print $1}'| xargs rpm --nodeps -e"
sudo后面的命令包含重定向符号
sudo cat /dev/null > Filename
重定向输出的时候报错,提示没有权限操作。
问题分析:
- 用重定向符号连接的命令时,重定向符号之前的sudo cat /dev/null命令被赋予了sudo权限。
- 但整串命令在一起并没有权限操作">"后的文件,这是为何不能执行成功的原因。
- 实际上只是改写"Filename"这个文件才需要sudo权限。
解决方法:
# 改变命令的执行方式为
sudo bash -c "cat /dev/null > Filename"
SSH 时 sudo 示例
cat hpnsCleanupHost.sh | ssh  ${ip}$host 'sudo bash -c "cat - > /path/hpnsCleanupHost.sh