Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BASH dirname basename problems with spaces

Tags:

bash

Writing a script to optimize my images for the web. Having issues with filenames and directories with spaces in the names.

Heres what I have:

read -p "Enter full path from root (/) to your site... example /var/www/public_html: " path1
echo ""
#read -p "Enter in ImageMagick quality (default is 80) if unsure enter 80: " optjpg
#echo ""
#id="$(id -u optiimage)"
cmd="id -u optiimage"
eval $cmd
id=$(eval $cmd)
tmp1="${path1}/shell/optiimage/imagemagick"
tmp2="${path1}/shell/optiimage/imagemagick/jpg"
restore1="${path1}/shell/optiimage/restore"
restore2="${path1}/shell/optiimage/restore/imagemagick/jpg"
backup1="${path1}/shell/optiimage/backup"
backup2="${path1}/shell/optiimage/backup/imagemagick/jpg"
log1="${path1}/shell/optiimage/log/imagemagick/"
DATE="$(date +%a-%b-%y-%T)"
# Need user input for www path from root
##
## Make directories
##
############################################################################################################
mkdir -p ${tmp1}
mkdir -p ${tmp2}
mkdir -p ${restore1}
mkdir -p ${restore2}
mkdir -p ${backup1}
mkdir -p ${backup2}
mkdir -p ${log1}
mkdir -p ${path1}/build

    echo "Processing JPG Files"
    find $path1 -iname "*jpg" | \
    #write out script to put on cron for image optimization
while read file;
do
    # If not equal to optimage uid
    # to check username id -u optimage
    if [ -u "${id}" ]; then
        filebase=`basename "$file" .jpg`
        dirbase=`dirname "$file"`
        echo "${dirbase}/${filebase}.jpg already optimized" >> ${log1}_optimized_$DATE.log
    else
    #simple log for size of image before optimization
    ls -s $file >> ${log1}_before_$DATE.log
    #Do the following if *.jpg found
        filebase=`basename $file .jpg`
        dirbase=`dirname $file`
        echo "cp -p ${dirbase}/${filebase}.jpg ${tmp2}" >> ${path1}/build/backup_jpg.txt
        echo "chown optiimage:www-data ${filebase}.jpg" >> ${path1}/build/restore_jpg.txt #${restore1}/imagemagick.sh
        echo "cp -p ${filebase}.jpg ${dirbase}/${filebase}.jpg" >> ${path1}/build/restore_jpg.txt #${restore1}/imagemagick.sh
    ##
    ## ImageMagick
    ## Original Command:
    ## convert $file -quality 80 ${filebase}.new.jpg
    ##########################
        echo "convert ${dirbase}/${filebase}.jpg -quality 80 ${tmp2}/${filebase}.jpg" >> ${path1}/build/imagemagick.txt 
        echo "mogrify -strip ${tmp2}/${filebase}.jpg" >> ${path1}/build/imagemagick.txt
        echo "chown optiimage:www-data ${tmp2}/${filebase}.jpg" >> ${path1}/build/owner_jpg.txt
        echo "rm ${dirbase}/${filebase}.jpg" >> ${path1}/build/remove_jpg.txt
        echo "cp -p ${tmp2}/${filebase}.jpg ${dirbase}/" >> ${path1}/build/migrate_jpg.txt

simple log for size of image after optimization

     ls -s $file >> ${log1}_after_$DATE.log
    fi
done

I have edited this with suggestions some have given me. It didn't seem to work. This works fine if I remove directories with spaces in the names otherwise it ends the name at the space and get errors directory doesn't exist.

like image 797
jmituzas Avatar asked Oct 20 '25 03:10

jmituzas


1 Answers

  1. You need to double-quote variable substitutions. This applies inside command substitutions as well as in the top-level lexical context. The only exception to this is assignment of a string variable from another string variable, e.g. str2=$str1;, although other types of variable assignments generally need quoting, such as assigning a string variable from an array slice, even if it only slices one element, e.g. str="${@:1:1}";.
  2. Although unlikely to be a problem here, the read builtin strips leading and trailing whitespace if you provide one or more NAMEs; you can solve that by not providing any NAMEs at all, and just letting it store the whole line in the $REPLY variable by default.
  3. You should always use the -r option of the read builtin, as that prevents its ill-advised default behavior of doing backslash interpolation/removal on the input data.
  4. If you don't need any kind of interpolation in a string literal, prefer the '...' syntax to "...", as the former does not do any interpolation.
  5. Prefer the [[ ... ]] expression evaluation form to the old-style [ ... ] form, as the former syntax is slightly more powerful.
  6. Prefer the $(...) command substitution form to the old-style `...` form, as the former syntax has more favorable nesting properties (namely, no need to escape the nested command substitution delimiters).

find "$path1" -iname '*jpeg'| \
    # write out script to put on cron for image optimization
    while read -r; do
        file=$REPLY;
        # If not equal to optimage uid
        # to check username id -u optimage
        if [[ -u "$id" ]]; then
            filebase=$(basename "$file" .jpeg);
            dirbase=$(dirname "$file");
            #MYBASENAME=$(basename "$1")
            echo "${dirbase}/${filebase}.jpeg already optimized" >>"${log1}_optimized_$DATE.log";
        fi;
    done;
;
like image 156
bgoldst Avatar answered Oct 21 '25 21:10

bgoldst



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!