シェルスクリプトを配布する適切な方法


8

シェルの動作が変更可能でset予測できない場合、シェルスクリプトを配布する最も適切な方法は何ですか?

たとえば、rm *.txt実行された環境では期待どおりに実行されませんset -f。がどのrm *.txt環境でも現在のディレクトリにあるすべてのテキストファイルを削除することを確認するにはどうすればよいですか?

一般的に配布する前に、シェルスクリプトが期待どおりに実行されることを確認するにはどうすればよいですか?


shell_state=$(set +o) ... スクリプト ...eval "$shell_state"
mikeserv '25 / 07/25

スクリプト自体の上部でこれらのコマンドを実行#!するか、を変更して必要なシェルオプションを指定できます。
HalosGhost 14

回答:


6

シェルスクリプトは通常、バイナリ、Pythonスクリプト、Perlスクリプト、その他の種類のスクリプトなど、その他の種類の実行可能ファイルと同じであるかのように扱われます。それらは、シェルを介してそれらを実行するようにカーネルに指示する上部にシバンがあります。これらは、他のコマンドと同じ方法で呼び出されることが期待されています。

そのため、スクリプトが呼び出されるたびに新しいシェルが開始さset -fれ、起動中のシェルやシステム内の他のシェルインスタンスに存在する設定などは関係ありません。

もちろん、ユーザーがスクリプトを実行する代わりに、たとえば次のようにソースを入手することは可能です。

. /path/to/your/script

または、次のようなデフォルト以外の設定を持つシェルで実行するには:

sh -f /path/to/your/script

しかし、これらは通常の方法やスクリプトの呼び出しとは見なされず、それを行うユーザーは、結果として得られるものをすべて期待する必要があります。

実行されるのではなく、供給されることを目的とするいくつかのスクリプトがあることに注意してください。それらの目的は、ソースシェルの環境に反映する必要があるcwdの変更や環境変数の設定などにあるためですが、これらは少数派ですそしてそれは通常、合意されたプロトコルの一部として行われます。これらのファイルは、独立したスクリプトとしてではなく、ソースとして提供されることが期待されているシステムにとって「プラグイン」のようなものと考えることができます。たとえば、/etc/rc*.d名前がで終わるファイルは、.sh実行されずに起動スクリプトサブシステムによって供給されます。このような名前のファイルを/etc/rc*.dそしてそれが行われるとき、それは故意に行われます。この方法で実行するのではなく、ソースを提供することを目的としたファイルの命名規則は、他の場所でも適用されますが、普遍的ではありません。

この方法で取得することを目的としたファイルは、シェルの動作に影響を与える可能性のある呼び出し元の環境に存在する可能性のある設定に注意する必要がありますが、合意されたプロトコルは予測可能な実行環境を約束するのが理想的です。


1
zshオプションには、ローカルコンテキスト(emulate -L zsh)の既知のセットにオプションを復元できる機能があり、zshに同梱され、zshコードとして記述されたすべての拡張機能で広く使用されています。のようないくつかのオプションを設定した場合、bash補完システムが惨めに失敗する方法を参照してくださいfailglob
ステファンChazelas

一部のシェルは、スクリプトを解釈するために呼び出された場合でも、カスタマイズファイルを読み取ります。そのため、たとえば、#! /bin/csh -f代わりに通常使用#! /bin/cshします。
ステファンChazelas

@StéphaneChazelasハハ、はい、確かに。もちろん、それがcshの使用が悪い考えの理由の一部ですよね?:-)しかし、zshにもの形式であると思いzshenvます。zshenvそのため、何を入れたか注意してください。
Celada 14

ちなみに、@StéphaneChazelas、私が知らないこと(emulate -Lこの場合)を私の回答の1つにコメントして教えるのは初めてではなく、感謝しています。
Celada 14

まあ、~/.zshenv(あなたがあなたの名前で呼び出されたすべてのzsh(インタラクティブかどうか)の設定(通常はenv vars)を強制し、他のいくつかの非zsh問題を回避する以外は一般的に使用されない場所)は~/.zshrc(インタラクティブカスタマイズシェル)、それはバグではなく機能です。(zsh -fを使用できます)バグは、非対話型bashシェルが~/.bashrc(sshを介して、それを防ぐためにコードを追加する必要があるなど)読み取り、または対話型bash(ログインシェル)が読み取らない場合です(そして、あなたは~/.bash_profileそれを回避するためにあなたの中にコードを追加する必要があります)。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.