bash脚本中转义字符问题



我是bash脚本的新手,我正在尝试创建一个shell脚本来处理视频,但我真的不知道发生了什么

#!/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

问题从这个参数开始

args2='-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "'

我不知道是不是因为特殊字符,通常如果我输入整个命令它工作,但在bash脚本中它是不同的

它给我的输出

Unable to find a suitable output format for 'scale=580:380'

就像我说的,如果我运行整个命令它就会起作用

在将要执行的内容前加上一个回显,这样您就可以看到将传递给命令的内容;

           something $args2

将展开为

           something -vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "

。调用带有两个参数的东西,一个是一个选项(或两个选项),另一个是一个"单一"字符串;我想你不需要双引号。

下面这行有两个问题。首先,等号周围不能有空格。第二,当你试图在双引号字符串中使用变量时,你需要使用花括号。

eppart1 = "$args[0]_$startingfrom_01_01_02.mp4"

你需要的是:

eppart1="$args[0]_${startingfrom}_01_01_02.mp4"

否则,bash将查找由startingfrom_01_01_02标识的变量,而不是startingfrom

你似乎在后面的行中修复了这个问题,所以也许你只是粘贴了一个旧版本?

除此之外,其他人所说的是正确的:在确定变量是正确的之前,您应该只执行赋值和返回。

在变量值中放入引号(就像您在args2中所做的那样)并不能达到您所期望的效果。具体来说,当使用变量时,它们不会被解析为引号,而只是作为常规字符。如果你这样做了:

args2='-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] "'
somecmd $args2

就等于:

somecmd '-vf' '"[in]' 'scale=580:380' '[T1],[T1]' 'pad=720:530:0:50' '[out]' '"'
请注意,双引号并没有被解释为将单词分组在一起,相反,它们只是作为单词的一部分传递给命令——这根本不是您想要的。顺便说一句,这是一个用echo调试不会有帮助的情况——一切都会看起来很好,因为echo没有清楚地分离它得到的参数。相反,使用set -x将使bash在执行命令时打印命令,并澄清其解析。

现在,关于修复它。如果需要将命令参数存储在变量中(就像这里所做的那样)并跟踪单词边界的位置(就像尝试使用双引号那样),标准的答案是使用数组而不是简单的变量。用每个参数作为数组元素创建数组,然后按照习惯用法"${arrayname[@]}"使用该数组(注意,它周围的双引号非常重要)。下面是我上面的例子:

args2=(-vf "[in] scale=580:380 [T1],[T1] pad=720:530:0:50 [out] ")
somecmd "${args2[@]}"

或在您的脚本中:

...
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"
...

顺便说一句,对其他"arg"变量做同样的事情是没有必要的(因为它们不包含任何带空格的参数),但不会有伤害,可能被认为是良好的实践。

最新更新