问题描述
我正在安装一个巨大的程序,该程序的资源作为rpm
文件。它卡在
#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]
显然,sh
使用此语法在Red Hat Linux中适用于bash
,但在Ubuntu中却给出了unexpected operator
的错误。
我无法将脚本更改为bash
,因为该脚本来自rpm
软件包。我可以解压缩并重新打包rpm
程序包,但是可能有很多这样的脚本。
有没有办法更改Shell默认值,以将#!/bin/sh
视为bash
或其他任何可以处理[
运算符的方法?
最佳答案
有多个程序实现/bin/sh
的语言。在Ubuntu上,/bin/sh
是破折号,旨在快速运行,以使用少量内存,并且不支持超过/bin/sh
期望的最小值。在RHEL上,/bin/sh
是bash,速度较慢,使用的内存更多,但功能更多。这些功能之一是[
条件语法的==
运算符。 Dash支持[
,这是基本的sh功能,但没有==
运算符,后者是bash(以及ksh和zsh)扩展名。
您可以将系统切换为使用bash。在Ubuntu上,/bin/sh
是dash
的符号链接。您可以改为使其成为bash
的符号链接。当前版本的Debian和Ubuntu(及其衍生版本)使它成为破折号的安装选项。要更改它,请运行
sudo dpkg-reconfigure dash
并回答“yes”以将破折号保持为/bin/sh
或“no”以切换为bash。
您可以将bash保留为/bin/sh
,但这会使您的系统速度变慢。甚至可以想象某些系统脚本与bash不兼容,尽管这不太可能,因为bash主要是破折号的超集。
对于没有接口在/bin/sh
的实现之间进行选择的发行版,这是切换到bash的方法。
sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh
将终端保持打开状态,然后检查您仍然可以运行一些sh
脚本。如果您弄乱了该命令,它将使您的系统无法使用。 (顺便说一句,我使用上面的多个命令而不是straightforward-looking 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
请注意,如果您的发行版上默认情况下sh为/bin/bash
,则切换到破折号可能会导致脚本失败,因为bash的功能比破折号更多。 Bash脚本应以#!/bin/bash
开头,以#!/bin/sh
开头的脚本不应使用bash-specific功能,但是随bash一起发行的发行版(作为/bin/sh
)可以在特定于该发行版的#!/bin/sh
脚本中使用bash-specific功能(只要没有用户期望就可以可以切换为破折号(/bin/sh
,并且不期望这些脚本可以在其他发行版上运行)。
次佳答案
要将sh
切换到bash
(而不是默认值dash
),请重新配置dash
(是的,有点像counter-intuitive):
sudo dpkg-reconfigure dash
这将询问您是否要dash
作为默认系统 shell 程序;回答“No”(Tab
然后Enter
)和bash
将成为默认值(即/bin/sh
指向/bin/bash
)。