2014-09-04 3 views
2

У меня есть небольшая проблема, возможно, это глупый вопрос, но я начал изучать bash около недели назад ... У меня есть 2 сценария, a.sh и b.sh. Мне нужно, чтобы оба работали постоянно. b.sh должен ждать сигнала от a.shотправить сигнал между сценариями (bash)

(Я пытаюсь объяснить: a.sh и b.sh run -> a.sh посылает сигнал на b.sh -> b. sh traps signal, делает что-то -> 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, даже если я перенаправляю стандартный вывод в файл ... Однако, когда я запускаю b.sh в фоновом режиме из моей оболочки bash, это кажется, отвечает на мой SIGUSR1 (отправляется с той же командой, непосредственно из оболочки) (я получаю правильный вывод) Что мне не хватает?

EDIT: это простой пример, который я пытаюсь запустить:

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 

я не могу получить файл «temp» при запуске a.sh. Однако, если я исполню ./b.sh & и затем kill -SIGUSR1 PIDOFB вручную, все работает отлично ...

+2

Также вам не нужно устанавливать ловушку повторно. Достаточно один раз. И петля в таком виде будет абсолютно ** сжигать ** через процессор. Вы должны обязательно добавить короткий сон там. –

+0

спасибо за ответы. Да, я знаю, просто ошибка записи, в моем тестовом скрипте у меня есть $ lastpid, я скучаю, чтобы переименовать оба здесь ... Может ли b.sh работать в фоновом режиме без выхода, если он содержит только ловушку без цикла? И поймать более одного сигнала? – Milite

+1

Другая ошибка, которую я предполагаю, заключается в том, что './b.sh &;' недопустим. У вас не может быть как '&', так и ';' в качестве таких терминаторов. При построении минимального тестового примера вы должны быть осторожны, чтобы правильно воспроизвести ваш фактический случай. Вы проверили этот минимальный случай, чтобы узнать, есть ли у него такая же проблема, как и ваш реальный случай? –

ответ

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 

идея заключается в том, чтобы просто записать значение PID изнутри b (фоновый) скрипт и прочитайте его с a (основной) скрипт.

+1

отлично работает, спасибо! У меня есть небольшая проблема ... почему, если я отправлю SIGINT из a.sh в b.sh, я не могу отловить ее от b.sh, тогда как я могу захватить «CTRL + C» из a.sh? – Milite

+0

№ SIGINT бесполезен для фоновой работы. См. Следующую ссылку, это может быть полезно для вас: http://stackoverflow.com/questions/14696427/how-can-bash-script-do-the-equivalent-of-ctrl-c-to-a-background- задача – constt

Смежные вопросы