0

I am a Linux novice and currently developing a security system using Raspberry Pi 3 and MotionEye. To get notifications via e-mail, I am attempting to create a custom shell script that will send an e-mail if there is motion, lock for X minutes, then send another e-mail if there is still motion. However, I am having some difficulties.

I created a simple Python script named "send_email.py" using SMTP that works perfectly fine for sending e-mails when I execute it via command line.

The shell script (named "flock_email.sh") is where I run into troubles in a few regards:

  1. Whenever I run flock_email.sh, it completely overwrites send_email.py. I have tried to change file permission so it is only executable by the user, but it still overwrites.
  2. The flock command/function does not work as I intended or at all. I have looked all over the internet and tried multiple different codes, but none have worked. I have attached my various flock_email.sh scripts I have tried.
  3. Not necessarily a problem, but I am a bit confused on what my "shebang" line should be. For flock_email.sh I have it as "!#/bin/bash", which I believe makes the script it executable, at least according to this. Do I still need to change the permissions via the command "chmod +x flock_email.sh"? The path is /home/pi, which is essentially the main directory of my Pi.

The different solutions I have tried:

  1. In flock_email.sh, I have tried to directly change the file permissions to read-only instead of using flock, having it sleep, then changing the permissions back to allow execution of the file.

  2. Multiple flock_email.sh implementations, as attached.

To summarize:

  1. I need to execute send_email.py before locking the file flock_email.sh.

  2. Once locked, it needs to stay locked for X time.

Does anyone have any pointers or suggestions? I have spent well over 15 hours tinkering with this and feel like I have gotten nowhere!

send_email.py:

#!/usr/bin/env
import smtplib

def send_email():
    content = "Message I want to send to specified e-mail."
    sender = "e-mail account that will send message"
    pword = "password of sender"
    receiver = "e-mail account that will receive message"
    mail = smtplib.SMTP("smtp.gmail.com",587)
    mail.ehlo
    mail.starttls()
    mail.login(sender,pword)
    mail.sendmail(sender,receiver,content)
    mail.close()

send_email()

flock_email.sh (1):

#!/bin/bash
(
    python /home/pi/send_email.py
    flock -e 200
    sleep [time in seconds]
)

flock_email.sh (2):

#!/bin/bash
(
    python /home/pi/send_email.py
    exec 3>/home/pi/send_email.py
    flock -x 3
    sleep [time in seconds]
    exec 3>&-
)

flock_email.sh (3):

#!/bin/bash
python /home/pi/send_email.py
chmod 444 /home/pi/send_email.py # modify to read only for all
sleep [time in seconds]
chmod 755 /home/pi/send_email.py # modify to rwx for owner, r-x for others
Community
  • 1
  • 1
  • `exec 3>/home/pi/send_email.py` opens the file for write access, which will truncate the file to zero bytes. Why are you doing that? – cdarke May 19 '17 at 18:34
  • The `#!` line does not make the script executable, that's what `chmod u+x script name` does. The `#!` line specifies which interpreter is to be used. In this case it is `bash`, but it could be `sed`, `awk`, `perl`, `python`, `ruby`, and so on. The default, if you don't specify a `#!` is `sh`, which is the basic POSIX shell (depending on the platform). – cdarke May 19 '17 at 18:38
  • 1
    What are you trying to achieve by using `flock`? Why do you need to use it? – cdarke May 19 '17 at 18:41
  • 2
    Why don't you just use `cron`? – l'L'l May 19 '17 at 18:41
  • @cdarke, I did not realize that. The [Stack Overflow post](http://stackoverflow.com/questions/24388009/linux-flock-how-to-just-lock-a-file) I was following made it seem like all it did was open the file handle. The 'chmod u+x script name' part makes sense. I am using 'flock' because of MotionEye's notification system. It will send an e-mail once every minute while it is detecting motion. Thus if there is motion for 15 minutes in front of the camera, I will get 15 e-mails. I want to change it to one e-mail per X minutes by not allowing the file to be executed because it is locked. –  May 19 '17 at 19:34
  • @I'L'I, I have not heard of that, I will check it out. Thank you. –  May 19 '17 at 19:37

1 Answers1

0

The reason why man flock and all posts say to use > is because you're supposed to use a dedicated lock file, typically in /var/lock:

#!/bin/bash
exec 3> /var/lock/motionmail
flock -ne 3 || exit
python /home/pi/send_email.py
sleep 3600

This additionally fixes you sending your email regardless, before you ever check the lock, and aborts new emails instead of queueing them all up.

You choose the lock file name based on the scope you want your lock to have:

  • If you only want one email per hour, you can use something like /var/lock/motionmail because there's just one per system.

  • If you want one email for each user per hour, you can use $HOME/.motionmail.lock because there's just one per user.

You can use /home/pi/send_email.py if you want with <, but this implies that you want one email per hour not only for each user, programming language and script copy, but also every time you hit save and replace the file with your editor*


* Editors differ in whether they replace or overwrite a file

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • I went ahead and made a new file based on your code named `motion_email.sh` and placed it in `/var/lock/`. I only want one e-mail per hour. I tried running `/var/lock/motion_email.sh` in my terminal, but was denied permission despite setting permissions so owner can rwx and all others can r-x. I am the owner. I am not sure what I am doing incorrectly. My first thought is that I should have another file, since your code "points" (not sure appropriate word) to the `/var/lock/` file. I see your `/var/lock/motionmail` does not have a `.sh` extension, is it correct? Thanks for the reply! –  May 20 '17 at 14:49
  • That repeats the error of trying to lock the script file instead of a dedicated empty lock file. This snippet automatically creates the lock file. Put this script in your `/home/pi/flock_email.sh` – that other guy May 20 '17 at 15:37