แนบกับเอาต์พุตกระบวนการสำหรับการดู


112

ฉันจะ 'แนบ' คอนโซล / มุมมองเทอร์มินัลเข้ากับเอาต์พุตของแอปพลิเคชันได้อย่างไรเพื่อที่ฉันจะได้เห็นว่ามันกำลังพูดอะไร

ฉันจะแยกออกจากเอาต์พุตของแอปพลิเคชันโดยไม่ฆ่าแอปพลิเคชันได้อย่างไร

โดยปกติถ้าคุณเปิดแอปพลิเคชันที่ช่างพูดโดยใช้บรรทัดคำสั่งคุณจะเห็นผลลัพธ์ที่ยอดเยี่ยมทุกประเภท อย่างไรก็ตามสมมติว่าฉันมีการเขียนโปรแกรมช่างพูดโดยเฉพาะที่กำลังทำงานอยู่เช่น KINO และฉันต้องการดูผลลัพธ์ในช่วงเวลาใดเวลาหนึ่งโดยไม่ต้องรีสตาร์ทผ่านบรรทัดคำสั่ง ฉันไม่สามารถ; อย่างน้อยฉันก็ไม่รู้ว่าเป็นอย่างไร


1
คุณมีสัญลักษณ์ debug ในกระบวนการของคุณหรือไม่? มันทำงานในสภาพแวดล้อมการผลิตหรือไม่? และถ้าเป็นเช่นนั้นคุณต้องใช้เพื่อไม่ให้หยุดชั่วคราวหรือไม่
yves Baumes

เมื่อฉันมีปัญหาด้านความเสถียรกับโปรแกรมสำหรับผู้ใช้ปลายทางเช่น kino (เกิดปัญหาและทำให้เสียงของฉันเสีย) ฉันต้องการทราบวิธี / สาเหตุที่มันขัดข้องเพื่อที่ฉันจะได้แก้ไขได้ นี่ไม่ใช่โปรแกรมที่ฉันกำลังพัฒนา แต่เป็นเทคนิคที่ฉันอยากรู้สำหรับปัญหาในการถ่ายทำ ฉันจะลองทำตามคำแนะนำของคุณด้านล่าง
aggitan

คำตอบ:


18

มีไม่กี่ตัวเลือกที่นี่ วิธีหนึ่งคือการเปลี่ยนทิศทางผลลัพธ์ของคำสั่งไปยังไฟล์จากนั้นใช้ 'tail' เพื่อดูบรรทัดใหม่ที่เพิ่มลงในไฟล์นั้นแบบเรียลไทม์

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


1
"มีตัวเลือกอยู่สองสามตัวเลือกหนึ่งคือเปลี่ยนเส้นทางเอาต์พุตของคำสั่งไปยังไฟล์จากนั้นใช้" tail "เพื่อดูบรรทัดใหม่ที่เพิ่มลงในไฟล์นั้นแบบเรียลไทม์" สามารถทำได้กับแอปพลิเคชันที่ใช้งานอยู่แล้วหรือไม่?
aggitan

2
คุณอาจต้องใช้ tail -f $ log_file เพื่อให้ได้ผลลัพธ์ตามที่เขียนไว้ในไฟล์ นอกจากนี้ไม่มีไม่มีทางที่ฉันรู้ว่าจะทำเช่นนั้นกับแอปที่ทำงานอยู่แล้ว
Varkhan

@aggitan: ไม่สำหรับแอปพลิเคชันที่มีอยู่คุณจะต้องเริ่มต้นใหม่เนื่องจากได้ผูก I / O ไว้กับเทอร์มินัลควบคุมแล้ว
Don Werve


289

ฉันคิดว่าฉันมีวิธีแก้ปัญหาที่ง่ายกว่าที่นี่ เพียงมองหาไดเร็กทอรีที่มีชื่อตรงกับ PID ที่คุณกำลังมองหาภายใต้ระบบไฟล์หลอกที่สามารถเข้าถึงได้ภายใต้/procพา ธ ดังนั้นหากคุณมีโปรแกรมที่ทำงานซึ่งมี ID คือ 1199 cdอยู่:

$ cd /proc/1199

จากนั้นมองหาfdไดเร็กทอรีด้านล่าง

$ cd fd

fdไดเร็กทอรีนี้เก็บอ็อบเจ็กต์ file-descriptors ที่โปรแกรมของคุณใช้ (0: stdin, 1: stdout, 2: stderr) และเป็นเพียงtail -fสิ่งที่คุณต้องการ - ในกรณีนี้คือ stdout):

$ tail -f 1

9
ฉันไม่สามารถใช้tailในกรณีของฉันผลลัพธ์ถูกเปลี่ยนเส้นทางไปยังกระบวนการอื่นสำหรับอินพุต แต่moreแสดงข้อมูลปัจจุบันให้ฉันเห็น
Ωmega

10
หนึ่งในโพสต์ที่น่าสนใจที่สุดในเว็บไซต์นี้!
robert

