0

I have a security camera which sends pictures it captures to an ftp server on my network, and I developed a script to trim the old files from the receiving directory. The script works well when started from the command line, so I added a line to crontab to execute the script twice a day.

# Remove old security images / videos from directory
1       7,19    *       *       *               /home/ftp/bin/secpurg

The script wasn't working though. The directory was getting full, so I decided to execute with #!/bin/bash -x to see what was going on. The following messages began to appear in my mail:

+ fileAge=10
+ SecDir=/home/ftp/_Security/
+ maxDirSize=3000000
++ du -s /home/ftp/_Security/
++ cut -f1
/home/ftp/bin/secpurg: line 11: cut: command not found
/home/ftp/bin/secpurg: line 11: du: command not found
+ secDirSize=
+ '[' -ge 3000000 ']'
/home/ftp/bin/secpurg: line 14: [: -ge: unary operator expected

Hu? 'cut' and 'du' are not found when executing the script via CRON? Can anyone provide me with some insight as to why these commands work just fine when I execute the script from a terminal, but not when it's executed from CRON?

In case it's useful, I've provided the script for reference:

#!/bin/bash -x
# secpurg - find and remove older security image files.

# Variable decleration
fileAge=10
SecDir="/home/ftp/_Security/"
maxDirSize=3000000

# Determine the size of $SecDir
secDirSize=`du -s $SecDir | cut -f1`

# If the size of $SecDir is greater than $maxDirSize ...
while [ $secDirSize -ge $maxDirSize ]
do
        # remove files of $fileAge days old or older ...
        find $SecDir* -mtime +$fileAge -exec rm {} \;

        # Generate some output to email a report when files are deleted.
        # set -x

        # Expanding $SecDir* makes for big emails, so we don't do that, but echo the command for reference ...
        echo -e "\t\t[ $secDirSize -ge $maxDirSize ] 
                fileAge=$fileAge
                SecDir=$SecDir
                maxDirSize$maxDirSize
                find $SecDir* -mtime +$fileAge -exec rm {} \;"

        # decrement $fileAge ...
        fileAge=$(( $fileAge - 1 ))

        # and re-determine the size of $SecDir.
        secDirSize=`du -s $SecDir | cut -f1`

        # Just in case things are crazy, don't delete todays files.
        if [ $fileAge -le 1 ]
        then
                secDirSize=0
        fi

        # Stop generating output for email.
        # set +x        
done

--

EDIT:

Adding echo "PATH -$PATH-" to the top of the script results in the first line of the email being: + echo 'PATH -~/bin:$PATH-'. So now my questions is, what happened to my PATH, and what's the recommended way to add useful directories to it? I assume that this is effecting all of my CRON jobs.

--

  • Try adding an echo "PATH -$PATH-" to the script to see what is going on. – Stephen Rauch Mar 12 '17 at 5:25
  • @Stephen Rauch - added echo "PATH -$PATH-" to the top of the script. Now the first line of the email is: + echo 'PATH -~/bin:$PATH-'. So now my questions is, what happened to my PATH? And why is $PATH part of it? – DrDR Mar 12 '17 at 5:33
  • Is..... You comment got truncated. But regardless, this sort of info should be edited into the question for all to easily see. – Stephen Rauch Mar 12 '17 at 5:35
  • So the path has $PATH and ~ in it. This likely means that who ever tried to add ~/bin to the path enclosed the statement in ' instead of ". Find and fix that and you are probably good to go. – Stephen Rauch Mar 12 '17 at 6:49
2

It works from from an interactive session so i would surmise it's a setting in cron.

Ensure you either don't have a PATH= line in your crontab, it if you do that it contains explicit directories (cron path assignment isn't additive like the shell)

PATH=/home/myhomedir/bin:/usr/local/bin:/bin:/usr/bin
  • 1
    BINGO! I'd added PATH="~/bin:$PATH" to crontab in an effort to expand my path to include the users local bin directory. I've replaced that with PATH=/home/ftp/bin:/home/ftp/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin. Thanks for the lesson. :-) – DrDR Mar 12 '17 at 15:31
0

Since echoing $PATH gives ~/bin:$PATH, you may well have something in your ~/.bashrc file that looks like

PATH='~/bin:$PATH'

This sets PATH to the literal string ~/bin:$PATH in which, because of the single quotes, $PATH never gets expanded to whatever the path was before that assignment.

Change the single quotes to double quotes.

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.