陷阱'Ctrl + c'用于bash脚本,但不用于在该脚本中打开进程


11

我试图在bash脚本中有一个交互式程序:

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_programmy_program2则不会执行,因为会退出整个脚本。

Answers:


13

您应该使用trap true 2trap : 2代替trap '' 2。这就是bash shell中的“帮助陷阱”所说的:

如果ARG为空字符串,则外壳程序及其调用的命令将忽略每个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命令-作为其动作参数,可以将陷阱重置为其默认值。如果在subshel​​l中执行此操作,则不会影响父shell中的陷阱。在脚本中,您可以为需要使用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
尽管对于外壳而言,可接受的答案可能更好,更规范,但这本身就是一个很好的答案,因为它引入了有关如何安全地进行这种信号屏蔽/忽略的一般原理(不是特定于外壳的)。
R .. GitHub停止帮助ICE,

我想您可以exec my_program在子外壳中提高效率。
Toby Speight

@R ..绝对不是特定于Shell的-如果您将信号设置为SIG_IGN(这是使用空字符串进行的陷阱),那么该状态将通过exec()继承,SIGCHLD除外。这是POSIX强制的行为。另请参见stackoverflow.com/questions/32708086/…
mosvy

@mosvy:我看不到您不同意我的评论的哪一部分。我的全部观点是“在fork之前屏蔽/忽略,在exec之前在子对象中取消屏蔽/忽略”是一个通用原理,对于仅在Shell编程环境之外的知识很有用。
R .. GitHub停止帮助ICE

1
这是一个非常有用的答案。作为经验丰富的Linux用户,我可以说我从未听说过。它有很多用途...您得到了我的赞誉和我的书签。
开发

-1


当使用Crtl+时C,将中断程序(“ 杀死 ”程序)。
您可能正在寻找的是暂停程序(“ 暂停 ”程序)。为此,您可以使用Crtl+ Z
程序暂停后,您可以使用查看它jobs。例如:
[1]+ Stopped ./foobar
在这里,我只有一个工作,即工作#1,但是可以有多个-每个工作都有自己的编号。
您可以使用多个命令,例如控制您挂起的进程bgfgkill
bg %1将启动作业#1中的b ACK
fg %1将重新启动作业#1的˚Fg round
kill %1将杀死作业1。
请注意,如果只有一个活动作业,则可以使用bg并且fg不带参数。


谢谢,但是不,我想做Ctrl + c。
鲍勃·迪伦(Bob dylan)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.