web-dev-qa-db-ja.com

bashスクリプトの代わりにzshを使用することをお勧めしますか?

十分な数の人がzshをインストールして、

#!/usr/bin/env zsh

シバンとして?

または、これにより、スクリプトが多すぎるシステムで実行できなくなりますか?

明確化:エンドユーザーが実行する可能性のあるプログラム/スクリプトに興味があります(Ubuntu、Debian、SUSE、Archなど)。

27
Profpatsch

移植性のために、いいえ。 zshは、少なくともCygwinを介して、任意のUnixまたはUnixライクなWindowsでコンパイルでき、ほとんどのオープンソースUnixライクおよびいくつかの商用のもの用にパッケージ化されていますが、通常、デフォルトのインストールには含まれていません。

反対側のbashは、GNUシステムにインストールされます(bashは、GNUプロジェクトのシェルであるため))ほとんどの非組み込みLinuxベースのシステムのようにApple OS/Xのような非GNUシステムでは時々あります。商用のUnix側では、Korn Shell(AT&Tバリアントですが、ksh88 one)が標準であり、 bashzshの両方がオプションパッケージに含まれています。BSDでは、優先するインタラクティブシェルは多くの場合tcshですが、shはAlmquistシェルまたはpdkshに基づいており、bashまたはzshもオプションパッケージとしてインストールする必要があります。

zshは、デフォルトでApple OS/Xにインストールされています。これは以前は/bin/shでした。デフォルトでは、SysRescCD、Grml、GobolinuxなどのいくつかのLinuxディストリビューションにあります。そしておそらく他の人が、私は主要なもののどれも考えていません。

bashの場合と同様に、インストールされているバージョンと、結果として使用可能な機能の問題があります。たとえば、bash3またはzsh3のシステムを見つけることは珍しくありません。また、zsh5で現在作成しているスクリプトがzsh6で機能することは保証されていませんが、bashと同様に、下位互換性を維持しようとします。

スクリプトの場合、私の見解は次のとおりです。すべてのUnicesには、その構文を解釈できるsh(必ずしも/binではない)と呼ばれるシェルが少なくとも1つあるため、POSIXシェル構文を使用します。そうすれば、移植性についてそれほど心配する必要はありません。そして、その構文で十分ではない場合は、おそらくシェル以上のものが必要です。

次に、オプションは次のとおりです。

  • ユビキタスなPerl(ここでも、古いバージョンの機能セットに制限する必要があり、デフォルトでインストールされているPerlモジュールを想定できない場合があります)
  • インタープリターとそのバージョン(python 2.6以降、zsh 4以降、bash 4.2以降...)をスクリプトの依存関係として指定します。依存関係を指定するすべてのターゲットシステムのパッケージをビルドするか、依存関係を指定します。 READMEファイルがスクリプトと一緒に出荷されるか、スクリプトの上部にコメントとして埋め込まれるか、またはスクリプトの先頭にBourne構文の数行を追加して、 このスクリプトにはzsh 4.0以降が必要のように、インタープリターを要求し、そうでない場合は明示的なエラーでベイルアウトします。
  • スクリプトと一緒にインタープリターを出荷します(ライセンスの影響に注意してください)。つまり、対象となるすべてのOSに1つのパッケージが必要です。一部のインタープリターは、スクリプトとそのインタープリターを単一の実行可能ファイルにパックする方法を提供することにより、それを容易にします。
  • コンパイルされた言語で書いてください。この場合も、ターゲットシステムごとに1つのパッケージです。
29

いいえ、あなたがすることはできません。保証されているのは/bin/sh、本質的にはオリジナルのボーンシェル。ほとんどすべての(「ほぼ」に注意してください!)Linuxインストールにはbashがありますが、* BSDシステムではまれです(BSDの説得では、bashのようにGPLコードについて深刻な懸念があります)。 Macで標準のShellが何であるかはわかりませんが、GPLについては不安があります。 Solarisでも同じです。

zshはニッチなシェルであり、Fedoraのデフォルトのインストールには含まれていません(そして、主要なディストリビューションのデフォルトであるとは思いません)。

9
vonbrand

私はそれが本当にあなたが使っているzsh余分な機能と場所に依存すると思います。さまざまなユーザーやシステムにスクリプトを配布する場合は、bashまたはを使用することをお勧めしますsh

スクリプトが組織全体で実行されるように設計されていて、マシンにzshを使用する規則がある場合(たとえば、同じ基本的なAMI)およびあなたの仕事には、高度なファイルセレクターなどの拡張機能や http://www.rayninfo.co.uk/tips/zshtips.html のような明確なメリットがあります。

