لينڪس ۾ فائل بيان ڪندڙ مثالن سان

هڪ دفعي، هڪ انٽرويو دوران، مون کان پڇيو ويو ته، توهان ڇا ڪندا آهيو جيڪڏهن توهان ڪنهن خدمت کي ڪم نه ڪري رهيا آهيو ان حقيقت جي ڪري ته ڊسڪ جي جاء ختم ٿي وئي آهي؟

يقينن، مون جواب ڏنو ته مان ڏسان ٿو ته هن جڳهه تي ڇا قبضو ڪيو ويو آهي ۽، جيڪڏهن ٿي سگهي ٿو ته آئون ان جڳهه کي صاف ڪندس.
پوءِ انٽرويو وٺندڙ پڇيو ته، جيڪڏهن پارٽيشن تي خالي جاءِ ناهي، پر توهان کي ڪا به فائل نظر نه ٿي اچي جيڪا سڄي جاءِ وٺي وڃي؟

ان لاءِ مون چيو ته توهان هميشه کليل فائل ڊسڪرپٽرز کي ڏسي سگهو ٿا، مثال طور lsof ڪمانڊ سان، ۽ سمجهي سگهو ٿا ته ڪهڙي ايپليڪيشن سموري دستياب جاءِ ورتي آهي، ۽ پوءِ توهان حالتن مطابق عمل ڪري سگهو ٿا، ان تي منحصر آهي ته ڊيٽا جي ضرورت آهي يا نه. .

انٽرويو وٺندڙ مون کي آخري لفظ تي روڪيو، هن جي سوال ۾ شامل ڪيو: "فرض ڪريو اسان کي ڊيٽا جي ضرورت ناهي، اهو صرف هڪ ڊيبگ لاگ آهي، پر ايپليڪيشن ڪم نه ڪندي ڇو ته اهو ڊيبگ نٿو لکي سگهي"؟

"ٺيڪ آهي،" مون جواب ڏنو، "اسان ايپليڪيشن جي ترتيب ۾ ڊيبگ کي بند ڪري سگھون ٿا ۽ ان کي ٻيهر شروع ڪري سگهون ٿا."
انٽرويو وٺندڙ اعتراض ڪيو: "نه، اسان ايپليڪيشن کي ٻيهر شروع نٿا ڪري سگهون، اسان وٽ اڃا تائين اهم ڊيٽا ميموري ۾ محفوظ آهي، ۽ اهم ڪلائنٽ پاڻ سان ڳنڍيل آهن، جن کي اسان ٻيهر ٻيهر ڳنڍڻ تي مجبور نٿا ڪري سگهون."

”ٺيڪ آهي،“ مون چيو، ”جيڪڏهن اسان ايپليڪيشن کي ريسٽارٽ نٿا ڪري سگهون ۽ ڊيٽا اسان لاءِ اهم نه آهي، ته پوءِ اسان آسانيءَ سان هن کليل فائل کي فائيل ڊسڪرپٽر ذريعي صاف ڪري سگهون ٿا، جيتوڻيڪ اسان ان کي ls ڪمانڊ ۾ نه ٿا ڏسون. فائل سسٽم تي.

انٽرويو وٺندڙ خوش هو، پر مان نه هو.

پوءِ مون سوچيو، ڇو نه منهنجي علم کي پرکڻ وارو ماڻهو وڌيڪ اونهو ٿي وڃي؟ پر ڇا جيڪڏهن ڊيٽا سڀ کان اهم آهي؟ ڇا جيڪڏهن اسان هڪ پروسيس کي ٻيهر شروع نه ڪري سگهون ٿا، ۽ پروسيس هڪ ورهاڱي تي فائل سسٽم ڏانهن لکندو آهي جنهن ۾ خالي جاء ناهي؟ ڇا جيڪڏهن اسان نه رڳو اهو ڊيٽا وڃائي سگهون ٿا جيڪو اڳ ۾ لکيو ويو آهي، پر اهو پڻ ڊيٽا جيڪو اهو عمل لکي ٿو يا لکڻ جي ڪوشش ڪري ٿو؟

توزڪ

