Linux環境変数名で使用できる文字


143

Linux環境変数名で使用できる文字は何ですか?manページとWebをざっと検索すると、変数の操作方法に関する情報のみが生成され、許可されている名前は生成されませんでした。

のようなドットを含む定義済みの環境変数を必要とするJavaプログラムがありますcom.example.fancyproperty。Windowsではその変数を設定できますが、Linuxでは設定できませんでした(SuSEとUbuntuで試してみました)。その変数名は許可されていますか?


3
幸いにも、プログラムはJavaシステムプロパティ(-Dコマンドラインオプションで宣言)と同じように満足していることがわかりました。明らかに、プログラムは私に言わずに両方の変数セットを調べます。しかし、それでも、どの環境変数名が許可されているのか知りたいです。
クリスチャンセムラウ

@AleksandrDubinsky削除しました。これは似ていますが、別名の定義についてではない、正確に環境変数がstackoverflow.com/questions/24690640/...
ライム

1
Springを使用している場合、デフォルトのSystemEnvironmentPropertySourceもルックアップcom_example_fancypropertyCOM_EXAMPLE_FANCYPROPERTYます。
Aleksandr Dubinsky 2016

回答:


203

オープングループから:

これらの文字列の形式はname = valueです。名前には文字「=」を含めないでください。IEEE Std 1003.1-2001に準拠するシステム間で値を移植できるようにするには、値を移植可能な文字セットの文字で構成する必要があります(NULを除き、以下に示すとおり)。

したがって、名前には=とNUL以外の任意の文字を含めることができますが、

IEEE Std 1003.1-2001のシェルおよびユーティリティボリュームのユーティリティで使用される環境変数名は、大文字、数字、およびポータブル文字セットで定義された文字の '_'(アンダースコア)のみで構成され、数字で始まっていません。。他の文字は実装によって許可される場合があります。アプリケーションは、そのような名前の存在を許容するものとします。

したがって、名前は有効である可能性がありますが、シェルは文字、数字、およびアンダースコア以外をサポートしない場合があります。


8
チェックするだけ:2番目の引用は非規範的です:POSIXがユーティリティのために特別であると定義する変数が[a-zA-Z_][a-zA-Z0-9_]*(このフォームがより適切であることを暗示的に示唆している)ことだけを観察しますが、実際の仕様(引用1)=NUL
Ciro Santilli郝海东冠状病六四事件法轮功

3
また、「ポータブル文字セット」pubs.opengroup.org/onlinepubs/000095399/basedefs/…には、スペースや印刷できないものなどが含まれているので、それらを使用できるかどうかはわかりますか?
Ciro Santilli郝海东冠状病六四事件法轮功

3
これはまさに私が観察していることです。シェルは変数名の一部として特殊文字を好まない。ただし、1つのプログラムまたはスクリプト(javaやperlなど)が名前に特殊文字を使用して変数を初期化し、別の実行可能ファイル(子プロセス)を呼び出す場合、後者の実行可能ファイルは問題なくその変数にアクセスできます。
oᴉɹǝɥɔ

1
@checksum、シェルを含むPOSIX指定のツールにとって意味のある変数名に対して大文字が明示的に指定されています。少なくとも1つの小文字を含む名前は、アプリケーションで使用するために明示的に予約されています。したがって、ベストプラクティスは、アプリケーションの変数名に少なくとも1つの小文字を含めて、(シェル変数を設定すると、同じ名前の環境変数が上書きされるため)意図的に変数を上書きしないようにすることです。システム。pubs.opengroup.org/onlinepubs/9699919799/basedefs/…を
Charles Duffy

2
@CiroSantilli烏竜事件2016六四事件法轮功、それらを環境変数で使用できます。これらをシェル変数で使用することはできません。また、これらの環境変数は、シェルからアクセスできることが保証されていません。
Charles Duffy

37

IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Shell and Tools標準のシェルセクションの POSIX標準は、変数名の字句規則を定義していませんが、ソースをざっと 見ると、次のようなものが使用されていることがわかります。

[a-zA-Z_]+[a-zA-Z0-9_]*

(編集:2番目の文字クラスに不足していたアンダースコアを追加。)

簡単なメモ、一部のシェルは正規表現で+をサポートしていないため、より移植性の高い正規表現は次のようになります。

[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}


