Ubuntu 遇到 bin/stop.sh: 52: kill: No such process和bin/stop.sh: 58: [: unexpected operator的问题

本文讲述了在Ubuntu系统中遇到bin/stop.sh脚本运行时的错误,如kill: No such process和[: unexpected operator],并提供了通过将.sh文件改为bash和修改shell默认连接为bash的方法。解决过程涉及到dash shell与bash的兼容性问题。

Ubuntu 遇到 bin/stop.sh: 52: kill: No such process和bin/stop.sh: 58: [: unexpected operator的问题

bin/stop.sh: 47: [: 25893: unexpected operator
-e ubuntu01: stopping canal 25893 ...
bin/stop.sh: 52: kill: No such process
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found
bin/stop.sh: 58: [: unexpected operator
bin/stop.sh: 63: let: not found

解决办法如下:

因为ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了.执行时可以把sh换成bash文件名.sh来执行.成功.dash是什么东西,查了一下,应该也是一种shell,貌似用户对它的诟病颇多的。
by the way修改sh默认连接到bash的一种方法:

sudo dpkg-reconfigure dash

选择no即可.
在这里插入图片描述

sudo dpkg-reconfigure dash

[sudo] password for ubuntu01: 输入密码
Removing 'diversion of /bin/sh to /bin/sh.distrib by dash'
Adding 'diversion of /bin/sh to /bin/sh.distrib by bash'
Removing 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash'
Adding 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by bash'
你遇到的错误: ``` /usr/bin/dj.sh: line 1924: syntax error: unexpected end of file /usr/bin/dj.sh: line 1516: ...: command not found ``` 是 Bash 脚本中非常典型的 **语法结构不匹配** **变量/命令解析失败** 问题。 --- ## 🚨 根本原因分析 ### 🔴 `syntax error: unexpected end of file`(第 1924 行) > 这表示:**Bash 解析器读到文件结尾时,发现有一个控制块还没闭合。** 常见于: - `if` 没有对应的 `fi` - `for` / `while` 没有 `done` - 函数开 `{` 但没闭 `}` - `case` 没有 `esac` - 多行字符串引号未闭合(如 `'` 或 `"`) 而你的脚本长达 2000+ 行,这种错误往往是因为某个地方少了一个 `fi`、`done` 或 `}`。 --- ### 🟡 `...: command not found`(第 1516 行) > 说明 Bash 把某一行当成了命令来执行,但它不是有效命令。 这通常是由于: - 变量展开失败 → 展开为空或特殊符号 - 引号未闭合导致命令被错误拼接 - `$()` 或 `$(())` 中包含非法内容 - 使用了 Unicode 字符或不可见字符(如 `\r`、零宽空格) --- ## ✅ 定位与修复步骤 --- ### ✅ 第一步:检查是否有 `CRLF` 换行符(Windows 风格换行) ```bash file /usr/bin/dj.sh ``` 如果输出包含: ``` CRLF, DOS ``` → 说明是 Windows 换行符!会导致每行末尾多一个 `\r`,使命令变成 `echo\r` 导致“command not found”。 #### ✅ 修复方法: 在脚本开头加入自动修复逻辑(你已经有): ```bash # --- 自动修复 CRLF 换行符 --- if grep -q $'\r' "$0" 2>/dev/null; then echo "🔧 正在修复 Windows 换行符..." sed -i 's/\r$//' "$0" echo "🔄 重新启动已修复的脚本..." exec bash "$0" "$@" fi ``` ✅ 确保这段代码位于 **shebang 之后的第一位**! 否则后续所有函数都会因 `\r` 报错。 --- ### ✅ 第二步:查找缺失的 `fi` / `done` / `}` 使用以下命令统计关键词数量是否平衡: ```bash # 统计 if/fi grep -c '^if' /usr/bin/dj.sh grep -c '^fi' /usr/bin/dj.sh # 统计 for/done grep -c '^for' /usr/bin/dj.sh grep -c '^done' /usr/bin/dj.sh # 统计 while/done grep -c '^while' /usr/bin/dj.sh grep -c '^done' /usr/bin/dj.sh # 统计 {/} grep -o '{' /usr/bin/dj.sh | wc -l grep -o '}' /usr/bin/dj.sh | wc -l ``` 📌 如果 `if > fi` 或 `{ > }` → 就知道哪里漏了。 --- ### ✅ 第三步:重点排查 `trap` 块是否闭合正确 你在最后写的 `trap` 是这样的: ```bash trap '{ ... exit "$EXIT_CODE" }' INT TERM ERR EXIT HUP ``` ⚠️ 注意:`trap` 后面是单引号包裹的大括号块。 必须确保: - 开头是 `'{'` - 结尾是 `}'` - 中间不能有未闭合的引号或括号 #### ❌ 错误示例: ```bash log ERROR "⛔ 脚本即将退出... ``` → 缺少右引号 `"`,会导致整个 `trap` 块无法闭合! 这就是为什么报“unexpected end of file”——因为 Bash 认为 `trap` 还没结束,一直读到文件尾才发现不对劲。 --- ### ✅ 第四步:查看第 1516 行附近代码 运行: ```bash sed -n '1510,1520p' /usr/bin/dj.sh | cat -A ``` `cat -A` 会显示隐藏字符,比如: - `$` 表示行尾 - `^M` 表示 `\r`(CRLF) - `M-oM-;M-&` 表示 UTF-8 BOM 或乱码 🔍 查看这一行是不是类似: ```bash ... log INFO "最长等待时间已根据性能动态调整为 ${timeout_sec} 秒 ... ``` → 缺少末尾双引号! 就会变成: ```bash log INFO "最长等待..." 下一行也被当作字符串的一部分 → 直到下一个 " 才闭合 ``` 最终导致语法错乱。 --- ## ✅ 快速修复建议 ### ✅ 修复 1:确保所有字符串闭合 检查这些常见的日志语句: ```bash log INFO "最长等待时间已根据性能动态调整为 ${timeout_sec} 秒" # ↑ 这里有没有闭合? ``` ✅ 改为: ```bash log INFO "最长等待时间已根据性能动态调整为 ${timeout_sec} 秒" ``` --- ### ✅ 修复 2:添加 missing `fi` 如果你有类似: ```bash if [ condition ]; then something # 没有 fi! ``` → 在适当位置补上: ```bash fi ``` --- ### ✅ 修复 3:用工具格式化 + 校验 安装 `shellcheck`: ```bash sudo apt install shellcheck -y shellcheck /usr/bin/dj.sh ``` 它会直接告诉你: ``` dj.sh:1924:1: error: Expected 'fi'. dj.sh:1516:6: error: Variable is referenced but not assigned. ``` --- ### ✅ 修复 4:临时加调试信息定位断点 在关键块前后打印: ```bash echo "DEBUG: Before setup_mysql" >&2 setup_mysql echo "DEBUG: After setup_mysql" >&2 ``` 帮助你判断脚本到底执行到了哪一行。 --- ## ✅ 总结:你现在的问题极可能是以下之一 | 可能性 | 描述 | 如何验证 | |-------|------|---------| | 🔴 **缺少 `fi` 或 `done`** | 最常见原因 | 用 `grep -c if/fi` 对比 | | 🔴 **字符串未闭合(缺 `"`) ** | 导致跨行解析错误 | `cat -A` 查看 1516 行 | | 🔴 **存在 `\r` 换行符** | 所有命令变 `cmd^M` | `file dj.sh` 或 `hexdump -C dj.sh \| head` | | 🔴 **`trap` 块内语法错误** | 导致整个 trap 不闭合 | 检查 `trap '{ ... }'` 是否完整 | --- ## ✅ 推荐最终修复顺序 1. ✅ 运行 `file /usr/bin/dj.sh` → 看是否为 DOS 换行 2. ✅ 添加 `cat -A` 查看第 1516 行真实内容 3. ✅ 使用 `shellcheck` 自动诊断 4. ✅ 在每个 `if` 后检查是否都有 `fi` 5. ✅ 删除末尾多余的 `set -euo pipefail`(前面讲过) 6. ✅ 确保 `trap` 块中的所有引号都成对出现 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WMSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值