LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-12-2010, 07:40 PM   #1
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Rep: Reputation: 31
Script not running as expected


My script is not working as expected.

I have a need to restart a program every hour.

If the program is running when the script runs,
kill it
then
restart it.

If the program is NOT running when script runs,
then
just start it.

Here is the script's behavior currently:

The script kills the program if the program is running,
but
it won't restart it, until the next time the script runs.
I.e., the only time it restarts the program is if it wasn't running.

Why is it doing this?

Here is the script...

#!/bin/sh

APP='ffmpeg2theora'
APPID=`pidof ffmpeg2theora`

if ps ax | grep -v grep | grep $APP > /dev/null
then
kill $APPID
fi

wait

/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
 
Old 07-12-2010, 07:50 PM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
What did you do to debug the issue ? E.g. did you check until what line inclusive your script is executed ?

For example, did you try to put

-xv

after

#/bin/sh

?
 
Old 07-12-2010, 09:38 PM   #3
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by Sergei Steshenko View Post
What did you do to debug the issue ? E.g. did you check until what line inclusive your script is executed ?

For example, did you try to put

-xv

after

#/bin/sh

?
Even without doing any debugging,
it makes no sense that the line
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
only runs if the program wasn't previously running.

Isn't a script supposed to run line-by-line?
And that anything outside a conditional statement runs automatically?

Anyway, I debugged the script the following way:

$ watch cat `pidof ffmpeg2theora`

When the script runs from cron,
the pid changes. E.g. from 14449 to 24045

But then 24045 disappears 2 seconds later.

Quite a bizarre behavior.

The following seems to work for now, but I still don't know where the problem lies.

Code:
#!/bin/sh

APP='ffmpeg2theora'
APPID=`pidof ffmpeg2theora`

if ps ax | grep -v grep | grep $APP > /dev/null
then
kill $APPID
fi
wait
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
wait
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
By running the line:
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
twice, I'm getting the expected behavior.
 
Old 07-13-2010, 08:14 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
What is the wait for?

It seems to me that the following much simpler script would work:
Code:
#!/bin/sh
killall /usr/bin/ffmpeg2theora
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
 
Old 07-13-2010, 09:04 AM   #5
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by ntubski View Post
What is the wait for?

It seems to me that the following much simpler script would work:
Code:
#!/bin/sh
killall /usr/bin/ffmpeg2theora
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...
The "wait" tells the script to wait for one line to finish before trying to run the next line.

I could use "sleep X" in place of "wait", but there is no guarantee that the line would finish executing in X seconds.

Your suggestion,

killall /usr/bin/ffmpeg2theora
/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout ...

suffers the same problem as I'm having. It kills the running process, but does not restart, until the next time the script runs.
 
Old 07-13-2010, 09:20 AM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by fw12 View Post
The "wait" tells the script to wait for one line to finish before trying to run the next line.
...
Justify your statement by excerpts from documentation.
 
Old 07-13-2010, 09:27 AM   #7
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by fw12 View Post
Even without doing any debugging ...
Enough said - please first make minimum decency effort. Debugging is first of all about checking your assumptions - you haven't shown any proof that in reality your assumptions are correct.
 
Old 07-13-2010, 11:02 AM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
The killall has a --wait option, perhaps that is what you are looking for. The following appears to work correctly over here:
Code:
#!/bin/sh
killall --wait --quiet /usr/bin/ffmpeg
/usr/bin/ffmpeg -f mpegvideo -i /dev/zero -o /dev/null 2>/dev/null &
Without the --wait option it still works but there is a period of time in which 2 ffmpeg processes are running. I imagine if 2 processes try to read from a real camera (instead of /dev/zero) there could be a problem. Have you tried redirecting stderr to a log file to see if any errors are reported?

I don't have ffmpeg2theora here, is it by any chance a shell script? That could also complicate things.
 
Old 07-13-2010, 08:13 PM   #9
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by ntubski View Post
The killall has a --wait option, perhaps that is what you are looking for. The following appears to work correctly over here:
Code:
#!/bin/sh
killall --wait --quiet /usr/bin/ffmpeg
/usr/bin/ffmpeg -f mpegvideo -i /dev/zero -o /dev/null 2>/dev/null &
Without the --wait option it still works but there is a period of time in which 2 ffmpeg processes are running. I imagine if 2 processes try to read from a real camera (instead of /dev/zero) there could be a problem. Have you tried redirecting stderr to a log file to see if any errors are reported?

I don't have ffmpeg2theora here, is it by any chance a shell script? That could also complicate things.
Yes, I need to forestall two ffmpeg2theora process running and trying to read from the same /dev/video0.

This is why the kill/killall command has to finish executing, before the script is allowed to proceed.
 
Old 07-13-2010, 08:30 PM   #10
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by Sergei Steshenko View Post
Enough said - please first make minimum decency effort. Debugging is first of all about checking your assumptions - you haven't shown any proof that in reality your assumptions are correct.
What assumptions are you referring to?

