Linux:su指令

翻译总结自:su(1) - Linux manual page

1、作用

su,switch user,用指定的用户和组执行某个命令。

su指令允许我们用指定的用户和组来执行某个命令,当没有指定任何用户时,su默认用root身份以交互式shell脚本的方式来执行命令。而当指定了用户,还可以额外指定一些参数来传入shell脚本中。

为了保证后台兼容性,su在默认情况下不会改变当前目录,并且只会使用HOME和SHELL下的环境变量(当使用了某个具体用户时,环境变量还会加上USER和LOGNAME)。文档推荐使用--login选项(而非它的简写 - )来避免由于环境混淆所引发的一些异常情况。

 

2、用法(在[ ]之内的项代表可选项)

su [选项] [-] [用户]

3、选项

选项

全拼

说明

-c --command=command

以用户视角,要执行的命令(会导致环境变量,创建文件权限的变化)

执行完毕后会返回原使用者

-f --fast 不必读启动文件(csh.cshrc等),只用于csh或tcsh两种shell 
-g --group=group 指定组,只对root用户有效
-G --supp-group=group 指定附加组,只对root用户有效
-或-l --login

以一个近乎真实登录的用户视角来执行shell:

1、清空除了TERM和--whitelist-environment之外的环境变量;

2、初始化环境变量HOME、SHELL、USER、LOGNAME、PATH

3、改变目标用户的home目录;

4、设置shell的0号参数argv[0]为-,来使这个shell成为一个登录shell

简而言之,使用-l可以保证shell脚本的执行主体从root变为另一个用户

-m或-p --preserve-environment

保护整个运行环境,例如不修改HOME、SHELL、USER、LOGNAME。

该项在参数--login生效时不起作用。

-P --pty  
-s --shell=shell

运行指定的shell而非默认shell,一般情况下默认shell为/bin/bash,可运行的shell通过cat /etc/shells查看,默认shell通过echo $SHELL查看。

将会被运行的shell通过以下规则加以确认,这些规则依次是:

1、通过--shell参数指定的shell;

2、如果使用了选项--preserve-environment,那么选择在环境变量SHELL中指定的shell

3、在目标用户的passwd条目中列出的shell;

4、/bin/sh

如果目标用户使用了一个受限的shell(例如没有在/etc/shells中列出来的shell),那么选项--shell和环境变量SHELL将被忽略,除非这个用户是root

  --session-command=command 跟-c类似,但是不创建新session,过时
-w --whitelist-environment=list

list中用逗号分隔一系列环境变量,这样在使用选项--login时,这些环境变量将不会被重置。

该选项对于环境变量HOME、SHELL、USER、LOGNAME、PATH会失效

-h --help 帮助
-V --version 版本

4、例子

1)写一个shell脚本,用root执行,以实现切换用户创建文件的目的(要保证脚本的执行主体顺利完成切换)

 脚本执行完毕后,test目录的用户和组都是root(期望的是miduser)

 原因,没加--login,导致环境变量什么的用的都是root的,修改为su - 用户 -c "命令"

用户和组发生变化

 

这就延伸出了一个问题:当我以用户1登录和以root登录再切换为用户1,执行某个指令,有什么区别呢?

回答(切换并取代用户身份命令):

Linux系统中,当用户登录时,会为每个用户创建一个shell进程,提供交互功能,如果使用的是bash,那这个shell进程就是bash,如果是ksh,该进程就是ksh,其他的shell也是一样。

而对于进程而言,在它的进程PCB(进程控制块)中,有实际用户ID有效用户ID两个值,实际用户ID是指该进程是以什么身份创建的,比如我当前是root,那么我创建的进程的实际用户ID就是root的ID,为0。而有效用户ID是指对该进程有使用权限的用户ID,比如我有一辆车,但把它租出去了,这个车的拥有者是我,但是使用权限却不是我们。

一般情况下实际用户ID和有效用户ID相同,su命令就拥有这样的功能,让一个进程以命令拥有者的权限运行,即可以使进程实际用户ID有效用户ID不同

当我们以root执行su时,su命令会以当前shell进程父进程创建一个新的shell进程这个shell进程提供给我们所要su的那个用户使用的,而root的shell进程仍存在反之亦然,这就是为什么我们在用su进入某个用户后,用exit退出并非退出登录,而是回到之前那个用户,因为它们是父子进程关系,子进程的结束不会影响父进程的执行。但是如果我们强制杀死父进程,那么就直接退出

如何查看当前shell的实际用户和有效用户?

who am i :实际用户

whoami :有效用户

 

posted @   ShineLe  阅读(476)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示