404 Not Found

404 Not Found


nginx

`os` モジュールと `process` モジュール:システム情報とプロセス制御

アリスは、数十台のサーバーの管理を担当するDevOpsエンジニアです。新しいアプリケーションをデプロイするたびに、サーバーに手動でログインしてCPUコア数、利用可能なメモリ、OSのバージョンを確認し、環境変数に基づいて設定を切り替える必要があります。ある日の午前3時、緊急のデプロイ中に、手動での確認作業でメモリ不足の問題を見逃してしまい、デプロイが失敗してしまいました。そこで彼女は、ワンクリックでサーバーのリソース情報や環境情報を取得できる自動検出スクリプトをNode.jsで作成し、今後のデプロイが円滑に行われるようにすることにしました。

1. 学習内容


2. os モジュール:システム情報の収集

(1) CPUおよびメモリの情報

os.cpus() は CPU コアの詳細情報を配列として返します。os.totalmem()os.freemem() は、それぞれ総メモリ容量と使用可能メモリ容量を(バイト単位で)返します。

▶ 例:サーバーのCPUとメモリの確認

JAVASCRIPT
const os = require('os');

const cpus = os.cpus();
console.log(`CPU Number of cores: ${cpus.length}`);
console.log(`CPU Model: ${cpus[0].model}`);

const totalMem = os.totalmem();
const freeMem = os.freemem();
const usedPercent = ((totalMem - freeMem) / totalMem * 100).toFixed(1);

console.log(`Total Memory: ${(totalMem / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Available memory: ${(freeMem / 1024 / 1024 / 1024).toFixed(2)} GB`);
console.log(`Memory Usage: ${usedPercent}%`);
TEXT
CPU Number of cores: 8
CPU Model: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
Total Memory: 15.88 GB
Available memory: 6.23 GB
Memory Usage: 60.7%

(2) オペレーティングシステムの識別子

os.platform() はプラットフォーム識別子(例:win32linuxdarwin)を返します。os.type() はオペレーティングシステムの名前を返し、os.arch() は CPU アーキテクチャを返し、os.hostname() はホスト名を返します。

▶ 例:オペレーティングシステムの情報の取得

JAVASCRIPT
const os = require('os');

console.log(`Platform: ${os.platform()}`);
console.log(`System Type: ${os.type()}`);
console.log(`CPU Architecture: ${os.arch()}`);
console.log(`Hostname: ${os.hostname()}`);
console.log(`System Version: ${os.version()}`);
TEXT
Platform: linux
System Type: Linux
CPU Architecture: x64
Hostname: web-server-01
System Version: #1 SMP Thu Jan 1 00:00:00 UTC 2026

(3) ユーザーおよびディレクトリ情報

os.userInfo() は現在のユーザー情報を返します。os.homedir() はユーザーのホームディレクトリを返します。os.tmpdir() は一時ファイルディレクトリを返します。

▶ 例:ユーザーおよびディレクトリ情報の取得

JAVASCRIPT
const os = require('os');

const userInfo = os.userInfo();
console.log(`Username: ${userInfo.username}`);
console.log(`Home Directory: ${os.homedir()}`);
console.log(`Shell: ${userInfo.shell}`);
console.log(`Temporary Directory: ${os.tmpdir()}`);
TEXT
Username: alice
Home Directory: /home/alice
Shell: /bin/bash
Temporary Directory: /tmp

(4) ネットワークインターフェース情報

os.networkInterfaces() すべてのネットワークインターフェースに関する詳細情報(IPアドレス、MACアドレス、アドレスファミリーなど)を返します。

▶ 例:ネットワークインターフェースの表示

JAVASCRIPT
const os = require('os');

const interfaces = os.networkInterfaces();
for (const [name, addrs] of Object.entries(interfaces)) {
  for (const addr of addrs) {
    if (addr.family === 'IPv4' && !addr.internal) {
      console.log(`${name}: ${addr.address} (${addr.family})`);
    }
  }
}
TEXT
eth0: 192.168.1.100 (IPv4)
wlan0: 10.0.0.5 (IPv4)

