Lors de l'exécution d'un script via sudo ou su, je veux obtenir l'utilisateur d'origine. Cela devrait se produire indépendamment de plusieurs sudo
ou su
s'exécute à l'intérieur de l'autre et spécifiquement sudo su -
.
93
Résultats:
Utilisez who am i | awk '{print $1}'
OR logname
car aucune autre méthode n'est garantie.
Connecté en tant que soi:
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 normal:
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 | awk '{print $1}'
who am i
est le même quewho smells bad
. De plus, cela ne fonctionne que s'ilSTDIN
est associé à un TTY. Donc, si vous l'exécutez,echo "hello" | who am i
cela ne fonctionnera tout simplement pas.echo "hello" | who am i
normalement, sauf si votre script s'exécute dans un environnement où il n'y a pas de terminal. Ensuite, vous pourriez voir l'erreur quiwho am i
ne fonctionne pas car il y a une sorte de problème avec le stdin non lisible, auquel cas vous pouvez essayer de canaliser les donnéeswho am i
par désespoir pour satisfaire ses exigences stdin. tylerl fait juste remarquer qu'il a déjà emprunté cette voie et que le tube ne fonctionnera pas car stdin doit être à la fois lisible et associé à un TTY.logname
maintenant, ce qui en fait fonctionne, oùwho am i
ne le fait pas.Il n'y a pas de parfait réponse . Lorsque vous modifiez les ID utilisateur, l'ID utilisateur d'origine n'est généralement pas conservé et les informations sont donc perdues. Certains programmes, tels que
logname
etwho -m
implémentent un hack où ils vérifient à quel terminal est connectéstdin
, puis vérifient quel utilisateur est connecté sur ce terminal.Cette solution souvent fonctionne , mais n'est pas infaillible et ne devrait certainement pas être considérée comme sûre. Par exemple, imaginez si
who
génère ce qui suit:tom
utilisésu
pour accéder à la racine et exécute votre programme. S'ilSTDIN
n'est pas redirigé, un programme comme celui-cilogname
sortiratom
. S'il est redirigé (par exemple à partir d'un fichier) comme suit:Alors le résultat est "
no login name
", puisque l'entrée n'est pas le terminal. Plus intéressant encore, cependant, est le fait que l'utilisateur peut se faire passer pour un autre utilisateur connecté. Puisque Joe est connecté sur pts / 1, Tom pourrait se faire passer pour lui en exécutantMaintenant, il dit
joe
même si c'est Tom qui a exécuté la commande. En d'autres termes, si vous utilisez ce mécanisme dans n'importe quel rôle de sécurité, vous êtes fou.la source
C'est une
ksh
fonction que j'ai écrite sur HP-UX. Je ne sais pas comment cela fonctionneraBash
sous Linux. L'idée est que lesudo
processus s'exécute en tant qu'utilisateur d'origine et que les processus enfants sont l'utilisateur cible. En parcourant les processus parents, nous pouvons trouver l'utilisateur du processus d'origine.# # 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 }
Je sais que la question originale remonte à il y a longtemps, mais des gens (comme moi) le demandent toujours et cela semblait être un bon endroit pour mettre la solution.
la source
Que diriez-vous d'utiliser logname (1) pour obtenir le nom de connexion de l'utilisateur?
la source
logname(1)
ne fonctionne pas maislogname
fait - en ajoutant les résultats ci$LOGNAME
mais cela n'a pas fonctionné. Également ajouté aux résultats ci-dessus.logname
toujours un tty? Avec mes tests, ça passe toujours. (Peut-être que j'ai quelque chose de mal.) J'utilise Linux avec coreutils 8.26.THIS_USER=`pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'`
C'est la seule chose qui a fonctionné pour moi.
la source
La fonction findUser () de user1683793 est portée
bash
et étendue pour qu'elle renvoie également les noms d'utilisateurs stockés dans les bibliothèques 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"
la source
revenir en arrière et donner une liste d'utilisateurs
basé sur la réponse de user1683793
En excluant les processus non-TTY, j'ignore root en tant qu'initiateur de la connexion. Je ne suis pas sûr que cela puisse en exclure trop dans certains cas
#!/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
ouwho am i
ne me donne pas la réponse souhaitée, surtout pas dans les listes plus longuessu user1
,su user2
,su user3
,...
Je sais que la question originale remonte à il y a longtemps, mais des gens (comme moi) le demandent toujours et cela semblait être un bon endroit pour mettre la solution.
la source
Alternative à l'appel ps plusieurs fois: faites un appel pstree
pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1
sortie (une fois connecté comme pair):
(evan)
arguments pstree:
Obtenez le premier changement d'utilisateur (qui est la connexion) avec
grep -o
ethead
.limitation: la commande peut ne pas contenir d'accolades
()
(elle ne le fait normalement pas)la source
Sur les systèmes en cours d'exécution
systemd-logind
, l' API systemd fournit ces informations . Si vous souhaitez accéder à ces informations à partir d'un script shell, vous devez utiliser quelque chose comme ceci:$ loginctl session-status \ | (read session_id ignored; loginctl show-session -p User $session_id) User=1000
Les commandes système
session-status
etshow-ssession
deloginctl
ont un comportement différent sans arguments:session-status
utilise la session en cours, maisshow-ssession
utilise le gestionnaire. Cependant, l'utilisationshow-session
est préférable pour l'utilisation de scripts en raison de sa sortie lisible par machine. C'est pourquoi deux invocations deloginctl
sont nécessaires.la source