Home > OS >  Why check if file is exists in shell always false?
Why check if file is exists in shell always false?

Time:10-11

I created a cron using bash to delete files older than 3 days, but when checking the age of the files with mtime 3 &> /dev/null it is always false. here's the script:

now=$(date)

create log file

file_names=('*_takrib_golive.gz' '*_takrib_golive_filestore.tar.gz')
touch /media/nfs/backup/backup_delete.log
echo "Date: $now" >> /media/nfs/backup/backup_delete.log
for filename in "${file_names[@]}";
do
 echo $filename

        if ls /media/nfs/backup/${filename} &> /dev/null
        then
                echo "backup files exist"
                if find /media/nfs/backup -maxdepth 1 -mtime  3 -name ${filename} -ls &> /dev/null
                then
                        echo "The following backup file was deleted" >> /media/nfs/backup/backup_delete.log 
                        find /media/nfs/backup -maxdepth 1 -mtime  3 -name ${filename} -delete
                else
                        echo "There are no ${filename} files older than 3 days in /media/nfs/backup" &>> /media/nfs/backup/backup_delete.log
                fi
        else
                echo "No ${filename} files found in /media/nfs/backup" >> /media/backup/backup_delete.log
        fi
done
exit 0

in if find /media/nfs/backup -maxdepth 1 -mtime 3 -name ${filename} -ls &> /dev/null always goes to else, even though files older than 3 days are in the directory

CodePudding user response:

You are not quoting the -name attribute so it expands to the name of the file which already exists.

I would refactor this rather extensively anyway. Don't parse ls output and perhaps simplify this by making it more obvious when to quote and when not to.

Untested, but hopefully vaguely useful still:

#!/bin/bash

backup=/media/nfs/backup
backuplog=$backup/backup_delete.log
# no need to touch if you write to the file anyway
date  "Date: %C" >> "$backuplog"

# Avoid using a variable, just loop over the stems
for stem in takrib_golive takrib_golive_filestore.tar
do
    # echo $filename
    # Avoid parsing ls; instead, loop over matches
    for filename in "$backup"/*_"$stem".gz; do
        pattern="*_$stem.gz"
        if [ -e "$filename" ]; then
            echo "backup files exist"
            if files=$(find "$backup" -maxdepth 1 -mtime  3 -false -o -name "$pattern" -print -delete)
            then
                echo "The following backup file was deleted" >> "$backuplog"
                echo "$files" >> "$backuplog"
            else
                echo "There are no $pattern files older than 3 days in $backup" >> "$backuplog"
            fi
        else
            echo "No $pattern files found in $backup" >> "$backuplog"
        fi
        # Either way, we can break the loop after one iteration
        break
    done
done
# no need to explicitly exit 0

The for if [ -e ... ] arrangement is slightly clumsy, but that's how you check if a wildcard matched any files. If the wildcard did not match, if [ -e will check for a file whose name is literally the wildcard expression itself, and fail.

  • Related