直接发.sh文件常报Permission denied,因Unix系统需chmod +x设执行权限,Windows需用WSL并终端执行bash deploy.sh;应加环境检查、引号变量、getopts参数解析、版本哈希及git归档发布。

为什么直接发 .sh 文件对方常报 Permission denied
你发过去一个 deploy.sh,对方双击或右键“运行”失败,不是脚本问题,而是 Unix-like 系统默认不执行未设权限的文件。Windows 用户更懵——PowerShell/CMD 根本不认 #!/usr/bin/env bash,连解析都跳过。
实操建议:
- 发之前先用
chmod +x deploy.sh加执行权限(Linux/macOS/WSL 下必须) - Windows 用户若需本地跑,必须走 WSL,且确认
wsl --list --verbose显示已启用、locale输出含UTF-8 - 别依赖“双击运行”:明确告诉对方在终端里执行
bash deploy.sh(绕过权限和 shebang 问题) - 如果脚本要读取当前目录下其他文件(如
config.yaml),提醒对方 cd 进目录再执行,避免路径错误
怎么让脚本在别人机器上不因环境差异崩掉
常见崩点不是语法错,而是 PATH、bash 版本、缺失命令(如 jq、yq)、中文路径或空格参数。硬编码 /bin/bash 在 macOS 或 Alpine 容器里直接 No such file or directory。
实操建议:
- shebang 必须用
#!/usr/bin/env bash,不是#!/bin/bash - 开头加环境检查段落:
#!/usr/bin/env bash set -euo pipefail command -v jq >/dev/null || { echo "jq is required"; exit 1; } [[ -f ./config.yaml ]] || { echo "config.yaml missing"; exit 1; } - 所有变量引用强制加双引号:
echo "$INPUT_DIR",否则含空格路径必炸 - 避免
source ~/.bashrc:对方环境不一定有该文件,改用显式导出:export PATH="/opt/bin:$PATH"
怎么嵌入说明、参数提示和快速帮助
别人拿到脚本第一反应是“这玩意儿怎么用”,而不是翻文档。VSCode 里写完不加 help,等于没写完。
实操建议:
- 用
getopts解析参数,并内置-h逻辑,例如:usage() { echo "Usage: $0 [-e ENV] [-d] [-h]" echo " -e ENV target environment (prod/staging)" echo " -d dry-run mode" echo " -h show this help" } while getopts "e:d:h" opt; do case $opt in e) ENV="$OPTARG" ;; d) DRY_RUN=1 ;; h) usage; exit 0 ;; esac done - 把关键说明写进注释区,VSCode 高亮后一目了然;但别只靠注释——运行
./script.sh -h必须能立刻看到 - 复杂脚本可在开头加一行
# vim: set ft=sh:,防止 VSCode 错判语言模式导致高亮失效
怎么避免共享后被误改、误删或版本混乱
运维脚本一旦被随手改两行又传出去,后续排查会变成灾难。你发的是 v1.2,对方用的可能是“我昨天改过的版本”,没人知道谁动了哪。
实操建议:
- 脚本头部固定加版本和哈希:
# VERSION: v1.2.0 # SHA256: a1b2c3... (run: sha256sum $0)
- 用
git archive打包发布,而非直接发单个文件:git archive --format=zip --output=deploy-v1.2.zip HEAD -- scripts/deploy.sh - 如果走邮件或 IM 发送,附上校验命令:
sha256sum deploy.sh,并注明预期值 - VSCode 中禁用自动保存格式化(尤其对
if和case结构),避免协作时被 shfmt 意外重排破坏可读性
真正难的不是写脚本,是让脚本能被别人安全、确定、无歧义地执行。每次发之前多花 30 秒加个 set -euo pipefail 和 -h 提示,比事后远程 debug 两小时强得多。











