【问题标题】:Mac OSx terminal : "not a valid identifier" on function definitionMac OSx终端:函数定义上的“不是有效标识符”
【发布时间】:2019-04-21 05:42:01
【问题描述】:

我有一个 bash 脚本,我在其中定义了以下函数,

function start-if-exists()
{
    if [ "`docker container ls -a|grep $1`" ]; then
        echo "Container $1 exists. Starting $1..."
        return `docker start $1`
    else
        echo "Container $1 doesn't exists."
        return ""
    fi
}

直接在终端(zsh)中执行上述功能时,我没有收到任何错误。但是当我使用sh 命令(sh my_script.sh)执行它时,我得到了以下错误。

my_script.sh:第 10 行:`start-if-exists':不是有效标识符

其中my_script.sh 是文件名。

我的脚本适用于 zsh 但在 sh 中失败,我错过了什么?

【问题讨论】:

  • 哪个 shell 正是你的sh?您可以通过查看符号链接的目标找到:realpath /bin/sh
  • @user803422:该问题涉及 Mac OS X。在 Mac OS X 或 macOS 上,realpath 不存在,/bin/sh 不是符号链接,除非已进行非 Apple 修改系统制作。
  • return 仅用于返回 8 位状态码,而非任意字符串。

标签: shell sh zsh


【解决方案1】:

/bin/shbash,但是当以 /bin/sh 启动时,它以 POSIX 模式启动。根据bash 手册页,在 POSIX 模式下:

  1. 函数名称必须是有效的 shell `name's。也就是说,他们可能不会 包含除字母、数字和下划线以外的字符,以及 不能以数字开头。声明一个无效的函数 name 在非交互式 shell 中会导致致命的语法错误。

关于如何解决此类问题的说明:

  • 在终端命令行中,我执行了/bin/sh --version 以查看有关它的信息。它打印了“GNU bash,版本 3.2.57(1)-release (x86_64-apple-darwin17)”。
  • 然后我参考了bash 手册页,使用命令man bash。由于这很长,您可能更喜欢将副本保存到文件并在首选文本编辑器中查看。原始的man 输出包括过时的下划线和退格键。您可以通过执行man bash | col -b > file.txt 来获取没有这些的副本。
  • 在手册页中,我搜索了“sh”(作为一个完整的词,而不是对这些字母的原始搜索,因为它们作为许多不相关词的一部分出现)。这很快揭示了 bash 在以“sh”开头时表现不同的讨论;它以 POSIX 模式启动。
  • 进一步搜索“POSIX”会发现在 POSIX 模式下的不同之处。

【讨论】:

  • /bin/sh 并不总是 bash。可以是dashash等。
  • @user803422:这个问题询问的是 Mac OS X,而不是一般的 Unix。在 Mac OS X 上,sh 是 GNU bash,除非对系统进行了非 Apple 修改。
  • 当我将 '-' 更改为 '_' 时,问题已解决。
猜你喜欢
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 2011-08-14
  • 1970-01-01
相关资源
最近更新 更多