Mengapa Anda harus meletakkan #! / Bin / bash di awal file skrip?

487

Saya telah membuat skrip Bash sebelumnya dan semuanya berjalan baik tanpa #!/bin/bashdi awal.

Apa gunanya memasukkannya? Apakah ada yang berbeda?

Juga, bagaimana Anda mengucapkannya #? Saya tahu itu !diucapkan sebagai "bang."

Bagaimana cara #!diucapkan?

simpul ninja
sumber
8
Anda tidak perlu dan Anda tidak seharusnya kecuali Anda tidak punya pilihan. Gunakan '#! / Bin / sh' selagi bisa dan pelajari tentang perbedaan antara shell (POSIX) dan bash. Akan datang sehari sebelum resume Anda tumbuh terlalu lama ketika Anda akan menemukan diri Anda pada sistem dengan shell yang berbeda dan Anda masih ingin skrip Anda bekerja.
Jens
50
Diucapkan "Hash-Bang" atau "She-Bang".
Beachhouse
22
Saya pikir perlu dicatat bahwa ini hanya dijalankan jika Anda menjalankan skrip Anda sebagai executable. Jadi jika Anda mengatur flag yang dapat dieksekusi dan kemudian mengetik ./yourscript.extension, misalnya, ./helloworld.pyatau ./helloworld.sh, itu akan mencari penerjemah di baris atas itu, yang akan menjadi #!/bin/pythonatau !#/bin/bash, sedangkan ketika menjalankan script seperti python helloworld.py, baris pertama tidak akan diamati karena dikomentari di luar. Jadi ini adalah urutan khusus untuk shell / kernel.
JFA
@JFA apakah ada perubahan urutan antara bash dan python, saat menggunakan! # Untuk python dan #! untuk bash?
AAI
1
@Ajeya dan tidak, itu adalah kesalahan ketik, tangkapan bagus
JFA

Jawaban:

426

Ini adalah konvensi sehingga shell * nix tahu jenis interpreter apa yang harus dijalankan.

Misalnya, rasa ATT yang lebih lama default ke sh (the Bourne shell), sementara versi BSD yang lebih lama default ke csh (shell C).

Bahkan hari ini (di mana sebagian besar sistem menjalankan bash, "Bourne Again Shell" ), skrip dapat menggunakan bash, python, perl, ruby, PHP, dll, dll. Misalnya, Anda mungkin melihat #!/bin/perlatau #!/bin/perl5.

