दूसरे बैश सत्र में चल रही प्रक्रिया के आउटपुट को कैसे देखें?


199

जब मैंने स्थानीय रूप से इस पर काम कर रहा था, तो मैंने एक स्क्रिप्ट को रिमोट मशीन पर छोड़ दिया है। मैं SSH को एक ही उपयोगकर्ता के रूप में मशीन से कनेक्ट कर सकता हूं और स्क्रिप्ट को चालू देख सकता हूं ps

$ ps aux | grep ipcheck
myuser  18386  0.0  0.0  18460  3476 pts/0    S+   Dec14   1:11 /bin/bash ./ipchecker.sh

यह बस एक स्थानीय सत्र (मैं ./ipchecker.shएक स्थानीय टर्मिनल विंडो, कोई पुनर्निर्देशन, screenआदि का कोई उपयोग नहीं करता है ) को चलाने के लिए आउटपुट देता है ।

वैसे भी SSH सत्र से मैं इस रनिंग कमांड के आउटपुट को देख सकता हूं (इसे बिना रोकें)?

अब तक मुझे जो सबसे अच्छा मिला है वह है उपयोग करना, strace -p 18386लेकिन मुझे स्क्रीन पर उड़ान भरने वाले पाठों की भीड़ मिलती है, इसका बहुत विस्तृत विवरण। मैं रोक सकता हूं straceऔर फिर आउटपुट के माध्यम से झार सकता हूं और पा सकता हूं कि टेक्स्ट को प्रिंटआउट में प्रिंट किया गया है लेकिन इसकी बहुत लंबी और भ्रामक है, और जाहिर है कि जब तक इसे रोका जाता है मुझे कुछ याद आ सकता है। मैं स्क्रिप्ट आउटपुट को देखने का एक तरीका खोजना चाहता हूं जैसे कि मैं स्थानीय स्तर पर काम कर रहा हूं।

क्या कोई इस पर सुधार कर सकता है? स्पष्ट उत्तर स्क्रिप्ट को पुनर्निर्देशन के साथ या एक screenसत्र आदि में फिर से शुरू करना है, यह एक मिशन महत्वपूर्ण स्क्रिप्ट नहीं है इसलिए मैं ऐसा कर सकता हूं। हालांकि, मैं इसे एक मजेदार सीखने के अभ्यास के रूप में देखता हूं।


क्या आपकी प्रक्रिया वर्चुअल कंसोल या GUI / xterm जैसे वातावरण में चल रही है?
jippie

4
strace -p 4232 -e write
स्ट्रेस के

@jippie मशीन पूर्ण GUI (लिनक्स Mynt 13, XFCE डेस्कटॉप) चला रही है, मैंने एक गनोम-टर्मिनल को निकाल दिया।
jwbensley

3
इस साइट पर कम से कम एक दर्जन समान प्रश्न हैं। उनमें से कुछ (और एक उत्तर) खोजने के लिए यहां पुनरावृत्ति के लिए देखें
स्टीफन चेज़लस

जवाबों:


180

यदि आप सभी मौजूदा प्रक्रिया पर जासूसी करना चाहते हैं, तो आप उपयोग कर सकते हैं strace -p1234 -s9999 -e writeजहां 1234 प्रक्रिया आईडी है। ( -s999932 वर्णों को काटे गए तार से बचा जाता है, और writeआउटपुट उत्पन्न करने वाला सिस्टम कॉल।) यदि आप किसी विशेष फ़ाइल डिस्क्रिप्टर पर लिखे गए केवल डेटा को देखना चाहते हैं, तो आप कुछ का उपयोग कर सकते हैं जैसे strace -p1234 -e trace= -e write=3कि केवल फाइल डिस्क्रिप्टर 3 में लिखे गए डेटा को देखना ( -e trace=सिस्टम को रोकता है) लॉग होने से कॉल)। यह आपको आउटपुट नहीं देगा जो पहले से ही उत्पादित है।

यदि आउटपुट बहुत तेज़ी से स्क्रॉल हो रहा है, तो आप इसे पेजर में पाइप कर सकते हैं less, या इसे किसी फ़ाइल के साथ भेज सकते हैं strace -o trace.log …

