Anda tidak bisa, dengan mudah, menempatkan lebih dari satu argumen pada satu #!
baris . Itu berarti hanya path lengkap dan satu argumen (mis#!/bin/sed -f
atau #!/usr/bin/sed -f
), atau #!/usr/bin/env
dan tidak ada argumen untuk penerjemah.
Sebuah solusi untuk mendapatkan skrip portabel adalah dengan menggunakan #!/bin/sh
dan pembungkus shell, melewati skrip sed sebagai argumen baris perintah. Perhatikan bahwa ini tidak disetujui oleh POSIX (skrip multi-instruksi harus ditulis dengan -e
argumen terpisah untuk setiap instruksi untuk portabilitas), tetapi ia bekerja dengan banyak implementasi.
#!/bin/sh
exec sed '
s/a/b/
' "$@"
Untuk skrip yang panjang, mungkin lebih nyaman menggunakan heredoc. Keuntungan dari heredoc adalah bahwa Anda tidak perlu mengutip kutipan tunggal di dalam, jika ada. Kelemahan utama adalah bahwa skrip diumpankan ke input standarnya, dengan dua konsekuensi yang mengganggu. Beberapa versi sed membutuhkan -f /dev/stdin
bukan -f -
, yang merupakan masalah untuk portabilitas. Lebih buruk lagi, skrip tidak dapat bertindak sebagai filter, karena input standar adalah skrip dan tidak dapat berupa data.
#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF
Kelemahan dari heredoc dapat diatasi dengan penggunaan yang bermanfaat cat
. Karena ini menempatkan seluruh skrip pada baris perintah lagi, itu bukan POSIX-compliant, tetapi sebagian besar portabel dalam praktek.
#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF
Solusi lain adalah dengan menulis skrip yang dapat diuraikan baik oleh sh dan oleh sed. Ini portabel, cukup efisien, hanya sedikit jelek.
#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/
Penjelasan:
- Di bawah sh: tentukan fungsi yang disebut
b
; isinya tidak masalah asalkan fungsi tersebut terbentuk dengan baik secara sintaksis (khususnya, Anda tidak dapat memiliki fungsi kosong). Kemudian jika benar (yaitu selalu), jalankan sed
pada script.
- Di bawah sed: bercabang ke
()
label, kemudian beberapa input yang terbentuk dengan baik. Lalu sebuahi
perintah, yang tidak memiliki efek karena selalu dilewati. Akhirnya ()
label diikuti oleh bagian skrip yang bermanfaat.
- Diuji di bawah GNU, BusyBox, dan OpenBSD. (Anda bisa lolos dengan sesuatu yang lebih sederhana pada GNU sed, tetapi OpenBSD sed pilih-pilih tentang bagian-bagian yang dilompati.)