通过sudo或su运行脚本时,我想获取原始用户。这应该发生在多个 sudo 或者 su 彼此之间,特别是 sudo su -.

有帮助吗?

解决方案

结果:

利用 who am i | awk '{print $1}' 或者 logname 由于不能保证其他方法。

登录自我:

evan> echo $USER
evan
evan> echo $SUDO_USER

evan> echo $LOGNAME
evan
evan> whoami
evan
evan> who am i | awk '{print $1}'
evan
evan> logname
evan
evan>

普通sudo:

evan> sudo -s
root> echo $USER
root
root> echo $SUDO_USER
evan
root> echo $LOGNAME
root
root> whoami
root
root> who am i | awk '{print $1}'
evan
root> logname
evan
root>

sudo su-:

evan> sudo su -
[root ]# echo $USER
root
[root ]# echo $SUDO_USER

[root ]# echo $LOGNAME
root
[root ]# whoami
root
[root ]# who am i | awk '{print $1}'
evan
[root ]# logname
evan
[root ]#

sudo su-;苏·汤姆:

evan> sudo su -
[root ]# su tom
tom$ echo $USER
tom
tom$ echo $SUDO_USER

tom$ echo $LOGNAME
tom
tom$ whoami
tom
tom$ who am i | awk '{print $1}'
evan
tom$ logname
evan
tom$

其他提示

没有 完美的 回答。当您更改用户ID时,通常不会保留原始用户ID,因此信息会丢失。一些程序,例如 lognamewho -m 实施一个黑客,他们检查以查看哪个终端连接到 stdin, ,然后检查以查看该终端登录的用户。

这个解决方案 经常 作品,但不是万无一失的,当然不应该被认为是安全的。例如,想象是否 who 输出以下内容:

tom     pts/0        2011-07-03 19:18 (1.2.3.4)
joe     pts/1        2011-07-03 19:10 (5.6.7.8)

tom 用过的 su 扎根并运行您的程序。如果 STDIN 没有重定向,然后是一个类似的程序 logname 将输出 tom. 。如果是重定向(例如,从文件中),则是这样:

logname < /some/file

然后结果是”no login name“由于输入不是终端。不过,更有趣的是,用户可以作为用户登录的另一个登录的用户姿势。由于Joe在PTS/1上登录,因此Tom可以通过运行来假装自己是他

logname < /dev/pts1

现在说 joe 即使汤姆是运行命令的人。换句话说,如果您以任何形式的安全角色使用这种机制,那您就疯了。

这是一个 ksh 我在HP-UX上写的功能。我不知道它将如何使用 Bash 在Linux中。这个想法是 sudo 当原始用户和子过程是目标用户时,过程正在运行。通过循环通过父进程,我们可以找到原始过程的用户。

#
# The options of ps require UNIX_STD=2003.  I am setting it
# in a subshell to avoid having it pollute the parent's namespace.
#
function findUser
{
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser
    while [ "$thisUser" = "$origUser" ]
    do
        ( export UNIX_STD=2003; ps -p$thisPID -ouser,ppid,pid,comm ) | grep $thisPID | read thisUser myPPid myPid myComm
        thisPID=$myPPid
    done
    if [ "$thisUser" = "root" ]
    then
        thisUser=$origUser
    fi
    if [ "$#" -gt "0" ]
    then
        echo $origUser--$thisUser--$myComm
    else
        echo $thisUser
    fi
    return 0
}

我知道最初的问题是很久以前的,但人们(例如我)仍在问,这看起来像是解决解决方案的好地方。

如何使用logName(1)获取用户的登录名?

THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`

那是对我有用的唯一一件事。

user1683793的finduser()函数移植到 bash 并扩展了,因此它也返回存储在NSS库中的用户名。

#!/bin/bash

function findUser() {
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser

    while [ "$thisUser" = "$origUser" ]
    do
        ARR=($(ps h -p$thisPID -ouser,ppid;))
        thisUser="${ARR[0]}"
        myPPid="${ARR[1]}"
        thisPID=$myPPid
    done

    getent passwd "$thisUser" | cut -d: -f1
}

user=$(findUser)
echo "logged in: $user"

骑自行车并提供用户列表

基于用户1683793的答案

通过超出非统计过程,我跳过根部作为登录的启动器。我不确定在某些情况下这是否会太多

#!/bin/ksh
function findUserList
{
    typeset userList prevUser thisPID thisUser myPPid myPid myTTY myComm
    thisPID=$$                 # starting with this process-ID
    while [ "$thisPID" != 1 ]  # and cycling back to the origin
    do
        (  ps -p$thisPID -ouser,ppid,pid,tty,comm ) | grep $thisPID | read thisUser myPPid myPid myTTY myComm
        thisPID=$myPPid
        [[ $myComm =~ ^su ]] && continue        # su is always run by root -> skip it
        [[ $myTTY == '?' ]] && continue         # skip what is running somewhere in the background (without a terminal)
        if [[ $prevUser != $thisUser ]]; then   # we only want the change of user
                prevUser="$thisUser"            # keep the user for comparing
                userList="${userList:+$userList }$thisUser"  # and add the new user to the list
        fi
        #print "$thisPID=$thisUser: $userList -> $thisUser -> $myComm " >&2
    done
    print "$userList"
    return 0
}

logname 或者 who am i 没有给我理想的答案,尤其是在更长的列表中 su user1, su user2, su user3, ...

我知道最初的问题是很久以前的,但人们(例如我)仍在问,这看起来像是解决解决方案的好地方。

多次致电PS的替代方法:做一个Pstree调用

pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1

输出(登录时登录时): (evan)

Pstree论点:

  • -L:长线(不缩短)
  • -u:显示用户何时更改为(用户名)
  • -s $$:向父母展示此过程

使用第一个用户更改(登录) grep -ohead.

限制:命令可能不包含任何括号 () (它通常不会)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top