我正在安装一个巨大的程序,它的资源是一个rpm
文件。它卡在了线
#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]
显然,使用此语法可以在 Red Hat Linux 中sh
工作,但在 Ubuntu 中bash
却给出错误。unexpected operator
我无法更改脚本,bash
因为脚本来自rpm
包。我可以提取并重新打包该rpm
包,但可能有很多这样的脚本。
有没有办法将 shell 默认值更改为视为#!/bin/sh
或bash
其他任何可以处理[
运算符的方法?
答案1
最高可达 Ubuntu 22.04(以及 Debian 11),你可以通过重新配置切换sh
到bash
(而不是dash
默认的)dash
(是的,这有点违反直觉):
sudo dpkg-reconfigure dash
这会询问你是否想dash
成为默认的系统 shell;回答“否”(Tab然后Enter)bash
并将成为默认值(IE /bin/sh
将指向/bin/bash
)。
从 Ubuntu 22.10 和 Debian 12 开始,不再支持此功能;如果您想切换/bin/sh
到/bin/bash
,则必须手动对其进行符号链接。看吉尔斯的回答了解详情。
答案2
有多个程序实现/bin/sh
.在 Ubuntu 上,/bin/sh
是 dash,它的设计速度很快,使用少量内存,并且不支持超出/bin/sh
.在 RHEL 上,/bin/sh
是 bash,它速度较慢,使用更多内存,但功能更多。这些功能之一是条件语法==
的运算符[
。 Dash 支持[
,这是一个基本的 sh 功能,但它没有==
作为 bash(以及 ksh 和 zsh)扩展的运算符。
您可以将系统切换为使用 bash。在 Ubuntu 上,/bin/sh
是指向dash
.您可以将其设为符号链接bash
。当前版本的 Debian 和 Ubuntu(及其衍生版本)使其成为 dash 的安装选项。要更改它,请运行
sudo dpkg-reconfigure dash
并回答“是”以保持破折号为/bin/sh
或“否”以切换到 bash。
您可以将 bash 保留为/bin/sh
,但这会使您的系统变慢一些。甚至可以想象,某些系统脚本与 bash 不兼容,尽管这不太可能,因为 bash 主要是 dash 的超集。
对于没有接口可以在 的实现之间进行选择的发行版/bin/sh
,以下是如何切换到 bash。
sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh
保持终端打开并检查sh
之后是否仍然可以运行一些脚本。如果你搞乱了这个命令,它会让你的系统无法使用。 (顺便说一句,我使用上面的多个命令而不是简单的命令的原因sudo ln -sf bash /bin/sh
是它ln -sf
不是原子的。在不可否认的不太可能的情况下,您的计算机在此操作期间崩溃,您需要从救援媒体启动才能恢复它。相反,mv
是原子的。)
要将破折号恢复为/bin/sh
:
sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh
请注意,如果/bin/bash
您的发行版默认使用 sh,则切换到 dash 可能会导致脚本失败,因为 bash 的功能比 dash 多得多。 Bash 脚本应该以 开头#!/bin/bash
,并且以 开头的脚本#!/bin/sh
不应该使用 bash 特定的功能,但是 bash 附带的发行版/bin/sh
可以在特定于该发行版的脚本中使用 bash 特定的功能#!/bin/sh
(只要用户不期望可以切换到 dash as/bin/sh
并且不希望这些脚本在另一个发行版上工作)。