在 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}