د مثالونو سره په لینکس کې د فایل توضیح کونکی

یو ځل، د مرکې په جریان کې، له ما څخه وپوښتل شول، تاسو به څه وکړئ که تاسو داسې خدمت ومومئ چې کار نه کوي ځکه چې ډیسک د ځای څخه وتلی دی؟

البته، ما ځواب ورکړ چې زه به وګورم چې په دې ځای کې څه نیول شوي او که امکان ولري، زه به هغه ځای پاک کړم.
بیا مرکه کونکي وپوښتل، که چیرې په ویش کې خالي ځای شتون ونلري، مګر تاسو داسې فایلونه هم نه ګورئ چې ټول ځای ونیسي؟

دې ته ما وویل چې تاسو تل کولی شئ د خلاص فایل توضیح کونکي وګورئ ، د مثال په توګه د lsof کمانډ سره ، او پوه شئ چې کوم غوښتنلیک ټول موجود ځای نیولی ، او بیا تاسو کولی شئ د شرایطو سره سم عمل وکړئ ، پدې پورې اړه لري چې ډیټا ته اړتیا ده که نه. .

مرکه کوونکی زما په وروستۍ کلمه کې مداخله وکړه، د هغه پوښتنې ته یې اضافه کړه: "فرض کړئ چې موږ ډیټا ته اړتیا نلرو، دا یوازې د ډیبګ لاګ دی، مګر غوښتنلیک کار نه کوي ځکه چې دا ډیبګ نشي لیکلی"؟

"ښه،" ما ځواب ورکړ، "موږ کولی شو د غوښتنلیک په ترتیب کې ډیبګ بند کړو او بیا یې پیل کړو."
مرکه کونکي اعتراض وکړ: "نه، موږ نشو کولی اپلیکیشن بیا پیل کړو، موږ لاهم په حافظه کې مهم معلومات لرو، او مهم مراجعین پخپله د خدماتو سره تړلي دي، کوم چې موږ نشو کولی بیا بیا وصل کړو."

"ښه،" ما وویل، "که موږ اپلیکیشن بیا پیل نه کړو او ډاټا زموږ لپاره مهم نه وي، نو موږ کولی شو دا خلاص فایل د فایل ډیسکریټر له لارې پاک کړو، حتی که موږ دا په ls کمانډ کې ونه ګورو. د فایل سیسټم کې.

مرکه کوونکی خوښ و، خو زه نه وم.

بیا مې فکر وکړ، ولې هغه څوک چې زما پوهه نه ازمويي، ژوره نه کوي؟ مګر څه که چیرې معلومات له هرڅه وروسته مهم وي؟ څه شی که موږ نشو کولی یوه پروسه بیا پیل کړو، او پروسه د فایل سیسټم ته په یوه ویش کې لیکي چې هیڅ خالي ځای نلري؟ څه که موږ نشو کولی نه یوازې هغه معلومات له لاسه ورکړو چې دمخه لیکل شوي وي ، بلکه هغه معلومات هم له لاسه ورکړي چې دا پروسه یې لیکي یا د لیکلو هڅه کوي؟

توزیک

زما د مسلک په پیل کې، ما هڅه وکړه چې یو کوچنی غوښتنلیک جوړ کړم چې د کاروونکي معلوماتو ذخیره کولو ته اړتیا لري. او بیا ما فکر وکړ، څنګه کولی شم د کاروونکي د هغه ډاټا سره سمون ومومي. د مثال په توګه، زه ایوانوف ایوانووویچ لرم، او هغه یو څه معلومات لري، مګر زه څنګه کولی شم له دوی سره ملګري شم؟ زه کولی شم مستقیم په ګوته کړم چې د "توزیک" په نوم سپی د دې ایوان پورې اړه لري. مګر څه که هغه خپل نوم بدل کړي او د آیوان پرځای، د مثال په توګه، اولیا شي؟ بیا به دا معلومه شي چې زموږ اولیا ایوانوفنا ایوانوا به نور سپی ونه لري، او زموږ توزیک به لاهم د غیر موجود ایوان سره تړاو ولري. یو ډیټابیس چې هر کارونکي ته یې یو ځانګړی پیژندونکی (ID) ورکړی د دې ستونزې په حل کې مرسته کړې، او زما توزیک د دې ID سره تړلی و، کوم چې په حقیقت کې یوازې یو سریال نمبر و. په دې توګه، د اکس مالک د ID نمبر 2 درلود، او په ځینو وختونو کې ایوان د دې ID لاندې و، او بیا اولیا د ورته ID لاندې شو. د بشریت او د څارویو د پالنې ستونزه په عملي توګه حل شوه.

