質問: なぜノードまたはpython readコマンドで設定された数値変数にアクセスできないのですか? 観察:数値のみの値を含むオペレーティングシステムの「読み取り」ユーティリティを使用して設定された環境変数は、pythonのos.environ[]構造またはノードのprocess.env構造ではアクセスできませんが、bashではアクセスできます。予想される動作は、作成方法に関係なく、すべての環境変数にアプリケーションから等しくアクセスできることです。export n=12345構文を使用してbashを使用して設定した場合、同じ変数にアクセスできます。 readコマンドを使用して作成された変数は、他の変数と同じように作成されていないため、ノード/ pythonのこれらの変数の解析ロジックが妨げられているようです。以下のechoステートメントに示すように、node/pythonからアクセスできない同じ変数には、bashコマンドラインから簡単にアクセスできます。readコマンドは、キー入力に基づいて環境変数を設定します。これは、シークレットの.bash_historyレコードを残さずに、シークレットを変数に入力する便利な方法です。複製: osx 10.14.6( "mojave")python 2.7、python 3.6、ノード10.16.3 linux カーネル3.10centos 64ビット、python2.7.5 サンプル:readを使用して、lという名前の環境変数の値を入力するようにユーザーに促します。~ $ read l 12345 ~ $ python2 python 2.7.16 (default, apr 12 2019, 15:32:40) [gcc 4.2.1 compatible apple llvm 10.0.1 (clang-1001.0.46.3)] on darwin type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.environ["l"] traceback (most recent call last): file "<stdin>", line 1, in <module> file "/usr/local/cellar/python@2/2.7.16/frameworks/python.framework/versions/2.7/lib/python2.7/userdict.py", line 40, in __getitem__ raise keyerror(key) keyerror: 'l' >>> ~ $ python3 python 3.7.3 (default, mar 27 2019, 09:23:15) [clang 10.0.1 (clang-1001.0.46.3)] on darwin type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.environ["l"] traceback (most recent call last): file "<stdin>", line 1, in <module> file "/usr/local/cellar/python/3.7.3/frameworks/python.framework/versions/3.7/lib/python3.7/os.py", line 678, in __getitem__ raise keyerror(key) from none keyerror: 'l' ~ $ echo $l 12345 興味深いことに、数値変数が読み取りコマンド以外の方法で設定されている場合、それらはpythonおよびノードでアクセス可能です。>>> os.environ["histsize"] '12345678'
回答: シェルでは、環境変数を操作していません– shell変数を操作しています。シェルは、初期環境のcopyで始まりますが、独自の変数名前空間を維持します。シェル変数は環境にのみコピーされます「エクスポート」フラグがある場合。真新しい変数はデフォルトではエクスポートされません–問題ではありませんhowそれらが生成された場合でも、exportコマンドを使用して正しいフラグを設定する必要があります。$ read l 12345↵ $ export l $ python -c 'import os; print("l is", os.environ["l"])' l is 12345 これはreadに固有のものではないことに再度注意してください。 exportを使用せずに変数を設定しただけでも、同じ失敗が見られます。$ n=abcdef $ python -c 'import os; print("n is", os.environ["n"])' traceback (most recent call last): file "<string>", line 1, in <module> file "/usr/lib/python3.7/os.py", line 678, in __getitem__ raise keyerror(key) from none keyerror: 'n' bashでは、declare -p varを使用して、その変数に現在環境へのエクスポートのフラグが設定されているかどうかを確認できます(フラグが設定されている場合は、-xオプションがあります)。$ declare -p l n declare -x l="12345" # the one that was exported in example 1 declare -- n="abcdef" # the one that deliberately wasn't, in example 2 (出力は入力として有効です。たとえば、実際にrun declare -xの場合、これはexportと同等です。)雑記: 環境には文字列値のみを含めることができますが、シェル変数はそれだけに限定されません。たとえば、ほとんどのシェルには配列/リストとdictがあります。 シェルには、エクスポートしない変数が含まれていることがよくありますwant。たとえば、$ linesと$ columnsはシェル自体の中で動的ですが、それらをエクスポートすると、プログラムに静的な値しか表示されないため、これはwould問題を引き起こします。