| 495 | } |
| 496 | |
| 497 | func (r *BashRuntime) Execute(ctx context.Context, code string, input map[string]any) (*ExecutionResult, error) { |
| 498 | start := time.Now() |
| 499 | |
| 500 | // 创建临时文件 |
| 501 | tmpFile, err := os.CreateTemp(r.config.WorkDir, "aster_*.sh") |
| 502 | if err != nil { |
| 503 | return nil, fmt.Errorf("create temp file: %w", err) |
| 504 | } |
| 505 | defer func() { _ = os.Remove(tmpFile.Name()) }() |
| 506 | |
| 507 | // 包装代码 |
| 508 | wrappedCode := r.wrapCode(code, input) |
| 509 | if _, err := tmpFile.WriteString(wrappedCode); err != nil { |
| 510 | return nil, fmt.Errorf("write code: %w", err) |
| 511 | } |
| 512 | _ = tmpFile.Close() |
| 513 | |
| 514 | // 设置执行权限 |
| 515 | if err := os.Chmod(tmpFile.Name(), 0755); err != nil { |
| 516 | return nil, fmt.Errorf("chmod: %w", err) |
| 517 | } |
| 518 | |
| 519 | // 创建带超时的 context |
| 520 | execCtx, cancel := context.WithTimeout(ctx, r.config.Timeout) |
| 521 | defer cancel() |
| 522 | |
| 523 | // 执行 Bash |
| 524 | cmd := exec.CommandContext(execCtx, r.bashPath, tmpFile.Name()) |
| 525 | cmd.Dir = r.config.WorkDir |
| 526 | |
| 527 | // 设置环境变量 |
| 528 | cmd.Env = os.Environ() |
| 529 | for k, v := range r.config.Env { |
| 530 | cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v)) |
| 531 | } |
| 532 | // 将 input 作为环境变量 |
| 533 | for k, v := range input { |
| 534 | if str, ok := v.(string); ok { |
| 535 | cmd.Env = append(cmd.Env, fmt.Sprintf("INPUT_%s=%s", strings.ToUpper(k), str)) |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | var stdout, stderr bytes.Buffer |
| 540 | cmd.Stdout = &stdout |
| 541 | cmd.Stderr = &stderr |
| 542 | |
| 543 | err = cmd.Run() |
| 544 | duration := time.Since(start).Milliseconds() |
| 545 | |
| 546 | result := &ExecutionResult{ |
| 547 | Stdout: truncateOutput(stdout.String(), r.config.MaxOutput), |
| 548 | Stderr: truncateOutput(stderr.String(), r.config.MaxOutput), |
| 549 | Duration: duration, |
| 550 | } |
| 551 | |
| 552 | if err != nil { |
| 553 | if execCtx.Err() == context.DeadlineExceeded { |
| 554 | result.Error = "execution timeout" |