د فایل توضیح کوونکی

د فایل او برنامه ستونزه چې د دې فایل سره کار کوي نږدې زموږ د سپي او سړي په څیر دی. فرض کړئ چې ما د ivan.txt په نوم یوه فایل خلاص کړ او په هغې کې د tuzik کلمه لیکل پیل کړل، مګر یوازې په فایل کې لومړی توری "t" لیکلو توان درلود، او دا فایل د یو چا لخوا بدل شو، د بیلګې په توګه، olya.txt. مګر فایل ورته پاتې دی ، او زه لاهم غواړم خپل کوچني هلک په دې کې ثبت کړم. هرکله چې فایل د سیسټم کال لخوا خلاص شي دابرخه په هره پروګرامینګ ژبه کې زه یو ځانګړی ID ترلاسه کوم چې ما ته یوه فایل ته اشاره کوي، دا ID د فایل تشریح کونکی دی. او دا مهمه نده چې د دې فایل سره څه او څوک کوي ، دا حذف کیدی شي ، نوم یې بدل کیدی شي ، مالک یې بدل کیدی شي ، یا د لوستلو او لیکلو حقونه ترې اخیستل کیدی شي ، زه به لاهم لاسرسی وموم. د دې لپاره، ځکه چې د فایل پرانیستلو په وخت کې، ما د لوستلو او/یا لیکلو حق درلود او ما د دې سره کار پیل کړ، پدې معنی چې زه باید دې کار ته دوام ورکړم.

په لینکس کې، د libc کتابتون د هر چلونکي غوښتنلیک (پروسس) لپاره 3 تشریح کونکي فایلونه خلاصوي، شمیره یې 0,1,2 ده. نور معلومات په لینکونو کې موندل کیدی شي سړی stdio и ښه سړی

  • د فایل توضیح کوونکی 0 د STDIN په نوم یادیږي او د غوښتنلیک ان پټ سره تړاو لري
  • د فایل ډیسکریټر 1 د STDOUT په نوم یادیږي او د غوښتنلیکونو لخوا د ډیټا تولید لپاره کارول کیږي ، لکه د چاپ کمانډونه
  • د فایل ډیسکریپټر 2 د STDERR په نوم یادیږي او د غوښتنلیکونو لخوا د غلط پیغامونو تولید لپاره کارول کیږي.

که ستاسو په برنامه کې تاسو د لوستلو یا لیکلو لپاره کومه فایل خلاص کړئ ، نو ډیر احتمال به تاسو لومړی وړیا ID ترلاسه کړئ او دا به 3 شمیره وي.

د فایل تشریح کونکو لیست د هرې پروسې لپاره لیدل کیدی شي که تاسو د هغې PID پیژنئ.

د مثال په توګه، راځئ چې د باش کنسول خلاص کړو او زموږ د پروسې 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 تشریح کونکي فایلونه د سیډو ټرمینل وسیلې سره تړاو لري /dev/pts، مګر موږ لاهم کولی شو دوی سمبال کړو ، د مثال په توګه ، دوی په دوهم کنسول کې پرمخ وړئ

[user@localhost ]$ echo "hello world" > /proc/15771/fd/0

او په لومړي کنسول کې به موږ وګورو

[user@localhost ]$ hello world

ریډیټ او پایپ

تاسو کولی شئ دا 3 تشریح کونکي فایلونه په هره پروسه کې په اسانۍ سره وګرځوئ ، پشمول په باش کې ، د مثال په توګه د پایپ له لارې چې دوه پروسې سره وصل کوي ، وګورئ

[user@localhost ]$ cat /dev/zero | sleep 10000

تاسو کولی شئ دا کمانډ پخپله پرمخ بوځي strace -f او وګورئ چې دننه څه روان دي، مګر زه به تاسو ته په لنډ ډول ووایم.

د PID 15771 سره زموږ د پلار باش پروسه زموږ کمانډ پارس کوي او په ریښتیا پوهیږي چې موږ څومره کمانډونه چلول غواړو ، زموږ په قضیه کې دوه یې شتون لري: بلی او خوب. باش پوهیږي چې دا اړتیا لري د ماشومانو دوه پروسې رامینځته کړي ، او په یو پایپ کې یې یوځای کړي. په مجموع کې، باش به د 2 ماشومانو پروسې او یو پایپ ته اړتیا ولري.

باش د ماشوم پروسې رامینځته کولو دمخه د سیسټم کال چلوي پائپ او په لنډمهاله پایپ بفر کې د نوي فایل توضیح کونکي ترلاسه کوي ، مګر دا بفر لاهم زموږ دوه ماشوم پروسې سره نه نښلوي.

