Chcę, aby moje skrypty powłoki kończyły się niepowodzeniem, ilekroć wykonanie polecenia nimi nie powiedzie się.
Zazwyczaj robię to z:
set -e
set -o pipefail
(zazwyczaj dodaję set -u
też)
Chodzi o to, że żadne z powyższych nie działa z podstawieniem procesu. Ten kod wypisuje „ok” i kończy z kodem powrotu = 0, podczas gdy chciałbym, aby się nie powiódł:
#!/bin/bash -e
set -o pipefail
cat <(false) <(echo ok)
Czy istnieje coś równoważnego z „pipefail” oprócz zamiany procesu? W jakikolwiek inny sposób przekazać do polecenia wynik polecenia, ponieważ były to pliki, ale zgłaszanie błędu za każdym razem, gdy któryś z tych programów zawiedzie?
Rozwiązaniem człowieka biednego byłoby wykrycie, czy te polecenia zapisują do stderr (ale niektóre polecenia zapisują do stderr w udanych scenariuszach).
Innym rozwiązaniem zgodnym z POSIX-em byłoby użycie nazwanych potoków, ale muszę wyliczyć te podstawienia poleceń, które używają procesu, ponieważ oneliniści budują w locie ze skompilowanego kodu, a tworzenie nazwanych potoków skomplikowałoby rzeczy (dodatkowe polecenia, błąd pułapkowania dla usuwanie ich itp.)
$$
podstawienie nie działa dla mnie, ponieważ podstawienie polecenia nie jest wykonywane, ponieważ polecenie korzystające z podstawienia procesu odbywa się w potoku poleceń, który jest spawnowany z kodu „non-shell” (python). Prawdopodobnie powinienem utworzyć podproces w Pythonie i potokować je programowo.
kill -2 0
.
mkfifo pipe; { rm pipe; cat <file; } >pipe
. Że komenda zawiśnie aż czytelnik otwierapipe
ponieważ jest powłoka, która robi toopen()
i tak szybko, jak tam jest czytnik napipe
fs odwołuje się dopipe
ISrm
D”, a następniecat
kopiuje plik_wejściowy się deskryptorze przez powłokę do tej rury. W każdym razie, jeśli chcesz propagować błąd poza procesem sub: <( ! : || kill -2 "$$")