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/nullantes 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 stderraparecerá en su consola.
n>&-dondenestá el descriptor de archivo./dev/nullno generará errores de E / S cuando un proceso intente escribir su stdout, pero descubra que1es 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 descriptorexec <&- >&- <>/dev/null >&0maneja stdin / out bastante exhaustivamente. Hace una diferencia enzshal menos qué tipo de concatenación de todas las aperturas en el mismo descriptor automáticamente cuando se establece multios.