我有这个代码:
[[ "$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/sh
BSD 上的内容通常是 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 美元 */|*\\) 摆动;; *) 摇摆;; 埃萨克
进一步阅读
- “实用程序:测试”。 外壳命令语言。单一 UNIX 规范。第 6 期。IEEE 1003.1。 2013。公开组。
- https://superuser.com/a/726762/38062
- https://superuser.com/a/696310/38062
sh
。 2014年1月26日。 FreeBSD 通用命令手册。- 破折号为
/bin/sh
。 Ubuntu 维基。 - 破折号为
/bin/sh
。 Debian 维基。 - 巴什主义。格雷格的维基。
- 外壳命令语言。 IEEE 标准 1003.1。第 7 期。开放组。
答案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