私は以下の関連質問を見ました。これしかし、彼らは私の質問に対する正確な答えを提供していません
私の実験でもこの回答、printenv
ほぼenv
同じシステム変数のセットを表示します。
変数を次に設定すると
/etc/bash.bashrc (システム全体のシステム変数でなければなりません)
SYSTEM_ENVI=1000
~/.bashrc(ユーザー固有のシステム変数に使用する必要があります)
USER_ENVI=10
/etc/environment が適用されるようにログアウトしてログインすることもありました。次のシナリオが発生します。
$echo $SYSTEM_ENVI
//outputs 1000
$echo $USER_ENVI
//outputs 10
$CURR_ENVI=1
$env | grep USER_ENVI
//nothing shows up, the same if I grepped SYSTEM_ENVI or CURR_ENVI
$set | grep USER_ENVI
//shows up USER_ENVI assignment, the same if I grepped SYSTEM_ENVI or CURR_ENVI
私の質問は次のとおりです
printenv
どのシステム変数が実行/印刷されますかenv
?- 代わりに、
set
アクセス可能なすべての変数(システム変数とローカル変数)を使用する必要がありますか?printenv
env
繰り返さない理由
私の場合、この質問と示された答えは次の事実を理解するのに役立ちました。
- シェル変数は環境変数ではありません
- 仕事/etc/bash.bashrcまたは~/.bashrc環境変数を作成するのではなく、対話型の非ログインシェルプロセスにこれらの変数を作成して初期化するように指示します。シェル変数スタートアップについて。
私の質問は必ずしも以下に関連しているとは思わない。これしかし、この質問に示されている回答を読むことは、この記事に記載されている回答ほど満足できませんでした。
答え1
env
そして、printenv
それを実行するコマンドによって提供される環境文字列のリスト(環境変数定義を含むことを意図しています)を印刷します。呼び出し側は最終的に次のことを行います。
execve("/usr/bin/env", argv, envp);
argv
ここで、envp
とは2つの文字列のリストであるシステムコールです。
env
/printenv
の文字列のリストだけを1行envp
に1つずつ印刷します。
慣例により、 の文字列はenvp
形式になっていますが、var=value
必ずしもそうする必要はなく(execve()
これを強制する実装についてはわかりません)、ほとんどのenv
実装ではprintenv
文字列をいつ表示するか気にしません。
呼び出し元がPOSIXシェルの場合は、表示されたシェルenvp
に渡された変数のリストに含まれます。env
出口(ユーザーがexport
/を呼び出しtypeset -x
たとき、または変数がシェルの起動時に受信した環境にすでに存在するため)。
起動時にシェルが受信した一部の環境変数をシェル変数にマップできない場合envp
、または受信した文字列に=
文字が含まれていない場合、シェルの実装によっては、これらの文字列は影響を受けずに渡されます。それ以外の場合、シェルはその文字列をGoから削除します。またはそれらのいくつか。
たとえばbash
、GNUを使用すると、任意env
の変数名のリストを渡すことができます(env
ただし、任意のenvp文字列は許可されず、aを含める必要があり、=
使用された文字列は1で始まる変数をsetenv()
渡すことはできません=
)。
$ env -i '=foo' '1=x' '+=y' bash -c printenv
+=y
1=x
[...]
(名前が空の変数は削除されますが、他の変数は削除されません。)
また、シェルがenvp
同じ変数名に対して複数の文字列を受け取ると、シェルに応じてすべてが渡されます。最初の文字列のみが渡され、最後の文字列のみが渡されます。
set
エクスポートを表示するかどうかに関係なく、配列/ハッシュ型をサポートするシェルのビスカラー変数を含む、POSIXシェルのシェル変数のリストを印刷します。
POSIXシェルでは、それを使用してエクスポート用にマークされたexport -p
変数を一覧表示することもできます。env
/とは異なり、エクスポートされたとしてマークさprintenv
れているがまだ値が割り当てられていない変数も一覧表示されます。
あるいはksh
、などのKorn様シェルでを使用して、変数属性を含む追加情報を取得し、型別に変数を一覧表示することもできます(配列変数のリストなど)。zsh
bash
typeset
typeset -a
ここでは、USER_ENVI=10
次を追加して、~/.bashrc
シェルの対話型非ログイン呼び出しをbash
構成できます。USER_ENVI
シェル起動時の変数。使用していないため、export
変数はまだシェル変数であるため(起動時に環境にない限りbash
)、次のように使用されません。環境このシェルで実行されるコマンドの変数です。
/etc/environment
Ubuntu 16.04のプラグイン認証モジュールからデフォルトで読み取られますpam_env.so
。ログインアプリケーション(たとえばlogin
、、、、、sshd
)はlightdm
これらのファイルを読み込みます(そのファイルを使用しpam_env.so
て転送するように設定されている場合)。/etc/pam.d
環境変数(ここではシェル変数とは関係ありません)は、認証後にユーザー名で実行されるコマンド(たとえば、login
/のログインシェルsshd
または...のグラフィカルセッションマネージャlightdm
)です。
環境はデフォルトで継承されるため、セッションマネージャがターミナルエミュレータを実行すると(ログインシェルが実行される)、これらの環境変数は各ステップで渡され、シェルは拡張可能なシェル変数にマップされます。のようなコマンドと一致しますecho "$VAR"
。
pam_env
envファイルは/etc/environment
シェルスクリプトのように見えますが、pam_env
それを解析するためにシェルは呼び出されず、シェル構文のサブセットだけが理解され、名前が1つ以上のASCII英数字または下線で構成される変数の定義のみを受け入れます。123
有効なPOSIXシェル変数名でなくても、変数を定義できます。
1. 任意の環境文字列のリストを渡すには、execve()
次のように直接呼び出すこともできます。
perl -e 'require "syscall.ph";
$cmd = "/bin/zsh";
$args = pack("p*x[p]", "sh", "-c", "printenv");
$env = pack("p*x[p]", "a=b", "a=c", "", "+=+", "=foo", "bar");
syscall(SYS_execve(), $cmd, $args, $env)'
zsh
代わりにここでテストしてください。bash
答え2
以下を実行してください。
USER_ENVI=10
変数を設定していますが、環境変数は設定しません。これを行うには、次のものが必要です。
export USER_ENVI=10
または
USER_ENVI=10; export USER_ENVI
それは合理的です。これはあなたには効果がありません:
$ env | grep SYSTEM_ENVI
setという環境変数はありませんSYSTEM_ENVI
。/etc/environment
あなたはコンテンツを公開しておらず、使用しないように見えるので、これについては申し上げません。
env
印刷する内容を正確に印刷しますprintenv
(オプションなし)。
答え:
envとprintenvはどちらも、実際に設定されたものとまったく同じ変数のリストを報告します。投資ファンドコマンドの後にオプションや変数のリストはありません。
set(オプションなし)を使用すると、すべての変数セットを表示できます。これはあなたを意味しません〜しなければならないそれを書いてください。それはあなたがリストしたいものに依存します。環境変数のリストを作成するだけで完全に有効で正確です。