Sudo veya su aracılığıyla bir komut dosyası çalıştırırken, orijinal kullanıcıyı almak istiyorum. Bu, birden fazla sudo
veya su
birbiri içine girmeden ve özellikle gerçekleşmelidir sudo su -
.
Yanıtlar:
Sonuçlar:
Başka hiçbir yöntem garanti edilmediğinden who am i | awk '{print $1}'
VEYA kullanın logname
.
Kendi olarak giriş yaptınız:
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>
Normal 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 -; su tom:
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
ile aynı who smells bad
. Ayrıca, yalnızca STDIN
bir TTY ile ilişkilendirilmişse çalışır . Yani çalıştırırsan echo "hello" | who am i
işe yaramaz.
echo "hello" | who am i
Komut dosyanız terminalin olmadığı bir ortamda çalışmadığı sürece normal şekilde çalışmazsınız . O zaman who am i
çalışmayan hatayı görebilirsiniz çünkü okunamayan stdin ile ilgili bir tür problem vardır, bu durumda who am i
stdin gereksinimini karşılamak için çaresizlikten veri içinde borulama yapmayı deneyebilirsiniz . tylerl, o yoldan zaten geçtiğini ve kanal çalışmayacağını çünkü stdin'in hem okunabilir hem de bir TTY ile ilişkili olması gerektiğini belirtiyor.
logname
şimdi kullanıyorum , ki işe yarıyor, nerede who am i
çalışmıyor.
Mükemmel bir cevap yok . Kullanıcı kimliklerini değiştirdiğinizde, orijinal kullanıcı kimliği genellikle korunmaz, bu nedenle bilgiler kaybolur. Gibi bazı programlar, logname
ve who -m
onlar bağlı olan terminali görmek için kontrol yazarlardan uygulamak stdin
ve daha sonra bu terminalde kaydedilir hangi kullanıcı bakın.
Bu çözüm genellikle işe yarar, ancak kusursuz değildir ve kesinlikle güvenli kabul edilmemelidir. Örneğin who
, aşağıdaki çıktıların çıktığını düşünün :
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
Root almak için kullanılır ve programınızı çalıştırır. Yeniden STDIN
yönlendirilmezse, benzeri bir program logname
çıktı alır tom
. Yönlendirilmişse (örneğin bir dosyadan):
logname < /some/file
no login name
Girdi uçbirim olmadığı için sonuç " " olur. Yine de daha ilginç olanı, kullanıcının farklı bir oturum açmış kullanıcı gibi görünebilmesidir. Joe pts / 1'de oturum açtığından, Tom koşarak onun gibi davranabilir
logname < /dev/pts1
Şimdi, joe
komutu Tom çalıştıran kişi olmasına rağmen diyor . Başka bir deyişle, bu mekanizmayı herhangi bir güvenlik rolünde kullanırsanız, delisiniz.
Bu, ksh
HP-UX üzerine yazdığım bir işlev. Bash
Linux'ta nasıl çalışacağını bilmiyorum . Buradaki fikir, sudo
sürecin orijinal kullanıcı olarak çalışması ve alt süreçlerin hedef kullanıcı olmasıdır. Ana süreçler arasında geri dönerek, orijinal sürecin kullanıcısını bulabiliriz.
#
# 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
}
Asıl sorunun uzun zaman öncesine ait olduğunu biliyorum ama insanlar (benim gibi) hala soruyorlar ve burası çözümü koymak için iyi bir yer gibi görünüyordu.
Kullanıcının oturum açma adını almak için logname (1) kullanmaya ne dersiniz?
logname(1)
çalışmıyor ama işe yarıyor logname
- yukarıdaki sonuçları ekliyor
$LOGNAME
ama bu işe yaramadı. Yukarıdaki sonuçlara da eklendi.
logname
Hala tty gerektiriyor mu ? Testlerimle her zaman geçer. (Belki yanlış bir şey yapıyorum.) Linux 8.26 coreutils ile çalıştırıyorum.
THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
Benim için işe yarayan tek şey bu.
user1683793'ün findUser () işlevi bash
, NSS kitaplıklarında depolanan kullanıcı adlarını da döndürmek için taşındı ve genişletildi.
#!/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"
geri dönme ve bir kullanıcı listesi verme
user1683793'ün cevabına göre
TTY dışı işlemleri dışlayarak, oturum açma işleminin başlatıcısı olarak kökü atlıyorum. Bazı durumlarda bunun çok fazla dışlayacağından emin değilim
#!/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
veya who am i
özellikle de uzun listelerde bana istenen cevap vermedi su user1
, su user2
, su user3
,...
Asıl sorunun uzun zaman öncesine ait olduğunu biliyorum ama insanlar (benim gibi) hala soruyorlar ve burası çözümü koymak için iyi bir yer gibi görünüyordu.
PS'yi birden çok kez aramaya alternatif: bir pstree araması yapın
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
çıktı (çift olarak oturum açıldığında): (evan)
pstree argümanları:
İlk kullanıcı değişikliğini (giriş olan) grep -o
ve ile alın head
.
sınırlama: komut herhangi bir küme parantezi içermeyebilir ()
(normalde değildir)
Sistemleri çalıştıran günü systemd-logind
, systemd API bu bilgi sağlar . Bu bilgilere bir kabuk komut dosyasından erişmek istiyorsanız, bunun gibi bir şey kullanmanız gerekir:
$ loginctl session-status \
| (read session_id ignored; loginctl show-session -p User $session_id)
User=1000
session-status
Ve show-ssession
sistem komutları loginctl
kanıtlar olmaksızın farklı davranışa sahip: session-status
Geçerli oturumu kullanır, ancak show-ssession
yöneticisi kullanır. Bununla birlikte, show-session
makine tarafından okunabilir çıktısı nedeniyle komut dosyası kullanımı için kullanılması tercih edilir. Bu nedenle iki çağrıya loginctl
ihtiyaç vardır.
who | awk '{print $1}'