直接跳进去:
while true; do
#--- MENU LOGIC HERE, stick response in $MENUEXIT
#----Deal with responses here
if [ $S1 == $MENUEXIT ];
then
tail -f /path-to-file
else
sleep 2
fi
done
Run Code Online (Sandbox Code Playgroud)
我尽量保持简单,如果您需要更多,请告诉我。
基本上,我在循环中粘贴菜单,因此,如果用户输入不正确或命令完成,则意味着重新显示菜单。
它工作正常,直到我添加了 tail 命令。
如果我从菜单中选择 tail 选项,则 tail 命令可以正常启动 - 但是,如果我点击Ctrl+ C,我希望 tail 终止并显示菜单,但它同时终止 tail和脚本。
我尝试了各种方法,例如继续/陷阱等,但是,我遇到了砖墙,需要一些帮助吗?!
当您从终端发送类似SIGINT( CtrlC) 或SIGSTOP( CtrlZ)的信号时,该信号将被发送到前台进程组。也就是说,由前台作业(您的脚本)及其在前台(命令)中拥有的任何子进程组成的组。这会导致所有这些进程退出(或通过处理信号来执行它们所做的任何事情)。您可以通过使用以下命令发送信号来测试差异:tailkill
在一个终端中,执行此脚本(我test在以下命令中调用它):
#! /bin/bash
while true
do
if [[ $1 = a ]]
then
yes
else
echo no
sleep 2
fi
done
Run Code Online (Sandbox Code Playgroud)
在另一个中,执行这些命令:
pstree -ps $(pgrep -f test)
pkill -f test
pstree -ps $(pgrep -f yes)
Run Code Online (Sandbox Code Playgroud)
命令的输出将是这样的:
init(1)???lightdm(1032)???lightdm(1154)???init(1173)???x-terminal-emul(17009)???bash(24262)???test.sh(24996)???yes(24997)
# No output for pkill
init(1)???lightdm(1032)???lightdm(1154)???init(1173)???yes(24997)
Run Code Online (Sandbox Code Playgroud)
(实际数字和程序可能会有所不同,但第一个 init 将始终具有pid 1。)
如您所见,该yes命令没有被终止,而是init因为其父级被终止而被附加。它仍然y在第一个终端上愉快地打印s 。所以用pkill -f yes. 现在重复实验,只做一处改动。而不是pkill -f test,做:
kill -INT -25165
# Use the pid of test.sh given in parentheses in the output of pstree
# instead of 25165
Run Code Online (Sandbox Code Playgroud)
注意领先的-. 在 Linux 中,对于kill命令,-25165是进程组,其领导者为 pid 25165。因此,该命令相当于从终端发送中断。
当然,确切的行为取决于 TTY 的配置、登录 shell 等。这就是我的理解。进一步阅读:
我建议:
tail到后台一个例子:
#! /bin/bash
kill_jobs ()
{
kill %1
}
while true
do
if [[ $1 = "a" ]]
then
trap kill_jobs INT
tail -f /var/log/syslog &
wait %%
shift #You don't need to shift, I just didn't want loop tail on this example
trap - INT
else
echo some output
sleep 2
fi
done
Run Code Online (Sandbox Code Playgroud)
这可以变得非常强大,通过使用不同的函数进行陷印,并且每个函数都做自己的清理工作。