2011-06-01 6 views
6

Conseguir un ID de proceso de fondo es fácil de hacer desde el símbolo yendo:Conseguir un PID de un proceso de fondo Ejecutar como otro usuario

$ my_daemon & 
$ echo $! 

Pero lo que si quiero ejecutarlo como un usuario diferente, como:

su - joe -c "/path/to/my_daemon &;" 

Ahora, ¿cómo puedo capturar el PID de my_daemon?

+2

Esto se ve sólidamente en el tema de SO para mí; es una pregunta sobre la programación de shell, y como tal está dentro del mandato de SO. –

Respuesta

12

Sucintamente, con una gran cantidad de dificultades.

Debe organizar que el shell su'd escriba el PID secundario en un archivo y luego elija la salida. Dado que será 'joe' la creación del archivo y no 'dex', que agrega otra capa de complejidad.

La solución más sencilla es probablemente:

su - joe -c "/path/to/my_daemon & echo \$! > /tmp/su.joe.$$" 
bg=$(</tmp/su.joe.$$) 
rm -f /tmp/su.joe.$$ # Probably fails - joe owns it, dex does not 

La siguiente solución implica el uso de un descriptor de archivo disperso - Número 3.

su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>/tmp/su.joe.$$ 
bg=$(</tmp/su.joe.$$) 
rm -f /tmp/su.joe.$$ 

Si usted está preocupado acerca de las interrupciones, etc (y probablemente debería ser), luego atrapas cosas también:

tmp=/tmp/su.joe.$$ 
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15 
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>$tmp 
bg=$(<$tmp) 
rm -f $tmp 
trap 0 1 2 3 13 15 

(Las señales atrapadas son HUP, IN T, QUIT, PIPE y PLAZO - plus 0 para la salida de la cáscara)

Advertencia:. La teoría agradable - código no probado ...

+0

Awesome answer. Podría ser capaz de salir adelante con solo esto: 'su - joe -c"/ruta/a/mi_daemon & eco \ $!> /tmp/su.joe. $$ "' ¡escapando $! y no hay punto y coma después de 'my_daemon &' también son trampas. Voy a jugar un poco con esto. – Dex

+0

¡Asegúrese de agregar un espacio después de $! o el caparazón puede interpretar esto de manera extraña. –

-1

aquí está mi solución

su oracle -c "/home/oracle/database/runInstaller" & 
pid=$(pgrep -P $!) 

Explantacion

  • pgrep -P $! - Obtiene el proceso hijo del padre pid $!
+0

¿Por qué esto es downvoted? Dos líneas de código sucinto sin uso de archivos tmp. – koola

-1

Tomé la solución anterior de Linux, pero tuve que agregar un descanso para darle al proceso infantil la oportunidad de comenzar.

su - joe -c "/path/to/my_daemon > /some/output/file" & 
parent=$! 
sleep 1 
pid=$(pgrep -P $parent) 

Correr en bash, que no le gusta pid=$(pgrep -P $!) pero si añado un espacio después del ! está bien: pid=$(pgrep -P $!). Me quedé con la variable adicional $parent para recordarme a mí mismo lo que estoy haciendo la próxima vez que vea el guión.

0

Los enfoques presentados aquí no funcionaron para mí. Esto es lo que hice:

PID_FILE=/tmp/service_pid_file 
su -m $SERVICE_USER -s /bin/bash -c "/path/to/executable $ARGS >/dev/null 2>&1 & echo \$! >$PID_FILE" 
PID=`cat $PID_FILE` 
Cuestiones relacionadas