PS: Tanda seru ( !) disebut "bang" . Simbol komentar shell ( #) kadang-kadang disebut "hash" .

PPS: Ingat - di bawah * nix, mengaitkan sufiks dengan tipe file hanyalah konvensi , bukan "aturan" . Sebuah executable dapat berupa program biner, salah satu dari sejuta jenis skrip dan hal lainnya juga. Maka kebutuhan untuk #!/bin/bash.

paulsm4
sumber
1
Saya menemukan sesuatu yang bermanfaat, $ #. Disebut apa itu?
simpul ninja
91
Shebang bukan konvensi shell , ia diinterpretasikan oleh kernel saat menangani execve(2)syscall; jadi shebang adalah konvensi kernel , bukan shell.
Basile Starynkevitch
10
Juga, ini membantu beberapa editor seperti Vim menentukan bahasa untuk penyorotan sintaksis jika file tidak memiliki ekstensi. Tanpa shebang, Vim akan menampilkan skrip bash sama dengan file teks biasa.
Aaron Blenkush
1
Itu membuat saya bertanya-tanya apakah Anda perlu menambahkan #!/bin/shhal-hal seperti .profiledan hal-hal yang berjalan onload
Kolob Canyon
5
Jadi ... hash-bang-slash-bin-slash-bash ?
Bernat
135

Untuk lebih tepatnya shebang #! , ketika itu adalah dua byte pertama dari file ( x mode ) yang dapat dieksekusi , ditafsirkan oleh panggilan sistem execve (2) (yang menjalankan program). Tetapi spesifikasi POSIX untukexecve tidak menyebutkan shebang.

Itu harus diikuti oleh path file dari interpreter executable (yang BTW bahkan bisa relatif, tetapi paling sering absolut).

Trik yang bagus (atau mungkin tidak terlalu bagus ) untuk menemukan penerjemah (mis. python) Pada pengguna $PATHadalah dengan menggunakan envprogram (selalu ada di /usr/bin/envsemua Linux) seperti mis.

 #!/usr/bin/env python

Setiap eksekusi ELF dapat menjadi juru bahasa. Anda bahkan dapat menggunakan #!/bin/catatau #!/bin/truejika Anda mau! (tapi itu akan sering tidak berguna)

Basile Starynkevitch
sumber
8
Lihat pertanyaan ini untuk diskusi tentang #!/usr/bin/envperetasan.
Keith Thompson
jika saya ingin memberikan argumen ke python bagaimana saya melakukan itu sebenarnya saya ingin mengeksekusi #!/usr/bin/env bash -x. Bagaimana aku melakukan itu ?
indianwebdevil
sederhana saya sendiri menemukannya, tambahkan saja param setelah itu#!/usr/bin/env bash -x
indianwebdevil
bashhampir selalu /bin/bashjadi shebang Anda seharusnya#!/bin/bash -x
Basile Starynkevitch
50

Ini disebut shebang . Dalam unix-speak, # disebut sharp (seperti dalam musik) atau hash (seperti hashtag di twitter), dan! disebut bang. (Anda benar-benar dapat merujuk perintah shell sebelumnya dengan !!, disebut bang-bang). Jadi ketika disatukan, Anda mendapatkan haSH-BANG, atau shebang.

Bagian setelah #! memberitahu Unix program apa yang digunakan untuk menjalankannya. Jika tidak ditentukan, ia akan mencoba dengan bash (atau sh, atau zsh, atau apa pun variabel $ SHELL Anda), tetapi jika ada, ia akan menggunakan program itu. Plus, # adalah komentar dalam sebagian besar bahasa, sehingga baris tersebut diabaikan dalam eksekusi berikutnya.

austin1howard
sumber
2
Jika saya sudah di bash, apakah itu memulai contoh bash lain jika melihat #! / Bin / bash? Bagaimana jika saya sudah di bash dan saya meninggalkannya? Apakah ada perbedaan?
simpul ninja
2
@javascriptninja, baik itu memulai bash shell baru. Dalam kasus bash, sebenarnya tidak ada perbedaan, selama Anda sudah menggunakan bash. Shebang hanya benar-benar penting jika (a) Anda perlu menjalankan sesuatu yang bukan hanya shell, seperti python atau perl, atau (b) Anda tidak menggunakan bash shell (yaitu Anda menggunakan zsh) tetapi Anda harus jalankan sesuatu yang mengharuskan dijalankan di bash.
austin1howard
Namun, menurut saya itu praktik yang baik untuk memasukkan shebang, supaya seseorang yang membaca kode tahu apa yang terjadi.
austin1howard
2
Salah: execve(2)syscall tidak menggunakan $SHELLvariabel. Adalah kernel yang mengartikan shebang.
Basile Starynkevitch
1
@ BasileStarynkevitch yang benar, loader elf di kernel mengartikan shebang. Saya menyatakan bahwa $ SHELL akan digunakan jika tidak ada shebang yang disediakan.
austin1howard
19

The shebang adalah direktif untuk loader untuk menggunakan program yang ditetapkan setelah #!sebagai juru bahasa untuk file tersebut ketika Anda mencoba untuk melaksanakannya. Jadi, jika Anda mencoba menjalankan file bernama foo.shyang ada #!/bin/bashdi bagian atas, perintah sebenarnya yang dijalankan adalah /bin/bash foo.sh. Ini adalah cara yang fleksibel dalam menggunakan penerjemah yang berbeda untuk program yang berbeda. Ini adalah sesuatu yang diimplementasikan pada tingkat sistem dan API tingkat pengguna adalah konvensi shebang.

Perlu juga diketahui bahwa shebang adalah angka ajaib - yang dapat dibaca manusia yang mengidentifikasi file sebagai skrip untuk penerjemah yang diberikan.

Maksud Anda tentang hal itu "bekerja" bahkan tanpa shebang hanya karena program tersebut adalah skrip shell yang ditulis untuk shell yang sama dengan yang Anda gunakan. Misalnya, Anda dapat menulis file javascript dengan sangat baik dan kemudian meletakkan #! /usr/bin/js(atau yang serupa) untuk memiliki "skrip Shell" javascript.

Noufal Ibrahim
sumber
18

Sistem operasi menggunakan shell default untuk menjalankan skrip shell Anda. jadi dengan menyebutkan path shell di awal skrip, Anda meminta OS untuk menggunakan shell tersebut. Ini juga berguna untuk portabilitas .

Balaswamy Vaddeman
sumber
15

Setiap distribusi memiliki shell default. Bash adalah default pada sebagian besar sistem. Jika Anda bekerja pada sistem yang memiliki shell default berbeda, maka skrip mungkin tidak berfungsi sebagaimana dimaksud jika ditulis khusus untuk Bash.

Bash telah berevolusi selama bertahun-tahun mengambil kode dari kshdan sh.

Menambahkan #!/bin/bashsebagai baris pertama skrip Anda, memberitahu OS untuk memanggil yang ditentukan shelluntuk menjalankan perintah yang mengikuti skrip.

#! sering disebut sebagai "hash-bang", "she-bang" atau "sha-bang".

jaypal singh
sumber
9

Ini disebut shebang . Ini terdiri dari tanda angka dan karakter tanda seru (#!), Diikuti oleh path lengkap ke penerjemah seperti / bin / bash. Semua skrip di bawah UNIX dan Linux mengeksekusi menggunakan interpreter yang ditentukan pada baris pertama.

Uday Sawant
sumber
0

Ini dapat bermanfaat bagi seseorang yang menggunakan sistem berbeda yang tidak memiliki perpustakaan yang tersedia. Jika itu tidak dideklarasikan dan Anda memiliki beberapa fungsi dalam skrip Anda yang tidak didukung oleh sistem itu, Anda harus mendeklarasikan # / bin / bash. Saya pernah mengalami masalah ini sebelum di tempat kerja dan sekarang saya hanya memasukkannya sebagai latihan.

Beruang
sumber