きれいな環境でスクリプトを起動するには?

きれいな環境でスクリプトを起動するには?

以下を試しましたが、うまくいかないようです。

$ cat script.sh
#!/bin/env -i /bin/sh

/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.

答え1

-i /bin/shこれがうまくいかない理由は、単一のパラメータとして扱われるからですenv。通常、これは2つのパラメータになります。-iこれは/bin/shshebangの制限です。周りに方法はありません。


ただし、他の方法でこれを行うこともできます。

同様の操作を行わずにスクリプト自体でこれを実行するには、env -i script.shスクリプトを独自に再実行させることができます。

#!/bin/sh
[ -z "$CLEANED" ] && exec /bin/env -i CLEANED=1 /bin/sh "$0" "$@"

CLEANED環境変数が設定されていない場合、スクリプトは自動的に再実行されます。次に、再実行時にループに陥らないように変数を設定します。

答え2

次のコマンドを使用してスクリプトを実行しますenv -i

env -i script.sh

通常と同じスクリプト:

#!/bin/sh
# ... your code here

実行時にこれを明示的に指定せずにクリーンな環境で実行したい場合。 Eduardo Ivanecはいくつかのアイデアを提示します。この回答exec、環境がきれいでない場合(例:$ HOME定義)、スクリプトを再帰的に呼び出すことができます。

[ "$HOME" != "" ] && exec -c $0

答え3

Bashを使用すると、次のことができます。

#!/usr/bin/bash

set -e
set -u

[ -v HOME ] && exec -c "$0" "$@"

# continue with the rest of the script
# e.g. print the cleaned environment:
export

set -eコマンドはset -u 必ずしも必要ではありませんが、このアプローチが設定されていない変数(たとえば[ "$HOME" != "" ])にアクセスすることに依存せず、設定と互換性があることを示すために含まれていますset -e

HOMEbashは非対話型モードでスクリプトを実行するため、テスト変数は安全でなければなりません。つまり~/.bashrc、(環境変数を設定できる)などの構成ファイルは起動中に選択されません。

出力例:

declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"

答え4

ほとんどの答えはLinux 2パラメータshebang制限(インタプリタ+単一パラメータ)を指していますが、それを行うことはできないと言うのは間違っています。単一のパラメータで役に立つタスクを実行できるインタプリタに変更するだけです。

#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here

それがすることは(安価に)整理し、引数を正しく引用して呼び出すperl一行スクリプト()を使って呼び出すことです。必要に応じてより多くのロジックを追加できます(Linuxでは文字数が制限されているため、それほど多くはありませんが、おそらく128個です)。バリエーションがあります。使用-e%ENVenv -iexec /bin/shperlBINPRM_BUF_SIZEawk この回答ではこの問題についてShebangの複数のパラメータ

残念ながら、これはLinux固有のものであり、複数のshebangパラメータを受け入れるシステムでは機能しません。

perlこの文字列を単一の引数として扱うので、引用しない上記はコマンドラインで通常行っていることと同じですperl -e ...(引用符を追加すると、その内容は保存され、Perlは無駄な定数について不平を言う警告とともにリテラル文字列のみを表示します)。

また、この方法を使用すると動作が若干変更されることに注意してください。@ARGV通常、パラメータのみが含まれ、$0スクリプト名も含まれますが、このshebangを使用すると、パラメータをより簡単に$ARGV[0]生成できるスクリプト名が含まれます。exec()$0-e

-cAT&Tがksh93行ったように(追加のパラメータなしで)コマンドラインを「再処理」するインタプリタを使用してこの問題を解決することもできます。

#!/bin/ksh /usr/bin/env -i /bin/sh

ksh今はあまり一般的ではないかもしれませんが;-)

bash同様の機能で--wordexpしかし、動作するバージョンでは「文書化されておらず」、文書化されたバージョンではコンパイル時に有効になりません。 :-/ 2つの引数が必要なので、この目的にも使用できません...)

また、実際に@Patrickと@maxschlepzigの答えが変形しました。

#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here

新しい変数ではなく特別な_変数を使用し、完全に「bash」に設定されていない場合は、スクリプトをusingexecに置き換えて「bash」のみを-a作成し、usingを使用して環境を消去します。ARGV[0]$_-c

または、スクリプトの冒頭で環境をクリーンアップできる場合(bashのみ):

#!/bin/sh
unset $(compgen -e)
# your script here

(完了ヘルパー)を使用してエクスポートしたcompgenすべての環境変数の名前を一覧表示し、unset一度にすべて保存します。

また、見ることができますShebangの複数のパラメータShebangの動作に関連する一般的な問題の詳細。

関連情報