วิธีการดูผลลัพธ์ของกระบวนการทำงานในเซสชั่นทุบตีอื่น?


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

มันเป็นเพียงการส่งออกไปยัง stdout ในเซสชั่นท้องถิ่น (ฉันวิ่งใน./ipchecker.shรูปแบบหน้าต่าง terminal ท้องถิ่นไม่มีการเปลี่ยนเส้นทางไม่มีการใช้งานscreenฯลฯ )

มีต่อไปจากเซสชัน SSH ที่ฉันสามารถดูผลลัพธ์ของคำสั่งที่รันอยู่ (โดยไม่หยุด)

จนถึงตอนนี้สิ่งที่ดีที่สุดที่ฉันพบคือใช้strace -p 18386แต่ฉันได้รับข้อความจำนวนมากลอยขึ้นมาบนหน้าจอซึ่งมีรายละเอียดมากเกินไป ฉันสามารถหยุดstraceและจากนั้นร่อนผ่านเอาท์พุทและค้นหาข้อความที่นำมาพิมพ์ไปยัง stdout แต่มันยาวและสับสนและเห็นได้ชัดว่าในขณะที่มันหยุดฉันอาจพลาดบางอย่าง ฉันต้องการหาวิธีที่จะเห็นเอาต์พุตสคริปต์ทำงานเสมือนว่าฉันทำงานในพื้นที่

ใครสามารถปรับปรุงสิ่งนี้ได้บ้าง คำตอบที่ชัดเจนคือการรีสตาร์ทสคริปต์ด้วยการเปลี่ยนเส้นทางหรือในscreenเซสชั่น ฯลฯ นี่ไม่ใช่สคริปต์ที่สำคัญต่อภารกิจดังนั้นฉันสามารถทำได้ แต่ฉันเห็นว่านี่เป็นแบบฝึกหัดการเรียนรู้ที่สนุกสนาน


กระบวนการของคุณทำงานในคอนโซลเสมือนหรือใน GUI / xterm ชอบสภาพแวดล้อมหรือไม่?
jippie

4
คุณสามารถ จำกัด เอาต์พุตของ strace ให้เป็นหนึ่ง syscall:strace -p 4232 -e write
otokan

@ jippie เครื่องใช้งาน GUI เต็มรูปแบบ (Linux Mynt 13, XFCE desktop) ฉันยิง gnome-terminal
jwbensley

3
มีคำถามที่คล้ายกันอย่างน้อยหนึ่งโหลในเว็บไซต์นี้ ค้นหาreptyrที่นี่เพื่อค้นหาบางรายการ (และคำตอบ)
Stéphane Chazelas

คำตอบ:


180

หากสิ่งที่คุณต้องการทำคือสอดแนมกระบวนการที่มีอยู่คุณสามารถใช้โดยstrace -p1234 -s9999 -e writeที่ 1234 เป็นรหัสกระบวนการ ( -s9999หลีกเลี่ยงการมีสตริงที่ถูกตัดให้เหลือ 32 อักขระและwriteการเรียกระบบที่สร้างเอาต์พุต) หากคุณต้องการดูเฉพาะข้อมูลที่เขียนในไฟล์ descriptor เฉพาะคุณสามารถใช้ข้อมูลที่ต้องการstrace -p1234 -e trace= -e write=3ดูเฉพาะข้อมูลที่เขียนลงในไฟล์ descriptor 3 ( -e trace=ป้องกันระบบ การโทรจากการบันทึก) ที่จะไม่ให้ผลลัพธ์ที่ได้รับการผลิตแล้ว

ถ้าผลการเลื่อนโดยเร็วเกินไปท่อคุณสามารถลงในเพจเจอร์เช่นหรือส่งไปยังไฟล์ที่มีlessstrace -o trace.log …

ด้วยหลายโปรแกรมคุณสามารถโอนเอาต์พุตที่ตามมาด้วยแฮ็ค ptrace ไม่ว่าจะเป็นเทอร์มินัลปัจจุบันของคุณหรือไปยังเซสชันหน้าจอใหม่ ดูฉันจะปฏิเสธกระบวนการที่กำลังทำงานอยู่และเชื่อมโยงกับเชลล์หน้าจอใหม่ได้อย่างไร และหัวข้อที่เชื่อมโยงอื่น ๆ

