---
name: process_spawn
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func ProcessSpawn(command string, dir string, env []string, shell string) (*ProcessHandle, error)"
description: "Lanza un subproceso usando el shell indicado. Si shell esta vacio usa 'sh'. Comandos con newlines se tratan como scripts multilinea (se escriben a un archivo temporal). Configura un process group propio (Setpgid) para poder matar todos los hijos con ProcessKill. Captura stdout y stderr via pipes."
tags: [process, subprocess, spawn, exec, shell, infra]
uses_functions: []
uses_types: [process_handle_go_infra]
returns: [process_handle_go_infra]
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os, os/exec, strings, syscall, time]
params:
  - name: command
    desc: "comando shell a ejecutar; si contiene newlines se trata como script multilinea"
  - name: dir
    desc: "directorio de trabajo del proceso hijo; vacio hereda el del proceso padre"
  - name: env
    desc: "variables de entorno en formato KEY=VALUE; nil hereda el entorno del proceso padre"
  - name: shell
    desc: "interprete shell a usar (sh, bash, zsh); vacio usa 'sh'"
output: "handle del proceso lanzado con Cmd, Pid, StartTime, Dir y los pipes de I/O"
tested: true
tests:
  - "spawn and wait echo"
  - "spawn with timeout kills"
  - "spawn with env"
  - "spawn script"
  - "spawn with working dir"
  - "kill process"
test_file_path: "functions/infra/process_spawn_test.go"
file_path: "functions/infra/process_spawn.go"
---

## Ejemplo

```go
h, err := ProcessSpawn("echo hello", "", nil, "")
if err != nil {
    log.Fatal(err)
}
res, err := ProcessWait(h, 10)
fmt.Println(res.Stdout) // "hello\n"
```

## Notas

Funcion impura: hace I/O (crea archivo temporal para scripts, lanza proceso). El process group (Setpgid=true) permite a ProcessKill enviar senales al grupo completo con -Pid, afectando a todos los hijos del proceso lanzado. Para scripts multilinea el archivo temporal queda en el directorio temporal del OS y no se limpia automaticamente.
