
Я уже пытался найти ответ здесь, но не нашел. Извините за мой плохой английский, потому что мне немного сложно говорить по-английски. У меня также почти нет навыков написания скриптов на bash, поэтому мой скрипт может выглядеть очень плохо. Он просто сделан из примеров, которые я смог найти в интернете, но теперь я застрял с этим, поэтому мне нужна ваша помощь, ребята!
Вот что мне нужно от этого скрипта:
- Рекурсивно найти все файлы PDF (форум Simple Machines хэширует вложения, поэтому расширение .dat)
- Определить тип PDF из файлов .dat
- Затем мне нужно использовать программу ps2pdf для оптимизации всех новых (за последние 24 часа) файлов PDF.
- Мне также нужно сохранить исходную временную метку из оптимизированных PDF-файлов.
- Этот файл «24h-pdf-compress-»
date +"%d-%m-%Y"
«.txt» предназначен только для регистрации событий, чтобы я мог позже проверить, работает ли он.
Структура каталога вложений форума smf следующая:
Под папкой вложений есть папка по году (2020).
Под каждым годом есть папка по месяцу (04 = апрель).
Под каждым месяцем находятся все файлы вложений за этот месяц.
Все файлы (jpg,png,pdf) имеют одинаковое расширение .dat.
/var/www/foorumi/attachments/2020/04/all-files-from-april.dat
Мой сценарий:
#!/bin/bash
cd /var/www/foorumi/attachments
find . -name '*.dat' -mtime -1 | xargs file -i | grep 'pdf' | cut -d: -f1 > "24h-pdf-compress-"`date +"%d-%m-%Y"`".txt"
find . -name '*.dat' -mtime -1 | xargs file -i | grep 'pdf' | cut -d: -f1 | while read -r file
do
touch -r "$file" "dummy_file"
ps2pdf "$file" "new_$file" # PROBLEM
rm "$file"
mv "new_$file" "$file" # PROBLEM
touch -r "dummy_file" "$file"
rm dummy_file
done
mv "24h-pdf-compress-"`date +"%d-%m-%Y"`".txt" /root/24h_pdf_compress_log
find . -iname '*.dat' -user root -exec chown www-data:www-data {} \;
exit 0
Хорошо, проблема в следующем. Когда я запускаю, find . -name '*.dat' -mtime -1 | xargs file -i | grep 'pdf' | cut -d: -f1
он печатает файлы типа ./04/somepdfattachment.dat
, поэтому, когда скрипт запускается, ps2pdf "$file" "new_$file"
он пытается создать новое имя файла типа new_./04/somepdfattachment.dat
.. это звучит неправильно.
Следующая ошибка возникает, когда скрипт пытается переименовать файл mv "new_$file" "$file"
, поскольку теперь он пытается переименовать new_./04/somepdfattachment.dat
файл, вернув ему исходное имя.
Надеюсь, вы понимаете, что я пытаюсь вам сказать. Я могу предоставить больше информации, если нужно.
Заранее спасибо!
ОБНОВЛЯТЬ! Как и предложил @pLumo, я изменил скрипт, и теперь он, кажется, работает. Надеюсь, я правильно понял предложения..
Вложения на форуме Simple Machines именуются следующим образом: 403_57066cef00fb1d57137b5613f076d254e89b88bc.dat
"403" = порядковый номер вложений, далее следует 404, затем 405 и так далее.
"57066cef00..." = случайный хеш
".dat"= все расширения вложений (jpg,png,pdf) переименовываются в .dat после загрузки.
Обновленный сценарий:
...
do
touch -r "$file" "dummy_file"
newname="$(dirname "$file")/new_$(basename "$file")"
ps2pdf "$file" "$newname" || continue
rm "$file"
mv "$newname" "$file"
touch -r "dummy_file" "$file"
rm dummy_file
done
...
решение1
Вам нужно разделить $file
его на путь ( dirname
) и имя файла ( basename
) и вставить new_
между ними:
newname="$(dirname "$file")/new_$(basename "$file")"
ps2pdf "$file" "$newname"
Дополнительные подсказки:
- Ваша
find
команда небезопасна, если в результатах есть новые строки, это испортит ваши результаты. Возможно, вам стоит ознакомиться с нулевым разделителем для безопасной передачи имен файлов. - Я думаю, то же самое применимо, если в именах файлов есть двоеточия, они
cut
будут разделены в неправильном месте. - Используйте
-exec
вместоxargs
:find . -name '*.dat' -mtime -1 -exec file -i {} +
- Если
ps2pdf
не получается, вы все еще продолжаете, удаляя исходный файл. Вы можете использовать, например:ps2pdf ... || continue
для перехода к следующей итерации при неудаче. - Пожалуйста, используйте более описательное название, тогда ваш вопрос может быть полезен и другим людям.