100

sudo または su を介してスクリプトを実行するときに、元のユーザーを取得したいと考えています。これは、相互の複数sudoまたは実行に関係なく、具体的に発生するはずです。susudo su -

4

10 に答える 10

143

結果:

他の方法は保証されていないため、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>

通常の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$
于 2011-01-04T20:30:24.120 に答える
20

完璧な答えはありません。ユーザー ID を変更すると、元のユーザー ID は通常保持されないため、情報は失われます。や などの一部のプログラムは、どの端末が に接続されているかを確認し、次にその端末にログインしているユーザーを確認するハックlognameを実装しています。who -mstdin

多くの場合、このソリューションは機能しますが、絶対確実というわけではなく、確実に安全と見なすべきではありません。たとえば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)

tomsuルートになり、プログラムを実行するために使用されます。STDINがリダイレクトされない場合、次のようなプログラムはlognameを出力しますtom。リダイレクトされた場合 (ファイルからなど):

logname < /some/file

no login name入力が端末ではないため、結果は " " になります。さらに興味深いのは、ユーザーが別のログイン ユーザーになりすます可能性があることです。Joe は pts/1 にログインしているので、Tom は次のコマンドを実行して彼になりすますことができます。

logname < /dev/pts1

今、joeコマンドを実行したのは tom ですが、それは表示されます。言い換えれば、このメカニズムを何らかのセキュリティ ロールで使用するとしたら、あなたは気が狂っているということです。

于 2011-07-04T00:27:37.030 に答える
8

これはksh私が HP-UX で書いた関数です。BashLinuxでどのように機能するかわかりません。アイデアは、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
}

元の質問はずっと前からあったことは知っていますが、人々(私のような人)はまだ質問していて、これは解決策を置くのに適した場所のように見えました.

于 2012-10-19T23:39:45.557 に答える
6

logname(1) を使用してユーザーのログイン名を取得するのはどうですか?

于 2011-01-05T14:13:01.097 に答える
2

ps を複数回呼び出す代わりに: pstree を 1 回呼び出す

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

出力 (偶数としてログインした場合):(evan)

pstree 引数:

  • -l: 長い行 (短縮ではない)
  • -u: ユーザーが (userName) として変更されたときに表示
  • -s $$: このプロセスの親を表示

と を使用して、最初のユーザー変更 (ログイン) を取得しgrep -oますhead

制限: コマンドには中かっこを含める()ことはできません (通常は含まれません) 。

于 2018-01-23T10:51:58.400 に答える