1

I got stuck with this cronjob that just won't work. I left it for a day to troubleshoot it again with some fresh idea's but still no luck.

I tried to find my answer on this great post, but not everything is clear to me and at the end it still refuses to work. And to make it all worse, there are no logs, no errors to find concerning cron in /var/log.

What do I try to achieve?
Automate the removal of directories that are populated by an ip cam. In the directories are the snapshots. Here is a view of the list.

pi@raspberrypi:/media/pi/USB/Dahua/Dahua $ ll
total 24K
drwxr-xr-x 3 xxxxxxxx xxxxxxxxx 4.0K Sep  2 05:59 2018-09-02d
drwxr-xr-x 3 xxxxxxxx xxxxxxxxx 4.0K Sep  3 00:57 2018-09-03d
drwxr-xr-x 3 xxxxxxxx xxxxxxxxx 4.0K Sep  4 02:03 2018-09-04d
drwxr-xr-x 3 xxxxxxxx xxxxxxxxx 4.0K Sep  5 01:20 2018-09-05d
drwxr-xr-x 3 xxxxxxxx xxxxxxxxx 4.0K Sep  6 00:20 2018-09-06
-rw-r--r-- 1 xxxxxxxx xxxxxxxxx 4.0K Sep  6 22:28 DVRWorkDirectory

I would like to keep the x newest files and get rid of the rest. All this with a cronjob that would run lets say every week or every day at a certain time.

Seems not to be difficult but I just can't make it work. It's true, my Linux knowledge is basic and will probably be the cause of my problem.


Step 1: My script, the permissions and file location.

In my research I found out that these three topics where important. So this should be valuable info.

-rwxr--r-- 1 root staff 183 Sep  6 15:22 dahuapurge.sh

/usr/local/bin

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#
#
#Keep the Dahua pics for max x time.
cd /media/pi/USB/Dahua/Dahua/
sudo rm -rf `ls -tl | tail -n +8`

Step 2: My cronjob config.

To create the cronjob I used the command crontab -e. In the file every line is commented except my manually written rule. I know, I set it to run every hour for the moment.

# AUTHOR: - xxxx xxxx
# DATE:   - 31/08/2018
# DESCR:  - Purge Cam pics
# LINK: -
#
0 * * * * /usr/local/bin/dahuapurge.sh

UPDATE:
I might have found one of my errors or maybe THE error. But I was quite far with my post so I share it anyway.
I added the option -rf to my rm command because I try to delete directories and not files. I modified my script and it should remove 1 directory again in about 30 mins.

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#
#
#Keep the Dahua pics for max x time.
cd /media/pi/USB/Dahua/Dahua/
sudo rm -rf `ls -tl | tail -n +7`

UPDATE:
Still not working but I'll try the suggestions that where posted and update this asap.

  • 1
    Depending on 'sudo' configuration it may ask for password and it will wait for answer forever doing nothing. Eliminate 'sudo' -- setup your cronjob as 'root' user. – John Doe Sep 6 '18 at 13:44
  • 2
    Ar you doing ls -tl or ls -t1? l will put lots of unnecessary text in the output, which rm won't know what to with... Please don't use images to show scripts etc.; indent 4 spaces to format the text as preformatted text. --edit-- I see you fixed this now. So don't use -l. – wurtel Sep 6 '18 at 13:51
  • don't parse ls -- especially when you're doing sudo rm -rf -- that seems a sure fire way to screw up your system. – glenn jackman Sep 6 '18 at 14:42
  • Looks like your script's owner is root, the script is executable only by root and executed by cron as another user because you are using the user crontab. – rexkogitans Sep 6 '18 at 14:57
  • Notice that the output of ls -lt contains a lot more than just filenames. Don't parse the output of ls. – Kusalananda Sep 6 '18 at 18:03
2

Things to check in this order:

  1. Does your script run non-interactively from command line with the exact owner set?

    sudo -H -u user -- command
    
  2. Is the crontab entry syntactically correct? Note that the systemwide crontab has a further column. Restart instead of reload the cron service, then you should get an appropriate error message in /var/log/syslog if the crontab has an error:

     Sep  6 15:56:50 myhost cron[834]: (CRON) STARTUP (fork ok)
     Sep  6 15:56:50 myhost cron[834]: Error: bad command; while reading /etc/crontab
     Sep  6 15:56:50 myhost cron[834]: (*system*) ERROR (Syntax error, this crontab file will be ignored)
    

The crontab contains a MAILTO variable pointing to a mail address. By this means you can debug your script. Whenever a script outputs something to stdout or stderr, its content is mailed to this address. For this purpose, an MTA (mail transport agent) is necessary. Take a look here.


To another thing: Passing the output of ls to a command is a design anti-pattern. Removing files named *.jpg that are older than 5 days (non-recursively) like this:

find /path -maxdepth 1 -type f -name '*.jpg' -ctime +5 -delete

For more details see man 1 find.

0

In a nutshell and then the outputs of the commands:

1/ Like advised by several people I stopped parsing ls. Especially when using with rm -rf and I understand why now. I had to use exec rm -rf though because delete does not work with 'not' empty directories.

2/ I created my crontab -e actions under root account (using sudo su).

3/ I changed the permissions of my scripts (allowed to execute by other groups too using chmod 756 file).

File permissions:

root@raspberrypi:/usr/local/bin# ls -l
total 8
-rwxr-xr-- 1 root staff 146 Sep  7 10:13 dahuapurge.sh

Script:

#!/bin/bash
#
#
#Keep the most recent Dahua pics.
find /media/pi/USB/Dahua/Dahua/ -maxdepth 1 -type d -name '20*' -mtime +10 -exec rm -rf {} +

Crontab last lines:

# AUTHOR: - xxxxx xxxx 
# DATE:   - 31/08/2018
# DESCR:  - Purge Cam pics
# LINK:   -
0 1 * * * /usr/local/bin/hikvisionpurge.sh
0 2 * * 2 /usr/local/bin/dahuapurge.sh


In the meantime I already created another one for another cam and working great.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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