ايران ويج

نسخه‌ی کامل: بستن فال هندل پروسه‌ در لینوکس
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
گاهی اوفات پیش میاد که یه برنامه یه فایلی رو باز کرده؛ و ما احتیاج داری اون فایل رو ببنیدم
راه ساده اینه که کل برنامه رو ببنیدیم (kill کنیم)؛

ولی هنگامی که نمیخواییم به پروسه دست بزنیم؛ راه حل چیه؟

راه حل اینه که به پروسه مورد نظرمون اتچ بشیم و سپس با استفاده از شماره فایل هندل اقدام به بستن اون کنیم؛

با یه مثال توضیح میدم

اسکریپت زیر (به زبان پرل) رو با نام p.pl ذخیره میکنیم
کد php:
#!/usr/bin/perl
open (KK,">file");
<
STDIN>;
print 
KK "TEST\n";
close(KK); 

و با دستور زیر اجراش میکنیم
کد php:
perl p.pl 


این اسکریپت اول به فایلی رو بنام file برای نوشتن باز میکنه؛ و میمونه کاربر یه اینتر بزنه؛ پ بعدش کلمه‌ی TEST رو توی فایل مینویسه!

هدف اینه که وقتی بنرامه منتظر ورودی کاربر هست (که اینتر بزنه) ما این فایل هندل رو ببندیم؛


برای اینکار از دستور lsof استفاده میکنیم؛ این برنامه لبست تمام فایلهایی که باز هستن رو لیست میکنه؛ با استفاده از پارامتر c میتونیم تعیین کنیم فقط باز شده توسط یه پروسه‌ی خاص رو نشون بده..

پس دستور زیر رو میزنیم:
کد php:
lsof -c perl 


خروجی ای شبیه زیر به ما نشون میده:
کد php:
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
perl    5705  ali  cwd    DIR    8
,1     4096 1970504 /tmp/ii
perl    5705  ali  rtd    DIR    8
,1     4096       2 /
perl    5705  ali  txt    REG    8,1  1462760 2224069 /usr/bin/perl
perl    5705  ali  mem    REG    8
,1  4447600 2231771 /usr/lib/locale/locale-archive
perl    5705  ali  mem    REG    8
,1    34316  530920 /lib/i386-linux-gnu/libcrypt-2.15.so
perl    5705  ali  mem    REG    8
,1  1730024  530919 /lib/i386-linux-gnu/libc-2.15.so
perl    5705  ali  mem    REG    8
,1   124663  530928 /lib/i386-linux-gnu/libpthread-2.15.so
perl    5705  ali  mem    REG    8
,1   173576  530930 /lib/i386-linux-gnu/libm-2.15.so
perl    5705  ali  mem    REG    8
,1    13940  530934 /lib/i386-linux-gnu/libdl-2.15.so
perl    5705  ali  mem    REG    8
,1   134344  530931 /lib/i386-linux-gnu/ld-2.15.so
perl    5705  ali    0u   CHR  136
,0      0t0       3 /dev/pts/0
perl    5705  ali    1u   CHR  136
,0      0t0       3 /dev/pts/0
perl    5705  ali    2u   CHR  136
,0      0t0       3 /dev/pts/0
perl    5705  ali    3w   REG    8
,1        0 1965991 /tmp/ii/file
perl    5705  ali    8r   REG    0
,3        0 1682256 /proc/5191/auxv 

در خط یکی مونده به آخر ؛ یعنی این خط:
کد php:
perl    5705  ali    3w   REG    8,1        0 1965991 /tmp/ii/file 

میبینیم اسم فایلمون رو نوشته! (برنامه رو در مسیر /tmp/ii اجرا کرده بودم و نام فایلی هم که قرار بود باز بشه file بود)
کد php:
/tmp/ii/file 

و همچنین در قسمت fd نوشته شده 3w ؛
3w یعنی نام شماه هندل فایل ۳ هست و برای نوشتن (w) باز شده!

علاوه بر اینها به شماره پروسه هم نیاز داریم که در خط بالا معلومه؛ نوشته شده 5705


توسط gdb به این پروسه وصل میشیم؛ و از این فایل هندل رو میبندیم! انگار که خود برنامه اینکارو کرده!

کد php:
sudo gdb -p 5705 

بعد از اینکه اعلان خط فرمان gdb ظاهر شد:
کد php:
(gdb

فرمان بستن فایل هندل ۳ رو میدیم:

کد php:
(gdbcall close(3)
$


با استفاده از

کد php:
call close(3

فرمان بسته شدن رو دادیم؛ و نتیجه این اجرا صفر بود که یعنی فرمان با موفقیت اجرا شده

و بعد دستور quit رو میزنیم و y رو انتخاب میکنیم؛ با اینکار دیگه به برنامه اتچ نیستیم

دوباره دستور بالارو اجرا میکنیم
کد php:
lsof -c perl 

میتونیم مشاهده کنیم که هیچ اثری از شماره فایل 3 و فایل file نیست!!!

میریم سراغ برنامه‌ی پرل که منتظر ورودی ما هست؛ اینتر میزنیم و برنامه به پایان میرسه
محتویات فایل file رو با دستور زیر میبینیم:
کد php:
cat file 

همونطور که انتظار داشتیم چیزی نشوته نشده!!!


دوباره برنامه رو اجرا میکنیم:
کد php:
perl p.pl 
و اینتر میزنیم؛ و محتویات فایل file میبینیم؛ اینبار عبارت TEST داخل فایل نوشته شده ...


باید دو نکته رو توجه داشت:
۱ - وقتی به برنامه‌ای اتچ میشیم؛ برنماه از روال عادی خارج میشه و به حالت خوابیده میره تا وقتی دستور ادامه‌ی کار رو به برنامه بدیم

۲ - همه چیز در لینوکس فایل هست! یعنی شما میتونید با این روس سوکت ها رو هم ببنید! چون از دیدی لینوکس سوکت هم فایله! میتونید به فایرفاکس اتچ بشید و سوکت‌های مورد نظر رو ببنید ...


منبع: خودم Biggrin