$> set -o pipefail
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли
Ин аст, fortune
барномаи шартӣ бе exit(rand())
.
Метавонед шарҳ диҳед? дар ин ҷо чӣ шуд?
Баромади лирикй-таърихй
Ман бори аввал бо ин Гейзенбуг чорьяк аср пеш шинос шуда будам. Сипас барои шлюз дар FaxNET лозим буд, ки тавассути якчанд утилитаҳо эҷод кунед
Таҷрибаи қаблии ман дар мубориза бо хатогиҳо дар sendmail ва uucp/uupc ба саъю кӯшиши ман дар “муомилоти ҳамаҷонибаи хатогӣ” илова кард. Ба тафсилоти он ҳикоя ғарқ шудан ҷоиз нест, аммо ман бо ин Ҳейзенбуг ду ҳафта 10-14 соат мубориза бурдам. Аз ин ру, ба ёдаш омад ва дируз ин шиноси дерина боз ба дидорбинй омад.
TL; DR Ҷавоб
Коммуналӣ head
метавонад каналро аз fortune
сразу баробари хондани сатри якум. Агар fortune
зиёда аз як сатр мебарорад, пас занги мувофиқ write()
хато бармегардонад ё хабар медиҳад, ки нисбат ба дархостшуда камтар байт бароварда шудааст. Дар навбати худ, бодиққат коркарди хато навишта шудааст fortune
хукук дорад ин вазъиятро дар холати баромади худ инъикос намояд. Баъд аз сабаби насб set -o pipefail
кор хохад кард || echo "Вы проиграли"
.
Аммо, head
мумкин аст, ки онро дар вакташ набароранд пеш бастан fortune
баровардани маълумотро ба охир мерасонад. Он гоҳ он кор хоҳад кард && echo "Повезло!"
.
Дар яке аз имрузаи ман GNUMakefile
echo '#define MDBX_BUILD_COMPILER "$(shell set -o pipefail; $(CC) --version | head -1 || echo 'Please use GCC or CLANG compatible compiler')"'
Ба инсон тарҷума шудааст
Дар ин ҷо барои он маъмул аст --version
аз он мепурсад, ки ӯ кист ва агар ин вариант дастгирӣ нашавад, нотача гузошта мешавад "Лутфан компилятори мувофиқи GCC ё CLANG -ро истифода баред".
Мисли
#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"
Рости ran, ман «ошнои» деринаамро дархол нашинохтам. Ғайр аз он, лоиҳа аллакай борҳо дар Элбрус ва дар доираи паҳнкунии гуногун, аз ҷумла Alt, санҷида шудааст. Бо компиляторҳои гуногун, версияҳои GNU Make ва bash. Аз ин рӯ, ман намехостам хатои худро дар ин ҷо бубинам.
Ҳангоми кӯшиши дубора тавлид кардани мушкилот ва / ё фаҳмидани он, ки чӣ рӯй дода истодааст, чизҳои аҷибтар ба амал омаданд.
Имлои сатри фармон:
echo "#define MDBX_BUILD_COMPILER '$(set -o pipefail; LC_ALL=C cc --version | head -1 || echo "Please use GCC or CLANG compatible compiler")'"
Ҳар гоҳ ва гоҳ он матни иловагӣ эҷод мекард, пас не... Аксар вақт яке аз вариантҳо муддати тӯлонӣ мемонд, аммо агар шумо дарозтар кашед, шумо ҳамеша ҳардуро мегиред!
Албатта, strace
Дар омади гап, мисли ҳар як эҳтироми худ strace
такрор накарданро афзалтар медонад.
Пас, чӣ мешавад?
- Коммуналӣ
head
хукук дорад (ё дурусттараш, хатто мачбур аст) баробари хондани шумораи сатрхои дархостшуда канали хондашавандаро банд кунад. - Муаллифи барномаи тавлидкунандаи маълумот (дар ин ҳолат
cc
) метавонад чанд сатр чоп кунед ва озод инро тавассути зангҳои сершумор иҷро кунедwrite()
. - агар хонанда пеш аз ба охир расидани сабт дар тарафи нависанда вақт дорад, ки каналро дар паҳлӯи худ пӯшад, пас нависанда хатогӣ мегирад.
- Барномаи нависанда ҳуқуқ дорад ҳарду хатои навиштани каналро нодида мегиранд ва онро дар рамзи анҷоми худ инъикос мекунанд.
- Аз сабаби насб
set -o pipefail
рамзи анҷоми қубур ғайрисифр (хатоӣ) хоҳад буд, агар натиҷа аз ҳадди аққал як элемент сифр набошад ва он гоҳ он кор хоҳад кард|| echo "Please use GCC or CLANG compatible compiler"
.
Вобаста аз он, ки барномаи нависанда бо сигналҳо чӣ гуна кор мекунад, метавонанд вариантҳо бошанд. Масалан, барнома метавонад ба таври ғайримуқаррарӣ қатъ шавад (бо тавлиди автоматии ҳолати қатъи сифр/хато) ё write()
натиҷаи навиштани байт камтар аз дархост ва муқарраршударо бармегардонад errno = EPIPE
.
Кӣ айбдор аст?
Дар сурати тавсифшуда каме аз ҳама чиз. Хатогӣ дар коркард cc
(lcc:1.23.20:Sep—4-2019:e2k-v3-linux) нест зиёдатӣ. Дар бисёр мавридҳо беҳтар аст, ки дар канори эҳтиёт хато кунед, гарчанде ки ин камбудиҳои ногаҳонӣ дар дегхонаи барои рафтори анъанавӣ тарҳрезӣшударо фош мекунад.
Чӣ бояд кард?
Хато:
fortune | head -1 && echo "Повезло, но вы рискуете!" || echo "WTF?"
Дуруст аст:
-
(fortune && echo "Успешно" || echo "Ошибка") | head -1
Дар ин ҷо барвақт бастани қубур аз ҷониби тарҷумони фармон ҳангоми хидматрасонӣ ба қубури лона гузошташуда ("дар дохили қавс") анҷом дода мешавад. Мувофики он, агар
fortune
хато дар навиштан ба канали пӯшида дар ҳолати хабар медиҳад, пас баромад|| echo "Ошибка"
он ба ҷое намерасад, зеро канал аллакай баста аст. -
fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"
Ин аст хидматрасонӣ
cat
ҳамчун дампер амал мекунад, зеро он хатогиро нодида мегирадEPIPE
ҳангоми хуруҷ. Ҳоло барои хулосабарорӣ ин кофӣ астfortune
хурд (якчанд сатр) ва ба буфери канал мувофиқат мекунад (аз 512 байт то ≈64К, дар аксари OS ≥4K). Дар акси ҳол, мушкилот метавонад баргардад.
Чӣ тавр дуруст коркард кардан EPIPE
ва дигар хатогиҳои сабт?
Ҳалли ягонаи дуруст вуҷуд надорад, аммо тавсияҳои оддӣ мавҷуданд:
EPIPE
талаб карда мешавад бояд коркард карда шавад (ва дар ҳолати баромадан инъикос карда мешавад) ҳангоми баровардани маълумоте, ки якпорчагӣ талаб мекунад. Масалан, ҳангоми кори архивҳо ё утилитаҳои эҳтиётӣ.EPIPE
нодида гирифтан беҳтар аст ҳангоми намоиш додани маълумот ва паёмҳои ёрирасон. Масалан, ҳангоми намоиш додани маълумот оид ба вариантҳо--help
ё--version
.- Агар коди таҳияшаванда метавонад дар як лӯлаи пеш истифода шавад
| head
, он гоҳEPIPE
Беҳтар аст, ки сарфи назар кунед, вагарна беҳтар аст, ки коркард ва инъикос дар ҳолати баромад.
Аз фурсат истифода бурда, мехоҳам ба дастаҳо миннатдории худро баён намоям
Онро давом диҳед Камарадес, боло
Спасибо
KDPV аз
Манбаъ: will.com