ยุติกระบวนการพื้นหลังทั้งหมด


10

ฉันมีStoppedกระบวนการพื้นหลังเล็กน้อย

kill $(jobs -p)และkill `jobs -p`ไม่มีผลกระทบ

kill %1, kill %2ฯลฯ ประสบความสำเร็จในการยกเลิกแต่ละกระบวนการ

ฉันจะฆ่าทุกกระบวนการพื้นหลังด้วยคำสั่งเดียวได้อย่างไร

นอกจากนี้ทำไมสองคำสั่งแรกไม่ทำงานสำหรับฉัน

ฉันใช้ Linux Mint 15, 64 บิต

คำตอบ:


10

เมื่อพวกเขากำลังทำงาน

ดูเหมือนว่าคุณก็สามารถทำเช่นนี้กับและการส่งออกของkilljobs -p

ตัวอย่าง

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

ตอนนี้ฉันมีงานปลอม 3 งานที่ทำงานอยู่

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

ฆ่าพวกเขาทั้งหมดเช่น:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

ยืนยันว่าพวกเขาทั้งหมดหายไป

$ jobs
$

เมื่อพวกเขาหยุด

หากคุณมีงานที่หยุดไม่ทำงานคุณทำเช่นนี้แทน

ตัวอย่าง

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

ตกลงเพื่อที่ไม่ได้ฆ่าพวกเขา แต่นั่นเป็นเพราะกระบวนการฆ่าสัญญาณไม่สามารถจัดการได้ด้วยตัวเองมันหยุด ดังนั้นบอกให้ระบบปฏิบัติการทำการฆ่าแทน นั่นคือสิ่งที่มี-9ไว้สำหรับ

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

มันดีกว่า.

$ jobs
$ 

เมื่อบางคนทำงานและบางคนก็หยุด

หากคุณมีกระบวนการหลายอย่างที่บางกระบวนการหยุดทำงานและบางกระบวนการกำลังทำงานอยู่คุณสามารถทำkillตามด้วย a kill -9ก่อน

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

ขยายเวลาเล็กน้อยหากคุณต้องการมากขึ้นเพื่อให้กระบวนการหยุดตนเองก่อน

สัญญาณ

ทั้ง HUP (-1) หรือ SIGTERM (-15) ที่จะฆ่าจะสำเร็จ แต่ทำไม นั่นเป็นเพราะสัญญาณเหล่านี้มีความอ่อนโยนกว่าในแง่ที่ว่าพวกเขากำลังบอกให้แอปพลิเคชั่นยุติการทำงาน แต่เนื่องจากแอปพลิเคชันอยู่ในสถานะหยุดทำงานจึงไม่สามารถประมวลผลสัญญาณเหล่านี้ได้ ดังนั้นคุณเพียงแค่ใช้หลักสูตร SIGKILL (-9)

คุณสามารถมองเห็นสัญญาณทั้งหมดที่ให้กับkillkill -l

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

man 7 signalหากคุณต้องการที่จะเรียนรู้มากยิ่งขึ้นเกี่ยวกับสัญญาณต่างๆผมขอแนะนำให้หนึ่งไปดูที่หน้าสัญญาณมนุษย์


เหตุใดเราจึงมี+สัญลักษณ์สำหรับกระบวนการแรกและ-สัญลักษณ์สำหรับกระบวนการที่สองและไม่มีสัญลักษณ์ในกระบวนการที่สาม
Ramesh

ฉันได้ผลลัพธ์เช่นเดียวกับคุณ อย่างไรก็ตามฉันต้องการterminateแทนkillเพราะฉันอ่านแล้วว่าปลอดภัยกว่า ฉันพยายามkill -15 $(jobs -p)แต่นั่นก็ไม่มีผล ฉันเดาว่ากระบวนการที่หยุดสามารถถูกฆ่าได้ แต่จากนั้นอีกครั้งkill %numberจะยุติ (หยุด) กระบวนการที่หยุดทำงาน
user49888

@Ramesh +และ-เป็นเพียงกระบวนการสุดท้ายที่ฉันสัมผัสเมื่อฉันตั้งค่าตัวอย่าง +หมายความว่าคำสั่งใด ๆ ที่ไม่ชัดเจนรวมถึง%#จะทำหน้าที่ในคำสั่งที่ เครื่องหมายขีดกลาง ( -) เป็นคำสั่งที่ 2 ถึงคำสั่งสุดท้ายที่ฉันสัมผัส
slm

@ user49888 - สิ่งที่kill -9 .. ควรจะได้ผล กระบวนการคืออะไร? พวกเขาจะตายหรือกระบวนการกำพร้า?
slm

1
@ user49888 - ใช่หากกระบวนการอยู่ตรงกลางของบางสิ่งบางอย่างมันไม่ได้รับโอกาสในการทำความสะอาดใด ๆ ก่อนที่จะถูกยกเลิก
slm

2

คุณสามารถลองสิ่งนี้

for x in `jobs -p`; do kill -9 $x; done

