在 Linux 下追溯進(jìn)程的發(fā)起者
作者:Xupeng
在 Linux 下要確認(rèn)一個進(jìn)程的發(fā)起者身份,比如用戶 tom 登錄系統(tǒng),sudo su - 到 root,然后執(zhí)行了腳本 hey.sh,要想在 hey.sh 中追溯到發(fā)起進(jìn)程的是 tom 這個用戶,并不是很容易做到準(zhǔn)確無誤,花了點時間,找到了一個相對靠譜的方式。
在 Linux 下要確認(rèn)一個進(jìn)程的發(fā)起者身份,比如用戶 tom 登錄系統(tǒng),sudo su - 到 root,然后執(zhí)行了腳本 hey.sh,要想在 hey.sh 中追溯到發(fā)起進(jìn)程的是 tom 這個用戶,并不是很容易做到準(zhǔn)確無誤,花了點時間,找到了一個相對靠譜的方式。
先說說遇到的幾個問題:
- 用戶登錄之后,使用 sudo hey.sh 的方式執(zhí)行 hey.sh,倒是可以通過環(huán)境變量 SUDO_USER 獲取到 sudo 之前的用戶,但沒有辦法解決上面提到的 sudo su - 這樣不繼承之前用戶環(huán)境變量的問題。
- 可以用 tty 命令獲取當(dāng)前進(jìn)程的 controlling terminal,然后通過 controlling terminal 文件的屬主來確認(rèn)登錄用戶,這可以解決 1 中提到的問題,但是如果當(dāng)前進(jìn)程的父進(jìn)程是 daemon 或者關(guān)掉了標(biāo)準(zhǔn)輸入,就沒有 controlling terminal。
- 可以通過讀取 /proc/self/loginuid 獲取當(dāng)前進(jìn)程的登錄用戶 ID,對于沒有 controlling terminal 的進(jìn)程也可以獲取到 ID,但對于 daemon 進(jìn)程來說,獲取的 ID 可能是 4294967295。
在我的場景下,對于第三個問題,并不是特別要緊,找不到對應(yīng)的用戶,fallback 回 effective user 就好, 所以,用來追溯進(jìn)程發(fā)起用戶身份的 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}
責(zé)任編輯:黃丹
來源:
Xupeng's blog