कई कार्यक्रमों के साथ, आप अपने वर्तमान टर्मिनल या नए स्क्रीन सत्र में या तो ptrace हैक के साथ बाद के आउटपुट को डायवर्ट कर सकते हैं। देखें कि मैं एक रनिंग प्रक्रिया को कैसे भंग कर सकता हूं और इसे एक नए स्क्रीन शेल में जोड़ सकता हूं? और अन्य जुड़े हुए धागे।

ध्यान दें कि आपका सिस्टम कैसे सेट किया गया है, इसके आधार पर, आपको इन सभी straceआदेशों को रूट के रूप में चलाने की आवश्यकता हो सकती है, भले ही प्रक्रिया आपके उपयोगकर्ता के तहत बिना किसी अतिरिक्त विशेषाधिकार के चल रही हो। (यदि प्रक्रिया एक अलग उपयोगकर्ता के रूप में चल रही है या setuid या setgid है, तो आपको straceरूट के रूप में चलाने की आवश्यकता होगी ।) अधिकांश वितरण केवल एक प्रक्रिया को अपने बच्चों का पता लगाने की अनुमति देते हैं (यह एक मध्यम सुरक्षा लाभ प्रदान करता है - यह कुछ प्रत्यक्ष मैलवेयर इंजेक्शन को रोकता है,) लेकिन फ़ाइलों को संशोधित करके अप्रत्यक्ष इंजेक्शन को नहीं रोकता है)। यह kernel.yama.ptrace_scomesysctl द्वारा नियंत्रित किया जाता है ।


18
मुझे नहीं लगता कि आउटपुट को केवल मानक आउटपुट तक सीमित करने का एक तरीका है ?
जोनाह

3
क्या आप सभी तर्क समझा सकते हैं?
उपयोगकर्ता

6
बहुत सारे आउटपुट में बैकस्लैश और संख्या थी जो मुझे नोडज से मिल रहा था; वे किस एन्कोडिंग में हो सकते हैं? बहुत सादा पाठ भी था, जिसकी मुझे बहुत आवश्यकता थी।
थोरसुमोनर

3
"क्या आप सभी तर्क समझा सकते हैं?" @ उपयोगकर्ता:man strace
पिस्तोस

3
@ राफेलमोनी एक कार्यक्रम जिसे आप पूछ रहे हैं उसे डिबगर कहा जाता है।
गिल्स

139

आप procफाइल सिस्टम के माध्यम से आउटपुट एक्सेस कर सकते हैं ।

tail -f /proc/<pid>/fd/1

1= stdout, 2= stderr


7
यह मुझे देता है: 'पढ़ने के लिए / नहीं खोल सकता / खरीद सकता है </ pid> / fd / 1 पढ़ने के लिए: ऐसा कोई उपकरण या पता नहीं'।
यारोस्लाव निकितेंको

18
हाँ <मेरी पिड> आपकी प्रक्रिया आईडी
टीवीएलॉय

29
यह तब काम नहीं करेगा जब आउटपुट टटी (या पुनर्निर्देशित /dev/null) पर जा रहा हो - यह केवल तभी काम करेगा जब आउटपुट किसी फाइल में रीडायरेक्ट हो।
Mattdm

1
उबंटू 16.04 पर परीक्षण किया गया और यह काम नहीं करता है। एक सत्र में मैं करता हूं: ping google.esऔर दूसरे में जड़ के रूप में: tail -f /proc/`pgrep ping`/fd/2और कुछ भी नहीं दिखाया गया है।
david.perez 8

1
तुम सही हो। क्योंकि fd 1 और 2 / dev / pts डिवाइस के लिए सीमलिंक हैं। आप -fa pts डिवाइस को टेल-टेल नहीं कर सकते। क्रोनजोब के रूप में अपने पिंग कमांड को शेड्यूल करें और फिर वही करें। टेल
-फ

9

बीएसडी में, आप watchकिसी दिए गए ट्टी जैसे स्नूप का उपयोग कर सकते हैं , जैसे

watch /dev/pts/0

