La función regresa, pero la sustitución del comando se bloquea, porque creó un trabajo en segundo plano, pero aún tiene su stdout fd abierta. Solo ciérrelo agregando >/dev/null
antes de &
.
#!/bin/bash
function start {
leafpad >/dev/null &
echo $!
}
PID=$(start)
echo "PID is $PID"
Si desea que su proceso también tenga stdin, stdout, stderr cerrados, use esto:
leafpad >/dev/null 0>&1 2>&1 &
Esto cerrará stdin (0), stdout (1) y stderr (2), luego el fondo (&). Además, cuando use estas redirecciones de flujo , no olvide que están "engañadas", lo que significa que están duplicadas en el orden de ejecución.
1>/dev/null 2>&1
y
2>&1 1>/dev/null
no son lo mismo ! En el primero, está duplicando una secuencia a / dev / null (que es lo que desea), en el segundo, está duplicando / dev / stdout a stderr, y luego, cerrando stdout. Por lo tanto, cualquier mensaje enviado a stderr
aparecerá en su consola.
n>&-
donden
está el descriptor de archivo./dev/null
no generará errores de E / S cuando un proceso intente escribir su stdout, pero descubra que1
es un FD no válido. Entonces, la terminología en la publicación es incorrecta, no la programación real de bash. (En realidad, duplicar FD 1 a 0 significa que stdin será un descriptor de archivo abiertoO_RDONLY
, lo que probablemente dará un error (en lugar de los no bytes deseados disponibles) cuando el proceso intente leer). Ej.wc >/dev/null 0>&1
->wc: standard input: Bad file descriptor
exec <&- >&- <>/dev/null >&0
maneja stdin / out bastante exhaustivamente. Hace una diferencia enzsh
al menos qué tipo de concatenación de todas las aperturas en el mismo descriptor automáticamente cuando se establece multios.