No puede, de forma portátil, poner más de un argumento en una #!
línea . Eso significa solo una ruta completa y un argumento (p. Ej. #!/bin/sed -f
O #!/usr/bin/sed -f
), o #!/usr/bin/env
sin argumento para el intérprete.
Una solución para obtener un script portátil es usar #!/bin/sh
un contenedor de shell, pasando el script sed como un argumento de línea de comandos. Tenga en cuenta que POSIX no lo autoriza (los scripts de instrucciones múltiples deben escribirse con un -e
argumento separado para cada instrucción de portabilidad), pero funciona con muchas implementaciones.
#!/bin/sh
exec sed '
s/a/b/
' "$@"
Para una secuencia de comandos larga, puede ser más conveniente usar un heredoc. Una ventaja de un heredoc es que no necesita citar las comillas simples dentro, si las hay. Una desventaja importante es que el script se alimenta a sed en su entrada estándar, con dos consecuencias molestas. Algunas versiones de sed requieren en -f /dev/stdin
lugar de -f -
, lo cual es un problema para la portabilidad. Peor aún, el script no puede actuar como un filtro, porque la entrada estándar es el script y no puede ser la información.
#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF
La desventaja del heredoc puede remediarse mediante un uso útil de cat
. Dado que esto vuelve a colocar todo el script en la línea de comando, no es compatible con POSIX, sino que es prácticamente portátil en la práctica.
#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF
Otra solución es escribir un script que pueda analizarse tanto por sh como por sed. Esto es portátil, razonablemente eficiente, solo un poco feo.
#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/
Explicaciones:
- Bajo sh: define una función llamada
b
; el contenido no importa siempre que la función esté sintácticamente bien formada (en particular, no puede tener una función vacía). Entonces, si es verdadero (es decir, siempre), ejecute sed
en el script.
- Bajo sed: se ramifica a la
()
etiqueta, luego una entrada bien formada. Luego, un i
comando, que no tiene ningún efecto porque siempre se omite. Finalmente la ()
etiqueta seguida de la parte útil del guión.
- Probado bajo GNU sed, BusyBox y OpenBSD. (Puede salirse con la suya con algo más simple en GNU sed, pero OpenBSD sed es exigente con las partes que omite).