การยกเลิกสคริปต์เชลล์ bash ที่รันในพื้นหลัง


16

ฉันมักจะใช้bashเชลล์สคริปต์เพื่อรันคำสั่งง่าย ๆ สำหรับไฟล์ที่แตกต่างกัน ตัวอย่างเช่นสมมติว่าฉันมีดังต่อไปนี้bashเชลล์สคริปต์เรียกscript.shว่ารันโปรแกรม / คำสั่งfooสามไฟล์ข้อความ"a.txt", "b.txt", "c.txt":

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

นอกจากนี้สมมติว่าfoo $strname".txt"ช้าดังนั้นการเรียกใช้สคริปต์จะใช้เวลานาน (ตัวอย่างเช่นชั่วโมงหรือวัน) ด้วยเหตุนี้ฉันต้องการใช้nohupเพื่อให้การดำเนินการต่อไปแม้ว่าเทอร์มินัลจะปิดหรือตัดการเชื่อมต่อ ฉันต้องการให้สคริปต์ไปที่พื้นหลังทันทีดังนั้นฉันจะใช้&โอเปอเรเตอร์ ดังนั้นฉันจะใช้คำสั่งต่อไปนี้เพื่อโทรscript.sh:

nohup bash script.sh &

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

ปัญหาที่ฉันได้พบก็คือว่าโดยดูที่topผมเห็นเพียงที่สอดคล้องกับfoo "a.txt"ฉันสามารถยุติการfooโทรนั้นได้ แต่จากนั้นการโทรที่fooสอดคล้องกันจะ"b.txt"ได้รับการเรียกและจากนั้นฉันต้องยุติการโทรนั้นเช่นกันและต่อไปเรื่อย ๆ สำหรับไฟล์ข้อความหลายสิบหรือร้อยไฟล์ที่ระบุในforลูปมันจะกลายเป็นความเจ็บปวดที่จะยกเลิกทุก ๆไฟล์ทีละไฟล์foo! ดังนั้นฉันต้องยกเลิกเชลล์สคริปเองแทนการโทรเฉพาะที่ออกจากเชลล์สคริป

เมื่อฉันพิมพ์คำสั่ง

ps -u myusername

myusernameชื่อผู้ใช้ของฉันอยู่ที่ไหนฉันได้รับรายการกระบวนการที่ฉันใช้อยู่ bashแต่ผมเห็นสองรหัสกระบวนการที่แตกต่างกันเรียกว่า ฉันจะรู้ได้อย่างไรว่ากระบวนการเหล่านี้ถ้ามีการสอดคล้องกับการเรียกร้องเดิมของฉันnohup bash script.sh &?


@Andrew, ทั้งสองกระบวนการแสดง nohup ที่กล่าวถึงในคำสั่งหรือไม่? .... หรือคุณสามารถลอง ps -aWu Andrew และตรวจสอบว่าคุณได้รับการค้นหารายการที่มีความยาวเพียงครั้งเดียวด้วย nohup .... มันช่วยได้ไหม?
nitin

2
นอกเหนือจากข้อความของคุณแปลกประหลาด for s in a b c; do foo "$s".txt; done
tripleee

1
@NSD: ไม่nohupนานไปเมื่อคุณเปิดรายการกระบวนการเพื่อดูงานที่คุณเริ่ม คุณสามารถดูคอลัมน์ "ความดี" ในpsผลลัพธ์ แต่คำตอบที่นี่มีประโยชน์มากกว่า
tripleee

คำตอบ:


9

ตามค่าเริ่มต้นpsจะไม่แสดงพารามิเตอร์ที่โปรแกรมถูกเรียกใช้ ตัวเลือก-fและ-lทั้งสองจะแสดงสายเต็ม

ps -fu username

จะทำให้ได้ผลลัพธ์ที่ดูเหมือนว่า:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh

2
มันมีประโยชน์พอสมควร แต่ไม่ทำให้สับสนหลายกระบวนการด้วยอาร์กิวเมนต์เดียวกัน
tripleee

11

คุณมีสองทางเลือก เนื่องจากกระบวนการของคุณทำงานในพื้นหลังคุณสามารถใช้jobsเพื่อค้นหา:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

คุณยังสามารถใช้pkillเพื่อค้นหาตารางกระบวนการสำหรับการจับคู่บรรทัดคำสั่ง ได้แก่ :

pkill -f script.sh

1

psเอาท์พุท (มีเช่นps aux) ประกอบด้วยกระบวนการ ID ของผู้ปกครอง ฆ่าผู้ปกครองbashและลูก ๆ ของมันเช่นกันจะถูกยกเลิก

สำหรับการแสดงภาพ ASCII ของแผนผังกระบวนการให้ลองpstree -pกับกระบวนการพื้นหลังสองสามตัวที่ทำงานอยู่

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