{T}

os 系统模块

os 模块是 Node.js 中内置的一个操作系统模块,它主要提供了对系统进行操作的一些方法,如获取内存信息、网络信息、系统名称、系统版本、系统目录等。

在 Node.js 中使用 os 模块之前,首先需要使用 require() 方法将 os 模块引入:

javascript
const os = require("os")

方法速查表

方法返回值类型功能描述
freemem()Number获取系统空闲内存(字节)
totalmem()Number获取系统总内存(字节)
networkInterfaces()Object获取网络接口信息
homedir()String获取用户主目录
tmpdir()String获取临时文件目录
hostname()String获取主机名
type()String获取操作系统类型
platform()String获取操作系统平台
arch()String获取 CPU 架构
release()String获取系统发行版本
version()String获取内核版本
uptime()Number获取系统运行时间(秒)
loadavg()Array获取系统平均负载
cpus()Array获取 CPU 信息
endianness()String获取 CPU 字节序
userInfo()Object获取当前用户信息
getPriority([pid])Number获取进程优先级
setPriority([pid], priority)void设置进程优先级
availableParallelism()Number获取可用并行度(v19.4.0+)

获取内存相关信息

获取系统剩余内存 freemem

通过 os 模块的 freemem() 方法可以获取空闲的系统内存量,该方法返回一个整数(单位:字节)

javascript
os.freemem()

返回值: 返回一个整数,表示空闲的系统内存量(单位:字节)

javascript
const os = require("os")
console.log("剩余内存:", os.freemem(), "B")
// 输出:剩余内存: 4485488640 B

获取系统总内存 totalmem

通过 os 模块的 totalmem() 方法可以获取系统的总内存量,该方法返回一个整数(单位:字节)。

javascript
os.totalmem()

返回值: 返回一个整数,表示系统的总内存量(单位:字节)

javascript
const os = require("os")
console.log("总内存:", os.totalmem(), "B")
// 输出:总内存: 17179869184 B

综合示例:显示系统的内存使用情况

javascript
const os = require("os")

const freeMem = os.freemem() // 剩余内存(字节)
const totalMem = os.totalmem() // 总内存(字节)
const usedMem = totalMem - freeMem // 已使用内存(字节)

// 将单位转换为 GB
const freeGB = (freeMem / 1024 / 1024 / 1024).toFixed(2)
const totalGB = (totalMem / 1024 / 1024 / 1024).toFixed(2)
const usedGB = (usedMem / 1024 / 1024 / 1024).toFixed(2)

// 计算内存使用率
const usageRate = ((usedMem / totalMem) * 100).toFixed(2)

console.log("总内存:", totalGB, "GB")
console.log("已使用内存:", usedGB, "GB")
console.log("剩余内存:", freeGB, "GB")
console.log("内存使用率:", usageRate, "%")

// 输出示例:
// 总内存: 16.00 GB
// 已使用内存: 11.82 GB
// 剩余内存: 4.18 GB
// 内存使用率: 73.88 %

获取网络相关信息

networkInterfaces

使用 os 模块可以获取计算机的网络信息,这需要通过 networkInterfaces() 方法实现,该方法的返回值是一个对象,该对象包含已分配了网络地址的网络接口信息。

语法:

javascript
os.networkInterfaces()

返回值: 返回一个对象,包含网络接口信息

网络接口信息属性说明:

属性类型说明
addressString一个字符串,用于指定分配的网络地址,即 IPv4 或 IPv6
netmaskString一个字符串,指定 IPv4 或 IPv6 网络掩码
familyString指定 Family 的字符串,值为 IPv4IPv6 之一
macString一个字符串,指定网络接口的 MAC 地址
internalBoolean布尔值,如果网络接口是不可远程访问的环回接口或类似接口,则为 true,否则为 false
scopeidNumber一个数字,指定 IPv6 的作用域 ID
cidrString一个字符串,用于指定分配的 IPv4 或 IPv6 地址以及 CIDR 表示法中的路由前缀。如果网络掩码无效,则将其设置为 null

示例:

javascript
const os = require("os")
console.log("该计算机的网络信息如下:\n")
console.log(os.networkInterfaces())

获取本机 IP 地址的实用示例:

