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 :有效用户
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性