Search code examples
bashquoting

"Quoting within quoting" question for professed bash affectionate


Out of sheer curiosity I would like to know how this quoting dilemma can be fixed. I already solved the issue by circumnavigating it (I added [vcodec!*=av01] to the -f argument and simply removed the --exec part entirely). Otherwise it only worked, when there were no spaces or minus signs in the --exec argument. The culprit line is the last and the issue is at the end with the --exec argument. You can ignore the rest.

Thanks for your help on the road to enlightenment! ;-)

#!/bin/bash

trap "exit" INT

avtomp4conv () {
  # tests if the given file (in argument) is an AV1 media and if so, converts it to mp4
  echo "${1}"
  if ($( ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${1}" | grep -i av > /dev/null )); then
    echo "$1 bad codec"
    ffmpeg -hide_banner -loglevel error -stats -i "${1}" -movflags faststart -preset ultrafast "${1%.mp4}_fixed.mp4" && mv "${1}" bogus/ && mv -n "${1%.mp4}_fixed.mp4" "${1}"
  fi
}

# ... lotsa other stuff ...

export -f avtomp4conv
cat links.txt | parallel -u -I % --retries 3 --max-args 1 --jobs 4 python3 `which youtube-dl` -c -f "'bestvideo[height<=720][ext=mp4]+bestaudio[ext=m4a]/mp4'" --external-downloader aria2c --external-downloader-args "'-x 4 -s 4'" --exec \'bash -c \"export -f avtomp4conv\;avtomp4conv \{\}\"\' %


Solution

  • Use another function to save you from the double indirection in a single command (parallel executes youtube-dl that executes avtomp4conv). GNU parallel uses your current shell to execute its commands, so no need for bash -c here.

    avtomp4conv () {
       ...
    }
    ytdl() {
       youtube-dl ... --exec "bash -c 'avtomp4conv \"$0\"' {}"
    }
    export -f avtomp4conv ytdl
    < links.txt parallel ... ytdl
    

    Without the function ytdl you could try the following. But why bother with these nested quotes?

    < links.txt parallel ... -I insteadOf{} \
    "youtube-dl ... --exec \"bash -c 'avtomp4conv \\\"\$0\\\"' {}\""