FreeBSD 的双方括号

FreeBSD 的双方括号

我有这个代码:

[[ "$1" =~ [/\\]$ ]]

在 Linux 上它工作得很好,但是当我在 FreeBSD 上测试它时,发生了错误:./projekt2.sh: [[: not found并且它..我有任何可以在两个系统上工作的替代方案吗?谢谢

BASH 版本:4.3.30(1)-发布

答案1

[[是一种羞辱。 /bin/sh不保证是 Bourne Again shell。

即使在 Linux 操作系统上,它也可能是 Debian Almquist shell 或符合策略的普通 shell。在 BSD 上,它不是开箱即用的 Bourne Again shell,因为在 BSD 上,Bourne Again shell 是操作系统本身的可选附加组件。在里面FreeBSD ports 集合。 (“端口”是在 FreeBSD 上从这些程序的外部维护源存储库构建其他程序(不是 FreeBSD 的一部分)的便捷方法。)

/bin/shBSD 上的内容通常是 Bourne 的早期重写之一。在 FreeBSD 上它是 Almquist shell,就像在 Debian Linux 上一样。 (在 OpenBSD 上,它是在 POSIX 模式下运行的 Korn shell。)

bashism 有一个简单的规则:

如果您在脚本中使用 bashism,请明确将其设置/bin/bash为脚本解释器。如果您改为使用/bin/sh作为脚本解释器,则请坚持使用符合 POSIX 标准的 shell 语言独自的

=~也是一种 bashism,并且不是该命令的 POSIX 兼容语法的一部分test。但这里的正则表达式有点矫枉过正,因为您显然真正要做的只是检查最后一个字符。

以下是 Thorsten Glaser 在 2012 年针对此类事情提出的建议:

案例 1 美元
    */|*\\)
        摆动;;
    *)
        摇摆;;
埃萨克

进一步阅读

答案2

[[语法是 ksh 和 bash 的东西,并不存在于所有 shell 中。你的 FreeBSD 默认 shell 可能是sh(或者 bash 的作用类似sh),而不是 bash。适用于所有 shell 的等效语法是:

case $1 in
        *[/\\] ) echo "Yes";;
esac

答案3

[[结构并不存在于所有 sh 变体中。它是 ksh 的东西,被 bash 和 zsh 采用。 FreeBSD 的 sh 是 ash 衍生品,不支持[[.

如果您想[[在脚本中使用,请使用舍邦调用支持[[.您可以在 FreeBSD 上将 bash 或 ksh93 或 mksh 作为软件包安装;他们都支持[[。软件包安装在 下/usr/local/bin,而 Linux 上的 bash 几乎总是安装在/bin;你可以用它/usr/bin/env来调用一个程序PATH(这是一个经典的黑客)。因此,如果您想使用[[bash 和其他 bash 结构,请确保安装了 bash 软件包并使用以下命令启动脚本

#!/usr/bin/env bash

或者,在 Linux 上创建一个符号链接/usr/local/bin/bash -> /bin/bash,然后使用以下命令启动脚本

#!/usr/local/bin/bash

/bin/bash -> /usr/local/bin/bash或者在 FreeBSD 上创建一个符号链接并以#!/bin/bash.

或者,编写遵循通用 sh 核心的脚本。使用[而不是[[.请注意,这[是一个普通命令,而不是保留字,因此单括号内的内容会正常解析,与双括号内的内容不同 - 例如,您不能以[[ condition1 && condition2 ]]与单括号相同的方式编写,您需要编写[ condition1 ] && [ condition2 ].普通 sh 没有正则表达式匹配构造,但对于您正在做的事情,通配符模式匹配就足够了:

case "$1" in
  *[\\/]) echo "$1 ends with a slash or backslash";;
  *) echo "$1 does not end with a slash or backslash";;
esac

相关内容