मैं यह कैसे निर्धारित कर सकता हूं कि लिनक्स में किस प्रक्रिया की फाइल खुली है?


124

मैं यह निर्धारित करना चाहूंगा कि लॉक-फाइल का स्वामित्व किस प्रक्रिया का है। लॉक-फाइलें केवल एक विशिष्ट नाम वाली फ़ाइल है जिसे बनाया गया है।

तो, मैं यह कैसे निर्धारित कर सकता हूं कि लिनक्स में किसी विशेष फ़ाइल की क्या प्रक्रिया है? अधिमानतः एक-लाइनर प्रकार या एक विशेष लिनक्स उपकरण समाधान इष्टतम होगा।

जवाबों:


55

आप इसके लिए भी उपयोग कर सकते हैं 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

यह बहुत अच्छा था, लेकिन एक स्क्रिप्ट में इसका उपयोग करने के लिए मुझे आउटपुट लंबाई की जांच करनी थी।
chovy

आप आउटपुट लंबाई का क्या मतलब है?
नाथन फ़ेलमैन

if [ फ्यूज़र "$ फ़ाइल" `]; फिर बाहर
निकलें

1
fuser के पास बाहर निकलने के कोड के साथ अजीब व्यवहार है। यह दो राज्यों के साथ 1 एक्जॉस्टकोड लौटाता है: ए / कुछ आंतरिक त्रुटि, जाँच की गई फ़ाइल नहीं मिली आदि, बी / कोई प्रक्रिया निर्दिष्ट फ़ाइल नहीं खोली। स्थिति में ए / कुछ त्रुटि संदेश इसके आउटपुट पर मुद्रित होता है। दुर्भाग्य से जब फ़ाइल उपलब्ध होती है और किसी चीज द्वारा खोली जाती है, तो आउटपुट जेनरेट हो जाता है, लेकिन एग्जिट कोड के साथ 0. यह बेहतर होगा यदि फ्यूजर तीन कोड के साथ बाहर निकलेगा, वर्तमान में दो नहीं। lsoft थोड़ा खराब संकल्प है क्योंकि यह अधिक धीमी गति से काम कर रहा है।
ज़नीक

यह अनिवार्य रूप से एक ही पैटर्न है जो lsइस प्रकार है - यदि कोई त्रुटि (जैसे, अमान्य विकल्प निर्दिष्ट) या फ़ाइल नहीं मिली (और 0 यदि यह सफलतापूर्वक सूचना रिपोर्ट करता है) तो यह बाहर निकलें कोड 2 को लौटाता है ।
स्कॉट

144

अधिकांश लिनक्स सिस्टम 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:~$

4
और अगर आपके पास lsof नहीं है तो क्या होगा?
जोसेल्गेसुरा

3
@JoseLSegura: मुझे लगता है कि आप जवाब के लिए पर्याप्त संसाधन हैं 'तो lsof स्थापित करें' आपके लिए बेकार है। क्या आप अपनी समस्या के बारे में विस्तार से बता सकते हैं? यदि आपके पास रूट नहीं है, तो आपके पास यह पता लगाने के लिए निजी नहीं है कि किसी अन्य उपयोगकर्ता के पास किसी भी तरह से फ़ाइल खुली है या नहीं।
माइकल शेपर

यह फाइलों के लिए काम नहीं करता है, केवल dirs के लिए
जेसन

@ जेसन: यह फाइलों के लिए काम करता है, लेकिन cwdलाइनें (जो कि किसी प्रक्रिया की वर्तमान कार्यशील निर्देशिका के रूप में रिपोर्ट का उपयोग करती हैं) केवल रिपोर्ट निर्देशिकाओं की।
रीइन्टीरियरपोस्ट

9

फ़ाइल खुला होना एक लॉक नहीं है क्योंकि, यदि प्रत्येक प्रक्रिया को जाँचना है कि फ़ाइल पहले खुली है या नहीं और आगे बढ़ना है या नहीं तो इसे खोलें / यदि यह नहीं है, तो दो प्रक्रियाएँ एक साथ बहुत अच्छी तरह से जाँच कर सकती हैं, दोनों मिल जाती हैं यह खुला नहीं है, तो दोनों इसे बनाएँ या खोलें।

किसी फ़ाइल को लॉक के रूप में उपयोग करने के लिए, चेक-एंड-लॉक ऑपरेशन को एक एकल निर्बाध संचालन होना चाहिए। आप इसे रीड-ओनली मोड के साथ फाइल बनाकर अनलॉक करने के लिए इसे हटाकर यूनिक्स फाइल सिस्टम में प्राप्त कर सकते हैं। यदि फ़ाइल मौजूद है (और केवल पढ़ने के लिए है) तो फ़ाइल निर्माण विफल हो जाएगा, इसलिए आपको एकल परमाणु ऑपरेशन में चेक-एंड-लॉक मिलता है।

यदि आपकी लॉकिंग प्रक्रिया एक शेल स्क्रिप्ट है जो डेमॉन के रूप में चल रही है, तो आप इस प्रभाव का उपयोग करके प्राप्त कर सकते हैं umask, एक प्रति-प्रक्रिया सेटिंग जो उन अनुमतियों को सेट करती है, जिनके साथ नई फाइलें बनाई जाती हैं:

oldumask = $ (umask)
umask 222 # मालिक के लिए भी अनावश्यक फ़ाइलें बनाएँ
यदि इको $ $> / var / लॉक / फू
फिर
    : ताला लगाना सफल रहा
अन्य
    : ताला लगाना विफल रहा
फाई
umask $ ओल्डमस्क
यह फ़ाइल में स्वयं की प्रक्रिया '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$'


लिनक्स के लिए `ls -l 'विधि काम करती है लेकिन लगता है कि साइगविन के लिए काम नहीं कर रहा है: वहाँ फ़ाइल लॉकिंग के बारे में कोई जानकारी नहीं है। क्या आप नहीं जानते कि कैसे हल करें? धन्यवाद।
शोपाजो डे एरियेरेज़

नहीं, आप लॉक के लिए केवल-पढ़ने के लिए फ़ाइल नहीं बनाते हैं, क्योंकि जब आपका ऐप क्रैश होगा, तब भी फ़ाइल वहाँ रहेगी। अपने दुर्घटनाग्रस्त एप्लिकेशन के मानसिक होने के बाद उपयोगकर्ता को बकवास को हटाने के लिए मजबूर करना।
पोल्कोवनिकोव .ph

6

यदि आप यह जानना चाहते हैं कि आपकी फ़ाइल के बिना कौन सी सटीक प्रक्रिया फ़ाइल डिस्क्रिप्टर लिंक करती है - 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 <pid>

@Fin द्वारा उत्तर को श्रेष्ठ उत्तर, जाहिर है, लेकिन जवाब देने के लिए @ JoseLSegura की टिप्पणी , अगर यह उपलब्ध नहीं है, इसके बाद के संस्करण समाधान मेरी प्रतिक्रिया थी।$ lsof <filename>


2

मैंने पाया कि स्वीकृत उत्तर का उपयोग करके मेरी निर्देशिका (ubuntu 14.04) का उपयोग करने वाली प्रक्रियाओं को सूचीबद्ध नहीं किया गया था।

अंत में, मैंने lsof का उपयोग किया (सूची खुली फाइलें) और आपत्तिजनक प्रक्रिया को खोजने के लिए इसके आउटपुट को पकड़ लिया:

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

इसके उपयोग के लिए अधिक स्वच्छ और तेज़ तरीका lsofइसका विकल्प है -R। जैसे: lsof -R [filename]
tron5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.