逃避bash头痛的变量

时间:2012-11-26 17:57:42

标签: linux bash variables escaping

我创建了一个脚本,以便自动将我的Camera视频从DV转换为mkv 但是,我无法使其工作,因为它没有正确地转义文件名变量。 脚本是:

#!/bin/bash
FTITLE="Tapes 2012, Tape 01 - "
i=1;
find ./ -type f -name "dv_*.dv" | while read fname; do
    CTIME=`stat -c %Y ${fname}`
    FNAME="${FTITLE} - ${i}.mkv"
    /usr/bin/ffmpeg -i ${fname} ${x264_OPTIONS} ./"$FNAME"
    let i=$i+1
done

当我运行脚本时,我看到以下错误:

[NULL @ 0x645f40] Unable to find a suitable output format for '2012,'
2012,: Invalid argument

显然,这是脚本和文件名的问题。 我试图逃避它

/usr/bin/ffmpeg -i ${fname} ${x264_OPTIONS} ./"\"$FNAME\""

但它也没有用。

1 个答案:

答案 0 :(得分:1)

使用更多报价!!!引用你拥有的每个变量!

而不是你的脚本,我会做以下事情:

#!/bin/bash

ftitle="Tapes 2012, Tape 01 - "

x264_options=( your options here in an array that is good practice "and quote if you have an option with spaces" )

shopt -s globstar
shopt -s nullglob

((i=1))

for fname in **/dv_*.dv; do
   [[ -f $fname ]] || continue
   ctime=$(stat -c %Y "$fname")
   fnameuppercase="$ftitle - $i.mkv"
   /usr/bin/ffmpeg -i "$fname" "${x264_options[@]}" ./"$fnameuppercase"
   ((++i))
done

与您的有几点不同:

  • 使用小写变量名称。使用大写变量名
  • 被认为是不好的做法
  • 此处无用find,因为您的搜索非常简单:改为使用bash的glob,
  • 所有变量都已正确引用,
  • 这些选项都在一个数组中(良好实践!并解决了几乎所有问题),
  • 不使用反引号,而是使用$(...)命令替换,
  • 使用bash的算术运算符((...))
  • 不使用子shell(在您的版本中,while循环在子shell中执行)