Saya memiliki skrip shell ini disimpan dalam file: ia melakukan beberapa penggantian string dasar.
#!/bin/sh
html_file=$1
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
Jika saya tempel ke baris perintah, itu berfungsi dengan baik:
$ html_file="/home/max/for_pauld/test_no_base64.html"
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
memberi
html_file = /home/max/for_pauld/test_no_base64.html
pdf_file = /home/max/for_pauld/test_no_base64.pdf
Itulah output dari gema di atas - itu berfungsi sebagaimana dimaksud.
Tapi, ketika saya memanggil skrip, dengan
$ saucer "/home/max/for_pauld/test_no_base64.html"
Saya mendapatkan hasil ini:
html_file = /home/max/for_pauld/test_no_base64.html
/home/max/bin/saucer: 5: /home/max/bin/saucer: Bad substitution
Apakah skrip saya menggunakan versi bash yang berbeda atau apa? Apakah saya perlu mengubah jalur shebang saya?
sh
danbash
. Saya akan membacanya. Jika Anda bisa repot-repot membuat komentar Anda menjadi jawaban maka saya akan menandainya dengan benar.#!/usr/bin/env bash
sebagai shebang Anda, dan gunakan substitusi yang sudah pasti seperti yang Anda inginkan, tetapi dengan peringatan portabilitas. Dan baca: unix.stackexchange.com/a/48787/27616Jawaban:
Apa itu sh
sh
(atau Bahasa Perintah Shell) adalah bahasa pemrograman yang dijelaskan oleh standar POSIX . Ini memiliki banyak implementasi (ksh88
,dash
, ...).bash
juga dapat dianggap sebagai implementasish
(lihat di bawah).Karena
sh
ini adalah spesifikasi, bukan implementasi,/bin/sh
adalah symlink (atau hard link) untuk implementasi aktual pada sebagian besar sistem POSIX.Apa itu bash
bash
dimulai sebagaish
implementasi -kompatibel (meskipun ia mendahului standar POSIX beberapa tahun), tetapi seiring berjalannya waktu ia telah memperoleh banyak ekstensi. Banyak dari ekstensi ini dapat mengubah perilaku skrip POSIX shell yang valid, jadi dengan sendirinyabash
bukan shell POSIX yang valid. Sebaliknya, ini adalah dialek bahasa shell POSIX.bash
mendukung--posix
switch, yang membuatnya lebih kompatibel dengan POSIX. Itu juga mencoba untuk meniru POSIX jika dipanggil sebagaish
.sh = bash?
Untuk waktu yang lama,
/bin/sh
digunakan untuk menunjuk/bin/bash
pada sebagian besar sistem GNU / Linux. Akibatnya, hampir menjadi aman untuk mengabaikan perbedaan antara keduanya. Tapi itu mulai berubah baru-baru ini.Beberapa contoh populer sistem di mana
/bin/sh
tidak menunjuk/bin/bash
(dan beberapa di antaranya/bin/bash
bahkan mungkin tidak ada) adalah:sh
untukdash
secara default;initramfs
. Ia menggunakanash
implementasi shell.pdksh
, keturunan dari shell Korn. FreeBSD'ssh
adalah turunan dari shell UNIX Bourne yang asli. Solaris memiliki sendirish
yang untuk waktu yang lama tidak sesuai dengan POSIX; implementasi gratis tersedia dari proyek Heirloom .Bagaimana Anda bisa mengetahui
/bin/sh
poin apa yang ada di sistem Anda?Kerumitannya
/bin/sh
bisa berupa tautan simbolik atau tautan keras. Jika itu tautan simbolis, cara portabel untuk mengatasinya adalah:Jika ini tautan keras, coba
Faktanya,
-L
flag tersebut mencakup symlink dan hardlink, tetapi kelemahan dari metode ini adalah tidak portable - POSIX tidak perlufind
mendukung-samefile
opsi, meskipun GNU menemukan dan FreeBSD menemukan mendukungnya.Garis Shebang
Pada akhirnya, terserah Anda untuk memutuskan mana yang akan digunakan, dengan menulis baris «shebang».
Misalnya
akan menggunakan
sh
(dan apa pun yang terjadi menunjuk ke),akan digunakan
/bin/bash
jika tersedia (dan gagal dengan pesan kesalahan jika tidak). Tentu saja, Anda juga dapat menentukan implementasi lain, misYang mana yang akan digunakan
Untuk skrip saya sendiri, saya lebih suka
sh
karena alasan berikut:bash
, mereka diharuskan memilikinyash
Ada keuntungan menggunakan
bash
juga. Fitur-fiturnya membuat pemrograman lebih mudah dan mirip dengan pemrograman dalam bahasa pemrograman modern lainnya. Ini termasuk hal-hal seperti scoping variabel lokal dan array. Plainsh
adalah bahasa pemrograman yang sangat minimalis.sumber
/bin/sh
memang merupakan symlink ke/bin/dash
.Menambahkan ke jawaban yang sangat baik dari @ Hunter.S.Thompson Saya ingin menunjukkan bahwa bagian non-portabel dari skrip adalah
Ini
${variable/search/replace}
adalah ekstensi GNU. Tetapi Anda dapat dengan mudah menghindarinya dengan POSIX murni:Mengikuti Hunter, ini adalah perbaikan yang lebih baik daripada mengubah shebang menjadi
#! /bin/bash
sumber