ฆ่าโพรเซสแล้วบังคับให้คืนค่า 0 ใน Linux?


16

ในสภาพแวดล้อม Linux ฉันจะส่งสัญญาณ kill ไปยังกระบวนการได้อย่างไรในขณะที่ตรวจสอบให้แน่ใจว่ารหัสทางออกที่ส่งคืนจากกระบวนการนั้นเป็น 0 ฉันต้องทำเวทย์มนตร์ GDB แฟนซีสำหรับเรื่องนี้หรือจะมีสัญญาณการฆ่าแฟนซีที่ฉันไม่รู้?

กรณีทดสอบ:

cat; echo $?

killall cat

การลองใช้สัญญาณ kill ต่าง ๆ จะให้สัญญาณส่งกลับที่แตกต่างกันเช่น 129, 137 และ 143 เป้าหมายของฉันคือฆ่ากระบวนการที่สคริปต์ทำงาน แต่ทำให้สคริปต์คิดว่ามันประสบความสำเร็จ

คำตอบ:


20

คุณสามารถแนบกับกระบวนการโดยใช้ GDB และ ID กระบวนการแล้วออกcallคำสั่งด้วยexit(0)เป็นอาร์กิวเมนต์

callช่วยให้คุณสามารถเรียกฟังก์ชั่นภายในโปรแกรมที่กำลังทำงานอยู่ การโทรexit(0)ออกด้วยรหัสส่งคืนเป็น 0

gdb -p <process name>
....
.... Gdb output clipped
(gdb) call exit(0)

Program exited normally.

เป็นเครื่องมือบรรทัดเดียว:

gdb --batch --eval-command 'call exit(0)' --pid <process id>

นี้จะไม่ทำงานถ้าโปรแกรมไม่ได้ใช้ (g) libc No symbol table is loaded. Use the "file" commandเช่นโปรแกรมที่เขียนในการชุมนุม: แม้ว่าจะเป็นไปได้ยาก
Cristian Ciupitu

ทำงานกับสคริปต์ ruby ​​:-D
Mikhail

1
@CristianCiupitu มีวิธีแก้ไขปัญหานั้น เมื่อเข้าสู่การเรียกระบบครั้งต่อไปเพียงแค่แก้ไขการลงทะเบียนที่เกี่ยวข้องเพื่อทำให้โปรแกรมเป้าหมายโทรการ_exitเรียกระบบด้วย0อาร์กิวเมนต์ ที่จะทำงานในกระบวนการใด ๆ ที่ไม่ได้วนซ้ำและเผาวงจร CPU หากกระบวนการไม่เกิดขึ้นในลูปที่ไม่มีที่สิ้นสุดคุณยังสามารถใช้วิธีการเดียวกันหากคุณสามารถหาคำแนะนำที่จำเป็นได้จากที่ไหนสักแห่งในการปฏิบัติการและชี้ตัวชี้คำแนะนำไปที่นั่น
kasperd

@ Mikail ใช้งานได้กับ "สคริปต์ทับทิม" เนื่องจาก GDB เชื่อมต่อกับกระบวนการล่ามทับทิมซึ่งไบนารีเชื่อมโยงกับ glibc
Daniel

@kasperd ใช่ฉันก็เป็นเช่นนั้น แต่คำแนะนำที่แม่นยำยิ่งขึ้นก็คงจะดี
Cristian Ciupitu

8

ไม่เมื่อเชลล์จับSIGCHLDมันโดยไม่มีเงื่อนไขจะตั้งค่าส่งคืนอย่างเหมาะสมให้เป็นค่าที่ไม่ใช่ศูนย์ดังนั้นสิ่งนี้จะต้องมีการแก้ไขสคริปต์หรือเชลล์


3

ฉันไม่แน่ใจ แต่สิ่งนี้จะออกด้วย 0 หากมีสัญญาณใด ๆ ที่แสดงรายการไว้ คุณสามารถดำเนินการอื่น ๆ รวมถึงการเรียกฟังก์ชั่น ฯลฯ

#!/bin/bash 
trap 'exit 0' SIGINT SIGQUIT SIGTERM

3

สิ่งนี้ใช้ได้กับฉัน:

/bin/bash -c '/usr/bin/killall -q process_name; exit 0'

ฉันไม่คิดว่าคุณเข้าใจคำถาม ไม่มีทางคำสั่งนั้นจะบรรลุสิ่งที่ถูกขอ นี่คือสิ่งที่ฉันได้รับจากการใช้คำสั่งของคุณ: $ cat; echo $? Terminated 143.
kasperd

2
@Landon Thomas บรรทัดรหัสของคุณแสดงที่นี่ในความเป็นจริงกลับ 0 แต่ process_name ที่ถูกฆ่าไม่กลับ 0 ซึ่งเป็นสิ่งที่ OP ต้องการ
Daniel

2

วิธีแฮ็กเล็กน้อย แต่ ..

คุณสามารถสร้าง wrapper ในกระบวนการของคุณโดยแทนที่ SIGCHLD Handler ตัวอย่างเช่น:

#!/bin/bash
set -o monitor
trap 'exit(0)' CHLD
/some/dir/yourcommand

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

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