見出し画像

dateコマンドで理解できるかもしれない「環境変数」の話

環境変数って意味わかんないよねーって話をしていて、まあ実際そうだよなという事なんで、使ってみれば理解できるんじゃねえか?と思いたった中で一番dateコマンドを使った事例が楽そうかなと思ったので書いてみました。シェル変数の話もちょっとはしておくけど基本的にシェル変数は今回は忘れときましょう。環境変数の事をやるには環境変数に集中して学習した方がおそらく効率はよいでしょう。


dateコマンドとは?

date
2023年 12月 12日 火曜日 01:42:41 UTC

このように「基本的には」現在時刻を単に出力するコマンド。基本的にはというのは応用的な使い方もあるんだけどそれは省略。で、

2023年 12月 12日 火曜日 01:46:31 UTC

という表示になっている。場合(環境)によっては英語になってるかもしれない。

出たねー、「環境」。

ここで今、このウインドウ

のこの中が「環境」と考えてok。つまり、「日本語環境」で作業しているという事。

今、どういう環境で作業してるのかの確認(envコマンド)

実は、この画面の環境はシステムとかそれ以外のもので予め諸々設定されている。例えば日本語で文字が出てくるのとか、これは個々の作業環境によって異なることがある。これはある意味ではアプリケーションの設定なのだが、もうちょいアバウトな設定を環境でセットするイメージ。たとえば日本語環境とか英語環境とかそういうものはdateコマンドに限らずlscpやら大抵ほとんど全ての多言語対応アプリは大抵環境変数LANGとかを見るような慣習がある。アプリが一々個々で設定をもっておくより大雑把に環境変数見た方が楽だよね?って考え方かもしれないな。

では、今どのような環境にあるのか、これはenv というコマンドで確認できるから、やってみよう。

ちなみに、rootシェルでこのような実験的な事をしてはいけない、でも今回記事を書くにあたって(主にスクショ目的…)、rootの環境が一番クリアだったので面倒くせえからrootでやってるのは勘弁して欲しい、けど、もしこの記事のような事を実際に手を動かしてやる場合はrootは使わないように。

ここでイコールを挟んで10個くらい何かが定義されている。これをchatgptにまとめてもらうと以下のような表になった。

ChatGPTによる現在の環境変数の一覧まとめ

ここでLANGという値に注目すると ja_JP.UTF-8 となっている。ロケールとかいうと、これの話をするだけで1ページ悠々使いそうだからやめておくけど、これはjaとか書いてあるから何となくjapanese感があるな〜と思っておくくらいでokであり、またこのLANGにenglishっぽいものを入れると英語になるんじゃね?って思いませんか?思って!

環境変数LANGを変更してみる

英語にするには先に答えを書いとくけど、環境変数LANGを en_US.UTF-8 にセットするといい。じゃあ、環境変数LANGを変更する場合どうすればいいかというのがLinux資格系の質問で出てくると思うけど、以下のようにexportするのが正解である。

注: bash系ではexportする。cshとかtcshなどという古のシェルを使っている場合はexportコマンドなんて知らんと言われるけど、これは流石にもう考えなくていいんじゃないかな…csh系での試験問題が万が一出てきたらすんません。古のアプリっつっても今でもinstallして使う事はできますが…

英語になり、Tue Dec 12 02:04:20 UTC 2023と表示された

つまり

date
2023年 12月 12日 火曜日 01:42:41 UTC

という環境から

date
Tue Dec 12 02:04:20 UTC 2023

という環境に変化した。これが環境変数を切り替えるという事であーる。

もういちど envコマンドで確認しておくと

LANGの値がen_US.UTF-8に変わってるよね!

このように変化しているのがわかる。

環境変数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してもいいんだけど、ここでは違う方法でやってみる事にしましょ

2行目の出力がJSTに、4行目の出力がUTCになってる点に注目してほしい!

このように

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とするとこの値が出てくる

TZには値は一応セットされてるんだけど…

でも

TZにAsia/Tokyoが入ってるのにUTCになっちゃった

envしても環境変数TZの値は設定されてないし、実際にdateしてもUTCが出てきていますよね。つまりこのTZって値は「環境に影響を与えてない」変数なのだった。

何でこんな得体にしれない変数が存在しているのかという話はこれはまた長くなるからシェル変数については実は今回のトピックではあんまやらない事にする。

でもまあ読み飛ばしといてけど、シェルっていうのはこういう簡単なプログラムチックなものも作れる

#!/bin/sh

read -p "n日後の日付を表示します。nを入力してください: " n
date -d "$n days"

ここでn日後を入力させシェル変数nに入れている。まあこういう使い方する(できる)よってくらいだからやっぱ読み飛ばしていいっすよ。まあでも試験に出るならシェル変数についてもやらないといけないな…

30日後の時間を計算したシェルスクリプトの結果。ただしUTCである。環境変数TZがAsia/TokyoにセットされてればJSTになる

シェル変数を環境変数に変更(昇格)する

今シェル変数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コマンドとか)まあ、あるいはプロセスの話とか)に繋がってくるんだけどもう十分長いので環境変数使い方基礎辺ってことで今回はここまで。おつかれさまでした。

この記事が気に入ったらサポートをしてみませんか?