$> set -o pipefail
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли
et ass fortune
bedingt Programm ouni exit(rand())
.
Kënnt Dir erklären? wat ass hei falsch?
Lyresch-historeschen Ausdrock
Ech hunn dës Heisenbug fir d'éischt virun engem Véierel Joerhonnert kennegeléiert. Dann fir de Paart am FaxNET war et néideg e puer Utilities ze kreéieren iwwer
Meng fréier Erfahrung mam Ëmgang mat Bugs am Sendmail an uucp / uupc huet zu menger Diligence am "gräifend Fehlerhandhabung" bäigefüügt. Et huet kee Sënn fir an d'Detailer vun där Geschicht ze tauchen, mee ech hu mat dëser Heisenbug zwou Woche fir 10-14 Stonnen gekämpft. Dofir gouf et drun erënnert, a gëschter war dësen ale Bekannten nach eng Kéier op Besuch.
TL; DR Äntwert
Utility head
kann zoumaachen de Kanal vun fortune
сразу soubal hien déi éischt Zeil liest. Wann fortune
Ausgab méi wéi eng Zeil, dann de entspriechende Uruff write()
wäert e Feeler zréckginn oder bericht datt manner Bytes erausginn wéi ugefrot. Am Tour, schrëftlech mat virsiichteg Feeler Ëmgank fortune
huet d'Recht dës Situatioun a sengem Austrëttstatus ze reflektéieren. Dann wéinst Installatioun set -o pipefail
wäert schaffen || echo "Вы проиграли"
.
Awer, head
kann et net zu Zäit maachen no virun fortune
wäert d'Daten ausginn. Da wäert et schaffen && echo "Повезло!"
.
An engem vun mengem haut GNUMakefile
echo '#define MDBX_BUILD_COMPILER "$(shell set -o pipefail; $(CC) --version | head -1 || echo 'Please use GCC or CLANG compatible compiler')"'
Op Mënsch iwwersat
Et ass hei allgemeng fir --version
et freet wien hien ass, a wann d'Optioun net ënnerstëtzt gëtt, da gëtt e Stéck agebaut "Benotzt w.e.g. GCC oder CLANG kompatibel Compiler".
wëll
#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"
Éierlech gesot, ech hunn meng al "Bekannten" net direkt erkannt. Ausserdeem gouf de Projet scho vill Mol op Elbrus getest an ënner ville verschiddene Verdeelungen, dorënner Alt. Mat verschiddene Compileren, Versioune vu GNU Make a bash. Dofir wollt ech mäi Feeler hei net gesinn.
Wann Dir probéiert de Problem ze reproduzéieren an / oder ze verstoen wat lass war, hunn méi komesch Saachen ugefaang ze geschéien.
Kommandozeil Zauber:
echo "#define MDBX_BUILD_COMPILER '$(set -o pipefail; LC_ALL=C cc --version | head -1 || echo "Please use GCC or CLANG compatible compiler")'"
Heiansdo géif et extra Text produzéieren, dann net ... Dacks géif eng vun den Optiounen zimlech laang bleiwen, awer wann Dir méi laang gepickt hutt, kritt Dir ëmmer béid!
Natiirlech, strace
Iwwregens, wéi all Self-Respekt strace
léiwer net reproduzéieren.
Also wat ass lass?
- Utility
head
huet d'Recht (oder besser gesot, ass souguer gezwongen) de Kanal zouzemaachen, dee gelies gëtt, soubal et déi ugefrote Unzuel vun Zeilen liest. - Den Date-generéierende Programm-Schrëftsteller (an dësem Fall
cc
) kann Drécken MÉI Linnen an fräi maachen dëst duerch Multiple Uruffwrite()
. - wann de Lieser wäert Zäit hunn de Kanal op senger Säit virum Enn vun der Opnam op der Säit vum Schrëftsteller zouzemaachen, da kritt de Schrëftsteller e Feeler.
- Schrëftsteller Programm Recht op souwuel ignoréieren de Kanal Schreiffehler a reflektéieren et an Ärem Ofschlosscode.
- Wéinst Installatioun
set -o pipefail
de Pipeline Fäerdegstellungscode wäert net null sinn (fehlerhaft) wann d'Resultat net null ass vun mindestens engem Element, an da funktionnéiert et|| echo "Please use GCC or CLANG compatible compiler"
.
Et kann Variatioune ginn je wéi de Schrëftsteller Programm Wierker mat Signaler. Zum Beispill kann de Programm abnormal ophalen (mat automatesch Generatioun vun engem Net-Null/Fehlerterminatiounsstatus), oder write()
wäert d'Resultat zréckginn fir manner Bytes ze schreiwen wéi gefrot a gesat errno = EPIPE
.
Wien ass schëlleg?
Am beschriwwene Fall bëssen vun allem. Feeler Ëmgank an cc
(lcc:1.23.20:Sep—4-2019:e2k-v3-linux) ass net iwwerflësseg. A ville Fäll ass et besser op der Säit vu Vorsicht ze falschen, obwuel dëst plötzlech Mängel an engem Kesselplack entworf fir traditionell Verhalen aussetzt.
Wat soll ech maachen?
Falsch:
fortune | head -1 && echo "Повезло, но вы рискуете!" || echo "WTF?"
Richteg:
-
(fortune && echo "Успешно" || echo "Ошибка") | head -1
Hei gëtt fréi Schließung vun enger Päif vum Kommando-Interpreter gehandhabt wann Dir déi nested Pipeline servéiert ("bannent" de Klammern). Deementspriechend, wann
fortune
wäert e Feeler schrëftlech zu engem zougemaach Kanal am Status Rapport, dann den Ausgang|| echo "Ошибка"
et wäert net iwwerall kommen, well de Kanal scho zou ass. -
fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"
Hei ass den Utility
cat
wierkt als Dämpfer well et de Feeler ignoréiertEPIPE
beim Austrëtt. Dëst ass genuch fir elo Conclusiounfortune
kleng (puer Linnen) a passt am Kanal Prellbock (vu 512 Bytes ze ≈64K, am meeschte OS ≥4K). Soss kann de Problem zréckkommen.
Wéi richteg veraarbecht EPIPE
an aner Opnam Feeler?
Et gëtt keng eenzeg richteg Léisung, awer et ginn einfach Empfehlungen:
EPIPE
erfuerderlech sinn muss veraarbecht ginn (a reflektéiert am Ausgangsstatus) wann Dir Daten ausginn déi Integritéit erfuerderen. Zum Beispill, während der Operatioun vun Archiver oder Backup Utilities.EPIPE
besser ze ignoréieren wann Dir Informatioun an Hëllefsmeldungen weist. Zum Beispill, wann Dir Informatioun iwwer Optiounen weist--help
oder--version
.- Wann de Code entwéckelt, kann an enger Pipeline benotzt ginn ier
| head
, dannEPIPE
Et ass besser ze ignoréieren, soss ass et besser ze veraarbecht an am Ausgangsstatus ze reflektéieren.
Ech wëll vun dëser Geleeënheet profitéieren fir d'Equipen meng Dankbarkeet auszedrécken
Weider sou Camarades, weider
Spass
KDPV aus
Source: will.com