尽管在Mac OS终端上工作,printf也不会在Cygwin中打印变量

时间:2018-03-11 06:09:28

标签: bash shell cygwin

我在脚本中有以下代码段:

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

1 个答案:

答案 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