npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zqw-cli/qenv

v1.0.4

Published

Cross-platform CLI for managing environment variables

Downloads

39

Readme


为什么选 qenv?

在不同操作系统上管理环境变量是件令人头疼的事:Windows 用 setx,macOS/Linux 要编辑 .bashrc.zshrc,项目里还有 .env 文件需要维护……

qenv 将这一切统一为一行命令。

# 不管你在什么平台,设置环境变量永远是这一行
qenv set NODE_ENV production

核心亮点

| 特性 | 说明 | |------|------| | 🌍 跨平台统一 | 同一命令在 Windows / macOS / Linux 上行为一致 | | 📋 Manifest 追踪 | 记录每一个由 qenv 管理过的变量,支持 listdiffclean | | 🐚 Shell 集成 | 通过 qenv init 安装 wrapper,支持 --local 在当前终端立即生效 | | 📁 .env 文件支持 | 用 --file 读写项目级 .env 文件,无需额外工具 | | 📦 批量导入导出 | qenv import / qenv export 快速迁移环境配置 | | 🎨 友好的终端输出 | 彩色图标、表格对齐、敏感值自动脱敏 |


目录


安装

要求: Node.js >= 16

npm install -g @zqw-cli/qenv

安装后即可在任意终端中使用 qenv 命令:

qenv --version
# 1.0.0

快速上手

1. 设置环境变量

# 设置用户级系统环境变量(永久生效,重启终端后可用)
qenv set NODE_ENV production

# 设置后覆盖已有的变量
qenv set NODE_ENV development --overwrite

2. 读取环境变量

qenv get NODE_ENV
# NODE_ENV=production

# 只输出纯值(适合在脚本中使用)
qenv get NODE_ENV --raw
# production

3. 使用 .env 文件

# 写入项目 .env 文件
qenv set DATABASE_URL postgres://localhost/mydb --file

# 写入指定的 .env 文件
qenv set API_KEY sk-xxx --file .env.local

# 查看 .env 文件中的所有变量
qenv list --file .env.local

4. 批量操作

# 从 .env 文件批量导入到系统变量
qenv import .env.prod

# 先预览再导入
qenv import .env.prod --dry-run

# 导出所有 qenv 管理的变量到文件
qenv export .env.backup

5. 查看与维护

# 列出所有由 qenv 管理的变量
qenv list

# 对比 manifest 记录与系统实际值
qenv diff

# 清理已失效的记录
qenv clean

命令参考

💡 每个命令都支持 --help 查看详细用法,例如 qenv set --help

qenv set

设置环境变量。

用法: qenv set <name> <value> [options]

| 选项 | 说明 | |------|------| | --local | 仅在当前 Shell 会话中生效(需先运行 qenv init) | | --system | 设置系统级变量(需管理员/sudo 权限) | | --file [path] | 写入 .env 文件,默认路径为 ./.env | | --json | 将 value 作为 JSON 解析并校验 | | --overwrite | 如果变量已存在,强制覆盖 |

示例:

# 基础用法:设置用户级系统变量(永久)
qenv set NODE_ENV production

# 仅当前终端会话生效(需 qenv init)
qenv set API_KEY sk-xxx --local

# 写入项目 .env 文件
qenv set PORT 3000 --file

# 写入指定 .env 文件
qenv set PORT 3000 --file .env.local

# JSON 值校验
qenv set CONFIG '{"debug":true}' --json

# 覆盖已有变量
qenv set NODE_ENV development --overwrite

行为说明:

  • 默认会检查变量是否已存在,若已存在则提示使用 --overwrite
  • 不带 --file--local 时,变量写入当前用户的系统环境(永久生效)
  • 写入的变量会自动记录到 manifest 中,可通过 qenv list 查看

qenv get

获取环境变量的值。

用法: qenv get <name> [options]

| 选项 | 说明 | |------|------| | --source | 显示变量来源(qenv 管理 / 系统原有 / 文件) | | --file [path] | 从 .env 文件读取,默认路径为 ./.env | | --json | 以 JSON 格式输出 { name, value, source } | | --raw | 仅输出纯值,不带任何前缀(适合 $() 嵌入脚本使用) |

示例:

# 读取系统变量
qenv get NODE_ENV
# NODE_ENV=production

# 查看变量来源
qenv get NODE_ENV --source
# NODE_ENV=production
# ℹ Source: qenv (system)