(5) 一般的なOSメソッドのクイックリファレンス

メソッド 戻り値の型 目的
os.cpus() object[] CPUコア情報配列
os.totalmem() number 総メモリ(バイト)
os.freemem() number 使用可能メモリ (バイト)
os.platform() string プラットフォーム識別子 (win32/linux/darwin)
os.type() string オペレーティングシステムの名称
os.arch() string CPUアーキテクチャ (x64/arm64)
os.hostname() string ホスト名
os.userInfo() object 現在のユーザー情報
os.homedir() string ユーザーのホームディレクトリのパス
os.tmpdir() string 一時ファイルのディレクトリパス
os.networkInterfaces() object ネットワークインターフェース情報
os.uptime() number システムの稼働時間(秒)
os.loadavg() number[] 平均システム負荷(1分/5分/15分)
os.EOL string 改行定数
os.devNull string デバイスパスが空です

3. process モジュール:プロセス制御

(1) コマンドライン引数 process.argv

process.argv は配列です。argv[0] は Node.js 実行ファイルへのパス、argv[1] は実行されるスクリプトへのパスであり、その後の要素は渡されたコマンドライン引数です。

100%
flowchart TD
    A["Command-Line Input<br/>node app.js --env prod --port 3000"] --> B["process.argv Array"]
    B --> C["argv[0]: Node.js Path<br/>/usr/local/bin/node"]
    B --> D["argv[1]: Script Path<br/>/home/alice/app.js"]
    B --> E["argv[2]: --env"]
    B --> F["argv[3]: prod"]
    B --> G["argv[4]: --port"]
    B --> H["argv[5]: 3000"]
    E --> I["Parameter Parsing Logic"]
    G --> I
    I --> J["{ env: 'prod', port: '3000' }"]

▶ 例:コマンドライン引数の解析

JAVASCRIPT
function parseArgs(argv) {
  const args = {};
  for (let i = 2; i < argv.length; i++) {
    if (argv[i].startsWith('--')) {
      const key = argv[i].slice(2);
      const value = argv[i + 1] && !argv[i + 1].startsWith('--')
        ? argv[++i]
        : true;
      args[key] = value;
    }
  }
  return args;
}

const config = parseArgs(process.argv);
console.log(config);
BASH
node cli.js --env production --port 8080 --verbose
TEXT
{ env: 'production', port: '8080', verbose: true }

(2) process.env 環境変数

process.env すべての環境変数のキーと値のペアが含まれており、デプロイスクリプトが実行環境を判別するための中心的な基盤となります。

▶ 例:環境変数の読み取りと設定

JAVASCRIPT
console.log(`NODE_ENV: ${process.env.NODE_ENV || 'development'}`);
console.log(`PATH: ${process.env.PATH}`);

process.env.APP_MODE = 'production';
console.log(`APP_MODE: ${process.env.APP_MODE}`);
TEXT
NODE_ENV: development
PATH: /usr/local/bin:/usr/bin:/bin
APP_MODE: production

(3) プロセスの終了と作業ディレクトリ

process.exit(code) プロセスを終了します(0は成功、0以外の場合は失敗を示します)、process.cwd() 現在の作業ディレクトリに戻ります。

▶ 例:条件付き終了とディレクトリチェック

JAVASCRIPT
const requiredEnv = ['DATABASE_URL', 'APP_SECRET'];
const missing = requiredEnv.filter(key => !process.env[key]);

if (missing.length > 0) {
  console.error(`Missing required environment variables: ${missing.join(', ')}`);
  process.exit(1);
}

console.log(`Working Directory: ${process.cwd()}`);
console.log(`Process ID: ${process.pid}`);
console.log(`Runtime: ${process.uptime().toFixed(0)} seconds`);
TEXT
Missing required environment variables: DATABASE_URL, APP_SECRET

(4) 標準ストリーム:stdin / stdout / stderr

process.stdoutprocess.stderr は書き込み可能なストリームであるのに対し、process.stdin は端末とのやり取りに使用される読み取り専用のストリームです。

