Я использую следующий скрипт для автоматической загрузки файлов из моего удаленного сеанса с помощью lftp:

set ftp:list-options -a
set ftp:ssl-allow no
set mirror:use-pget-n 5
set cmd:fail-exit true
open ftp.myseedbox.com
mirror -c -P5 --Remove-source-files --log=synctorrents.log /completed /media/ExternalHd/
quit

Теперь это удаляет файлы после успешной передачи, но оставляет пустые папки. Есть ли какой-нибудь метод / скрипт для автоматического удаления пустых папок?

3 ответа3

2

В Linux есть встроенный инструмент для этого, rmdir:

$ man rmdir
NAME
       rmdir - remove empty directories

SYNOPSIS
       rmdir [OPTION]... DIRECTORY...

DESCRIPTION
       Remove the DIRECTORY(ies), if they are empty.

Вы можете безопасно запустить такую команду, как rmdir * поскольку она удалит ТОЛЬКО пустые каталоги.

1

В моем случае rmdir -f * не работал, и мне пришлось искать другое решение.

У меня была такая ситуация:

зеркалирование с помощью этой команды в моем скрипте:

lftp -u ${FTPUSER},${FTPPASS} ${FTPHOST} -e "mirror --depth-first --no-empty-dirs --Remove-source-files --verbose . ${MYLOCALFOLDER} ; bye" >> $LOG 2>&1

но это оставило пустое дерево каталогов, как это на удаленном:

|-- 693
|   `-- 2014-01-06
|-- 75
|   |-- 2014-01-10
|   |-- 2014-01-11
|   |-- 2014-01-12
|   |-- 2014-01-13
|   |-- 2014-01-14
|   |-- 2014-01-15
|   `-- 2014-01-16
|-- 811
|   |-- 2014-01-07
|   |-- 2014-01-08
|   |-- 2014-01-09
|   |-- 2014-01-10
|   |-- 2014-01-11
|   |-- 2014-01-12
|   |-- 2014-01-13
|   |-- 2014-01-14
|   |-- 2014-01-15
|   `-- 2014-01-16

поэтому я добавил это в свой скрипт:

# create a local mirror with the empty dir structure                                                                   
mkdir /tmp/lftp_emptydirlist
cd /tmp/lftp_emptydirlist
lftp -u ${FTPUSER},${FTPPASS} ${FTPHOST} -e "mirror ;bye"

# sort -r is to reverse and leave the empty parent dirs at the end. 
# egrep will strip the "." directory from the list   
find|sort -r|egrep -v '^.$' > /tmp/emptydirlist.txt

# remove remote empty directories                                                                                      
for i in $(cat /tmp/emptydirlist.txt) do
   lftp -u ${FTPUSER},${FTPPASS} ${FTPHOST} -e "rmdir -f $i; bye"
done

# remove local empty directories                                                                                        
find ${MYLOCALFOLDER} -type d -empty -delete

Если вы хотите проверить и посмотреть, что на самом деле делает команда bash 'for', вы можете добавить 'echo' перед командой lftp, чтобы она выводила ее вместо того, чтобы фактически делать это:

for i in $(cat /tmp/emptydirlist.txt); do echo lftp -u ${FTPUSER},${FTPPASS} ${FTPHOST} -e "rmdir -f $i; bye"; done

Недостатком этого подхода является то, что он откроет много сеансов ftp, фактически один сеанс для каждого каталога, который нужно удалить ... что, вероятно, не лучший способ, но ... в любом случае это лучший способ, который я нашел до сих пор :)

1

rmdir * не работает должным образом в lftp, так как не поддерживает расширение по шаблону. Это можно преодолеть с помощью приведенного ниже кода, для удаления вложенных папок требуется некоторая грубая сила:

glob -a rmdir /remote/directory/*/*/*
glob -a rmdir /remote/directory/*/*
glob -a rmdir /remote/directory/*

Я не рекомендую использовать rm -rf, так как любые файлы, добавленные во время выполнения зеркала (и любые файлы, которые не удалось перенести), будут удалены без зеркалирования.

Вот код, который удаляет пустые папки (включая вложенные и папки, содержащие пробелы), сохраняя файлы, которые не были отражены, и выполняет все за один сеанс Lftp:

lftp -p $port -u $login,$pass sftp://$host <<-EOF
cd "$remote_dir"
find . | grep [[:alnum:]] | sed -e 's~.~rmdir" "-f" "\".~' -e 's~$~\"~' | tac > /tmp/delete
mirror -v --no-empty-dirs --Remove-source-files -c -P3 $remote_dir $local_dir
source /tmp/delete
quit
EOF

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .