UbuntuでshにBashを使用する方法


13

rpmファイルとしてリソースを持つ巨大なプログラムをインストールしています。の行で立ち往生

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

どうやら、この構文shを使用bashしてRed Hat Linuxで動作しますがunexpected operator、Ubuntuでエラーが発生します。

bashスクリプトがrpmパッケージから取得されるため、スクリプトをに変更できません。rpmパッケージを抽出して再パックすることはできますが、そのようなスクリプトが多数ある可能性があります。

御馳走にシェルのデフォルトを変更する方法がある#!/bin/shとしてbash扱うことができ、または何か他の[オペレータは?


5
唯一間違っているのは、==それがあるべきこと=です。そして、変数展開は二重引用符で囲む必要があります。
クサラナナンダ

4
[は演算子ではなく、と呼ばれる組み込みコマンドですtest。予期しない演算子はPOSIXに準拠していないため==、これを置き換える必要があり=ます。
18年

2番目に間違っているのは、$SCITEGICPERLHOME引用する必要があることです。
l0b0

12
プログラムの作者に文句を言うべきです。を使用する場合、拡張#!/bin/sh機能ではなくPOSIXシェル機能のみを使用するようにしてくださいbash。このプログラマは非常にずさんです。彼は自分のコードを修正するか、を使用する必要があります#!/bin/bash
バーマー

他の同様の問題を知りたい人のために、ここに「バシズム」のリストがあります。この質問も参照してください。
キャプテンマン

回答:


21

の言語を実装する複数のプログラムがあります/bin/sh。Ubuntuに/bin/shはダッシュがあります。これは高速で、少量のメモリを使用するように設計されており、から予想される最小値をはるかに上回りません/bin/sh。RHELに/bin/shはbashがあります。bashはより遅く、より多くのメモリを使用しますが、より多くの機能を備えています。これらの機能の1つは==[条件付き構文の演算子です。Dashは[基本的なsh機能であるをサポートしています==が、bash(およびkshとzsh)拡張機能である演算子はありません。

システムをbashを使用するように切り替えることができます。Ubuntuでは、/bin/shへのシンボリックリンクdashです。bash代わりにシンボリックリンクにすることができます。DebianおよびUbuntu(および派生物)の現在のバージョンは、これをダッシュ​​のインストールオプションにします。変更するには、実行します

sudo dpkg-reconfigure dash

ダッシュをそのままにする/bin/sh場合は「yes」、bashに切り替える場合は「no」と答えます。

bashをそのまま/bin/shにしておくことができますが、システムが少し遅くなります。一部のシステムスクリプトはbashと互換性がないことも考えられますが、bashはほとんどがダッシュのスーパーセットであるため、それはありそうにありません。


の実装を選択するためのインターフェースを持たないディストリビューションの場合/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

shが/bin/bashディストリビューションでデフォルトである場合、bashにはdashよりも多くの機能があるため、dashに切り替えるとスクリプトが失敗する可能性があることに注意してください。Bashスクリプトはで始まる必要があり#!/bin/bash、で始まるスクリプト#!/bin/shはbash固有の機能を使用するべきではありませんが、bashに付属するディストリビューションは、そのディストリビューションに/bin/sh固有の#!/bin/shスクリプトでbash固有の機能を使用する場合がありますとしてダッシュに切り替えることができ/bin/sh、これらのスクリプトが別のディストリビューションで機能することは期待できません)。


私のそれほど謙虚な意見では、あるスクリプト/bin/shがBashのときに失敗する場合、それはシステム(スクリプトを含むパッケージ)またはBashのsh-modeのバグです。Stephenが言うように、システムは明示的/bin/shにBashに戻ることを許可しますdpkg-reconfigure。この問題に関するUbuntu wikiでも可能性として言及されています:wiki.ubuntu.com/DashAsBinSh
ilkkachu

5
@ilkkachuはい、/bin/shbashである場合にスクリプトが失敗すると、バグになります。ただし、バグが発生します。他の人があなたのためにそれをテストしたので、私はあなたがそのようなバグを能力がなく、喜んで診断するならデフォルトに固執することを勧めます。/bin/shDebianで公式にサポートされる以前のようにダッシュを使用しましたが、何かが起こった場合に対処できることを知って、これは私が取ったリスクでした。
ジル 'SO-悪であるのをやめる'

手動で上書きされたシンボリックリンクはdebconf、次回のdash更新時に保存された構成に復元されることに注意してください。確かに、これはDebian安定版を実行しているシステムでは(特定のリリースで)頻繁には起こりません。
スティーブンキット

36

(デフォルトではなく)に切り替えるshには、再構成します(はい、直感に反します):bashdashdash

sudo dpkg-reconfigure dash

これdashにより、デフォルトのシステムシェルになりたいかどうかが尋ねられます。答えは「いいえ」(Tabその後Enter)及びbash(代わりにデフォルトになりますつまり /bin/shを指します/bin/bash)。


1
あなたの解決策は確かに最も合理的なものですが、問題を明確にする詳細な説明のために別の答えを受け入れました。ご不便をかけて申し訳ありません。
Googlebot

@Googlebotは謝罪する必要はありません。受け入れられた答えを選択することは、アスカーの特権です。そして、私はそれから金バッジを得ました;-)。
スティーブンキット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.