GNU/Linux >> Belajar Linux >  >> Linux

Kapan saya harus menggunakan #!/bin/bash dan kapan #!/bin/sh?

Singkatnya:

  • Ada beberapa shell yang mengimplementasikan superset dari spesifikasi sh POSIX. Pada sistem yang berbeda, /bin/sh mungkin link ke ash, bash, dash, ksh, zsh, &c. (Ini akan selalu kompatibel dengan sh – tidak pernah csh atau fish.)

  • Selama Anda tetap menggunakan sh fitur saja, Anda dapat (dan bahkan mungkin seharusnya) menggunakan #!/bin/sh dan skrip harus berfungsi dengan baik, apa pun shell-nya.

  • Jika Anda mulai menggunakan fitur khusus bash (mis. array), Anda harus secara khusus meminta bash – karena, meskipun /bin/sh sudah memanggil bash di your sistem, mungkin tidak pada milik orang lain sistem, dan skrip Anda tidak akan berjalan di sana. (Hal yang sama tentu saja berlaku untuk zsh dan ksh.) Anda dapat menggunakan shellcheck untuk mengidentifikasi bashism.

  • Meskipun skrip hanya untuk penggunaan pribadi, Anda mungkin memperhatikan bahwa beberapa OS mengubah /bin/sh selama peningkatan – mis. di Debian dulu bash, tapi kemudian diganti dengan tanda hubung yang sangat minim. Skrip yang menggunakan bashism tetapi memiliki #!/bin/sh tiba-tiba rusak.

Namun:

  • Bahkan #!/bin/bash tidak terlalu benar. Pada sistem yang berbeda, bash mungkin berada di /usr/bin atau /usr/pkg/bin atau /usr/local/bin .

  • Opsi yang lebih andal adalah #!/usr/bin/env bash , yang menggunakan $PATH. (Meskipun env alat itu sendiri juga tidak dijamin secara ketat, /usr/bin/env masih berfungsi di lebih banyak sistem daripada /bin/bash melakukannya.)


Gunakan shebang yang sesuai dengan shell yang sebenarnya Anda gunakan untuk mengembangkan dan men-debug skrip Anda. Yaitu. jika shell login Anda adalah bash , dan Anda menjalankan skrip Anda sebagai yang dapat dieksekusi di terminal Anda, gunakan #!/bin/bash . Jangan hanya berasumsi bahwa karena Anda belum pernah menggunakan array (atau bash apa pun fitur yang Anda ketahui), Anda aman untuk memilih shell apa pun yang Anda suka. Ada banyak perbedaan halus antara shell (echo , function, loops, sebut saja) yang tidak dapat ditemukan tanpa pengujian yang tepat.

Pertimbangkan ini:jika Anda meninggalkan #!/bin/bash dan pengguna Anda tidak memilikinya, mereka akan melihat pesan kesalahan yang jelas, seperti

Error: /bin/bash not found

Sebagian besar pengguna dapat memperbaikinya dalam waktu kurang dari satu menit dengan menginstal paket yang sesuai. Di sisi lain, jika Anda mengganti shebang dengan #!/bin/sh dan mengujinya pada sistem tempat /bin/sh adalah symlink ke /bin/bash , pengguna Anda yang tidak memiliki bash akan berada dalam kesulitan. Mereka kemungkinan besar akan melihat pesan kesalahan samar seperti:

Error in script.sh line 123: error parsing token xyz

Ini mungkin memakan waktu berjam-jam untuk memperbaikinya, dan tidak akan ada petunjuk tentang shell mana yang harus mereka gunakan.

Tidak banyak alasan mengapa Anda ingin menggunakan shell yang berbeda di shebang. Salah satu alasannya adalah ketika shell yang Anda gunakan tidak tersebar luas. Satu lagi adalah untuk mendapatkan kinerja dengan sh yang secara signifikan lebih cepat pada beberapa sistem, DAN skrip Anda akan menjadi hambatan kinerja. Jika demikian, uji skrip Anda secara menyeluruh dengan shell target, lalu ubah shebang.


