目录
兼容性
概念
连接符
wait vs sleep
PID = Process ID:进程ID
echo ≈ print
#! vs #
常用
实战:Node.js
【项目】环境参数、变量:多环境本地开发配置
【系统】终端:Gateway(网关)服务
兼容性
| Linux (bash/sh/zsh) | ✅ 完全适用 | 标准 Shell 环境 |
| macOS (zsh/bash) | ✅ 大部分适用 | 部分命令参数略有差异(如 sed -i 需要备份后缀) |
| Windows (CMD) | ❌ 不适用 | 使用完全不同的命令(dir vs ls) |
| Windows (PowerShell) | ⚠️ 部分适用 | 支持 ls、cat 等别名,但底层机制不同 |
| Windows (WSL/Git Bash) | ✅ 适用 | 模拟 Linux 环境 |
| Dockerfile | ⚠️ 有限适用 | 仅 RUN/CMD 内可使用,且取决于基础镜像的 Shell |
Shell 命令语言(bash/sh)主要在 Unix-like 系统(Linux、macOS、WSL)中通用
Dockerfile 是一种声明式配置语言,内部嵌套使用 Shell 命令
跨平台问题:写脚本时需要考虑目标环境(例如用 python 而不是 python3 这种差异)
如果想让 Shell 脚本在不同终端都适用,建议:使用 POSIX 标准语法(避免 bash 特有特性)
-
或用 Python 等真正的跨平台语言
概念
man test 查看完整文档(Linux/Mac)
连接符
| 顺序/逻辑控制 | |||
| ; 或直接换行 | 顺序执行符 | 前者结束(无论成败)则执行后者 | cmd1 ; cmd2 |
| && | 逻辑与 | 前者成功才执行后者 | make && make install |
| || | 逻辑或 | 前者失败才执行后者 | make || echo "Failed" |
| 后台/异步控制 | |||
| & | 后台运行符 | 前者后台运行,不等待立即执行后者 | server & client |
| 数据流控制 | |||
| | | 管道符 | 把前者的输出作为后者的输入 | cat log.txt | grep "error" |
| 其他常用 | |||
| # | 注释符 | 其后的内容为注释,不执行 | # 这是注释 |
| \\ | 换行转义符 | 将下一行拼接为同一命令 | echo "hello \\ world" |
wait vs sleep
sleep time #等time秒 wait $PID # 等进程结束
PID = Process ID:进程ID
$$ # 当前 Shell 的 PID
$! # 最后一个后台进程的 PID
$? # 上一个命令的退出码(0=成功)
ps aux | grep node # 可以看到所有进程和 PID
kill 12345 # 通过 PID 杀死进程
echo $! # 输出刚启动的进程 PID
echo ≈ print
输出内容到终端(类似 console.log 或 print)
echo "Hello World" # 输出: Hello World echo "错误信息" >&2 # 输出到错误流 echo -n "不换行" # -n 参数不换行 echo $VAR # 输出变量值
#! vs #
-
普通 # 开头的行 → 注释,完全忽略
-
第一行的 #! → Shebang,告诉系统用哪个程序执行脚本
#!/usr/bin/env zsh
#指定zsh执行
常用
| cat | Concatenate | 连接/查看文件 | cat file.txt | 查看文件内容或合并多个文件 |
| cd | Change Directory | 切换目录 | cd /home/user | 进入指定目录 |
| grep | Global Regular Expression Print | 全局正则匹配打印 | grep "text" file.txt | 在文件中搜索匹配的文本模式 |
| Tab 补全 | Tab Completion | 自动补全 | 输入 cd /ho 后按 Tab | 自动补全文件/目录名,减少输入错误 |
| ll | Long Listing (alias) | 详细列表 | ll | 列出文件详细信息(权限、大小、时间等) |
| ls | List Segments/List | 列出目录内容 | ls | 显示当前目录下的文件和文件夹 |
| ll -al | Long Listing – All Long | 显示所有详细列表 | ll -al | 列出所有文件(包括隐藏文件)的详细信息 |
| pwd | Print Working Directory | 打印当前工作目录 | pwd | 显示当前所在的绝对路径 |
| mkdir | Make Directory | 创建目录 | mkdir a/b/c | 创建新目录,若目录已存在则报错 |
| mkdir -p | Make Directory – Parents | 递归创建目录 | mkdir -p a/b/c | 自动创建路径中所有缺失的父目录,若目录已存在则静默跳过 |
| cp | Copy | 复制文件 | cp file1.txt file2.txt | 复制文件,若目标已存在则覆盖(不询问) |
| cp -r | Copy – Recursive | 递归复制目录 | cp -r sourcedir/ destdir/ | 复制整个目录(包含所有子文件和子文件夹) |
实战:Node.js
在 Node.js 项目中,package.json 里的 "scripts" 对象就是一个“快捷键映射表”。
{
"main": "index.js",
"scripts": {
"start": "node index.js",
"setup": "node setup.js",
"report": "node weeklyReport.js",
"sync": "npm run setup && npm run start && npm run report"
},
npm run start (简写为 npm start)是一个快捷命令(别名)。npm 就会在后台执行真正的命令:node index.js(即运行项目根目录下的 index.js 文件)。
【项目】环境参数、变量:多环境本地开发配置
"scripts": {
"dev:test": "cross-env BUILD_ENV=test NODE_OPTIONS=–openssl-legacy-provider webpack-dev-server –inline –progress –config build/webpack.dev.conf.js",
}
-
cross-env:这是一个跨平台的工具。因为 Windows 和 Mac/Linux 设置环境变量的语法不一样,用它能保证在所有电脑上都能成功设置后面的变量。
-
BUILD_ENV=test / sandbox / prod:唯一的变量! 运行在测试环境/沙箱环境/生产环境,调对应环境的后端接口 API。”
-
NODE_OPTIONS=–openssl-legacy-provider:这是一个兼容性补丁。说明你的项目较老(比如 Webpack 3/4),而你电脑的 Node.js 版本较新(Node 17+),不加这一句项目会直接报错崩掉。
-
webpack-dev-server –config …:这是真正干活的启动命令。利用 Webpack 启动一个本地开发服务器(支持热更新,代码改了浏览器自动刷新)。
【系统】终端:Gateway(网关)服务
run.sh
.sh 是 Shell 脚本(Shell Script)的标准文件扩展名。 不过需要说明的是,虽然后缀是 .sh,但具体用什么 Shell 解释器执行,取决于脚本内部第一行(Shebang)。比如你这个脚本的第一行是:
#!/usr/bin/env zsh
这代表它实际上指定了用 zsh 来执行,而不是最古老的 sh 或常见的 bash。
#!/usr/bin/env zsh
# Load nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"
# 使用子 Shell 执行,确保执行完(或中断后)回到原目录
cd ../../ && nvm use 22 && PNPM_CONFIG_BLOCK_EXOTIC_SUBDEPS=false OPENCLAW_FORCE_BUILD=1 PROJECT_MOCK_AUTH=1 node scripts/run-node.mjs gateway
加载环境: 寻找并加载 NVM(Node Version Manager),确保终端可以使用 nvm 命令。
切换目录: cd ../../ 让终端向上跳两级目录(去到项目的根目录)。
切换 Node 版本: nvm use 22 自动把当前 Node.js 环境切换到大版本 22。
注入环境变量并运行: 后面那一长串是大写字母的是环境变量,用来临时改变程序的行为,最后用 node 执行了核心脚本。
-
PNPM_CONFIG_BLOCK_EXOTIC_SUBDEPS=false:允许 pnpm 安装或使用一些非标准的依赖项。
-
OPENCLAW_FORCE_BUILD=1:强制重新编译/构建 OpenClaw(可能涉及一些 C++ 原生模块或前端资源)。
-
PROJECT_MOCK_AUTH=1:开启“PROJECT”服务的 Mock(模拟)身份验证,研发阶段不需要真的去走登录鉴权流程。
-
node scripts/run-node.mjs gateway:用 Node 运行 run-node.mjs 脚本,并传入参数 gateway,正式把网关服务跑起来。




