序章

シェルセッションを介してサーバーと対話する場合、シェルの動作とリソースへのアクセスを決定するためにシェルがコンパイルする多くの情報があります。 これらの設定の一部は構成設定に含まれ、その他はユーザー入力によって決定されます。

シェルがこれらすべての設定と詳細を追跡する1つの方法は、環境と呼ばれるシェルが維持する領域を介することです。 環境は、システムプロパティを定義する変数を含むセッションを開始するたびにシェルが構築する領域です。

このガイドでは、環境と対話し、環境変数とシェル変数を対話形式で構成ファイルを介して読み取りまたは設定する方法について説明します。

ブラウザの端末を使用してこのチュートリアルを実行するには、下のLaunch an Interactive Terminal!ボタンをクリックしてください。

それ以外の場合、ローカルシステムまたはリモートサーバーを使用して続行する場合は、ターミナルを開き、そこでこのチュートリアルのコマンドを実行します。

環境と環境変数のしくみ

シェルセッションが生成されるたびに、シェルプロセスとその子プロセスで利用できるはずの情報を収集してコンパイルするプロセスが実行されます。 これらの設定のデータは、システム上のさまざまなファイルや設定から取得されます。

この環境は、シェルプロセスが設定を取得または設定し、それらを子プロセスに渡すための媒体を提供します。

環境は、キーと値のペアを表す文字列として実装されます。 複数の値が渡される場合、それらは通常、コロン(:)文字で区切られます。 各ペアは通常、次のようになります。

KEY=value1:value2:...

値に重要な空白が含まれている場合は、引用符が使用されます。

KEY="value with spaces"

これらのシナリオのキーは変数です。 これらは、環境変数またはシェル変数の2つのタイプのいずれかになります。

環境変数は、現在のシェルに対して定義され、子シェルまたはプロセスによって継承される変数です。 環境変数は、シェルから生成されるプロセスに情報を渡すために使用されます。

シェル変数は、それらが設定または定義されたシェル内に排他的に含まれる変数です。 これらは、現在の作業ディレクトリなどの一時的なデータを追跡するためによく使用されます。

慣例により、これらのタイプの変数は通常、すべて大文字を使用して定義されます。 これは、ユーザーが他のコンテキスト内の環境変数を区別するのに役立ちます。

シェルと環境変数の印刷

各シェルセッションは、独自のシェルと環境変数を追跡します。 これらにはいくつかの異なる方法でアクセスできます。

envまたはprintenvコマンドを使用すると、すべての環境変数のリストを表示できます。 デフォルトの状態では、まったく同じように機能するはずです。

  1. printenv

シェル環境には、次の出力とは異なる値で設定された変数が多かれ少なかれある場合があります。

Output
SHELL=/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

これは、printenvenvの両方の出力のかなり典型的なものです。 2つのコマンドの違いは、より具体的な機能でのみ明らかです。 たとえば、printenvを使用すると、個々の変数の値を要求できます。

  1. printenv PATH
Output
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

一方、envでは、変数定義のセットを次のようなコマンドに渡すことにより、プログラムが実行される環境を変更できます。

  1. env VAR1="value" command_to_run command_options

上で学習したように、子プロセスは通常、親プロセスの環境変数を継承するため、これにより、値をオーバーライドしたり、子の変数を追加したりすることができます。

printenvコマンドの出力からわかるように、入力なしでシステムファイルとプロセスを介して設定された環境変数がかなりあります。

これらは環境変数を示していますが、シェル変数はどのように見えますか?

これには、setコマンドを使用できます。 追加のパラメーターを指定せずにsetと入力すると、すべてのシェル変数、環境変数、ローカル変数、およびシェル関数のリストが表示されます。

  1. set
Output
BASH=/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=() . . .

これは通常、膨大なリストです。 出力量をより簡単に処理するために、おそらくそれをポケットベルプログラムにパイプする必要があります。

  1. set | less

私たちが受け取る追加情報の量は少し圧倒的です。 たとえば、定義されているすべてのbash関数を知る必要はおそらくありません。

setがシェル関数を出力しないPOSIXモードで動作するように指定することで、出力をクリーンアップできます。 これをサブシェルで実行して、現在の環境を変更しないようにすることができます。

  1. (set -o posix; set)

これにより、定義されているすべての環境変数とシェル変数が一覧表示されます。

この出力をenvまたはprintenvコマンドの出力と比較して、シェル変数のみのリストを取得しようとすることができますが、これらのコマンドの方法が異なるため、これは不完全です。出力情報:

  1. 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:画面に出力を描画するために使用されている幅の列の数。
  • DIRSTACKpushdおよびpopdコマンドで使用できるディレクトリのスタック。
  • HISTFILESIZE:ファイルに保存されているコマンド履歴の行数。
  • HISTSIZE:メモリに許可されているコマンド履歴の行数。
  • HOSTNAME:この時点でのコンピューターのホスト名。
  • IFS:コマンドラインの入力を分離するための内部フィールドセパレーター。 デフォルトでは、これはスペースです。
  • PS1:プライマリコマンドプロンプトの定義。 これは、シェルセッションを開始したときにプロンプトがどのように表示されるかを定義するために使用されます。 PS2は、コマンドが複数行にまたがる場合の2次プロンプトを宣言するために使用されます。
  • SHELLOPTSsetオプションで設定できるシェルオプション。
  • UID:現在のユーザーのUID。

