मैं `टेल-एफ / प्रॉप / $ पीआईडी ​​/ एफडी / 1` क्यों नहीं कर सकता?


10

मैंने एक साधारण स्क्रिप्ट लिखी है, जो echoअपने पीआईडी:

#/bin/bash

while true; do
    echo $$;
    sleep 0.5;
done

मैं 3844एक टर्मिनल में स्क्रिप्ट (यह कहता है कि अधिक से अधिक) चला रहा हूं tailऔर एक दूसरे में फाइल डिस्क्रिप्टर की कोशिश कर रहा हूं :

$ tail -f /proc/3844/fd/1

यह स्क्रीन के लिए कुछ भी प्रिंट नहीं करता है और तब तक लटका रहता है ^c। क्यों?

इसके अलावा, सभी एसटीडी फ़ाइल डिस्क्रिप्टर (IN / OUT / ERR) एक ही pts से लिंक करते हैं:

$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14

क्या यह सामान्य है?

उबंटू GNOME 14.04 रनिंग।

अगर आपको लगता है कि यह सवाल UL के बजाय SO या SU का है, तो बताएं।


जवाबों:


13

एक बनाने straceके tail -fलिए, यह सब कुछ बताते हैं। दिलचस्प हिस्सा:

13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 fstatfs(3, {...}) = 0
13791 inotify_init()                    = 4
13791 inotify_add_watch(4, "/path/to/file", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 read(4, 0xd981c0, 26)             = -1 EINTR (Interrupted system call)

यह क्या करता है? यह inotifyफ़ाइल के लिए एक हैंडलर सेट करता है , और तब तक प्रतीक्षा करता है जब तक कि इस फ़ाइल के साथ कुछ नहीं होता है। यदि कर्नेल tailइस इनॉटिफ़ाइड हैंडलर के माध्यम से कहता है , कि फ़ाइल बदल गई (सामान्य रूप से, जोड़ दी गई), तो tail1) 2 चाहता है) परिवर्तनों को पढ़ता है 3) उन्हें स्क्रीन पर लिखता है।

/proc/3844/fd/1आपके सिस्टम पर एक प्रतीकात्मक लिंक है /dev/pts/14, जो एक चरित्र उपकरण है। कुछ "मेमोरी मैप" जैसी कोई चीज नहीं है, जिसे उस तक पहुँचा जा सकता है। इस प्रकार, कुछ भी नहीं है जिसके परिवर्तनों को इनोटाइज़ में हस्ताक्षरित किया जा सकता है, क्योंकि कोई डिस्क या मेमोरी क्षेत्र नहीं है जो उस तक पहुँचा जा सकता है।

यह कैरेक्टर डिवाइस एक वर्चुअल टर्मिनल है, जो व्यावहारिक रूप से इस तरह काम करता है जैसे कि यह एक नेटवर्क सॉकेट हो। इस वर्चुअल टर्मिनल पर चलने वाले प्रोग्राम इस डिवाइस से कनेक्ट हो रहे हैं (जैसे कि अगर आप टेलनेट-टेड को tcp पोर्ट में रखते हैं), और वे जो लिखना चाहते हैं उसे लिख रहे हैं। साथ ही जटिल चीजें भी हैं, उदाहरण के लिए स्क्रीन लॉक करना, टर्मिनल नियंत्रण अनुक्रम और इस तरह, ये सामान्य रूप से ioctl()कॉल द्वारा नियंत्रित होते हैं।

मुझे लगता है, आप किसी तरह वर्चुअल टर्मिनल देखना चाहते हैं। यह लिनक्स पर किया जा सकता है, लेकिन यह इतना सरल नहीं है, इसके लिए कुछ नेटवर्क प्रॉक्सी जैसी कार्यक्षमता की आवश्यकता है, और इन ioctl()कॉलों का थोड़ा मुश्किल उपयोग । लेकिन ऐसे उपकरण हैं जो ऐसा कर सकते हैं।

वर्तमान में मुझे याद नहीं आ रहा है कि किस डेबियन पैकेज में इस लक्ष्य के लिए उपकरण है, लेकिन थोड़ी सी गुगली के साथ आप पा सकते हैं कि शायद आसानी से।

विस्तार: जैसा @ जजेश ने यहां उल्लेख किया है (उन्हें +1 करें यदि आपने मुझे दिया है), उपकरण का नाम है watch

विस्तार # 2: @kelnos उल्लेख किया है, एक सरल cat /dev/pts/14भी पर्याप्त थे। मैंने कोशिश की, और हाँ, यह काम किया, लेकिन सही ढंग से नहीं। मुझे लगता है कि के साथ एक बहुत प्रयोग नहीं किया है, लेकिन यह करता है, तो एक आउटपुट कि आभासी चला टर्मिनल में जाने के रूप में मुझे लगता है या तो करने के लिए catआदेश, या उसके मूल स्थान पर है, और दोनों के लिए कभी नहीं। लेकिन यह निश्चित नहीं है।


