කිඹුලා පසුකර ගිය තවත් එක් හයිසන්බග්

කිඹුලා පසුකර ගිය තවත් එක් හයිසන්බග්

$> set -o pipefail

$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!

$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли

එය fortune තොරව කොන්දේසි සහිත වැඩසටහන exit(rand()).

ඔබට පැහැදිලි කළ හැකිද මොකක්ද මෙතන වැරැද්ද?

ගීතමය-ඓතිහාසික අපගමනය

මම මේ හයිසන්බග් සමඟ මුලින්ම දැන හඳුනා ගත්තේ සියවසකට හතරකට පෙරය. එවිට FaxNET හි ද්වාරය සඳහා එය හරහා උපයෝගිතා කිහිපයක් නිර්මාණය කිරීමට අවශ්ය විය පයිප්ප FreeBSD යටතේ "සෙල්ලම් චෙක්සර්". අපේක්ෂා කළ පරිදි, මම උසස් සහ තරමක් පළපුරුදු වැඩසටහන්කරුවෙකු ලෙස සැලකුවෙමි. එමනිසා, දෝෂ හැසිරවීම කෙරෙහි විශේෂ අවධානයක් යොමු කරමින්, හැකිතාක් ප්‍රවේශමෙන් සහ ප්‍රවේශමෙන් සෑම දෙයක්ම කිරීමට මම අදහස් කළෙමි ...

යැවීමේ තැපෑලෙහි සහ 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')"'

මිනිසා බවට පරිවර්තනය කර ඇත

ඒක මෙතනට පොදුයි GNU සාදන්න и බෂ් විකල්පය භාවිතා කරමින් සම්පාදක ආකාරයෙන් --version එය ඔහු කවුදැයි අසන අතර, විකල්පයට සහය නොදක්වන්නේ නම්, එවිට අංකුරයක් ඇතුල් කරනු ලැබේ "කරුණාකර GCC හෝ CLANG ගැළපෙන සම්පාදකය භාවිතා කරන්න".

මෙන් බොයිලේරු තහඩුව ඕනෑම තැනක සොයා ගත හැක. එය බොහෝ කලකට පෙර මෙම ස්ථානයේ දර්ශනය වූ අතර සෑම තැනකම පරිපූර්ණව වැඩ කළේය (Linux, Solaris, OSX, FreeBSD, WSL ආදිය). නමුත් ඊයේ දී altlinux වේදිකාවේ Elbrus 2000 (E2K) මම දැක්කා:

#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"

අවංකවම, මම මගේ පැරණි "හඳුනන අය" වහාම හඳුනා ගත්තේ නැත. එපමනක් නොව, මෙම ව්‍යාපෘතිය දැනටමත් Elbrus හි බොහෝ වාරයක් පරීක්ෂා කර ඇති අතර 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 අපේ හැම දෙයක්ම! ස්ට්‍රේස් ට්‍රේඩ් එකක් ටයිප් කර ඇතත්, එන්ටර් එබීමට වෙලාවක් නොතිබූ බැවින්, මම මගේ පැරණි මිතුරා වන හයිසන්බග් මහතා සහ සංවර්ධකයින් හඳුනා ගතිමි. සම්පාදක මම අවුරුදු 25 කට පෙර, නොස්ටැල්ජිය... ඒ වගේම මම දුක් වෙලා මේ සටහන ලියන්න තීරණය කළා 😉

මාර්ගය වන විට, ඕනෑම ආත්ම ගෞරවයක් මෙන් හයිසන්බග්, යටතේ strace ප්රතිනිෂ්පාදනය නොකිරීමට කැමැත්තක් දක්වයි.

