ฆ่างานพื้นหลังทั้งหมด


63

มีรูปแบบที่กะทัดรัดกว่าในการฆ่างานพื้นหลังมากกว่า:

for i in {1..5}; do kill %$i; done

นอกจากนี้ {1..5} เห็นได้ชัดว่ามีหมายเลขเวทย์มนตร์ที่เข้ารหัสยากฉันจะทำให้ "N" โดยที่ N เป็นหมายเลขที่ถูกต้องได้อย่างไรโดยไม่ต้องทำ:

$(jobs | wc -l)

ฉันใช้ \ j ใน PS1 จริง ๆ เพื่อให้ได้ # ของงานที่จัดการมันเทียบเท่ากันไหม


3
kill $(jobs -p)ดูเหมือนง่ายขึ้น
jw013

ฉันอยากจะฆ่างานทีละคนถ้าเป็นไปได้ (ฉันอาจเข้าใจผิดความคิดเห็นของคุณ)
Robottinosino

for pid in $(jobs -p); do kill $pid; done?
jw013

3
@ jw013 ไม่เพียง แต่ง่ายขึ้นจริงแล้วมันถูกต้อง (โปรดโพสต์มันเป็นคำตอบ) ซึ่งแตกต่างจากวิธีการแก้ปัญหาตามการนับจำนวนบรรทัดของผลลัพธ์jobsที่ใช้งานได้เฉพาะเมื่องานมีหมายเลขตามลำดับอย่างต่อเนื่อง โอ้และ“ ฆ่างานทีละคน” นั้นไม่มีความหมาย: การส่ง PID หลายตัวไปยังkillคำสั่งนั้นจะเหมือนกับการส่งผ่านพวกมันต่างหาก
Gilles

ฉันป้อนคำสั่งไม่ถูกต้องฆ่าคำ $ (jobs -p) และดูถูกต้องสำหรับฉันเช่นกัน พร้อมที่จะยอมรับ
Robottinosino

คำตอบ:


102

หากต้องการเพียงkillงานพื้นหลังทั้งหมดที่จัดการโดยbashให้ทำ

kill $(jobs -p)

โปรดทราบว่าเนื่องจากทั้งคู่jobsและkillอยู่ภายในbashคุณไม่ควรพบข้อผิดพลาดของรายการอาร์กิวเมนต์ชนิดยาวเกินไป


2
สำหรับลูกหลานสิ่งที่บาฮามัตคิดว่าเป็นวิธีที่จะzshทำให้พวกเขาถูกตัดสิทธิ์ในฐานะผู้มีอำนาจในหัวข้อใด ๆ
peth

ฉันรู้สึกว่าฉันควรรู้สิ่งนี้ แต่ '$' ทำงานที่นี่ได้อย่างไร
fersarr

1
@fersarr นี่คุณไป
jw013

