我在脚本中有以下代码段:
bitrate=$(ffmpeg -i "$vidfile" 2>&1 | grep bitrate | \
perl -pe 's/.*bitrate: (\d{1,} .*)\r?\n\r?$/$1/')
echo "\$bitrate = $bitrate" #added for debugging
printf "\$bitrate = $bitrate\n" #added for debugging
printf " $bitrate $vidfile\n" #added for debugging
printf " %s %s \n\n" "$bitrate" "$vidfile"
这个BASH shell脚本(减去为调试添加的行)在Mac OS X终端上工作正常。当我尝试在Cygwin上运行时,最后一个&倒数第二个printf
不打印$bitrate
变量的值。
运行的示例输出:
$ bitrate.sh 20180305-01.mov 20180305-02.mov
$bitrate = 31103 kb/s
$bitrate = 31103 kb/s
20180305-01.mov
20180305-01.mov
$bitrate = 30735 kb/s
$bitrate = 30735 kb/s
20180305-02.mov
20180305-02.mov
答案 0 :(得分:1)
问题是由于非打印回车字符(有时表示为\r
或^M
或<CR>
)。 DOS和Windows使用以下惯例:文本行以回车符后跟换行符结束,但unix只使用换行符。因此,当您使用DOS / Windows格式的行并将其传递给unix程序(例如shell)时,它会认为换行符是行的结尾,并将回车视为内容的一部分。线。在Windows中使用unix工具(例如Cygwin)时,会出现很多的问题。
在这种情况下,我认为这是因为脚本文件本身是DOS / Windows格式,但显然不是;所以我不确定回车的确切位置(也许perl
试图与Windows兼容并输出DOS / Windows格式?)。无论如何,最终结果是变量bitrate
在末尾有一个回车符。打印它本身,这是不可见的,但如果你打印后跟一个空格和文件名,它会发送“31103 kb/s\r 20180305-01.mov
”到终端,打印“31103 kb / s”,然后回车让它回到行的开头(这实际上是“回车”的意思是“),然后在”31103 kb / s“的顶部打印”20180305-01.mov“,取而代之。
解决方案:删除回车,将tr -d '\r'
添加到计算比特率的管道末尾。
当您怀疑此类问题时,有用的故障排除技巧:使用printf
的{{1}}格式打印变量:
%q
...并通过$ printf 'the var is %q\n' "$bitratenormal"
the var is 31103\ kb/s
$ printf 'the var is %q\n' "$bitratewithcr"
the var is $'31103 kb/s\r'
运行文件,以使各种常常不可见的字符可见:
LC_ALL=C cat -vet