อย่างไรก็ตามหากคุณต้องการยุติกระบวนการคุณสามารถออกคำสั่งเป็น

for x in `jobs -p`; do kill -15 $x; done

จากหน้าคำสั่งของWikiKill

กระบวนการสามารถส่งสัญญาณSIGTERM ได้สี่วิธี (ID กระบวนการคือ '1234' ในกรณีนี้):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

กระบวนการสามารถส่งสัญญาณSIGKILL ได้สามวิธี:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

ตามที่อธิบายไว้ในนี้คำตอบนี้เป็นความแตกต่างระหว่างยุติและฆ่า

สัญญาณยุติSIGTERMเป็นสัญญาณที่สามารถดักจับในโปรแกรม บ่อยครั้งที่กระบวนการที่ตั้งใจให้ทำงานในพื้นหลังจะจับสัญญาณนี้และเริ่มกระบวนการปิดเครื่องทำให้เกิดการออกใหม่ทั้งหมด สัญญาณ kill, SIGKILLไม่สามารถดักจับได้ เมื่อสิ่งนี้ถูกส่งไปยังกระบวนการมันจะส่งผลให้เกิดการยกเลิกอย่างกระทันหันของโปรแกรมนั้น

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


มันทำkillทุกกระบวนการพื้นหลัง อย่างไรก็ตามมีวิธีใดที่terminateพวกเขาแทนเนื่องจากฉันเชื่อว่าปลอดภัยกว่าหรือไม่
user49888

หากคุณต้องการยุติคุณสามารถใช้-15ในคำสั่ง kill
Ramesh

-15จะไม่ทำงานที่นี่เช่นกัน ดูของฉัน A.
slm

@Ramesh - 2 ย่อหน้าสุดท้ายไม่ถูกต้อง SIGTERM ไม่ถูกส่ง (ไม่ใช่เริ่มแรก) กระบวนการพยายามหยุดก่อนผ่านทางสคริปต์หยุด / เริ่มบริการ หากเป็นกรณีที่ 9 ถูกส่งไปยังกระบวนการแล้วด้วยกระบวนการหยุดในตัวอย่างของ OP ในตัวอย่างkill -9ของฉันจะไม่ทำงาน
slm

1

ตกลงเล่นกับสิ่งนี้ฉันเห็นว่าเมื่อคุณฆ่างานที่หยุด (ซึ่งการดำเนินการถูกหยุดชั่วคราว แต่ไม่สิ้นสุด) จากนั้นจะไม่เสร็จจนกว่าจะถูกนำเข้าสู่เบื้องหน้า โปรแกรมมักจะหยุดทำงานโดยการกดCtrl- Zที่เทอร์มินัล อาคารส่วนใหญ่ส่งSIGSTOPในกรณีนี้ แต่แน่นอนนอกจากนี้ยังมีวิธีการอื่น ๆ ในการส่งมันดังกล่าวเช่นเดียวกับหรือkill -STOPkill -19

มันเป็นพฤติกรรมปกติสำหรับโปรแกรมที่จะไม่เสร็จสิ้นทันทีตั้งแต่โปรแกรมจะต้องมีการทำงานในการประมวลผลเริ่มต้นสัญญาณที่ส่งมาจากSIGTERM killยิ่งไปกว่านั้นบางครั้งหลังจากbashส่งSIGTERMไปยังกระบวนการพื้นหลังมันก็หยุดลงอย่างใด (แม้ว่าSIGTERMจะยังคงค้างอยู่)

วิธีที่ปลอดภัยที่สุดในการทำให้งานทั้งหมดให้เสร็จสิ้น ( โดยไม่ต้องหันไปหาkill -9) คือการส่งSIGTERMแบบปกติkillก่อนจากนั้นจึงส่งSIGCONTไปยังงานที่เหลือเช่น:

kill $(jobs -p)
kill -18 $(jobs -p)

SIGCONT( 18เป็นจำนวนสัญญาณ) จะนำงานหยุดใด ๆ ลงในเบื้องหน้าเพื่อให้พวกเขาสามารถดำเนินการSIGTERMตามที่พวกเขาตามปกติ

หากโปรแกรมทั้งหมดไม่เสร็จสิ้นสิ่งนี้แสดงว่ามีสัญญาณอื่น ๆ อีกสองสามอย่างที่คุณสามารถลองทำตามปกติให้เสร็จสิ้นกระบวนการก่อนที่จะหันไปkill -9ใช้ คนแรกที่ผมแนะนำคือSIGHUPตั้งแต่โปรแกรมจำนวนมากที่มักจะปิดกั้นสัญญาณการเลิกจ้างอื่น ๆ SIGHUPที่ตอบสนองต่อการ สิ่งนี้มักจะถูกส่งเมื่อเทอร์มินัลการควบคุมปิดลงโดยเฉพาะอย่างยิ่งมันจะถูกส่งเมื่อsshเซสชันที่มีการttyเสร็จสิ้น โปรแกรมแบบโต้ตอบจำนวนมากเช่น shells จะไม่ตอบสนองต่อสัญญาณการเลิกจ้างอื่น ๆ แต่จะตอบสนองต่อสิ่งนี้เนื่องจากมันจะเป็นปัญหาสำหรับพวกเขาที่จะทำงานต่อหลังจากsshเซสชันเสร็จสิ้น (หรือหลังจากที่เทอร์มินัลการควบคุมปิด) หากต้องการลองสิ่งนี้คุณสามารถทำได้

