并发登录bash脚本
我目前正试图弄清楚为什么
shell脚本在每次偶尔记录时都会失败.
我有一个shell函数,如下所示: 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 } 这种方式错误出现频率较低,但仍然存在,因此这不是一个真正的修复. 解决方法
我会说这绝对是bash中的一个错误,我鼓励你向bash开发者报告.至少,你应该永远不会得到语法错误的语法错误代码.
为了记录,我得到了与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 让我的脚本稳定.
我想你不应该采取特别的预防措施,但显然你在实践中.鉴于问题似乎在没有函数调用的情况下消失了,我猜测bash中的某些东西或者不是重入的,它应该是或者在第一时间阻止重新进入. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |