- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新
我为发布的答案使用了更好的测试用例。我在这里添加了更新的测试用例,以防有人想进一步试验:
#!/bin/bash
mypts="$( tty )"
# main traps
trap "echo 'trapped SIGCHLD' >$mypts" SIGCHLD
trap "echo 'trapped SIGHUP' >$mypts" SIGHUP
trap "echo 'trapped SIGINT' >$mypts" SIGINT
trap "echo 'trapped SIGPIPE' >$mypts" SIGPIPE
trap "echo 'trapped SIGSEGV' >$mypts" SIGSEGV
trap "echo 'trapped SIGSYS' >$mypts" SIGSYS
trap "echo 'trapped SIGTERM' >$mypts" SIGTERM
function h4 {
# function traps
# these mask the main traps
#trap "echo 'trapped h4 SIGCHLD'" SIGCHLD
#trap "echo 'trapped h4 SIGHUP'" SIGHUP
#trap "echo 'trapped h4 SIGINT'" SIGINT
#trap "echo 'trapped h4 SIGPIPE'" SIGPIPE
#trap "echo 'trapped h4 SIGSEGV'" SIGSEGV
#trap "echo 'trapped h4 SIGSYS'" SIGSYS
#trap "echo 'trapped h4 SIGTERM'" SIGTERM
{
# compound statement traps
# these mask the function traps
#trap "echo 'trapped compound SIGCHLD'" SIGCHLD
#trap "echo 'trapped compound SIGHUP'" SIGHUP
#trap "echo 'trapped compound SIGINT'" SIGINT
#trap "echo 'trapped compound SIGPIPE'" SIGPIPE
#trap "echo 'trapped compound SIGSEGV'" SIGSEGV
#trap "echo 'trapped compound SIGSYS'" SIGSYS
#trap "echo 'trapped compound SIGTERM'" SIGTERM
echo begin err 1>&2
echo begin log
# enable one of sleep/while/find
#sleep 63
#while : ; do sleep 0.1; done
find ~ 2>/dev/null 1>/dev/null
echo end err 1>&2
echo end log
} \
2> >(
trap "echo 'trapped 2 SIGCHLD' >$mypts" SIGCHLD
trap "echo 'trapped 2 SIGHUP' >$mypts" SIGHUP
trap "echo 'trapped 2 SIGINT' >$mypts" SIGINT
trap "echo 'trapped 2 SIGPIPE' >$mypts" SIGPIPE
trap "echo 'trapped 2 SIGSEGV' >$mypts" SIGSEGV
trap "echo 'trapped 2 SIGSYS' >$mypts" SIGSYS
trap "echo 'trapped 2 SIGTERM' >$mypts" SIGTERM
echo begin 2 >$mypts
awk '{ print "processed by 2: " $0 }' >$mypts &
wait
echo end 2 >$mypts
) \
1> >(
trap "echo 'trapped 1 SIGCHLD' >$mypts" SIGCHLD
trap "echo 'trapped 1 SIGHUP' >$mypts" SIGHUP
trap "echo 'trapped 1 SIGINT' >$mypts" SIGINT
trap "echo 'trapped 1 SIGPIPE' >$mypts" SIGPIPE
trap "echo 'trapped 1 SIGSEGV' >$mypts" SIGSEGV
trap "echo 'trapped 1 SIGSYS' >$mypts" SIGSYS
trap "echo 'trapped 1 SIGTERM' >$mypts" SIGTERM
echo begin 1 >$mypts
awk '{ print "processed by 1: " $0 }' >$mypts &
wait
echo end 1 >$mypts
)
echo end fnc
}
h4
echo finish
ps axjf | less
main_trap
func
compound_statement(additional_traps) > process_redirection(additional_traps)
Ctrl+C
#!/bin/bash
# variation 1:
trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
# variation 2:
#trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
h {
{
echo begin
( trap "echo 'trapped inner' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
sleep 63 )
echo end
} \
2> >( trap "echo 'trapped 2' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat ) \
1> >( trap "echo 'trapped 1' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat )
echo end 2
}
h
echo finish
# variation 1:
# trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
Segmentation fault
# variation 2:
# trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Cend 2
finish
trapped 2
begin
^Ctrapped 2
end 2
finish
begin
^Ctrapped 2
Segmentation fault
#!/bin/bash
# variation 1:
trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
# variation 2:
#trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
h2 {
{
echo begin
( trap "echo 'trapped inner' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
sleep 63 )
echo end
} \
2> >( trap "echo 'trapped 2' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat; cat ) \
1> >( trap "echo 'trapped 1' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat; cat )
echo end 2
}
h2
echo finish
# variation 1:
# trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
end 2
finish
end
trapped 1
trapped
begin
^Ctrapped 2
end 2
finish
end
trapped
begin
^Cend 2
finish
trapped 2
end
trapped inner
trapped
trapped 1
# variation 2:
# trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
end 2
finish
trapped inner
trapped 1
trapped
end
begin
^Ctrapped 2
end 2
finish
trapped
end
trapped inner
trapped 1
begin
^Ctrapped 2
end 2
finish
trapped inner
trapped 1
trapped
end
#!/bin/bash
# variation 1:
trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
# variation 2:
#trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
h3 {
{
echo begin
sleep 63
echo end
} \
2> >( trap "echo 'trapped 2' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat; cat ) \
1> >( trap "echo 'trapped 1' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE;
cat; cat )
echo end 2
}
h3
echo finish
# variation 1:
# trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
end 2
finish
end
trapped 1
trapped
begin
^Ctrapped 2
end 2
finish
trapped 1
trapped
end
begin
^Cend 2
finish
trapped 2
trapped 1
trapped
end
begin
^Cend 2
finish
end
trapped 2
trapped 1
trapped
begin
^Cend 2
finish
trapped 2
end
trapped
trapped 1
begin
^Cend 2
finish
end
trapped 2
# variation 2:
# trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Cend 2
trapped 2
finish
trapped
end
trapped 1
begin
^Ctrapped 2
end 2
finish
trapped
end
trapped 1
begin
^Ctrapped 2
end 2
finish
trapped 1
trapped
end
SEGFAULT
。我将其核心转储,但无法确定其来源。似乎在某种程度上取决于主陷阱中的回声是否重定向到
/dev/stderr
(变体1)(否)(变体2)。
Ctrl+C
之后,通常首先会激活
"trapped 2"
,很少激活
"end 2"
。这表明(与我最初的想法相反),处理信号时不涉及过程层次。正在运行的进程(compound语句,2个进程的替换,在h和h2中的子 shell ,
sleep
进程,
cat
进程)并行运行,并且在信号传递时碰巧正在运行的任何一个都将对其进行处理。由于某些原因,主要是stderr重定向的进程替换。我以为
cat
是主要的接收者,没有安装信号处理程序,所以它就死了(这就是为什么我尝试添加2个
cat
,以便第二个可以保持子 shell 运行)。
cat
传播到其包含的进程,即安装了信号处理程序的进程替换bash shell,并打印
"trapped 2"
。
sleep
。即使有2个
cat
,所以即使其中一个被销毁,该子 shell 也会保持 Activity 状态。我发现
SIGPIPE
最有可能杀死睡眠,因为没有捕获到该错误,我看到的行为与我在此处发布的有所不同。但有趣的是,似乎我需要在每个位置
trap
SIGPIPE
而不是仅在sleep子 shell 中,否则,它表现出不同的行为。
SIGPIPE
信号到达
sleep
,将其杀死,因此复合语句中只剩下一个
echo
,它会执行并完成子 shell 。 stdout重定向的进程替换也被杀死,可能是由被杀死的复合语句/函数shell通过另一个
SIGPIPE
杀死的?
"trapped 1"
。
"trapped 2"
和50%
"trapped 1"
。
sleep
/
cat
表示的“业务流程”没有自己的信号处理,则没有多少
trap
可以使它们免于被杀死。
trap
可以保护安装在其内的 shell 中的任何东西都不接收信号,因此
sleep
-s,
cat
-s将被指定的清理功能关闭:杀死
sleep
,其余将记录其最后几行,然后跟随-而不是:清除所有日志记录,只有在此之后,主进程才最终被杀死...
Ctrl+C
之后如何真正传播?
SEGFAULT
来自哪里?
sleep 63
代替
while : ; do sleep 0.1; done
,结果如下:
# (both variations)
# 1 Ctrl + C got me a SEGFAULT
begin
^Ctrapped 2
Segmentation fault
# 2 Ctrl + C got me a SEGFAULT
begin
^Ctrapped 2
^CSegmentation fault
# variation 1
# trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
trapped 1
trapped inner
^Ctrapped 2
^CSegmentation fault
# variation 2
# trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
trapped inner
trapped 1
^Ctrapped 2
Segmentation fault
begin
^Ctrapped 2
trapped inner
trapped 1
^Ctrapped 2
^CSegmentation fault
# variation 1
# trap "echo 'trapped' >/dev/stderr" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
trapped 1
trapped
^Ctrapped 2
^CSegmentation fault
# variation 2
# trap "echo 'trapped'" SIGTERM SIGINT SIGHUP SIGPIPE
begin
^Ctrapped 2
trapped 1
trapped
^Ctrapped 2
^CSegmentation fault
^Ctrapped 2
trapped 1
trapped
^Ctrapped 2
Segmentation fault
cat
-s并允许2
Ctrl+C
-s,但它始终使我
SEGFAULT
仍然不知道它来自何处。
最佳答案
经过无数次实验,我得出的结论是,不可能做自己想做的事,但我仍然不了解每个细节。
我发布了我的发现,但是一会儿不接受我的回答,以防万一-希望-有人对正在发生的事情有更好的了解。
看来,我错了很多事...
1)SEGFAULT
来自写入封闭的fd(stderr
)。但是我认为这是在bash的某个深处甚至在内核级别触发的,可能是某种竞争条件-我以为,bash管理的进程树会在关闭的I/O的剩余虚拟内存地址上分段(我怀疑,这会导致错误)。无论如何,用正确的TTY设备替换/dev/stderr
似乎可以解决此问题。
Write to terminal after redirecting stdout to a file without using stderr?
echo or print /dev/stdin /dev/stdout /dev/stderr
Portability of “> /dev/stdout”
2)日志在被记录的进程之前停止的整个问题是由于它们全部在前台进程组中。终端将在Ctrl+C
上向fg进程组中的每个进程传递SIGINT
。事实证明,在打印进程树之后,记录器进程是所打印数组中的第一个进程,因此可能是第一个要交付并处理SIGINT
的进程。
How does Ctrl-C terminate a child process?
How to make a program reading stdin run in background on linux?
Control which process gets cancelled by Ctrl+C
3)产生进程的 shell 无法控制信号的传递,实际上它正在等待,因此无法在该 shell 中设置一些魔术来保护诸如cat
之类的内容,该内容由未安装信号处理程序的 shell 启动。
4)看到问题是由fg进程组中的所有进程引起的,因此显而易见的解决方案是将不必要的进程移入后台,例如:
2> >( cat & )
cat
,而是立即终止。
SIGSTOP
的后台作业有关,如果它的
stdin
在被后台处理时是打开的。
setsid cmd
将使
cmd
在其自己的 session 中开始,该 session 将具有一个全新的进程组,该进程组将仅包含
cmd
,因此它很可能用于分隔记录器和记录器。我没有考虑过,也没有尝试过。
{
cmd
} \
2> >(logger) \
1> >(logger)
cmd
与
logger
分开的好方法。将
logger
s设置为背景会使它们无法接收输出,而是可能会通过
SIGSTOP
立即终止。
cmd
+
logger
)成为背景,并让另一个层次处理这些信号。
f {
{
cmd
} \
2> >(logger) \
1> >(logger)
}
trap ...
set -m
f &
wait
set -m
。 (我希望这不会引起新的问题,到目前为止看来还不错。)
setsid
在功能上不起作用,因此主脚本将需要其自己的文件,并从第二个脚本文件开始。
关于linux - bash陷阱和过程替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47012675/
我用 IntelliJ IDEA 2021.1 CE 在 流行!_OS 20.04 与 bash 5.0.17 . 问题造句:我将IntelliJ终端设置为/bin/bash通过 IntelliJ 设
给定如下命令: bash --shortcuts 我想显示一个快捷方式列表,就像在这个页面上一样: http://www.skorks.com/2009/09/bash-shortcuts-for-m
我有一个脚本可以操作数据、创建参数并将它们发送到第二个脚本。其中一个参数包含一个空格。 脚本1.sh: args=() args+=("A") args+=("1 2") args+=("B") .
我的脚本的“只运行一次”版本的一个非常简单的示例: ./myscript.sh var1 "var2 with spaces" var3 #!/bin/bash echo $1 #output: va
我想了解数字( double )在 bash 中是如何表示的,以及当我在 bash 中以十六进制格式打印数字时会发生什么。 根据 IEEE 754 标准,double 应由 64 位表示:52 位(1
我试图在 bash -c "..." 命令中获取 bash 脚本,但它不起作用。 如果我在 bash -c "..." 之外运行命令,它会起作用。 我需要使用 bash -c "..." 因为我想确保
如何检测我的 bash shell 中是否加载了 bash 补全包?从 bash-completion 的 2.1 版(包含在 Debian 8 中)开始,除了 BASH_COMPLETION_COM
我的 bash_profile 中有一个投影函数。现在我试图从 bash 脚本中调用这个函数,但是我得到了一个未找到的错误。如何使投影函数对 bash 脚本可见? 最佳答案 必须导出函数 export
我正在编写一个 bash 脚本,它接受许多命令行参数(可能包括空格)并通过登录 shell 将它们全部传递给程序 (/bin/some_program)。从 bash 脚本调用的登录 shell 将取
当我创建一个新的 bash 进程时,提示符默认为一个非常简单的提示符。我知道我可以编辑 .bashrc 等来更改它,但是有没有办法使用 bash 命令传递提示? 谢谢! 最佳答案 提示由 PS1、PS
好的,我希望这个问题有一定道理,但是 bash shell 和 bash 终端之间有什么区别?例子。当我第一次打开终端时,会提示我当前的目录和用户名。在终端窗口标题中显示 -bash- ,当我键入 e
我是 SBCL 的新手,我正在尝试从 bash 终端运行存储在文本文件中的 Lisp 脚本。 这是我在文件开头写的内容 http://www.sbcl.org/manual/#Running-from
我知道我们可以在 bash 中使用将十六进制转换为十进制 #!/bin/bash echo "Type a hex number" read hexNum echo $(( 16#$hexNum ))
我正在尝试在 bash 脚本中自动完成文件夹名称。如果我输入完整的文件夹名称,一切正常,但我不知道如何自动完成名称。有什么想法吗? repo() { cd ~/Desktop/_REPOS/$1 }
我想检查远程网站上的一些文件。 这里是bash命令生成计算文件md5的命令 [root]# head -n 3 zrcpathAll | awk '{print $3}' | xargs -I {}
是否有任何内置函数可以使用 bash shell 脚本从给定日期获取下周日(下周一、下周二等)?例如,2014 年 9 月 1 日之后的第一个星期日是什么时候?我预计 2014 年 9 月 7 日。
我一直在尝试根据表格重命名一些特定文件,但没有成功。它要么重命名所有文件,要么给出错误。 该目录包含数百个以长条形码命名的文件,我只想重命名包含模式 _1_ 的文件。 例子 barcode_1_bar
bash 中有没有办法用变量的内容替换文本文件中的占位符? 例如,我想发送一封电子邮件通知,如下所示: Dear Foo, Alert: blah blah blah blah blah blah
我有一个 bash 脚本,它在某些字符串上附加了一个重音字符,导致它失败,我找不到这些字符在哪里或如何进入那里。 这是一些示例输出: mv: cannot move â/tmp/myapp.zipâ
这个问题在这里已经有了答案: How do I place stdout on edit line? (1 个回答) Can a bash script prepopulate the prompt
我是一名优秀的程序员,十分优秀!