$> set -o pipefail
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!
$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли
ဒါဟာဖြစ်ပါတယ် fortune
conditional program မပါပဲ exit(rand())
.
ရှင်းပြနိုင်မလား။ ဒီမှာ ဘာဖြစ်နေတာလဲ?
သီချင်းစာသား- သမိုင်းဆိုင်ရာ ကွဲလွဲမှု
လွန်ခဲ့တဲ့ ရာစုနှစ်ရဲ့ လေးပုံတစ်ပုံလောက်က ဒီ Heisenbug နဲ့ ပထမဆုံး သိကျွမ်းခဲ့တယ်။ ထို့နောက် FaxNET ရှိ gateway အတွက် utilities အများအပြားကို ဖန်တီးရန် လိုအပ်ပါသည်။
ပေးပို့စာမေးလ်နှင့် uucp/uupc တွင် ချို့ယွင်းချက်များနှင့် ကိုင်တွယ်ဖြေရှင်းခြင်းဆိုင်ရာ ကျွန်ုပ်၏ယခင်အတွေ့အကြုံသည် “သေချာသောအမှားအယွင်းကို ကိုင်တွယ်ခြင်း” တွင် ကျွန်ုပ်၏လုံ့လဝီရိယကို ပေါင်းထည့်ပါသည်။ ထိုဇာတ်လမ်း၏အသေးစိတ်အချက်အလက်များကို စေ့စေ့ငုကြည့်ရန်မှာ အဓိပ္ပါယ်မရှိသော်လည်း၊ ဤ Heisenbug ကို နှစ်ပတ်ကြာအောင် 10-14 နာရီကြာ ရုန်းကန်ခဲ့ရသည်။ ထို့ကြောင့် သတိရမိသည်နှင့် မနေ့ က ဤအသိအကျွမ်းဟောင်းသည် နောက်တစ်ကြိမ် လည်ပတ်ရန် ရပ်တန့်သွားခဲ့သည်။
TL;DR အဖြေ
အသုံးဝင်သည် head
နိုင် ချန်နယ်ကို ပိတ်ပါ။ fortune
တစ်ကြိမ် ပထမစာကြောင်းကို ဖတ်ပြီးတာနဲ့ ရှိရင် fortune
လိုင်းတစ်ခုထက်ပို၍ ထွက်ပြီးနောက် သက်ဆိုင်ရာခေါ်ဆိုမှု write()
တောင်းဆိုသည်ထက် ဘိုက်များ အထွက်နည်းကြောင်း အမှားတစ်ခု ပြန်ပေးမည် သို့မဟုတ် အစီရင်ခံပါမည်။ တစ်ဖန် ဂရုတစိုက် အမှားအယွင်း ဖြင့် ရေးထား သည်။ fortune
ဤအခြေအနေကို ၎င်း၏ ထွက်ပေါက်အခြေအနေတွင် ထင်ဟပ်ဖော်ပြပိုင်ခွင့်ရှိသည်။ ထို့နောက် တပ်ဆင်မှုကြောင့် ဖြစ်သည်။ set -o pipefail
အလုပ်လုပ်ပါလိမ့်မယ်။ || echo "Вы проиграли"
.
သို့သျောလညျး head
အချိန်မီ မဆောင်ရွက်နိုင်ပါ။ အရင်ပိတ် fortune
data output ပြီးသွားပါလိမ့်မယ်။ ပြီးရင် အလုပ်ဖြစ်လိမ့်မယ်။ && 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 တွဲသုံးနိုင်သော compiler ကိုသုံးပါ".
ကြိုက်တယ်။
#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"
ရှင်းရှင်းပြောရလျှင်၊ ကျွန်ုပ်သည် ကျွန်ုပ်၏ “အသိမိတ်ဆွေဟောင်း” ကို ချက်ချင်းမမှတ်မိပါ။ ထို့အပြင်၊ ပရောဂျက်ကို Elbrus တွင် အကြိမ်များစွာ စမ်းသပ်ခဲ့ပြီး Alt အပါအဝင် မတူညီသော ဖြန့်ဖြူးမှုများစွာအောက်တွင် ရှိနေသည်။ အမျိုးမျိုးသော compilers၊ GNU Make နှင့် bash ဗားရှင်းများ။ ဒါကြောင့် ငါ့အမှားကို ဒီမှာ မမြင်ချင်ဘူး။
ပြဿနာကို ပြန်လည်ဖန်တီးရန်နှင့်/သို့မဟုတ် ဖြစ်ပျက်နေသည့်အရာများကို နားလည်ရန်ကြိုးစားသောအခါတွင် ပို၍ထူးဆန်းသောအရာများ ပေါ်ပေါက်လာသည်။
Command line စာလုံးပေါင်း-
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
) နိုင် လိုင်းများစွာနှင့် print ထုတ်ပါ။ အခမဲ့ ခေါ်ဆိုမှုများစွာဖြင့် ပြုလုပ်ပါ။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
အမှားကိုလျစ်လျူရှုသောကြောင့် damper အဖြစ်လုပ်ဆောင်သည်။EPIPE
နုတ်ထွက်ပြီးနောက်။ အခု နိဂုံးချုပ်ဖို့ လုံလောက်ပါပြီ။fortune
သေးငယ်သော (လိုင်းများစွာ) နှင့် ချန်နယ်ကြားခံစနစ် (OS ≥512K အများစုတွင် 64 bytes မှ ≈4K အထိ) တွင် အံဝင်ခွင်ကျရှိသည်။ မဟုတ်ရင် ပြဿနာက ပြန်ဖြစ်လာနိုင်တယ်။
မှန်ကန်စွာ စီမံဆောင်ရွက်ပုံ EPIPE
နှင့် အခြားသော အသံသွင်းအမှားများ ?
မှန်ကန်သောဖြေရှင်းချက်တစ်ခုမျှမရှိသော်လည်း ရိုးရှင်းသောအကြံပြုချက်များရှိသည်။
EPIPE
လိုအပ် စီမံဆောင်ရွက်ရမည်။ ခိုင်မာမှုလိုအပ်သော ဒေတာကို ထုတ်သည့်အခါ (ထွက်ပေါက်အခြေအနေတွင် ထင်ဟပ်စေသည်)။ ဥပမာအားဖြင့်၊ archivers သို့မဟုတ် backup utilities များလည်ပတ်နေစဉ်။EPIPE
လျစ်လျူရှုတာ ပိုကောင်းပါတယ်။ အချက်အလက်နှင့် အရန်စာများကို ပြသသည့်အခါ။ ဥပမာအားဖြင့်၊ ရွေးချယ်စရာများပေါ်တွင် အချက်အလက်ပြသသည့်အခါ--help
သို့မဟုတ်--version
.- ကုဒ်ကို တီထွင်နေပါက ပိုက်လိုင်းကို အရင်သုံးနိုင်သည်။
| head
ထိုအခါEPIPE
လျစ်လျူရှုခြင်းသည် ပိုကောင်းသည်၊ မဟုတ်ပါက ထွက်ပေါက်အခြေအနေတွင် စီမံဆောင်ရွက်ပြီး ထင်ဟပ်ပြခြင်းက ပိုကောင်းပါသည်။
အသင်းတွေကို ကျေးဇူးတင်ကြောင်း ဖော်ပြဖို့ ဒီအခွင့်အရေးကို ရယူချင်ပါတယ်။
အဲဒါကို စောင့်ပါ ရဲဘော်ရဲဘက်တွေ၊
Спасибо
KDPV ထံမှ
source: www.habr.com