2
A B

述べたように、bashは多くのディストリビューションのデフォルトのインストールで一般的に利用可能です。 zshに依存しても、スクリプトは最大のユーザーベースに到達しません。

スクリプトを設計する前に回答する重要な質問は、「スクリプトが実行されるシェルがなぜ重要なのか」です。

異なるシェルは異なる構文を使用するか、他のシェルではサポートされていない可能性のある追加のシェル関数を提供します。 「一般的なLinuxエンドユーザーの世界」向けのスクリプトを作成するには、スクリプトが特定のシェル環境に依存する構文またはシェル関数を使用するかどうかを決定します。

たとえば、 bash Shell は、dash、Bourne Shell、または/bin/shが指しているものでサポートされていない特定の展開をサポートしますユーザーのシステム。

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

echo {1..10}/bin/shと比較して/bin/bashを使用して実行すると、非常に異なる出力が得られます。

同じことがzshにも当てはまります。これは、ほとんどのbash構文をサポートしますが、bashシェルではサポートされていない追加の拡張と構文を提供します。特定の例については、この shells を比較する表を参照してください。

#!/bin/sh -uで呼び出されたときに機能するスクリプトを使用することで、bashを超えて潜在的なユーザーベースを拡大できます。しかし、これは別の重要な質問を引き起こします:「移植性を高める代わりに何が犠牲になっていますか?

セキュリティ上の懸念、機能性、効率性など、スクリプトの優先事項であると感じる違いが、犠牲に値するかどうかを判断します。より多くの環境で機能するという理由だけで、既知のセキュリティ脆弱性を持つスクリプトを広範囲に使用したくない場合があります。

非常に多くのスクリプトがbash用に作成されているため、これらのスクリプトのサポートは、 コマンドシェル を比較する際の基準として使用されます。スクリプトがzshまたはシェル環境専用のその他の構文に依存している場合よりも多くの人がスクリプトを実行できます。

また、ユーザーがスクリプトを実行する方法を最終的に制御することはできないことに注意してください( 別のシェルでスクリプトをデバッグする場合にも便利です ):

シェルを使用してシェルスクリプト(「shスクリプト名」)を直接実行するのではなく(「./scriptname」)、シェルがシェルスクリプトの先頭にあるすべてのコメントをコメントとして扱うことに注意してください。特に、スクリプトの実行時に使用するインタープリターを指定するコメント(「#!/ bin/sh -u」)は無視され、そのインタープリターの横にリストされているすべてのオプションも無視されます。

したがって、これについてできる最善の方法は、スクリプトの移植性を高めることです。ただし、スクリプトの機能に大きな犠牲を払わなければ、スクリプトを移植できます。

Bashコーディング規約-Stack Overflow も表示される場合があります。

1
iyrin

ほぼ保証できる唯一のことは、/bin/sh。これは、実際に静的にリンクされたシェルである場合と、別のシェルへのリンクである場合があります。他のシェルは通常、それがshとして呼び出され、互換モードで実行されることを検出します。

最初の文のalmostに注意してください。

私がこれまで取り組んだすべてのUNIXライクなシステムにはそれがありました。それらの多くにもbashがインストールされていました(しかしすべてではありません。たとえば、一部のBSDにはデフォルトでインストールされていません。一部のLinuxディストリビューションには- [〜#〜] dash [〜#〜] 、代わりにDebian Almquistシェル。

保証できるのは、インストール手順です。 READMEファイルにzshが必要であることを示す行を追加できます。パッケージをビルドする場合は、zshを依存関係としてマークできます。autoconf/ automakeツールで確認できます。インストールスクリプトでzshが見つかったかどうかを確認できます(/ bin/shで始まり、zshを見つけてみてください。見つかった場合は続行してください。エラーが表示されない場合。例:「警告:ZSHがインストールされていません。インストール手順ファイルを読んでください! 」

私はいくつかのオプションを忘れたと確信しています。ただし、重要な点は次のとおりです。

  • 確認するまで何も保証できません。
  • / bin/shが存在すること、およびそれを使用していくつかのチェックを実行できることがほぼ保証されています。
1
Hennes

これは良い質問です。一般的に使用されるtcshスクリプトのライブラリがあります。ただし、tcshの評判を考えると、私はそれらを書き直す必要があります(それ以外の場合は正常に動作します)。答えは簡単だと思います。bashです。 GNU/Linuxにより、インストールベースが最も広くなっています。

0
Steve