Infra Engineer

シェル変数と環境変数
2022.09.30
Lv1

シェル変数と環境変数

本記事の対象者

LPIC level1習得を目指す初学者の方
コマンドの基本的な用途について、要点を絞って解説します。


今回の内容

今回は、Linuxの変数について解説します。


・Linuxにおける変数

・シェル変数
・環境変数
・変数に関するコマンド等
・まとめ
・確認問題

Linuxにおける変数

シェルが動いている時、ユーザのホームディレクトリやカレントディレクトリやユーザ名などのデータを、どこかに保持して認識しておく必要があります。
そうでなければ、「cd」と打てばホームディレクトリに移動したり、「ls」と打てばカレントディレクトリの中身が表示されたりすることはありません。
Linuxにおいてこの保持の役割は「変数」が担っています。

一般的に「変数」とは、データを入れておく箱のようなものと説明されます。
上に挙げた例以外にも、様々な「データ」をシェルが保持し参照するために変数が使われています。
また、自分で変数を定義することも可能です。

例①)
ユーザのホームディレクトリの情報を保持している変数
[root@localhost ~]# echo $HOME
/root

「HOME」という変数は、Linuxであらかじめ定義されている変数で、ログインしているユーザのホームディレクトリの情報を保持するために使用されています。
中身を確認してみると、ホームディレクトリのパスが格納されていることが確認できます。

例②)
ユーザが変数を定義することも可能
[root@localhost ~]# example='変数は自分で定義できる'
[root@localhost ~]# echo $example
変数は自分で定義できる

任意の変数名を用意して、ここに「=」で代入することで変数を定義できます。

 

また、Linuxの変数には2種類あります。
シェル変数と環境変数です。
ふたつの違いはスコープ(有効範囲)です。

シェル変数と環境変数のスコープ
・シェル変数
その変数を定義したシェル、プロセスのみ
・環境変数
その変数を定義したシェル上、およびそのシェルで実行されるプログラムすべて

シェル変数

シェル変数とは、その変数を定義したシェルとプロセスのみで有効な変数のことです。
そのシェルやプロセスを終了すると、シェル変数は失われます。
また、子プロセスからは親プロセスで定義したシェル変数を参照することはできません。

例)
シェル変数のスコープ
[root@localhost ~]# SP="シェル変数"  #シェル変数を定義
[root@localhost ~]# echo $SP
シェル変数
[root@localhost ~]# bash  #ここで新たなbashを起動している(子プロセス)
[root@localhost ~]# echo $SP  #子プロセスからは親プロセスで定義したシェル変数を参照できない

[root@localhost ~]# exit  #親プロセスに戻る
exit
[root@localhost ~]# echo $SP
シェル変数

シェル上で「SP」というシェル変数を定義しました。
そのシェル上で中身を参照することは当然可能です。
しかし、そこから新しいシェル(子プロセス)を立ち上げ、その子プロセス内からシェル変数を参照しようとしてもできません。
なぜなら、シェル変数は、定義したシェルやプロセス内でのみ有効だからです。

シェル変数を使用する場面は、例えばシェルスクリプトなどが挙げられます。
(シェルスクリプトについは102の範囲ですのでここではとりあげません)


環境変数

環境変数とは、その変数を定義したシェル上、およびそのシェルで実行されるプログラムすべてで有効な変数のことです。
子プロセスには親プロセスの環境変数のコピーが渡される形です。
よって、子プロセスで環境変数に再代入を行っても、親プロセスの環境変数には影響がありません。

例①)
環境変数のスコープ
[root@localhost ~]# EP="環境変数"  #変数を定義(この時点ではシェル変数)
[root@localhost ~]# export EP     #EPを環境変数に
[root@localhost ~]# echo $EP    
環境変数
[root@localhost ~]# bash          #ここで新たなbashを起動している(子プロセス)
[root@localhost ~]# echo $EP      #子プロセスからも参照できる
環境変数
[root@localhost ~]# EP="子プロセス内で値を変更" #子プロセスで環境変数に再代入
[root@localhost ~]# echo $EP
子プロセス内で値を変更
[root@localhost ~]# exit      #親プロセスに戻る
exit
[root@localhost ~]# echo $EP       #親プロセスの環境変数の値は変化しない
環境変数

先ほどのシェル変数との違いをおさえてください。
環境変数は子プロセスからも参照できています。
また、子プロセス内で再代入を行っても、親プロセスの環境変数の値は変化しません。

