$> set -o pipefail
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли
Hawnhekk fortune
programm kondizzjonali mingħajr exit(rand())
.
Tista' tispjega? x'hemm ħażin hawn?
Digressjoni lirika-storika
L-ewwel sirt familjari ma' dan il-Heisenbug kwart ta' seklu ilu. Imbagħad għall-portal f'FaxNET kien meħtieġ li jinħolqu diversi utilitajiet permezz
L-esperjenza preċedenti tiegħi li nittratta l-bugs fis-sendmail u l-uucp/uupc żiedet mad-diliġenza tiegħi fl-"immaniġġjar bir-reqqa tal-iżbalji." M'hemm l-ebda skop li togħdos fid-dettalji ta 'dik l-istorja, iżda tħabtu ma' dan Heisenbug għal ġimgħatejn għal 10-14-il siegħa. Għalhekk, ġie mfakkar, u lbieraħ dan il-konoxxenza antik waqaf biex jerġa’ jżur.
TL;DR Tweġiba
Utilità head
jista agħlaq il-kanal minn fortune
f'daqqa malli jaqra l-ewwel linja. Jekk fortune
joħroġ aktar minn linja waħda, imbagħad is-sejħa korrispondenti write()
se jirritorna żball jew jirrapporta li jinħarġu inqas bytes milli mitlub. Min-naħa tagħhom, miktuba bl-immaniġġjar tal-iżbalji bir-reqqa fortune
għandha d-dritt li tirrifletti din is-sitwazzjoni fl-istatus ta’ ħruġ tagħha. Imbagħad minħabba l-installazzjoni set -o pipefail
se taħdem || echo "Вы проиграли"
.
Madankollu, head
ma jistax jasal fil-ħin qrib qabel fortune
se jispiċċa joħroġ id-data. Imbagħad se taħdem && echo "Повезло!"
.
F'wieħed mill-lum tiegħi GNUMakefile
echo '#define MDBX_BUILD_COMPILER "$(shell set -o pipefail; $(CC) --version | head -1 || echo 'Please use GCC or CLANG compatible compiler')"'
Tradott fil-bniedem
Huwa komuni hawn għal --version
tistaqsi min hu, u jekk l-għażla ma tkunx appoġġjata, imbagħad jiddaħħal stub "Jekk jogħġbok uża kompilatur kompatibbli GCC jew CLANG".
Simili
#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"
Franchement, ma għarafejtx mill-ewwel il-“konoxxenza” tiegħi. Barra minn hekk, il-proġett diġà ġie ttestjat ħafna drabi fuq Elbrus u taħt ħafna distribuzzjonijiet differenti, inkluż Alt. B'diversi kompilaturi, verżjonijiet ta' GNU Make u bash. Għalhekk, ma ridtx nara l-iżball tiegħi hawn.
Meta tipprova tirriproduċi l-problema u/jew tifhem x'kien qed jiġri, bdew iseħħu aktar affarijiet strambi.
Spell tal-linja tal-kmand:
echo "#define MDBX_BUILD_COMPILER '$(set -o pipefail; LC_ALL=C cc --version | head -1 || echo "Please use GCC or CLANG compatible compiler")'"
Kultant kien jipproduċi test żejjed, allura le... Ħafna drabi waħda mill-għażliet kienet tibqa 'għal żmien pjuttost twil, imma jekk tpoġġi aktar, dejjem ikollok it-tnejn!
Of course, strace
Mill-mod, bħal kull li jirrispetta lilu nnifsu strace
jippreferi ma jirriproduċix.
Allura x'qed jiġri?
- Utilità
head
għandu d-dritt (jew aħjar, huwa saħansitra sfurzat) li jagħlaq il-kanal li qed jinqara hekk kif jaqra n-numru ta’ linji mitlub. - Il-kittieb tal-programm li jiġġenera d-dejta (f'dan il-każ
cc
) jista istampa linji multipli u b'xejn tagħmel dan permezz ta' sejħiet multipliwrite()
. - Jekk il-qarrej ikollu ħin biex jagħlaq il-kanal fuq in-naħa tiegħu qabel it-tmiem tar-reġistrazzjoni fuq in-naħa tal-kittieb, allura l-kittieb jirċievi żball.
- Programm tal-kittieb għandu d-dritt it-tnejn jinjoraw l-iżball tal-kitba tal-kanal u jirriflettuh fil-kodiċi tat-tlestija tiegħek.
- Minħabba l-installazzjoni
set -o pipefail
il-kodiċi tat-tlestija tal-pipeline se jkun mhux żero (żbaljat) jekk ir-riżultat ikun mhux żero minn mill-inqas element wieħed, u mbagħad jaħdem|| echo "Please use GCC or CLANG compatible compiler"
.
Jista 'jkun hemm varjazzjonijiet skond kif il-programm kittieb jaħdem mas-sinjali. Pereżempju, il-programm jista' jintemm b'mod anormali (b'ġenerazzjoni awtomatika ta' status ta' terminazzjoni mhux żero/żball), jew write()
se jirritorna r-riżultat tal-kitba ta 'inqas bytes milli mitlub u ssettjat errno = EPIPE
.
Min hu ħati?
Fil-każ deskritt ftit minn kollox. Immaniġġjar ta' żbalji fi cc
(lcc:1.23.20:Sep—4-2019:e2k-v3-linux) mhux żejda. F'ħafna każijiet huwa aħjar li wieħed jiżbalja min-naħa tal-kawtela, għalkemm dan jesponi difetti f'daqqa f'boilerplate iddisinjat għal imġieba tradizzjonali.
X'għandek tagħmel?
Ħażin:
fortune | head -1 && echo "Повезло, но вы рискуете!" || echo "WTF?"
B'mod korrett:
-
(fortune && echo "Успешно" || echo "Ошибка") | head -1
Hawnhekk, l-għeluq bikri ta 'pajp se jiġi mmaniġġjat mill-interpretu tal-kmand meta jservi l-pipeline nested ("ġewwa" il-parentesi). Għaldaqstant, jekk
fortune
se tirrapporta żball bil-miktub lil kanal magħluq fl-istatus, imbagħad l-output|| echo "Ошибка"
ma jasal imkien, peress li l-kanal huwa diġà magħluq. -
fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"
Hawn l-utilità
cat
jaġixxi bħala umidifikatur minħabba li jinjora l-iżballEPIPE
mal-irtirar. Dan huwa biżżejjed għalissa konklużjonifortune
żgħar (diversi linji) u jidħlu fil-buffer tal-kanal (minn 512 bytes għal ≈64K, fil-biċċa l-kbira tal-OS ≥4K). Inkella l-problema tista 'tirritorna.
Kif tipproċessa b'mod korrett EPIPE
u żbalji oħra ta' reġistrazzjoni?
M'hemm l-ebda soluzzjoni tajba waħda, iżda hemm rakkomandazzjonijiet sempliċi:
EPIPE
meħtieġa għandhom jiġu pproċessati (u rifless fl-istatus tal-ħruġ) meta toħroġ data li teħtieġ integrità. Per eżempju, waqt l-operazzjoni ta 'arkivji jew utilitajiet backup.EPIPE
aħjar li tinjora meta turi informazzjoni u messaġġi awżiljarji. Per eżempju, meta turi informazzjoni dwar l-għażliet--help
jew--version
.- Jekk il-kodiċi li qed jiġi żviluppat jista 'jintuża f'pipeline qabel
| head
, ImbagħadEPIPE
Huwa aħjar li tinjora, inkella huwa aħjar li tipproċessa u tirrifletti fl-istatus tal-ħruġ.
Nixtieq nieħu din l-opportunità biex nesprimi l-gratitudni tiegħi lit-timijiet
Żomm hekk Camarades, up
Grazzi
KDPV minn
Sors: www.habr.com