2
moreกำลังทำงานให้ฉัน ubuntu 14.04 ในกระบวนการโหนด
Shih-Min Lee

1
สิ่งนี้ใช้ไม่ได้สำหรับฉันกับกระบวนการ java ที่เรียก System.out.println ไม่มีเอาต์พุตเลยถึง / proc / [pid] / fd / 1
นิค

1
พยายามสร้างการจำลองโดยใช้ด้านล่าง แต่ไม่มีประโยชน์: `` นักเทียบท่ารัน -it --name container1 ubuntu bash -c -i "COUNT = 0; ในขณะที่จริงทำ echo ให้จังหวะฟลอร์เต้นรำดำเนินต่อไป; (( COUNT ++)); sleep 1; echo \ "Count is: \ $ {COUNT} \"; done; " `` ในเทอร์มินัลอื่น: `` docker exec -it container1 tail -f / proc / 1 / fd / 1 ``
JacobWuzHere

54

ฉันกำลังมองหาสิ่งเดียวกันนี้และพบว่าคุณสามารถทำได้:

strace -ewrite -p $PID

มันไม่ตรงกับที่คุณต้องการ แต่มันค่อนข้างใกล้เคียง

ฉันลองใช้เอาต์พุตการเปลี่ยนเส้นทาง แต่ไม่ได้ผลสำหรับฉัน อาจเป็นเพราะกระบวนการเขียนลงในซ็อกเก็ตฉันไม่รู้


ขอบคุณที่ใช้งานได้ แต่เอาต์พุตถูกตัดทอนเช่นสำหรับ ping: write (1, "64 bytes from 1.0.0.1: icmp_seq =" ... , 56) = 56
izy

8

ฉันจะ 'แนบ' คอนโซล / มุมมองเทอร์มินัลเข้ากับเอาต์พุตของแอปพลิเคชันได้อย่างไรเพื่อที่ฉันจะได้เห็นว่ามันกำลังพูดอะไร

เกี่ยวกับคำถามนี้ฉันรู้ว่าเป็นไปได้ที่จะจับเอาท์พุทแม้ว่าคุณจะไม่ได้เปิดคำสั่ง sceen ก่อนที่จะเปิดใช้งาน processus

แม้ว่าฉันจะไม่เคยลอง แต่ฉันก็พบบทความที่น่าสนใจซึ่งอธิบายวิธีการใช้ GDB (และไม่ต้องรีสตาร์ทกระบวนการของคุณ)

การเปลี่ยนเส้นทางเอาต์พุตจากกระบวนการรัน

โดยทั่วไป:

  1. ตรวจสอบรายการไฟล์ที่เปิดอยู่สำหรับกระบวนการของคุณขอบคุณ/ proc / xxx / fd
  2. แนบกระบวนการของคุณกับ GDB
  3. ในขณะที่หยุดชั่วคราวให้ปิดไฟล์ที่คุณสนใจโดยเรียกใช้ฟังก์ชันclose () (คุณสามารถทำงานใด ๆ ของกระบวนการของคุณใน GDB ฉันสงสัยว่าคุณต้องการสัญลักษณ์ดีบักในกระบวนการของคุณ .. )
  4. เปิดไฟล์ใหม่ที่เรียกใช้ฟังก์ชันcreate ()หรือ open () (ดูความคิดเห็นในตอนท้ายคุณจะเห็นคนแนะนำให้ใช้dup2 ()เพื่อให้แน่ใจว่าจะใช้หมายเลขอ้างอิงเดียวกัน)
  5. ถอดกระบวนการและปล่อยให้ทำงาน

โดยวิธีการที่ถ้าคุณใช้ระบบปฏิบัติการลินุกซ์บน i386 กล่องความเห็นมีการพูดคุยเกี่ยวกับเครื่องมือที่ดีกว่าที่จะส่งออกเปลี่ยนเส้นทางไปยังคอนโซลใหม่: 'Retty' ถ้าเป็นเช่นนั้นให้พิจารณาการใช้งาน


6

สำหรับฉันสิ่งนี้ได้ผล:

  1. เข้าสู่ระบบในฐานะเจ้าของกระบวนการ (แม้rootจะถูกปฏิเสธการอนุญาต)

    ~$ su - process_owner
    
  2. ระบุคำอธิบายไฟล์ตามที่กล่าวไว้ในคำตอบอื่น ๆ

    ~$ tail -f /proc/<process-id>/fd/1 # (0: stdin, 1: stdout, 2: stderr)
    

2

ฉันต้องการดูกระบวนการอัปเกรดยำที่ทำงานในพื้นที่จากระยะไกลดังนั้นในขณะที่อาจมีวิธีที่มีประสิทธิภาพมากกว่าในการทำสิ่งนี้นี่คือสิ่งที่ฉันทำ:

watch cat /dev/vcsa1

เห็นได้ชัดว่าคุณต้องการใช้ vcsa2, vcsa3 ฯลฯ ขึ้นอยู่กับว่าใช้เทอร์มินัลใด

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

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