2012-02-16 16 views
6

En bash cuando corro un comando como wc & o cat & que quiere norma de inmediato, devuelve inmediatamente con¿Cómo puedo saber si un niño pide stdin? ¿Cómo le digo que deje de hacer eso?

[1] + Stopped cat

¿Cómo se logra esto? ¿Cómo detengo un programa que comencé con el ejecutivo, y cómo sé para detener estos programas en primer lugar? ¿Hay alguna manera de decir que estos programas quieren stdin?

Gracias!

PD también, ¿cuál es el + sobre? Siempre me he preguntado, pero eso es realmente difícil de google ...

+2

+1 para símbolos "difíciles de googlear" – Tim

+2

Puede encontrar esclarecedoras las respuestas a esta pregunta: [¿Cómo puedo saber si el ejecutable de un programa C se ejecuta en primer plano o en segundo plano?] (Http://stackoverflow.com/ preguntas/2425005/how-do-i-know-if-an-c-programs-executable-is-run-in-foreground-or-background) –

Respuesta

1

El setpgid() página del manual explica cómo funciona esto:

Una sesión puede tener un terminal de control. En cualquier momento, uno (y solo uno) de los grupos de procesos en la sesión puede ser el grupo de proceso en primer plano para el terminal; los grupos de proceso restantes están en el fondo. Si se genera una señal desde el terminal (por ejemplo, escribiendo la clave de interrupción para generar SIGINT), esa señal se envía al grupo de proceso de primer plano . (Consulte termios(3) para obtener una descripción de los caracteres que generan señales). Solo el proceso en primer plano grupo puede read(2) desde el terminal; si un grupo de proceso en segundo plano intenta a read(2) desde el terminal, se envía al grupo una señal SIGTSTP, que lo suspende. Las funciones tcgetpgrp(3) y tcsetpgrp(3) se utilizan para obtener/establecer el grupo de proceso en primer plano del terminal de control.

Así que lo que quiere hacer es la siguiente:

  1. Cuando se crea un nuevo gasoducto, llame setpgid() poner todos los miembros de la tubería en un nuevo grupo de procesos (con el PID del primer proceso en la tubería como el PGID).

  2. Uso tcsetpgrp() para gestionar el cual el grupo de procesos está en primer plano - si se pone una tubería en el fondo con &, usted debe hacer propio grupo de proceso de la cáscara del grupo de procesos en primer plano de nuevo.

  3. llamada waitpid() con los WNOHANG y WUNTRACED banderas para comprobar el estado de los procesos hijo - esto le informará cuando son detenidos por SIGTSTP, lo que permitirá imprimir un mensaje como lo hace bash.

+0

Usted, señor o señora, lo hizo. Esa es una página de manual larga, gracias por la referencia. No puedo dejar de notar que tiene 73 páginas de respuestas, pero solo tres preguntas: ¡eso es algo! Tú me honras e inspiras. – Ziggy

2

Si desea que los programas engendrados se comporten de manera similar a cómo funciona el shell, llame al setpgrp() después de bifurcar a su hijo. Esto hará que el programa en segundo plano se ejecute en su propio grupo de procesos y, por lo tanto, tenga un tty separado. Cuando intente hacer E/S a la consola, recibirá señales SIGTTIN o SIGTTOU. El comportamiento predeterminado de SIGTTIN o SIGTTOU es detener el proceso al igual que SIGSTOP.

Como padre, puede averiguar si ha detenido procesos secundarios usando waitpid() y WUNTRACED.

+0

'setpgrp()' está marcado como obsoleto en POSIX; históricamente ha tenido una firma diferente en los sistemas SYSV y BSD. 'setpgid()' es la interfaz preferida. – caf

2

[Editado - ver otras respuestas para la respuesta a la pregunta principal]

El signo + se refiere simplemente a la corriente trabajo. Cada canalización de comandos (como foo | bar | baz) es un trabajo, al que se puede hacer referencia utilizando jobspec comenzando con el carácter %. %1 es el trabajo número 1, %+ es el trabajo actual, y %- es el trabajo anterior.

Para obtener más información acerca de los trabajos, consulte el Job Control section del manual de Bash.

+0

El primer párrafo es incorrecto. Debe leer "desde el terminal de control del grupo de procesos" (o algo parecido a eso - Olvidé los detalles exactos), no "desde stdin (descriptor de archivo 0)". Una manera perfectamente buena de evitar esto es hacer que el descriptor de archivo 0 se refiera a un terminal no terminal, p. poniendo '

+1

Y es la acción predeterminada para 'SIGTTIN', no el shell, que suspende el proceso. Se puede anular con un manejador de señal. –

+0

Creo que esto no responde mi pregunta, que trata de c en lugar de bash. ¿Cómo se suspende el proceso y cómo sé que está leyendo de stdin? Recuerda, soy bash. (sin embargo, ¡sígueme la parte de PS! ¡Gracias!) – Ziggy

0

Puede utilizar system("command &") en el proceso hijo bifurcado y luego hacerlo manualmente la salida, si no hay tiempo y prioridad limitaciones.

Cuestiones relacionadas