Reputation: 1109
I am trying to use youtube-dl to get the urls of some videos and then pipe the resulting urls into the input of my script. So in my terminal I do
youtube-dl --ignore-config -iga ~/Desktop/youtube/videolist.txt | myscript.sh
In my script I define things as
command='ffmpeg'
inputArgs='-i'
outputArgs='-c:v libx264 -preset ultrafast -qp 0'
directory="${HOME}/Desktop/Videos/"
output="video${count}"
extension='mp4'
I test it with echo
to make sure everything appears in the correct order.
echo "${command}" "${inputArgs}" "${input}" "${outputArgs}" \
"${directory}""${output}${count}"."${extension}"
And the output from that looks correct. But when I try to run the same thing without the preceding echo
command, i.e.,
"${command}" "${inputArgs}" "${input}" "${outputArgs}" \
"${directory}""${output}${count}"."${extension}"
I get an error message that says
At least one output file must be specified.
So it seems pretty obvious to me that I'm doing something wrong when attempting to execute it.
I have tried:
exec
command in front of everythingNo matter what I do, an error occurs at some point in the process. I know it's something simple I'm doing wrong. Would someone please enlighten me as to what that might be?
I feel very strongly that the .
shouldn't just be in the middle of everything like that, but I really don't know.
Again, everything looks as it should when I run echo
before the string of shell parameters.
If more of the script I'm using is needed to understand what I'm talking about, that is not a problem.
Upvotes: 0
Views: 3035
Reputation: 183
You tried to rely on a string to convey multiple arguments. You probably would want to use an array in all cases like this. An array is easy to use and more versatile (works with any arbitrary strings) and you don't have to walk on that many eggshells in order to avoid quirks and security holes, unlike when leaving quotes off.
command='ffmpeg'
inputArgs=(-i)
outputArgs=(-c:v libx264 -preset ultrafast -qp 0
-metadata 'title=another * string'
-metadata 'artist=; echo "Just a string'
-metadata "comment=Processed by my ${command} script.")
directory="${HOME}/Desktop/Videos/"
output="video${count}"
extension='mp4'
outputArgs+=(-metadata "track=${count}")
When expanding an array, the reference must have the {}
around it. When used in the form: "${name[@]}"
, it behaves as if you had typed the contents on the line directly.
printf '%q\n'
is a more useful way of examining a command compared to echo
, as it can clearly tell you what belongs to which separate argument.
You can also expand an array into another array:
whole_thing=("${command}" "${inputArgs[@]}" "${input}"
"${outputArgs[@]}"
"${directory}/${output}"."${extension}")
#This will output lines you can paste
# into bash to recreate the array:
printf 'whole_thing=()\n'
printf 'whole_thing+=(%q)\n' "${whole_thing[@]}"
#This will run the command:
"${whole_thing[@]}"
Upvotes: 1
Reputation: 39641
The problem is that because you put it in quotes "${outputArgs}"
is expanded as a single argument. It doesn't get split up into separate arguments so ffmpeg only see it as a single -c
option with a really long stream specifier. The next argument, the output file is interpreted as the codec instead.
To fix the problem simply remove the quotes:
"$command" $inputArgs "$input" $outputArgs "$directory$output$count.$extension"
I removed the curly braces ({}) just to save space. There's nothing wrong with using them if you prefer.
Upvotes: 1