Linuxにはあらかじめ定義されている環境変数が多くあり、これを利用して値を保持参照しています。

表. 主な環境変数

環境変数名 保持されているデータ
HOME ログインユーザのホームディレクトリ
PWD カレントディレクトリ
USER ログインユーザのユーザ名
HOSTNAME コンピュータのホスト名
PATH コマンドやプログラムを検索するディレクトリリスト
HISTSIZE コマンド履歴の保存件数
LANG 使用する言語
SHELL ログインユーザのシェル
例②)
環境変数に保持されている値
[root@localhost ~]# echo $HOME
/root
[root@localhost ~]# echo $PWD
/root
[root@localhost ~]# echo $USER
root
[root@localhost ~]# echo $HOSTNAME
localhost.localdomain
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# echo $HISTSIZE
1000
[root@localhost ~]# echo $LANG
ja_JP.UTF-8
[root@localhost ~]# echo $SHELL
/bin/bash

変数に関するコマンド等

変数に関するコマンド等について紹介します。
今までの説明内に使用した「echo」や「export」などがそれにあたります。

コマンドや記号 書式 説明
= 変数名=値 変数を定義し、値を代入します。
echo echo $変数名 変数の値を出力します。
set set [シェル変数名=値] シェル変数に値を代入します。引数を指定しない場合は、すべての変数の一覧を出力します。
unset unset 変数名 変数を削除します。
env env 環境変数の一覧を出力します。
export export 変数名[=値] 環境変数を定義します。既存のシェル変数を環境変数にします。

赤文字は特に注意してほしいところです。
echoで変数の値を参照する際には「$」が必要です。(後の例で理由を説明します)
setは「すべての変数の一覧」を表示しますが、envは「環境変数のみ」を表示します。

例①)
変数の代入と値の表示。(echo)
[root@localhost ~]# $example=例   #代入時に「$」をつけてはいけない
bash: =例: コマンドが見つかりませんでした...
[root@localhost ~]# example=例
[root@localhost ~]# echo example  #「$」をつけなかった場合
example
[root@localhost ~]# echo $example
例

ポイントは、echoコマンドは「変数の値を出力するコマンドではない」ということです。
echoコマンドは「引数に渡した文字列を表示するコマンド」です。
「echo linux」と打てば、単に「linux」と出力されるのです。
つまり、echoコマンドで変数の値を出力したいなら、「引数に渡したのが単なる文字列ではなく変数名であることを明示する必要がある」ということです。
そのために「$」をつけます。

例②)
変数の一覧表示。(set、env)
[root@localhost ~]# set | grep example
example=例
[root@localhost ~]# env | grep example
[root@localhost ~]# export example
[root@localhost ~]# env | grep example
example=例

set、envのみの出力は膨大になるため載せません。
setの出力から「example」を検索すると、先ほど定義したシェル変数が見つかります。
一方、envの出力から「example」を検索しても見つかりません。
その後「export」コマンドで「example」を環境変数にすると、「env」の出力に「example」が見つかるようになりました。


まとめ

今回は、Linuxの変数について解説しました。
シェル変数と環境変数の違いを抑え、主要な環境変数については暗記しましょう。

「$」をつけなければならないのかどうかわからなくなるというのは初学者によくある悩みですが、それは「$」をつける理由を理解していないからです。
「変数名であることを明示する必要があるのかないのか」という観点さえ持っていれば悩む必要はありません。
「変数名=値」の際に「$」をつける必要はありません。なぜなら左辺には変数名以外こないことが保証されているからです。
setやunsetの引数についても同じです。
「そこに変数名以外入ることがあり得ないのならば$をつける必要はない」ということです。


確認問題

問題①

すべての変数の一覧を表示するコマンドは以下のうちどれか。

A) env
B) ls $
C) set
D) env –all
E) set –all

解答①
答え:C

A) ⇒ envで表示するのは環境変数のみです。
B) ⇒ このようなコマンドはありません。
C) ⇒ 正解です。
D) ⇒ このようなオプションはありません。
E) ⇒ このようなオプションはありません。

問題②

以下のうち、エラーとなるコマンドはどれか。

A) sak=システムアーキテクチャナレッジ
B) echo sak
C) echo $sak
D) unset $sak
E) export sak=システムアーキテクチャナレッジ

解答②
答え:D

unsetコマンドの引数には変数名以外きません。
よって、不要な$をつけるとエラーになります。