4
ありがとう、エイデン。私は角括弧の2番目のセットにアンダースコアがないと思います:おそらく読むべきです:[a-zA-Z_][a-zA-Z0-9_]* bash-4.1への参照が少し漠然としている(コードの616'000行)を見つける私のような人のために、ここにいくつかのヒントがあります関連するコード行を見つけます:subst.c: param_expand(), in the default case-> general.h:/ *正当なシェル識別子の構成要素を正確に定義します。* / #define legal_variable_starter(c)(ISALPHA(c)||(c == ' '))#define legal_variable_char(c)(ISALNUM(c)|| c == ' ')
Chris

3
最初の文字クラスでは、そのプラスは必要ありません。
クレイジー

2
。私は+を維持するつもりだので、私はソースから正規表現を取ったものの、真@scravy
エイデン・ベル

4
POSIXは以下を定義します:3.231 Name a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit

シェルセクションにはありませんが、環境変数の命名規則を含むPOSIX標準は絶対にあります(実際には、シェルで使用するために予約されている名前についても説明しています)。pubs.opengroup.org/onlinepubs/9699919799/basedefs/…を
Charles Duffy

12

私の簡単なテストでは、Cの変数名と基本的に同じ規則に従っていることがわかりました。

  1. az、AZ、_0-9
  2. 数字で始めることはできません

したがって、これは.それらの内部を除外します。不正な変数名はでクレジットされunknown commandます。

これは主にBASH互換であるZSHでテストされました。


6

「許可」の意味によって異なります。

nonceでWindowsを無視する:

環境は、プログラムのメイン関数に渡される文字列の配列です。execve(2)を読むと、ヌル終了以外のこれらの文字列に対する要件や制限はありません。

慣例により、各文字列はNAME = valueで構成されます。引用規則はないため、この規則では名前に「=」を含めることはできません。

通常の人間は、これらの文字列をシェルで議論することによって設定します。各シェルには、有効な変数NAMEが何であるかについて独自のアイデアがあるため、瞬間的なシェルのmanページを読んで、それが何を考えているかを確認する必要があります。

一般に、com.baseball.spit = fleaghのようなものはJavaシステムプロパティであり、Javaプログラムが環境にフォールバックする用意があるかどうかに関係なく、-Dで指定することをお勧めします。


変数は環境変数として設定しようとするのではなく、Javaシステムプロパティのようにフォーマットされているという結論に以前に達したはずです。
クリスチャンセムラウ


4

はい、できます。

コマンドを使用してexecenvこのシーンを実装します。

Dockerのテストフィクスチャ

docker run -it --rm alpine:3.10

コンテナでコマンドを実行:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}

環境変数を確認します。

HOSTNAME=bd0bccfdc53b
SHLVL=2
HOME=/root
spring.application_name=happy-variable-name
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

ps auxPIDが変更されていないことを確認するために使用します

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux

python環境変数を確認するために使用します

apk add python
python -c 'import os; print(os.environ["spring.application_name"])'

出力はhappy-variable-nameです。

何が起きましたか?

  1. シェル呼び出し組み込みexec
  2. シェル組み込みexec呼び出しsyscall.execは、現在のシェルを置き換えるプロセス 'env'を作成します
  3. envプロセスはsyscall.execvp createプロセス '/ bin / sh'を呼び出して、envプロセスを置き換えます

別の方法

  • Dockerイメージ

dockerを使用している場合は、Dockerfileで変数を設定できます

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Kubernetes configmap

kubernetesを使用している場合は、ConfigMapで変数を設定できます

test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-config
data:
  "xx.ff-bar": "1234"

---
apiVersion: v1
kind: Pod
metadata:
  name: foobar
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: foo-config
  restartPolicy: Never

ポッドをデプロイする kubectl apply -f test.yaml

kubectl logs foobar出力を確認します。

xx.ff-bar=1234

ConfigMapは「-」、「_」、または「。」を許可します


0

ほとんどのシェルでは(他の回答で述べたように)環境変数を設定できませんが、必要に応じて、非標準の環境変数を使用して他のプログラムを実行できます。 env(1)

たとえば、すべての環境を消去しStrange.Env:Varてvalue fooに設定し、それを出力するperlプログラムを実行します。

env -i Strange.Env:Var=foo perl -MData::Dumper -E 'say Dumper(\%ENV)'

印刷します

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.