आप कई sudo और su कमांड के माध्यम से मूल उपयोगकर्ता कैसे खोज सकते हैं?


93

सुडो या सु के माध्यम से स्क्रिप्ट चलाते समय मैं मूल उपयोगकर्ता प्राप्त करना चाहता हूं। यह कई की परवाह किए बिना होना चाहिए sudoया suएक-दूसरे के अंदर और विशेष रूप से चलता है sudo su -

जवाबों:


136

परिणाम:

उपयोग 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>

सामान्य सुडोल:

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>

सूदो सु -:

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 ]#

सुडो सु -; सु टॉम:

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$

1
उस मामले में आप बस का उपयोग कर सकते हैंwho | awk '{print $1}'
SiegeX

2
... यदि आप केवल एक लॉग इन हैं (और यह केवल एक बार है)।
अगली सूचना तक रोक दिया गया।

9
आप सभी की जरूरत 2 तर्कों है: who am iके रूप में ही है who smells bad। इसके अलावा, यह केवल तभी काम करता है जब STDINकोई TTY से जुड़ा हो। इसलिए अगर आप echo "hello" | who am iइसे चलाते हैं तो यह काम नहीं करेगा।
tylerl

1
आप echo "hello" | who am iसामान्य रूप से नहीं चलेंगे , जब तक कि आपकी स्क्रिप्ट ऐसे वातावरण में नहीं चल रही है जहाँ कोई टर्मिनल नहीं है। तब आपको वह त्रुटि दिखाई दे सकती है जो who am iकाम नहीं कर रही है क्योंकि गैर-पठनीय स्टड के साथ किसी प्रकार की समस्या है, जिस स्थिति में आप डेटा को पाइप करने की कोशिश कर सकते हैं ताकि who am iस्टीन की आवश्यकता पूरी हो सके। टायलर सिर्फ यह देख रहा है कि वह पहले से ही उस रास्ते से नीचे है, और पाइप काम नहीं करेगा क्योंकि स्टड को पठनीय और TTY दोनों के साथ संबद्ध होना चाहिए।
एडविन बक

4
@ इवेन ट्रू, हालाँकि मैं चाहूँगा कि इसे जितना संभव हो उतना कम कॉन्फ़िगरेशन की आवश्यकता हो, इसलिए मैं अभी उपयोग कर रहा हूं logname, जो यह बताता है कि यह काम who am iनहीं करता है , जहां नहीं है।
बार्ट वैन ह्युकेलोम

18

कोई सही जवाब नहीं है। जब आप उपयोगकर्ता आईडी बदलते हैं, तो मूल उपयोगकर्ता आईडी आमतौर पर संरक्षित नहीं होती है, इसलिए जानकारी खो जाती है। कुछ प्रोग्राम, जैसे कि एक हैक को लागू करना lognameऔर who -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)

tomsuरूट करने के लिए इस्तेमाल किया , और अपने कार्यक्रम चलाता है। यदि STDINपुनर्निर्देशित नहीं किया जाता है, तो एक प्रोग्राम जैसे lognameआउटपुट देगा tom। यदि यह पुनर्निर्देशित है (जैसे फ़ाइल से) तो:

logname < /some/file

तब परिणाम " no login name" है, क्योंकि इनपुट टर्मिनल नहीं है। अधिक दिलचस्प बात यह है कि हालांकि, यह तथ्य यह है कि उपयोगकर्ता उपयोगकर्ता में एक अलग लॉग के रूप में पोज दे सकता है। चूंकि पीटीएस / 1 पर जो लॉग इन किया गया है, टॉम उसे चलाने का दिखावा कर सकता है

logname < /dev/pts1

अब, यह कहते हैं कि joeभले ही टॉम कमांड चलाने वाले हैं। दूसरे शब्दों में, यदि आप किसी भी प्रकार की सुरक्षा भूमिका में इस तंत्र का उपयोग करते हैं, तो आप पागल हैं।


2
यदि आप स्वयं स्क्रिप्ट चला रहे हैं (जैसा कि उपयोग किए गए आदेशों से स्पष्ट है), सुरक्षा समस्या नहीं है। यदि यह है, तो आपके पास बहुत अधिक समस्या है क्योंकि उनके पास भी सुडो पहुंच है। व्यक्ति केवल स्क्रिप्ट की प्रतिलिपि बना सकता है और इसे किसी भी तरह से संशोधित कर सकता है जैसे वे पसंद करते हैं। यह एक स्क्रिप्ट में उपयोग के लिए लॉग इन नाम प्राप्त करने का एक तरीका है। या मैं कुछ याद कर रहा हूँ कि तुम क्या कह रहे हो?
evan

1
@ इवान: सुडो एक्सेस होने से फाइलों को अधिलेखित करने की क्षमता नहीं होती है।
टिमटिमा