▶ 例:標準入力と標準出力の使用

JAVASCRIPT
process.stdout.write('Please enter your name: ');

process.stdin.once('data', (data) => {
  const name = data.toString().trim();
  process.stdout.write(`Hello, ${name}!\n`);
  process.exit(0);
});
TEXT
Please enter your name: Alice
Hello, Alice!

(5) process.nextTick()

process.nextTick() コールバックをマイクロタスクキューに追加します。コールバックは、現在の処理が完了した後、I/O イベントが発生する前に実行されます。これは、非同期処理が期待される順序で進行するようにするために、よく使用されます。

▶ 例:nextTickの実行順序

JAVASCRIPT
console.log('1 - Synchronize Code');

process.nextTick(() => {
  console.log('3 - nextTick callback');
});

console.log('2 - Synchronize Code');

setImmediate(() => {
  console.log('5 - setImmediate');
});

Promise.resolve().then(() => {
  console.log('4 - Promise then');
});
TEXT
1 - Synchronize Code
2 - Synchronize Code
3 - nextTick callback
4 - Promise then
5 - setImmediate

(6) 一般的なプロセス特性および手法のクイックリファレンス

プロパティ/メソッド 目的
process.argv string[] コマンドライン引数の配列
process.env object Environment Variable Object
process.exit(code) 方法 プロセスの終了
process.cwd() コマンド 現在の作業ディレクトリに戻る
process.pid number 現在のプロセスID
process.uptime() 手法 処理時間 (秒)
process.stdin ReadStream 標準入力ストリーム
process.stdout WriteStream 標準出力ストリーム
process.stderr WriteStream 標準エラーストリーム
process.nextTick(cb) 手法 マイクロタスクのスケジューリング
process.platform string 動作プラットフォーム
process.version string Node.jsのバージョン
process.versions object コンポーネントのバージョン情報
process.kill(pid) メソッド プロセスにシグナルを送信する
process.title string プロセスタイトル

4. クロスプラットフォームの定数とパスの取り扱い

(1) 改行とパス区切り文字

改行やパス区切り文字はオペレーティングシステムによって異なるため、これらをハードコーディングすると、クロスプラットフォームの問題を引き起こす可能性があります。

▶ 例:os.EOL と os.sep の使用

JAVASCRIPT
const os = require('os');
const path = require('path');

const lines = ['First line', 'Second line', 'Third line'].join(os.EOL);
console.log('Escaping Line Breaks:', JSON.stringify(os.EOL));
console.log('Path separator:', os.sep);
console.log('path.join Results:', path.join('src', 'utils', 'index.js'));
TEXT
Escaping Line Breaks: "\n"
Path separator: /
path.join Results: src/utils/index.js

(2) クロスプラットフォームのパスと改行定数の比較

定数 Windows の値 POSIX の値 用途
os.EOL \r\n \n 行末
os.sep \ / パス区切り文字
path.sep \ / パス区切り文字(パスモジュール)
os.devNull nul /dev/null デバイスパスが空です
path.delimiter ; : PATH 環境変数の区切り文字

5. 環境変数の管理:.env と dotenv

(1) dotenv ライブラリの基本的な使い方

dotenv ファイルから .env ファイルへ環境変数を読み込むことは、プロジェクト構成を管理するための業界標準の手法です。

▶ 例:dotenv を使用して .env ファイルを読み込む

.env ファイルを作成します:

TEXT
NODE_ENV=production
DATABASE_URL=postgresql://db.example.com:5432/myapp
APP_SECRET=my-super-secret-key
APP_PORT=3000

コードを読み込みます:

JAVASCRIPT
require('dotenv').config();

console.log(`Environment: ${process.env.NODE_ENV}`);
console.log(`Database: ${process.env.DATABASE_URL}`);
console.log(`Port: ${process.env.APP_PORT}`);
TEXT
Environment: production
Database: postgresql://db.example.com:5432/myapp
Port: 3000

(2) 環境変数の設定方法の比較