# 从 .env 文件读取
qenv get DATABASE_URL --file .env.prod

# 纯值输出(适合脚本嵌入)
echo "当前环境: $(qenv get NODE_ENV --raw)"

# JSON 格式
qenv get PORT --json
# {"name":"PORT","value":"3000","source":"qenv (system)"}

行为说明:

  • --raw 模式下,如果变量不存在,进程退出码为 1,stdout 无输出
  • 不加 --raw 时,变量不存在会输出 ⚠ Variable "XXX" not found

qenv remove

删除环境变量。别名:qenv rm

用法: qenv remove <name> [options]

| 选项 | 说明 | |------|------| | --system | 删除系统级变量(需管理员/sudo 权限) | | --local | 从当前 Shell 会话中移除(需 qenv init) | | --file [path] | 从 .env 文件中删除 | | --force | 跳过确认提示,直接删除 | | --all | 配合 --file 使用,清空文件中所有变量 |

示例:

# 删除用户级系统变量(会有确认提示)
qenv remove NODE_ENV

# 跳过确认直接删除
qenv remove NODE_ENV --force

# 从 .env 文件删除
qenv remove DATABASE_URL --file .env.prod

# 清空 .env 文件中所有变量
qenv remove --all --file

# 从当前会话移除(需 qenv init)
qenv remove API_KEY --local

行为说明:

  • 默认删除前会弹出确认提示 (y/N),使用 --force 跳过
  • 删除成功后同时从 manifest 中清除记录

qenv list

列出环境变量。别名:qenv ls

用法: qenv list [options]

| 选项 | 说明 | |------|------| | --all | 列出系统中所有环境变量(等同 printenv) | | --file [path] | 列出 .env 文件中的变量 | | --json | 以 JSON 格式输出 | | --verify | 检验 manifest 记录与系统实际值是否一致 | | --stale | 仅显示已失效的 manifest 记录 |

示例:

# 列出 qenv 管理的变量(默认)
qenv list

# 输出示例:
#   NAME         VALUE              SCOPE    UPDATED
#   ─────────────────────────────────────────────────────
#   NODE_ENV     pro***ion          system   2 days ago
#   API_KEY      sk-***xxx          system   1 hour ago
#   DATABASE_URL (not found) ⚠      system   5 days ago
#
#   ⚠  1 stale entry found. Run `qenv clean` to remove.

# 列出所有系统变量
qenv list --all

# 列出 .env 文件变量
qenv list --file .env.prod

# 仅查看失效记录
qenv list --stale

# JSON 输出
qenv list --json

