Escape characters in variables for using in another variable

Yesterday I made a bash script that encodes the video with the parameters I need using ffmpeg. It uses MPV socket and receives information about the media file from it while I watch the video. Therefore it doesn’t require setting routine parameters such as the start & end video points, duration, filename and path. There is already a special script for that (Encode with mpv-webm script in MPV) but it lacks some options that I like, so I made my own script.

But I have few skills in this matter so there was one problem that I couldn’t solve for 2 hours. It is about character escaping. I tried to put two variables in another. These variables contained characters that needed to be escaped. And these variables were surrounded by other options.

It looks something like this:

VARIABLE='[options] [options] [options]' "${PROCESS_WORKING_DIRECTORY}/${FILE_NAME}" '[options] [options] [options]'

The problem is that ffmpeg can’t understand it when i pass it as a parameter:

ffmpeg [options] -vf subtitles="${VARIABLE}" [options] [options]
File does not exist OR non existing video filter OR bash cuts the file path in the wrong places

I was looking for a solution to the problem on the Internet, tried to use a lot of tricks in bash ( ${[email protected]}, arrays) but it didn’t work.

Then an idea came to my mind, what other Linux commands can escape characters? Maybe this is a bash problem? Maybe I need to use something easier since I can’t do it in a bash?

I searched for other escaping methods and found that printf function can do this.

It looks like this:

printf "%q" "${VARIABLE_1} OTHER STUFF ${VARIABLE_2}"

The function returns escaped string. Therefore, it can be used in this way:

NEW_VARIABLE=$(printf "%q" "${VARIABLE_1} -param1 value -param2 value ${VARIABLE_2}")

A new variable on the command line should be used like this:


Then this variable will return escaped strings from other variables.


File path and file name may contain characters which we should escape. Therefore, it is necessary to foresee that the script worked without errors.

I wanted to put one big line of options into a variable. It contains variables that can be changed, and other options that I never change. But all this is just for subtitles. Therefore I wanted to put this in one variable.

VSUBTITLES='subtitles='$(printf "%q" "${MPV_CWD}/${FILENAME}")':si='"$SUBS_INDEX"',setpts=PTS-'"$START_POSITION"'/TB'

MPV (Media Player) current working directory and file name should be escaped. Therefore, for these two variables we use printf “%q” command. It return absolute file path.

Then this variable can be used on the command line among other variables, like this:

ffmpeg [options] ${VFILTER} "${VSUBTITLES}"${VSCALE} [other_options]

Note that the variable is in double quotes.