Bash 有没有办法只终止一系列命令中的第一个命令?
当使用tmux时,我使用等待特性,在该特性中,tmux会话将在命令完成后收到通知。但是,有时我希望在不终止等待部分的情况下终止命令序列,这样原始脚本就不会挂起 基本上,如果我有:Bash 有没有办法只终止一系列命令中的第一个命令?,bash,shell,tmux,Bash,Shell,Tmux,当使用tmux时,我使用等待特性,在该特性中,tmux会话将在命令完成后收到通知。但是,有时我希望在不终止等待部分的情况下终止命令序列,这样原始脚本就不会挂起 基本上,如果我有: command 1; command 2 点击Ctrl-C会同时退出这两个命令,我主要想退出命令1,但继续执行命令2(这是等待确认以便脚本不会挂起) 有办法吗 我已经试过了: command 1 || command 2 但是Ctrl-C仍然同时存在。您可以尝试在后台运行命令1并捕获Ctrl+C发送的信号 #/bi
command 1; command 2
点击Ctrl-C会同时退出这两个命令,我主要想退出命令1,但继续执行命令2(这是等待确认以便脚本不会挂起)
有办法吗
我已经试过了:
command 1 || command 2
但是Ctrl-C仍然同时存在。您可以尝试在后台运行命令1并捕获Ctrl+C发送的信号
#/bin/bash
(命令1)在后台运行c1
pid=$!#存储子shell的PID
陷阱“kill-INT$pid”SIGINT使Ctrl+C终止后台进程
等待#等待c1的完成
trap-SIGINT#恢复Ctrl+C的默认行为
命令2运行第二个命令
要让命令退出但脚本在Ctrl-C上继续,只需设置一个no op sigint陷阱:
trap "true" INT
sleep 30
echo "Continuing"
如果要恢复终止脚本的行为,可以使用
trap-INT
以下命令应确保,如果按ctrl-C、command1以及它可能具有的任何子进程,则可以获得SIGINT
#!/bin/bash
# Use "set -m" to test if "-m" option is currently set
# If set, this will ensure that any subprocesses are started
# as process group leaders (we'll need this later)
if [ -z "${-//[^m]/}" ] # -m option not already set
then
set -m
setm=1
else
setm=0
fi
# launch the command and capture its pid
command1 &
pid=$!
# install a trap so that if SIGINT is received, then every
# process in the process group of which command1 is leader
# is sent a SIGINT (note the "-" before $pid)
trap "kill -INT -$pid" SIGINT
# wait for command1 to finish (ignoring any other previously launched
# children that finish meanwhile)
wait $pid
# undo "set -m" setting as appropriate
if [ $setm -eq 1 ]
then
set +m
fi
# cancel the trap
trap - SIGINT
# and carry on
command2
例如,如果command1
本身就是一个shell脚本,那么该shell脚本运行的命令应该正确终止
使用-m
选项的一个轻微副作用是,如果按ctrl-C,则会收到如下消息:
[1]+ Interrupt command1
这可能会推迟到下一个命令完成之后。您可以在
command2
(例如sleep 0.1
)之前插入一个短睡眠,以便在睡眠结束时(command2运行之前)而不是在command2之后发送任何此类通知。这就是我的想法。带有子shell的一行程序不会捕获中断。很好。退出后台命令是否将状态设置为false?我依靠读取状态来决定是否使用脚本中的下一个操作移动。wait
返回它等待的命令的退出状态。但是如果你用Ctrl+C终止它,它将返回130
(128+2表示SIGINT)。单独的行表示第二个不会等到第一个完成。这是我正在等待通知的行动。