Linux shell script for delete old files from ftp

2019-02-10 05:35发布

问题:

There is a problem - need to store the database backup on the FTP. On the FTP should not be more than 10 back-ups, ie, After you add backup to FTP should be removed, the oldest files to make the total number of files can not exceed 10 pieces. How can we implement such a removal from the ftp? I'm trying to write a script, but does not work delete:

x=1
ftp -vn $FTP_SERVER<<!
user $FTP_LOGIN $FTP_PASSWORD
binary
put $DUMP_FILE_NAME

for i in `ls -t` do
    if [ $x -le $keep ] then
        ((x++))
        continue
    fi
    delete $i
done

bye
EOF
</i>

回答1:

This is a script I wrote to remove any files on a remote ftp site older than 7 days. It works by retrieving a listing of the directory, parsing the modified date, and then re-connecting to delete any files older than ndays.

I suspect that the numbers hard-coded into the loop (element date) may change depending on the setup of your system. The return formatting of the ls command is dependent on the local system settings.

Assuming your backups are every day, then setting ndays to 10 might solve your problem.

#!/bin/bash
# get a list of files and dates from ftp and remove files older than ndays
ftpsite="ftp.yourserver.com"
ftpuser="loginusername"
ftppass="password"
putdir="/public_ftp/admin/logs"

ndays=7


# work out our cutoff date
MM=`date --date="$ndays days ago" +%b`
DD=`date --date="$ndays days ago" +%d`


echo removing files older than $MM $DD

# get directory listing from remote source
listing=`ftp -i -n $ftpsite <<EOMYF 
user $ftpuser $ftppass
binary
cd $putdir
ls
quit
EOMYF
`
lista=( $listing )

# loop over our files
for ((FNO=0; FNO<${#lista[@]}; FNO+=9));do
  # month (element 5), day (element 6) and filename (element 8)
  #echo Date ${lista[`expr $FNO+5`]} ${lista[`expr $FNO+6`]}          File: ${lista[`expr $FNO+8`]}

  # check the date stamp
  if [ ${lista[`expr $FNO+5`]}=$MM ];
  then
    if [[ ${lista[`expr $FNO+6`]} -lt $DD ]];
    then
      # Remove this file
      echo "Removing ${lista[`expr $FNO+8`]}"
      ftp -i -n $ftpsite <<EOMYF2 
      user $ftpuser $ftppass
      binary
      cd $putdir
      delete ${lista[`expr $FNO+8`]}
      quit
EOMYF2


    fi
  fi
done


回答2:

This one is dealing with sftp and has proper date check as the script from @Graeme is only working within one month:

#!/bin/bash
# get a list of files and dates from ftp and remove files older than ndays
ftpsite="sftp -b-  -oIdentityFile=<KEYFILE> -oPort=<PORT>  <USER>@<HOST>"
putdir="/data"

ndays=19

# work out our cutoff date
MM=`date --date="$ndays days ago" +%b`
DD=`date --date="$ndays days ago" +%d`
TT=`date --date="$ndays days ago" +%s`

echo removing files older than $MM $DD

# get directory listing from remote source
echo "
cd $putdir
ls -l
"|$ftpsite >dirlist

# skip first three and last line, ftp command echo
listing="`tail -n+4 dirlist|head -n-1`"

lista=( $listing )

# loop over our files
for ((FNO=0; FNO<${#lista[@]}; FNO+=9));do
  # month (element 5), day (element 6) and filename (element 8)
  # echo Date ${lista[`expr $FNO+5`]} ${lista[`expr $FNO+6`]}          File: ${lista[`expr $FNO+8`]}

  fdate="${lista[`expr $FNO+5`]} ${lista[`expr $FNO+6`]} ${lista[`expr $FNO+7`]}"
  sdate=`date --date="$fdate" +%s`
  # check the date stamp
  if [ $sdate -lt $TT ]
  then
      # Remove this file
      echo "$MM $DD: Removing  ${lista[`expr $FNO+5`]} /  ${lista[`expr $FNO+6`]} / ${lista[`expr $FNO+8`]}"
      $ftpsite <<EOMYF2
      cd $putdir
      delete ${lista[`expr $FNO+8`]}
      quit
EOMYF2

  fi
done


回答3:

Here's a shorter solution using lftp, that'll also work with subdirectories:

#!/bin/bash
# get a list of files and dates from ftp and remove files older than ndays
ftpsite="ftpback-xxx.ovh.net"
ftpuser="user"
ftppass="pass"
#remote folder in which you want to delete files
putdir="/"
nullfolder="/tmp/null"

ndays=19

mkdir -p nullfolder
MM=`date --date="$ndays days ago" +%b`
DD=`date --date="$ndays days ago" +%d`

echo removing files older than $MM $DD
#The no-ssl is there because it's on a local network and remote doesn't support ftp
lftp -e "set ftp:ssl-allow no; mirror $putdir $nullfolder --older-than=now-${ndays}days --Remove-source-files; exit" -u $ftpuser,$ftppass $ftpsite

rm $nullfolder/* -Rf

It has two drawbacks though:

  • It will first download those old files (before removing them later), so it uses some more bandwidth
  • Those old files will take some space on the local disk before being removed. You can use nullfs to pally to that


回答4:

It has passed several years, and while Graeme's answer helped me but I faced some problems with it and here is how to fix them.

Sometimes the sentence like Trying aaaa:bbb:ccc:dddd::0... is at first line of listing varable. You have to remove it.

rem="Trying aaaa:bbb:ccc:dddd::0...";
rep="";
listing=${listing/$rem/$rep}

Also jsan commented he faced other issue: "value too great for base (error token is "08")" when $DD is 0x it is interpreted as x in octal (problem for 8 and 9)

I faced same problem. So you better make sure there is no nun-numeric characters in $MM or $DD and then remove the 0 from beggining. Like 08 should become 8.

so before looping on files, add this code:

MM=$(tr -dc '0-9' <<< $MM)
DD=$(tr -dc '0-9' <<< $DD)
MM=${MM#0}
DD=${DD#0}

First two lines remove non-numeric characters and second last lines fix the problem with 08



回答5:

Don't use FTP (for many reasons). However, if you do that in ssh, you get a tty, environment, and everything else. Also, if you want a file 10 days old to be deleted (and not one 10 calendar days stale) a simple find -mtime +10 -delete would replace that for loop. So:

ssh user@host 'find $DIR -mtime +10 -delete'

If you want FTP, look at NcFTP, if I recall correctly there were some pretty decent scripting capabilities there.



标签: shell ftp