Non puoi, portabilmente, mettere più di un argomento su una #!
riga . Ciò significa solo un percorso completo e un argomento (ad esempio #!/bin/sed -f
o #!/usr/bin/sed -f
) o #!/usr/bin/env
nessun argomento per l'interprete.
Una soluzione alternativa per ottenere uno script portatile consiste nell'utilizzare #!/bin/sh
un involucro della shell, passando lo script sed come argomento della riga di comando. Si noti che questo non è sanzionato da POSIX (gli script multiistruzione devono essere scritti con un -e
argomento separato per ciascuna istruzione per la portabilità), ma funziona con molte implementazioni.
#!/bin/sh
exec sed '
s/a/b/
' "$@"
Per una sceneggiatura lunga, può essere più comodo usare una eredità. Un vantaggio di una eredità è che non è necessario citare le virgolette singole all'interno, se presenti. Un grande svantaggio è che la sceneggiatura è alimentata da sed sul suo input standard, con due fastidiose conseguenze. Alcune versioni di sed richiedono -f /dev/stdin
invece di -f -
, il che è un problema per la portabilità. Peggio ancora, lo script non può fungere da filtro, perché l'input standard è lo script e non può essere i dati.
#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF
Il rovescio della medaglia dell'ereditarietà può essere risolto da un uso utile di cat
. Dal momento che questo pone di nuovo l'intero script sulla riga di comando, non è conforme a POSIX, ma in pratica in gran parte portabile.
#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF
Un'altra soluzione alternativa è scrivere una sceneggiatura che può essere analizzata sia da sh che da sed. È portatile, abbastanza efficiente, solo un po 'brutto.
#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/
spiegazioni:
- Sotto sh: definisce una funzione chiamata
b
; i contenuti non contano finché la funzione è sintatticamente ben formata (in particolare, non è possibile avere una funzione vuota). Quindi, se vero (cioè sempre), esegui sed
sullo script.
- Sotto sed: ramo
()
all'etichetta, quindi alcuni input ben formati. Quindi un i
comando, che non ha alcun effetto perché viene sempre ignorato. Finalmente l' ()
etichetta seguita dalla parte utile della sceneggiatura.
- Testato sotto GNU sed, BusyBox e OpenBSD. (Puoi cavartela con qualcosa di più semplice su GNU sed, ma OpenBSD sed è esigente riguardo alle parti che salta.)