bash: passing around arguments with quotes

Update: I just learned on IRC that checking with shellcheck would have told me everything, including the usage of arrays, and the linked page even mentions ffmpeg … how stupid to reinvent the wheel again and again … Thanks to pabs for telling me!

It has hit me several times, and searching the internet gives lots of suggestions: How to pass and argument containing quotes to another program from a bash program.

My case was a script that automatized video processing using ffmpeg, and I needed to call ffmpeg with arguments like

ffmpeg ... --filter_complex "some arg with spaces" ...

My first (failed) shot at doing this in the shell script was:

filterarg='--filter_complex "some arg with spaces"'
...
ffmpeg $someargs $filterarg ...

which, as most bash gurus will know, will fail. Solutions are using eval that are complicated.

Recently I realized a much simpler method using bash arrays: Assume the program show_arguments just prints the arguments passed in, maybe something like (again in bash):

#!/bin/bash
for i in "$@" ; do
  echo "=== $i"
done

The program under consideration would be – in the broken version:

#!/bin/bash
# Variant 1 - NOT WORKING
myargs='-filter_complex "arg with space"'
show_arguments $myargs

This would give

=== -filter_complex
=== "arg
=== with
=== space"

which is not what we want.

The solution is to stuff the arguments into an array, and expand that as arguments.

#!/bin/bash
# Variant 2 - WORKING
declare -a myargs
myargs=(-filter_complex "arg with space")
show_arguments "${myargs[@]}"

which, correctly, would give

=== -filter_complex
=== arg with space

Now I only need to remember that trick for the next time it bites me!

2 Responses

  1. Wow. I would’ve sweared the example you gave works. And I’ve been doing bash for 25 years? Jeesus!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>