dateコマンドで理解できるかもしれない「環境変数」の話
環境変数って意味わかんないよねーって話をしていて、まあ実際そうだよなという事なんで、使ってみれば理解できるんじゃねえか?と思いたった中で一番dateコマンドを使った事例が楽そうかなと思ったので書いてみました。シェル変数の話もちょっとはしておくけど基本的にシェル変数は今回は忘れときましょう。環境変数の事をやるには環境変数に集中して学習した方がおそらく効率はよいでしょう。
dateコマンドとは?
date
2023年 12月 12日 火曜日 01:42:41 UTC
このように「基本的には」現在時刻を単に出力するコマンド。基本的にはというのは応用的な使い方もあるんだけどそれは省略。で、
2023年 12月 12日 火曜日 01:46:31 UTC
という表示になっている。場合(環境)によっては英語になってるかもしれない。
出たねー、「環境」。
ここで今、このウインドウ
のこの中が「環境」と考えてok。つまり、「日本語環境」で作業しているという事。
今、どういう環境で作業してるのかの確認(envコマンド)
実は、この画面の環境はシステムとかそれ以外のもので予め諸々設定されている。例えば日本語で文字が出てくるのとか、これは個々の作業環境によって異なることがある。これはある意味ではアプリケーションの設定なのだが、もうちょいアバウトな設定を環境でセットするイメージ。たとえば日本語環境とか英語環境とかそういうものはdateコマンドに限らずlsやcpやら大抵ほとんど全ての多言語対応アプリは大抵環境変数LANGとかを見るような慣習がある。アプリが一々個々で設定をもっておくより大雑把に環境変数見た方が楽だよね?って考え方かもしれないな。
では、今どのような環境にあるのか、これはenv というコマンドで確認できるから、やってみよう。
ここでイコールを挟んで10個くらい何かが定義されている。これをchatgptにまとめてもらうと以下のような表になった。
ここでLANGという値に注目すると ja_JP.UTF-8 となっている。ロケールとかいうと、これの話をするだけで1ページ悠々使いそうだからやめておくけど、これはjaとか書いてあるから何となくjapanese感があるな〜と思っておくくらいでokであり、またこのLANGにenglishっぽいものを入れると英語になるんじゃね?って思いませんか?思って!
環境変数LANGを変更してみる
英語にするには先に答えを書いとくけど、環境変数LANGを en_US.UTF-8 にセットするといい。じゃあ、環境変数LANGを変更する場合どうすればいいかというのがLinux資格系の質問で出てくると思うけど、以下のようにexportするのが正解である。
つまり
date
2023年 12月 12日 火曜日 01:42:41 UTC
という環境から
date
Tue Dec 12 02:04:20 UTC 2023
という環境に変化した。これが環境変数を切り替えるという事であーる。
もういちど envコマンドで確認しておくと
このように変化しているのがわかる。
環境変数TZとシェル変数
dateコマンドは環境変数LANGの他に、実は環境変数TZというのを見ている。見てるんだけど、上のenvコマンドを見てもわかるようにTZという環境変数が存在しない事も当然ある。環境変数の値が無い場合はUTCにしてね(正確にはシステム時間なのかもしれんけど)という挙動になっており、環境変数が存在する場合はそれを使うという挙動になっている。
UTCとは
UTCの話とかは環境変数とは実は全く関係無いんだけど、どうせ絶対知っておかないといけない話だから書いておくと世界協定時間とかいうやつで日本だと時差が9時間ある奴である。昔はGMTとよんでいて、グリニッジ標準時間だった奴をなんていうのか、もうちょっと科学的に補正した奴のことだったりするんだけど、まあそれはさておいて、日本の時間とズレているという事が重要。
実際
date
Tue Dec 12 02:14:44 UTC 2023
を入力した今の時間は11:14分であった。このように日本時間で11:14分なのにdateしたら2:14分になってるこのマシンの時間がずれてるんじゃねーか?と思ったらあかんという事。UTCと表示されているのでこれが正解なのである。
そうはいっても時間ずれてたら使い辛いじゃん
と考えるのは至って普通の思考なので、これを切り替えたい。ここで使う環境変数がTZである。TZっていうのはタイムゾーン(timezone)の省略形と思ってok。
さっきも見たようにenvコマンドで確認すると
env
SHELL=/bin/bash
PWD=/root
LOGNAME=root
HOME=/root
LANG=en_US.UTF-8
TERM=xterm
USER=root
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAIL=/var/mail/root
_=/usr/bin/env
TZという名前の環境変数は見あたらない。なので、ここでは新たに環境変数を自分でセットしないといけない。
セットしてみる
つっても何の値を入れればいいのかわからないのが普通なのでこれは答えを書いときます。日本時間にするにはAsia/TokyoをTZにセットします
まあ、LANGの時にやったように普通にexportしてもいいんだけど、ここでは違う方法でやってみる事にしましょ
このように
TZ=Asia/Tokyo date
Tue Dec 12 11:21:31 JST 2023
と、「コマンドの前に変数=値」を付けてコマンドを打ちこむと、そのコマンド一回実行したら元に戻ります。要するに使い捨て環境変数やね。現に続くコマンドでは
date
Tue Dec 12 02:21:59 UTC 2023
このように即座にUTCに切り変わってしまっていて11時だったやつが2時になってるのがわかるでしょう。これをずっと使いたい場合はexportしますけど
export TZ=Asia/Tokyo
exportしなかったらどーなるの?って思いませんか?思わねえか…
exportしなかったときの扱い(これはシェル変数になる)
TZ=Asia/Tokyo
とした場合このTZという変数は環境変数じゃなくてシェル変数になる。出たねーシェル変数。実際echo $TZとするとこの値が出てくる
でも
envしても環境変数TZの値は設定されてないし、実際にdateしてもUTCが出てきていますよね。つまりこのTZって値は「環境に影響を与えてない」変数なのだった。
何でこんな得体にしれない変数が存在しているのかという話はこれはまた長くなるからシェル変数については実は今回のトピックではあんまやらない事にする。
でもまあ読み飛ばしといてけど、シェルっていうのはこういう簡単なプログラムチックなものも作れる
#!/bin/sh
read -p "n日後の日付を表示します。nを入力してください: " n
date -d "$n days"
ここでn日後を入力させシェル変数nに入れている。まあこういう使い方する(できる)よってくらいだからやっぱ読み飛ばしていいっすよ。まあでも試験に出るならシェル変数についてもやらないといけないな…
シェル変数を環境変数に変更(昇格)する
今シェル変数TZが存在するものの環境変数TZは存在しないという状況の場合、これをexportするとシェル変数TZが環境変数TZにいわば昇格する。
export TZ
date
Tue Dec 12 11:51:10 JST 2023
このようにシェル変数をexportするだけ
っつっても正直あんまこのオペレーションは行う事は少ないだろう。でも試験問題にでてんだもん、仕方ないっすね。
まとめ
長くなったけど、覚えておくべき要点を上げときますよ。
環境変数を設定するには大抵の場合exportをつけて「式=値」を設定する
例 export TZ=Asia/Tokyo (以降Asia/Tokyoの時間が出る)
コマンドの前にセットすると使い捨て環境変数になる
例 TZ=Europe/Lisbon date (リスボンの時間が出るだろう)
環境変数は大抵の場合、大雑把なアプリケーションの共通設定で使われるパターンが多いがそうじゃないものも勿論ある。
これに関して環境変数のいくつかはある程度取り決めがあるのでいくつか覚えておく。たとえばおそらく問題に頻出するのはPATH,場合によってはHOMEとか、今見てきたLANGとか
オペレーションするにあたっては特定のアプリケーションがどのような環境変数を設定すればいいのかというのは、それはコマンドの説明に書いてあるから、Linuxとかのオペレーターはその設定情報を注意深く読んで設定する事が求められるし、プログラマーであればその環境変数を使うプログラムを書く事も実際よくある。
これで終われれば楽なんだけどな〜
で、一回exportした環境変数つのは、たとえばそのシェルの画面を閉じて、またシェルを再開したときに復活すんのか?っていうと、これがしないんだね〜実は。この場合は環境変数はリセットされて消滅します。このあたりの事はシェルの起動とか.bashrcまたは.bash_profileとか、あるいはsourceコマンドとか)まあ、あるいはプロセスの話とか)に繋がってくるんだけどもう十分長いので環境変数使い方基礎辺ってことで今回はここまで。おつかれさまでした。