Você não pode, de maneira portável, colocar mais de um argumento em uma #!
linha . Isso significa apenas um caminho completo e um argumento (por exemplo, #!/bin/sed -f
ou #!/usr/bin/sed -f
) ou #!/usr/bin/env
nenhum argumento para o intérprete.
Uma solução alternativa para obter um script portátil é usar #!/bin/sh
um invólucro de shell, passando o script sed como um argumento da linha de comando. Observe que isso não é sancionado pelo POSIX (scripts de várias instruções devem ser escritos com um -e
argumento separado para cada instrução de portabilidade), mas funciona com muitas implementações.
#!/bin/sh
exec sed '
s/a/b/
' "$@"
Para um script longo, pode ser mais conveniente usar um heredoc. Uma vantagem de um heredoc é que você não precisa citar as aspas simples, se houver. Uma desvantagem importante é que o script é alimentado para sed em sua entrada padrão, com duas conseqüências irritantes. Algumas versões do sed requerem, em -f /dev/stdin
vez de -f -
, o que é um problema de portabilidade. Pior, o script não pode atuar como um filtro, porque a entrada padrão é o script e não pode ser os dados.
#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF
A desvantagem do heredoc pode ser remediada com um uso útil de cat
. Como isso coloca o script inteiro na linha de comando novamente, ele não é compatível com POSIX, mas é amplamente portátil na prática.
#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF
Outra solução alternativa é escrever um script que possa ser analisado por sh e por sed. Isso é portátil, razoavelmente eficiente, apenas um pouco feio.
#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/
Explicações:
- Sob sh: defina uma função chamada
b
; o conteúdo não importa, desde que a função esteja sintaticamente bem formada (em particular, você não pode ter uma função vazia). Então, se verdadeiro (ou seja, sempre), execute sed
o script.
- Sob sed: ramifique para o
()
rótulo, em seguida, alguma entrada bem formada. Em seguida, um i
comando, que não tem efeito, porque é sempre ignorado. Finalmente, o ()
rótulo seguido pela parte útil do script.
- Testado sob GNU sed, BusyBox e OpenBSD. (Você pode se safar de algo mais simples no GNU sed, mas o OpenBSD sed é exigente quanto às partes que pula.)