$> 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"
අවංකවම, මම මගේ පැරණි "හඳුනන අය" වහාම හඳුනා ගත්තේ නැත. එපමනක් නොව, මෙම ව්යාපෘතිය දැනටමත් 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
මාර්ගය වන විට, ඕනෑම ආත්ම ගෞරවයක් මෙන් 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?"
නිවැරදිව:
-
(fortune && echo "Успешно" || echo "Ошибка") | head -1
මෙහිදී, කැදලි නල මාර්ගය ("වරහන් තුල") සේවා කිරීමේදී නලයක් ඉක්මනින් වසා දැමීම විධාන පරිවර්තකයා විසින් හසුරුවනු ලැබේ. ඒ අනුව, නම්
fortune
තත්ත්වය තුළ සංවෘත නාලිකාවකට ලිඛිතව දෝෂයක් වාර්තා කරනු ඇත, පසුව ප්රතිදානය|| echo "Ошибка"
නාලිකාව දැනටමත් වසා ඇති බැවින් එය කොතැනකවත් නොලැබේ. -
fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"
මෙන්න උපයෝගීතාව
cat
දෝෂය නොසලකා හරින නිසා damper ලෙස ක්රියා කරයිEPIPE
ආපසු ගැනීම මත. දැන් නිගමනය සඳහා මෙය ප්රමාණවත්යfortune
කුඩා (රේඛා කිහිපයක්) සහ නාලිකා බෆරයට ගැලපේ (බයිට් 512 සිට ≈64K දක්වා, බොහෝ OS ≥4K තුළ). එසේ නොමැතිනම් ගැටළුව නැවත පැමිණිය හැකිය.
නිවැරදිව සකසන ආකාරය EPIPE
සහ වෙනත් පටිගත කිරීමේ දෝෂද?
තනි නිවැරදි විසඳුමක් නොමැත, නමුත් සරල නිර්දේශ තිබේ:
EPIPE
අවශ්යයි සකස් කළ යුතුය (සහ පිටවීමේ තත්ත්වයෙන් පිළිබිඹු වේ) අඛණ්ඩතාව අවශ්ය දත්ත ප්රතිදානය කරන විට. උදාහරණයක් ලෙස, ලේඛනාගාර හෝ උපස්ථ උපයෝගිතා ක්රියාත්මක කිරීමේදී.EPIPE
නොසලකා හැරීම වඩා හොඳය තොරතුරු සහ සහායක පණිවිඩ පෙන්වන විට. උදාහරණයක් ලෙස, විකල්ප පිළිබඳ තොරතුරු පෙන්වන විට--help
හෝ--version
.- සංවර්ධනය කරන කේතය පෙර නල මාර්ගයක භාවිතා කළ හැකි නම්
| head
එවිටEPIPE
එය නොසලකා හැරීම වඩා හොඳය, එසේ නොමැතිනම් පිටවීමේ තත්ත්වය සැකසීමට සහ පරාවර්තනය කිරීමට වඩා හොඳය.
කණ්ඩායම්වලට මගේ කෘතඥතාව පළ කිරීමට මෙය අවස්ථාවක් කර ගනිමි
එය දිගටම කරගෙන යන්න සහෝදරවරුනි, ඉහළට
ස්තුතියි
KDPV වෙතින්
මූලාශ්රය: www.habr.com