If you read my post carefully, I said I debugged using

$ watch echo `pidof ffmpeg2theora`

Did you just read the one line, and quickly ran to reply? Don't do that. You should read the entire post, and my reasoning.
 
Old 07-13-2010, 08:32 PM   #11
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by Sergei Steshenko View Post
Justify your statement by excerpts from documentation.
If you're looking for a guide on "wait" command, here it is

http://www.linux.com/archive/feed/43774
 
Old 07-13-2010, 09:08 PM   #12
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by fw12 View Post
If you're looking for a guide on "wait" command, here it is

http://www.linux.com/archive/feed/43774
Wow, I guess that explains where your misconceptions come from but that article is completely wrong. Just read a few of the comments on it.

Quote:
Yes, I need to forestall two ffmpeg2theora process running and trying to read from the same /dev/video0.

This is why the kill/killall command has to finish executing, before the script is allowed to proceed.
The problem is not waiting for kill/killall command to finish executing, it is that the kill/killall command may finish executing before the other process receives the signal. Passing the --wait option to killall should solve this problem, have you tried that?
 
Old 07-14-2010, 08:46 AM   #13
fw12
Member
 
Registered: Mar 2006
Distribution: Fedora core, Ubuntu
Posts: 175

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by ntubski View Post
Wow, I guess that explains where your misconceptions come from but that article is completely wrong. Just read a few of the comments on it.



The problem is not waiting for kill/killall command to finish executing, it is that the kill/killall command may finish executing before the other process receives the signal. Passing the --wait option to killall should solve this problem, have you tried that?
I now have a better feel for what the "wait" command does.

As for using --wait with killall, I'm reluctant to use killall, because a case may arise where I have more than two ffmpeg2theora processes running.

So, I've rewritten my code as follows with grep and kill. Grep lets me find particular ffmpeg2theora processes.


APP='ffmpeg2theora'
APPID=`pidof ffmpeg2theora`

CMD=/usr/bin/ffmpeg2theora /dev/video0 -o /dev/stdout...

if ps ax | grep -v grep | grep $APP > /dev/null
then
kill $APPID & # backgrounding makes it a sub-process, and gives it a pid.
LPID=$! #$! contains the PID of the last called process.
wait $LPID
$CMD

else
$CMD
fi

This seems to do what I want.
Please critique for obvious flaws.
 
Old 07-14-2010, 09:30 AM   #14
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by fw12 View Post
I now have a better feel for what the "wait" command does.
Still not correct though,
Code:
kill $APPID & # backgrounding makes it a sub-process, and gives it a pid.
LPID=$! #$! contains the PID of the last called process.
wait $LPID
is completely identical to kill $APPID. Also it doesn't really solve the problem because the kill command may finish before the process receives the signal; perhaps it turns out that doing things this way happens to cause processes to be scheduled in such a way that things work, but there is no more assurance of correctness than using sleep.

Quote:
As for using --wait with killall, I'm reluctant to use killall, because a case may arise where I have more than two ffmpeg2theora processes running.

So, I've rewritten my code as follows with grep and kill. Grep lets me find particular ffmpeg2theora processes.
How will grep know which process you want? You're applying kill to the pidof result, so even if grep did magically know, it wouldn't matter. pidof will return both pids if you have 2 ffmpeg2theora processes, so your method has the same problems as killall. If you want to kill a particular process, you should save its pid when you start it.

By the way, I suggest pgrep instead of the ps | grep foo | grep -v grep thing in general.
 
Old 07-14-2010, 09:41 AM   #15
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ntubski View Post
Still not correct though,
Code:
kill $APPID & # backgrounding makes it a sub-process, and gives it a pid.
LPID=$! #$! contains the PID of the last called process.
wait $LPID
is completely identical to kill $APPID. Also it doesn't really solve the problem because the kill command may finish before the process receives the signal; perhaps it turns out that doing things this way happens to cause processes to be scheduled in such a way that things work, but there is no more assurance of correctness than using sleep.



How will grep know which process you want? You're applying kill to the pidof result, so even if grep did magically know, it wouldn't matter. pidof will return both pids if you have 2 ffmpeg2theora processes, so your method has the same problems as killall. If you want to kill a particular process, you should save its pid when you start it.

By the way, I suggest pgrep instead of the ps | grep foo | grep -v grep thing in general.

FWIW, 'man killall' might be useful if one wants to kill processes by name.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
c code not running as expected isamuede Programming 6 04-28-2010 09:21 PM
Wireless script not working as expected SlowCoder Linux - General 6 05-24-2008 07:06 AM
Script cd not work as expected cdcshu Linux - Software 1 11-10-2007 04:38 AM
New computer is not running as fast as expected davidguygc Linux - Hardware 30 05-01-2007 02:16 AM
sh script not executing as expected ryzor Linux - General 4 12-18-2006 09:03 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:34 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration