Автоматизация jpegtran | FreeBSD

Решил заняться оптимизацией изображений на вебсервере – jpegtran и подобные утилиты позволяют уменьшить размер изображений без потери качества – удаляют мета информацию и т.д.

Вызов такой:

jpegtran -copy none -optimize -perfect -outfile outfile.jpeg sourcefile.jpeg

или

jpegtran -copy none -optimize -perfect source.jpg > dest.jpg

Все хорошо, но для оптимизации работы хорошо бы написать скрипт для автоматизации работы – указать целевую папку и запланировать в крон.

Пришлось немного поупражняться в «программировании» в шелл.
Основа для скрипта нашлась в сети, я лишь внес небольшие изменения и оформил функцией. Ищем файлы с разрешением jpg, jpeg, png и обрабатываем копируя во временный файл с последующей заменой исходного файла.

tran() {
    echo "Start OPTIMIZING...."
    for file
    in `find $DIR -iname "*.jpg" -or -iname "*.png" -or -iname "*.jpeg"`;
    do
     ext=${file##*.}
        if [ -n "$ext" ]; then
if [ "$ext" = "jpg" ]; then
         echo "optimizing ${file} as jpeg file with jpegtran"
          jpegtran -copy none -optimize -perfect -outfile temp_file.jpg $file
          mv -f temp_file.jpg $file;
        fi
        if [ "$ext" = "jpeg" ]; then
    echo "optimizing ${file} as jpeg file with jpegtran"
    jpegtran -copy none -optimize -perfect -outfile temp_file.jpeg $file
    mv -f temp_file.jpeg $file;
        fi
        if [ "$ext" = "png" ]; then
           echo "optimizing ${file} as png file with pngcrush"
       pngcrush -rem alla -reduce -brute "$file" temp_file.png;
            mv -f temp_file.png $file;
         fi
        fi
    done;
      echo "OPTIMIZE IS DONE!";
      echo "You can find your files before optimization in $DIR.old"
    }

В самом начале скрипта обьявляем переменные:

DIR=$1; DIR=`echo $1 |sed -e 's,\(.\)/$,\1,'`

DIR – берется из строки запроса: $0 – это всегда имя скрипта в строке, $1 – это то что мы передаем скрипту в качестве аргумента:

./script.sh argument

У нас вызов будет такой (в качестве аргумента передаем имя папки в кторой лежат файлы для обработки):

./script.sh /dir_to_proceed

Строка DIR=`echo $1 |sed -e 's,\(.\)/$,\1,'` удаляет слеши в конце пути котрый мы указали – целевая папка должна указываться без слеша в конце.

Бэкапим целевую папку (можно указать временную метку вместо .old):

back() {
    mkdir "$DIR.old";
    for i in `ls $DIR`;
    do
    cp $DIR/$i $DIR.old;
    done;
    echo "Your files copied to $DIR.old...."
    }

Теперь нужно провести проверку того что мы передали скрипту переменную – указали какую папку обработать. Пишем цикл с условием – если переменная $DIR не пустая ( -z) значит выполняем функции бэкапа и обработки, если переменную скрипту не передали – выходим с ошибкой (exit 1):

dojob() {
    if [ -z "$DIR" ]
    then
    echo "Script usage: ./tran.sh /dirname"
    exit 1
    else
    back
    tran
    fi
    }

Теперь осталось вызвать функцию:

echo "Script is starting...."
    dojob
    echo "Script job finished"
    exit 0

Теперь все собираем вместе:

#!/bin/sh.

    DIR=$1;
    DIR=`echo $1 |sed -e 's,\(.\)/$,\1,'`

    back() {
    mkdir "$DIR.old";
    for i in `ls $DIR`;
    do
    cp $DIR/$i $DIR.old;
    done;
    echo "Your files copied to $DIR.old...."
    }

    tran() {
    echo "Start OPTIMIZING...."
    for file
    in `find $DIR -iname "*.jpg" -or -iname "*.png" -or -iname "*.jpeg"`;
    do
     ext=${file##*.}
        if [ -n "$ext" ]; then
      if [ "$ext" = "jpg" ]; then
         echo "optimizing ${file} as jpeg file with jpegtran"
          jpegtran -copy none -optimize -perfect -outfile temp_file.jpg $file
          mv -f temp_file.jpg $file;
        fi
        if [ "$ext" = "jpeg" ]; then
              echo "optimizing ${file} as jpeg file with jpegtran"
              jpegtran -copy none -optimize -perfect -outfile temp_file.jpeg $file
             mv -f temp_file.jpeg $file;
        fi
        if [ "$ext" = "png" ]; then
           echo "optimizing ${file} as png file with pngcrush"
           pngcrush -rem alla -reduce -brute "$file" temp_file.png;
            mv -f temp_file.png $file;
         fi
        fi
    done;
      echo "OPTIMIZE IS DONE!";
      echo "You can find your files before optimization in $DIR.old"
    }

    dojob() {
    if [ -z "$DIR" ]
    then
    echo "Script usage: ./tran.sh /dirname"
    exit 1
    else
    back
    tran
    fi
    }

    echo "Script is starting...."
    dojob
    echo "Script job finished"
    exit 0

Не забываем установить соответствующие пакеты: jpegtran и pngcrush!
Осталось только научить скрипт обрабатывать папки с рекурсией, протестировать и добавить в крон…