【问题标题】:syntax error near unexpected token `do' in bash scriptbash脚本中意外标记“do”附近的语法错误
【发布时间】:2016-09-06 04:54:25
【问题描述】:

我有 bash 脚本,它从命令行获取 3 个参数。它比较目录中的所有文件以查看它们是否属于前 2 个参数的类型。如果是,则脚本使用 FFMPEG 命令将此类文件转换为第三个参数的类型。我将使用以下命令执行脚本:

./convert.sh .avi .mp4 .flv 

这个脚本会将所有 .avi 和 .mp4 文件转换为 .flv。

当我运行脚本时,我得到了错误

syntax error near unexpected token `do' in bash script.

代码如下:

#!/bin/bash

# $1 is the first parameter passed
# $2 is the second parameter passed 
# $3 is the third parameter passed

for file in *.*; 
    do 
        #comparing the file types in the directory to the first 2 parameters passed
        if[  ( ${file: -4} == "$1" ) || ( ${file: -4 } == "$2" )  ]{
            export extension=${file: -4}
            #converting such files to the type of the first parameter using the FFMPEG comand
            do ffmpeg -i "$file" "${file%.extension}"$3;
done

【问题讨论】:

  • shellcheck测试你的代码
  • 我做过,但我是 bash 的初学者。我不太了解 shellcheck 上的一些错误消息。任何提示我出错的地方都将不胜感激。
  • 说实话,我只能看到这个脚本中的 shebang 行是正确的:|

标签: bash unix ffmpeg


【解决方案1】:

您的格式和语法存在一些问题。 sjsam 使用 shellcheck 的建议很好,但简短的版本是您应该在 if 语句的内部括号中使用方括号而不是圆括号:

if [ ${file: -4} == "$1" ] || [ ${file: -4 } == "$2" ] {

而且我认为您不需要在您的 ffmpeg 行之前的“do”或上面行末尾的大括号,所以您最终会得到...

for file in *.*; 
    do 
    #comparing the file types in the directory to the first 2 parameters passed
    if [  ${file: -4} == "$1" ] || [ ${file: -4 } == "$2" ]
        export extension=${file: -4}
        #converting such files to the type of the first parameter using the FFMPEG comand
        ffmpeg -i "$file" "${file%.extension}"$3;
    fi
done

【讨论】:

  • 很高兴听到这个消息,虽然下面 Gordon 的回答比我的要彻底得多 - 我更正了 'if[' 缺失的空格,但忘了提及它,也忽略了发现缺失的 'then' ...
【解决方案2】:

这里有一堆语法错误。让我们从这一行开始:

if[  ( ${file: -4} == "$1" ) || ( ${file: -4 } == "$2" )  ]{
  • 您需要在if[(或后面的任何内容)之间留一个空格。正如所写,shell 将“if[”视为命令的名称,这根本不是您想要的。

  • 条件的[ ... ] 样式不理解||(它使用-o 代替),要求对所有shell 元字符(如括号)进行转义或引用,可能无法理解==(只是= 是标准),如果任何未加引号的变量/参数引用为空白,将会非常混乱。

  • if 条件以then 结尾(在下一行,或在; 之后)而不是{

你可以这样修复它:

if [  \( "${file: -4}" = "$1" \) -o \( "${file: -4}" = "$2" \) ]; then

或者,由于您使用的是bash(而不是更基本的shell),您可以使用[[ ... ]] 条件样式,它的语法更加简洁:

if [[ "${file: -4}" = "$1" || "${file: -4}" = "$2" ]]; then

接下来,删除ffmpeg 之前的dodoforwhile 循环语法的一部分;你上面已经有一个(它所属的地方),而这个没有意义。这就是导致您看到的错误的原因。

接下来,您替换文件扩展名的方式将无法正常工作。变量引用"${file%.extension}"$3 将尝试从$file 的末尾删除“.extension”(不是变量,只是字符串)。它在引号之外还有$3,这可能会造成麻烦。您可以改用"${file%$extension}$3" 来修复它,但坦率地说,我只会使用"${file%.*}$3" 来删除扩展名,无论它是多长(我也会类似地重做if 比较,但这更复杂) .

最后,您需要一个fi(在ffmpeg 行之后)来结束条件。每个if 都需要一个then 和一个fi

作为一种风格,你不需要; 在shell 的行尾;仅当您将多个命令(或 dothen 之类的东西)放在同一行时才需要它。无论如何,这是我的快速重写:

#!/bin/bash

# $1 is the first parameter passed
# $2 is the second parameter passed 
# $3 is the third parameter passed

for file in *.*; do
    #comparing the file types in the directory to the first 2 parameters passed
    if [[  "${file: -4}" = "$1" || "${file: -4}" = "$2"  ]]; then
        #converting such files to the type of the first parameter using the FFMPEG comand
        ffmpeg -i "$file" "${file%.*}$3"
    fi
done

【讨论】:

    【解决方案3】:

    您的脚本可以简化为:

    #!/bin/bash
    
    for file in *; do
        [[ ${file: -4} = $1 || ${file: -4} = $2 ]] && ffmpeg -i "$file" "${file%.*}$3"
    done
    

    【讨论】:

      【解决方案4】:

      对我来说,这是由于CRLF。对于 linux 环境,它应该是 LF

      【讨论】:

        【解决方案5】:

        即使我也遇到了同样的错误。 [https://i.stack.imgur.com/PsWGF.png] --> 这个链接会带你到错误信息。

        下面的链接中提供了让我遇到此消息的代码。 [https://i.stack.imgur.com/Wom7q.png]

        如果您观察到与 do 命令相关的错误,随后会出现有关 while 语法的错误。您可以通过在方括号周围引入空格来消除错误。 [https://i.stack.imgur.com/F1C7x.png]

        这是因为 [ 不是 shell-built-in 而是接收表达式作为参数。如果 [ 没有被空格包围,解释器会将其解释为 $PATH。

        希望这个回答能帮助你解决问题。

        【讨论】:

        • 请不要将错误消息和代码发布为图像(如果您确实使用图像,formatting guide 将帮助您正确执行此操作)。代码应始终作为文本添加到问题和答案中。无法搜索图像,使用辅助技术的人也无法访问它们。
        猜你喜欢
        • 1970-01-01
        • 2015-03-31
        • 1970-01-01
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        • 2014-09-01
        相关资源
        最近更新 更多