You are not logged in.

#1 2012-05-29 13:24:10

Archdove
Member
Registered: 2011-09-23
Posts: 118

Bash: React to stderr of another program

Hi

[I actualli didn't meant to post this thread just yet. I'm still evaluating this and i've probably just found the solution]

A mono program crashes from time to time with only a message to the stderr. I want to react to this message and restart the program.
How can i use the stdout of program A as stdin of script B?

My test setup looks as followed. I try to redirect the stout of top to test.sh and just echo it there. This already crashes.
Any idea how to do this?

The plan is to only redirect the stderr from the mono program to the stdin of the script

test.sh:

while read ; do 
    if [ echo $REPLY ] ; then
        echo $REPLY
    fi
done
$ top -b -d 1 -n 5 | ./test.sh 
./test.sh: 5: read: arg count

Last edited by Archdove (2012-05-29 13:34:38)

Offline

#2 2012-05-29 13:51:57

Gnarl
Member
Registered: 2010-11-18
Posts: 63

Re: Bash: React to stderr of another program

Try this as your test.sh

while read line; do 
    if [ "$line" ] ; then
        echo $line
    fi
done

Offline

#3 2012-05-29 14:03:28

Archdove
Member
Registered: 2011-09-23
Posts: 118

Re: Bash: React to stderr of another program

Thanks gnarl. Thats what i was working on. What i don't understand is why i get just one line i output if i echo directly and a hundred lines if i echo inside a if-statement:

#!/bin/sh

IFS='\n'
while read input; do
        if [ $(echo $input | grep Xorg) ] ; then
            echo $input
        fi  
done

echo "end of script"

Well ok.. i do understand it...
EDIT: Code above works now. I will update the redirecting of the stderr to stdin later in this thread. Maybe it helps someone in the future.

Last edited by Archdove (2012-05-29 16:03:09)

Offline

#4 2012-05-29 19:14:19

Roken
Member
From: South Wales, UK
Registered: 2012-01-16
Posts: 1,302

Re: Bash: React to stderr of another program

What is that you are running. I ask because I have an opensim server running with mono, and had a similar issue where I wanted to restart it automatically if it crashed. I did so by launching it in a screen session, then set up a script to restart it if it was no longer running, the script itself managed by a cron job at 30 second intervals. By running in screen it's a trivial matter to test if it's dead. If you launch with a defined screen name:

screen -S screenname -d -m mono yourprogram

you can then test with

if [ -z `screen -ls | grep screenname | sed 's/\.\([0-9]*\).*/\1/' | sed 's/^[ \t]//g'` ]; then

the sed expression strips the value returned if it's still running down to just the numerical PID, preventing an error on the "if" statement.

Last edited by Roken (2012-05-29 19:14:54)


Ryzen 5900X 12 core/24 thread - RTX 3090 FE 24 Gb, Asus B550-F Gaming MB, 128Gb Corsair DDR4, Cooler Master N300 chassis, 5 HD (2 NvME PCI, 4SSD) + 1 x optical.
Linux user #545703

/ is the root of all problems.

Offline

#5 2012-05-29 19:49:20

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

Re: Bash: React to stderr of another program

Could you do a script like

ok=0
while (( $ok == 0 ))
do
   mono-program
   ok=$?
done

That would restart the program anytime it exited with non-zero status.


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

#6 2012-05-29 21:06:24

Archdove
Member
Registered: 2011-09-23
Posts: 118

Re: Bash: React to stderr of another program

@Roken: @alphaniner:
It's a software i'm maintaining internally. The stop script consists of "killall" so there aren't any non error exit codes even if it should keep shut. Its planned to plan the rewriting in the future ... but there is just no time for it now.
Actually i think i will be fine with what i have. The error i'm looking for is a SIGSEGV which is pretty easy to spot and, what i learnd is its also easy to just do:

program.sh | stderr_monitor.sh 1>&2

Offline

#7 2012-05-29 21:22:18

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: Bash: React to stderr of another program

Why monitor stderr? Why not just wrap the program in a loop...

#!/bin/sh
until some_program; do :; done

This way it'll restart itself as long as it exits nonzero, which should happen when it exits via a signal.

Offline

#8 2012-05-30 07:14:46

Archdove
Member
Registered: 2011-09-23
Posts: 118

Re: Bash: React to stderr of another program

@falconindy: My english skills lack a little bit and a cannot figure out the exact meaning of what you said.

until: loops until expression returns true ( while(true) == until(false) ); did you mean closing it with a signal (kill) should result into a non zero exit value and an internal SIGSEGV won't?
Just try to clarify this. Your solution is much simpler than mine but using the until loop and killall the process leads to a restart. But it should stay dead.

Question is:
SIGKILL (killall?) -> no restart
SIGSEGV -> restart

I can always hack around it and include the restart_script into the stop_script and kill it also. The other way around would be cleaner though.

After a bit of testing it looks as if until loops on signals resulting in Term action but not on signals resulting in Core action. I tried with manually sending SIGSEGV and SIGTERM. Sending SIGSEGV in this test scenario will leave the process "running" while in the real world the process vanishes. Not trustworthy at all.

       Signal	  Value	    Action   Comment
       -------------------------------------------------------------------------
       SIGHUP	     1	     Term    Hangup detected on controlling terminal
				     or death of controlling process
       SIGINT	     2	     Term    Interrupt from keyboard
       SIGQUIT	     3	     Core    Quit from keyboard
       SIGILL	     4	     Core    Illegal Instruction
       SIGABRT	     6	     Core    Abort signal from abort(3)
       SIGFPE	     8	     Core    Floating point exception
       SIGKILL	     9	     Term    Kill signal
       SIGSEGV	    11	     Core    Invalid memory reference
       SIGPIPE	    13	     Term    Broken pipe: write to pipe with no readers
       SIGALRM	    14	     Term    Timer signal from alarm(2)
       SIGTERM	    15	     Term    Termination signal
       SIGUSR1	 30,10,16    Term    User-defined signal 1
       SIGUSR2	 31,12,17    Term    User-defined signal 2
       SIGCHLD	 20,17,18    Ign     Child stopped or terminated
       SIGCONT	 19,18,25    Cont    Continue if stopped
       SIGSTOP	 17,19,23    Stop    Stop process
       SIGTSTP	 18,20,24    Stop    Stop typed at tty
       SIGTTIN	 21,21,26    Stop    tty input for background process
       SIGTTOU	 22,22,27    Stop    tty output for background process

Guess all i can do is set up test and hope it crashes while I'm still around. Thanks for all the input until now.

Last edited by Archdove (2012-05-30 08:03:44)

Offline

Board footer

Powered by FluxBB