โปรดทราบว่าขึ้นอยู่กับวิธีการตั้งค่าระบบของคุณคุณอาจต้องเรียกใช้straceคำสั่งเหล่านี้ทั้งหมดเป็นรูทแม้ว่ากระบวนการทำงานภายใต้ผู้ใช้ของคุณโดยไม่มีสิทธิ์พิเศษ (หากกระบวนการทำงานในฐานะผู้ใช้อื่นหรือเป็น setuid หรือ setgid คุณจะต้องเรียกใช้straceในฐานะ root) การแจกจ่ายส่วนใหญ่อนุญาตให้กระบวนการติดตามเด็ก ๆ (กระบวนการนี้ให้ประโยชน์ด้านความปลอดภัยปานกลาง - ป้องกันการฉีดมัลแวร์โดยตรง แต่ไม่ป้องกันการฉีดทางอ้อมด้วยการแก้ไขไฟล์) สิ่งนี้ถูกควบคุมโดยkernel.yama.ptrace_scomesysctl


18
ฉันไม่คิดว่าจะมีวิธี จำกัด เอาท์พุทให้แคบลงเป็นแค่เอาต์พุตมาตรฐานหรือไม่
Jonah

3
คุณสามารถอธิบายข้อโต้แย้งทั้งหมดได้หรือไม่?
ผู้ใช้

6
มีแบ็กสแลชและตัวเลขจำนวนมากในเอาต์พุตจำนวนมากที่ฉันได้รับจาก nodejs; มีโอกาสในการเข้ารหัสอะไรบ้าง มีข้อความธรรมดามากมายเช่นกันซึ่งทั้งหมดที่ฉันต้องการ
ThorSummoner

3
"คุณสามารถอธิบายข้อโต้แย้งทั้งหมดได้หรือไม่" @ ผู้ใช้:man strace
Pistos

3
@RafaelMoni โปรแกรมที่จะทำสิ่งที่คุณขอเรียกว่า debugger
Gilles

139

คุณสามารถเข้าถึงเอาต์พุตผ่านprocระบบไฟล์

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

1= stdout, 2= stderr


7
มันให้ฉัน: 'ไม่สามารถเปิด / proc / <my pid> / fd / 1 สำหรับการอ่าน: ไม่มีอุปกรณ์หรือที่อยู่ดังกล่าว'
Yaroslav Nikitenko

18
ใช่ <pid ของฉัน> ควรจะเป็นกระบวนการ id ของคุณ
tvlooy

29
สิ่งนี้จะไม่ทำงานหากเอาต์พุตกำลังไปยัง tty (หรือเปลี่ยนเส้นทางไปที่/dev/null) - มันจะใช้ได้เฉพาะเมื่อเอาต์พุตถูกเปลี่ยนเส้นทางไปยังไฟล์
mattdm

1
ทดสอบกับ Ubuntu 16.04 และใช้งานไม่ได้ ในเซสชั่นที่ฉันทำ: ping google.esและในอีกหนึ่งเป็น root: tail -f /proc/`pgrep ping`/fd/2และไม่มีอะไรจะแสดง
david.perez

1
คุณพูดถูก เนื่องจาก fd 1 และ 2 เป็น symlink ไปยังอุปกรณ์ / dev / pts คุณไม่สามารถปรับอุปกรณ์ -fa pts ได้ กำหนดเวลาคำสั่ง ping ของคุณเป็น cronjob จากนั้นทำเช่นเดียวกัน tail -f จะทำงาน
tvlooy

9

ใน BSD คุณสามารถใช้การwatchสอดแนม tty ที่กำหนดเช่น

watch /dev/pts/0

ในลินุกซ์ก็จะไม่เป็นไปได้ถ้าเป็นกระบวนการที่ไม่ได้ทำงานภายใต้ Multiplexer ก่อนเช่นหรือscreen tmuxดูเพิ่มเติมที่: Reptyr: แนบกระบวนการทำงานกับอาคารใหม่

ดูเหมือนว่าวิธีเดียวคือการแก้ปัญหากระบวนการ (เช่นstrace, dtrace/ dtruss, gdb, lldbฯลฯ )

เมื่อคุณใช้straceเพื่อดึงเอาท์พุทที่มีความหมายคุณจะต้องกรองตามนิพจน์ที่มีคุณสมบัติ (เช่นfile) จากนั้นแยกวิเคราะห์เอาต์พุต นี่คือตัวอย่าง:

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

