su和sudo

切换用户身份——su

su意为switch user,用于切换当前用户身份。除了root用户之外, 所有用户切换其他用户身份时均需要目标用户的密码。比如当前用户身份是普通用户sinoiot, 想要切换到root时,需要输入root用户的密码。但是root切换到sinoiot用户是无需密码的。

$ su --help
用法:su [选项] [登录]

选项:
  -c, --command COMMAND        将 COMMAND 传递至启动的 shell
  -h, --help            显示此帮助信息并退出
  -, -l, --login        将 shell 设为登录 shell
  -m, -p,
  --preserve-environment    不重置环境变量并保持同一 shell
  -s, --shell SHELL        使用 SHELL 而非 passwd 中的默认值

特别注意-|-l|--login这个特殊参数。su默参是非登录式切换用户(回忆一下, 讲解bash配置文件加载次序时,提到bash几种不同工作模式下加载的配置是不一样的)。

这意味着,非登录式 切换用户身份时,仅仅切换了用户的身份,并未初始化对应用户的环境。 也就是说,只有$USER,$HOME等这些和用户身份关联的变量会修改,其余用户自定义的配置文件并未加载生效。 切换用户身份后,用户也并没有处于家目录。

加上这个参数时,用户将以 登录式 形式切换用户身份。相当于以新用户重新登录到系统中。 此时不但会更改用户身份,也会初始化用户的配置文件。是一种彻底切换用户身份的方式。一般推荐加上这个参数。

注意-c参数同样很有用,这将以非交互式的形式以目标用户的身份执行一条命令,执行完毕就退出。

例如:

su - -c "ls /root"         # 以root身份列出/root/目录下的文件
su - -c psql postgres      # 以postgres用户的身份执行psql命令,执行完毕之后返回当前用户身份
su - -s /bin/bash postgres # 切换当前用户身份为postgres,指定/bin/bash为shell。

使用管理员授权执行命令——sudo

su切换用户意味着需要知道目标用户的密码,而且可以以目标用户身份执行任何操作。因此是不安全的。

因此Linux系统提供了另一种方式提权——sudosudo执行有以下特点:

  • 使用sudo执行命令时不需要目标用户的密码
  • sudo可执行的命令受到管理员的授权限制

sudo命令的相关配置文件存放于/etc/sudoers,同样注意这个文件的权限,被不合理的放大会导致无法sudo。 该文件即改即生效,并且错误的格式将导致sudo不可用。因此不推荐直接编辑,而使用visudo命令编辑。

此文件的格式语法参考man 5 sudoers。比如Ubuntu默认的配置中有一行: %admin ALL=(ALL) ALL。 代表admin这个组的用户被授权使用所有命令。Ubuntu安装过程中添加的普通用户将默认添加到admin这个组。

sudo默认记住密码15分钟,可以被timeout选项覆盖,可以用NOPASSWD选项指定无需密码。

常用参数:

  • -i: 以目标用户身份运行一个登录 shell;可同时指定一条命令(参考su -l)
  • -u: 以指定用户或 ID 运行命令(或编辑文件)
  • -S: 从stdin读取密码