本文目录导读:

- 方案一:使用 Shell 脚本 + 平台检测(最主流,用于 Linux/macOS/Windows WSL)
- 方案二:使用 Node.js(最灵活,跨平台兼容性最好)
- 方案三:使用 Python(适合自动化运维,跨平台支持好)
- 方案四:Bash 检测 + 回退到 PowerShell(三合一全能方案)
- 推荐的开发工作流
跨平台兼容脚本的核心目标是让同一个脚本文件能够在不同操作系统(Windows、Linux、macOS)以及不同Shell环境(Bash、PowerShell、CMD)下正确执行。
由于不同平台的命令、路径分隔符、环境变量等差异巨大,通常无法用单一“万能”语法实现,最常用的方法是多环境检测 + 条件分支。
以下是最实用的几种跨平台脚本编写方案,按推荐程度排序:
使用 Shell 脚本 + 平台检测(最主流,用于 Linux/macOS/Windows WSL)
这是开发运维中最常见的做法,脚本以 .sh 使用 Bash/Sh语法,通过 uname 检测系统类型。
示例脚本:cross_platform.sh
#!/usr/bin/env bash
# 跨平台兼容脚本示例 (Bash)
set -e # 遇到错误停止执行
# 1. 获取操作系统类型
OS="$(uname -s)"
echo "检测到操作系统: $OS"
# 2. 根据平台执行不同命令
case "$OS" in
Linux*)
echo "执行 Linux 相关操作..."
# 使用 Linux 路径分隔符 /
TARGET_DIR="/opt/myapp"
mkdir -p "$TARGET_DIR"
# 使用 Linux 命令
cp ./config.ini "$TARGET_DIR/"
# 设置执行权限
chmod +x "$TARGET_DIR/app"
;;
Darwin*)
echo "执行 macOS 相关操作..."
TARGET_DIR="/usr/local/myapp"
mkdir -p "$TARGET_DIR"
cp ./config.ini "$TARGET_DIR/"
# macOS 一般不需要 chmod,但如果需要可以加
;;
CYGWIN*|MINGW*|MSYS*)
echo "执行 Windows (Git Bash / Cygwin) 相关操作..."
# 使用 Windows 路径,注意转义反斜杠或使用正斜杠
TARGET_DIR="/c/Program Files/MyApp"
mkdir -p "$TARGET_DIR"
cp ./config.ini "$TARGET_DIR/"
;;
*)
echo "未知操作系统: $OS"
exit 1
;;
esac
echo "所有操作完成。"
优势: 语法简洁,依赖少(只需安装 Git Bash 或 WSL)。 缺点: 不支持原生的 cmd.exe 或 PowerShell(除非用户安装了 Bash环境)。
使用 Node.js(最灵活,跨平台兼容性最好)
如果你的系统安装了 Node.js,这是最可靠的方案,Node.js 内置的 os 模块和 path 模块能完美处理跨平台差异。
示例脚本:cross_platform.js
#!/usr/bin/env node
// 跨平台兼容脚本示例 (Node.js)
const os = require('os');
const path = require('path');
const fs = require('fs');
const { execSync } = require('child_process');
// 1. 获取平台
const platform = os.platform();
console.log(`检测到平台: ${platform}`); // 输出: 'win32', 'darwin', 'linux'
// 2. 使用 path.join 自动处理路径分隔符
// 在 Windows 下会自动变成 \,在 Linux/macOS 下变成 /
const targetDir = path.join(os.homedir(), 'myapp', 'config');
fs.mkdirSync(targetDir, { recursive: true });
// 3. 根据平台执行不同命令
if (platform === 'win32') {
// Windows 特定操作
console.log('执行 Windows 操作...');
execSync('echo %USERNAME%', { stdio: 'inherit' });
// 使用 cmd 命令
execSync('copy config.ini ' + targetDir, { stdio: 'inherit' });
} else if (platform === 'darwin') {
// macOS
console.log('执行 macOS 操作...');
execSync('echo $USER', { stdio: 'inherit' });
execSync(`cp config.ini "${targetDir}/"`, { stdio: 'inherit' });
} else {
// Linux 或其他 Unix-like
console.log('执行 Linux 操作...');
execSync('whoami', { stdio: 'inherit' });
execSync(`cp config.ini "${targetDir}/"`, { stdio: 'inherit' });
}
console.log('所有操作完成。');
优势:
- 处理文件路径、环境变量最安全
- 调用外部命令时,
execSync会自动处理 shell 差异 - 支持异步操作,适合复杂任务
缺点: 需要安装 Node.js 运行环境。
使用 Python(适合自动化运维,跨平台支持好)
Python 也是跨平台脚本的常用选择。
示例脚本:cross_platform.py
#!/usr/bin/env python3
# 跨平台兼容脚本示例 (Python)
import os
import sys
import platform
import subprocess
import shutil
# 1. 获取系统类型
system = platform.system()
print(f"检测到系统: {system}") # 输出: 'Windows', 'Linux', 'Darwin'
# 2. 使用 os.path.join 处理路径
target_dir = os.path.join(os.path.expanduser("~"), "myapp", "config")
os.makedirs(target_dir, exist_ok=True)
# 3. 根据平台执行不同命令
if system == "Windows":
print("执行 Windows 操作...")
# 使用 subprocess 调用 cmd 命令
subprocess.run(["copy", "config.ini", target_dir], shell=True)
# 或者使用 Python 原生方法
shutil.copy("config.ini", target_dir)
elif system == "Darwin":
print("执行 macOS 操作...")
subprocess.run(["cp", "config.ini", target_dir])
else:
print("执行 Linux 操作...")
subprocess.run(["cp", "config.ini", target_dir])
print("所有操作完成。")
优势: 语法清晰,功能强大,适合不依赖 Node.js 的环境。 缺点: 相对 Node.js 稍重一些,但对脚本来说还是轻量级。
Bash 检测 + 回退到 PowerShell(三合一全能方案)
如果你必须支持“双击”运行(Windows用 .bat 或 .ps1,Mac/Linux用 .sh),且希望一个文件工作,可以这样设计:
思路: 文件命名为 .sh,但在头部检测是否在 Windows 下,如果是则调用 PowerShell 执行对应逻辑。
示例:universal.sh
#!/usr/bin/env bash
# 这个脚本会被所有平台尝试执行,如果在 Windows 下双击运行,通常会被 Git Bash 或 WSL 处理。
# 为了兼容 cmd 双击,可以创建一个 .bat 文件跳转,但更常见的是:
# 检测是否是 Windows (MINGW, MSYS, CYGWIN)
if echo "$OSTYPE" | grep -E "msys|cygwin|mingw" > /dev/null 2>&1; then
echo "检测到 Windows 环境,使用 PowerShell 执行..."
# 调用 PowerShell 执行真正的工作
powershell.exe -ExecutionPolicy Bypass -File "universal.ps1"
exit $?
fi
# 下面是 Linux/macOS 版本的逻辑
echo "检测到 Unix-like 环境,执行 Bash 版本..."
# ... 你的 Unix 逻辑 ...
缺点: 文件管理较乱,通常不推荐这种既要又要的方案,更常见的做法是分发包时提供 .sh 和 .bat 两个入口文件。
- 路径分隔符:永远不要硬编码 或 ,用
os.path.join()(Python)、path.join()(Node.js)或变量(Bash)。 - 环境变量:
- Windows:
%USERPROFILE%、%APPDATA% - Unix:
$HOME、$XDG_CONFIG_HOME
- Windows:
- 换行符:
.sh文件必须使用 LF(Unix)换行符,否则 Windows 的 Bash 会报$'\r': command not found,建议使用 VSCode 或 VS 设置右下角为LF。 - 执行权限:在 Unix 上需要
chmod +x script.sh,Git 仓库里保留755权限或通过.gitattributes设置。 - 包管理差异:
- 安装软件:
apt-getvsyumvsbrewvschocovsnpm - 处理方式:用
case语句检测平台后,分别调用对应的包管理器。
- 安装软件:
推荐的开发工作流
- 主力使用 Node.js 或 Python:如果你控制运行环境(如 CI/CD 或企业内部),它们是跨平台的第一选择。
- 如果必须用 Shell:编写
.sh文件,要求用户安装 Git Bash(Windows 下),不要尝试兼容原生的cmd.exe。 - 最终交付:可以同时提供
.sh(Unix 用户用)和.ps1(Windows 用户用)两个版本,共享核心逻辑(比如调用同一个 Python 脚本)。
如果你是代码初学者,建议从 Node.js 脚本 开始写跨平台兼容脚本,它的 os 和 path 模块会让你少掉很多头发。