如何在 Ubuntu 中使用 Bash 进行 sh

如何在 Ubuntu 中使用 Bash 进行 sh

我正在安装一个巨大的程序,它的资源是一个rpm文件。它卡在了线

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

显然,使用此语法可以在 Red Hat Linux 中sh工作,但在 Ubuntu 中bash却给出错误。unexpected operator

我无法更改脚本,bash因为脚本来自rpm包。我可以提取并重新打包该rpm包,但可能有很多这样的脚本。

有没有办法将 shell 默认值更改为视为#!/bin/shbash其他任何可以处理[运算符的方法?

答案1

最高可达 Ubuntu 22.04(以及 Debian 11),你可以通过重新配置切换shbash(而不是dash默认的)dash(是的,这有点违反直觉):

sudo dpkg-reconfigure dash

这会询问你是否想dash成为默认的系统 shell;回答“否”(Tab然后Enterbash并将成为默认值(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并且不希望这些脚本在另一个发行版上工作)。

相关内容