2011-01-04 10 views

Respuesta

105

Resultados:

Use who am i | awk '{print $1}' O logname como están garantizados no hay otros métodos.

Conectado como auto:

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$ 
+0

En ese caso, sólo se puede usar 'que | awk '{print $ 1}' ' – SiegeX

+2

... si eres el único que ha iniciado sesión (y solo una vez). –

+6

todo lo que necesitas son 2 argumentos: 'quién soy yo 'es lo mismo que' quién huele mal '. Además, solo funciona si 'STDIN' está asociado con un TTY. Entonces, si ejecutas 'echo 'hello' '| ¿quién soy? Simplemente no funcionará. – tylerl

5

¿Qué le parece usar el nombre de usuario (1) para obtener el nombre de usuario?

+0

' logname (1) 'no funciona, pero' logname' hace - agregando los resultados por encima de – evan

+0

originalmente probé '$ LOGNAME' pero eso no funcionó . También se agregó a los resultados anteriores. – evan

+0

También solo funciona si STDIN es un tty – tylerl

11

No hay perfecto respuesta. Cuando cambia las ID de usuario, la ID de usuario original no suele conservarse, por lo que la información se pierde. Algunos programas, como logname y who -m implementan un truco donde verifican qué terminal está conectado a stdin y luego verifican qué usuario está conectado en ese terminal.

Esta solución a menudo funciona, pero no es infalible, y ciertamente no debe considerarse segura. Por ejemplo, imaginemos si who da el siguiente resultado:

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 utiliza su para llegar a la raíz, y se ejecuta el programa. Si STDIN no se redirige, entonces un programa como logname dará salida a tom. Si es redirigido (por ejemplo de un archivo) como así:

logname < /some/file 

entonces el resultado es "no login name", ya que la entrada no es el terminal. Más interesante aún, sin embargo, es el hecho de que el usuario podría posar como un usuario diferente conectado. Desde que Joe se registra en el pts/1, Tom podría hacerse pasar por él mediante la ejecución de

logname < /dev/pts1 

Ahora, dice joe a pesar de que Tom es el que ejecutó el comando. En otras palabras, si usa este mecanismo en cualquier tipo de función de seguridad, está loco.

+0

Si está ejecutando el script usted mismo (como lo demuestran los comandos utilizados), la seguridad no es el problema. Si es así, tienes mucho más problema ya que también tienen acceso sudo. La persona podría simplemente copiar el guión y modificarlo de la manera que quiera. Esta es simplemente una forma de obtener el nombre de usuario para usar en un script. ¿O me estoy perdiendo algo de lo que dices? – evan

+0

@evan: Tener acceso a sudo no implica la capacidad de sobrescribir archivos. – Flimzy

+0

@Flimzy ¿En qué caso root no tiene la capacidad de sobrescribir un archivo? – evan

8

Esta es una función ksh que escribí en HP-UX. No sé cómo funcionará con Bash en Linux. La idea es que el proceso sudo se esté ejecutando como el usuario original y los procesos hijo sean el usuario objetivo. Al retroceder en los procesos principales, podemos encontrar al usuario del proceso original.

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

sé la pregunta original era desde hace mucho tiempo, pero la gente (como yo) todavía están pidiendo y esto parecía un buen lugar para poner la solución.

2

La función findUser() del usuario1683793 está portada a bash y extendida, por lo que también devuelve los nombres de usuario almacenados en las bibliotecas 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" 
+0

FYI: esta función (y aquella en la que se basa) no retrocederá a través de múltiples shells generados por sudo anidados entre sí. – asdfghjkl

2

bicicleta hacia atrás y dar una lista de usuarios

basado en la respuesta de user1683793

Por exlcuding procesos que no son TTY, me salto raíz como el iniciador de la sesión. No estoy seguro de si eso puede exlcude demasiado en algunos casos

#!/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 o who am i no me dio la respuesta deseada, especialmente no en listas más largas de su user1, su user2, su user3, ...

Sé que la pregunta original era de hace mucho tiempo, pero las personas (como yo) siguen preguntando y este parecía un buen lugar para poner la solución.

0

alternativa a llamar varias veces ps: hacer una llamada pstree

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

de salida (cuando se conectó como par): (evan)

argumentos pstree:

  • -l: largas colas (no acortando)
  • -u: muestra cuando el usuario cambia como (nombre de usuario)
  • -s: $$ muestran los padres de este proceso

Obtener el primer cambio de usuario (que es inicio de sesión) con grep -o y head.

limitación: el comando no puede contener ningún apoyos () (no lo hace normalmente)

+0

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

Cuestiones relacionadas