我在一个简单的 Bash 脚本中收到“意外标记‘'$#''附近的语法错误”

rap*_*l75 4 bash syntax

我正在使用Debian 10 (Buster) 并且在一个简单的 Bash 脚本中遇到错误。它所做的只是检查是否传入了一个参数,如果它是一个文件,只需回显该文件:

#!/usr/bin/bash
if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then
        echo "$1"
fi

exit 1
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

line 2: syntax error near unexpected token `'$#''
line 2: `if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then'
Run Code Online (Sandbox Code Playgroud)

我已经尝试了围绕 的所有引号(“,',无引号)的组合$#,并且我总是使用我使用的引号类型获得这些错误消息的变体。我无法弄清楚它在寻找什么。

ter*_*don 20

这里有两个问题。首先,简单的[内置函数不能包含&&. 如果要组合多个条件,则需要多个[

if [ "$#" -eq 1 ] && [ -f "$1" ]; then
Run Code Online (Sandbox Code Playgroud)

其次,您不能在 周围使用单引号,$#因为它需要扩展。您的版本'$#' -eq 1是将字符串 $#与数字 1进行比较。

如果你使用 bash 的[[关键字,整个事情就会简单得多:

if [[  "$#" -eq 1  &&  -f "$1"  ]]; then
Run Code Online (Sandbox Code Playgroud)


Fox*_*Fox 11

[是一个命令,所以问题实际上是您尝试使用多个条件的方式。你要这个:

if [ "$#" -eq 1 ] && [ -f "$1" ]; then
Run Code Online (Sandbox Code Playgroud)


JoL*_*JoL 10

尽管其他答案解释了如何修复脚本,但我想知道技术上的错误是什么。我认为 bash 允许命令中的单词不带引号和不转义的唯一有效语法(是定义函数时。所以,bash 看到(并立即认为它必须是一个名为 的函数的定义[,但随后你跟着'$#'bash 只是期待),所以这就是你遇到语法错误的原因。如果它不是一个函数定义,那么谁知道它是什么意思。(除此之外的任何其他内容)都会引发相同的语法错误:

$ echo ( foo )
bash: syntax error near unexpected token `foo'
Run Code Online (Sandbox Code Playgroud)

如果删除(不符合函数定义语法的内容,您将得到:

$ [ ( ) ( -f "$1" )
Run Code Online (Sandbox Code Playgroud)

最终定义了函数[

$ [
bash: -f: command not found
Run Code Online (Sandbox Code Playgroud)

  • 事实上它是一个 if 语句并不重要,你仍然可以在其中定义一个函数。`如果[(){回声你好;}; 然后 [; [; fi` 打印了两次 `hello`。 (5认同)