के बारे tailमें पीटर का जवाब सही है (घड़ी को थोड़ा सुधारें), लेकिन वह गलत है कि यह वास्तव में बहुत आसान है कि आप क्या चाहते हैं: catइसके बजाय बस का उपयोग करें tail
kelnos

@kelnos धन्यवाद, मैं कोशिश करूँगा और परिणामों के साथ अपने उत्तर का विस्तार करूँगा।
पेटेर -

@kelnos catमेरे लिए भी काम नहीं करता है, यह उसी तरह से लटका रहता है जिस तरह से पूंछ करता है और जो मैं कर सकता हूं वह है ctrl+c
cprn

1
मैं अभी भी नहीं मिला। मैं बदल echo $$गया echo $$ >> fooइसलिए अब एक फ़ाइल है और प्रक्रिया इसे खोलती है और इसे हर 0.5 सेकंड में जोड़ देती है। मैं अभी भी फ़ाइल डिस्क्रिप्टर और सभी फ़ाइल डिस्क्रिप्टर /proc/$pid/fd/(लेकिन 254 जो test.shस्वयं स्क्रिप्ट से लिंक करता हूं ) लिंक के माध्यम से इसे एक्सेस नहीं कर सकता /dev/pts/14। बैश एक्सेस fooइसे कैसे लिखता है?
cprn

1
विषम, यह केवल कुछ स्थितियों में काम करने के लिए प्रकट होता है। प्रश्न में स्क्रिप्ट का उपयोग करना, यह काम नहीं करता है। लेकिन अगर मैं एक शेल में "इको $ $" करता हूं, और फिर एफडी 1 को एक और शेल में पीआईडी ​​करता हूं, तो पहले शेल में जो कुछ भी मैं टाइप करता हूं वह दूसरे में गूँजता है।
kelnos 20

4

फाइलें /dev/ptsनियमित फाइल नहीं हैं, वे वर्चुअल टर्मिनलों के लिए हैंडल हैं। ptsपढ़ने और लिखने के लिए एक व्यवहार सममित नहीं है (अर्थात, वहां जो कुछ लिखा गया है, उसे बाद में एक नियमित फ़ाइल या पंद्रो / पाइप की तरह से पढ़ा जा सकता है), लेकिन इस प्रक्रिया द्वारा मध्यस्थता की गई जिसने वर्चुअल टर्मिनल बनाया: कुछ सामान्य हैं xterm या ssh या agetty या स्क्रीन। नियंत्रण प्रक्रिया आमतौर पर उन प्रक्रियाओं को कुंजी दबाती है जो ptsफाइल को पढ़ती हैं , और स्क्रीन पर प्रस्तुत करती हैं कि वे क्या लिखते हैं pts

इस प्रकार, tail -f /dev/pts/14आप उस कुंजी को प्रिंट करेंगे , जिस टर्मिनल पर आपने अपनी स्क्रिप्ट शुरू की थी, और यदि आप करते हैं echo meh > /dev/pts/14तो mehसंदेश टर्मिनल में दिखाई देगा।


आप कहने के लिए सही हैं कि मैं pts डिवाइस को लिख सकता हूं, लेकिन मैं इससे पढ़ नहीं सकता। जैसे: tail -f /dev/pts/14मैं उस टर्मिनल पर टैप की जाने वाली चाबियों को प्रिंट नहीं करता। हालांकि यह एक दिलचस्प जवाब है। धन्यवाद।
cprn

0

कुछ समय पहले मैंने पाया कि एक तरह का वर्कअराउंड है जो कभी-कभी यह जांचने की आवश्यकता का जवाब देता है कि एसटीडीयूएसटी के लिए क्या किया जा रहा है, यह मानकर कि आपके पास pidप्रक्रिया है और आप आंखों को बेवजह परिणाम दे सकते हैं:

sudo strace -p $pid 2>&1 | grep write\(

-2

मुझे लगता है, इसके लिए पूंछने के बजाय, आपको आउटपुट देखने की क्या जरूरत होगी।

$ watch -n2 ls -l /proc/3844/fd/

आशा है कि यह वही है जो आपको चाहिए।


3
यह कमांड प्रत्येक 2 सेकंड में खुले fds की सूची दिखाएगा, न कि स्टडआउट पर सामग्री आउटपुट।
.ngel

Ángel, सच। वह परिणाम देखने के लिए एक बिल्ली के साथ घड़ी का उपयोग कर सकता था जिस पर वह विवरणकर्ता को मॉनिटर करना चाहता था। मुझे लगता है कि @ पीटर-होर्वाथ ने प्रश्न के लिए सही स्पष्टीकरण दिया।
जयेश

मुझे पता है watch। मैं जो करने की कोशिश कर रहा हूं वह पहले से चल रही प्रक्रिया के आउटपुट को झांकना है, इसलिए watchमदद नहीं करता है।
cprn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.