د والدین پروسې لپاره، داسې ښکاري چې لا دمخه یو پایپ شتون لري، مګر تر اوسه د ماشوم پروسې شتون نلري:

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

بیا د سیسټم کال په کارولو سره د ورايټۍ 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
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 سره د لومړي ماشوم باش پروسې کې ، سیسټم زنګ ووهئ dup2، زموږ د STDOUT فایل ډیسکریټر نمبر 1 د فایل ډیسکریټر نمبر ته بدلوي چې پایپ ته په ګوته کوي ، زموږ په قضیه کې دا نمبر 3 دی. پدې توګه ، هرڅه چې د PID 9004 سره د ماشوم لومړنۍ پروسه STDOUT ته لیکي به په اتوماتيک ډول پایپ بفر کې پای ته ورسیږي.

د PID 9005 سره د دویم ماشوم پروسې کې، bash د فایل ډیسکریټر STDIN شمیره 2 بدلولو لپاره dup0 کاروي. اوس هرڅه چې زموږ دوهم بش د PID 9005 سره لوستل کیږي د پایپ څخه لوستل کیږي.

له دې وروسته، د 3 او 4 شمیره د فایل تشریح کونکي هم د ماشوم پروسو کې تړل شوي، ځکه چې دوی نور نه کارول کیږي.

زه په قصدي توګه د فایل ډیسکریټر 255 له پامه غورځوم؛ دا پخپله د باش لخوا د داخلي موخو لپاره کارول کیږي او د ماشومانو پروسو کې به هم بند شي.

بیا، د PID 9004 سره په لومړي ماشوم پروسې کې، bash د سیسټم کال کارول پیل کوي Exec د اجرا وړ فایل چې موږ د کمانډ لاین کې مشخص کړی، زموږ په قضیه کې دا دی /usr/bin/cat.

د PID 9005 سره د دویم ماشوم پروسې کې، bash دویم اجرایوي چلوي چې موږ یې مشخص کړی، زموږ په قضیه کې /usr/bin/sleep.

د اجرایی سیسټم کال د فایل لاسوندونه نه بندوي پرته لدې چې دوی د O_CLOEXEC بیرغ سره د خلاص کال په وخت کې خلاص شوي نه وي. زموږ په قضیه کې، د اجرا وړ فایلونو په لاره اچولو وروسته، ټول اوسني فایل تشریح کونکي به خوندي شي.

په کنسول کې وګورئ:

[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 -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

لکه څنګه چې تاسو لیدلی شئ، د فایل اندازه یوازې وده کوي او زموږ ټرک کار نه کوي. راځئ چې د سیسټم کال اسناد وګورو دابرخه. که موږ د فایل خلاصولو پر مهال د O_APPEND بیرغ وکاروو، نو د هرې لیکلو سره، عملیاتي سیسټم د فایل اندازه ګوري او د فایل پای پای ته ډاټا لیکي، او دا په اټومي ډول ترسره کوي. دا ډیری تارونه یا پروسې ته اجازه ورکوي چې ورته فایل ته ولیکي. مګر زموږ په کوډ کې موږ دا بیرغ نه کاروو. موږ کولی شو د ټرک وروسته په lsof کې د مختلف فایل اندازه وګورو یوازې هغه وخت چې موږ د اضافي لیکلو لپاره فایل خلاص کړو ، پدې معنی چې زموږ په کوډ کې

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٪ اشغال شوی.

موږ په یاد لرو چې د دندې شرایطو سره سم، موږ هڅه کوو خورا مهم معلومات ثبت کړو چې له لاسه ورنکړل شي. او په ورته وخت کې، موږ اړتیا لرو چې د پروسې بیا پیل کولو پرته خدمت حل کړو.

راځئ چې ووایو موږ لاهم د ډیسک ځای لرو ، مګر په مختلف برخو کې ، د مثال په توګه / کور کې.

راځئ هڅه وکړو چې زموږ کوډ "په الوتنه کې بیا پروګرام" وکړو.

راځئ چې زموږ د پروسې 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

معلومات خوندي شوي، ستونزه حل شوې.

زه له دې فرصت څخه کار اخلم چې له دیګیرو څخه خپلو همکارانو ته سلام ووایم.
د راډیو - ټي پوډکاسټونه واورئ.

بریالیتوب مو غواړم.

د کور کار په توګه، زه وړاندیز کوم چې تاسو فکر وکړئ چې د پروسې فایل تشریح کونکي بلی او خوب کې به څه وي که تاسو لاندې کمانډ پرمخ وړئ:

[user@localhost ~]$ cat /dev/zero 2>/dev/null| sleep 10000

سرچینه: www.habr.com

Add a comment