Quiero que mis scripts de shell fallen siempre que un comando ejecutado con ellos falle.
Típicamente hago eso con:
set -e
set -o pipefail
(normalmente agrego set -u
también)
El caso es que ninguno de los anteriores funciona con la sustitución de procesos. Este código imprime "ok" y sale con el código de retorno = 0, mientras que me gustaría que fallara:
#!/bin/bash -e
set -o pipefail
cat <(false) <(echo ok)
¿Hay algo equivalente a "pipefail" pero para la sustitución del proceso? ¿Hay alguna otra forma de pasar a un comando la salida de comandos como si fueran archivos, pero generar un error cada vez que falla alguno de esos programas?
La solución de un hombre pobre sería detectar si esos comandos escriben en stderr (pero algunos comandos escriben en stderr en escenarios exitosos).
Otra solución más compatible con posix sería usar canalizaciones con nombre, pero necesito eliminar esos comandos que utilizan la sustitución de procesos como líneas integradas sobre la marcha a partir de código compilado, y crear canalizaciones con nombre complicaría las cosas (comandos adicionales, error de captura para eliminándolos, etc.)
$$
sustitución no funciona para mí, ya que la sustitución de este comando no se realiza ya que el comando que utiliza la sustitución del proceso se realiza dentro de una tubería de comando que se genera a partir de un código "no shell" (python). Probablemente debería crear un subproceso en python y canalizarlos programáticamente.
kill -2 0
.
mkfifo pipe; { rm pipe; cat <file; } >pipe
. Ese comando se bloqueará hasta que se abra un lectorpipe
porque es el shell el que hace el comandoopen()
y, en cuanto haya un lector enpipe
el enlace fs parapipe
isrm
'd, y luegocat
copie el archivo en el descriptor del shell para ese conducto. Y de todos modos, si desea propagar un error fuera de un subproceso de proceso: <( ! : || kill -2 "$$")