@bahamat ที่ใช้งานไม่ได้จริงเนื่องจาก PID อาจอยู่ในฟิลด์ 2 หรือ 3 ขึ้นอยู่กับว่างานนั้นเป็นหนึ่งใน% + หรือ% - หรือไม่ การทำงานคืออะไรkill %${(k)^jobdirs}ซึ่งอีกต่อไปแน่นอน; หากคุณต้องการแสดงรายการ PID คุณก็สามารถใช้ PID ได้นาน${${jobstates#*:*:}%%=*}ขึ้น
Gilles

บน CentOS พรอมต์ของฉันกำลังรอการป้อนข้อมูลเพิ่มเติม>
Janac Meena

15

ใช้xargsแทนคำ$(jobs -p)สั่งย่อยเพราะถ้าjobs -pว่างเปล่าคำสั่ง kill จะล้มเหลว

jobs -p | xargs kill

1
มันมีผลที่แน่นอนเหมือนกันแม้ว่ามันจะพิมพ์วิธีใช้และออกด้วยรหัส 123
cat

1
คำสั่งทำงานได้ดีบน OSX แต่ไม่สามารถใช้งานได้กับ Debian
brunocascio

วิธีนี้ใช้งานได้ดีบน CentOS 6
Janac Meena

jobs -p | xargs -rn10 killจะทำได้ดีกว่าถ้าjobs -pไม่คืนค่า PID ใด ๆ โปรดทราบว่า-rตัวเลือกนั้นคือส่วนขยาย GNU
NarūnasK

ดังกล่าวข้างต้น-rเป็นรูปแบบสั้น ๆ สำหรับ--no-run-if-emptyส่วนขยาย GNU xargsที่สั่งให้มันไม่ได้เรียกใช้คำสั่งถ้า stdin ไม่มีข้อมูล
Anthony G - ความยุติธรรมสำหรับโมนิก้า

3

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

นอกจากนี้ยังสั้นกว่าที่จะพิมพ์ โยนสิ่งนี้ในของคุณ.bash_profile:

function killjobs () {
    JOBS="$(jobs -p)";
    if [ -n "${JOBS}" ]; then;
        kill -KILL ${JOBS};
    fi
}

จากนั้นเรียกใช้:

killjobs

เพื่อฆ่างานใด ๆ ที่ทำงานอยู่


1

ฉันมีคำสั่งผสมแบบพื้นหลังหลายคำสั่งที่ฉันต้องการยุติอย่างสง่างามโดยการส่ง SIGINT ไปยังแต่ละกระบวนการบน macOS ไม่มีวิธีแก้ปัญหาอื่นที่ทำงานได้อย่างถูกต้องดังนั้นฉันจึงได้สิ่งนี้:

jobs -p | xargs -n1 pkill -SIGINT -g

jobs -p แสดงรายการกระบวนการพื้นหลังที่เริ่มต้นโดยเชลล์ปัจจุบัน

xargs -n1 รัน pkill หนึ่งครั้งสำหรับแต่ละงาน

pkill -SIGINT -g ส่ง SIGINT (เหมือนกับ ctrl + c) ไปยังกระบวนการทั้งหมดในกลุ่มกระบวนการ


1

ฉันเดาขึ้นอยู่กับสิ่งที่jobs -pให้ผลผลิตทางออกอาจแตกต่างกันเล็กน้อย ในกรณีของฉัน

$ jobs -p
[1]  - 96029 running    some job
[2]  + 96111 running    some other job

ดังนั้นการทำสิ่งต่อไปนี้จึงไม่ดี

$ jobs -p | xargs kill
kill: illegal process id: [1]

ในทางกลับกันการรันkill $(jobs -p)จะทำงานได้ แต่มีข้อความแสดงข้อผิดพลาดมากมายเนื่องจากสตริงที่ไม่ใช่ PID จะถูกส่งผ่านไปยังkillเช่นกัน

ดังนั้นทางออกของฉันคือgrepPID ก่อนแล้วจึงใช้xargsดังนี้:

$ jobs -p | grep -o -E '\s\d+\s' | xargs kill

1
คุณใช้เปลือกอะไร สิ่งที่ไม่echo $0แสดง? สิ่งที่ไม่help jobsแสดง? ภาพประกอบที่แสดงไม่เป็นไปตาม POSIX ; การดำเนินการใด ๆของjobsควรมี-pตัวเลือกกับพฤติกรรมที่ตั้งใจไว้
Wildcard

1
ขอบคุณที่ชี้นำสิ่งนี้ ฉันใช้ zsh และนั่นคือเหตุผลสำหรับผลลัพธ์ที่แปลก ฉันเปลี่ยนเป็นการทุบตีและjobs -pส่งออก PID เท่านั้น ฉันเพิ่งเรียนรู้ว่า zsh ไม่สอดคล้องกับ POSIX อย่างสมบูรณ์
Fanchen Bao

0

ดูเหมือนว่าjobs -p | xargs killจะทำงานได้ดี แต่ก็สร้างเอาต์พุตที่ไม่ต้องการไปป์ไลน์เพื่อฆ่า ที่นี่ฉันกำลังจัดกลุ่มผลลัพธ์ของjobs -pโดยมี / ไม่มีตัวอักษร + หรือ -

function killjobs() {
    JOBS=$(jobs -p)
    echo $JOBS | grep -v "+\|-"| awk '{print $2}' | xargs kill -9
    echo $JOBS | grep "+\|-"| awk '{print $3}' | xargs kill -9
}

และต่อมาคุณก็สามารถโทร killjobs

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