Passing shell variables containing spaces as arguments

I know that many of these questions are already there, but my situation is so unique that none of them have helped me until now.

I am writing a script that reformats my (poorly marked) music library. It currently represents music / genre / artist / album / ## - Title.wav.

From the Music directory, I run my script1, which calls find -name "*.wav" -exec script2 {} ${other_args}

. Script2 parses the variable path, creates an appropriate output directory if it doesn't exist, and then calls ffmpeg to compress.

ex: ($ sourcefilepath contains {} from find)

ffmpeg -i "$sourcefilepath" "$path/$to/$outfile.$extension"

      

If my filename or path contains no spaces, it works like a charm.

If it contains spaces, ffmpeg fails, with the following error:

Blues / Country Blues / Rhythm, Country and Blues / 08-Natalie Cole and Reba McEntire Since I Fell For You.wav: No such file or directory

Note: original file it can't find. The output file works correctly, even with spaces. This is not a complete command that I am running (it also has some metadata flags, but this also works correctly. I am debugging the command I wrote above).

Interestingly, ffmpeg does NOT interpret $ sourcefilepath as two arguments, it just cannot find the file I specified. The following is done from the Music catalog.

ffmpeg -i Blues/Country\ Blues/Rhythm\,\ Country\ And\ Blues/08-Natalie\ Cole\ \&\ Reba\ McEntire\ \ \ Since\ I\ Fell\ For\ You.wav output.flac

      

I'm kind of stuck here. Other information on the internet suggests getting the command to see a variable with a space as one argument instead of several. I seem to have done this, but ffmpeg cannot find my file now.

I usually just use find -name "*.wav" -exec ffmpeg -i {} ${args} \;

, but I need to parse the file path to extract my metadata.

I am new to shell scripting; does anyone know what is going on here?

+1


source to share


1 answer


My psychic powers suggest that at some point in your code, you do something like:

something=$(echo $filename | something)

      

It should be:

something=$(echo "$filename" | something)

      

Here's a script demonstrating why this is the problem:

#!/bin/sh
filename="Reba McEntire   Since I fell"    
echo "$filename"    # Correct, quoted
echo $filename      # Incorrect, unquoted

      



It outputs:

Reba McEntire   Since I fell
Reba McEntire Since I fell

      

You will notice that

  • the first line has three spaces after the executor, as in your correct command.
  • the second line has one space after the executor, as in your error message.

This is due to the unordered variable expansion going through wordplitting. echo

then concatenates the arguments with single spaces. The end result is the concatenation of multiple spaces into one space.

+2


source







All Articles