javascript
const os = require("os")

function getLocalIP() {
  const interfaces = os.networkInterfaces()
  for (const name of Object.keys(interfaces)) {
    for (const iface of interfaces[name]) {
      // 跳过内部(环回)地址和 IPv6 地址
      if (iface.family === "IPv4" && !iface.internal) {
        return iface.address
      }
    }
  }
  return "127.0.0.1"
}

console.log("本机 IP 地址:", getLocalIP())
// 输出:本机 IP 地址: 192.168.1.104

networkInterfaces() 返回值的完整示例:

javascript
{
  lo0: [
    {
      address: '127.0.0.1',
      netmask: '255.0.0.0',
      family: 'IPv4',
      mac: '00:00:00:00:00:00',
      internal: true,
      cidr: '127.0.0.1/8'
    },
    {
      address: '::1',
      netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
      family: 'IPv6',
      mac: '00:00:00:00:00:00',
      internal: true,
      cidr: '::1/128',
      scopeid: 0
    }
  ],
  en0: [
    {
      address: '192.168.1.104',
      netmask: '255.255.255.0',
      family: 'IPv4',
      mac: '0e:7a:10:d8:77:1c',
      internal: false,
      cidr: '192.168.1.104/24'
    }
  ]
  // ... 其他网络接口
}

获取系统相关目录

获取用户主目录 homedir

通过 os 模块的 homedir() 方法可以获取当前用户的主目录。

语法:

javascript
os.homedir()

返回值: 返回一个字符串,表示当前用户的主目录路径

示例:

javascript
const os = require("os")
console.log("当前用户的主目录为:", os.homedir())
// macOS/Linux 输出:当前用户的主目录为: /Users/zhangzhengyang
// Windows 输出:当前用户的主目录为: C:\Users\username

获取临时文件目录 tmpdir

通过 os 模块的 tmpdir() 方法可以获取本地计算机的临时文件目录。

语法:

javascript
os.tmpdir()

返回值: 返回一个字符串,表示默认的临时文件目录路径

示例:

javascript
const os = require("os")
console.log("当前计算机的临时文件目录为:", os.tmpdir())

// macOS 输出:
// 当前计算机的临时文件目录为: /var/folders/kg/yy1xg95j3mvb05rd1m0r2dh40000gn/T

// Linux 输出:
// 当前计算机的临时文件目录为: /tmp

// Windows 输出:
// 当前计算机的临时文件目录为: C:\Users\username\AppData\Local\Temp

获取系统相关信息

使用 os 模块可以获取与操作系统相关的信息,如主机名、系统名、系统 CPU 架构等。

系统信息方法总览

方法返回值类型说明
hostname()String返回操作系统的主机名
type()String返回操作系统名
platform()String返回编译时的操作系统名
arch()String返回操作系统的 CPU 架构
release()String返回操作系统的发行版本
version()String返回标识操作系统内核版本的字符串
loadavg()Array返回一个包含 1、5、15 分钟平均负载的数组(UNIX 特定,Windows 返回 [0,0,0])
cpus()Array返回一个对象数组,包含所安装的每个 CPU 内核的信息
uptime()Number返回操作系统运行的时间,以秒为单位
endianness()String获取 CPU 的字节序,可能返回的值为 BE(大端字节序)和 LE(小端字节序)
getPriority(pid)Number获取指定进程的调度优先级
setPriority(pid, priority)-为指定的进程设置调度优先级

基础系统信息

hostname - 获取主机名

javascript
const os = require("os")
console.log("当前主机名:", os.hostname())
// 输出:当前主机名: MacBook-Pro.local

type - 获取操作系统类型

javascript
const os = require("os")
console.log("当前操作系统为:", os.type())
// Linux 输出:当前操作系统为: Linux
// macOS 输出:当前操作系统为: Darwin
// Windows 输出:当前操作系统为: Windows_NT

platform - 获取平台名称

javascript
const os = require("os")
console.log("当前操作系统编译时的名称为:", os.platform())
// 可能的值:aix、darwin、freebsd、linux、openbsd、sunos、win32
// macOS 输出:当前操作系统编译时的名称为: darwin

arch - 获取 CPU 架构