ඉතින් මොකද වෙන්නේ?

  • උපයෝගීතාව head ඉල්ලන ලද පේළි ගණන කියවූ විගස කියවන නාලිකාව වසා දැමීමට අයිතියක් ඇත (හෝ ඒ වෙනුවට බල කෙරේ).
  • දත්ත උත්පාදනය කරන වැඩසටහන් ලේඛකයා (මෙම අවස්ථාවේදී cc) පුළුවන් බහු පේළි මුද්රණය සහ නිදහස් මෙය බහු ඇමතුම් හරහා කරන්න write().
  • නම් ලේඛකයාගේ පැත්තෙන් පටිගත කිරීම අවසන් වීමට පෙර පාඨකයාට ඔහුගේ පැත්තේ නාලිකාව වසා දැමීමට කාලය තිබේ, එවිට ලේඛකයාට දෝෂයක් ලැබෙනු ඇත.
  • ලේඛක වැඩසටහන අයිතියක් ඇත දෙකම නාලිකා ලිවීමේ දෝෂය නොසලකා හරින අතර එය ඔබගේ සම්පූර්ණ කිරීමේ කේතයෙන් පිළිබිඹු කරයි.
  • ස්ථාපනය හේතුවෙන් set -o pipefail ප්‍රති result ලය අවම වශයෙන් එක් මූලද්‍රව්‍යයකින් හෝ ශුන්‍ය නොවේ නම් නල මාර්ග සම්පූර්ණ කිරීමේ කේතය ශුන්‍ය නොවන (දෝෂ සහිත) වනු ඇත, එවිට එය ක්‍රියා කරයි || 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?"

නිවැරදිව:

  1. (fortune && echo "Успешно" || echo "Ошибка") | head -1

    මෙහිදී, කැදලි නල මාර්ගය ("වරහන් තුල") සේවා කිරීමේදී නලයක් ඉක්මනින් වසා දැමීම විධාන පරිවර්තකයා විසින් හසුරුවනු ලැබේ. ඒ අනුව, නම් fortune තත්ත්වය තුළ සංවෘත නාලිකාවකට ලිඛිතව දෝෂයක් වාර්තා කරනු ඇත, පසුව ප්රතිදානය || echo "Ошибка" නාලිකාව දැනටමත් වසා ඇති බැවින් එය කොතැනකවත් නොලැබේ.

  2. fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"

    මෙන්න උපයෝගීතාව cat දෝෂය නොසලකා හරින නිසා damper ලෙස ක්රියා කරයි EPIPE ආපසු ගැනීම මත. දැන් නිගමනය සඳහා මෙය ප්රමාණවත්ය fortune කුඩා (රේඛා කිහිපයක්) සහ නාලිකා බෆරයට ගැලපේ (බයිට් 512 සිට ≈64K දක්වා, බොහෝ OS ≥4K තුළ). එසේ නොමැතිනම් ගැටළුව නැවත පැමිණිය හැකිය.

නිවැරදිව සකසන ආකාරය EPIPE සහ වෙනත් පටිගත කිරීමේ දෝෂද?

තනි නිවැරදි විසඳුමක් නොමැත, නමුත් සරල නිර්දේශ තිබේ:

  • EPIPE අවශ්යයි සකස් කළ යුතුය (සහ පිටවීමේ තත්ත්වයෙන් පිළිබිඹු වේ) අඛණ්ඩතාව අවශ්‍ය දත්ත ප්‍රතිදානය කරන විට. උදාහරණයක් ලෙස, ලේඛනාගාර හෝ උපස්ථ උපයෝගිතා ක්රියාත්මක කිරීමේදී.
  • EPIPE නොසලකා හැරීම වඩා හොඳය තොරතුරු සහ සහායක පණිවිඩ පෙන්වන විට. උදාහරණයක් ලෙස, විකල්ප පිළිබඳ තොරතුරු පෙන්වන විට --help හෝ --version.
  • සංවර්ධනය කරන කේතය පෙර නල මාර්ගයක භාවිතා කළ හැකි නම් | headඑවිට EPIPE එය නොසලකා හැරීම වඩා හොඳය, එසේ නොමැතිනම් පිටවීමේ තත්ත්වය සැකසීමට සහ පරාවර්තනය කිරීමට වඩා හොඳය.

කණ්ඩායම්වලට මගේ කෘතඥතාව පළ කිරීමට මෙය අවස්ථාවක් කර ගනිමි MCST и altlinux විශිෂ්ට ඵලදායී කාර්යයක් සඳහා. ඔබේ අධිෂ්ඨානය පුදුම සහගතයි!
එය දිගටම කරගෙන යන්න සහෝදරවරුනි, ඉහළට වැටීම තුළ රැස්වීම්!

ස්තුතියි බෙරෙස් අකුරු වැරදි සහ දෝෂ නිවැරදි කිරීම සඳහා.
KDPV වෙතින් ජෝර්ජි ඒ.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න