在Linux上,是否有可能以某种方式禁用外部程序的信令...即,不修改其源代码?
语境:
我在Linux上的bash脚本中调用了一个C(也是一个Java)程序.我不希望我的bash脚本和脚本启动的其他程序(作为前台进程)中断.
虽然我可以用...
trap '' INT
Run Code Online (Sandbox Code Playgroud)
...在我的bash脚本中禁用Ctrl C信号,这仅在程序控件恰好在bash代码中时才有效.也就是说,如果我在C程序运行时按下Ctrl C,C程序会被中断并退出!这个C程序正在进行一些关键操作,因此我不希望它被中断.我无法访问此C程序的源代码,因此C程序内的信号处理是不可能的.
#!/bin/bash
trap 'echo You pressed Ctrl C' INT
# A C program to emulate a real-world, long-running program,
# which I don't want to be interrupted, and for which I
# don't have the source code!
#
# File: y.c
# To build: gcc -o y y.c
#
# #include <stdio.h>
# int main(int argc, char *argv[]) {
# printf("Performing a critical operation...\n");
# for(;;); // …Run Code Online (Sandbox Code Playgroud) 我一直在寻找各地,我开始相信除了拥有全局变量之外别无他法,但我相信stackoverflow.com中的大师可能能够帮助我:
在bash中有没有办法通过向它传递参数来捕获函数?
例如,trap <function_name> <arg_1> <arg_2> SIGINT?
语境:
我有一个bash脚本,其中包含一个子shell和一个EXIT伪信号的陷阱,并且它没有正确捕获中断期间的中断rsync.这是一个例子:
#!/bin/bash
logfile=/path/to/file;
directory1=/path/to/dir
directory2=/path/to/dir
cleanup () {
echo "Cleaning up!"
#do stuff
trap - EXIT
}
trap '{
(cleanup;) | 2>&1 tee -a $logfile
}' EXIT
(
#main script logic, including the following lines:
(exec sleep 10;);
(exec rsync --progress -av --delete $directory1 /var/tmp/$directory2;);
) | 2>&1 tee -a $logfile
trap - EXIT #just in case cleanup isn't called for some reason
Run Code Online (Sandbox Code Playgroud)
脚本的想法是这样的:大多数重要的逻辑运行在子shell中,通过管道传输tee到日志文件,因此我不必tee将主逻辑的每一行都记录下来.每当子shell结束,或脚本因任何原因停止(EXIT伪信号应捕获所有这些情况),陷阱将拦截它并运行该cleanup()函数,然后删除陷阱.该rsync和sleep命令(睡眠只是一个例子)通过运行exec,以防止僵尸进程的创建,如果我杀了父脚本,而他们正在运行,并且每个潜在的,长期运行的命令被包裹在自己的子shell,这样,当exec …
我有一堆通用的清理代码需要在某个bash脚本退出时完成,无论它是正常退出还是被中断.我想我会使用trap "..." EXIT伪信号来实现这一点.
除了通用的清理工作之外,还有一个特定的清理工作,只有在脚本正常完成时才能完成.我想我可以通过让'trap'块测试一个变量来触发这个,就像这样:
#!/bin/bash
done=false;
trap "{
#generic cleanup code goes here.
if $done
then
#cleanup to be done only on completion goes here.
echo Test;
fi
}" EXIT
#main script goes here
done=true;
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.运行以下代码永远不会回显"测试".之后添加显式exit调用done=true;不会更改任何内容.我错过了什么?
干杯!
我有一个bash脚本,可以安装和卸载一个设备,在其间执行一些读取操作.由于设备非常慢,脚本需要大约15秒才能完成(安装至少需要5-6秒).由于安装此设备可能会导致其他问题,我不希望此脚本被中断.
话虽如此,我可以正确处理SIGINT(Ctrl + c),但是当我尝试处理SIGTSTP(Ctrl + z)时,脚本会冻结.这意味着信号被捕获但处理程序不运行.
#!/bin/sh
cleanup()
{
# Don't worry about unmounting yet. Just checking if trap works.
echo "Quitting..." > /dev/tty
exit 0
}
trap 'cleanup' SIGTSTP
...
Run Code Online (Sandbox Code Playgroud)
我手动必须将KILL信号发送到进程.知道为什么会发生这种情况以及如何解决这个问题吗?
这是myscript.sh:
#!/bin/bash
function mytrap {
echo "Trapped!"
}
trap mytrap EXIT
exit 3
Run Code Online (Sandbox Code Playgroud)
当我运行它:
> ./myscript.sh
echo $?
3
Run Code Online (Sandbox Code Playgroud)
为什么脚本的退出代码与陷阱的退出代码相同而没有它?通常,函数隐式返回最后执行的命令的退出代码.在这种情况下:
mytrap能回归0mytrap是最后执行的函数,脚本应返回0为什么不是这样?我的想法错在哪里?
我编写了一个 bash 脚本来对我的系统进行一些测试。测试在后台并行运行。测试可能需要很长时间,有时我可能希望中途中止测试。
如果我 Control+C 那么它会中止父脚本,但让各个子脚本继续运行。我希望这样我就可以按 Control+C 或其他方式退出,然后杀死在后台运行的所有子进程。如果我直接从终端运行后台作业,我有一些代码可以完成这项工作,但它在我的脚本中不起作用。
我有一个最小的工作示例。
我尝试过将 trap 与 pgrep -P $$ 结合使用。
#!/bin/bash
trap 'kill -n 2 $(pgrep -P $$)' 2
sleep 10 &
wait
Run Code Online (Sandbox Code Playgroud)
我希望点击 control+c (SIGINT) 会杀死脚本启动的所有内容,但它实际上说:
./breakTest.sh: line 1: kill: (3220) - No such process
Run Code Online (Sandbox Code Playgroud)
这个数字发生了变化,但似乎不适用于任何正在运行的进程,所以我不知道它来自哪里。
我想如果 trap 命令的内容在 trap 命令发生的地方被评估,那么它可能会解释结果。3220 pid 可能用于 pgrep 本身。
我希望能在这里得到一些见解
谢谢
我已经看过监视程序,无论是在脚本中,使用'ps'或'服务状态(在Linux上)'定期检查进程状态,还是在C/C++中分析并等待进程...
我想知道是否有可能使用带有陷阱的bash并在收到SIGCLD时重新启动子进程?
我已经在RedHat Linux上测试了一个带有以下想法的基本套件(当然它没有用......)
#!/bin/bash
set -o monitor # can someone explain this? discussion on Internet say this is needed
trap startProcess SIGCHLD
startProcess() {
/path/to/another/bash/script.sh & # the one to restart
while [ 1 ]
do
sleep 60
done
}
startProcess
Run Code Online (Sandbox Code Playgroud)
什么bash脚本启动只是睡了几秒钟然后退出.
观察到几个问题:
......无论如何,这根本不起作用.我不得不说我对这个话题知之甚少.有人可以建议或提供一些有用的例子吗?是否有这样的脚本?
那么在bash中使用等待怎么样?
谢谢
以下是问题演示的最小代码:http: //pastebin.com/5TXDpSh5
#!/bin/bash
set -e
set -o pipefail
function echoTraps() {
echo "= on start:"
trap -p
trap -- 'echo func-EXIT' EXIT
echo "= after set new:"
trap -p
# we can ensure after script done - file '/tmp/tmp.txt' was not created
trap -- 'echo SIG 1>/tmp/tmp.txt' SIGPIPE SIGHUP SIGINT SIGQUIT SIGTERM
}
trap -- 'echo main-EXIT1' EXIT
echo "===== subshell trap"
( echoTraps; )
echo "===== pipe trap"
echoTraps | cat
echo "===== done everything"
Run Code Online (Sandbox Code Playgroud)
===== …Run Code Online (Sandbox Code Playgroud) 我试图将一个文件复制到其他目录,并在调用中断时收到错误消息.
剧本 :
#!/bin/bash
PATH=~/MkFile/
exitfn () {
trap SIGINT # Resore signal handling for SIGINT
echo ; echo 'Called ctrl + c ' # Growl at user,
cp ./BKP/temp.txt $PATH/backup.txt
exit # then exit script.
}
trap "exitfn" INT # Set up SIGINT trap to call function.ii
read -p "What? "
echo "You said: $REPLY"
# reset all traps##
trap - 0 SIGINT
Run Code Online (Sandbox Code Playgroud)
输出:
./signal.sh
What? ^C
Called ctrl + c
./signal.sh: line 9: cp: command not found
Run Code Online (Sandbox Code Playgroud)
你知道这个剧本有什么问题吗?