0

I am trying to create a series bash scripts to check on my dog when I am at work. I have cron jobs setup to run the scripts on the days I work, but after about 8 days the script stops working. I tried adding a script to remove the video files and reboot the Pi as well, but it did not fix it. I am running Rasbian on the Pi. Thanks in advance for any insight on this issue.

Capture script

#!/bin/bash

for ((n=0;n<60;n++))
do

raspivid -o video.h264 -t 5000 -w 640 -h 360 -fps 30 -b 150000

MP4Box -add video.h264 dog.mp4

sleep 300

done

Upload script

#!/bin/bash

sleep 33

for ((n=0;n<60;n++))
do

lftp -u username,password ftp.website.com<<EOF

cd /public_html/beta
lcd /home/pi
put -E dog.mp4

quit 0

EOF

sleep 267

done

Clean up script

#!/bin/bash

rm dog.mp4
rm video.h264

sudo reboot

2 Answers 2

1

This solution seems overly complicated and prone to errors.

I suggest you make one script to capture, upload and remove the video, and that you learn crontab well enough to have cron start that script as often as appropriate.

Check

man 5 crontab
1
  • Thanks...i will combine it into one and go from there. I di understand the crontab well enough that it runs the script when i want. Thanks again.
    – shawn
    Commented Dec 6, 2016 at 15:53
1

There's no error checking or handling at all in those scripts. If you don't have that and something is failing mysteriously, the first thing you need to do is add it -- otherwise there is not much point in doing anything else.

Foreground process calls always exit with a status code, and while not all programs necessarily use this, the vast majority do. Unfortunately, what the values mean is often undocumented, but conventionally the approach is to consider many kinds of failure and only one kind of success, and indicate the latter with an exit status of 0.

The exit status of the last foreground process is available within POSIX shell scripts via the special variable $?. For example:

#!/bin/sh

ls /home > /dev/null
echo $?
ls /nosuchthing > /dev/null
echo $?

This should print:

0
ls: cannot access '/nosuchthing': No such file or directory
2

A few things to notice:

  • The first ls call, which succeeded because /home is a real directory which is world readable, returned 0. The actual output was redirected to /dev/null, so we don't see it.

  • The second call, which failed because /nosuchthing does not exist for me here, failed. Why ls returns 2 is another question; what is important for us is that it isn't 0, because ls follows convention and only exits 0 when it succeeds.

  • The error output from ls was not redirected to /dev/null, because it is printed to a separate stream, "standard error". It could have been redirected to the same place as "standard output" (which is what ls /home printed to) by using ls /nosuchthing > /dev/null 2>&1.

The last point is important, because by not combining the output and error streams, we can discard one (which is sometimes what you want to do in a shell script, if you don't care about what's output when a process succeeds), and redirect errors to a log!

ls /nosuchthing > /dev/null 2>> err.log

The script will now simply spit out:

0
2

And, if your current directory is writable, leave an err.log behind it with the error message. Some fancier approaches to this are described here:

Log output of background or boot script

Again, what we are most concerned with is that exit code, because even if the program does not spit out messages on failure, we can:

if [ $? -ne 0 ]; then
    echo "Whatever failed!" >> /home/pi/whatever/err.log
fi

Notice that here, and in the last example, I'm using append (>>) instead of truncate (>) with redirection. That's also described in the other Q&A about logging. It is important.

If a program's exit status is undocumented, which it often is, you'll need to do a bit of experimentation on the command line (which is a POSIX shell, so $? is available there too). Note that while not all programs make use of the exit status, they all have one. If they don't make use of it, they probably just return 0 for everything.

I don't have a camera connected and running anywhere right now to check that way WRT to raspistill, but from a quick glance at main() in the source code it should be apparent to anyone who understands C that raspistill does implement a variable exit status, and in fact makes use of sysexits.h, a header file which includes some standardized exit values, including 0 for success.

So, raspistill, and most (possibly, all) of the commands you use will exit 0 on success and something else on failure.

You need to:

  • Check and respond to the exit status of foreground/blocking calls within the script appropriately, and
  • Use a log.

Note that this may or may not isolate your problem, but until you rule out the possibilities it covers, there is no point in contemplating anything else.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.