加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

并发登录bash脚本

发布时间:2020-12-16 01:57:21 所属栏目:安全 来源:网络整理
导读:我目前正试图弄清楚为什么 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}" ec
我目前正试图弄清楚为什么 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

让我的脚本稳定.

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中的某些东西或者不是重入的,它应该是或者在第一时间阻止重新进入.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读