bash 脚本中意外标记“do”附近的语法错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37151619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:18:00  来源:igfitidea点击:

syntax error near unexpected token `do' in bash script

bashunixffmpeg

提问by Avi

I have bash script which takes 3 parameters from the command line. It compares all of the files in the directory to see if they are of the type of the first 2 parameters. If they are, the script converts such files to the type of the third parameter using an FFMPEG command. I would execute the script with the following command:

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

./convert.sh .avi .mp4 .flv 

That this, this script would convert all of the .avi and .mp4 files to .flv.

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

When I run the script, I get the error

当我运行脚本时,出现错误

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

Here is the code:

这是代码:

#!/bin/bash

#  is the first parameter passed
#  is the second parameter passed 
#  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} == "" ) || ( ${file: -4 } == "" )  ]{
            export extension=${file: -4}
            #converting such files to the type of the first parameter using the FFMPEG comand
            do ffmpeg -i "$file" "${file%.extension}";
done

采纳答案by Greg

You have some issues with your formatting and syntax. sjsam's advice to use shellcheck is good, but the short version is that you should be using square brackets instead of round ones on the internal brackets of your if statement:

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

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

And I don't think you need the 'do' before your ffmpeg line or the curly bracket at the end of the line above, so you end up with...

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

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

回答by Sheikh Abdul Wahid

For me, it was due to CRLF. It should be LFfor linux env.

对我来说,这是由于CRLF. 它应该LF适用于 linux env。

回答by Gordon Davisson

There are a bunch of syntax errors here. Let's start with the line:

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

if[  ( ${file: -4} == "" ) || ( ${file: -4 } == "" )  ]{
  • You need a space between ifand [(or whatever comes after it). As written, the shell is treating "if[" as the name of a command, which isn't what you want at all.

  • The [ ... ]style of conditional doesn't understand ||(it uses -oinstead), requires that all shell metacharacters (like parentheses) be escaped or quoted, might not understand ==(just =is the standard), and will get very confused if any of the unquoted variable/parameter references are blank.

  • ifconditionals end with then(either on the next line, or after a ;) not {

  • 您需要在if[(或后面的任何内容)之间留一个空格。正如所写,shell 将“if[”视为命令的名称,这根本不是您想要的。

  • [ ... ]条件的样式不理解||(它使用-o),要求所有 shell 元字符(如括号)被转义或引用,可能不理解==(只是=标准),如果任何未引用的变量/参数引用为空。

  • if条件以then(在下一行或在 a 之后;) not{

You could fix it like this:

你可以像这样修复它:

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

Or, since you're using bash(instead of a more basic shell), you can use the [[ ... ]]conditional style, which has much cleaner syntax:

或者,由于您正在使用bash(而不是更基本的 shell),您可以使用[[ ... ]]条件样式,它具有更清晰的语法:

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

Next, remove the dobefore ffmpeg. dois part of the syntax for forand whileloops; you already have one above (where it belongs), and this one just doesn't make sense. This is what's causing the error you see.

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

Next, the way you're replacing the file's extension won't work right. The variable reference "${file%.extension}"$3will try to remove ".extension" (not the variable, just the string) from the end of $file. It also has $3outside the quotes, which can cause trouble. You could fix it by using "${file%$extension}$3"instead, but frankly I'd just use "${file%.*}$3"to remove the extension no matter what length it is (and I'd also redo the ifcomparisons similarly, but that's more complicated).

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

Finally, you need a fi(after the ffmpegline) to end the conditional. Every ifneeds a thenand a fi.

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

And just as a stylistic thing, you don't need ;at the end of a line in shell; it's only needed when you're putting multiple commands (or things like doand then) on the same line. Anyway, here's my quick rewrite:

就像文体一样,你不需要;在 shell 中的行尾;仅当您将多个命令(或诸如do和 之类的东西then)放在同一行上时才需要它。无论如何,这是我的快速重写:

#!/bin/bash

#  is the first parameter passed
#  is the second parameter passed 
#  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}" = "" || "${file: -4}" = ""  ]]; then
        #converting such files to the type of the first parameter using the FFMPEG comand
        ffmpeg -i "$file" "${file%.*}"
    fi
done

回答by user3439894

Your script could be reduced to simply:

您的脚本可以简化为:

#!/bin/bash

for file in *; do
    [[ ${file: -4} =  || ${file: -4} =  ]] && ffmpeg -i "$file" "${file%.*}"
done