Linuxで環境変数とシェル変数を読み取って設定する方法
序章
シェルセッションを介してサーバーと対話する場合、シェルの動作とリソースへのアクセスを決定するためにシェルがコンパイルする多くの情報があります。 これらの設定の一部は構成設定に含まれ、その他はユーザー入力によって決定されます。
シェルがこれらすべての設定と詳細を追跡する1つの方法は、環境と呼ばれるシェルが維持する領域を介することです。 環境は、システムプロパティを定義する変数を含むセッションを開始するたびにシェルが構築する領域です。
このガイドでは、環境と対話し、環境変数とシェル変数を対話形式で構成ファイルを介して読み取りまたは設定する方法について説明します。
If you’d like to follow along using your local system or a remote server, open a terminal and run the commands from this tutorial there.
環境と環境変数のしくみ
シェルセッションが生成されるたびに、シェルプロセスとその子プロセスで利用できるはずの情報を収集してコンパイルするプロセスが実行されます。 これらの設定のデータは、システム上のさまざまなファイルや設定から取得されます。
この環境は、シェルプロセスが設定を取得または設定し、それらを子プロセスに渡すための媒体を提供します。
環境は、キーと値のペアを表す文字列として実装されます。 複数の値が渡される場合、それらは通常コロンで区切られます(:
)文字。 各ペアは通常、次のようになります。
KEY=value1:value2:...
値に重要な空白が含まれている場合は、引用符が使用されます。
KEY="value with spaces"
これらのシナリオのキーは変数です。 それらは、環境変数またはシェル変数の2つのタイプのいずれかになります。
環境変数は、現在のシェルに対して定義され、子シェルまたはプロセスによって継承される変数です。 環境変数は、シェルから生成されるプロセスに情報を渡すために使用されます。
シェル変数は、それらが設定または定義されたシェル内に排他的に含まれる変数です。 これらは、現在の作業ディレクトリなどの一時的なデータを追跡するためによく使用されます。
慣例により、これらのタイプの変数は通常、すべて大文字を使用して定義されます。 これは、ユーザーが他のコンテキスト内の環境変数を区別するのに役立ちます。
シェルと環境変数の印刷
各シェルセッションは、独自のシェルと環境変数を追跡します。 これらにはいくつかの異なる方法でアクセスできます。
を使用して、すべての環境変数のリストを表示できます。 env
また printenv
コマンド。 デフォルトの状態では、まったく同じように機能するはずです。
- printenv
シェル環境には、次の出力とは異なる値で設定された変数が多かれ少なかれある場合があります。
OutputSHELL=/bin/bash
TERM=xterm
USER=demouser
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:...
MAIL=/var/mail/demouser
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
PWD=/home/demouser
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/demouser
LOGNAME=demouser
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/printenv
これは、両方の出力のかなり典型的なものです printenv
と env
. 2つのコマンドの違いは、より具体的な機能でのみ明らかです。 たとえば、 printenv
、個々の変数の値を要求できます。
- printenv PATH
Output/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
一方で、 env
次のようなコマンドに一連の変数定義を渡すことにより、プログラムが実行される環境を変更できます。
- env VAR1="value" command_to_run command_options
上で学習したように、子プロセスは通常、親プロセスの環境変数を継承するため、これにより、値をオーバーライドしたり、子の変数を追加したりすることができます。
あなたが私たちの出力から見ることができるように printenv
コマンドでは、入力なしでシステムファイルとプロセスを介して設定された環境変数がかなりあります。
これらは環境変数を示していますが、シェル変数はどのように見えますか?
The set
これにはコマンドを使用できます。 入力すると set
追加のパラメーターなしで、すべてのシェル変数、環境変数、ローカル変数、およびシェル関数のリストを取得します。
- set
OutputBASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
. . .
これは通常、膨大なリストです。 出力量をより簡単に処理するために、おそらくそれをポケットベルプログラムにパイプする必要があります。
- set | less
私たちが受け取る追加情報の量は少し圧倒的です。 たとえば、定義されているすべてのbash関数を知る必要はおそらくありません。
次のように指定することで、出力をクリーンアップできます。 set
シェル関数を出力しないPOSIXモードで動作する必要があります。 これをサブシェルで実行して、現在の環境を変更しないようにすることができます。
- (set -o posix; set)
これにより、定義されているすべての環境変数とシェル変数が一覧表示されます。
この出力をの出力と比較することを試みることができます env
また printenv
シェル変数のみのリストを取得しようとするコマンドですが、これらのコマンドが情報を出力する方法が異なるため、これは不完全です。
- comm -23 <(set -o posix; set | sort) <(env | sort)
これには、いくつかの環境変数が含まれている可能性があります。 set
コマンドは引用符で囲まれた値を出力しますが、 printenv
と env
コマンドは文字列の値を引用しません。
これにより、セッションで設定されている環境変数とシェル変数についての良いアイデアが得られるはずです。
これらの変数は、あらゆる種類のものに使用されます。 これらは、ファイルに変更を書き込むことなく、プロセス間のセッションに永続的な値を設定する別の方法を提供します。
一般的な環境変数とシェル変数
一部の環境変数とシェル変数は非常に便利で、かなり頻繁に参照されます。 遭遇する一般的な環境変数は次のとおりです。
SHELL
:これは、入力したコマンドを解釈するシェルについて説明しています。 ほとんどの場合、これはデフォルトでbashになりますが、他のオプションが必要な場合は、他の値を設定できます。TERM
:これは、シェルの実行時にエミュレートする端末のタイプを指定します。 さまざまな動作要件に応じて、さまざまなハードウェア端末をエミュレートできます。 ただし、通常はこれについて心配する必要はありません。USER
:現在ログインしているユーザー。PWD
:現在の作業ディレクトリ。OLDPWD
:前の作業ディレクトリ。 これは、実行して前のディレクトリに戻すためにシェルによって保持されますcd -
.LS_COLORS
:これは、オプションで色付きの出力をに追加するために使用されるカラーコードを定義しますls
指図。 これは、さまざまなファイルタイプを区別し、ユーザーに一目でより多くの情報を提供するために使用されます。MAIL
:現在のユーザーのメールボックスへのパス。PATH
:コマンドを探すときにシステムがチェックするディレクトリのリスト。 ユーザーがコマンドを入力すると、システムはこの順序で実行可能ファイルのディレクトリをチェックします。LANG
:文字エンコードを含む、現在の言語とローカリゼーション設定。HOME
:現在のユーザーのホームディレクトリ。_
:以前に実行された最新のコマンド。
これらの環境変数に加えて、よく目にするシェル変数は次のとおりです。
BASHOPTS
:bashの実行時に使用されたオプションのリスト。 これは、シェル環境が希望どおりに動作するかどうかを確認するのに役立ちます。BASH_VERSION
:人間が読める形式で実行されているbashのバージョン。BASH_VERSINFO
:機械可読出力のbashのバージョン。COLUMNS
:画面に出力を描画するために使用されている幅の列の数。DIRSTACK
:で使用可能なディレクトリのスタックpushd
とpopd
コマンド。HISTFILESIZE
:ファイルに保存されているコマンド履歴の行数。HISTSIZE
:メモリに許可されているコマンド履歴の行数。HOSTNAME
:この時点でのコンピューターのホスト名。IFS
:コマンドラインで入力を分離するための内部フィールドセパレータ。 デフォルトでは、これはスペースです。PS1
:プライマリコマンドプロンプトの定義。 これは、シェルセッションを開始したときにプロンプトがどのように表示されるかを定義するために使用されます。 ThePS2
コマンドが複数行にまたがる場合のセカンダリプロンプトを宣言するために使用されます。SHELLOPTS
:で設定できるシェルオプションset
オプション。UID
:現在のユーザーのUID。
シェルと環境変数の設定
シェル変数と環境変数の違いをよりよく理解し、これらの変数を設定するための構文を紹介するために、簡単なデモンストレーションを行います。
シェル変数の作成
まず、現在のセッション内でシェル変数を定義します。 これは簡単に実行できます。 名前と値を指定するだけです。 変数名のすべての大文字を保持するという規則に従い、単純な文字列に設定します。
- TEST_VAR='Hello World!'
ここでは、変数の値にスペースが含まれているため、引用符を使用しました。 さらに、感嘆符はbashシェルの特殊文字であり、エスケープまたは一重引用符に入れられない場合、通常はbash履歴に展開されるため、一重引用符を使用しました。
これでシェル変数ができました。 この変数は現在のセッションで使用できますが、子プロセスには渡されません。
これは、内の新しい変数をgrepすることで確認できます。 set
出力:
- set | grep TEST_VAR
OutputTEST_VAR='Hello World!'
同じことを試してみると、これが環境変数ではないことを確認できます。 printenv
:
- printenv | grep TEST_VAR
出力は返されません。
これを機会として、シェルまたは環境変数の値にアクセスする方法を示しましょう。
- echo $TEST_VAR
OutputHello World!
ご覧のとおり、変数の値の前に $
サイン。 シェルはこれを、これに遭遇したときに変数の値を置き換える必要があることを意味します。
これでシェル変数ができました。 子プロセスに渡されるべきではありません。 現在のシェル内からnew bashシェルを生成して、次のことを示すことができます。
- bash
- echo $TEST_VAR
入力すると bash
子シェルを生成してから、変数の内容にアクセスしようとすると、何も返されません。 これは私たちが期待したことです。
次のように入力して、元のシェルに戻ります exit
:
- exit
環境変数の作成
それでは、シェル変数を環境変数に変えましょう。 これは、変数をエクスポートすることで実行できます。 そのためのコマンドには、適切な名前が付けられています。
- export TEST_VAR
これにより、変数が環境変数に変更されます。 これは、環境リストをもう一度確認することで確認できます。
- printenv | grep TEST_VAR
OutputTEST_VAR=Hello World!
今回は、変数が表示されます。 子シェルを使って実験をもう一度試してみましょう。
- bash
- echo $TEST_VAR
OutputHello World!
素晴らしい! 子シェルは、その親によって設定された変数を受け取りました。 この子シェルを終了する前に、別の変数をエクスポートしてみましょう。 次のように、1つのステップで環境変数を設定できます。
- export NEW_VAR="Testing export"
環境変数としてエクスポートされることをテストします。
- printenv | grep NEW_VAR
OutputNEW_VAR=Testing export
それでは、元のシェルに戻りましょう。
- exit
新しい変数が利用可能かどうかを見てみましょう。
- echo $NEW_VAR
何も返されません。
これは、環境変数が子プロセスにのみ渡されるためです。 親シェルの環境変数を設定する組み込みの方法はありません。 これはほとんどの場合に有効であり、プログラムが呼び出された操作環境に影響を与えるのを防ぎます。
The NEW_VAR
変数は、子シェルで環境変数として設定されました。 この変数は、それ自体とその子シェルおよびプロセスのいずれかで使用できます。 メインシェルに戻ると、その環境は破壊されました。
変数の降格と設定解除
私たちはまだ私たちを持っています TEST_VAR
環境変数として定義された変数。 次のように入力すると、シェル変数に戻すことができます。
- export -n TEST_VAR
それはもはや環境変数ではありません:
- printenv | grep TEST_VAR
ただし、それでもシェル変数です。
- set | grep TEST_VAR
OutputTEST_VAR='Hello World!'
シェルまたは環境のいずれかの変数の設定を完全に解除したい場合は、 unset
指図:
- unset TEST_VAR
設定されていないことを確認できます。
- echo $TEST_VAR
変数が設定されていないため、何も返されません。
ログイン時の環境変数の設定
多くのプログラムが環境変数を使用して操作方法の詳細を決定することはすでに述べました。 新しいシェルセッションを開始するたびに重要な変数を設定する必要はなく、ログイン時にすでに設定されている変数の数をすでに確認しているので、変数を自動的に作成して定義するにはどうすればよいですか?
これは、bashシェルが起動方法に応じて読み取る多数の構成ファイルがあるため、実際には当初の見た目よりも複雑な問題です。
ログイン、非ログイン、対話型、および非対話型のシェルセッションの違い
bashシェルは、セッションの開始方法に応じて、さまざまな構成ファイルを読み取ります。
異なるセッション間の1つの違いは、シェルがloginまたはnon-loginセッションとして生成されているかどうかです。
login シェルは、ユーザーの認証から始まるシェルセッションです。 ターミナルセッションにサインインするか、SSHを介して認証する場合、シェルセッションはログインシェルとして設定されます。
認証されたセッション内から新しいシェルセッションを開始する場合、 bash
ターミナルからコマンドを実行すると、non-loginシェルセッションが開始されます。 子シェルを開始したときに、認証の詳細を尋ねられることはありませんでした。
行うことができる別の区別は、シェルセッションがインタラクティブであるか非インタラクティブであるかです。
Interactive シェルセッションは、端末に接続されているシェルセッションです。 非対話型シェルセッションは、ターミナルセッションに接続されていないものです。
したがって、各シェルセッションは、ログインまたは非ログインとインタラクティブまたは非インタラクティブのいずれかに分類されます。
SSHで始まる通常のセッションは、通常、対話型ログインシェルです。 コマンドラインから実行されるスクリプトは、通常、非対話型、非ログインシェルで実行されます。 ターミナルセッションは、これら2つのプロパティの任意の組み合わせにすることができます。
シェルセッションがログインシェルまたは非ログインシェルとして分類されるかどうかは、シェルセッションを初期化するためにどのファイルが読み取られるかに影響します。
ログインセッションとして開始されたセッションは、から構成の詳細を読み取ります /etc/profile
最初にファイルします。 次に、ユーザーのホームディレクトリで最初のログインシェル構成ファイルを検索して、ユーザー固有の構成の詳細を取得します。
見つけた最初のファイルを読み取ります ~/.bash_profile
, ~/.bash_login
、 と ~/.profile
それ以上のファイルは読み込まれません。
対照的に、非ログインシェルとして定義されたセッションは読み取ります /etc/bash.bashrc
次に、ユーザー固有の ~/.bashrc
その環境を構築するためのファイル。
非対話型シェルは、と呼ばれる環境変数を読み取ります BASH_ENV
指定されたファイルを読み取って、新しい環境を定義します。
環境変数の実装
ご覧のとおり、設定を配置するために通常確認する必要のあるさまざまなファイルがあります。
これにより、ログインシェルで特定の設定を行い、非ログインシェルで他の設定を行う必要がある特定の状況で役立つ多くの柔軟性が提供されます。 ただし、ほとんどの場合、両方の状況で同じ設定が必要になります。
幸い、ほとんどのLinuxディストリビューションは、ログイン構成ファイルを構成して、非ログイン構成ファイルを入手します。 これは、ログイン以外の構成ファイル内の両方で必要な環境変数を定義できることを意味します。 その後、両方のシナリオで読み取られます。
通常、ユーザー固有の環境変数を設定します。通常、ログインシェルと非ログインシェルの両方で設定を使用できるようにします。 これは、これらの変数を定義する場所が ~/.bashrc
ファイル。
このファイルを今すぐ開きます。
- nano ~/.bashrc
これには、すでにかなりの量のデータが含まれている可能性があります。 ここでの定義のほとんどは、環境変数とは関係のないbashオプションを設定するためのものです。 コマンドラインから行うのと同じように、環境変数を設定できます。
- export VARNAME=value
新しい環境変数は、どこにでも追加できます。 ~/.bashrc
別のコマンドの途中またはforループに配置されていない限り、ファイル。 その後、ファイルを保存して閉じることができます。 次にシェルセッションを開始すると、環境変数宣言が読み取られ、シェル環境に渡されます。 次のように入力すると、現在のセッションでファイルを強制的に読み取ることができます。
- source ~/.bashrc
システム全体の変数を設定する必要がある場合は、それらをに追加することを検討してください。 /etc/profile
, /etc/bash.bashrc
、 また /etc/environment
.
結論
環境変数とシェル変数はシェルセッションに常に存在し、非常に便利です。 これらは、親プロセスがその子の構成の詳細を設定するための興味深い方法であり、ファイルの外部でオプションを設定する方法です。
これには、特定の状況で多くの利点があります。 たとえば、一部の展開メカニズムは、認証情報を構成するために環境変数に依存しています。 これは、外部の第三者に見られる可能性のあるファイルにこれらを保持する必要がないため、便利です。
システムの環境を読んだり変更したりする必要がある、他にももっとありふれた、しかしもっと一般的なシナリオはたくさんあります。 これらのツールとテクニックは、これらの変更を行い、正しく使用するための優れた基盤を提供するはずです。