diff --git a/agent/agent.go b/agent/agent.go index 6fd0b0d..4b1d11e 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -23,6 +23,25 @@ import ( "github.com/robfig/cron/v3" ) +// findAvailableShell 查找可用的 shell +func findAvailableShell() string { + // 优先使用环境变量中的 SHELL + if envShell := os.Getenv("SHELL"); envShell != "" { + return envShell + } + + // 尝试按优先级查找可用的 shell + shells := []string{"/bin/bash", "/bin/zsh", "/bin/sh"} + for _, sh := range shells { + if _, err := os.Stat(sh); err == nil { + return sh + } + } + + // 最后回退到 sh(应该总是存在) + return "sh" +} + // WebSocket 消息类型 const ( WSTypeHeartbeat = "heartbeat" @@ -520,14 +539,17 @@ func (a *Agent) executeTask(task *AgentTask) { finalCommand = fmt.Sprintf("cd %s && %s", task.WorkDir, task.Command) log.Infof("任务 #%d 工作目录: %s", task.ID, task.WorkDir) } - cmd = exec.CommandContext(ctx, "sh", "-c", finalCommand) + // 尝试按优先级查找可用的 shell + shell := findAvailableShell() + cmd = exec.CommandContext(ctx, shell, "-c", finalCommand) } - // 处理环境变量 + // 处理环境变量(始终继承系统环境变量) + cmd.Env = os.Environ() if task.Envs != "" { envVars := a.parseEnvVars(task.Envs) if len(envVars) > 0 { - cmd.Env = append(os.Environ(), envVars...) + cmd.Env = append(cmd.Env, envVars...) log.Infof("任务 #%d 设置了 %d 个环境变量", task.ID, len(envVars)) } } diff --git a/internal/services/tasks/task_execution_service.go b/internal/services/tasks/task_execution_service.go index b505727..4151d68 100644 --- a/internal/services/tasks/task_execution_service.go +++ b/internal/services/tasks/task_execution_service.go @@ -5,6 +5,7 @@ import ( "baihu/internal/database" "baihu/internal/logger" "baihu/internal/models" + "baihu/internal/utils" "bytes" "context" "fmt" @@ -194,12 +195,15 @@ func (s *TaskExecutionService) prepareCommand(ctx context.Context, task *models. if task.WorkDir != "" { command = fmt.Sprintf("cd %s && %s", task.WorkDir, command) } - cmd = exec.CommandContext(ctx, "sh", "-c", command) + // 使用工具函数获取合适的 shell + shell, _ := utils.GetShell() + cmd = exec.CommandContext(ctx, shell, "-c", command) } - // 设置环境变量 + // 设置环境变量(始终继承系统环境变量) + cmd.Env = os.Environ() if len(envVars) > 0 { - cmd.Env = append(os.Environ(), envVars...) + cmd.Env = append(cmd.Env, envVars...) } return cmd, nil diff --git a/internal/utils/shell.go b/internal/utils/shell.go index 9e68380..fe42c2c 100644 --- a/internal/utils/shell.go +++ b/internal/utils/shell.go @@ -17,15 +17,16 @@ func GetShell() (shell string, args []string) { return envShell, []string{} } - // macOS 默认使用 zsh - if runtime.GOOS == "darwin" { - if _, err := exec.LookPath("/bin/zsh"); err == nil { - return "/bin/zsh", []string{} + // 尝试按优先级查找可用的 shell + shells := []string{"/bin/bash", "/bin/zsh", "/bin/sh"} + for _, sh := range shells { + if _, err := os.Stat(sh); err == nil { + return sh, []string{} } } - // Linux 默认使用 bash - return "/bin/bash", []string{} + // 最后回退到 sh(应该总是存在) + return "sh", []string{} } // GetShellCommand 返回执行命令的 shell 和参数