提交 1dd466fc authored 作者: 陈泽健's avatar 陈泽健

fix(mqtt): 输出执行报错问题文档,解决MQTT工具上传和fdfs检测异常问题

- 修复命令行过长导致的base64传输失败问题
- 解决远程lib目录不存在导致的库文件上传失败
- 添加LD_LIBRARY_PATH环境变量设置确保动态库加载
- 修正PowerShell字符串转义问题解决退出码解析异常
- 增强退出码解析逻辑支持True/False格式
- 使用Here-String构建命令确保变量在远程正确展开
上级 4a80cb90
......@@ -253,14 +253,18 @@ function Test-MQTTConnection {
# 上传 lib 目录中的所有库文件
$libDir = Join-Path $localMqttToolPath "lib"
if (Test-Path $libDir) {
# 先创建远程 lib 目录(确保目录存在)
$libRemoteDir = "$mqttToolDir/lib"
$createLibDirCmd = "mkdir -p '$libRemoteDir' 2>/dev/null || true"
Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $createLibDirCmd | Out-Null
$libFiles = Get-ChildItem -Path $libDir -File
foreach ($libFile in $libFiles) {
# 使用 Copy-File-To-Remote 函数上传文件
$libRemoteDir = "$mqttToolDir/lib"
$uploadOk = Copy-File-To-Remote -LocalPath $libFile.FullName -Server $Server -RemoteDir $libRemoteDir
if ($uploadOk) {
# 设置执行权限
$chmodCmd = "chmod +x '$mqttToolDir/lib/$($libFile.Name)' 2>/dev/null || true"
$chmodCmd = "chmod +x '$libRemoteDir/$($libFile.Name)' 2>/dev/null || true"
Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $chmodCmd | Out-Null
}
}
......@@ -277,7 +281,8 @@ function Test-MQTTConnection {
$subscribedTopics = 0
foreach ($topic in $mqttTopics) {
# 订阅主题(在后台运行5秒后退出)
$subCmd = "cd '$mqttToolDir' && timeout 5 ./mqtt sub -h localhost -t '$topic' -v 2>&1 || echo 'TIMEOUT'"
# 设置 LD_LIBRARY_PATH 以确保 mqtt 工具能找到依赖库
$subCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && timeout 5 ./mqtt sub -h localhost -t '$topic' -v 2>&1 || echo 'TIMEOUT'"
$subResult = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $subCmd
# 检查订阅是否成功(查找 "Connected" 或成功订阅的标志)
......@@ -314,7 +319,8 @@ function Test-MQTTConnection {
Write-Log -Level "INFO" -Message "[MQTT] 测试消息内容: $testMessage"
# 发布测试消息
$pubCmd = "cd '$mqttToolDir' && ./mqtt pub -h localhost -t '$testTopic' -m '$testMessage' 2>&1"
# 设置 LD_LIBRARY_PATH 以确保 mqtt 工具能找到依赖库
$pubCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && ./mqtt pub -h localhost -t '$testTopic' -m '$testMessage' 2>&1"
$pubResult = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $pubCmd
# 检查推送是否成功
......@@ -961,8 +967,10 @@ function Test-FastDFSConnection {
Write-Log -Level "INFO" -Message "[FastDFS] 使用 $fdfsScriptName 脚本进行完整检测: $actualScriptPath"
# 执行检测脚本,设置超时限制(60秒超时)
# 使用单引号避免 PowerShell 解析特殊字符,$actualScriptPath 单独拼接
$fdfsCmd = 'timeout 60 bash "' + $actualScriptPath + '" 2>&1; echo ''===EXIT_CODE===$?'''
# 使用 Here-String 构建命令,确保 $? 在远程 Bash 中正确展开
$fdfsCmd = @'
timeout 60 bash "__SCRIPT_PATH__" 2>&1; echo "===EXIT_CODE===$?"
'@.Replace('__SCRIPT_PATH__', $actualScriptPath)
$fdfsResult = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $fdfsCmd
$outputText = $fdfsResult.Output -join "`n"
......
......@@ -128,6 +128,89 @@
### 2.2问题二
```ignorelang
[2026-02-24 11:42:12] [INFO] [MQTT] ========== MQTT主题订阅检测 ==========
[2026-02-24 11:42:12] [INFO] [MQTT] 准备上传 MQTT 测试工具到远程服务器...
[2026-02-24 11:42:13] [INFO] [MQTT] 本地 MQTT 工具路径: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86
[2026-02-24 11:42:13] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:13] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mqtt -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:42:14] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:15] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mosquitto_sub -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:42:16] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:17] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mosquitto_pub -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:42:17] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:18] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:18] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:19] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:19] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:20] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:20] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:21] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:21] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:21] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:21] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:22] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:22] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:23] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:23] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:42:24] [ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
[2026-02-24 11:42:24] [SUCCESS] [MQTT] MQTT 测试工具上传完成
[2026-02-24 11:42:24] [WARN] [MQTT] 主题订阅失败或超时: /androidPanel/
[2026-02-24 11:42:25] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/conference/service/request/
[2026-02-24 11:42:26] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessService/callService
[2026-02-24 11:42:27] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessAuthor/onthewall
[2026-02-24 11:42:28] [WARN] [MQTT] 主题订阅失败或超时: /meeting/message/
[2026-02-24 11:42:28] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/event/request/
[2026-02-24 11:42:29] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/service/request/
[2026-02-24 11:42:29] [INFO] [MQTT] 主题订阅完成: 成功 0/7 个
[2026-02-24 11:42:29] [INFO] [MQTT] ========== MQTT消息推送检测 ==========
[2026-02-24 11:42:29] [INFO] [MQTT] 测试推送主题: /androidPanel/
[2026-02-24 11:42:29] [INFO] [MQTT] 测试消息内容: test_message_from_health_check_20260224114229
[2026-02-24 11:42:30] [WARN] [MQTT] 消息推送失败: /androidPanel/
[2026-02-24 11:42:30] [INFO] [MQTT] 消息推送检测完成
```
### 2.3 问题三
```ignorelang
[2026-02-24 11:48:35] [INFO] [MQTT] ========== MQTT主题订阅检测 ==========
[2026-02-24 11:48:35] [INFO] [MQTT] 准备上传 MQTT 测试工具到远程服务器...
[2026-02-24 11:48:36] [INFO] [MQTT] 本地 MQTT 工具路径: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86
[2026-02-24 11:48:36] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:37] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mqtt -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:48:37] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:38] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mosquitto_sub -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:48:39] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:40] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\mosquitto_pub -> root@192.168.5.47:/tmp/mqtt_test/
[2026-02-24 11:48:41] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:42] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\ld-musl-x86_64.so.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:43] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:43] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libcares.so.2 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:44] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:45] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libcares.so.2.6.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:45] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:46] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libcjson.so.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:47] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:47] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libcjson.so.1.7.17 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:48] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:49] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libcrypto.so.1.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:49] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:50] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libmosquitto.so.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:51] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:48:51] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\mqtt_test_x86\lib\libssl.so.1.1 -> root@192.168.5.47:/tmp/mqtt_test/lib/
[2026-02-24 11:48:52] [SUCCESS] [MQTT] MQTT 测试工具上传完成
[2026-02-24 11:48:53] [WARN] [MQTT] 主题订阅失败或超时: /androidPanel/
[2026-02-24 11:48:53] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/conference/service/request/
[2026-02-24 11:48:54] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessService/callService
[2026-02-24 11:48:55] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessAuthor/onthewall
[2026-02-24 11:48:56] [WARN] [MQTT] 主题订阅失败或超时: /meeting/message/
[2026-02-24 11:48:56] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/event/request/
[2026-02-24 11:48:57] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/service/request/
[2026-02-24 11:48:57] [INFO] [MQTT] 主题订阅完成: 成功 0/7 个
[2026-02-24 11:48:57] [INFO] [MQTT] ========== MQTT消息推送检测 ==========
[2026-02-24 11:48:57] [INFO] [MQTT] 测试推送主题: /androidPanel/
[2026-02-24 11:48:57] [INFO] [MQTT] 测试消息内容: test_message_from_health_check_20260224114857
[2026-02-24 11:48:58] [WARN] [MQTT] 消息推送失败: /androidPanel/
[2026-02-24 11:48:58] [INFO] [MQTT] 消息推送检测完成
```
## 3. 问题解决分析
......
......@@ -3,13 +3,15 @@
## 执行时间
- 创建时间:2026-02-24
- 更新时间:2026-02-24
- 执行状态:已完成
- 执行状态:已完成(问题一、问题二)
---
## 问题概述
执行主运行脚本后 MQTT 离线工具执行异常,命令行过长导致执行失败,随后 MQTT 主题订阅和消息推送检测全部失败。
执行主运行脚本后 MQTT 离线工具执行异常。
### 问题一(2026-02-24 10:34)
**错误信息:**
```
......@@ -18,13 +20,23 @@
```
**后续影响:**
- MQTT 工具上传失败
- 7 个主题订阅全部失败
- 消息推送失败
### 问题二(2026-02-24 11:42)
**错误信息:**
```
[WARN] [MQTT] 主题订阅失败或超时: /androidPanel/
[WARN] [MQTT] 主题订阅失败或超时: /iot/v1/conference/service/request/
... (共7个主题全部失败)
[WARN] [MQTT] 消息推送失败: /androidPanel/
[ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
```
**后续影响:**
- MQTT 工具可执行文件上传成功
- lib 目录下的库文件全部上传失败
- 7 个主题订阅全部失败
- 消息推送失败
---
## 执行步骤
......@@ -68,6 +80,12 @@ $uploadResult = Invoke-SSHCommand -HostName $Server.IP ...
- MQTT 工具无法正确上传
- 主题订阅和消息推送检测全部失败
3. **命令行过长的影响**
- plink.exe 无法执行:`The filename or extension is too long`
- 文件传输失败或被截断
- MQTT 工具无法正确上传
- 主题订阅和消息推送检测全部失败
**目录结构分析:**
```
mqtt_test_x86/
......@@ -120,12 +138,21 @@ if ($uploadOk) {
### 步骤 4:修复执行
#### 问题一修复(已完成)
- [x] 定位问题代码:MiddlewareCheck.psm1 第 237-262 行
- [x] 修改二进制文件上传逻辑,使用 `Copy-File-To-Remote`
- [x] 修改库文件上传逻辑,使用 `Copy-File-To-Remote`
- [x] 添加执行权限设置逻辑
- [x] 删除错误的 base64 命令行方式代码
#### 问题二修复(已完成 2026-02-24)
- [x] 定位问题代码:MiddlewareCheck.psm1 第 253-266 行
- [x] 分析错误信息:`pscp: unable to open /tmp/mqtt_test/lib/: failure`
- [x] 识别根本原因:远程 lib 目录不存在
- [x] 添加远程目录创建逻辑
---
## 执行结果
......@@ -134,7 +161,72 @@ if ($uploadOk) {
| 文件 | 修改位置 | 修改内容 | 状态 |
|------|----------|----------|------|
| MiddlewareCheck.psm1 | 第 237-262 行 | 使用 `Copy-File-To-Remote` 替换 base64 命令行方式 | ✅ 已修复 |
| MiddlewareCheck.psm1 | 第 237-266 行 | 问题一:使用 `Copy-File-To-Remote` 替换 base64 命令行方式 | ✅ 已修复 |
| MiddlewareCheck.psm1 | 第 253-267 行 | 问题二:添加远程 lib 目录创建逻辑 | ✅ 已修复 |
### 问题二专项说明
**问题二错误信息(2026-02-24 11:42):**
```
[ERROR] pscp 上传失败: pscp: unable to open /tmp/mqtt_test/lib/: failure
```
**根本原因:**
1. **远程目录不存在**
- pscp 尝试将文件上传到 `/tmp/mqtt_test/lib/` 目录
- 但该目录在远程服务器上不存在
- pscp 需要目标目录已经存在,否则会报错
2. **原代码流程**
```powershell
# 上传 lib 目录中的所有库文件
foreach ($libFile in $libFiles) {
$libRemoteDir = "$mqttToolDir/lib"
# 直接调用 Copy-File-To-Remote,没有先创建目录
$uploadOk = Copy-File-To-Remote -LocalPath $libFile.FullName -Server $Server -RemoteDir $libRemoteDir
}
```
3. **Copy-File-To-Remote 的 pscp 调用**
```powershell
# Common.psm1 第 227 行
("{0}@{1}:{2}/" -f $Server.User, $Server.IP, $RemoteDir)
# 结果: root@192.168.5.47:/tmp/mqtt_test/lib/
# pscp 尝试打开这个目录,但不存在
```
**解决方案:**
在上传库文件之前,先创建远程 lib 目录:
```powershell
# 先创建远程 lib 目录(确保目录存在)
$libRemoteDir = "$mqttToolDir/lib"
$createLibDirCmd = "mkdir -p '$libRemoteDir' 2>/dev/null || true"
Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $createLibDirCmd | Out-Null
```
**修复对比:**
| 修复前 | 修复后 |
|--------|--------|
| 直接上传文件到 `/tmp/mqtt_test/lib/` | 先创建 `/tmp/mqtt_test/lib/` 目录 |
| pscp 报错:目录不存在 | pscp 成功上传文件 |
**pscp 目录要求:**
| 工具 | 目录要求 | 说明 |
|------|----------|------|
| pscp | 目标目录必须存在 | 不会自动创建目录 |
| scp | 目标目录可以不存在 | 会自动创建目录 |
| Copy-File-To-Remote | 需手动创建目录 | 内部使用 pscp |
**预防措施:**
1. 在上传文件前,先确保远程目录存在
2. 使用 `mkdir -p` 命令创建目录(`-p` 选项确保不会因目录已存在而报错)
3. 对于包含子目录的上传操作,逐层创建目录结构
### 修复详情
......@@ -261,13 +353,131 @@ EOF
| 状态 | 说明 |
|------|------|
| 问题类型 | 命令行过长导致执行失败 |
| 根本原因 | 使用 `echo '$base64Content'` 方式传输二进制文件 |
| 问题类型 | 命令行过长 + 远程目录不存在 + 库依赖问题 |
| 涉及问题 | 问题一(命令行过长)、问题二(远程目录)、问题三(LD_LIBRARY_PATH) |
| 根本原因 | 1. base64 命令行过长<br>2. 远程 lib 目录不存在<br>3. 未设置 LD_LIBRARY_PATH |
| 影响范围 | MQTT 工具上传、主题订阅检测、消息推送检测 |
| 当前状态 | ✅ 已修复 |
| 当前状态 | ✅ 已修复(问题一、二、三) |
| 修复日期 | 2026-02-24 |
| 验证状态 | 待实际环境测试 |
---
## 问题三专项说明(2026-02-24 11:48)
### 问题三分析
**错误信息(2026-02-24 11:48):**
```
[SUCCESS] [MQTT] MQTT 测试工具上传完成
[WARN] [MQTT] 主题订阅失败或超时: /androidPanel/
[WARN] [MQTT] 主题订阅失败或超时: /iot/v1/conference/service/request/
... (共7个主题全部失败)
[INFO] [MQTT] 主题订阅完成: 成功 0/7 个
[WARN] [MQTT] 消息推送失败: /androidPanel/
```
**观察结果:**
- ✅ MQTT 工具上传成功(包括 lib 目录下的所有库文件)
- ❌ MQTT 主题订阅全部失败(0/7 成功)
- ❌ MQTT 消息推送失败
**根本原因:**
`mqtt` 工具是动态链接的可执行文件,依赖 `lib/` 目录下的共享库:
- `libmosquitto.so.1`
- `libssl.so.1.1`
- `libcrypto.so.1.1`
- `libcares.so.2`
- `libcjson.so.1`
- `ld-musl-x86_64.so.1`
当执行 `./mqtt sub` 时,动态链接器需要在 `LD_LIBRARY_PATH` 指定的目录中查找这些库文件。如果没有设置 `LD_LIBRARY_PATH`,工具会报错:
```
./mqtt: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
```
### 手动检测指令
在远程服务器上执行以下命令来诊断问题:
```bash
# 1. 检查工具文件
cd /tmp/mqtt_test
ls -la mqtt mosquitto_sub mosquitto_pub
# 2. 检查依赖库
ldd ./mqtt
# 3. 不设置 LD_LIBRARY_PATH 执行(应该失败)
./mqtt sub -h localhost -t "/test/" -v
# 4. 设置 LD_LIBRARY_PATH 后执行(应该成功)
export LD_LIBRARY_PATH=/tmp/mqtt_test/lib:$LD_LIBRARY_PATH
./mqtt sub -h localhost -t "/test/" -v
```
### 解决方案
**修复前代码:**
```powershell
# 订阅主题(在后台运行5秒后退出)
$subCmd = "cd '$mqttToolDir' && timeout 5 ./mqtt sub -h localhost -t '$topic' -v 2>&1 || echo 'TIMEOUT'"
$subResult = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $subCmd
```
**修复后代码:**
```powershell
# 订阅主题(在后台运行5秒后退出)
# 设置 LD_LIBRARY_PATH 以确保 mqtt 工具能找到依赖库
$subCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && timeout 5 ./mqtt sub -h localhost -t '$topic' -v 2>&1 || echo 'TIMEOUT'"
$subResult = Invoke-SSHCommand -HostName $Server.IP -User $Server.User -Pass $Server.Pass -Port $Server.Port -Command $subCmd
```
**消息推送修复:**
```powershell
# 修复前
$pubCmd = "cd '$mqttToolDir' && ./mqtt pub -h localhost -t '$testTopic' -m '$testMessage' 2>&1"
# 修复后
$pubCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && ./mqtt pub -h localhost -t '$testTopic' -m '$testMessage' 2>&1"
```
### 修复对比
| 项目 | 修复前 | 修复后 |
|------|--------|--------|
| 订阅命令 | `cd /tmp/mqtt_test && timeout 5 ./mqtt sub ...` | `cd /tmp/mqtt_test && export LD_LIBRARY_PATH=/tmp/mqtt_test/lib:$LD_LIBRARY_PATH && timeout 5 ./mqtt sub ...` |
| 推送命令 | `cd /tmp/mqtt_test && ./mqtt pub ...` | `cd /tmp/mqtt_test && export LD_LIBRARY_PATH=/tmp/mqtt_test/lib:$LD_LIBRARY_PATH && ./mqtt pub ...` |
| 库查找 | ❌ 失败(找不到库) | ✅ 成功(能找到库) |
| 工具执行 | ❌ 报错退出 | ✅ 正常执行 |
### Linux 动态库查找机制
**查找顺序:**
1. `LD_LIBRARY_PATH` 环境变量指定的目录
2. `/etc/ld.so.cache` 缓存文件
3. `/lib` 和 `/usr/lib` 系统库目录
4. `DT_RPATH` 和 `DT_RUNPATH` 编译时指定的目录
**MQTT 工具依赖:**
```
mqtt
├── libmosquitto.so.1 (MQTT 库)
├── libssl.so.1.1 (SSL/TLS 库)
├── libcrypto.so.1.1 (加密库)
├── libcares.so.2 (异步 DNS 库)
├── libcjson.so.1 (JSON 库)
└── ld-musl-x86_64.so.1 (musl C 库)
```
### 修复位置
| 功能 | 文件 | 行号 | 修改内容 |
|------|------|------|----------|
| MQTT 主题订阅 | MiddlewareCheck.psm1 | 284 | 添加 `export LD_LIBRARY_PATH` |
| MQTT 消息推送 | MiddlewareCheck.psm1 | 321 | 添加 `export LD_LIBRARY_PATH` |
### 测试计划
**测试环境:**
......
......@@ -16,7 +16,7 @@
---
## 2. 问题报错信息
### 2.1 问题一
```
[2026-02-09 16:26:35] [INFO] ========== FastDFS连接检测 ==========
[2026-02-09 16:26:35] [INFO] [FastDFS] 检测到x86架构,使用 check_fdfs_x86.sh
......@@ -66,6 +66,61 @@
[2026-02-09 16:26:40] [ERROR] [FastDFS] check_fdfs_x86.sh 检测失败
```
### 2.2 问题二
```ignorelang
[2026-02-24 11:01:58] [INFO] ========== FastDFS连接检测 ==========
[2026-02-24 11:01:59] [INFO] [FastDFS] 检测到x86架构,使用 check_fdfs_x86.sh
[2026-02-24 11:02:00] [INFO] [FastDFS] 未检测到远程脚本目录,使用默认目录: /root
[2026-02-24 11:02:00] [INFO] [FastDFS] 加载脚本: C:\Users\UBAINS\Desktop\Test\check_fdfs_x86.sh,上传至远程 (强制覆盖)
[2026-02-24 11:02:00] [INFO] 已找到 pscp: C:\Users\UBAINS\Desktop\Test\pscp.exe
[2026-02-24 11:02:01] [SUCCESS] 文件上传成功: C:\Users\UBAINS\Desktop\Test\check_fdfs_x86.sh -> root@192.168.5.47:/root/
[2026-02-24 11:02:01] [SUCCESS] [FastDFS] check_fdfs_x86.sh 上传成功
[2026-02-24 11:02:02] [INFO] [FastDFS] 使用 check_fdfs_x86.sh 脚本进行完整检测: /root/check_fdfs_x86.sh
[2026-02-24 11:02:06] [INFO] [FastDFS] check_fdfs_x86.sh 输出:
==========================================
FastDFS 最终功能验证
==========================================
检测到容器: Storage=ustorage, Tracker=utracker
1. 创建测试文件: /tmp/fastdfs_final_test_1771902124.txt (MD5: dfa6814088fd40a301703cc3badc7775)
2. ✓ 测试文件已复制到容器
3. 执行上传测试...
上传命令退出码: 0
上传输出: group1/M00/00/01/wKgFL2mdFKyAaw7WAAAATYLbDIY636.txt
✓ 上传成功
文件ID: group1/M00/00/01/wKgFL2mdFKyAaw7WAAAATYLbDIY636.txt
4. 执行下载测试...
下载命令退出码: 0
✓ 下载成功
5. 执行完整性验证...
MD5命令退出码: 0
原始MD5: dfa6814088fd40a301703cc3badc7775
下载MD5: dfa6814088fd40a301703cc3badc7775
✓ 文件完整性验证通过
==========================================
✅ FastDFS 所有核心功能验证通过!
==========================================
功能验证清单:
✓ 文件上传
✓ 文件下载
✓ 文件完整性
✓ Tracker服务
✓ Storage服务
✓ 网络通信
6. 访问信息:
访问URL: https://192.168.5.47/group1/M00/00/01/wKgFL2mdFKyAaw7WAAAATYLbDIY636.txt
==========================================
验证完成 - 所有测试通过
==========================================
===EXIT_CODE===$?
[2026-02-24 11:02:06] [ERROR] [FastDFS] check_fdfs_x86.sh 执行失败
```
## 3. 问题解决分析
### 3.1 问题根因
......
......@@ -2,7 +2,8 @@
## 执行时间
- 创建时间:2026-02-09
- 执行状态:已完成
- 更新时间:2026-02-24
- 执行状态:已完成(问题一、问题二)
---
......@@ -10,11 +11,24 @@
执行主运行脚本后FastDFS检测报告异常,脚本输出显示所有功能验证通过,但最终判定为检测失败。
### 问题一(2026-02-09)
```
===EXIT_CODE===True
[2026-02-09 16:26:40] [ERROR] [FastDFS] check_fdfs_x86.sh 检测失败
```
### 问题二(2026-02-24)
```
===EXIT_CODE===$?
[2026-02-24 11:02:06] [ERROR] [FastDFS] check_fdfs_x86.sh 执行失败
```
**问题分析:**
- 问题一:退出码是 `True` 字符串而非数字 `0`
- 问题二:退出码 `$?` 没有被展开,直接输出字面量 `$?`
---
## 执行步骤
......@@ -70,19 +84,118 @@
| _PRD_服务自检需求文档_主运行脚本模块拆分_fdfs检测异常_问题处理.md | 更新 | 补充完整的问题解决分析 |
### 问题结论
- **问题类型**:代码兼容性问题
- **问题类型**:代码兼容性问题 + 命令构建错误
- **是否需要代码修改**:是
- **解决方案**:增强退出码解析逻辑,支持多种退出码格式
- **解决方案**
- 问题一:增强退出码解析逻辑,支持 True/False 格式
- 问题二:修正命令构建方式,使用 Here-String 确保 `$?` 在远程 Bash 中展开
---
## 问题二专项说明(2026-02-24)
### 问题二分析
**错误信息:**
```
===EXIT_CODE===$?
[2026-02-24 11:02:06] [ERROR] [FastDFS] check_fdfs_x86.sh 执行失败
```
**根本原因:**
原代码(MiddlewareCheck.psm1 第 965 行)使用了错误的单引号字符串拼接方式:
```powershell
$fdfsCmd = 'timeout 60 bash "' + $actualScriptPath + '" 2>&1; echo ''===EXIT_CODE===$?'''
```
**问题分析:**
1. **单引号转义问题**
- 在 PowerShell 中,`''` 表示一个转义的单引号字符
- `'text''more'` 结果是 `text'more`
-`'text''` 没有闭合引号,语法不完整
2. **实际传递的命令**
```
echo '===EXIT_CODE===$?
```
- `$?` 后面缺少闭合单引号
- 远程 Bash 将 `$?` 作为字面量输出,而不是变量展开
3. **结果**:
- 退出码输出为 `===EXIT_CODE===$?`(字面量)
- 无法被任何正则表达式匹配(数字或 True/False)
- 默认判定为失败(`$actualExitCode = 1`)
### 问题二修复
**修复前代码:**
```powershell
# 使用单引号避免 PowerShell 解析特殊字符,$actualScriptPath 单独拼接
$fdfsCmd = 'timeout 60 bash "' + $actualScriptPath + '" 2>&1; echo ''===EXIT_CODE===$?'''
```
**修复后代码:**
```powershell
# 使用 Here-String 构建命令,确保 $? 在远程 Bash 中正确展开
$fdfsCmd = @'
timeout 60 bash "__SCRIPT_PATH__" 2>&1; echo "===EXIT_CODE===$?"
'@.Replace('__SCRIPT_PATH__', $actualScriptPath)
```
**修复说明:**
1. **使用 Here-String (`@'...'@`)**:
- 单引号 Here-String 中,内容完全按字面量处理
- 变量不会在 PowerShell 端展开
2. **使用双引号包裹 `echo` 的内容**:
- `"===EXIT_CODE===$?"` 在远程 Bash 中展开
- `$?` 会被 Bash 正确解析为上一个命令的退出码
3. **使用占位符替换**:
- `__SCRIPT_PATH__` 作为占位符
- 使用 `.Replace()` 方法替换为实际路径
### 命令对比
| 方式 | PowerShell 端 | 远程 Bash 端 | 结果 |
|------|-------------|-------------|------|
| 修复前 | `'echo ''===EXIT_CODE===$?'''` | `echo '===EXIT_CODE===$?'` | ❌ `$?` 字面量 |
| 修复后 | `@"...echo \"===EXIT_CODE===$?\""@` | `echo "===EXIT_CODE===$?"` | ✅ `$?` 变量展开 |
### PowerShell 字符串规则
| 类型 | 语法 | 变量展开 | 转义单引号 | 适用场景 |
|------|------|----------|-----------|----------|
| 单引号字符串 | `'text'` | ❌ | `''` → `'` | 纯字面量 |
| 双引号字符串 | `"text"` | ✅ | `` `` `` → `"` | 需要变量展开 |
| 单引号 Here-String | `@'newline'@` | ❌ | 直接输入 `'` | 多行字面量 |
| 双引号 Here-String | `@"newline"@` | ✅ | 直接输入 `"` | 多行+变量 |
---
## 验证清单
修复后,可按以下清单验证:
### 问题一验证
- [x] 确认在标准bash环境下,退出码 `0` 能被正确识别
- [x] 增强正则表达式支持 `True`/`False` 格式
### 问题二验证
- [x] 修正命令构建方式,使用 Here-String
- [x] 确保 `$?` 在远程 Bash 中正确展开
- [ ] 运行完整检测,确认 FastDFS 检测通过
- [ ] 检查日志输出,确认退出码正确展开为数字
### 综合验证
- [ ] 确认在标准bash环境下,退出码 `0` 能被正确识别
- [ ] 确认在特殊Shell环境下,`True` 能被正确识别为成功
- [ ] 确认在特殊Shell环境下,`False` 能被正确识别为失败
- [ ] 确认不再出现 `===EXIT_CODE===$?` 字面量输出
- [ ] 运行完整检测,确认FastDFS检测通过
- [ ] 检查日志输出,确认无报错
......@@ -90,10 +203,49 @@
## 附录:关键代码位置
| 功能 | 文件 | 行号 |
|------|------|------|
| FastDFS检测命令构建 | MiddlewareCheck.psm1 | 774 |
| 退出码正则匹配 | MiddlewareCheck.psm1 | 781-788 |
| 退出码转换 | MiddlewareCheck.psm1 | 782-787 |
| 输出文本清理 | MiddlewareCheck.psm1 | 783/787 |
| 退出码判断 | MiddlewareCheck.psm1 | 792 |
### 问题一相关
| 功能 | 文件 | 行号 | 状态 |
|------|------|------|------|
| 退出码正则匹配 | MiddlewareCheck.psm1 | 972-981 | ✅ 已修复 |
| 退出码转换 | MiddlewareCheck.psm1 | 974-975, 978-979 | ✅ 已修复 |
### 问题二相关
| 功能 | 文件 | 行号 | 修复前 | 修复后 | 状态 |
|------|------|------|--------|--------|------|
| FastDFS 检测命令构建 | MiddlewareCheck.psm1 | 965-966 | 单引号拼接 | Here-String | ✅ 已修复 |
### 修复前后代码对比
**问题二修复详情(MiddlewareCheck.psm1 第 965-966 行):**
| 修复前 | 修复后 |
|--------|--------|
| `$fdfsCmd = 'timeout 60 bash "' + $actualScriptPath + '" 2>&1; echo ''===EXIT_CODE===$?'''` | `$fdfsCmd = @'\ntimeout 60 bash \"__SCRIPT_PATH__\" 2>&1; echo \"===EXIT_CODE===$?\"\n'@.Replace('__SCRIPT_PATH__', $actualScriptPath)` |
| ❌ 单引号转义问题,`$?` 作为字面量 | ✅ Here-String + 双引号,`$?` 在远程展开 |
### 问题二 PowerShell 单引号转义说明
**错误的转义方式:**
```powershell
'echo ''===EXIT_CODE===$?'''
# 结果: echo '===EXIT_CODE===$?
# 问题: $? 后面没有闭合单引号,语法不完整
```
**正确的转义方式:**
```powershell
# 方式 1: 使用双引号字符串
$fdfsCmd = "echo `"===EXIT_CODE===$?`""
# 方式 2: 使用 Here-String(推荐)
$fdfsCmd = @"
echo "===EXIT_CODE===$?"
"@
# 方式 3: 使用占位符替换
$fdfsCmd = @'
echo "===EXIT_CODE===$?"
'@.Replace('$?Variable', '$?')
```
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论