kill -1 $(jobs -p)
kill -18 $(jobs -p)

แน่นอนว่าคุณต้องตรวจสอบให้แน่ใจว่าโปรแกรมนั้นไม่หยุดทำงานเพื่อให้สามารถประมวลผลสัญญาณได้ สัญญาณการเลิกจ้างอื่น ๆ ที่คุณสามารถลองได้คือSIGINT( kill -2) และSIGQUIT( kill -3) แต่แน่นอนว่าประโยชน์ของการลองเต็มรูปแบบลดน้อยลงและอาจนำไปสู่การหลีกเลี่ยงไม่ได้SIGKILL(aka kill -9)


ถ้าคุณทำman signalคุณจะได้รับวัสดุอ้างอิงเพื่อสำรอง
slm

นี่เป็นรูปแบบที่นุ่มนวลกว่าสิ่งที่ A ของฉันแนะนำ มีบางครั้งที่ฉันเคยพบเจอในอดีตที่ซึ่งสิ่งนี้ยังคงไม่หมดจดอย่างสมบูรณ์ดังนั้นหากคุณกำลังทำสิ่งนี้จากสคริปต์kill -9 ..วิธีการจะทำงานในกรณีส่วนใหญ่ บางครั้งสิ่งนี้จะทำให้กระบวนการหยุดทำงานดังนั้นจะล้มเหลวมากขึ้น มันเป็นการแลกเปลี่ยนที่คุณต้องตัดสินใจ ดีกว่าที่จะส่งมอบอย่างหนักและฆ่าทุกสิ่งเสี่ยงต่อข้อมูล / การล้างข้อมูลเมื่อเทียบกับการล้างข้อมูลที่นุ่มนวลกว่า แต่ต้องทำการวิเคราะห์เพิ่มเติมเนื่องจากการสังหารของคุณจะรุนแรงขึ้นเรื่อย ๆ
slm

@slm คุณควรหลีกเลี่ยงkill -9เมื่อใดก็ตามที่ทำได้เนื่องจากเพียงแค่ดึงปลั๊กโดยไม่ให้โปรแกรมมีโอกาสทำความสะอาดอย่างถูกต้อง ฉันจะอัปเดตด้วยทางเลือกอื่น
แกรม

อย่างที่ฉันบอกว่ารสชาติของคุณนิ่มกว่าที่ฉันแนะนำไว้มันลงมากับสิ่งที่คุณพยายามทำและเต็มใจที่จะทนต่อมุมมองที่มีความเสี่ยง ฉันใช้วิธีการของคุณเช่นเดียวกับของฉัน พวกเขาทั้งคู่ถูกต้อง IMO นอกจากนี้ยังมีkill ..; sleep <time>; kill -18 ..; หลับ <เวลา>; ฆ่า -9 ... . Basically working up to the -9`
slm

@slm kill -18เป็นสิ่งที่ควรใช้เนื่องจากเป็นเรื่องปกติที่จะหยุดงาน (และในบางกรณีดูเหมือนว่าbashจะหยุดทำงานก่อนที่จะส่งSIGTERM) ตามที่เพิ่มไว้ข้างต้นSIGHUPก็คุ้มค่าที่จะลองเพราะหลาย ๆ โปรแกรมที่ไม่ตอบสนองต่อผู้อื่นจะตอบสนองต่อสิ่งนี้ (ลองใช้กับเชลล์) นอกเหนือจากนั้นแม้ว่าใช่มันไม่คุ้มค่าเพราะSIGKILLอาจหลีกเลี่ยงไม่ได้
แกรม

0

สิ่งนี้จะยกเลิกงานทั้งหมดในเชลล์ปัจจุบันของคุณทีละ:

while kill %; do :; done

คำอธิบาย: %หมายถึงงานล่าสุดในรายการดังนั้นมันจะวนซ้ำจนกว่าจะkillส่งคืนค่าที่ไม่เป็นศูนย์ซึ่งจะหมายความว่าไม่มีงานที่จะยกเลิกอีกต่อไป

อีกวิธีหนึ่งที่อาจจะเป็นครั้งแรกที่ส่งSIGTERMแล้วเพื่อให้งานของคุณสามารถดำเนินต่อไปและสิ่งแรกที่พวกเขาจะทำคือการได้รับของคุณSIGCONTSIGTERM

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(ด้วยเหตุผลบางอย่างในตัวkillเป็นเรื่องแปลกดังนั้นฉันจึงใช้ภายนอกที่นี่)

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