2014-01-29 2 views
0

Я использую следующий сценарий. Я нашел here с использованием версии CentOS 6.5 и GNU bash версии 4.1.2 (встроенной в ОС).Оператор Unary, ожидаемый при сжатии статических файлов

#! /bin/bash 

FILETYPES=("*.html" "*.css" "*.js" "*.xml") 
DIRECTORIES="/var/www/html/phpmyadmin" 
MIN_SIZE=32 

for currentdir in $DIRECTORIES 
do 
    for i in "${FILETYPES[@]}" 
    do 
     find $currentdir -iname "$i" -exec bash -c 'PLAINFILE={};GZIPPEDFILE={}.gz; \ 
     if [ -e $GZIPPEDFILE ]; \ 
     then if [ `stat --printf=%Y $PLAINFILE` -gt `stat --printf=%Y $GZIPPEDFILE` ]; \ 
       then gzip -1 -f -c $PLAINFILE > $GZIPPEDFILE; \ 
       fi; \ 
     elif [ `stat --printf=%s $PLAINFILE` -gt $MIN_SIZE ]; \ 
      then gzip -1 -c $PLAINFILE > $GZIPPEDFILE; \ 
     fi' \; 
    done 
done 

Но каждый раз, когда я исполняю, я окажусь с:

bash: line 5: [: 10262: unary operator expected 
bash: line 5: [: 5329: unary operator expected 
bash: line 5: [: 264839: unary operator expected 
bash: line 5: [: 183256: unary operator expected 
bash: line 5: [: 12481: unary operator expected 
[...] and lots more :-(

Я попытался с помощью [[ в строке 5 elif [ stat --printf=%s $PLAINFILE -gt $MIN_SIZE ];, но я получаю странные вещи через стандартный вывод.

+0

Если вы используете 'bash' 4 или более поздней версии, вы можете использовать опцию globstar, чтобы устранить потребность в' find' и громоздкий скрипт-как-нить. – chepner

ответ

2

Я думаю, что ваша переменная $MIN_SIZE не попадает в подоболочку, поэтому она пуста и не цитируется, и поэтому вы получаете это вводящее в заблуждение сообщение об ошибке, потому что оболочка видит что-то вроде [ 123 -gt ] после расширения переменной (не цитирование является шагом к темной стороне и ведет к ненависти и страданиям).

Вы должны установить, что константа в субоболочке:

-exec bash -c '\ 
    MIN_SIZE=32; \ 
    PLAINFILE={};GZIPPEDFILE={}.gz; \ 
    if [ -e $GZIPPEDFILE ]; \ 
    then if [ `stat --printf=%Y $PLAINFILE` -gt `stat --printf=%Y $GZIPPEDFILE` ]; \ 
      then gzip -1 -f -c $PLAINFILE > $GZIPPEDFILE; \ 
      fi; \ 
    elif [ `stat --printf=%s $PLAINFILE` -gt $MIN_SIZE ]; \ 
     then gzip -1 -c $PLAINFILE > $GZIPPEDFILE; \ 
    fi' \; 

И, конечно, вы должны процитировать ваши вещи правильно, по крайней мере, получить достойные сообщения об ошибках:

-exec bash -c '\ 
    MIN_SIZE=32; \ 
    PLAINFILE={};GZIPPEDFILE={}.gz; \ 
    if [ -e "$GZIPPEDFILE" ]; \ 
    then if [ "`stat --printf=%Y "$PLAINFILE"`" -gt "`stat --printf=%Y "$GZIPPEDFILE"`" ]; \ 
      then gzip -1 -f -c "$PLAINFILE" > "$GZIPPEDFILE"; \ 
      fi; \ 
    elif [ "`stat --printf=%s "$PLAINFILE"`" -gt "$MIN_SIZE" ]; \ 
     then gzip -1 -c "$PLAINFILE" > "$GZIPPEDFILE"; \ 
    fi' \; 
+0

Вот и все! Большое спасибо!! – Axel

0

Используйте globstar вариант, чтобы избежать необходимо использовать find для получения всех совпадающих файлов в подкаталогах. #!/Бен/Баш

FILETYPES=("*.html" "*.css" "*.js" "*.xml") 
DIRECTORIES="/var/www/html/phpmyadmin" 
MIN_SIZE=32 

get_mtime() { stat --printf=%Y "$1"; } 

for currentdir in "$DIRECTORIES" 
do 
    for i in "${FILETYPES[@]}" 
    do 
     for fname in "$currentdir/**/$i" 
     do 
      if [[ -e $fname.gz ]]; then 
       if (($(stat --printf=%Y "$1" "$fname") > 
        $(stat --printf=%Y "$1" "$fname.gz"))); then 
        gzip -1 -f -c "$fname" > "$fname.gz" 
       fi 
      elif (($(stat --printf=%s "$fname") > MIN_SIZE)); then 
       gzip -1 -f -c "$fname" > "$fname.gz" 
      fi 
     done 
    done 
done 
Смежные вопросы