メソッド 適用範囲 永続性 ユースケース
シェルの一時設定 (export KEY=val) 現在のターミナルセッション セッション終了時に消える 一時的なデバッグ
.env ファイル + dotenv 現在の Node プロセス ファイルの永続化 プロジェクト開発
システム環境変数 グローバル(ユーザー/システム) 永続的 サーバーへの展開
Docker ENV / env-file コンテナ内部 コンテナのライフサイクル コンテナ化されたデプロイ
CI/CDプラットフォームの設定 CI/CDパイプライン パイプライン内 継続的インテグレーション

(3) 環境変数の安全な読み取り

▶ 例:検証付きで環境変数を読み込む

JAVASCRIPT
function getEnv(key, options = {}) {
  const value = process.env[key];

  if (value === undefined) {
    if (options.required) {
      throw new Error(`Environment Variables ${key} It is necessary`);
    }
    return options.default ?? null;
  }

  if (options.type === 'number') {
    const num = Number(value);
    if (isNaN(num)) throw new Error(`Environment Variables ${key} It must be a number`);
    return num;
  }

  if (options.type === 'boolean') {
    return value === 'true' || value === '1';
  }

  return value;
}

const port = getEnv('APP_PORT', { default: 3000, type: 'number' });
const debug = getEnv('DEBUG', { default: false, type: 'boolean' });
const dbUrl = getEnv('DATABASE_URL', { required: true });

6. 包括的な例:システム診断 CLI ツール

完全なCLIツールを構築する:OS・メモリ・CPUを検出 → 環境変数を読み込む → 出力レポートをフォーマットする。

▶ 例:syscheck.js

JAVASCRIPT
const os = require('os');

function parseArgs(argv) {
  const args = {};
  for (let i = 2; i < argv.length; i++) {
    if (argv[i].startsWith('--')) {
      const key = argv[i].slice(2);
      const value = argv[i + 1] && !argv[i + 1].startsWith('--')
        ? argv[++i] : true;
      args[key] = value;
    }
  }
  return args;
}

function formatBytes(bytes) {
  const units = ['B', 'KB', 'MB', 'GB'];
  let i = 0;
  let size = bytes;
  while (size >= 1024 && i < units.length - 1) {
    size /= 1024;
    i++;
  }
  return `${size.toFixed(2)} ${units[i]}`;
}

function getSystemInfo() {
  const cpus = os.cpus();
  const totalMem = os.totalmem();
  const freeMem = os.freemem();
  return {
    hostname: os.hostname(),
    platform: os.platform(),
    arch: os.arch(),
    osType: os.type(),
    cpuModel: cpus[0].model,
    cpuCores: cpus.length,
    totalMemory: formatBytes(totalMem),
    freeMemory: formatBytes(freeMem),
    memUsage: ((totalMem - freeMem) / totalMem * 100).toFixed(1) + '%',
    uptime: (os.uptime() / 3600).toFixed(1) + ' hours'
  };
}

function getEnvInfo(keys) {
  const result = {};
  for (const key of keys) {
    result[key] = process.env[key] || '(Not set)';
  }
  return result;
}

function printReport(sys, env) {
  const sep = '='.repeat(48);
  console.log(`\n${sep}`);
  console.log('  System Diagnostic Report');
  console.log(`${sep}`);
  console.log(`  Hostname     : ${sys.hostname}`);
  console.log(`  Platform       : ${sys.platform} / ${sys.arch}`);
  console.log(`  Operating System   : ${sys.osType}`);
  console.log(`  CPU        : ${sys.cpuModel}`);
  console.log(`  CPU Number of cores : ${sys.cpuCores}`);
  console.log(`  Total Memory     : ${sys.totalMemory}`);
  console.log(`  Available memory   : ${sys.freeMemory}`);
  console.log(`  Memory Usage : ${sys.memUsage}`);
  console.log(`  Runtime   : ${sys.uptime}`);
  console.log(`${sep}`);
  console.log('  Environment Variables');
  console.log('-'.repeat(48));
  for (const [key, val] of Object.entries(env)) {
    console.log(`  ${key.padEnd(20)} : ${val}`);
  }
  console.log(`${sep}\n`);
}

