වරක්, සම්මුඛ පරීක්ෂණයකදී, මගෙන් ඇසුවා, තැටියේ ඉඩ මදි බව නිසා සේවාවක් ක්රියා නොකරනු ඇත්නම් ඔබ කුමක් කරන්නේද?
ඇත්ත වශයෙන්ම, මම පිළිතුරු දුන්නේ මෙම ස්ථානය අල්ලාගෙන ඇත්තේ කුමක්දැයි මම බලා සිටින බවත්, හැකි නම්, මම එම ස්ථානය පිරිසිදු කරන බවත්ය.
එවිට සම්මුඛ පරීක්ෂකවරයා ඇසුවේ, කොටසේ නිදහස් ඉඩක් නොමැති නම්, නමුත් ඔබට සියලු ඉඩ ලබා ගන්නා ගොනු කිසිවක් නොපෙනේ නම් කුමක් කළ යුතුද?
මෙයට මම පැවසුවේ ඔබට සැමවිටම විවෘත ගොනු විස්තර කිරීම් දෙස බැලිය හැකි බවයි, උදාහරණයක් ලෙස lsof විධානය සමඟ, සහ පවතින සියලුම ඉඩ ලබාගෙන ඇත්තේ කුමන යෙදුමද යන්න තේරුම් ගත හැකි අතර, දත්ත අවශ්යද යන්න මත පදනම්ව ඔබට තත්වයන් අනුව ක්රියා කළ හැකි බව. .
සම්මුඛ පරීක්ෂකවරයා අවසාන වචනයෙන් මට බාධා කළේය, ඔහුගේ ප්රශ්නයට එක් කරමින්: "අපිට දත්ත අවශ්ය නැතැයි සිතන්න, එය නිදොස් කිරීමේ ලොගයක් පමණි, නමුත් යෙදුම නිදොස් කිරීමක් ලිවීමට නොහැකි නිසා ක්රියා නොකරයි"?
“හරි,” මම පිළිතුරු දුන්නා, “අපිට යෙදුම් වින්යාසය තුළ නිදොස්කරණය අක්රිය කර එය නැවත ආරම්භ කළ හැකිය.”
සම්මුඛ පරීක්ෂකවරයා විරුද්ධ විය: “නැහැ, අපට යෙදුම නැවත ආරම්භ කළ නොහැක, අපට තවමත් වැදගත් දත්ත මතකයේ ගබඩා කර ඇත, සහ වැදගත් සේවාදායකයින් සේවාවටම සම්බන්ධ වී ඇත, අපට නැවත සම්බන්ධ වීමට බල කළ නොහැක.”
“හරි,” මම කිව්වා, “අපට යෙදුම නැවත ආරම්භ කළ නොහැකි නම් සහ දත්ත අපට වැදගත් නොවේ නම්, අපට මෙම විවෘත ගොනුව ls විධානයේ නොපෙනුනත්, ගොනු විස්තරය හරහා සරලව ඉවත් කළ හැකිය. ගොනු පද්ධතිය මත."
සම්මුඛ පරීක්ෂකවරයා සතුටු වූ නමුත් මම එසේ නොකළෙමි.
එවිට මම සිතුවෙමි, මගේ දැනුම පරීක්ෂා කරන පුද්ගලයා ගැඹුරට නොයන්නේ ඇයි? නමුත් දත්ත සියල්ලටම වඩා වැදගත් නම් කුමක් කළ යුතුද? අපට ක්රියාවලියක් නැවත ආරම්භ කළ නොහැකි නම්, සහ ක්රියාවලිය නිදහස් ඉඩක් නොමැති කොටසක ගොනු පද්ධතියට ලියයි නම් කුමක් කළ යුතුද? දැනටමත් ලියා ඇති දත්ත පමණක් නොව, මෙම ක්රියාවලිය ලියන හෝ ලිවීමට උත්සාහ කරන දත්තද අපට නැති කර ගත නොහැකි නම් කුමක් කළ යුතුද?
ටුසික්
මගේ වෘත්තීය ජීවිතය ආරම්භයේදී, පරිශීලක තොරතුරු ගබඩා කිරීමට අවශ්ය කුඩා යෙදුමක් නිර්මාණය කිරීමට මම උත්සාහ කළෙමි. ඊට පස්සේ මම හිතුවා, මම කොහොමද පරිශීලකයාගේ දත්තවලට ගැලපෙන්නේ කියලා. නිදසුනක් වශයෙන්, මට Ivanov Ivan Ivanovich ඇත, ඔහුට යම් තොරතුරු තිබේ, නමුත් මම ඔවුන් සමඟ මිතුරු වන්නේ කෙසේද? "ටුසික්" නම් බල්ලා අයිති මේ අයිවන්ටම බව මට කෙලින්ම පෙන්වා දිය හැකිය. නමුත් ඔහු තම නම වෙනස් කර අයිවන් වෙනුවට ඔලියා බවට පත් වුවහොත් කුමක් කළ යුතුද? එවිට අපගේ ඔලියා ඉවානොව්නා ඉවානෝවාට තවදුරටත් බල්ලෙකු නොසිටින අතර අපගේ ටුසික් තවමත් නොපවතින අයිවන්ට අයත් වනු ඇත. සෑම පරිශීලකයෙකුටම අනන්ය හඳුනාගැනීමක් (ID) ලබා දුන් දත්ත සමුදායක් මෙම ගැටළුව විසඳීමට උපකාරී වූ අතර මගේ Tuzik මෙම හැඳුනුම්පතට සම්බන්ධ කර ඇත, එය සැබවින්ම අනුක්රමික අංකයක් විය. මේ අනුව, ටුසික්ගේ හිමිකරුට හැඳුනුම්පත් අංක 2 තිබූ අතර, යම් අවස්ථාවක දී අයිවන් මෙම හැඳුනුම්පත යටතේ සිටි අතර, පසුව ඔලියා මෙම හැඳුනුම්පත යටතේම විය. මනුෂ්යත්වය සහ සත්ව පාලනය පිළිබඳ ගැටලුව ප්රායෝගිකව විසඳා ඇත.
ගොනු විස්තරකය
මෙම ගොනුව සමඟ ක්රියා කරන ගොනුවේ සහ වැඩසටහනේ ගැටලුව අපේ බල්ලාගේ සහ මිනිසාගේ ප්රශ්නයට ආසන්න වශයෙන් සමාන වේ. මම ivan.txt නම් ගොනුවක් විවෘත කර එහි ටුසික් යන වචනය ලිවීමට පටන් ගත් නමුත් ගොනුවේ පළමු අකුර “t” ලිවීමට පමණක් සමත් වූ අතර, මෙම ගොනුව යමෙකු විසින් olya.txt ලෙස නම් කරන ලදී. නමුත් ගොනුව එලෙසම පවතින අතර, මට තවමත් මගේ ace එක එහි සටහන් කිරීමට අවශ්යයි. පද්ධති ඇමතුමකින් ගොනුවක් විවෘත කරන සෑම අවස්ථාවකම
Linux හි, libc පුස්තකාලය එක් එක් ධාවනය වන යෙදුම් (ක්රියාවලිය) සඳහා 3 අංක සහිත විස්තර ගොනු 0,1,2ක් විවෘත කරයි. වැඩි විස්තර සබැඳි වලින් සොයාගත හැකිය
- ගොනු විස්තරය 0 STDIN ලෙස හඳුන්වන අතර යෙදුම් ආදානය සමඟ සම්බන්ධ වේ
- ගොනු විස්තරය 1 STDOUT ලෙස හඳුන්වනු ලබන අතර මුද්රණ විධාන වැනි දත්ත ප්රතිදානය කිරීමට යෙදුම් විසින් භාවිතා කරයි.
- ගොනු විස්තරය 2 STDERR ලෙස හඳුන්වන අතර දෝෂ පණිවිඩ ප්රතිදානය කිරීමට යෙදුම් භාවිතා කරයි.
ඔබගේ වැඩසටහනේ ඔබ කියවීමට හෝ ලිවීමට කිසියම් ගොනුවක් විවෘත කරන්නේ නම්, බොහෝ විට ඔබට පළමු නොමිලේ හැඳුනුම්පත ලැබෙනු ඇති අතර එය අංක 3 වනු ඇත.
ඔබ එහි PID දන්නේ නම්, ගොනු විස්තර ලැයිස්තුව ඕනෑම ක්රියාවලියක් සඳහා බැලිය හැක.
උදාහරණයක් ලෙස, අපි bash කොන්සෝලය විවෘත කර අපගේ ක්රියාවලියේ PID බලමු
[user@localhost ]$ echo $$
15771
දෙවන කොන්සෝලයේ අපි ධාවනය කරමු
[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user 0 Oct 7 15:42 .
dr-xr-xr-x 9 user user 0 Oct 7 15:42 ..
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
මෙම ලිපියේ අරමුණු සඳහා ඔබට ගොනු විස්තර අංක 255 ආරක්ෂිතව නොසලකා හැරිය හැක; එය එහි අවශ්යතා සඳහා විවෘත කරන ලද්දේ බැෂ් විසින්ම මිස සම්බන්ධිත පුස්තකාලය මගින් නොවේ.
දැන් සියලුම විස්තර ගොනු 3 ව්යාජ පර්යන්ත උපාංගය සමඟ සම්බන්ධ වේ
[user@localhost ]$ echo "hello world" > /proc/15771/fd/0
සහ පළමු කොන්සෝලය තුළ අපි දකිනු ඇත
[user@localhost ]$ hello world
යළි-යොමුවීම් සහ පයිප්ප
bash ඇතුළුව ඕනෑම ක්රියාවලියකදී ඔබට මෙම විස්තර ගොනු 3 පහසුවෙන් අභිබවා යා හැක, උදාහරණයක් ලෙස ක්රියාවලි දෙකක් සම්බන්ධ කරන පයිප්පයක් හරහා, බලන්න
[user@localhost ]$ cat /dev/zero | sleep 10000
ඔබට මෙම විධානය ඔබම ක්රියාත්මක කළ හැකිය strace -f සහ ඇතුළත සිදුවන්නේ කුමක්දැයි බලන්න, නමුත් මම ඔබට කෙටියෙන් කියන්නම්.
PID 15771 සමඟින් අපගේ parent bash ක්රියාවලිය අපගේ විධානය විග්රහ කර අපට ක්රියාත්මක කිරීමට අවශ්ය විධාන ගණන හරියටම තේරුම් ගනී, අපගේ නඩුවේදී ඒවායින් දෙකක් තිබේ: cat සහ sleep. Bash එය ළමා ක්රියාවලි දෙකක් නිර්මාණය කිරීමට අවශ්ය බව දනී, සහ එක් නලයක් ඔවුන් ඒකාබද්ධ. සමස්තයක් වශයෙන්, bash ළමා ක්රියාවලීන් 2 ක් සහ එක් පයිප්පයක් අවශ්ය වනු ඇත.
Bash ළමා ක්රියාවලි නිර්මාණය කිරීමට පෙර පද්ධති ඇමතුමක් ක්රියාත්මක කරයි
මාපිය ක්රියාවලිය සඳහා, දැනටමත් නලයක් ඇති බව පෙනේ, නමුත් තවමත් ළමා ක්රියාවලි නොමැත:
PID command
15771 bash
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
ඉන්පසු පද්ධති ඇමතුම භාවිතා කරන්න
PID command
15771 bash
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
PID command
9004 bash
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 255 -> /dev/pts/21
PID command
9005 bash
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 255 -> /dev/pts/21
ක්ලෝන ක්රියාවලිය සියලුම ගොනු විස්තර සමඟ ක්ලෝන කරන බව අමතක නොකරන්න, එබැවින් ඒවා මාපිය ක්රියාවලියේදී සහ දරුවා තුළ සමාන වනු ඇත. PID 15771 සමඟ මාපිය ක්රියාවලියේ කාර්යය වන්නේ ළමා ක්රියාවලීන් නිරීක්ෂණය කිරීමයි, එබැවින් එය ළමයින්ගෙන් ප්රතිචාරයක් ලැබෙන තෙක් බලා සිටී.
එබැවින්, එය පයිප්ප අවශ්ය නොවන අතර, එය අංක 3 සහ 4 ගොනු විස්තර කිරීම් වසා දමයි.
PID 9004 සමඟ පළමු ළමා බෂ් ක්රියාවලියේදී, පද්ධතිය ඇමතුම
PID 9005 සමඟ දෙවන ළමා ක්රියාවලියේදී, bash විසින් STDIN අංකය 2 යන ගොනු විස්තරය වෙනස් කිරීමට dup0 භාවිතා කරයි. දැන් PID 9005 සමඟ අපගේ දෙවන bash කියවන සියල්ල පයිප්පයෙන් කියවනු ඇත.
මෙයින් පසු, අංක 3 සහ 4 ගොනු විස්තර කිරීම් තවදුරටත් භාවිතා නොකරන බැවින් ළමා ක්රියාවලීන්හි වසා ඇත.
මම හිතාමතාම ගොනු විස්තරය 255 නොසලකා හරිමි; එය බාෂ් විසින්ම අභ්යන්තර අරමුණු සඳහා භාවිතා කරන අතර ළමා ක්රියාවලීන් තුළද වසා දමනු ඇත.
ඊළඟට, PID 9004 සමඟ පළමු ළමා ක්රියාවලියේදී, bash පද්ධති ඇමතුමක් භාවිතා කිරීමට පටන් ගනී
PID 9005 සමඟ ඇති දෙවන ළමා ක්රියාවලියේදී, අපගේ නඩුවේ /usr/bin/sleep වලදී, bash විසින් අප සඳහන් කළ දෙවන ක්රියාත්මක කළ හැකි ක්රියාවලිය ධාවනය කරයි.
විවෘත ඇමතුම ලබා දුන් අවස්ථාවේ O_CLOEXEC ධජය සමඟ විවෘත කර ඇත්නම් මිස exec පද්ධති ඇමතුම ගොනු හසුරු වසා නොදමයි. අපගේ නඩුවේදී, ක්රියාත්මක කළ හැකි ගොනු දියත් කිරීමෙන් පසුව, සියලුම වත්මන් ගොනු විස්තරයන් සුරැකෙනු ඇත.
කොන්සෝලය තුළ පරීක්ෂා කරන්න:
[user@localhost ]$ pgrep -P 15771
9004
9005
[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user 0 Oct 7 15:42 .
dr-xr-xr-x 9 user user 0 Oct 7 15:42 ..
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
[user@localhost ]$ ls -lah /proc/9004/fd
total 0
dr-x------ 2 user user 0 Oct 7 15:57 .
dr-xr-xr-x 9 user user 0 Oct 7 15:57 ..
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
l-wx------ 1 user user 64 Oct 7 15:57 1 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lr-x------ 1 user user 64 Oct 7 15:57 3 -> /dev/zero
[user@localhost ]$ ls -lah /proc/9005/fd
total 0
dr-x------ 2 user user 0 Oct 7 15:57 .
dr-xr-xr-x 9 user user 0 Oct 7 15:57 ..
lr-x------ 1 user user 64 Oct 7 15:57 0 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
[user@localhost ]$ ps -up 9004
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 9004 0.0 0.0 107972 620 pts/21 S+ 15:57 0:00 cat /dev/zero
[user@localhost ]$ ps -up 9005
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 9005 0.0 0.0 107952 360 pts/21 S+ 15:57 0:00 sleep 10000
ඔබට පෙනෙන පරිදි, අපගේ පයිප්පයේ අද්විතීය අංකය ක්රියාවලීන් දෙකෙහිම සමාන වේ. මේ අනුව අපට එකම මාපියෙකු සමඟ විවිධ ක්රියාවලි දෙකක් අතර සම්බන්ධයක් ඇත.
bash භාවිතා කරන පද්ධති ඇමතුම් ගැන නොදන්නා අය සඳහා, විධාන strace හරහා ක්රියාත්මක කිරීම සහ අභ්යන්තරව සිදුවන දේ බැලීම මම තරයේ නිර්දේශ කරමි, උදාහරණයක් ලෙස මේ වගේ:
strace -s 1024 -f bash -c "ls | grep hello"
අඩු තැටි ඉඩ සහ ක්රියාවලිය නැවත ආරම්භ නොකර දත්ත සුරැකීමට උත්සාහ කිරීම සමඟ අපගේ ගැටලුව වෙත ආපසු යමු. තැටියට තත්පරයට මෙගාබයිට් 1ක් පමණ ලියන කුඩා වැඩසටහනක් ලියමු. එපමණක් නොව, කිසියම් හේතුවක් නිසා අපට තැටියට දත්ත ලිවීමට නොහැකි වූවා නම්, අපි මෙය නොසලකා හැර තත්පරයකින් දත්ත නැවත ලිවීමට උත්සාහ කරමු. මම Python භාවිතා කරන උදාහරණයේ, ඔබට වෙනත් ඕනෑම ක්රමලේඛන භාෂාවක් භාවිතා කළ හැකිය.
[user@localhost ]$ cat openforwrite.py
import datetime
import time
mystr="a"*1024*1024+"n"
with open("123.txt", "w") as f:
while True:
try:
f.write(str(datetime.datetime.now()))
f.write(mystr)
f.flush()
time.sleep(1)
except:
pass
අපි වැඩසටහන ක්රියාත්මක කර ගොනු විස්තර දෙස බලමු
[user@localhost ]$ python openforwrite.py &
[1] 3762
[user@localhost ]$ ps axuf | grep [o]penforwrite
user 3762 0.0 0.0 128600 5744 pts/22 S+ 16:28 0:00 | _ python openforwrite.py
[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user 0 Oct 7 16:29 .
dr-xr-xr-x 9 user user 0 Oct 7 16:29 ..
lrwx------ 1 user user 64 Oct 7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 7 16:29 3 -> /home/user/123.txt
ඔබට පෙනෙන පරිදි, අපගේ සම්මත ගොනු විස්තර 3 ක් සහ අප විසින් විවෘත කරන ලද තවත් එකක් ඇත. අපි ගොනු විශාලත්වය පරීක්ෂා කරමු:
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 user user 117M Oct 7 16:30 123.txt
දත්ත ලියා ඇත, අපි ගොනුවේ අවසර වෙනස් කිරීමට උත්සාහ කරමු:
[user@localhost ]$ sudo chown root: 123.txt
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 root root 168M Oct 7 16:31 123.txt
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 root root 172M Oct 7 16:31 123.txt
අපගේ පරිශීලකයාට ගොනුවට ලිවීමට අවසර නැතත්, දත්ත තවමත් ලියා ඇති බව අපට පෙනේ. අපි එය ඉවත් කිරීමට උත්සාහ කරමු:
[user@localhost ]$ sudo rm 123.txt
[user@localhost ]$ ls 123.txt
ls: cannot access 123.txt: No such file or directory
දත්ත ලියා ඇත්තේ කොහේද? සහ ඒවා කිසිසේත් ලියා තිබේද? අපි පරීක්ෂා කරමු:
[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user 0 Oct 7 16:29 .
dr-xr-xr-x 9 user user 0 Oct 7 16:29 ..
lrwx------ 1 user user 64 Oct 7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 7 16:29 3 -> /home/user/123.txt (deleted)
ඔව්, අපගේ ගොනු විස්තරය තවමත් පවතින අතර අපට මෙම ගොනු විස්තරය අපගේ පැරණි ගොනුව මෙන් සැලකිය හැකිය, අපට එය කියවීමට, ඉවත් කිරීමට සහ පිටපත් කිරීමට හැකිය.
ගොනු විශාලත්වය දෙස බලමු:
[user@localhost ]$ lsof | grep 123.txt
python 31083 user 3w REG 8,5 19923457 2621522 /home/user/123.txt
ගොනු විශාලත්වය 19923457. අපි ගොනුව හිස් කිරීමට උත්සාහ කරමු:
[user@localhost ]$ truncate -s 0 /proc/31083/fd/3
[user@localhost ]$ lsof | grep 123.txt
python 31083 user 3w REG 8,5 136318390 2621522 /home/user/123.txt
ඔබට පෙනෙන පරිදි, ගොනු ප්රමාණය වැඩි වන අතර අපගේ කඳට වැඩ නොකළේය. පද්ධති ඇමතුම් ලේඛන දෙස බලමු
with open("123.txt", "w") as f:
අපි දාන්න ඕනේ
with open("123.txt", "a") as f:
"w" ධජය සමඟ පරීක්ෂා කිරීම
[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
සහ "a" ධජය සමඟ
[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
ක්රමලේඛනය දැනටමත් ක්රියාත්මක වන ක්රියාවලියකි
බොහෝ විට ක්රමලේඛකයින්, වැඩසටහන් නිර්මාණය කිරීමේදී සහ පරීක්ෂා කිරීමේදී, දෝශ නිරාකරණ (උදාහරණයක් ලෙස GDB) හෝ යෙදුමේ විවිධ මට්ටම් ලොග් වීම භාවිතා කරයි. ලිනක්ස් මඟින් දැනටමත් ක්රියාත්මක වන වැඩසටහනක් ලිවීමට සහ වෙනස් කිරීමට හැකියාව ලබා දේ, උදාහරණයක් ලෙස, විචල්යවල අගයන් වෙනස් කිරීම, බිඳවැටීමක් සැකසීම යනාදිය.
ගොනුවක් ලිවීමට ප්රමාණවත් තැටි ඉඩක් නොමැති වීම පිළිබඳ මුල් ප්රශ්නය වෙත ආපසු යමින්, ගැටලුව අනුකරණය කිරීමට උත්සාහ කරමු.
අපි අපගේ කොටස සඳහා ගොනුවක් සාදන්නෙමු, එය අපි වෙනම තැටියක් ලෙස සවි කරමු:
[user@localhost ~]$ dd if=/dev/zero of=~/tempfile_for_article.dd bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00525929 s, 2.0 GB/s
[user@localhost ~]$
අපි ගොනු පද්ධතියක් නිර්මාණය කරමු:
[user@localhost ~]$ mkfs.ext4 ~/tempfile_for_article.dd
mke2fs 1.42.9 (28-Dec-2013)
/home/user/tempfile_for_article.dd is not a block special device.
Proceed anyway? (y,n) y
...
Writing superblocks and filesystem accounting information: done
[user@localhost ~]$
ගොනු පද්ධතිය සවි කරන්න:
[user@localhost ~]$ sudo mount ~/tempfile_for_article.dd /mnt/
[sudo] password for user:
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 172K 7.9M 3% /mnt
අපි අපගේ හිමිකරු සමඟ නාමාවලියක් සාදන්නෙමු:
[user@localhost ~]$ sudo mkdir /mnt/logs
[user@localhost ~]$ sudo chown user: /mnt/logs
අපගේ වැඩසටහනේ පමණක් ලිවීම සඳහා ගොනුව විවෘත කරමු:
with open("/mnt/logs/123.txt", "w") as f:
අපි දියත් කරනවා
[user@localhost ]$ python openforwrite.py
අපි තත්පර කිහිපයක් බලා සිටිමු
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 8.0M 0 100% /mnt
එබැවින්, මෙම ලිපියේ ආරම්භයේ විස්තර කර ඇති ගැටලුව අපට තිබේ. නිදහස් ඉඩ 0, 100% අල්ලාගෙන ඇත.
කර්තව්යයේ කොන්දේසි අනුව, අපි අහිමි කළ නොහැකි ඉතා වැදගත් දත්ත වාර්තා කිරීමට උත්සාහ කරන බව අපට මතකයි. ඒ අතරම, ක්රියාවලිය නැවත ආරම්භ නොකර සේවාව නිවැරදි කිරීමට අපට අවශ්ය වේ.
අපි හිතමු අපට තවමත් තැටි ඉඩ ඇති නමුත් වෙනත් කොටසක, උදාහරණයක් ලෙස /home හි.
අපගේ කේතය "පියාසරයේදී නැවත වැඩසටහන්" කිරීමට උත්සාහ කරමු.
අපගේ ක්රියාවලියේ PID දෙස බලමු, එය සියලුම තැටි අවකාශය කා දමා ඇත:
[user@localhost ~]$ ps axuf | grep [o]penfor
user 10078 27.2 0.0 128600 5744 pts/22 R+ 11:06 0:02 | _ python openforwrite.py
gdb හරහා ක්රියාවලියට සම්බන්ධ වන්න
[user@localhost ~]$ gdb -p 10078
...
(gdb)
විවෘත ගොනු විස්තර කරන්නන් දෙස බලමු:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /mnt/logs/123.txt
අපට උනන්දුවක් දක්වන ගොනු විස්තර අංක 3 පිළිබඳ තොරතුරු අපි බලමු
(gdb) shell cat /proc/10078/fdinfo/3
pos: 8189952
flags: 0100001
mnt_id: 482
Python කුමන පද්ධති ඇමතුමක් ලබා දෙන්නේද යන්න මතක තබා ගනිමින් (ඉහත බලන්න, අපි ස්ට්රේස් ධාවනය කර විවෘත ඇමතුම සොයාගත් ස්ථානය බලන්න), ගොනුවක් විවෘත කිරීමට අපගේ කේතය සැකසීමේදී, අපගේ ක්රියාවලිය වෙනුවෙන් අපි එයම කරමු, නමුත් අපට O_WRONLY|O_CREAT| O_TRUNC බිටු සංඛ්යාත්මක අගයකින් ප්රතිස්ථාපනය වේ. මෙය සිදු කිරීම සඳහා, උදාහරණයක් ලෙස, කර්නල් මූලාශ්ර විවෘත කරන්න
#O_WRONLY 00000001 නිර්වචනය කරන්න
#O_CREAT 00000100 අර්ථ දක්වන්න
#O_TRUNC 00001000 නිර්වචනය කරන්න
අපි සියලු අගයන් එකකට ඒකාබද්ධ කරමු, අපට 00001101 ලැබේ
අපි අපගේ ඇමතුම gdb වෙතින් ධාවනය කරමු
(gdb) call open("/home/user/123.txt", 00001101,0666)
$1 = 4
එබැවින් අපට අංක 4 සහිත නව ගොනු විස්තරයක් සහ වෙනත් කොටසක නව විවෘත ගොනුවක් ලැබුණි, අපි පරීක්ෂා කරමු:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct 8 11:15 4 -> /home/user/123.txt
පයිප්ප සමඟ උදාහරණය අපට මතකයි - bash ගොනු විස්තර වෙනස් කරන්නේ කෙසේද, සහ අපි දැනටමත් dup2 පද්ධති ඇමතුම ඉගෙන ගෙන ඇත.
අපි එක් ගොනු විස්තරයක් තවත් එකක් සමඟ ප්රතිස්ථාපනය කිරීමට උත්සාහ කරමු
(gdb) call dup2(4,3)
$2 = 3
අපි පරීක්ෂා කරමු:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /home/user/123.txt
l-wx------ 1 user user 64 Oct 8 11:15 4 -> /home/user/123.txt
අපට එය අවශ්ය නොවන බැවින් අපි ගොනු විස්තරය 4 වසා දමමු:
(gdb) call close (4)
$1 = 0
සහ gdb පිටවන්න
(gdb) quit
A debugging session is active.
Inferior 1 [process 10078] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 10078
නව ගොනුව පරීක්ෂා කිරීම:
[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 5.1M Oct 8 11:18 /home/user/123.txt
[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 7.1M Oct 8 11:18 /home/user/123.txt
ඔබට පෙනෙන පරිදි, දත්ත නව ගොනුවකට ලියා ඇත, අපි පැරණි එක පරීක්ෂා කරමු:
[user@localhost ~]$ ls -lah /mnt/logs/123.txt
-rw-rw-r-- 1 user user 7.9M Oct 8 11:08 /mnt/logs/123.txt
දත්ත නැති වී නැත, යෙදුම ක්රියා කරයි, ලොග් නව ස්ථානයකට ලියා ඇත.
අපි කාර්යය ටිකක් සංකීර්ණ කරමු
දත්ත අපට වැදගත් යැයි සිතමු, නමුත් අපට කිසිදු කොටසක තැටි ඉඩක් නොමැති අතර අපට තැටිය සම්බන්ධ කළ නොහැක.
අපට කළ හැක්කේ අපගේ දත්ත කොතැනකට හෝ හරවා යැවීමයි, උදාහරණයක් ලෙස පයිප්පයට, සහ අනෙක් අතට, පයිප්පයේ සිට ජාලයට දත්ත යම් වැඩසටහනක් හරහා හරවා යැවීමයි, උදාහරණයක් ලෙස netcat.
අපට mkfifo විධානය සමඟ නම් කරන ලද පයිප්පයක් සෑදිය හැකිය. එය ගොනු පද්ධතියේ නිදහස් ඉඩක් නොමැති වුවද එය ව්යාජ ගොනුවක් සාදනු ඇත.
යෙදුම නැවත ආරම්භ කර පරීක්ෂා කරන්න:
[user@localhost ]$ python openforwrite.py
[user@localhost ~]$ ps axuf | grep [o]pen
user 5946 72.9 0.0 128600 5744 pts/22 R+ 11:27 0:20 | _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 8.0M 0 100% /mnt
තැටි ඉඩක් නොමැත, නමුත් අපි එහි නම් කරන ලද පයිප්පයක් සාර්ථකව නිර්මාණය කරමු:
[user@localhost ~]$ mkfifo /mnt/logs/megapipe
[user@localhost ~]$ ls -lah /mnt/logs/megapipe
prw-rw-r-- 1 user user 0 Oct 8 11:28 /mnt/logs/megapipe
දැන් අපි කෙසේ හෝ මෙම පයිප්පයට ඇතුළු වන සියලුම දත්ත ජාලය හරහා වෙනත් සේවාදායකයකට ඔතා ගත යුතුය; මේ සඳහා එකම netcat සුදුසු වේ.
remote-server.example.com සේවාදායකයේ අපි ධාවනය කරමු
[user@localhost ~]$ nc -l 7777 > 123.txt
අපගේ ගැටළු සහගත සේවාදායකයේ අපි වෙනම පර්යන්තයක දියත් කරමු
[user@localhost ~]$ nc remote-server.example.com 7777 < /mnt/logs/megapipe
දැන් පයිප්පයේ අවසන් වන සියලුම දත්ත ස්වයංක්රීයව netcat හි stdin වෙත යයි, එය එය 7777 වරායේ ජාලයට යවනු ඇත.
අප කළ යුත්තේ මෙම නම් කරන ලද පයිප්පයට අපගේ දත්ත ලිවීම ආරම්භ කිරීමයි.
අපි දැනටමත් යෙදුම ධාවනය කර ඇත:
[user@localhost ~]$ ps axuf | grep [o]pen
user 5946 99.8 0.0 128600 5744 pts/22 R+ 11:27 169:27 | _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
සියලුම කොඩි අතුරින්, ගොනුව දැනටමත් පවතින බැවින් සහ අපට එය හිස් කිරීමට අවශ්ය නොවන බැවින් අපට අවශ්ය වන්නේ O_WRONLY පමණි
[user@localhost ~]$ gdb -p 5946
...
(gdb) call open("/mnt/logs/megapipe", 00000001,0666)
$1 = 4
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct 8 14:20 4 -> /mnt/logs/megapipe
(gdb) call dup2(4,3)
$2 = 3
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/megapipe
l-wx------ 1 user user 64 Oct 8 14:20 4 -> /mnt/logs/megapipe
(gdb) call close(4)
$3 = 0
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/megapipe
(gdb) quit
A debugging session is active.
Inferior 1 [process 5946] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 5946
දුරස්ථ සේවාදායකය remote-server.example.com පරීක්ෂා කිරීම
[user@localhost ~]$ ls -lah 123.txt
-rw-rw-r-- 1 user user 38M Oct 8 14:21 123.txt
දත්ත එනවා, අපි ගැටළු සේවාදායකය පරීක්ෂා කරන්නෙමු
[user@localhost ~]$ ls -lah /mnt/logs/
total 7.9M
drwxr-xr-x 2 user user 1.0K Oct 8 11:28 .
drwxr-xr-x 4 root root 1.0K Oct 8 10:55 ..
-rw-rw-r-- 1 user user 7.9M Oct 8 14:17 123.txt
prw-rw-r-- 1 user user 0 Oct 8 14:22 megapipe
දත්ත සුරකිනු ඇත, ගැටළුව විසඳනු ලැබේ.
මම Degiro සිට මගේ සගයන්ට ආයුබෝවන් කියන්න මෙය අවස්ථාවක් කර ගනිමි.
රේඩියෝ-ටී පොඩ්කාස්ට් වලට සවන් දෙන්න.
සියල්ලම සාර්ථක වෙන්න කියා ප්රාර්ථනා කරනවා.
ගෙදර වැඩ ලෙස, ඔබ පහත විධානය ක්රියාත්මක කරන්නේ නම්, cat and sleep විස්තර කරන ක්රියාවලි ගොනුවේ ඇති දේ ගැන සිතා බැලීමට මම ඔබට යෝජනා කරමි:
[user@localhost ~]$ cat /dev/zero 2>/dev/null| sleep 10000
මූලාශ්රය: www.habr.com