เมื่อเรียกใช้สคริปต์ผ่าน sudo หรือ su ฉันต้องการรับผู้ใช้ดั้งเดิม นี้ควรจะเกิดขึ้นโดยไม่คำนึงถึงหลาย ๆsudo
หรือsu
ทำงานภายในของแต่ละอื่น ๆ sudo su -
และโดยเฉพาะ
เมื่อเรียกใช้สคริปต์ผ่าน 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 ]#
ซูโดซู -; สุทอม:
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$
who am i
เหมือนกับwho smells bad
. นอกจากนี้ยังใช้งานได้เฉพาะเมื่อSTDIN
เชื่อมโยงกับ TTY ดังนั้นหากคุณเรียกใช้echo "hello" | who am i
มันจะไม่ทำงาน
echo "hello" | who am i
ตามปกติเว้นแต่สคริปต์ของคุณจะทำงานในสภาพแวดล้อมที่ไม่มีเทอร์มินัล จากนั้นคุณอาจเห็นข้อผิดพลาดที่who am i
ใช้งานไม่ได้เนื่องจากมีปัญหาบางอย่างเกี่ยวกับ stdin ที่ไม่สามารถอ่านได้ซึ่งในกรณีนี้คุณอาจลองวางข้อมูลให้who am i
หมดสิ้นเพื่อให้เป็นไปตามข้อกำหนด stdin tylerl เพียงแค่สังเกตว่าเขาอยู่ในเส้นทางนั้นแล้วและไปป์จะไม่ทำงานเพราะ stdin ต้องอ่านได้และเชื่อมโยงกับ TTY
logname
ในขณะนี้ซึ่งมันจะเปิดออกไม่ทำงานที่who am i
ไม่ได้
ไม่มีคำตอบที่สมบูรณ์แบบ เมื่อคุณเปลี่ยน ID ผู้ใช้โดยปกติ ID ผู้ใช้เดิมจะไม่ถูกเก็บรักษาข้อมูลจึงหายไป บางโปรแกรมเช่น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)
tom
ใช้su
ในการรูทและรันโปรแกรมของคุณ ถ้าSTDIN
ไม่ได้เปลี่ยนเส้นทางแล้วโปรแกรมเช่นส่งออกจะlogname
tom
หากมีการเปลี่ยนเส้นทาง (เช่นจากไฟล์) ดังนี้:
logname < /some/file
ผลลัพธ์คือ " no login name
" เนื่องจากอินพุตไม่ใช่เทอร์มินัล อย่างไรก็ตามสิ่งที่น่าสนใจกว่านั้นก็คือความจริงที่ว่าผู้ใช้สามารถสวมรอยเป็นผู้ใช้อื่นที่เข้าสู่ระบบ เนื่องจาก Joe เข้าสู่ระบบใน pts / 1 ทอมสามารถแกล้งทำเป็นเขาได้โดยการวิ่ง
logname < /dev/pts1
ตอนนี้มันบอกว่าjoe
ถึงแม้ทอมจะเป็นคนสั่งการ กล่าวอีกนัยหนึ่งถ้าคุณใช้กลไกนี้ใน Security role ใด ๆ คุณก็บ้า
นี่คือ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) เพื่อรับชื่อล็อกอินของผู้ใช้?
logname(1)
ใช้งานไม่ได้ แต่logname
เพิ่มผลลัพธ์ด้านบน
$LOGNAME
แล้วแต่ไม่ได้ผล นอกจากนี้ยังเพิ่มในผลลัพธ์ด้านบน
logname
ยังคงต้อง TTY หรือไม่? ด้วยการทดสอบของฉันมันมักจะผ่านไป (บางทีฉันอาจจะทำอะไรผิดพลาด) ฉันใช้งาน linux กับ coreutils 8.26
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
นั่นเป็นสิ่งเดียวที่เหมาะกับฉัน
ฟังก์ชัน findUser () ของ user1683793 พอร์ต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"
ขี่จักรยานกลับและให้รายชื่อผู้ใช้
ตามคำตอบของ user1683793
โดย exlcuding กระบวนการที่ไม่ใช่ TTY ฉันข้ามรูทเป็นตัวเริ่มต้นของการเข้าสู่ระบบ ฉันไม่แน่ใจว่ามันอาจจะมากเกินไปในบางกรณีหรือไม่
#!/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:
ได้รับการเปลี่ยนแปลงที่ผู้ใช้รายแรก (ซึ่งก็คือการเข้าสู่ระบบ) ด้วยและgrep -o
head
ข้อ จำกัด : คำสั่งต้องไม่มีวงเล็บปีกกา()
(ปกติไม่ได้)
บนระบบที่ใช้systemd-logind
ในAPI 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
ต้องมีการร้องขอสองครั้ง
who | awk '{print $1}'