लिनक्स में, यह संभव नहीं होगा यदि प्रक्रिया मल्टीप्लेक्सर के तहत नहीं चलती थी जैसे पहले screenया tmux। इसे भी देखें: Reptyr: एक नए टर्मिनल के लिए एक रनिंग प्रक्रिया संलग्न करें

यह (जैसे लगता है एक ही रास्ता प्रक्रिया डिबग करने के लिए है strace, dtrace/ dtruss, gdb, lldb, आदि)।

चूंकि आपने straceकिसी सार्थक आउटपुट को लाने के लिए उपयोग किया है , इसलिए आपको क्वालिफाइंग एक्सप्रेशन (जैसे file) द्वारा फ़िल्टर करने की आवश्यकता है , फिर आउटपुट को पार्स करें। यहाँ उदाहरण है:

strace -e trace=write -s1000 -fp 18386 2>&1 | grep -o '".\+[^"]"'

यह क्या करता है यह PID द्वारा निर्दिष्ट प्रक्रिया (1000 लंबाई) के संचालन को लिखता है ( pgrepइसे नाम से खोजने के लिए उपयोग करें), मानक त्रुटि को आउटपुट में (फ़िल्टर किए जाने के लिए) और दोहरे-उद्धृत स्ट्रिंग को प्रिंट करता है।

यदि आप बाइनरी आउटपुट के साथ काम कर रहे हैं, तो आप read(के साथ -r) और printf (के साथ %b), जैसे अनुक्रम दृश्यों से बच सकते हैं

while read -r -t1 line; do printf "%b" $line; done

help readअधिक मापदंडों के लिए जाँच करें (उदाहरण के -nलिए, नई पंक्ति के बजाय वर्णों की निश्चित मात्रा के बाद मुद्रित करें)।

यहाँ और अधिक पूर्ण उदाहरण है:

strace -e trace=write -s1000 -fp 18386 2>&1 \
| grep --line-buffered -o '".\+[^"]"' \
| grep --line-buffered -o '[^"]\+[^"]' \
| while read -r line; do
  printf "%b" $line;
done

किसी भी प्रक्रिया का उपयोग करने वाले उदाहरणों के लिए, कृपया जांचें: शेल में सादे पाठ में स्ट्रेस को पार्स कैसे करें? स्टैकओवरफ्लो पर


4
  1. आप का उपयोग कर रिमोट स्क्रीन पर नज़र करने के लिए सक्षम हो सकता है ssh localhost 'DISPLAY=:0.0 xwd -root' | xwud -scale, जहां localhostअपने दूरस्थ सर्वर लॉगइन क्रेडेंशियल्स द्वारा और को बदल देना चाहिए :0.0आपके GUI का प्रदर्शन संख्या के साथ।

  2. उपयोग करें x11vnc, जो आपके स्क्रीन एक्स-सत्र के लिए एक वीएनसी सर्वर है।

  3. 6 वर्चुअल कंसोल में से एक पर चलने पर sudo setterm -dump 2 -file /dev/stdout, जहां आप 2उपयुक्त vc से प्रतिस्थापित करते हैं।


4

मैं एक नामित पाइप ( mkfifo) बनाने की सलाह दूंगा और फिर उस फाइल को लिखूंगा। फिर, इससे पढ़ें। आप हमेशा ऐसा कर सकते हैं जैसे कि tailआउटपुट को कम करने के लिए, आदि। जब भी आप पाइप को साफ़ करते हैं (इससे पढ़ें), यह साफ़ हो जाता है, इसलिए आउटपुट संरक्षित नहीं होता है।

दूसरा विकल्प यह होगा कि आप सब कुछ एक फ़ाइल में लिखें (एक लॉगफ़ाइल की तरह) और फिर किसी भी समय इसका विश्लेषण करें। यह पसंदीदा कार्रवाई होगी, यदि आप सभी आउटपुट को संरक्षित करना चाहते हैं।


3

तुम हमेशा एक प्रक्रिया whith शुरू कर सकते हैं nohup और &

nohup rsync source_file dest_file &

फिर, आप किसी भी tty से प्रगति की जाँच कर सकते हैं:

