Watch at EaseHistorias. Respuestas. Perspectiva.

Tecnología · GUÍA PRÁCTICA

¿sed dice “unterminated s command”? Demuestra el límite shell-datos antes de añadir escapes

El diagnóstico solo indica que el programa de sustitución que recibió sed no conserva un cierre utilizable. Captura el argumento y sus bytes, clasifica cuatro familias de fallo y valida la reparación sin edición in situ.

Diagrama del origen en el shell, el vector de argumentos real y el analizador de sed
Ilustración conceptual: inspecciona el argumento y los bytes recibidos por sed antes de cambiar escapes. Watch at Ease

“Unterminated s command” es un informe del analizador, no un diagnóstico completo. El programa de sustitución que llegó a sed ya no tiene un delimitador de cierre válido donde se esperaba. Puede faltar en el origen, aparecer dentro de los datos, llegar un retorno o salto de línea por expansión, o haber sido consumida una comilla o barra por otra capa.

Empieza en el límite del proceso. Captura el argumento exacto enviado a sed y examina sus bytes antes de cambiar escapes. Cuando veas el límite roto, corrige solo la capa propietaria, prueba el texto transformado en un ejemplo pequeño sin -i y añade la edición in situ únicamente cuando la diferencia sea exacta.

1. Captura lo que sed recibió realmente

Reproduce con la entrada mínima y quita -i. El trazado del shell es solo una pista; donde exista soporte, imprime un argumento escapado por línea y usa od o xxd para ver delimitadores, barras, retornos y saltos ocultos por la terminal.

Anota los propietarios en orden: shell o script, expansión de parámetros, sustitución de comandos, plantilla YAML o CI, capa SSH o contenedor y finalmente sed. No uses eval: añade otro analizador y cambia la evidencia.

2. Clasifica el límite roto

Si el argumento final nunca tuvo el tercer delimitador, corrige la sintaxis. Si los datos contienen el delimitador, elige otro o escapa solo ese campo. Si hay CR o salto de línea, decide primero si esos datos multilínea pertenecen a este comando.

Si funciona localmente y falla en CI, YAML, SSH o sustitución de comandos, compara los bytes en cada transferencia. El primer límite que cambia es dueño de la reparación; añadir barras después solo oculta la causa.

3. Escapa patrón y reemplazo por separado

El campo de expresión regular y el de reemplazo son lenguajes distintos. Los metacaracteres pertenecen a la decisión del patrón. En el reemplazo, & inserta el texto coincidente y las barras introducen escapes. Resuelve primero las comillas del shell y aplica después el mínimo escape de sed para ese campo.

Con datos complejos usa un codificador específico o genera un archivo de script sed desde una plantilla controlada. Si un analizador estructurado o una biblioteca puede expresar el límite, no concatenes texto no confiable dentro de sintaxis ejecutable.

4. Prueba una matriz de fallos, no un valor feliz

Con una muestra pequeña prueba valor vacío, espacios, delimitador, ampersand, barra inversa, CR, salto de línea y un valor que no coincide. Compara stdout con el archivo esperado; dejar de mostrar el error no demuestra una transformación correcta.

Repite a través de la capa que falló. Un éxito directo en terminal no valida YAML, SSH, la entrada de un contenedor o una variable de compilación. Conserva el argumento capturado y la salida esperada como prueba de regresión.

5. Añade edición in situ solo tras una diferencia exacta

Ejecuta primero la expresión aprobada sobre una copia. Comprueba la implementación porque GNU, BSD y BusyBox difieren en -i y el sufijo de respaldo; conserva una copia o reemplazo atómico si el archivo importa.

La reparación termina cuando la capa real emite los bytes revisados, la diferencia de la muestra es exacta, los casos límite siguen literales y la copia cambia una sola vez. Si falta algún propietario o byte, detente en stdout y conserva la evidencia.

Matriz de cuatro clases para diagnosticar una sustitución sed sin terminar
Ilustración conceptual: repara la clase propietaria y supera la prueba sin edición in situ. Watch at Ease