¿Invocar un comando / script desconectado del terminal de control?

9

Estoy investigando el comportamiento de un script que normalmente se ejecuta como un proceso automatizado (por ejemplo, cron, Jenkins). El script puede (eventualmente) invocar comandos que se comportan de manera diferente (buscando la entrada del usuario) cuando se ejecuta de forma interactiva; por ejemplo, patchpreguntará qué hacer con un parche invertido y svnsolicitará contraseñas, pero necesito ver qué sucede cuando se ejecutan de manera no interactiva.

Persuadir patchque no es interactivo es bastante fácil; Solo necesito redirigir stdoutpara ser un no-tty:

$ </dev/null > >(cat) /path/to/myscript --args

Sin embargo, svnse conectará al terminal de control si existe; editar los scripts para pasar --non-interactiveno es realmente una opción, ya que proviene de varios niveles y sería difícil estar seguro de que encontré cada invocación.

¿Hay alguna manera de invocar un script / comando de forma no interactiva, sin un terminal de control (para que eso /dev/ttyno exista)? Prefiero que stdout / stderr aún vaya a mi terminal.

(Encontré la pregunta ¿ Ejecutar script en un shell no interactivo? Pero las respuestas a eso discuten las diferencias entre el entorno cron y el entorno del usuario; ya he eliminado todas las diferencias excepto la no interactividad).

ecatmur
fuente

Respuestas:

13

Debe iniciar otra sesión no conectada a un terminal, por ejemplo:

$ setsid sh -c 'tty; ps -jp "$$"; echo test' < /dev/null > log 2>&1
$ cat log
not a tty
  PID  PGID   SID TTY          TIME CMD
19506 19506 19506 ?        00:00:00 sh
test

Vea también el start-stop-daemoncomando que se encuentra en algunas distribuciones de Linux. También hay un daemoncomando.

Stéphane Chazelas
fuente
¿Qué significa esta salida? Se ve muy críptico.
anatoly techtonik
2
@anatolytechtonik las partes importantes son "no un tty", que es el resultado de ttyconfirmar que no hay terminal en stdin, y el "?" en la columna de pssalida TTY que confirma que no hay control tty para el shproceso (y cualquier cosa que se ejecute debajo de él).
Sr.Spuratic
Para ejecutar el comando como cualquier otro comando, use setsid -w. Ejemplo: setsid -w sh -c 'tty < /dev/tty'da sh: 1: cannot open /dev/tty: No such device or address(Nota: /dev/ttyes su tty controlador). Sin -wsetsid se ejecuta el proceso en paralelo / en segundo plano.
Tino
0

Probablemente quieras hacer un script de esperar. Ejemplo con SVN:

/programming/609445/using-expect-to-login-into-svn

Bratchley
fuente
Eso no funciona esperar ejecuta comandos de forma interactiva.
ecatmur
¿Interactivamente en qué sentido? En el sentido de que requiere la entrada del usuario? Si eso es lo que quieres decir, no tendría mucho sentido esperar que exista en ese caso. Un ejemplo para el que lo uso es en Solaris, el comando passwd no tiene una opción --stdin, así que tengo un cronjob configurado que ejecuta un script de espera que envuelve passwd para proporcionarle una contraseña aleatoria para una cuenta. No se requiere interacción humana. Tengo entendido que este es el requisito del usuario. Aunque podría haber entendido mal.
Bratchley
En realidad, cuanto más vuelvo a leer esto, más me doy cuenta de que entendí mal lo que estabas buscando. Disculpas
Bratchley
0

A veces es necesario mantener abierto el stdin (no recibir eof en el stdin) (por ejemplo, esperar). En ese caso, cambie / dev / null a / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Roger
fuente