Just do IT

思うは招く

Linuxの「シェル変数」と「環境変数」について整理

Linuxでは、大きくわけて2つの変数が存在する。 「シェル変数」と「環境変数」の2つ。

シェル変数とは

シェル変数とは、そのLinuxで採用されているシェル内部で使用される変数のことを指す(シェルは基本的にはbashが採用されている)

シェル変数を設定することで、いろんな機能をカスタマイズできる。 ここでは、代表的なシェル変数であるPATHとLANGを用いて解説する。

シェル変数PATH

たとえば、有名なのはPATHというシェル変数。

PATHには、シェルがコマンドを検索するパスが設定されている。「コマンド検索パス」と呼ばれる。 PATHに実行可能ファイルのパスを設定すると、フルパスで指定しなくても実行できるようになる。

echoでPATHを出力してみると、パスがずらっと見れる。 (シェル変数を参照するには、$をつけるルールがある)

echo $PATH
# vagrant, Ubuntu環境だとこうなる
/home/vagrant/.yarn/bin:/home/vagrant/.config/yarn/global/node_modules/.bin:/home/vagrant/.nvm/versions/node/v10.14.2/bin:/home/vagrant/.rbenv/shims:/home/vagrant/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

ずらっと並んでいてわかりにくいが、:で区切って、複数のパスが登録されている。 見やすく出力すると、わかりやすくなる。

echo $PATH | sed -e 's/:/\n/g'
/home/vagrant/.yarn/bin
/home/vagrant/.config/yarn/global/node_modules/.bin
/home/vagrant/.nvm/versions/node/v10.14.2/bin
/home/vagrant/.rbenv/shims
/home/vagrant/.rbenv/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

これらのディレクトリに設定されている実行可能ファイルは、わざわざ/usr/binといったフルパスを指定しなくても、ファイル名だけで実行できる。

たとえば、よく使うlsコマンドは、次のパスに実行可能ファイルが設置されている。

which ls
/bin/ls

この場合、lsが/bin/lsに設置されており、その/bin/lsがコマンド検索パスに登録されている。そのため、lsとコマンドを打っても、シェルが自動でコマンド検索パスを探して、フルパスで実行したのと同じ動作をしてくれる。

シェル変数LANG

LANGは、表示する言語や日付の書式などを設定するためのシェル変数。ロケールとも呼ばれる。

こちらも$をつけてechoで参照してみる。

echo $LANG
C.UTF-8

私の環境では英語を使用しているが、日本語環境なら次のような表示が出るはず。

ja_JP.UTF-8

なお、システムがサポートしているロケールを見るには、ズバリそのままlocaleコマンドが存在する。

locale

LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=

ためしに、私の環境だとUTC時間が使われているので、これを日本時間に変更してみる。 日付や時間などを出力するdateコマンドをすると、次のような結果になる。

date
Tue Jan 28 00:47:02 UTC 2020

この記事を書いている日本の日時は、2020/01/28、火曜日の朝9時47分なので、上記とは異なる。

日本時間に設定してみる。

sudo timedatectl set-timezone Asia/Tokyo

そしてdateを実行すると

date
Tue Jan 28 09:50:20 JST 2020

このように、JST(日本の時間)が表示された。 私は言語を英語の環境で使いたいため、英語にしているが、日本語にする方法は以下の記事に書いている。

k-koh.hatenablog.com

他のシェル変数

シェル変数は上記で紹介した以外にもいろいろある。 たとえば、HOME変数にはホームディレクトリのパスが代入されている。

echo $HOME
/home/vagrant

SHELLには、今使っているシェル(ここではbash)のパスが表示されている。 つまり、bashファイルがどこにあるかがわかる。

echo $SHELL
/bin/bash

ほかのシェル変数をチェックしてみたいなら、いろいろ検索してみることをおすすめする。

www.tutorialspoint.com

環境変数とは

まず前提として、シェルのコマンドは、大きく「組み込みコマンド」と「外部コマンド」に分けられる。

  • 組み込みコマンド:シェルがもともと持っているコマンド
  • 外部コマンド:実行ファイルとしてシステム上に存在するコマンド

このうち、外部コマンドは、シェル変数を参照できない仕様になっている。外部コマンドはシェルの外側で実行されるためだ。

では、どれが組み込みコマンドで、どれが外部コマンドなのか。 これは、typeコマンドで知ることができる。 たとえば、echoコマンドをtypeを使って調べてみると。

type echo
echo is a shell builtin

「echoコマンドは、シェルのビルトイン」と返ってくる。ビルトインとは組み込みという意味だ。

一方で、catコマンドをtypeで調べてみる。

type cat
cat is hashed (/bin/cat)

catコマンドの実行可能ファイルが設置されているディレクトリが表示され、外部コマンドということがわかる。

「外部コマンドは、シェル変数を参照できない」ということを理解するためには、自分で実際にシェル変数を作ってみるとわかりやすい。

# シェル変数を作る
test_var='this is a test-variable'

# echoで参照する
echo $test_var
=> this is a test-variable

# catで参照してみると
cat $test_var

cat: this: No such file or directory
cat: is: No such file or directory
cat: a: No such file or directory
cat: test-variable: No such file or directory

上記のように、catコマンドは外部コマンドのため、$test_varは参照できない。

ただ、外部コマンドからシェル変数を参照できないのは、ちょっと不便。 そこで、外部コマンドからでも値を参照するときに使われるのが、環境変数である。

現在設定されている環境変数をチェックするには、printenvコマンドを使う。

printenv

# たくさんあるので省略
LANG=C.UTF-8
NVM_CD_FLAGS=
S_COLORS=auto
XDG_SESSION_ID=3
USER=vagrant
RBENV_SHELL=bash
PWD=/home/vagrant/workspace
HOME=/home/vagrant

おや、見たことのある変数たちがいる・・・?

そう、LANGHOMEなどは、シェル変数でもあり、環境変数でもある。

なぜなら、catコマンドをしてファイルを読み込むとき、それがもし日本語のファイルだったら、日本語の設定を読み込んでいないと日本語として出力できない。 よって、catコマンドが実行されたら、LANGという環境変数をチェックして言語を確認し、それに従って内容を表示している。

環境変数として設定するexportコマンド

自分で作ったシェル変数を、環境変数として登録するためのコマンドがexportだ。

もっとも頻繁にこのコマンドを見かけるのは、シェル変数PATHにコマンド検索パスを登録するときだろう。

# 例
export PATH="$PATH:~/mybin"

これは実は、次と同じことをしている。

# まずPATHに代入
PATH="$PATH:~/mybin"

# exportでPATHを環境変数として登録
export PATH

これが具体的に何をしているのかは、以下の記事で解説している。

k-koh.hatenablog.com

まとめ

  • Linuxでは「シェル変数」と「環境変数」という2種類の変数がある
  • シェル変数とは、そのLinuxで採用されているシェル内部で使用される変数のこと
    • シェル変数を設定することで、いろんな機能をカスタマイズできる
  • 環境変数とは、外部コマンドから値を参照するときに使われる変数
  • 環境変数を自分で設定するには、exportコマンドを利用する