bash 意外标记“fi”附近的语法错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20586785/
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-10 00:31:56  来源:igfitidea点击:

Syntax error near unexpected token 'fi'

bash

提问by Calvin Koder

I'm trying to write a script that removes all the .jpg's that end in an odd number. This is my code:

我正在尝试编写一个脚本来删除所有以奇数结尾的 .jpg。这是我的代码:

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if[$((fname %  2)) -eq 1 ] then
    echo "removing $fname\n"
    rm $f
  fi
done

When I run it it outputs start and then says "syntax error near unexpected token 'fi'"

当我运行它时,它输出 start 然后说“意外标记 'fi' 附近的语法错误”

When I had then on the line after if it said "syntax error near unexpected token 'then'"

当我上线后,如果它说“意外标记附近的语法错误'then'”

How do i fix this?

我该如何解决?

回答by jprice

As well as having thenon a new line, you also need a space before and after the [, which is a special symbol in BASH.

除了then换行外,您还需要在 前后留一个空格[,这是 BASH 中的一个特殊符号。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [ $((fname %  2)) -eq 1 ]
  then
    echo "removing $fname\n"
    rm "$f"
  fi
done

回答by Sagar

Use Notepad ++ and use the option to Convert the file to UNIX format. That should solve this problem.

使用 Notepad ++ 并使用将文件转换为 UNIX 格式的选项。那应该可以解决这个问题。

回答by peterh - Reinstate Monica

"Then" is a command in bash, thus it needs a ";" or a newline before it.

“then”是bash中的命令,因此它需要一个“;” 或者它之前的换行符。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [$[fname%2] -eq 1 ]
  then
    echo "removing $fname\n"
    rm $f
  fi
done

回答by Aleks-Daniel Jakimenko-A.

The first problem with your script is that you have to put a space after the [.
Type type [to see what is really happening. It should tell you that [is an alias to testcommand, so [ ]in bash is not some special syntax for conditionals, it is just a command on its own. What you should prefer in bash is [[ ]]. This common pitfall is greatly explained hereand here.

你的脚本的第一个问题是你必须在[.
键入type [以查看实际发生的情况。它应该告诉你这[test命令的别名,所以[ ]在 bash 中不是一些特殊的条件语法,它本身只是一个命令。在 bash 中你应该更喜欢的是[[ ]]. 这个常见的陷阱在这里这里都有很好的解释。

Another problem is that you didn't quote "$f"which might become a problem later. This is explained here

另一个问题是您没有引用"$f"这可能会在以后成为问题。这是解释here

You can use arithmetic expressions in if, so you don't have to use [ ]or [[ ]]at all in some cases. More info here

您可以在 中使用算术表达式if,因此在某些情况下您不必使用[ ]或根本不必使用[[ ]]。更多信息在这里

Also there's no need to use \nin every echo, because echoplaces newlines by default. If you want TWO newlines to appear, then use echo -e 'start\n'or echo $'start\n'. This $''syntax is explained here

也不需要\n在 every 中使用echo,因为echo默认情况下会放置换行符。如果您希望出现两个换行符,请使用echo -e 'start\n'echo $'start\n'。此$''语法解释here

To make it completely perfect you should place --before arbitrary filenames, otherwise rmmight treat it as a parameter if the file name starts with dashes. This is explained here.

为了使其完全完美,您应该将其放在--任意文件名之前,否则rm如果文件名以破折号开头,则可能会将其视为参数。这是解释here

So here's your script:

所以这是你的脚本:

#!/bin/bash
echo "start"
for f in *.jpg
do
    fname="${f##*/}"
    echo "fname is $fname"
    if (( fname % 2 == 1 )); then
        echo "removing $fname"
        rm -- "$f"
    fi
done