แทร็บ 'Ctrl + c' สำหรับสคริปต์ทุบตี แต่ไม่เปิดสำหรับกระบวนการในสคริปต์นี้


11

ฉันพยายามที่จะมีโปรแกรมแบบโต้ตอบในสคริปต์ทุบตี:

my_program

และฉันต้องการปิดด้วย 'Ctrl + c' แต่เมื่อฉันทำมันสคริปต์ของฉันก็ปิดเช่นกัน

ฉันรู้เกี่ยวกับ

trap '' 2
my_program
trap 2

แต่ในกรณีนี้ฉันไม่สามารถปิดmy_programด้วย Ctrl + c

คุณมีความคิดวิธีการอนุญาตให้ Ctrl + c ในโปรแกรม แต่ไม่ปิดสคริปต์ทำงานหรือไม่

แก้ไข: เพิ่มตัวอย่าง

#!/bin/bash
my_program
my_program2

ถ้าฉันใช้ Ctrl + C เพื่อใกล้my_program, my_program2ไม่เคยดำเนินการเพราะสคริปต์ทั้งหมดจะออก

คำตอบ:


13

คุณควรใช้trap true 2หรือแทนtrap : 2 trap '' 2นั่นคือสิ่งที่ "help trap" ใน bash shell พูดถึงมัน:

ถ้าหาเรื่องเป็นสตริงแต่ละ SIGNAL_SPEC ถูกละเว้นจากเปลือกและคำสั่งที่มันจะเรียก

ตัวอย่าง:

$ cat /tmp/test
#! /bin/sh
trap : INT
cat
echo first cat killed
cat
echo second cat killed
echo done
$ /tmp/test
   <press control-C>
^Cfirst cat killed
   <press control-C>
^Csecond cat killed
done

2
ในtailครั้งต่อไปแทนที่จะฆ่าแมว
kubanczyk

12

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

#!/bin/bash
# make the shell (and its children) ignore SIGINT
trap '' INT
.
.
.
# but this child won't ignore SIGINT
(trap - INT; my_program)
# the rest of the script is still ignoring SIGINT
.
.
.

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

ฉันเดาว่าคุณสามารถexec my_programใช้ subshell เพื่อให้มีประสิทธิภาพมากขึ้นเล็กน้อย
Toby Speight

@R .. นั่นไม่ใช่เปลือกเฉพาะ - ถ้าคุณตั้งสัญญาณเป็น SIG_IGN (นั่นคือสิ่งที่กับดักกับสตริงว่างกำลังทำอยู่) สถานะนั้นจะถูกสืบทอดผ่าน exec () ยกเว้น SIGCHLD นั่นเป็นพฤติกรรมที่ได้รับคำสั่งจาก POSIX ดูคำตอบสำหรับstackoverflow.com/questions/32708086//
mosvy

@mosvy: ฉันไม่เห็นความคิดเห็นของฉันที่คุณไม่เห็นด้วย ประเด็นทั้งหมดของฉันคือ "หน้ากาก / ไม่สนใจก่อนส้อมเปิดโปง / unignore ในเด็กก่อน exec" เป็นหลักการทั่วไปที่มีประโยชน์ที่จะรู้นอกบริบทของการเขียนโปรแกรมเปลือกเพียง
. GitHub หยุดช่วยน้ำแข็ง

1
นี่เป็นคำตอบที่มีประโยชน์มาก ในฐานะผู้ใช้ Linux ที่มีประสบการณ์ฉันสามารถพูดได้ว่าฉันไม่เคยได้ยินเรื่องนี้มาก่อน มันมีการใช้งานค่อนข้างมาก ... คุณได้ upvote และบุ๊คมาร์คของฉัน
Dev

-1


เมื่อคุณใช้Crtl+ Cคุณขัดจังหวะโปรแกรม (" ฆ่า ")
สิ่งที่คุณกำลังมองหาคือการระงับโปรแกรมของคุณ (" หยุด " ชั่วคราว ) สำหรับนี้คุณสามารถใช้+Crtl เมื่อโปรแกรมถูกหยุดชั่วคราวคุณสามารถดูได้โดยใช้ ตัวอย่างเช่น: ที่ นี่ฉันมีเพียงงานเดียวงาน # 1 แต่อาจมีมากกว่าหนึ่งงาน - แต่ละงานมีหมายเลขของตัวเอง คุณสามารถควบคุมคุณระงับกระบวนการโดยใช้หมายเลขของคำสั่งเช่น, และ จะเริ่มต้นทำงานใหม่อันดับ 1 ในแอ๊กรัมรอบจะเริ่มต้นงานอันดับ 1 ในแร่Z
jobs
[1]+ Stopped ./foobar

bgfgkill
bg %1
fg %1g round
kill %1จะฆ่างาน # 1
โปรดทราบว่าคุณสามารถใช้bgและfgไม่มีข้อโต้แย้งหากคุณมีงานที่ใช้งานเพียงงานเดียว


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