$> set -o pipefail
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли
دا fortune
پرته له مشروط پروګرام exit(rand())
.
کولای شی تشریح کړی؟ دلته څه غلط دي?
شعر - تاریخي تحلیل
زه د لومړي ځل لپاره د دې هیزنبګ سره څلورمه پیړۍ دمخه آشنا شوم. بیا په FaxNET کې د دروازې لپاره دا اړینه وه چې له لارې ډیری اسانتیاوې رامینځته کړي
په لیږل شوي میل او 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"
په ریښتیا، ما سمدلاسه زما زوړ "آشنا" نه پیژندلی. سربیره پردې ، پروژه دمخه په ایلبروس کې څو ځله ازمول شوې او د ډیری مختلف توزیع لاندې ، په شمول د Alt. د مختلف کمپیلرونو سره ، د GNU میک او باش نسخې. له همدې امله، زه نه غواړم دلته خپله تېروتنه وګورم.
کله چې د ستونزې د بیا تولید هڅه وکړئ او / یا پوه شئ چې څه تیریږي، ډیر عجیب شیان پیښ شوي.
د کمانډ لاین املا:
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 بایټ څخه تر ≈64K پورې، په ډیری OS ≥4K کې). که نه نو ستونزه به بیرته راشي.
څنګه سمه پروسس کول EPIPE
او د ثبت کولو نورې تېروتنې؟
هیڅ یو مناسب حل شتون نلري، مګر ساده سپارښتنې شتون لري:
EPIPE
اړین دی باید پروسس شي (او د وتلو حالت کې منعکس کیږي) کله چې ډیټا تولیدوي چې بشپړتیا ته اړتیا لري. د مثال په توګه، د آرشیف یا بیک اپ اسانتیاوو د عملیاتو په جریان کې.EPIPE
له پامه غورځول غوره دي کله چې معلومات او مرستندویه پیغامونه ښکاره کوي. د مثال په توګه، کله چې د اختیارونو په اړه معلومات ښکاره کول--help
او یا--version
.- که چیرې کوډ رامینځته شي مخکې له دې په پایپ لاین کې وکارول شي
| head
بیا وروستهEPIPE
دا غوره ده چې سترګې پټې کړئ، که نه نو دا غوره ده چې د وتلو حالت کې پروسس او منعکس کړئ.
زه غواړم له دې فرصت څخه ګټه واخلم چې له ټیمونو څخه خپله مننه څرګند کړم
دا ساتئ کامریډز، پورته
سپوږمکۍ
له KDPV څخه
سرچینه: www.habr.com