javascript
const os = require("os")
console.log("操作系统的 CPU 架构为:", os.arch())
// 可能的值:arm、arm64、ia32、mips、mipsel、ppc、ppc64、s390、s390x、x32、x64
// 输出:操作系统的 CPU 架构为: x64

release - 获取系统发行版本

javascript
const os = require("os")
console.log("当前操作系统的发行版本为:", os.release())
// macOS 输出:当前操作系统的发行版本为: 24.0.0
// Linux 输出:当前操作系统的发行版本为: 5.15.0-91-generic

version - 获取内核版本

javascript
const os = require("os")
console.log("操作系统内核版本:", os.version())
// macOS 输出:操作系统内核版本: Darwin Kernel Version 24.0.0...
// Linux 输出:操作系统内核版本: #1 SMP ...

uptime - 获取系统运行时间

javascript
const os = require("os")
const uptimeSeconds = os.uptime()
const hours = Math.floor(uptimeSeconds / 3600)
const minutes = Math.floor((uptimeSeconds % 3600) / 60)
const seconds = Math.floor(uptimeSeconds % 60)

console.log(`系统运行时间:${hours}小时 ${minutes}分钟 ${seconds}秒`)
// 输出:系统运行时间:66小时 32分钟 1秒

endianness - 获取字节序

javascript
const os = require("os")
console.log("CPU 字节序:", os.endianness())
// 输出:CPU 字节序: LE  (小端字节序)
// 或:CPU 字节序: BE  (大端字节序)

loadavg - 获取系统平均负载

返回一个包含 1、5、15 分钟平均负载的数组。平均负载是 UNIX 特定的概念,在 Windows 上,其返回值始终为 [0, 0, 0]

javascript
const os = require("os")
const loadAvg = os.loadavg()
console.log("系统平均负载:")
console.log("1 分钟:", loadAvg[0])
console.log("5 分钟:", loadAvg[1])
console.log("15 分钟:", loadAvg[2])

// 输出示例:
// 系统平均负载:
// 1 分钟: 2.5
// 5 分钟: 2.1
// 15 分钟: 1.8

cpus - 获取 CPU 信息

返回一个对象数组,包含所安装的每个 CPU 内核的信息。

javascript
const os = require("os")
const cpus = os.cpus()

console.log("CPU 核心数:", cpus.length)
console.log("CPU 详细信息:")
cpus.forEach((cpu, index) => {
  console.log(`核心 ${index + 1}:`)
  console.log("  型号:", cpu.model)
  console.log("  速度:", cpu.speed, "MHz")
  console.log("  时间统计:", cpu.times)
})

// 输出示例:
// CPU 核心数: 12
// CPU 详细信息:
// 核心 1:
//   型号: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
//   速度: 2600 MHz
//   时间统计: { user: 28016960, nice: 0, sys: 19867260, idle: 122183510, irq: 0 }

CPU 时间统计说明:

  • user: 用户模式下的 CPU 时间(毫秒)
  • nice: 低优先级用户模式下的 CPU 时间(毫秒)
  • sys: 系统模式下的 CPU 时间(毫秒)
  • idle: 空闲时间(毫秒)
  • irq: 中断请求时间(毫秒)

计算 CPU 使用率示例:

javascript
const os = require("os")

function getCPUUsage() {
  const cpus = os.cpus()
  let totalIdle = 0
  let totalTick = 0

  cpus.forEach((cpu) => {
    for (const type in cpu.times) {
      totalTick += cpu.times[type]
    }
    totalIdle += cpu.times.idle
  })

  const idle = totalIdle / cpus.length
  const total = totalTick / cpus.length
  const usage = 100 - ~~((100 * idle) / total)

  return usage
}

console.log("CPU 使用率:", getCPUUsage(), "%")

getPrioritysetPriority - 进程优先级

getPriority(pid) - 获取进程优先级

javascript
const os = require("os")
const process = require("process")

// 获取当前进程的优先级
const currentPid = process.pid
const priority = os.getPriority(currentPid)
console.log("当前进程优先级:", priority)
// 输出:当前进程优先级: 0

setPriority(pid, priority) - 设置进程优先级

javascript
const os = require("os")
const process = require("process")

