| 42 | var _ agentexec.Execer = (*commandEnvExecer)(nil) |
| 43 | |
| 44 | func (e *commandEnvExecer) prepare(ctx context.Context, inName string, inArgs ...string) (name string, args []string, dir string, env []string) { |
| 45 | shell, dir, env, err := e.commandEnv(nil, nil) |
| 46 | if err != nil { |
| 47 | e.logger.Error(ctx, "get command environment failed", slog.Error(err)) |
| 48 | return inName, inArgs, "", nil |
| 49 | } |
| 50 | |
| 51 | name = shell |
| 52 | // Pass the command through the shell as positional parameters and run |
| 53 | // "$@" so the shell re-emits argv verbatim without re-parsing it. This |
| 54 | // prevents arguments containing shell metacharacters such as $, `, and |
| 55 | // quotes from being interpreted (e.g. command substitution). The token |
| 56 | // before them fills $0, which "$@" never references, so it is discarded. |
| 57 | // This assumes a POSIX shell; Windows is not supported here. |
| 58 | cmdArgs := append([]string{inName}, inArgs...) |
| 59 | args = append([]string{"-c", `"$@"`, ""}, cmdArgs...) |
| 60 | return name, args, dir, env |
| 61 | } |
| 62 | |
| 63 | func (e *commandEnvExecer) CommandContext(ctx context.Context, cmd string, args ...string) *exec.Cmd { |
| 64 | name, args, dir, env := e.prepare(ctx, cmd, args...) |