通过sudo调用的Bash脚本如何识别用户

130

如果我创建脚本/root/bin/whoami.sh包含:

#!/bin/bash
whoami

如果这个脚本是由已经正确配置sudo的用户调用的,它会指示

root

有没有一种快速获取脚本中实际用户的方法,还是我必须通过传递该用户名来解决问题?

8个回答

168

如果你使用sudo su -,那么$SUDO_USER将不起作用。 另外需要进行多个检查-如果$USER == 'root',则获取$SUDO_USER

使用命令who am i代替whoami。这会运行过滤了当前会话的who命令。它提供了比你所需更多的信息。所以,要只获取用户,请执行以下操作:

who am i | awk '{print $1}'

另外(也更简单的方法)是使用logname。它与上述语句执行的操作相同。

这将提供登录会话的用户名。

无论是否使用sudosudo su [whatever],这些都适用。它也适用于susudo被调用的次数。


57
“Who am I”的替代说法是“妈妈喜欢谁”。由你决定。 - wchargin
3
who 命令返回两行,都包含我的名字,而 who am i 命令则返回空。有什么帮助吗? - GManz
10
我在使用Ubuntu 16.04,命令"who am i"没有反应,似乎只需要用"who"即可。所以"who | awk '{print $1}'"可以按预期工作 ;) - daveoncode
3
如果您没有安装awk,也可以使用cut命令:who mom likes | cut -d' ' -f1或者出于某些原因使用sed命令:who mom likes | sed -n 's/^\([^ ]*\).*/\1/p' - Yzmir Ramirez
1
注意:当您从终端窗口运行时,logname 不起作用,因为它是非登录终端。 - Lucas
显示剩余5条评论

66

我认为$SUDO_USER是有效的。

#!/bin/bash
echo $SUDO_USER
whoami

3
有趣的事情:sudo env 显示 SUDO_USER 但是 sudo echo $SUDO_USER 没有输出任何内容... - mtvec
20
工作,这并不奇怪,是可以预料的。在 sudo echo $SUDO_USER 中,Bash 在执行 sudo 之前就已经评估了 $SUDO_USER。尝试此解决方案中发布的脚本,它会起作用。 - user410344
@quadmore:如果您对答案满意,请不要忘记接受它。 - mtvec
4
你也可以使用 echo ${SUDO_USER:-$USER} 来同时捕获sudo和非sudo运行。但是 evan's answer 中的 logname 更容易理解。 - Tobias Kienzler
2
正如Evan所指出的那样,$SUDO_USER在使用sudo su -时无法工作,但是logname始终有效。 - David Harkness
sudo sh -c "echo $SUDO_USER" - Boopathi Rajaa

15

无论使用 sudo 还是不使用 sudo,以下方法都可以获取调用脚本的用户名:

if [ $SUDO_USER ]; then user=$SUDO_USER; else user=`whoami`; fi

或者一个更短的版本

[ $SUDO_USER ] && user=$SUDO_USER || user=`whoami`

11
更简洁的写法:user=${SUDO_USER:-$(whoami)} 或者是 user=$(logname)。详见链接:https://dev59.com/73A75IYBdhLWcg3wAUB9#4597929。 - Tobias Kienzler

8

使用 whoamiwho am iwhoid$SUDO_USER 并不是正确的方法。

实际上,who 从来都不是解决问题的方法,因为它只会列出已登录的用户,可能有数十个...

在我看来,唯一有价值的答案是使用 logname

希望这个能有所帮助。

罗布


5
如果你要获取UID(用于docker的一些操作),可以使用以下方法:
```bash id -u ```
其中,``是你需要查询UID的用户名。
LOCAL_USER_ID=$(id -u $(logname))

2

who am i | awk '{print $1}' 对我来说不起作用,但是who|awk '{print $1}' 可以完成任务。


2
不要在有多个用户会话的主机上运行。 - Roman Grazhdan
它是whoami,不是who am i。这遵循了典型的结构,其中shell命令通常是单个单词,后跟参数。 who am i将被解释为运行带有ami参数的who命令。 who碰巧也是一个命令,但在这种情况下输出的内容比所需的要多,而whoami只打印用户名。 - Eli Smith
@EliSmith whoami无法解决问题,因为它不会通过root查找调用者。 - undefined

1

奇怪的是,系统确实区分真实和有效UID,但我找不到在Shell级别导出此信息的程序。


0

我有同样的问题,使用Rocky Linux 9.2,我运行了这个脚本:

#!/bin/bash
echo "LOGNAME: $LOGNAME"
echo "SUDO_USER: $SUDO_USER"
set | grep username

在每种情况下:
  • 作为用户(./script.sh

    • LOGNAME:用户名
    • SUDO_USER:null
  • 通过sudo以root身份运行(sudo ./script.sh

    • LOGNAME:root
    • SUDO_USER:用户名
  • 通过su以root身份运行(./script.sh

    • LOGNAME:用户名
    • SUDO_USER:null
  • 通过sudo su以root身份运行(./script.sh

    • LOGNAME:root
    • SUDO_USER:用户名

使用if...then...else检查会起作用,除非您在已经处于超级用户提示符的情况下意外地使用sudo运行脚本:

#root: sudo ./script.sh
  • 通过su或sudo su,结果如下:
    • LOGNAME:root
    • SUDO_USER:root

然而,一个set变量在我所有的场景中都被证明是一致的:

MAIL=/var/spool/mail/username

我现在将已登录用户设置为:

UNAME=$(echo $MAIL |cut -d/ -f5)

我相信有时可能会出现这种方法行不通的情况,但是我还没有找到这样的例子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接