输出说明:

  • VALUE 列会自动脱敏显示(保留前 3 位和后 3 位,中间用 *** 替代)
  • UPDATED 列显示上次更新的相对时间(如 2 days agojust now
  • 系统中已不存在的变量会显示 (not found) ⚠ 标记
  • --all 模式展示完整值,不做脱敏处理

qenv import

.env 文件批量导入环境变量。

用法: qenv import <file> [options]

| 选项 | 说明 | |------|------| | --local | 导入到当前 Shell 会话(需 qenv init) | | --dry-run | 预览将要导入的变量,不实际执行 | | --overwrite | 覆盖已存在的变量 |

示例:

# 将 .env 文件中的变量导入为系统环境变量
qenv import .env

# 先预览,确认后再操作
qenv import .env.prod --dry-run
# ℹ Preview of import from .env.prod:
#   + NODE_ENV=production
#   + API_KEY=sk-xxx
#   + PORT=3000
#
#   Total: 3 variables

# 覆盖已存在的变量
qenv import .env --overwrite

# 导入到当前会话(需 qenv init)
qenv import .env.dev --local

行为说明:

  • 默认不覆盖已存在的变量,逐条跳过并提示
  • .env 文件格式支持:KEY=VALUE、带引号 KEY="VALUE"、注释 # ...

qenv export

将环境变量导出为 .env 格式。

用法: qenv export [file] [options]

| 选项 | 说明 | |------|------| | --all | 导出系统中所有环境变量 | | --filter <prefix> | 仅导出匹配指定前缀的变量 |

示例:

# 导出 qenv 管理的变量到 stdout
qenv export

# 导出到文件
qenv export .env.backup

# 导出所有系统变量
qenv export env-full.txt --all

# 仅导出特定前缀的变量
qenv export --filter REACT_APP_
qenv export .env.react --filter REACT_APP_

行为说明:

  • 不指定文件时输出到 stdout,可配合管道使用:qenv export | grep NODE
  • 默认只导出 manifest 中跟踪的变量,--all 则导出系统全部

qenv diff

对比 manifest 记录与系统中的实际值。

用法: qenv diff [options]

| 选项 | 说明 | |------|------| | --json | 以 JSON 格式输出对比结果 |

示例:

qenv diff
# 输出示例:
#   NAME         SCOPE  STATUS
#   ─────────────────────────────────────────
#   NODE_ENV     system ✔ in sync
#   API_KEY      system ✔ in sync
#   OLD_VAR      system ✖ missing
#
#   ⚠ 1 variable missing from system. Run `qenv clean` to remove stale entries.

qenv diff --json

状态说明:

| 状态 | 含义 | |------|------| | ✔ in sync | manifest 记录的变量在系统中存在 | | ✖ missing | manifest 中记录了但系统中已不存在 |


qenv clean

清理 manifest 中的失效记录。

用法: qenv clean [options]

| 选项 | 说明 | |------|------| | --force | 跳过确认提示,直接清理 |

示例:

# 交互式清理(有确认提示)
qenv clean
# ℹ Found 2 stale entries:
#   ⚠ OLD_VAR_1
#   ⚠ OLD_VAR_2
#
# Remove these stale entries from manifest? (y/N)

# 跳过确认直接清理
qenv clean --force

qenv init

安装 Shell 集成(wrapper function),以支持 --local 模式。

用法: qenv init [options]

| 选项 | 说明 | |------|------| | --shell <type> | 指定 Shell 类型:bash / zsh / fish / pwsh | | --print | 仅打印 wrapper 代码,不自动安装 | | --uninstall | 从配置文件中移除 wrapper |

示例:

# 自动检测当前 Shell 并安装
qenv init

# 指定 Shell 类型
qenv init --shell zsh

# 只查看代码,不安装
qenv init --print

# 卸载 Shell 集成
qenv init --uninstall

详见 Shell 集成详解


全局选项

以下选项可与任意命令组合使用:

| 选项 | 说明 | |------|------| | -V, --version | 输出版本号 | | -h, --help | 显示帮助信息 | | --no-color | 禁用终端彩色输出 | | --silent | 禁止所有 stdout 输出(仅保留 stderr 错误信息) | | --verbose | 输出调试信息(驱动层调用详情) |

# 无色输出(适合重定向到文件)
qenv list --no-color > vars.txt

# 静默模式(CI 中使用)
qenv set CI true --silent

# 调试模式
qenv set NODE_ENV test --verbose

Shell 集成详解

为什么需要 Shell 集成?

qenv set NAME value 默认将变量写入系统环境(永久但需重启终端),如果你希望变量在当前终端窗口立即可用,需要使用 --local 模式。

然而,一个子进程(qenv CLI)无法直接修改父进程(你的终端)的环境变量。为了解决这个限制,qenv 使用了 shell wrapper + eval 机制:

  1. qenv init 在你的 Shell 配置文件中安装一个 wrapper function
  2. 调用 qenv set NAME value --local 时,wrapper 实际执行的是 qenv --shell-eval set NAME value --local
  3. qenv 在 --shell-eval 模式下只向 stdout 输出一行 shell 表达式(如 export NAME="value"
  4. wrapper 用 eval 执行这行表达式,从而修改当前 Shell 会话的环境

各 Shell 的 wrapper 代码

Bash / Zsh(写入 ~/.bashrc~/.zshrc):

# qenv shell integration
qenv() { eval "$(command qenv --shell-eval "$@")"; }
# end qenv

Fish(写入 ~/.config/fish/config.fish):

# qenv shell integration
function qenv
  eval (command qenv --shell-eval $argv)
end
# end qenv

PowerShell(写入 $PROFILE):

# qenv shell integration
function qenv { $result = & qenv.cmd --shell-eval @args; if ($result) { Invoke-Expression $result } }
# end qenv

手动安装

如果不想自动修改配置文件,可以用 --print 查看代码后手动添加:

qenv init --print

工作原理

平台驱动层

qenv 根据 process.platform 自动选择合适的驱动:

| 平台 | 用户级操作 | 系统级操作 (--system) | |------|-----------|----------------------| | Windows | setx NAME "value"(写入 HKCU\Environment) | reg add HKLM\...\Environment(需管理员) | | macOS | 追加 export NAME="value" # qenv:managed~/.zshrc | 写入 /etc/environment(需 sudo) | | Linux | 追加 export NAME="value" # qenv:managed~/.bashrc | 写入 /etc/environment(需 sudo) | | .env 文件 | 直接读写指定的 .env 文件 | — |

Unix 驱动细节:

  • 使用注释标记 # qenv:managed 管理 Shell 配置文件中的行
  • 更新变量时通过正则精准替换已标记的行,不会产生重复条目
  • 自动检测当前 Shell 类型,选择正确的配置文件

Windows 驱动细节:

  • 用户级变量使用 setx 命令,系统级使用 reg add 操作注册表
  • 设置变量后自动广播 WM_SETTINGCHANGE 消息,通知其他进程刷新环境
  • 自动校验值长度,超过 setx 的 1024 字符限制时提前报错

Manifest 机制

qenv 使用 conf 库将 manifest 持久化到用户配置目录:

| 平台 | 路径 | |------|------| | macOS / Linux | ~/.config/qenv/config.json | | Windows | %APPDATA%\qenv\config.json |

数据结构示例:

{
  "version": 1,
  "vars": {
    "NODE_ENV": {
      "scope": "system",
      "filePath": null,
      "setAt": "2026-03-16T10:00:00Z",
      "updatedAt": "2026-03-16T12:00:00Z",
      "setBy": "[email protected]"
    },
    "DATABASE_URL": {
      "scope": "file",
      "filePath": "D:\\projects\\myapp\\.env",
      "setAt": "2026-03-16T09:00:00Z",
      "updatedAt": "2026-03-16T09:00:00Z",
      "setBy": "[email protected]"
    }
  }
}

字段说明:

| 字段 | 说明 | |------|------| | scope | system(用户级永久)/ system-wide(系统级)/ file(.env 文件) | | filePath | 仅 scope=file 时有值,记录 .env 文件的绝对路径 | | setAt | 首次设置时间(ISO 8601 格式) | | updatedAt | 最近一次更新时间 | | setBy | 写入时的 qenv 版本号 |

⚠️ 重要边界: manifest 仅记录"qenv 操作过哪些变量",不独占管理权。如果用户或其他工具直接修改了同一变量,qenv 不会阻止,但 qenv diff 可以发现变量已被删除(missing)。

Scope 说明

| Scope | 触发方式 | 生效范围 | 持久性 | |-------|---------|---------|--------| | system(默认) | qenv set NAME value | 新终端窗口 | ✅ 永久 | | system-wide | qenv set NAME value --system | 所有用户的新终端 | ✅ 永久 | | session | qenv set NAME value --local | 仅当前终端窗口 | ❌ 关闭即失效 | | file | qenv set NAME value --file | 取决于应用是否读取 | ✅ 文件存在即有效 |


常见用法示例

CI/CD 中批量设置环境变量

# 从密钥管理中导出 .env 文件,然后导入到系统
qenv import .env.ci --overwrite --silent

在脚本中获取值

# Bash / Zsh
DB_HOST=$(qenv get DB_HOST --raw)
echo "连接到数据库: $DB_HOST"
# PowerShell
$dbHost = qenv get DB_HOST --raw
Write-Host "连接到数据库: $dbHost"

在不同 .env 文件间切换

# 查看各环境配置
qenv list --file .env.dev
qenv list --file .env.staging
qenv list --file .env.prod

# 导入开发环境配置到当前会话
qenv import .env.dev --local

导出特定前缀的变量

# 只导出 React 应用相关变量
qenv export .env.react --filter REACT_APP_

# 只导出 AWS 相关变量到 stdout
qenv export --filter AWS_

项目初始化模板

# 为新同事快速搭建开发环境
qenv import .env.example --overwrite
qenv list --verify

定期维护 manifest

# 检查是否有过期的记录
qenv diff

# 自动清理所有失效记录
qenv clean --force

注意事项与限制

Windows 平台

| 限制 | 说明 | |------|------| | setx 字符上限 | 值不能超过 1024 个字符,超出时 qenv 会提前报错 | | 需重启终端 | 通过 setx 设置的变量需要打开新终端窗口才能生效 | | 管理员权限 | --system 模式需要以管理员身份运行终端 |

💡 提示: 使用 --local 模式可以避免重启终端的问题,变量立即在当前窗口生效。

macOS / Linux 平台

| 限制 | 说明 | |------|------| | 需 source 配置 | 修改 .bashrc / .zshrc 后需 source 或重启终端才能生效 | | sudo 权限 | --system 操作 /etc/environment 需要 sudo | | Shell 兼容 | 已内置支持 Bash、Zsh、Fish;其他 Shell 可用 qenv init --print 手动适配 |

通用限制

| 限制 | 说明 | |------|------| | 变量名规则 | 必须匹配 /^[A-Za-z_][A-Za-z0-9_]*$/(字母或下划线开头) | | 不存储值 | manifest 仅记录元信息,不缓存变量的实际值 | | 非独占管理 | 其他工具可修改同一变量,qenv 不阻止但 diff 可检测差异 |


开发指南

环境准备

git clone https://github.com/af-zqw/qenv.git
cd qenv
npm install

📦 npm 包名为 @zqw-cli/qenv,CLI 命令名仍为 qenv

常用命令

| 命令 | 说明 | |------|------| | npm run build | 使用 tsup 构建,输出到 dist/ | | npm run dev | 开发模式(watch,文件变更自动重新构建) | | npm test | 运行 Vitest 单元测试 | | npm link | 本地全局链接,方便开发调试 |

本地调试

# 构建
npm run build

# 直接运行
node dist/index.js --help

# 或全局链接后使用
npm link
qenv --help

技术栈

| 工具 | 用途 | |------|------| | TypeScript | 类型安全的开发语言 | | tsup | 零配置打包,输出 CJS + DTS,自动加 #!/usr/bin/env node | | Commander.js | CLI 框架,链式 API,自动 --help 生成 | | chalk | 终端彩色输出 | | conf | 跨平台 JSON 持久化存储(manifest) | | ora | 终端 spinner 加载动画 | | Vitest | 快速单元测试框架 |

发布到 npm

# prepublishOnly 会自动执行 build + test
npm publish

项目结构

qenv/
├── src/
│   ├── index.ts                 # CLI 入口:注册全部命令 + 全局选项 + --shell-eval 处理
│   ├── commands/
│   │   ├── set.ts               # qenv set — 设置环境变量
│   │   ├── get.ts               # qenv get — 读取环境变量
│   │   ├── remove.ts            # qenv remove (rm) — 删除环境变量
│   │   ├── list.ts              # qenv list (ls) — 列出变量 + 失效标记
│   │   ├── diff.ts              # qenv diff + qenv clean — 对比 & 清理 manifest
│   │   ├── init.ts              # qenv init — 安装/卸载 Shell 集成
│   │   └── import.ts            # qenv import + qenv export — 批量导入导出
│   ├── drivers/
│   │   ├── types.ts             # EnvDriver 接口定义(get/set/remove/list)
│   │   ├── index.ts             # 驱动选择器(根据 process.platform)
│   │   ├── windows.ts           # Windows 驱动(setx / reg add / reg query)
│   │   ├── unix.ts              # Unix 驱动(读写 .bashrc / .zshrc / config.fish)
│   │   └── dotenv.ts            # .env 文件驱动(解析、写入、保留注释)
│   ├── shell/
│   │   ├── detect.ts            # Shell 类型自动检测(bash/zsh/fish/pwsh/cmd)
│   │   └── eval.ts              # --shell-eval 输出 eval 表达式
│   ├── manifest/
│   │   └── index.ts             # Manifest 管理器(基于 conf 库的单例)
│   └── utils/
│       ├── logger.ts            # 统一日志输出(success/warn/error/info/table)
│       ├── validator.ts         # 变量名校验 + .env 解析 + 序列化
│       └── platform.ts          # 平台判断 + 权限检测 + Home 目录
├── tests/
│   ├── validator.test.ts        # 校验器 & .env 解析测试(15 cases)
│   ├── dotenv.test.ts           # .env 驱动集成测试(8 cases)
│   ├── platform.test.ts         # 平台工具测试(2 cases)
│   ├── shell.test.ts            # Shell 检测测试(2 cases)
│   └── manifest.test.ts         # Manifest 结构测试(2 cases)
├── dist/                        # 构建输出(.gitignore)
├── tsup.config.ts               # tsup 构建配置
├── tsconfig.json                # TypeScript 编译配置
├── vitest.config.ts             # Vitest 测试配置
├── package.json                 # 包描述 & 脚本
├── .gitignore
└── README.md                    # 本文档

License

MIT © 2026 af-zqw