// 设置当前进程的优先级
try {
  // 使用常量设置优先级
  os.setPriority(process.pid, os.constants.priority.PRIORITY_HIGH)
  console.log("进程优先级已设置为 HIGH")

  // 或直接使用数值
  // os.setPriority(process.pid, -14)  // 等同于 PRIORITY_HIGH
} catch (err) {
  console.error("设置优先级失败:", err.message)
}

获取用户信息

userInfo - 获取当前用户信息

返回关于当前有效用户的信息对象。

语法:

javascript
os.userInfo([options])

参数:

  • options (可选):对象,可包含 encoding 属性设置返回字符串的编码

返回值: 返回一个对象,包含用户信息

返回对象属性说明:

属性类型说明
uidNumber用户的数字标识符(UNIX 特有,Windows 返回 -1)
gidNumber用户组的数字标识符(UNIX 特有,Windows 返回 -1)
usernameString用户名
homedirString用户主目录
shellString用户默认 shell(Windows 返回 null)

示例:

javascript
const os = require("os")

const userInfo = os.userInfo()
console.log("用户名:", userInfo.username)
console.log("用户主目录:", userInfo.homedir)
console.log("用户 ID:", userInfo.uid)
console.log("用户组 ID:", userInfo.gid)
console.log("默认 Shell:", userInfo.shell)

// macOS/Linux 输出示例:
// 用户名: zhangzhengyang
// 用户主目录: /Users/zhangzhengyang
// 用户 ID: 501
// 用户组 ID: 20
// 默认 Shell: /bin/zsh

// Windows 输出示例:
// 用户名: username
// 用户主目录: C:\Users\username
// 用户 ID: -1
// 用户组 ID: -1
// 默认 Shell: null

availableParallelism - 获取可用并行度(v19.4.0+)

返回程序应使用的可用并行度(通常为 CPU 核心数)。这是 os.cpus().length 的推荐替代方法,因为它更准确且跨平台兼容性更好。

语法:

javascript
os.availableParallelism()

返回值: 返回一个整数,表示可用的并行度

示例:

javascript
const os = require("os")

// 推荐方式(Node.js v19.4.0+)
const parallelism = os.availableParallelism()
console.log("可用并行度:", parallelism)

// 传统方式(兼容旧版本)
const cpuCount = os.cpus().length
console.log("CPU 核心数:", cpuCount)

// 应用场景:创建 Worker 线程池
const { Worker } = require("worker_threads")
const workerCount = os.availableParallelism?.() || os.cpus().length
console.log(`将创建 ${workerCount} 个 Worker 线程`)

注意: 此方法在 Node.js v19.4.0 及以上版本可用,建议使用时检查版本兼容性。

os 模块常用属性

os 模块中除了上面介绍的方法,还提供了三个常用的属性:EOLdevNullconstants

os.EOL - 行末标志

操作系统特定的行末标志。在 POSIX 系统(Linux、macOS)上是 \n,在 Windows 上是 \r\n

示例:

javascript
const os = require("os")
const fs = require("fs")

// 跨平台写入文件时使用 EOL
const content = `第一行${os.EOL}第二行${os.EOL}第三行`
fs.writeFileSync("test.txt", content)

// 在 Windows 上会写入 \r\n,在 Unix 系统上会写入 \n

os.devNull - 空设备路径

返回空设备的平台特定路径。

  • Windows\\.\nul
  • POSIX(Linux/macOS):/dev/null

示例:

javascript
const os = require("os")
const fs = require("fs")

console.log("空设备路径:", os.devNull)
// macOS/Linux 输出:空设备路径: /dev/null
// Windows 输出:空设备路径: \\.\nul

// 应用场景:丢弃不需要的输出
fs.writeFileSync(os.devNull, "这段内容将被丢弃")

os.constants - 系统常量

os.constants 是一个对象,包含各种系统常量,主要用于系统级操作。

os.constants.signals - 信号常量

用于进程间通信的信号常量列表。

javascript
const os = require("os")
console.log("信号常量示例:")
console.log("SIGTERM:", os.constants.signals.SIGTERM)
console.log("SIGINT:", os.constants.signals.SIGINT)
console.log("SIGKILL:", os.constants.signals.SIGKILL)

os.constants.errno - 错误常量

