log() { local l_text=$1 local l_file="/path/to/logs/$(date +%Y%m%d)_script.log" local l_line="$(date +'%Y-%m-%d %H:%M:%s') $(hostname -s) ${l_text}" echo ${l_line} >> ${l_file} }
现在每隔一段时间就会因语法错误而失败:
/path/to/script.sh: command substitution: line 163: Syntax error near unexpected token `)' /path/to/script.sh: command substitution: line 163: `hostname -s) ${l_text}'
问题是,我有多个子流程,每个子流程都需要记录以及发送陷阱(在此期间也会执行记录).我调试了这个问题并发现,当这个函数同时输入三次时会发生这种情况.首先是主要过程,然后是孩子.在执行l_text的日期部分之后,main get被一个由child引起的陷阱中断,并且在此陷阱中尝试记录某些内容.子进程和陷阱很好地完成了日志记录,但是然后main在陷阱之后恢复并尝试执行主机名部分(假定为)并因此错误而失败.
因此,似乎主要不喜欢在产生$(日期’%Y-%m-%d%H:%M:%S’)$(主机名-s)${l_text}部分时被置于睡眠状态日志语句并不能很好地恢复.我假设这应该工作正常,因为我只是使用局部变量和线程安全输出方法.
这是我遇到的一般并发问题吗?或者这是否特别针对bash脚本中的陷阱机制?我知道C中SIGNAL处理的商品,所以我知道SIGNAL处理程序中只允许某些操作.但是,我不知道在bash脚本中处理SIGNAL时是否也适用相同的预防措施.我试图找到关于此的文档,但是我找不到的任何文档都没有给出脚本中SIGNAL处理问题的任何迹象.
编辑:
这是一个可用于复制问题的实际简单脚本:
#!/bin/bash log() { local text="$(date +'%Y-%m-%d %H:%M:%s') $(hostname -s) $1" echo $text >> /dev/null } sub_process() { while true; do log "Thread is running" kill -ALRM $$ sleep 1 done } trap "log 'received ALRM'" ALRM sub_process & sub_process_pid=$! trap "kill ${sub_process_pid}; exit 0" INT TERM while true; do log "Main is running" sleep 1 done
由于第5行中的语法错误,此脚本每隔一段时间就会被杀死.第5行是echo $text>> / dev / null,但由于语法错误也提到了hostname命令,类似于我上面发布的那个,我假设还有一个一个错误,实际错误在第4行,这是本地的text =“$(日期’%Y-%m-%d%H:%M:%S’)$(主机名-s)$1”.
有谁知道如何处理上面的脚本来纠正它?我已经尝试将字符串的构造移出一些临时变量:
log() { local thedate=$(date +'%Y-%m-%d %H:%M:%s') local thehostname=$(hostname -s) local text="${thedate} ${thehostname} $1" echo $text >> /dev/null }
解决方法
为了记录,我得到了与GNU bash版本4.2.10(1)-release(x86_64-pc-linux-gnu)相同的结果.
我发现你可以通过不在陷阱处理程序中调用函数来解决问题.例如.更换
trap "log 'received ALRM'" ALRM
同
trap "echo $(date +'%Y-%m-%d %H:%M:%s') $(hostname -s) received ALRM" ALRM
让我的脚本稳定.
I kNow about the commodities of SIGNAL handling in C,so I am aware
that only certain operations are allowed in SIGNAL handlers. However I
am not aware if the same precautions also apply when handling SIGNALs
in a bash script.
我想你不应该采取特别的预防措施,但显然你在实践中.鉴于问题似乎在没有函数调用的情况下消失了,我猜测bash中的某些东西或者不是重入的,它应该是或者在第一时间阻止重新进入.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。