私はシェルスクリプトの詳細を学び始めたばかりで、常にスクリプトをファイルに入れてchmod +x
とマークし、次に/path/to/script.sh
を実行して、デフォルトのインタープリターにデフォルトの方法を使用させていますそれは私がzshであると私が想定したもので、それは私が自分のシェルに使用したものだからです。どうやら、zshプロンプトからスクリプトを実行したとしても、スクリプトにzsh固有のものを入れ始めたので、/bin/sh
を実行しないと失敗するため、デフォルトではzsh /path/to/script.sh
だけのようです。
ポイントを得るために、ここに私の質問があります:
#!/path/to/Shell
)がない場合、どのシェルがスクリプトを実行しますか? /bin/sh
と思いますが、確認できません。Zshを使用しようとし、zshが使用できない場合にbashにフォールバックするスクリプトを作成することは可能ですか?以下のように2つのシバン行を入れてみましたが、zshのないマシンで試した場合、bad interpreter: /bin/zsh: no such file or directory
でエラーになります。
#!/bin/zsh
#!/bin/bash
最初にシバン行(#!/ path/to/Shell)がない場合、どのシェルがスクリプトを実行しますか?/bin/shを想定していますが、確認できません。
カーネルはそのようなスクリプトの実行を拒否し、ENOEXECを返すため、正確な動作は、そのようなスクリプトfromを実行するプログラムによって異なります。
glibcでは、関数execv()
またはexecve()
はENOEXECを返すだけです。ただし、execvp()
はこのエラーコードを非表示にし、/ bin/shを自動的に呼び出します。 (これは exec(3p) に記載されています。)
任意のプラットフォームで実行されるシェルスクリプトを作成するという観点から、「ベストプラクティス」と見なされるものは何ですか? (OK、これは一種の自由回答です)
sh
とPOSIX定義の機能のみに固執するか、またはbash(広く利用可能)をフルにして、配布する場合は要件に記載してください。
(今考えてみると、Perl –またはおそらくPython –は、構文が優れていることは言うまでもなく、さらに移植性が高いでしょう。)
常にシバンラインを追加します。 bashまたはzshを使用する場合は、シェルのパスをハードコーディングする代わりに#!/usr/bin/env bash
を使用します。 (ただし、POSIXシェルは/bin/sh
にあることが保証されているため、その場合はenv
をスキップしてください。)
(残念ながら、/bin/sh
でさえ常に同じであるとは限りません。GNUautoconfプログラムは 多くの異なる癖 。)
Zshを使用しようとし、zshが使用できない場合にbashにフォールバックするスクリプトを作成することは可能ですか?以下のように2つのシバン行を入れてみましたが、悪いインタープリターでエラーが発生しました:/ bin/zsh:そのようなファイルやディレクトリはありませんマシンで試した場合zshなし。
シバンラインは1つしか存在できません。改行文字の後のすべてはカーネルによっても読み取られず、シェルによってコメントとして扱われます。
#!/bin/sh
として実行され、使用可能なシェルを確認し、結果に応じてexec zsh "$0" "$@"
またはexec bash "$0" "$@"
を実行するスクリプトを作成することは可能です。 。ただし、bashとzshで使用される構文はさまざまな場所で非常に異なるため、自分の正気のためにこれを行うことはお勧めしません。
1)実行している現在のシェル。
2)同じシェルタイプ(bash/dash/ash/csh /どのフレーバーでも)を使用し、「サポートされているプラットフォーム」がデフォルトで使用するシェルをインストールしていることを確認します。また、システムで一般的に使用可能なコマンドを使用してみてください。マシン固有のオプションは避けてください。
3)interpreter directive
には実際には「if-then-else」ロジックはありません。サポートするすべてのシステムに存在する必要があるシェルを指定する必要があります...つまり、スクリプトがすべてのシェルでかなり汎用的である限り、#!/bin/bash
または汎用の#!/bin/sh
を指定します。