มันจะพิมพ์การดำเนินการเขียนของกระบวนการ (ความยาว 1,000) ที่ระบุโดย PID (ใช้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

สำหรับตัวอย่างที่ใช้กระบวนการใด ๆ โปรดตรวจสอบ: วิธีแยกวิเคราะห์ strace ในเชลล์เป็นข้อความธรรมดาได้อย่างไร ที่ stackoverflow


4
  1. คุณอาจสามารถดูที่หน้าจอระยะไกลโดยใช้ssh localhost 'DISPLAY=:0.0 xwd -root' | xwud -scaleตำแหน่งที่localhostจะถูกแทนที่ด้วยข้อมูลรับรองการเข้าสู่ระบบเซิร์ฟเวอร์ระยะไกลของคุณและ:0.0ด้วยหมายเลขที่แสดงของ GUI ของคุณ

  2. ใช้x11vncซึ่งเป็นเซิร์ฟเวอร์ VNC สำหรับ X-session บนหน้าจอของคุณ

  3. เมื่อลองใช้หนึ่งใน 6 คอนโซลเสมือนลองsudo setterm -dump 2 -file /dev/stdoutที่คุณแทนที่2ด้วย vc ที่เหมาะสม


4

ฉันแนะนำให้ทำไปป์ที่มีชื่อ ( mkfifo) แล้วเขียนไปที่ไฟล์นั้น จากนั้นอ่านจากมัน คุณสามารถทำสิ่งต่าง ๆ เช่นtailลดขนาดเอาต์พุต ฯลฯ เมื่อใดก็ตามที่คุณล้างท่อ (อ่านจาก) จะได้รับการล้างดังนั้นเอาต์พุตจะไม่ถูกสงวนไว้

ตัวเลือกอื่นจะเขียนทุกอย่างลงในไฟล์ (เหมือน logfile) จากนั้นวิเคราะห์เมื่อใดก็ได้ นี่จะเป็นการกระทำที่ต้องการถ้าคุณต้องการที่จะรักษาเอาท์พุททั้งหมด


3

คุณสามารถเปิดกระบวนการ whith nohupและ&

nohup rsync source_file dest_file &

จากนั้นคุณสามารถตรวจสอบความคืบหน้าจาก tty ใด ๆ ด้วย:

tail -f nohup.out

มันใช้งานได้ดีสำหรับฉัน


6
คำถามนี้ฉันต้องการเกี่ยวกับวิธีการดูผลลัพธ์ของกระบวนการทำงานการแจ้งเตือนไม่ใช่วิธีการเรียกใช้กระบวนการในพื้นหลังตามคำตอบของคุณแนะนำ
jwbensley

ที่จริงแล้วคุณ: nohup พูดถึงความรู้แจ้งฉัน! ขอบคุณ!
Nam G VU

1

วิธีที่ง่ายมากในการรับเอาท์พุทคือการจับเอาท์พุทของคุณไปยังไฟล์และปรับแต่งไฟล์นั้น

หากทำ: ./ipcheck

ทำแทน: ./ipcheck> [replacewithyourfilename]

สิ่งนี้จะสร้างไฟล์เอาต์พุตที่สคริปต์ของคุณตั้งอยู่ จาก bash shell อื่น ๆ คุณสามารถทำการ tail file ได้:

หาง [แทนที่ด้วยชื่อของคุณชื่อไฟล์] -f


การเปลี่ยนเส้นทางไฟล์มีแนวโน้มที่จะใช้การบล็อกบัฟเฟอร์ตามค่าเริ่มต้น (ดูsetbuf(3)) ซึ่งอาจทำให้เกิดtailปัญหา
thrig

5
นอกจากนี้ยังไม่ได้ช่วยคำถามซึ่งเกี่ยวกับวิธีการดูผลลัพธ์ของกระบวนการทำงานแล้วไม่ใช่วิธีการเปลี่ยนเส้นทาง stdout สำหรับกระบวนการใหม่
jwbensley

1

การแยกเอาต์พุตของ strace:

ฉันใช้คำตอบยอดนิยม (ด้วย ID กระบวนการของฉันที่ 28223) ...

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

write(9เพื่อตรวจสอบว่าผมดูแลเกี่ยวกับ (9 ตัวที่ใช้ด้านล่างอาจเป็นตัวจัดการไฟล์และอาจแตกต่างกันสำหรับกระบวนการของคุณ) จากนั้นฉันก็เขียนสคริปต์ Ruby แบบย่อเพื่อแยกวิเคราะห์และแสดง

วางต่อไปนี้ลงใน /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(แสดงผลเลขฐานสิบหกดังนั้น regex จะจับคู่อย่างถูกต้อง), piping (รวมถึง STDERR) กับสคริปต์ของฉันด้วย9arg แรก

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

และ voila จะแสดง STDOUT ดั้งเดิมของบรรทัดใหม่สีและทั้งหมด!

การแนบเพื่อประมวลผล STDOUT


0

คุณไม่สามารถรับรหัสกระบวนการและสื่อสารกับ USR1 ได้

$pgrep -l '^ipchecker.sh$'

ซึ่งจะพิมพ์ PID ของสคริปต์ของคุณจากนั้นใช้เพื่อ

$ kill -USR1 PID

ฉันเข้าใจว่า USR1 เป็นสัญญาณ "ผู้ใช้กำหนด" ซึ่งหมายความว่าใครก็ตามที่สร้างโปรแกรมสามารถใช้มันเพื่อหมายถึง "ปิด" หรือ "ทิ้งบันทึกของคุณ" หรือ "พิมพ์ foo พันครั้ง" หรืออะไรก็ตาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.