سؤال كيف يمكنني تحديد العملية التي بها ملف مفتوح في Linux؟


أود تحديد العملية التي لها ملكية ملف قفل. ملفات القفل هي ببساطة ملف ذو اسم محدد تم إنشاؤه.

لذا ، كيف يمكنني تحديد العملية التي تحتوي على ملف معين مفتوح في Linux؟ يفضل أن يكون النوع أحادي الخطوط أو حل أداة Linux معين هو الأمثل.


112
2018-01-19 16:08


الأصل




الأجوبة:


تستطيع ايضا استخذام fuser لهذا:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc:              28135
~> ps 28135
  PID TTY      STAT   TIME COMMAND
28135 pts/36   T      0:00 less .vimrc

49
2018-01-19 17:37



كان هذا رائعا ، ولكن لاستخدامه في البرنامج النصي اضطررت للتحقق من طول الانتاج. - chovy
ماذا تقصد طول الانتاج؟ - Nathan Fellman
if [ fuser "$ file" `]؛ ثم الخروج - chovy
الصهر لديه سلوك غريب مع رموز الخروج. تقوم بإرجاع 1 exitcode مع حالتين: A / بعض خطأ داخلي ، ملف لم يتم العثور على الخ ، ب / لا عملية فتح الملف المحدد. في حالة A / يتم طباعة بعض رسائل الخطأ إلى الإخراج الخاص به. للأسف عندما يكون الملف متاحًا ويفتح بشيء ما ، يتم إنشاء المخرجات ولكن برمز الخروج 0. سيكون من الأفضل أن تخرج وحدة المصهر مع ثلاثة رموز ، وليست اثنتين كما هو الحال حاليًا. lsoft هو حل أسوأ قليلاً لأن هذا يعمل ببطء أكبر. - Znik
هذا هو في الأساس نفس النمط الذي ls يتبع - يعرض رمز الإنهاء 2 إذا كان هناك خطأ (على سبيل المثال ، تم تحديد خيار غير صالح) أو لم يتم العثور على الملف (و 0 إذا كان التقرير ناجحًا). - Scott


على معظم أنظمة Linux lsof NAME لا وظيفة:

fin@r2d2:~$ lsof /home/fin
COMMAND   PID USER   FD   TYPE DEVICE SIZE    NODE NAME
bash    21310  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21320  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21321  fin  cwd    DIR    8,1 4096 5054467 /home/fin
fin@r2d2:~$

134
2018-01-19 16:18



وماذا لو لم يكن لديك lsof؟ - JoseLSegura
JoseLSegura: أفترض أنك خبير بالقدر الكافي للإجابة 'ثم ثبت lsof' لتكون غير مجدية بالنسبة لك. هل يمكنك توضيح مشكلتك؟ إذا لم يكن لديك جذر ، فمن المحتمل ألا يكون لديك معلومات لمعرفة ما إذا كان هناك مستخدم آخر لديه ملف مفتوح على أية حال. - Michael Scheper


إن فتح الملف ليس قفلًا ، لأنه إذا كان على كل عملية أن تتحقق مما إذا كان الملف مفتوحًا أولاً وألا يستمر إذا كان موجودًا أو ينشئ / يفتحه إذا لم يكن كذلك ، فمن الممكن أن تحقق عمليتان جيدًا في وقت واحد ، أنه ليس مفتوحًا ، ثم ينشئه أو يفتحه.

لاستخدام ملف كقفل ، يجب أن تكون عملية الفحص والاختبار عملية واحدة غير متقطعة. يمكنك تحقيق ذلك في نظام ملفات Unix عن طريق إنشاء ملف مع وضع القراءة فقط وإزالته لفتحه. إذا كان الملف موجودًا (وقراءة فقط) ، فسوف تفشل عملية إنشاء الملف ، بحيث تحصل على فحص وتسجيل في عملية ذرية واحدة.

إذا كانت عملية القفل عبارة عن نص برمجي شيل يعمل كخادم ، يمكنك الحصول على هذا التأثير باستخدامه umask، إعداد لكل عملية يقوم بتعيين الأذونات التي يتم إنشاء الملفات الجديدة بها:

oldumask = $ (umask)
umask 222 # إنشاء ملفات غير صالح للمالك أيضا
إذا كان echo $$> / var / lock / foo
ثم
    : قفل نجح
آخر
    : قفل فشل
فاي
umask $ oldumask
هذا يكتب أيضا عملية التملك 'PID في الملف ، والذي يحل مشكلتك الأخرى: cat /var/lock/foo
فيما يتعلق بالسؤال المحدد "أي عمليات فتح هذا الملف؟" ، يمكن أن يكون هذا مفيدًا عندما تريد إلغاء تحميل نظام ملفات ولكن لا يمكن ذلك نظرًا لأن بعض العمليات بها ملف مفتوح فيه. إذا لم يكن لديك هذه الأوامر المتاحة ، يمكنك أن تسأل /proc كجذر:

ls -l /proc/*/cwd | grep '/var/lock/foo$'

أو كمستخدم مميت:

ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'


8
2018-01-20 13:14



تعمل طريقة 'ls -l' لنظام التشغيل Linux ولكن يبدو أنها لا تعمل مع CygWin: لا توجد معلومات حول تأمين الملفات هناك. ألن تعرف كيف تحل؟ شكر. - Sopalajo de Arrierez
لا ، لا تنشئ ملفًا للقراءة فقط لقفل ، لأنه في حالة تعطل تطبيقك ، سيظل الملف موجودًا. إجبار المستخدم على إزالة حماقة بعد التطبيق المعطوب الخاص بك هو عقلي. - polkovnikov.ph


إذا كنت تريد معرفة أي واصف ملف العملية بالضبط يرتبط بملفك بدون lsof أو fuser - البحث من خلال /proc:

$ find /proc -regex '\/proc\/[0-9]+\/fd\/.*' -type l -lname "*$1*" -printf "%p -> %l\n" 2> /dev/null

يحل محل $1 مع اسم الملف المفتوح الذي تبحث عنه. يمكنك تعديل -printf لكل ما تريد رؤيته ، أو الانبوب egrep -o '[0-9]+' | head -1 للاستعمال مع ps -Fp <معرف المنتج> للحصول على معلومات هذه العملية.

ال $ lsof <اسم الملف> الإجابة عن طريقfin هي أفضل إجابة ، بالطبع ، ولكن الإجابة @ تعليق JoseLSeguraإذا لم يكن هذا متاحًا ، فإن الحل أعلاه كان ردي.


4
2017-11-15 21:41





لقد وجدت أن استخدام الإجابة المقبولة لم يسرد العمليات التي كانت تستخدم دليلي (ubuntu 14.04).

في النهاية ، استخدمت lsof (قائمة الملفات المفتوحة) وحصلت على إنتاجها للعثور على العملية المسيئة:

lsof | egrep "<regexp-for-your-file>"

2
2017-10-30 14:21