如何在纯sh(非bash)脚本无dirname时获取脚本所在目录
纯POSIX sh 无外部依赖解决方案
直接替换start-dev.sh内容为以下代码即可,不需要dirname、不需要bash,所有标准sh环境均可运行:
#!/bin/sh # 获取脚本自身所在目录,无任何外部命令依赖 case "$0" in */*) SCRIPT_DIR="${0%/*}" ;; *) SCRIPT_DIR="." ;; esac # 切换到脚本所在目录执行,和手动cd进目录执行行为完全一致 cd "$SCRIPT_DIR" || exit 1 docker-compose -p my-container up -d docker-compose -p my-container exec app bash
实现说明
- 核心逻辑使用POSIX sh标准内置的参数扩展语法
${变量%匹配模式},该语法会删除变量值末尾匹配通配符的最短片段,全程由shell内部完成,不需要调用任何外部命令。 - 针对脚本调用路径
$0做两类分支处理:- 若路径包含
/(比如deployment/start-dev.sh、/opt/proj/deployment/start-dev.sh这类带路径的调用方式),直接截掉最后一个/及后面的脚本文件名,剩余部分就是脚本所在目录 - 若路径不包含
/(比如cd到deployment目录后直接执行./start-dev.sh,或脚本在PATH路径中直接调用),说明脚本所在目录就是当前工作目录,直接赋值为.即可
- 若路径包含
- 拿到脚本目录后先执行
cd切换到对应目录,后续docker-compose命令不需要重复拼接-f参数,和手动进入目录执行的逻辑完全一致,也避免了相对路径拼接可能出现的转义、层级错误问题。
覆盖场景验证
- 项目根目录执行
deployment/start-dev.sh:正常定位到deployment目录完成部署 - 进入deployment目录执行
./start-dev.sh:行为和原脚本完全一致,无兼容问题 - 任意目录下用绝对路径调用脚本:可正确识别脚本所在目录
- 极简sh环境(busybox、dash、ash等):无兼容问题,不依赖任何非内置命令
内容的提问来源于stack exchange,提问作者s3c
相关产品推荐
相关产品推荐

