在 Linux 下要确认一个进程的发起者身份,比如用户 tom 登录系统,sudo su -
到 root,然后执行了脚本 hey.sh
,要想在 hey.sh
中追溯到发起进程的是 tom 这个用户,并不是很容易做到准确无误,花了点时间,找到了一个相对靠谱的方式。
先说说遇到的几个问题:
- 用户登录之后,使用
sudo hey.sh
的方式执行hey.sh
,倒是可以通过环境变量SUDO_USER
获取到sudo
之前的用户,但没有办法解决上面提到的sudo su -
这样不继承之前用户环境变量的问题。 - 可以用
tty
命令获取当前进程的 controlling terminal,然后通过 controlling terminal 文件的属主来确认登录用户,这可以解决 1 中提到的问题,但是如果当前进程的父进程是 daemon 或者关掉了标准输入,就没有 controlling terminal。 - 可以通过读取
/proc/self/loginuid
获取当前进程的登录用户 ID,对于没有 controlling terminal 的进程也可以获取到 ID,但对于 daemon 进程来说,获取的 ID 可能是 4294967295。
在我的场景下,对于第三个问题,并不是特别要紧,找不到对应的用户,fallback 回 effective user 就好, 所以,用来追溯进程发起用户身份的 bash 脚本是这样:
#!/bin/bash
# A relatively reliable way to find process initiator on Linux
user_entry=`getent passwd $(cat /proc/self/loginuid)`
if [ $? -eq 0 ]; then
login_user=`echo ${user_entry} | cut -d: -f1`
else
login_user=${SUDO_USER:-${LOGNAME}}
if [ "${login_user}" = "" ]; then
login_user=`id -urn`
fi
fi
echo ${login_user}