ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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.
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.
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.
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.
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.
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?
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.
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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.