Ubuntu-OSXの互換性、使いやすさ、POSIXには#!/bin/shまたは#!/bin/bashを使用してください。

Ubuntu-OSXの互換性、使いやすさ、POSIXには#!/bin/shまたは#!/bin/bashを使用してください。

私は、必要なシェルを呼び出すためにスクリプトの最初の行としてこれらのいずれかを使用できることを知っています。

#!/bin/shすべてのUNIXシステムとの互換性が絶対的な要件であることをお勧めしますか?

私が興味を持っているオペレーティングシステムはUbuntu(Debian)とOSXだけです。では、これを使用して#!/bin/bash両方のシステムで動作することを保証できますか?
これにより、より現代的で明確なコマンド構文を使用するスクリプトを簡単に使用できますか?使用は#!/bin/shPOSIXの使用とも関連していますか?

答え1

まず、Bashがプリインストールされていると仮定できる場合(私が知っている限り、リストされているすべてのシステムに対応)、互換性のために次のハッシュバンを使用してください。

#!/usr/bin/env bash

これはinかoutかbashどうかにかかわらず、すべての設定で呼び出されます。/bin/usr/local/bin

ほとんどのシステム(AIX、Solaris、複数のBSDバージョンを含む)は常にbash別の場所にあります。しかし、このヒントは私が書いたものではなく、Bash Cookbookの作者が提供したものです。env/usr/bin/env

とにかく、そうです。 Bashを使用すると、「現代的な」機能を使用して人生をより簡単にすることができます。

たとえば、二重括弧は次のようになります。

[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"

そして伝統的なシェル方言では、以下を使用する必要があります。

test -f "/etc/debian_version" && echo "This is a Debian flavor"

しかし、二重括弧の最大の利点は、正規表現を使用した一致が可能であることです。これバッシュハッカーウィキこれについて多くのアドバイスをいたします。

$((2**10))構文とともにインラインで他の算術式などの非常に便利な式を使用することもできます$((expression))

少し昔ながらですが、サブシェルにバックティックを使用するのは大丈夫です。ただし、呼び出しのネスト機能は、$(command ...)さまざまなサブシェルレベルで多くの項目をエスケープする必要がないため、より便利です。

これは、Bashが従来の一般的なPOSIX構文と比較して提供する機能のほんの一部ですsh

しかし、スクリプトだけでなくシェルでより多くの機能が必要な場合は、見てくださいzsh

答え2

DebianとUbuntuでは/bin/shそうですdash。 POSIX互換シェルです。指定した場合は、#!/bin/shスクリプトでPOSIXステートメントに制限する必要があります。 (利点は.dashより速く開始されるため、bashスクリプトが短時間で作業を実行できることです。)

多くの(ほとんど?)他のLinuxシステムではそうです。これはまさに多くのスクリプトが/bin/sh拡張子です。bash#!/bin/shbash

bash拡張機能を使用したい場合は、すべてのシステムで最も安全な方法です#!/bin/bashbash必要DebianとUbuntuでこれを行います。追加ボーナスとして、一部の拡張機能は実行時に無効になります/bin/sh bash(参照:bashPOSIXモードの説明詳細はこちらをご覧ください。)したがって、#!/bin/bash最大限に活用するためにbash

OS Xでも/bin/bash使用でき、/bin/shyesとしてbash指定して#!/bin/bashも問題ありません。

答え3

はい、OSXとLinuxの両方が提供されています/bin/bash。絶対に安全でしょう。しかしそれはいいえPOSIX。 POSIXシェルは/bin/shほとんどの(すべての)システムに存在し、最も移植性の高い方法であり、POSIXと互換性がある唯一の方法です。

/bin/sh多くのシステムでは異なるシェルを指しますが、bash他のシステムでは異なるシェルを指すことがあります。dashたとえば、DebianとUbuntuのシンボリックリンクです。また/bin/shlink を使用してもシェルがbash呼び出されるとシェルの動作が変更されますsh( from man bash、強調内の項目)。

bash が sh 名で呼び出されると、POSIX 標準に準拠しながら、sh の以前のバージョンの起動動作をできるだけ近い模倣しようとします。 --login オプションを使用して対話型ログインシェルまたは非対話型シェルとして呼び出されると、まず /etc/profile および ~/.profile からコマンドを順番に読み込んで実行しようとします。 --noprofileオプションを使用すると、この動作を抑制できます。 shという名前の対話型シェルとして呼び出されると、bashは変数ENVを探し、その
値が定義されている場合は拡張し、拡張値を読み取り、実行するファイル名として使用します。 shで呼び出されたシェルは他の起動ファイルからコマンドを読み込んで実行しようとしないため、--rcfileオプションは効果がありません。 shという名前で呼び出された非対話型シェルは、他の起動ファイルを読み取ろうとしません。 sh で呼び出されると、 bash は起動ファイルを読み込み、posix モードに入ります。

答え4

「すべてのUnixシステム」との互換性が絶対に必要な場合 -そうでなければ、なぜシェルスクリプトを書いていますか?- そうであれば、#! /bin/shBashのインストールは保証されていないので、使用する必要があります。どこかにはもちろんです/bin

実際にはそれよりはるかに悪いです。互換性が必要な場合みんなSolarisやAIXなどを含むUnixシステムシェル環境凍結1995年頃。これはsort +N、古い構文のようなものを使用する必要があることを意味します。最新システムがオフラインです!これはまた、シェル関数なし、配列なし、[[ ... ]]算術${foo#glob}なし$(( ... ))、スタイルコマンド置換なし$( ... )、小さく文書化されていない入力サイズの上限などを意味します。

君は気にせず逃げられるかもしれないそれ互換性は優れていますが、これが最初から問題である場合は、シェルよりも安全な言語を検討することを強くお勧めします。デフォルトのPerlインタプリタは次のとおりです。もっとおそらくBashよりも便利です。

関連情報