概要
小ネタ。よく忘れるのでメモメモ。知ってるとちょっと便利なもの。
特定の環境変数の値を読み取って動作するプログラムはよくあります。
で、実行してみるとなんか挙動がおかしい。。。ってときがたまにあります。
どうも環境変数の値っぽい感じがするんだけど、プログラムをデバッグのためにいじって再コンパイルすることなどはちょっと無理・・・みたいな状況もたまにあります・・。実環境にgdbも入ってないとかもよくあります。。。
そういうときは、/proc
ファイルシステムの プロセステーブル の値を見るのが使えるかもしれません。
/proc
の下には現在のプロセス毎にディレクトリが配置されます。
例えば、プロセスIDが1111の場合は /proc/1111
というディレクトリがあります。
この中を見ると、そのプロセスに関する情報がいっぱいあるのですが、プロセス起動時に適用された環境変数のリストが入っている environ
という名前のファイルがあります。
このファイルの中身を見ると、プロセスが起動されたときの環境変数が見れます。
注意点として
- /proc/pid/environ ファイルは ヌル文字 で結合されている
という点があります。改行ではないので、区切り文字を変換してやらないと全部つながってみえちゃいます。
読み取り専用の普通のファイルと同じように扱えますので、cat とかで中身が見えます。
Linux/Unix の「全てはファイルである (Everything is a file)」の思想は素晴らしいですね。
サンプル
同じプログラムを2回起動して、1回目は環境変数指定なし、2回目は環境変数指定ありで起動しています。
#!/usr/bin/env bash basedirpath=/tmp/try-linux/list_proc_environ # 実験用のディレクトリ作成 rm -rf "$basedirpath" mkdir -p "$basedirpath" # SIGTERMを受け取るまで待機するプログラム cat << EOF > "$basedirpath"/main.go package main import ( "os" "os/signal" "syscall" ) func main() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGTERM) <-c } EOF # プログラムをコンパイル # ベースディレクトリを動かしたくないのでサブシェル起動して処理 ( cd "$basedirpath" go build -o app main.go ) # # 独自の環境変数を追加せずプロセス起動 # echo '---------- not set ----------' "$basedirpath"/app >/dev/null 2>&1 & app1_pid="$!" # MY_ENV という環境変数は設定していないので何も表示されない # /proc/pid/environ ファイルのデータは ヌル文字 で結合されていることに注意 tr '\0' '\n' < "/proc/$app1_pid/environ" | grep 'MY_ENV' kill -SIGTERM "$app1_pid" # # 独自の環境変数を追加してプロセス起動 # echo '---------- set ----------' MY_ENV='my_env' "$basedirpath"/app >/dev/null 2>&1 & app2_pid="$!" # MY_ENV という環境変数を設定しているので表示される # /proc/pid/environ ファイルのデータは ヌル文字 で結合されていることに注意 tr '\0' '\n' < "/proc/$app2_pid/environ" | grep 'MY_ENV' kill -SIGTERM "$app2_pid" # プロセス終了待ち wait "$app1_pid" "$app2_pid"
try-linux/list_proc_environ.sh at master · devlights/try-linux · GitHub
実行すると以下のようになります。
gitpod /workspace/try-linux $ make bash ./main.sh -o ENTER EXAMPLE NAME: proc [INPUT ] proc [TARGET] proc_list_proc_environ [SCRIPT] basic/proc/list_proc_environ.sh ===== START [basic/proc/list_proc_environ.sh] ===== ---------- not set ---------- ---------- set ---------- MY_ENV=my_env ===== END [basic/proc/list_proc_environ.sh] =====
参考情報
LinuxサーバHacks―プロが使うテクニック&ツール100選
- 作者:ロブ フリッケンガー
- 発売日: 2003/11/01
- メディア: 単行本
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場