系统错误码常量列表,用于处理系统级错误。

javascript
const os = require("os")
console.log("错误常量示例:")
console.log("EACCES:", os.constants.errno.EACCES) // 权限被拒绝
console.log("EEXIST:", os.constants.errno.EEXIST) // 文件已存在
console.log("ENOENT:", os.constants.errno.ENOENT) // 文件不存在

os.constants.dlopen - dlopen 常量

动态库加载相关的常量。

javascript
const os = require("os")
console.log("dlopen 常量:", os.constants.dlopen)

os.constants.priority - 优先级常量

进程优先级常量列表,用于 setPriority() 方法。

javascript
const os = require("os")
console.log("优先级常量:", os.constants.priority)

// 输出:
// {
//   PRIORITY_LOW: 19,
//   PRIORITY_BELOW_NORMAL: 10,
//   PRIORITY_NORMAL: 0,
//   PRIORITY_ABOVE_NORMAL: -7,
//   PRIORITY_HIGH: -14,
//   PRIORITY_HIGHEST: -20
// }

优先级说明:

  • PRIORITY_LOW (19): 最低优先级
  • PRIORITY_BELOW_NORMAL (10): 低于正常优先级
  • PRIORITY_NORMAL (0): 正常优先级(默认)
  • PRIORITY_ABOVE_NORMAL (-7): 高于正常优先级
  • PRIORITY_HIGH (-14): 高优先级
  • PRIORITY_HIGHEST (-20): 最高优先级

使用优先级常量设置进程优先级:

javascript
const os = require("os")
const process = require("process")

// 使用常量设置优先级(推荐)
os.setPriority(process.pid, os.constants.priority.PRIORITY_HIGH)

// 或直接使用数值
os.setPriority(process.pid, -14) // 等同于 PRIORITY_HIGH

综合应用示例

系统信息监控脚本

javascript
const os = require("os")

function formatBytes(bytes) {
  return (bytes / 1024 / 1024 / 1024).toFixed(2) + " GB"
}

function formatUptime(seconds) {
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  return `${hours}小时 ${minutes}分钟`
}

console.log("========== 系统信息 ==========")
console.log("主机名:", os.hostname())
console.log("操作系统:", os.type())
console.log("平台:", os.platform())
console.log("架构:", os.arch())
console.log("发行版本:", os.release())
console.log("内核版本:", os.version())
console.log("系统运行时间:", formatUptime(os.uptime()))
console.log("")

console.log("========== 内存信息 ==========")
console.log("总内存:", formatBytes(os.totalmem()))
console.log("剩余内存:", formatBytes(os.freemem()))
console.log("已使用内存:", formatBytes(os.totalmem() - os.freemem()))
const memUsage = (((os.totalmem() - os.freemem()) / os.totalmem()) * 100).toFixed(2)
console.log("内存使用率:", memUsage, "%")
console.log("")

console.log("========== CPU 信息 ==========")
const cpus = os.cpus()
console.log("CPU 核心数:", cpus.length)
console.log("CPU 型号:", cpus[0].model)
console.log("")

console.log("========== 网络信息 ==========")
const interfaces = os.networkInterfaces()
for (const name of Object.keys(interfaces)) {
  console.log(`${name}:`)
  interfaces[name].forEach((iface) => {
    if (iface.family === "IPv4" && !iface.internal) {
      console.log(`  IPv4: ${iface.address}`)
    }
  })
}
console.log("")

console.log("========== 目录信息 ==========")
console.log("用户主目录:", os.homedir())
console.log("临时文件目录:", os.tmpdir())

系统资源监控

javascript
const os = require("os")

function monitorSystem() {
  setInterval(() => {
    const totalMem = os.totalmem()
    const freeMem = os.freemem()
    const usedMem = totalMem - freeMem
    const memUsage = ((usedMem / totalMem) * 100).toFixed(2)

    console.log(`[${new Date().toLocaleTimeString()}] 内存使用率: ${memUsage}%`)

    if (parseFloat(memUsage) > 80) {
      console.warn("⚠️  警告:内存使用率超过 80%!")
    }
  }, 5000) // 每 5 秒检查一次
}

// monitorSystem()  // 取消注释以启用监控

常见问题

