如何通过多个sudo和su命令找到原始用户?

eva*_*van 79 unix linux bash sudo su

通过sudo或su运行脚本时我想获得原始用户.这应该发生在不管多个sudosu彼此内部并且特别是在内部sudo su -.

eva*_*van 125

结果:

使用who am i | awk '{print $1}'OR,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>
Run Code Online (Sandbox Code Playgroud)

普通的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>
Run Code Online (Sandbox Code Playgroud)

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 ]#
Run Code Online (Sandbox Code Playgroud)

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$
Run Code Online (Sandbox Code Playgroud)

  • 所有你需要的是两个论点:"我是谁?"和"谁闻起来不好"相同.此外,它仅在"STDIN"与TTY关联时才有效.所以,如果你运行`echo"hello"| 我是谁?它根本行不通. (7认同)
  • @even是的,虽然我希望它尽可能少的配置,所以我现在使用`logname`,因为它结果确实有用,其中`我是谁'不会. (3认同)
  • `logname`效果最好,也在OS X上工作. (3认同)
  • ...如果你是唯一登录的人(而且只有一次). (2认同)

tyl*_*erl 14

没有完美的答案.更改用户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)
Run Code Online (Sandbox Code Playgroud)

tomsu来到root,并运行你的程序.如果STDIN没有被重定向,那么类似的程序logname将输出tom.如果它被重定向(例如从文件中),如下所示:

logname < /some/file
Run Code Online (Sandbox Code Playgroud)

然后结果是" no login name",因为输入不是终端.但更有趣的是,用户可以将其作为不同的登录用户.由于Joe在pts/1上登录,Tom可以通过跑步假装成为他

logname < /dev/pts1
Run Code Online (Sandbox Code Playgroud)

现在,它说joe即使汤姆是执行命令的人.换句话说,如果你在任何安全角色中使用这种机制,那你就疯了.

  • 如果您自己运行脚本(如所使用的命令所示),安全性不是问题。如果是这样,则您还有很多问题,因为他们也具有sudo访问权限。该人员可以复制脚本并按自己喜欢的方式对其进行修改。这只是获取登录名称以在脚本中使用的一种方法。还是我想念您在说什么? (2认同)

use*_*793 8

这是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
}
Run Code Online (Sandbox Code Playgroud)

我知道最初的问题来自很久以前,但人们(比如我)仍然在问,这看起来是一个提出解决方案的好地方.


小智 6

UserName1=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'` # Run commands in backtick and save output to variable

UserName2=$(pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g') # Run commands in brackets and save output to variable`

UserName3=$(pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1) # Run commands in brackets without removing output brackets and save output to variable`

echo $UserName1 

echo $UserName2 

echo $UserName3 
Run Code Online (Sandbox Code Playgroud)

  • 没有解释,仅从 [现有答案] (/sf/answers/3387991561/) 中略有改进 (2认同)

Flo*_*mer 6

在运行的系统上systemd-logindsystemd API 提供此信息。如果您想从 shell 脚本访问此信息,需要使用如下内容:

$ loginctl session-status \
  | (read session_id ignored; loginctl show-session -p User $session_id)
User=1000
Run Code Online (Sandbox Code Playgroud)

和系统命令在不带参数的session-status情况下具有不同的行为:使用当前会话,但使用管理器。但是,由于其机器可读的输出,using 更适合脚本使用。这就是为什么需要两次调用 的原因。show-ssessionloginctlsession-statusshow-ssessionshow-sessionloginctl


小智 5

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