Your first command (the one you tried manually and that works) pass 2 arguments to "packager" (both starting with in=...
). Your second, packager "$input"
passes only one argument (containg a space, in=... in=...
in a signle string).
So either you just drop the double quotes around $input
when calling, in the last line: sudo packager $input
. It will work if you are sure that none of your in=...
strings ever contain spaces. But that is not advisable. Because if ever one of your file contains a space, such as "vid 720.mp4", then input will look like
in=vid 720.mp4,output=packaged/vid 720.mp4 in=other.mp4,output=pack.mp4
And then running with quotes (sudo packager "$input"
) is wong, because pakager will be run with a single argument in=vid 720.mp4,output=packaged/vid 720.mp4 in=other.mp4,output=pack.mp4
that means nothing coherent to it.
Running without quotes (sudo packager $input
) is also wrong, because then packager will be run with 4 arguments, in=vid
, 720.mp4,output=packaged/vid
, 720.mp4
and int=other.mp4,output=pack.mp4
. Which is not what you want neither.
So again, if you are positive that never any space can find its way in your file names, go ahead, run without double quotes around input, and stop reading :-)
Otherwise, I would use arrays.
inputs=()
# using a for loop here
inputs+=("in="$output_path"/"$content_id"_"$height"p.mp4,stream=video,output="$packaged_out"/"$content_id"_"$height"p.mp4 ")
done
echo "${inputs[@]}"
sudo packager "${inputs[@]}"
Note1: if you want to see how args ars split, use printf rather that echo.
Because you can't see difference between echo "one two"
and echo one two
. Whereas printf "(%s) " one two
and printf "(%s) " "one two"
shows what are the args.
Note2: You don't need to end double quotes each time you want to add a variable. Variables are expanded inside double quotes
So
inputs=()
# using a for loop here
inputs+=("in=${output_path}/${content_id}_${height}p.mp4,stream=video,output=${packaged_out}/${content_id}_${height}p.mp4")
done
printf "(%s) " "${inputs[@]}"
sudo packager "${inputs[@]}"
(Not all ${...}
are necessary here. But taking the habit of using ${...}
each times avoids problems, for example for your ${height}p.mp4
: it avoids p to be taken as part of the variable name)
Addendum: some experiments
To understand what happen here, see
printf "(%s) " in=1 in=2
#(in=1) (in=2)
input=""
input="$input in=1"
input="$input in=2"
printf "(%s) " "$input"
#( in=1 in=2)
input=""
input="$input in=1"
input="$input in=2"
printf "(%s) " $input
#(in=1) (in=2)
# So, victory? No! see below
input=""
input="$input in=one 1"
input="$input in='two 2'" # in case you expect something in nested quotes
printf "(%s) " "$input" #Nope: ( in=one 1 in='two 2')
printf "(%s) " $input # Even worse: (in=one) (1) (in='two) (2')
# Now arrays
input=()
input+=("in=1")
input+=("in=two 2")
input+=("in='three 3'")
avar="four 4"
input+=("in=${avar}") # Just to check what I say about variable inside double quotes
printf "(%s) " "${input[@]}" # Victory: (in=1) (in=two 2) (in='three 3') (in=four 4)
printf "(%s) " ${input[@]} # Don't forget quotes. (in=1) (in=two) (2) (in='three) (3') (in=four) (4)
Edit
To take into account your edit to your question: it should really change nothing. What is the failure? Are you sure it was not there before, but couldn't see it because of previous problem now solved.
Just to experiment (without your "packager" program, but replacing it, again, with printf)
inputs=()
for i in {1..5}
do
content="content $i"
height=$((i*100))
inputs+=("in=indir/${content}_${height}p.mp4,out=out/${content}_${height}p.mp4")
done
key_server=aServer
content_id=123
signer_uname="John Doe"
packaged_out=/home/me/out
printf '(%s) ' sudo packager "${inputs[@]}" \
--enable_widevine_encryption \
--key_server_url "${key_server}" \
--content_id "${content_id}" \
--signer "${signer_uname}" \
--mpd_output "${packaged_out}/${content_id}.mpd" \
--hls_master_playlist_output "${packaged_out}/${content_id}.m3u8"
Displays
(sudo) (packager) (in=indir/content 1_100p.mp4,out=out/content 1_100p.mp4) (in=indir/content 2_200p.mp4,out=out/content 2_200p.mp4) (in=indir/content 3_300p.mp4,out=out/content 3_300p.mp4) (in=indir/content 4_400p.mp4,out=out/content 4_400p.mp4) (in=indir/content 5_500p.mp4,out=out/content 5_500p.mp4) (--enable_widevine_encryption) (--key_server_url) (aServer) (--content_id) (123) (--signer) (John Doe) (--mpd_output) (/home/me/out/123.mpd) (--hls_master_playlist_output) (/home/me/out/123.m3u8)
Which is exactly what is expected.