【问题标题】:send signal between scripts (bash)在脚本之间发送信号(bash)
【发布时间】:2014-09-05 10:58:10
【问题描述】:

我有一个小问题,可能这是一个愚蠢的问题,但我大约一周前开始学习 bash ...... 我有 2 个脚本,a.sh 和 b.sh。我需要让两者不断运行。 b.sh 应该等待来自 a.sh 的信号

(我试图解释: a.sh 和 b.sh 运行 --> a.sh 向 b.sh 发送信号 -> b.sh 捕获信号,执行某些操作 --> a.sh 执行其他操作,然后发送另一个信号 --> b. sh 捕获信号,执行某些操作 --> 等等)

这是我尝试过的:

a.sh:

#!/bin/bash
./b.sh &;
bpid=$!;
# do something.....
while true
do
     #do something....
     if [ condition ]
     then
          kill -SIGUSR1 $bpid;
     fi
done

b.sh:

#!/bin/bash 
while true
do
     trap "echo I'm here;" SIGUSR1;
done

当我运行 a.sh 时,我没有从 b.sh 得到任何输出,即使我将标准输出重定向到一个文件... 但是,当我从我的 bash shell 在后台运行 b.sh 时,它似乎回答了我的 SIGUSR1(使用相同的命令直接从 shell 发送)(我得到了正确的输出) 我错过了什么?

编辑: 这是我正在尝试运行的一个简单示例:

a.sh:

#!/bin/bash
./b.sh &
lastpid=$!;
if [ "$1" == "something" ]
then    
    kill -SIGUSR1 $lastpid;
fi

b.sh:

#!/bin/bash
trap "echo testlog 1>temp" SIGUSR1;
while true
do
    wait
done

运行 a.sh 时无法获取文件“temp”。 但是,如果我手动执行./b.sh & 然后kill -SIGUSR1 PIDOFB,一切正常...

【问题讨论】:

  • 另外你不需要重复安装陷阱。一次就够了。像这样的while循环绝对会通过cpu。你绝对应该在里面加一个短暂的睡眠。
  • 我假设的另一个错字是./b.sh &; 无效。你不能同时拥有&; 作为这样的终结者。在构建最小测试用例时,您需要小心正确地复制实际用例。您是否测试过这个最小案例,看看它是否与您的实际案例有相同的问题?
  • 我没说不要循环。我说不要在循环中设置陷阱。捕获时陷阱不会消失(据我所知),因此您只需设置一次陷阱处理程序。
  • 循环只需要阻止你的脚本退出。陷阱处理程序完成这项工作。 trap "handler" SIGUSR1 命令添加一个陷阱处理程序,它不会暂停脚本等待该信号进入。获取一个最小的工作脚本对失败并更新你的和他们一起发帖。在那之前,这是无法解决的。
  • 那些文字脚本在这里工作。虽然a.sh 显然只向b.sh 发送一次信号,然后退出并让b.sh 运行。此外,wait 并没有为你做任何事情,因为b.shwait 没有任何作用,所以b.sh 仍然忙于循环并耗尽你所有的 CPU。

标签: bash shell unix signals


【解决方案1】:

可能的解决方案之一是下一个(也许,它很脏,但它有效):

a.sh:

#!/bin/bash

BPIDFILE=b.pid

echo "a.sh: started"
echo "a.sh: starting b.sh.."

./b.sh &
sleep 1

BPID=`cat $BPIDFILE`

echo "a.sh: ok; b.sh pid: $BPID"

if [ "$1" == "something" ]; then
    kill -SIGUSR1 $BPID
fi

# cleaning up..
rm $BPIDFILE

echo "a.sh: quitting"

b.sh:

#!/bin/bash

BPIDFILE=b.pid

trap 'echo "got SIGUSR1" > b.log; echo "b.sh: quitting"; exit 0' SIGUSR1

echo "b.sh: started"

echo "b.sh: writing my PID to $BPIDFILE"
echo $$ > $BPIDFILE

while true; do
    sleep 3
done

这个想法是简单地从 b(背景)脚本中写下一个 PID 值,然后从 a(主)脚本中读取它。

【讨论】:

  • 完美运行,谢谢!我有一个小问题......为什么如果我从 a.sh 向 b.sh 发送一个 SIGINT,我不能从 b.sh 捕获它,而我可以从 a.sh 捕获“CTRL+C”?
  • 没有。 SIGINT 对后台作业毫无用处。看下一个链接,可能对你有帮助:stackoverflow.com/questions/14696427/…
猜你喜欢
  • 2014-06-02
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
相关资源
最近更新 更多