tail -f nohup.out

यह मेरे लिए ठीक काम करता है।


6
यह सवाल मैं कैसे एक चेतावनी चल प्रक्रिया के उत्पादन में देखने के लिए के बारे में चाहते हैं, न कि कैसे एक प्रक्रिया पृष्ठभूमि में के रूप में अपने जवाब से पता चलता है चलाने के लिए
jwbensley

वास्तव में, अपने: nohup उल्लेख मुझे ज्ञान! धन्यवाद!
नम जी वीयू

1

आउटपुट प्राप्त करने के लिए एक बहुत ही सरल आपके आउटपुट को एक फ़ाइल में कैप्चर करेगा और उस फ़ाइल को सिलाई करेगा।

यदि DO :/ipcheck

INSTEAD DO :/ipcheck> [Replacewithyourfilename]

यह एक आउटपुट फ़ाइल बनाता है जहाँ आपकी स्क्रिप्ट स्थित है। फिर किसी अन्य बैश शेल से आप बस फ़ाइल को पूँछ सकते हैं:

पूंछ [रिप्लेसिथयुरफिलनेम] -f


फ़ाइल पुनर्निर्देशन डिफ़ॉल्ट रूप से ब्लॉक-आधारित बफ़रिंग का उपयोग करता है (देखें setbuf(3)) जो tailसमस्याग्रस्त हो सकता है।
थ्रिग

5
इसके अलावा यह सवाल के साथ मदद नहीं करता है, जो कि पहले से चल रही प्रक्रिया के आउटपुट को देखने के बारे में था, न कि एक नई प्रक्रिया के लिए stdout को रीडायरेक्ट करने के लिए।
jwbensley

1

स्ट्रेस का आउटपुट पार्स करना:

मैंने शीर्ष उत्तर का उपयोग किया (मेरी प्रक्रिया आईडी के साथ 28223) ...

> sudo strace -p28223 -s9999 -e write
...
write(9, "Info\nI\nCare\nabout", 55) = 55
...

यह निर्धारित करने के लिए कि मुझे परवाह है write(9। (नीचे 9 का उपयोग किया गया है, यह संभवतः एक फ़ाइल हैंडल है और आपकी प्रक्रिया के लिए भिन्न हो सकता है।) फिर मैंने उन्हें लिखने और प्रदर्शित करने के लिए एक त्वरित रूबी स्क्रिप्ट लिखी।

निम्नलिखित में पेस्ट करें /usr/bin/parse_strace.rb

#!/usr/bin/ruby

num = ARGV[0]
STDIN.each { |line|
  if (line.match(/write\(#{ num },\s*"(.*?)"/)) then
    puts $1.split('\x').map { |s| s.to_i(16).chr }.join()
  end
}

मत भूलना chmod a+x /usr/bin/parse_strace.rb

मैं आह्वान करता हूं strace -xx(हेक्स को आउटपुट करता है, इसलिए रेगेक्स ठीक से मेल खाता है), पाइपिंग (एसटीडीआरआर सहित) मेरी स्क्रिप्ट के साथ 9पहले आर्ग के रूप में।

sudo sh -c 'strace -xx -p28223 -s9999 -e write 2>&1 | parse_strace.rb 9'

और, वॉयला, यह प्रक्रिया के मूल STDOUT, newlines, रंग और सभी को आउटपुट करता है!

STDOUT प्रक्रिया के लिए संलग्न


0

क्या आप प्रक्रिया आईडी प्राप्त नहीं कर सकते हैं और इसके साथ USR1 के साथ संवाद कर सकते हैं,

$pgrep -l '^ipchecker.sh$'

जो आपकी स्क्रिप्ट के PID को प्रिंट करता है, फिर उसका उपयोग करें

$ kill -USR1 PID

मैं समझता हूं कि USR1 एक "उपयोगकर्ता परिभाषित" संकेत है, जिसका अर्थ है कि जिसने भी प्रोग्राम बनाया है वह इसका अर्थ "शट डाउन" या "अपने लॉग्स को डंप" या "एक हजार बार फू फूँक" या जो भी हो सकता है।

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