Q1: freememtotalmem 返回的字节数太大,如何转换为可读格式?

答: 可以编写工具函数进行转换:

javascript
const os = require("os")

function formatBytes(bytes, decimals = 2) {
  if (bytes === 0) return "0 Bytes"
  const k = 1024
  const sizes = ["Bytes", "KB", "MB", "GB", "TB"]
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i]
}

console.log("总内存:", formatBytes(os.totalmem()))
console.log("剩余内存:", formatBytes(os.freemem()))
// 输出:总内存: 16.00 GB
// 输出:剩余内存: 4.18 GB

Q2: 如何跨平台获取本机 IP 地址?

答: 使用 networkInterfaces() 方法,并过滤出 IPv4 非内部地址:

javascript
const os = require("os")

function getLocalIP() {
  const interfaces = os.networkInterfaces()
  for (const name of Object.keys(interfaces)) {
    for (const iface of interfaces[name]) {
      // 跳过内部地址和 IPv6
      if (iface.family === "IPv4" && !iface.internal) {
        return iface.address
      }
    }
  }
  return "127.0.0.1"
}

console.log("本机 IP:", getLocalIP())

Q3: loadavg 在 Windows 上返回什么?

答: Windows 不支持平均负载概念,os.loadavg() 始终返回 [0, 0, 0]。建议在 Windows 上使用其他方式监控系统负载,如 WMI(Windows Management Instrumentation)。

Q4: 如何判断当前是哪个操作系统?

答: 使用 os.platform()os.type() 方法:

javascript
const os = require("os")

// 方法一:platform()
const platform = os.platform()
if (platform === "win32") {
  console.log("Windows 系统")
} else if (platform === "darwin") {
  console.log("macOS 系统")
} else if (platform === "linux") {
  console.log("Linux 系统")
}

// 方法二:type()
const type = os.type()
// Windows 返回 "Windows_NT"
// macOS 返回 "Darwin"
// Linux 返回 "Linux"

Q5: 如何实现跨平台的换行符处理?

答: 使用 os.EOL 属性:

javascript
const os = require("os")
const fs = require("fs")

// 方式一:拼接字符串
const content = "第一行" + os.EOL + "第二行" + os.EOL + "第三行"

// 方式二:使用数组 join(推荐)
const lines = ["第一行", "第二行", "第三行"]
const text = lines.join(os.EOL)

fs.writeFileSync("output.txt", text)

Q6: userInfohomedir 有什么区别?

答: homedir() 仅返回用户主目录路径,而 userInfo() 返回包含更多用户信息的对象:

javascript
const os = require("os")

// homedir() - 仅返回目录路径
console.log(os.homedir()) // /Users/username

// userInfo() - 返回完整用户信息
console.log(os.userInfo())
// { uid: 501, gid: 20, username: 'username', homedir: '/Users/username', shell: '/bin/zsh' }

注意事项

1. 跨平台兼容性

某些方法在不同平台上的行为可能不同:

方法Windows 行为POSIX 行为
loadavg()返回 [0, 0, 0]返回真实的平均负载
userInfo().uid/gid返回 -1返回真实的用户/组 ID
userInfo().shell返回 null返回默认 shell
cpus()速度可能不准确正常工作

2. 权限要求

以下操作可能需要特定权限:

  • setPriority():设置更高优先级可能需要管理员/root 权限
  • getPriority():获取其他用户进程优先级可能需要权限

3. 性能建议

  • 频繁调用 cpus() 可能影响性能,建议缓存结果
  • 实时监控场景建议设置合理的轮询间隔(如 5-10 秒)
  • 使用 availableParallelism() 替代 cpus().length(Node.js v19.4.0+)

4. 版本兼容性

方法引入版本说明
availableParallelism()v19.4.0获取可用并行度
version()v13.10.0获取内核版本
devNullv16.3.0空设备路径
其他方法v0.1.x基础方法,广泛支持

建议在使用新方法前检查 Node.js 版本:

javascript
const semver = require("semver")
const nodeVersion = process.version

// 条件使用新 API
if (semver.gte(nodeVersion, "19.4.0")) {
  const parallelism = os.availableParallelism()
} else {
  const parallelism = os.cpus().length
}