const args = parseArgs(process.argv);
const envKeys = args.envKeys
  ? args.envKeys.split(',')
  : ['NODE_ENV', 'HOME', 'PATH', 'SHELL'];
const sys = getSystemInfo();
const env = getEnvInfo(envKeys);
printReport(sys, env);
BASH
node syscheck.js --envKeys NODE_ENV,APP_PORT,DATABASE_URL
TEXT
================================================
  System Diagnostic Report
================================================
  Hostname     : web-server-01
  Platform       : linux / x64
  Operating System   : Linux
  CPU        : Intel(R) Xeon(R) CPU E5-2680 v4
  CPU Number of cores : 8
  Total Memory     : 15.88 GB
  Available memory   : 6.23 GB
  Memory Usage : 60.7%
  Runtime   : 72.5 hours
================================================
  Environment Variables
------------------------------------------------
  NODE_ENV             : production
  APP_PORT             : (Not set)
  DATABASE_URL         : (Not set)
================================================

❓ よくある質問

Q process.argv[0] と process.argv[1] は、それぞれ何ですか?
A argv[0] は Node.js 実行ファイルへのパス(例:/usr/local/bin/node)であり、argv[1] は実行中のスクリプトファイルへのパス(例:/home/alice/app.js)です。ユーザーが実際に指定した引数は argv[2] から始まります。
Q 環境変数を安全に読み取るにはどうすればよいですか?
A 常にデフォルト値を指定するか、変数が存在するかどうかを確認してください。数値型の場合は変換と検証を行い、.env ファイルの管理には dotenv を使用してください。また、.env ファイルをバージョン管理システムにコミットしてはいけません。
Q os.freemem() はどのような単位で値を返しますか?
A バイト数を返します。結果を GB で表示するには、手動で 1073741824(つまり 1024 × 1024 × 1024)で割る必要があります。あるいは、書式設定関数を使用して値を自動的に変換することもできます。
Q Node.js でユーザー入力を読み取るにはどうすればよいですか?
A process.stdin 読み取りストリームを data イベントリスナーと組み合わせて使用するか、readline モジュールが提供する行単位の読み取りインターフェースを使用できます。readline は、対話型の Q&A シナリオに適しています。
Q なぜ process.exit() は注意して使用すべきなのでしょうか?
A process.exit() は、保留中のすべてのコールバック、I/O 操作、およびクリーンアップ処理をスキップしてプロセスを即座に終了させるため、データの損失やリソースの解放漏れにつながる可能性があります。イベントループが自然に終了するようにすることを優先すべきです。
Q process.nextTick()setImmediate() の違いは何ですか?
A nextTick コールバックはマイクロタスクキューにあり、現在の操作の直後に実行され、すべての I/O 操作よりも優先されます。setImmediateはマクロタスクキューにあり、I/Oイベントループフェーズ中に実行されます。なお、nextTickの方が優先度が高くなります。
Q dotenv用の.envファイルはどこに配置すべきですか?
A デフォルトでは、プロジェクトのルートディレクトリに配置されます。config({ path: 'custom/path' }) を使用してパスを指定することもできます。機密情報が漏洩しないよう、必ず .env.gitignore に追加してください。

📖 まとめ


📝 練習問題

  1. 現在のシステムのCPUコア数、総メモリ容量(GB)、空きメモリ容量(GB)、およびメモリ使用率(%)を出力するスクリプトを作成してください。
  2. process.argv を使用して、--add--sub--mul の 3 つの演算をサポートする、簡単なコマンドライン電卓を実装してください。
  3. データベースの接続情報を保存するための .env ファイルを作成し、dotenv を使用して読み込み、スクリプト内で安全に読み込む(デフォルト値を指定する)
  4. 現在のプラットフォームが Windows であるかどうかを確認する関数を実装してください。Windows の場合は改行文字 \r\n を使用し、そうでない場合は \n を使用してください。
  5. メモリ使用量を監視し、90%を超えた場合にstderrに警告メッセージを出力するスクリプトを作成してください。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%