Anda seharusnya hanya menggunakan #! /bin/sh .

Anda tidak boleh menggunakan ekstensi bash (atau zsh, atau fish, atau ...) dalam skrip shell.

Anda hanya boleh menulis skrip shell yang berfungsi dengan apa saja implementasi bahasa shell (termasuk semua program "utilitas" yang sejalan dengan shell itu sendiri). Hari-hari ini Anda mungkin ambil POSIX.1-2001 (bukan -2008) sebagai otoritatif untuk apa yang mampu dilakukan oleh shell dan utilitas, tetapi perlu diketahui bahwa suatu hari Anda mungkin dipanggil untuk mem-porting skrip Anda ke sistem lawas (mis. Solaris atau AIX) yang shell dan utilitasnya dibekukan sekitar tahun 1992.

Apa, serius?!

Ya, serius.

Inilah masalahnya:Shell itu mengerikan bahasa pemrograman. Satu-satunya hal yang terjadi adalah /bin/sh adalah satu-satunya penerjemah skrip yang setiap Instalasi Unix dijamin memiliki.

Inilah hal lainnya:beberapa iterasi dari interpreter inti Perl 5 (/usr/bin/perl ) adalah lebih kemungkinan akan tersedia pada instalasi Unix yang dipilih secara acak dari (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash adalah. Bahasa skrip bagus lainnya (Python, Ruby, node.js, dll. — Saya bahkan akan menyertakan PHP dan Tcl dalam kategori tersebut jika dibandingkan dengan shell) juga tersedia secara kasar seperti bash dan shell tambahan lainnya.

Oleh karena itu, jika Anda memiliki opsi untuk menulis skrip bash, Anda memiliki opsi untuk menggunakan bahasa pemrograman yang tidak buruk.

Sekarang, sederhana skrip shell, jenis yang hanya menjalankan beberapa program secara berurutan dari tugas cron atau semacamnya, tidak ada salahnya membiarkannya sebagai skrip shell. Tetapi skrip shell sederhana tidak memerlukan larik atau fungsi atau [[ bahkan. Dan Anda hanya boleh menulis rumit skrip shell saat Anda tidak punya pilihan lain. Skrip autoconf, misalnya, masih merupakan skrip shell. Namun skrip tersebut harus dijalankan di setiap inkarnasi dari /bin/sh yang relevan dengan program yang sedang dikonfigurasi. dan itu berarti mereka tidak dapat menggunakan ekstensi apa pun. Anda mungkin tidak perlu peduli dengan Unix berpemilik lama akhir-akhir ini, tetapi Anda mungkin harus peduli dengan BSD sumber terbuka saat ini, beberapa di antaranya tidak menginstal bash secara default, dan lingkungan tersemat yang hanya memberi Anda shell minimal dan busybox .

Kesimpulannya, saat Anda mendapati diri Anda menginginkan fitur yang tidak tersedia dalam bahasa shell portabel, itu adalah tanda bahwa skrip menjadi terlalu rumit untuk tetap menjadi skrip shell. Tulis ulang dalam bahasa yang lebih baik.


Linux
  1. Bagaimana Linux Menangani Beberapa Pemisah Jalur Berturut-turut (/home////username///file)?

  2. Apakah Ruang Diizinkan Antara #! Dan /bin/bash Di Shebang?

  3. Bash =~ Regex Dan Https://regex101.com/?

  1. Mengapa Tidak Ada yang Menggunakan Shell Bourne Sejati Sebagai /bin/sh?

  2. Linux – Menggabungkan /usr/bin Dan /usr/sbin Ke /bin (gnu/linux)?

  3. cmake --version menunjuk ke /usr/bin/cmake sementara cmake menunjuk ke /usr/local/bin

  1. /usr/bin Vs /usr/local/bin Di Linux?

  2. Kapan saya harus menggunakan /dev/shm/ dan kapan saya harus menggunakan /tmp/?

  3. Perbedaan antara /bin dan /usr/bin