Linux – Using a shell script but it fails with spaces on directory or name

linuxscriptshell

I'm relatively new to Linux script and I'm having an issue with one I'm trying to use when there are spaces in the directory name or file name. The script shrinks PDF files so that i can put them in an e-mail.

gs  -q -dNOPAUSE -dBATCH -dSAFER \
    -sDEVICE=pdfwrite \
    -dCompatibilityLevel=1.3 \
    -dPDFSETTINGS=/screen \
    -dEmbedAllFonts=true \
    -dSubsetFonts=true \
    -dColorImageDownsampleType=/Bicubic \
    -dColorImageResolution=72 \
    -dGrayImageDownsampleType=/Bicubic \
    -dGrayImageResolution=72 \
    -dMonoImageDownsampleType=/Bicubic \
    -dMonoImageResolution=72 \
    -sOutputFile=Compressed$1 \
     "$1"

so I use the command

find * -type f -name "*.pdf" -exec sudo sh ~/shrinkpdf.sh {} \;

It will work on the PDF in the same folder that has no spaces in it, but whenit tries to access the folders within that have spaces it errors and created a file using only the first word of the folder name.

How can I get this to accept files and folders with spaces in the names?

Thanks from a user who is Shell Script Challenged,

Best Answer

You are quoting one of the $1 's but not the other. If your path contains spaces, quoting is essential. To be safe, it's best to assume that every path a script receives contains problematic characters, and quote every path.

Here's my suggestion:

gs  -q -dNOPAUSE -dBATCH -dSAFER \
    -sDEVICE=pdfwrite \
    -dCompatibilityLevel=1.3 \
    -dPDFSETTINGS=/screen \
    -dEmbedAllFonts=true \
    -dSubsetFonts=true \
    -dColorImageDownsampleType=/Bicubic \
    -dColorImageResolution=72 \
    -dGrayImageDownsampleType=/Bicubic \
    -dGrayImageResolution=72 \
    -dMonoImageDownsampleType=/Bicubic \
    -dMonoImageResolution=72 \
    "-sOutputFile=Compressed$1" \
    "$1"

In case you are wondering, it's fine to quote options like this; it's no different from quoting other kinds of arguments. gs -q and gs "-q" look exactly the same to gs when gs receives them.

We just use them here to make sure the entire path is made part of the -sOutputFile option , rather than what was previously the case: the fragment before the space was correctly assigned to the option argument, and the fragment after the space was an independent argument, that gs may well have treated as if it were the input file argument.

Related Question