منهنجي ڪيريئر جي شروعات ۾، مون هڪ ننڍڙي ايپليڪيشن ٺاهڻ جي ڪوشش ڪئي جيڪا صارف جي معلومات کي ذخيرو ڪرڻ جي ضرورت هئي. ۽ پوءِ مون سوچيو، مان صارف کي سندس ڊيٽا سان ڪيئن ملائي سگهان ٿو. مثال طور، مون وٽ Ivanov Ivan Ivanovich آهي، ۽ هن وٽ ڪجهه معلومات آهي، پر آئون انهن سان دوستي ڪيئن ڪري سگهان ٿو؟ مان سڌو اشارو ڪري سگهان ٿو ته ڪتي جو نالو "Tuzik" هن ئي ايوان سان تعلق رکي ٿو. پر ڇا جيڪڏهن هو پنهنجو نالو تبديل ڪري ٿو ۽ ايوان جي بدران، مثال طور، اوليا؟ پوءِ اهو معلوم ٿيندو ته اسان جي اوليا ايوانونا ايوانووا وٽ هاڻي ڪتو نه هوندو ۽ اسان جو تزڪ اڃا به غير موجود ايوان سان تعلق رکندو. هڪ ڊيٽابيس جنهن هر صارف کي هڪ منفرد سڃاڻپ ڪندڙ (ID) ڏنو، هن مسئلي کي حل ڪرڻ ۾ مدد ڪئي، ۽ منهنجو Tuzik هن ID سان ڳنڍيل هو، جيڪو، حقيقت ۾، صرف هڪ سيريل نمبر هو. اهڙيءَ طرح، ايڪي جي مالڪ وٽ آئي ڊي نمبر 2 هو، ۽ ڪنهن وقت آئيون ان آئي ڊي هيٺ هو، ۽ پوءِ اوليا به ان ئي ID هيٺ ٿي ويو. انسانيت ۽ جانورن پالڻ جو مسئلو عملي طور تي حل ڪيو ويو.

فائل بيان ڪندڙ

فائل جو مسئلو ۽ پروگرام جيڪو هن فائل سان ڪم ڪري ٿو تقريبن اسان جي ڪتي ۽ انسان جي برابر آهي. فرض ڪريو مون ivan.txt نالي هڪ فائل کوليو ۽ ان ۾ لفظ tuzik لکڻ شروع ڪيو، پر فائل ۾ صرف پهريون اکر “t” لکڻ ۾ ڪامياب ٿيس، ۽ ان فائل جو نالو ڪنهن ماڻهو رکيو، مثال طور، olya.txt. پر فائل ساڳي رهي، ۽ مان اڃا تائين ان ۾ پنهنجو ايڪو رڪارڊ ڪرڻ چاهيان ٿو. هر وقت هڪ فائل کوليو ويندو آهي سسٽم ڪال ذريعي کليل ڪنهن به پروگرامنگ ٻولي ۾ مون کي هڪ منفرد ID ملي ٿي جيڪا مون کي هڪ فائل ڏانهن اشارو ڪري ٿي، هي ID فائل بيان ڪندڙ آهي. ۽ ان سان ڪو به فرق نه ٿو پوي ته هن فائل سان ڇا ۽ ڪير ڪري ٿو، ان کي ڊليٽ ڪري سگهجي ٿو، ان جو نالو تبديل ڪري سگهجي ٿو، مالڪ کي تبديل ڪري سگهجي ٿو، يا لکڻ پڙهڻ جا حق کسي سگهجن ٿا، تڏهن به مون وٽ رسائي هوندي. ان لاءِ، ڇاڪاڻ ته فائل کولڻ وقت، مون وٽ ان کي پڙهڻ ۽/يا لکڻ جا حق هئا ۽ مان ان سان ڪم شروع ڪرڻ ۾ ڪامياب ٿيس، جنهن جو مطلب آهي ته مون کي ائين ڪرڻ جاري رکڻ گهرجي.

لينڪس ۾، libc لائبريري هر هلندڙ ايپليڪيشن (پروسيس) لاءِ 3 بيان ڪندڙ فائلون کوليندي آهي، جنهن جو تعداد 0,1,2 آهي. وڌيڪ معلومات ڳولهي سگهجن ٿا لنڪس تي انسان اسٽيڊيو и مرد سڳورو

  • فائل بيان ڪندڙ 0 کي STDIN سڏيو ويندو آهي ۽ ايپليڪيشن ان پٽ سان لاڳاپيل آهي
  • فائل ڊسپيڪٽر 1 کي STDOUT سڏيو ويندو آهي ۽ ايپليڪيشنن پاران ڊيٽا کي ڪڍڻ لاءِ استعمال ڪيو ويندو آهي، جهڙوڪ پرنٽ ڪمانڊ
  • فائل بيان ڪندڙ 2 کي STDERR سڏيو ويندو آهي ۽ ايپليڪيشنن پاران استعمال ڪيو ويندو آهي آئوٽ پُٽ نقص پيغامن لاءِ.

جيڪڏهن توهان پنهنجي پروگرام ۾ پڙهڻ يا لکڻ لاءِ ڪا به فائل کوليندا آهيو ته گهڻو ڪري توهان کي پهرين مفت آئي ڊي ملندي ۽ ان جو نمبر 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 بيان ڪندڙ فائلون pseudo ٽرمينل ڊوائيس سان لاڳاپيل آھن /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 ٻارن جي پروسيس ۽ هڪ پائپ جي ضرورت هوندي.

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

