Problem escaping characters in bash script
I'm really new to bash script, I'm trying create a shell script to process videos using a cron but I really don't know what's going on
#!/bin/bash
args=("$@")
count=0
startingfrom=5
args1="-r 29.97 -t 00:13:30 -vsync 0 -vpre libx264-medium -i"
args2='-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "'
args12="-r 29.97 -ss 00:40:30 -vsync 0 -vpre libx264-medium -i"
args3="-vcodec libx264 -acodec libfaac"
for file in /home/allen/s/
do
eppart1 = "$args[0]_$startingfrom_01_01_02.mp4"
eppart2 = "$args[0]_$startingfrom_01_02_02.mp4"
/usr/local/bin/ffmpeg $args1 "$file" $args2 $args3 "${args[0]}_${startingfrom}_01_01_02.mp4"
mv "${args[0]}_${startingfrom}_01_01_02.mp4" upload/
/usr/local/bin/ffmpeg $args12 "$file" $args2 $args3 "${args[0]}_${startingfrom}_01_02_02.mp4"
mv "${args[0]}_${startingfrom}_01_02_02.mp4" upload/
let "count += 1"
let "startingfrom +=1"
echo "$count"
echo ${args[0]}
echo ${args[1]}
done
/usr/local/bin/python2.5 /home/allen/s/process.py
Problem starts in this argument
args2='-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "'
I don't know if its because of the special character or not, usually if I type the whole command it works, but in bash script it's different
The output it gives me
Unable to find a suitable output format 开发者_运维问答for 'scale=580:380'
Though like I said, if I run the whole command it just works
prepend what will be executed with an echo, so you will see what will be passed to the commands;
something $args2
will expand to
something -vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "
i.e. calling something with two arguments, one being an option (or 2 options) and the other is a "single" string; I suppose you don't want the double quotes.
The line below has two problems. First, you cannot have spaces around the equals. Second, when you try to use a variable within a double-quoted string, you need to use curly braces.
eppart1 = "$args[0]_$startingfrom_01_01_02.mp4"
What you need is this:
eppart1="$args[0]_${startingfrom}_01_01_02.mp4"
Otherwise, bash will be looking for a variable identified by startingfrom_01_01_02
, not startingfrom
You seem to have this fixed in later lines so maybe you just pasted an older version?
Other than that, what the others said is correct: You should execute nothing but assignments and echos until you are sure your variables are correct.
Putting quotes inside a variable value (as you did with args2) does not do what you expect. Specifically, they won't be parsed as quotes when the variable is used, but just as regular characters. So if you do:
args2='-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "'
somecmd $args2
it winds up being equivalent to:
somecmd '-vf' '"[in]' 'scale=580:380' '[T1],[T1]' 'pad=720:530:0:50' '[out]' '"'
note that the double-quotes aren't being interpreted as grouping words together, instead they're just passed to the command as parts of the words -- not what you want at all. BTW, this is a case where debugging with echo
won't help -- everything will look fine, because echo
doesn't clearly separate the arguments it gets. Instead, using set -x
will get bash to print the commands as it executes them, with its parsing clarified.
Now, about fixing it. If you need to store command arguments in a variable (as you're doing here) and keep track of where the word boundaries are (as you're trying to use double-quotes to do), the standard answer is to use arrays instead of simple variables. Create the array with each argument as an array element, then use the array with the idiom "${arrayname[@]}"
(note that the double-quotes around it are very important). Here's my example above:
args2=(-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] ")
somecmd "${args2[@]}"
or in your script:
...
args2=(-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] ")
...
/usr/local/bin/ffmpeg $args1 "$file" "${args2[@]}" $args3 "${args[0]}_${startingfrom}_01_01_02.mp4"
mv "${args[0]}_${startingfrom}_01_01_02.mp4" upload/
/usr/local/bin/ffmpeg $args12 "$file" "${args2[@]}" $args3 "${args[0]}_${startingfrom}_01_02_02.mp4"
...
BTW, doing the same thing to your other "arg" variables isn't necessary (since they don't contain any arguments with spaces in them), but wouldn't hurt and might be considered good practice.
精彩评论