シェルと環境変数の設定

シェル変数と環境変数の違いをよりよく理解し、これらの変数を設定するための構文を紹介するために、簡単なデモンストレーションを行います。

シェル変数の作成

まず、現在のセッション内でシェル変数を定義します。 これは簡単に実行できます。 名前と値を指定するだけです。 変数名のすべての大文字を保持するという規則に従い、単純な文字列に設定します。

  1. TEST_VAR='Hello World!'

ここでは、変数の値にスペースが含まれているため、引用符を使用しました。 さらに、感嘆符はbashシェルの特殊文字であり、エスケープまたは一重引用符に入れられない場合、通常はbash履歴に展開されるため、一重引用符を使用しました。

これでシェル変数ができました。 この変数は現在のセッションで使用できますが、子プロセスには渡されません。

これは、set出力内の新しい変数をgrepすることで確認できます。

  1. set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

printenvで同じことを試すことで、これが環境変数ではないことを確認できます。

  1. printenv | grep TEST_VAR

出力は返されません。

これを機会として、シェルまたは環境変数の値にアクセスする方法を示しましょう。

  1. echo $TEST_VAR
Output
Hello World!

ご覧のとおり、変数の値の前に$記号を付けて参照してください。 シェルはこれを、これに遭遇したときに変数の値を置き換える必要があることを意味します。

これでシェル変数ができました。 子プロセスに渡されるべきではありません。 現在のシェル内からnew bashシェルを生成して、次のことを示すことができます。

  1. bash
  2. echo $TEST_VAR

bashと入力して子シェルを生成し、変数の内容にアクセスしようとすると、何も返されません。 これは私たちが期待したことです。

exitと入力して、元のシェルに戻ります。

  1. exit

環境変数の作成

それでは、シェル変数を環境変数に変えましょう。 これは、変数をエクスポートすることで実行できます。 そのためのコマンドには、適切な名前が付けられています。

  1. export TEST_VAR

これにより、変数が環境変数に変更されます。 これは、環境リストをもう一度確認することで確認できます。

  1. printenv | grep TEST_VAR
Output
TEST_VAR=Hello World!

今回は、変数が表示されます。 子シェルを使って実験をもう一度試してみましょう。

  1. bash
  2. echo $TEST_VAR
Output
Hello World!

素晴らしい! 子シェルは、その親によって設定された変数を受け取りました。 この子シェルを終了する前に、別の変数をエクスポートしてみましょう。 次のように、1つのステップで環境変数を設定できます。

  1. export NEW_VAR="Testing export"

環境変数としてエクスポートされることをテストします。

  1. printenv | grep NEW_VAR
Output
NEW_VAR=Testing export

それでは、元のシェルに戻りましょう。

  1. exit

新しい変数が使用可能かどうかを見てみましょう。

  1. echo $NEW_VAR

何も返されません。

これは、環境変数が子プロセスにのみ渡されるためです。 親シェルの環境変数を設定する組み込みの方法はありません。 これはほとんどの場合に有効であり、プログラムが呼び出された操作環境に影響を与えるのを防ぎます。

NEW_VAR変数は、子シェルの環境変数として設定されました。 この変数は、それ自体とその子シェルおよびプロセスのいずれかで使用できます。 メインシェルに戻ると、その環境は破壊されました。

変数の降格と設定解除

TEST_VAR変数はまだ環境変数として定義されています。 次のように入力すると、シェル変数に戻すことができます。

  1. export -n TEST_VAR

それはもはや環境変数ではありません:

  1. printenv | grep TEST_VAR

ただし、それでもシェル変数です。

  1. set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

シェルまたは環境のいずれかの変数の設定を完全に解除したい場合は、unsetコマンドを使用して行うことができます。

  1. unset TEST_VAR

設定されていないことを確認できます。

  1. 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ファイルにあることを意味します。

このファイルを今すぐ開きます。

  1. nano ~/.bashrc

これには、すでにかなりの量のデータが含まれている可能性があります。 ここでの定義のほとんどは、環境変数とは関係のないbashオプションを設定するためのものです。 コマンドラインから行うのと同じように、環境変数を設定できます。

  1. export VARNAME=value

新しい環境変数は、別のコマンドまたはforループの途中に配置されていない限り、~/.bashrcファイルのどこにでも追加できます。 その後、ファイルを保存して閉じることができます。 次にシェルセッションを開始すると、環境変数宣言が読み取られ、シェル環境に渡されます。 次のように入力すると、現在のセッションでファイルを強制的に読み取ることができます。

  1. source ~/.bashrc

システム全体の変数を設定する必要がある場合は、それらを/etc/profile/etc/bash.bashrc、または/etc/environmentに追加することを検討してください。

結論

環境変数とシェル変数はシェルセッションに常に存在し、非常に便利です。 これらは、親プロセスがその子の構成の詳細を設定するための興味深い方法であり、ファイルの外部でオプションを設定する方法です。

これには、特定の状況で多くの利点があります。 たとえば、一部の展開メカニズムは、認証情報を構成するために環境変数に依存しています。 これは、外部の第三者に見られる可能性のあるファイルにこれらを保持する必要がないため、便利です。

システムの環境を読んだり変更したりする必要がある、他にももっとありふれた、しかしもっと一般的なシナリオはたくさんあります。 これらのツールとテクニックは、これらの変更を行い、正しく使用するための優れた基盤を提供するはずです。