Browse Source

优化修改sshd模块代码,解决自测过程中发现的问题和bug

niujiuru 1 week atrás
parent
commit
e9bfe51690

BIN
package/rtu_linux_modules_1.0.0.1.tar.gz


BIN
package/yfkj_ssh_client_v1.0.0.1.tar.gz


+ 8 - 1
sshd/client/client.go

@@ -71,7 +71,7 @@ func main() {
 
 	id, err := machineid.ID()
 	if err == nil {
-		coupler.clientID = id
+		coupler.machineID = id
 	}
 
 	if err := coupler.init2(); err != nil {
@@ -137,6 +137,13 @@ func term(pingState *atomic.Bool) {
 		return matches
 	})
 
+	executing.Store(true)
+	result, err := coupler.exec("pwd")
+	executing.Store(false)
+	if err == nil && result.Cwd != "" { /// 在进入前对齐路径
+		coupler.cwd = result.Cwd
+	}
+
 	for {
 		if !pingState.Load() {
 			fmt.Printf("[%s] 目标设备连接丢失!!\n", MODULE_NAME)

+ 1 - 0
sshd/client/coupler.go

@@ -28,6 +28,7 @@ type MQTTCoupler struct {
 
 	client      mqtt.Client
 	clientID    string
+	machineID   string
 	isConnected atomic.Bool /// 标记是否已连接MQTT的Broker服务
 
 	imei     string // 设备唯一标识

+ 3 - 13
sshd/client/invoker.go

@@ -2,8 +2,6 @@ package main
 
 import (
 	"encoding/json"
-	"fmt"
-	"strings"
 	"time"
 
 	"hnyfkj.com.cn/rtu/linux/utils/jsonrpc2"
@@ -55,23 +53,15 @@ func (c *MQTTCoupler) ping() (*jsonrpc2.Response, error) {
 // 执行命令
 func (c *MQTTCoupler) exec(
 	cmd string) (*shell.ExecuteResult, error) {
-	if strings.ContainsAny(cmd, "&") {
-		return nil, fmt.Errorf("禁止启动后台任务")
-	}
-
-	if strings.ContainsAny(cmd, "|>;") || strings.Contains(cmd, "\n") {
-		safeCmd := strings.ReplaceAll(cmd, "'", "'\\''")
-		cmd = fmt.Sprintf("sh -c '%s'", safeCmd) // 包装成 shell 命令, 支持管道等高级功能
-	}
-
 	params := struct {
 		ClientID string `json:"client_id"`
 		shell.ExecuteParams
 	}{
 		ClientID: c.clientID,
 		ExecuteParams: shell.ExecuteParams{
-			Cmd:     cmd,
-			Timeout: int(shell.DefaultTimeout / time.Second),
+			HostFingerprint: c.machineID, // 调用者主机指纹
+			Cmd:             cmd,
+			Timeout:         int(shell.DefaultTimeout / time.Second),
 		},
 	}
 

+ 28 - 9
sshd/sshd.go

@@ -3,6 +3,7 @@ package sshd
 import (
 	"context"
 	"errors"
+	"fmt"
 	"os"
 	"strings"
 	"sync"
@@ -291,24 +292,42 @@ func (c *MQTTCoupler) execOneCmd(msg mqtt.Message) {
 			goto retp
 		}
 
+		cmd := params.Cmd
+		if strings.ContainsAny(cmd, "&") {
+			ce.mu.Unlock()
+			resp = jsonrpc2.BuildError(req, -32003, "prohibit the startup of background tasks")
+			goto retp
+		}
+
+		if strings.ContainsAny(cmd, "|>;") || strings.Contains(cmd, "\n") {
+			safeCmd := strings.ReplaceAll(cmd, "'", "'\\''")
+			cmd = fmt.Sprintf("sh -c '%s'", safeCmd) // 包装成 shell 命令, 支持管道等高级功能
+			params.Cmd = cmd
+		}
+
+		hostID := params.HostFingerprint
+		if hostID == "" {
+			hostID = "unknown"
+		}
+
 		ce.state = execRunning
 		ce.mu.Unlock()
 
 		start := time.Now()
 		if true { //////// 记录执行日志-执行前
-			baseapp.Logger.Infof("[%s][▷ EXEC] client=%s cmd=%q dir=%q timeout=%ds",
-				MODULE_NAME, clientID, params.Cmd, params.Dir, params.Timeout)
+			baseapp.Logger.Infof("[%s][▷ EXEC] host=%s, cmd=%q, timeout=%ds",
+				MODULE_NAME, hostID, params.Cmd, params.Timeout)
 		}
 
 		result, err := ce.executor.Exec(params) // 本地执行用户指令
 
 		cost := time.Since(start)
-		if err != nil { // 记录执行日志-执行后
-			baseapp.Logger.Warnf("[%s][✖ EXEC] client=%s cost=%v cmd=%q err=%v",
-				MODULE_NAME, clientID, cost, params.Cmd, err)
-		} else {
-			baseapp.Logger.Infof("[%s][✔ EXEC] client=%s cost=%v cmd=%q",
-				MODULE_NAME, clientID, cost, params.Cmd)
+		if err != nil { // 记录失败日志-执行后
+			baseapp.Logger.Warnf("[%s][✖ EXEC] host=%s, cmd=%q, err=%v, cost=%v",
+				MODULE_NAME, hostID, params.Cmd, err, cost)
+		} else { ///////// 记录成功日志-执行后
+			baseapp.Logger.Infof("[%s][✔ EXEC] host=%s, cmd=%q, cost=%v",
+				MODULE_NAME, hostID, params.Cmd, cost)
 		}
 
 		ce.mu.Lock()
@@ -327,7 +346,7 @@ func (c *MQTTCoupler) execOneCmd(msg mqtt.Message) {
 		ce.mu.Unlock()
 
 		if !running {
-			resp = jsonrpc2.BuildError(req, -32003, "no running command")
+			resp = jsonrpc2.BuildError(req, -32004, "no running command")
 			goto retp
 		}
 

+ 9 - 8
utils/shell/execute_types.go

@@ -9,7 +9,7 @@ import (
 )
 
 const (
-	DefaultTimeout = 5 * time.Second
+	DefaultTimeout = 5 * time.Second ////// 执行命令的默认超时时间, 单位: 秒
 )
 
 var (
@@ -18,14 +18,15 @@ var (
 )
 
 type ExecuteParams struct {
-	Cmd     string `json:"cmd"`               // 命令
-	Timeout int    `json:"timeout,omitempty"` // 超时(秒)
-	Dir     string `json:"-"`                 // 工作目录
+	HostFingerprint string `json:"host_fingerprint,omitempty"` // 主机指纹
+	Cmd             string `json:"cmd"`                        // 用户指令
+	Timeout         int    `json:"timeout,omitempty"`          // 超时(秒)
+	Dir             string `json:"-"`                          // 工作目录
 }
 
 type ExecuteResult struct {
-	Stdout   string `json:"stdout"`    ///////// 标准输出
-	Stderr   string `json:"stderr"`    ///////// 错误输出
-	ExitCode int    `json:"exit_code"` ///////// 退出状态码: 0表示成功, 非0表示失败
-	Cwd      string `json:"cwd"`       ///////// 当前目录
+	Stdout   string `json:"stdout"`    ////////////////////////// 标准输出
+	Stderr   string `json:"stderr"`    ////////////////////////// 错误输出
+	ExitCode int    `json:"exit_code"` ///////// 退出状态码: 0成功, 非0失败
+	Cwd      string `json:"cwd"`       ////////////////////////// 当前目录
 }

+ 1 - 1
utils/shell/executor.go

@@ -16,7 +16,7 @@ import (
 type Executor struct {
 	cwd     string        // 当前目录
 	prevCwd string        // 上次目录
-	pg      *processGroup // --进程组
+	pg      *processGroup // 执行命令的进程组
 }
 
 type PathError struct {