【问题标题】:pipe ffprobe in sh scriptsh脚本中的管道ffprobe
【发布时间】:2016-03-10 20:28:33
【问题描述】:

我正在尝试使用 ffprobe 获取 OSX sh 脚本中的音频类型:ffprobe "$i" |& egrep -ci "vorbis|aac" 它适用于 tcsh 中的 cli,但不适用于脚本。 |& 似乎在脚本内部不起作用。 |& 重定向 ffprobe 的输出,否则 ffprobe 会打印到 cli。任何帮助表示赞赏。

##mkv files
for i in "$input"*.mkv ; do
    if [ -e "$i" ] ; then
         ##1st check type(vorbis|aac)
         type=$(/usr/local/bin/ffprobe "$i" |& egrep -i "vorbis|aac")
         echo "Test: $type"
         ##just get audio format
         type=$(/usr/bin/perl -e '$_=@ARGV[0];if (/(aac|vorbis)/ig) {print $1;}' "$type")
         echo "Type: $type"
         exit
    fi
done

我得到的错误是:

command substitution: line 46: syntax error near unexpected token `&'
command substitution: line 46: `/usr/local/bin/ffprobe "$i" |& egrep -i "vorbis|aac"'

【问题讨论】:

  • 你为什么需要|&(我通常不使用它,所以我不记得它是什么了)。你不能只做ffprobe "$i" | grep -i ... 吗?此外,您的代码看起来像 bash 或相关的 shell,而不是 tcsh。例如,tcsh 使用 endif,而不是 fi。祝你好运。
  • 为什么你认为这是一个tcsh 脚本?这看起来像一个 Bourne shell 脚本。 |& 不是标准的 Bourne shell 构造,仅适用于 bash 以及可能的其他一些 Bourne shell 扩展(csh 也有它)。如果您使用 bash 运行此脚本,它应该可以正常工作。
  • 也许你应该澄清你的问题(edit 文本,还有标签!),并包含实际的错误消息;事实上,我们不得不猜测太多的事情。
  • @Carpetsmoker 我回滚了你的标签编辑,因为sh 显然不比tcsh 更正确。也许等待OP澄清。
  • 我一直使用fi 关闭if,它总是有效,所以我从不质疑它。 |& 确实适用于 tcsh。我已经用错误更新了问题。

标签: shell sh tcsh ffprobe


【解决方案1】:

您正试图在sh 脚本中使用tcsh 语法;尽管您似乎没有意识到它们是两种不同的语言,但这不起作用这一事实应该不足为奇。

也许最直接的脚本解决方案是在bash 而不是sh 中运行它,前者支持您尝试使用的tcsh 语法,这不仅是巧合,而且因为它借了很多好以及来自 tcsh 的一些不太好的想法,同时保持与 POSIX sh 的完全向后兼容性。

假设您想要的信息打印到标准输出 py ffprobe,您也可以切换到常规管道,并保留 sh shebang 行。无论哪种方式,都不太推荐使用sh 显式调用脚本——只需将文件标记为可执行文件并直接调用它,系统将使用shebang 指定的任何解释器(相反,如果您显式地忽略shebang指定解释器)。

人们普遍认为 tcsh 应避免用于脚本和交互使用——我建议您也考虑切换到 bash 用于交互使用,这将统一您显然已经用于脚本的语法具有交互式使用的语法。事实上,由于使用不兼容的交互式 shell,您目前错过了 shell 的一个吸引人的特性。

Tom Christiansen 的csh.whynot 是对 C shell 的规范参考批评。虽然tcsh 修复了csh 中的大量错误和不一致之处,但仍然存在许多。切换到主流 shell 还可以为您提供更广泛的帮助、学习和故障排除资源网络,为您提供支持。

【讨论】:

  • 这几乎是正确的答案,所以我不妨标记一下。在我的 osx 版本上,sh 在 posix 模式下调用 bash。所以脚本是在 bash 中从 tcsh 运行的。我只需要将 ffprobe 调用更改为典型的 bash 重定向 type=`/usr/local/bin/ffprobe "$i" 2>&1 | egrep -i "audio"`
  • 您系统上的sh 在 POSIX 模式下运行 Bash 的事实是巧合。标有#!/bin/sh 的脚本应该(或者更确切地说,基本上必须)遵守许多 Bash 构造不可用的受限语法。在许多基于 Debian 的发行版中,默认的 sh 已从以前作为 Bash 的符号链接更改为 dash(就像在您的系统上一样),这揭示了许多他们粗心的情况,和/或 Bash 应该在的地方更严格。你想避免被它咬;未来版本的 Bash 可能在 POSIX 模式下允许的 bashism 更加严格。
  • 如果您觉得这个答案有帮助,请点击大分数旁边的空心复选标记接受它,这样它就会变成纯绿色。这会奖励我一些声望点,但更重要的是,标记您的问题,使其不再出现未解决。
猜你喜欢
  • 2019-09-24
  • 2013-05-31
  • 2018-12-18
  • 2017-06-03
  • 2012-11-25
  • 2016-07-31
  • 1970-01-01
  • 2018-11-21
  • 2017-07-22
相关资源
最近更新 更多