@ फ़ाइल्ज़ी किस मामले में किसी फाइल को अधिलेखित करने की क्षमता नहीं है?
ईवान

1
@ इवान: किसी भी समय आपकी सुडोल पहुँच आपको शेल या किसी अन्य कमांड तक पहुँच प्रदान नहीं करती है, जो फाइलों को अधिलेखित कर सकती है।
Flimzy

@evan sudo की पहुंच हमेशा नहीं होती है (न कि यह अधिकांश व्यवस्थापक मामलों में होनी चाहिए) कुल रूट एक्सेस। यह विन्यास योग्य प्रतिबंधित निष्पादन संदर्भों का एक समूह है।
DylanYoung

8

यह एक kshफ़ंक्शन है जिसे मैंने HP-UX पर लिखा है। मुझे नहीं पता कि यह Bashलिनक्स में कैसे काम करेगा । विचार यह है कि 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
}

मुझे पता है कि मूल प्रश्न बहुत समय पहले से था, लेकिन लोग (जैसे मेरे) अभी भी पूछ रहे हैं और यह समाधान डालने के लिए एक अच्छी जगह की तरह लग रहा था।


5

उपयोगकर्ता का लॉगिन नाम प्राप्त करने के लिए logname (1) का उपयोग कैसे करें?


logname(1)काम नहीं करता है लेकिन lognameकरता है - उपरोक्त परिणाम जोड़ते हुए
evan

मूल रूप से मैंने कोशिश की थी, $LOGNAMEलेकिन यह काम नहीं किया। उपरोक्त परिणामों में भी जोड़ा गया।
evan

क्या lognameअभी भी टैटी की आवश्यकता है? मेरे परीक्षणों के साथ यह हमेशा गुजरता है। (शायद मैं कुछ गलत कर रहा हूं।) मैं कोरुटिल्स 8.26 के साथ लिनक्स चला रहा हूं।
सिमोहे

मेरा लॉग इन (GNU कोरुटिल्स) 8.28 हमेशा "लॉगनाम: नो लॉगिन नाम" (Ubuntu 18.04.2)
sondra.kinsey


2

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"

FYI करें: यह फ़ंक्शन (और यह जिस पर आधारित था) एक-दूसरे में बसे हुए कई सूडो द्वारा पैदा किए गए कई गोले के माध्यम से वापस चक्र नहीं करेगा।
asdfghjkl

2

वापस साइकिल चलाना और उपयोगकर्ताओं की एक सूची देना

user1683793 के उत्तर पर आधारित है

गैर-टीटीवाई प्रक्रियाओं को समाप्त करके, मैं लॉगिन के सर्जक के रूप में रूट को छोड़ देता हूं। मुझे यकीन नहीं है कि अगर किसी मामले में बहुत ज्यादा हो सकता है

#!/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,...

मुझे पता है कि मूल प्रश्न बहुत समय पहले से था, लेकिन लोग (जैसे मेरे) अभी भी पूछ रहे हैं और यह समाधान डालने के लिए एक अच्छी जगह की तरह लग रहा था।


2

कई बार कॉल करने के लिए वैकल्पिक: एक pstree कॉल करें

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

आउटपुट (जब भी लॉग इन किया जाता है): (evan)

पाश्चात्य तर्क:

  • -l: लंबी लाइनें (छोटा नहीं)
  • -u: जब उपयोगकर्ता (उपयोगकर्ता नाम) के रूप में बदलता है
  • -s $ $: इस प्रक्रिया के माता-पिता को दिखाएं

पहले उपयोगकर्ता परिवर्तन (जो लॉगिन है) के साथ grep -oऔरhead

सीमा: कमांड में कोई ब्रेसिज़ नहीं हो सकता है ()(यह सामान्य रूप से नहीं होता है)


pstree -lu -s $$ | head -n1 | sed -e 's / [() * (([^)] *))। * / \ 1 /'
Alexx Roche

0

सिस्टम चलाने पर systemd-logind, systemd एपीआई इस जानकारी प्रदान करता है । यदि आप इस जानकारी को शेल स्क्रिप्ट से एक्सेस करना चाहते हैं, तो कुछ इस तरह का उपयोग करने की आवश्यकता है:

$ loginctl session-status \
  | (read session_id ignored; loginctl show-session -p User $session_id)
User=1000

session-statusऔर show-ssessionकी प्रणाली आदेशों loginctlतर्क के बिना अलग व्यवहार कर: session-statusवर्तमान सत्र का उपयोग करता है, लेकिन show-ssessionप्रबंधक का उपयोग करता है। हालांकि, show-sessionइसके मशीन-पठनीय आउटपुट के कारण स्क्रिप्ट उपयोग के लिए उपयोग करना बेहतर है। यही कारण है कि दो आह्वान की loginctlजरूरत है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.