У меня есть куча недисциплинированных пользователей с почтовыми учетными записями на моем сервере. Они никогда не очищают свои папки для мусора и мусора, а количество файлов увеличивается до бесконечности.

Я создаю скрипт Bash для периодического стирания этих файлов с помощью cron.

Я сделал это:

  1. создайте текстовый файл со списком каталогов, которые я хочу стереть;
  2. создайте скрипт, который будет читать построчно каждый каталог и стирать все с cur и new .

Пример текстового файла:

~/mail/.Junk/cur
~/mail/.Junk/new
~/mail/.Trash/cur
~/mail/. Trash/new
~/mail/.administrative@example.com/.Junk/cur
~/mail/.administrative@example.com/.Junk/new
~/mail/.administrative@example.com/.Trash/cur
~/mail/.administrative@example.com/.Trash/new
~/mail/.finance@example.com/.Junk/cur
~/mail/. finance@example.com/.Junk/new
~/mail/. finance@example.com/.Trash/cur
~/mail/. finance@example.com/.Trash/new

Я нахожусь на первом этапе создания сценария, где я проверяю, могу ли я получить доступ к каталогам и перечислить их содержимое.

Итак, у меня есть этот скрипт:

#!/bin/bash 

while read line 
do 
ls $line
done < ~/directories.txt 

Когда я запускаю скрипт, я получаю следующую ошибку:

ls: не может получить доступ к ~/mail/.administrative@example.com/.Junk/new/: нет такого файла или каталога

для всех каталогов, но если я наберу

ls ~/mail/.administrative@example.com/.Junk/new/

это работает отлично.

Зачем?

1 ответ1

3

Цитируйте свои переменные!

while read line а затем выполнение ls $line не будет работать; Вы должны использовать ls "$line" для обработки пробелов в переменных. Как правило, указывайте ваши переменные, когда вы их используете!

Если вы этого не сделаете, у вас возникнет огромная проблема при попытке получить rm $line , если эта строка

~/mail/. Trash/new

Затем, если вы выполните ls $line , она попытается перечислить две папки:

  • ~/mail
  • Trash/new

В худшем случае, если вы выполнили rm -rf $line , вы удалили бы ~/mail полностью ! Итак, используйте ls "$line" внутри вашего цикла. И то же самое для rm .

На самом деле, наиболее надежный способ построчного чтения файла и правильной обработки пробелов объясняется здесь:

while IFS= read -r line; do
    ls "$line"
done < "$file"

-r предотвращает расширение обратной косой черты, а IFS= помогает в случае, если строка начинается или заканчивается пробелом, который в противном случае оболочка обрезала бы.

Не используйте пути, которые должны быть расширены!

Если ваш текстовый файл содержит пути, которые будут расширены только позже, путь будет меняться в зависимости от того, кто и где выполняет сценарий. Здесь ~ будет расширен до домашнего пути пользователя во время выполнения, поэтому, если вы запускаете скрипт от имени пользователя root , он будет начинаться из /root , а не из дома пользователя в момент создания текстового файла.

Поэтому храните полные пути в вашем файле.

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