پوءِ سسٽم ڪال استعمال ڪندي ڪلون 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 ۾ تبديل ڪري ٿي، اسان جي صورت ۾ اھو نمبر 9004 آھي. اھڙيءَ طرح، PID XNUMX سان پهريون ٻار عمل جيڪو STDOUT ڏانھن لکندو اھو سڀ ڪجھ پاڻمرادو پائپ بفر ۾ ختم ٿي ويندو.

PID 9005 سان سيڪنڊ چائلڊ پروسيس ۾، bash فائل ڊسڪرپٽر STDIN نمبر 2 کي تبديل ڪرڻ لاءِ dup0 استعمال ڪندو آهي. هاڻي PID 9005 سان اسان جي سيڪنڊ بيش جيڪا به پڙهي ويندي اها پائپ مان پڙهي ويندي.

ان کان پوء، فائل وضاحت ڪندڙ نمبر 3 ۽ 4 پڻ ٻارن جي عمل ۾ بند ٿي ويا آهن، ڇاڪاڻ ته اهي هاڻي استعمال نه ڪيا ويا آهن.

مان جان بوجھ ڪري نظر انداز ڪريان ٿو فائل ڊسڪرپٽر 255؛ اهو اندروني مقصدن لاءِ استعمال ڪيو ويندو آهي بش طرفان ۽ پڻ بند ڪيو ويندو ٻارن جي عملن ۾.

اڳيون، پهرين ٻار جي عمل ۾ PID 9004 سان، بش سسٽم ڪال استعمال ڪندي شروع ٿئي ٿو 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

جئين توهان ڏسي سگهو ٿا، اسان جي پائپ جو منفرد نمبر ٻنهي عملن ۾ ساڳيو آهي. اهڙيءَ طرح اسان وٽ هڪ ئي والدين سان ٻن مختلف عملن جي وچ ۾ تعلق آهي.

انهن لاءِ جيڪي سسٽم ڪالن کان واقف نه آهن جيڪي بش استعمال ڪن ٿا، آئون سفارش ڪريان ٿو حڪمن کي هلائڻ جي ذريعي اسٽريس ۽ ڏسو ته اندروني طور تي ڇا ٿي رهيو آهي، مثال طور هن وانگر:

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

انهي ڳالهه کي ذهن ۾ رکندي ته پٿون ڪهڙي سسٽم کي ڪال ڪري ٿو (مٿي ڏسو جتي اسان اسٽريس هليا ۽ اوپن ڪال ملي)، جڏهن فائل کولڻ لاءِ اسان جي ڪوڊ کي پروسيس ڪري رهيا آهيون، اسان پنهنجي عمل جي طرفان اهو ئي ڪندا آهيون، پر اسان کي ضرورت آهي O_WRONLY|O_CREAT| O_TRUNC بٽ عددي قدر سان بدلجي ٿو. هن کي ڪرڻ لاء، کوليو ڪني ذريعن، مثال طور هتي ۽ ڏسو ته ڪهڙا جھنڊا ذميوار آهن ڇا لاءِ

# define O_WRONLY 00000001
# وضاحت ڪريو O_CREAT 00000100
# define O_TRUNC 00001000

اسان سڀني قدرن کي گڏ ڪريون ٿا، اسان کي 00001101 ملي ٿو

اسان اسان جي ڪال کي جي ڊي بي کان هلائيندا آهيون

(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

اسان پائپ سان مثال ياد رکون ٿا - ڪيئن بش فائل ڊسڪٽر کي تبديل ڪري ٿو، ۽ اسان اڳ ۾ ئي سکيو آهي 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 ڪمانڊ سان نالي واري پائپ ٺاهي سگھون ٿا. اهو فائيل سسٽم تي هڪ pseudo فائل ٺاهيندو جيتوڻيڪ ان تي ڪابه خالي جاء ناهي.

ايپليڪيشن کي ٻيهر شروع ڪريو ۽ چيڪ ڪريو:

[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

ڊيٽا محفوظ ڪئي وئي آهي، مسئلو حل ڪيو ويو آهي.

مان هن موقعي تي پنهنجي ساٿين کي ڊيگيرو کان هيلو چوڻ جو موقعو وٺان ٿو.
ريڊيو ٽي پوڊ ڪاسٽ ٻڌو.

دعائون.

هوم ورڪ جي طور تي، مان توهان کي صلاح ڏيان ٿو ته ڇا ٿيندو پروسيس فائل ۾ ڇا ٿيندو بيان ڪندڙ cat and sleep جيڪڏهن توهان هيٺ ڏنل حڪم هلائيندا آهيو:

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

جو ذريعو: www.habr.com

تبصرو شامل ڪريو