Voglio che i miei script di shell falliscano ogni volta che un comando eseguito con loro fallisce.
In genere lo faccio con:
set -e
set -o pipefail
(in genere aggiungo set -u
anche io )
Il fatto è che nessuna delle precedenti funziona con la sostituzione del processo. Questo codice stampa "ok" ed esce con codice di ritorno = 0, mentre vorrei che fallisse:
#!/bin/bash -e
set -o pipefail
cat <(false) <(echo ok)
Esiste qualcosa di equivalente a "pipefail" se non per la sostituzione del processo? Qualche altro modo per passare a un comando l'output dei comandi come se fossero file, ma generando un errore ogni volta che uno di questi programmi fallisce?
La soluzione di un uomo povero sarebbe rilevare se quei comandi scrivono a stderr (ma alcuni comandi scrivono a stderr in scenari di successo).
Un'altra soluzione più conforme a posix sarebbe l'uso di named pipe, ma ho bisogno di lanciare quei comandi che usano la sostituzione del processo come oneliners costruiti al volo dal codice compilato, e la creazione di named pipe complicherà le cose (comandi extra, errore di intrappolamento per eliminandoli, ecc.)
$$
sostituzione non funziona per me, poiché la sostituzione del comando non viene eseguita poiché il comando che utilizza la sostituzione del processo viene eseguito all'interno di una pipeline di comandi generata da un codice "non shell" (python). Probabilmente dovrei creare un sottoprocesso in Python e installarli a livello di codice.
kill -2 0
.
mkfifo pipe; { rm pipe; cat <file; } >pipe
. Questo comando si bloccherà fino a quando un lettore aprepipe
perché è il guscio che fa l'open()
e così, non appena v'è un lettore supipe
FS collegamento perpipe
ISrm
'd e quindicat
copie infile fuori al descrittore della shell per quel tubo. E comunque, se vuoi propagare un errore fuori da un processo sub do: <( ! : || kill -2 "$$")