Dalam bash
atau sh
, saya kira apa yang dimulai dengan #
sebuah komentar .
Namun dalam bash
skrip kami menulis:
#!/bin/bash
Dan dalam skrip Python, ada:
#!/bin/python
Apakah ini berarti bahwa #
dengan sendirinya adalah komentar sedangkan #!
tidak?
#include
. Di sana juga,#
itu tidak dimaksudkan sebagai komentar.Jawaban:
The
#!
line digunakan sebelum script dijalankan, maka diabaikan ketika script berjalan.Anda bertanya apa perbedaan antara garis shebang dan komentar biasa.
Baris yang diawali dengan
#!
komentar sama banyaknya dengan baris lain yang dimulai#
. Ini benar jika#!
ini adalah baris pertama file, atau di mana saja.#!/bin/sh
memiliki efek , tetapi tidak dibaca oleh penerjemah itu sendiri .#
bukan komentar dalam semua bahasa pemrograman tetapi, seperti yang Anda tahu, ini adalah komentar di shell gaya Bourne termasuksh
danbash
(serta sebagian besar shell gaya non-Bourne, seperticsh
). Ini juga komentar dalam Python . Dan itu adalah komentar dalam berbagai file konfigurasi yang sebenarnya bukan skrip (seperti/etc/fstab
).Misalkan skrip shell dimulai dengan
#!/bin/sh
. Itu adalah komentar, dan penerjemah (shell) mengabaikan semua yang ada di baris setelah#
karakter.Tujuan dari suatu
#!
garis bukanlah untuk memberikan informasi kepada penerjemah. Tujuan dari#!
jalur ini adalah untuk memberi tahu sistem operasi (atau proses apa pun yang meluncurkan penerjemah) apa yang harus digunakan sebagai penerjemah .Jika Anda menjalankan skrip sebagai file yang dapat dieksekusi, misalnya, dengan menjalankan
./script.sh
, sistem berkonsultasi dengan baris pertama untuk melihat apakah dimulai dengan#!
, diikuti oleh nol atau lebih banyak ruang, diikuti oleh perintah. Jika ya, ia menjalankan perintah itu dengan nama skrip sebagai argumennya. Dalam contoh ini, ini berjalan/bin/sh script.sh
(atau, secara teknis,/bin/sh ./script.sh
).Jika Anda mengaktifkan skrip dengan secara eksplisit memanggil juru bahasa,
#!
garis itu tidak pernah dikonsultasikan. Jadi, jika Anda menjalankansh script.sh
, baris pertama tidak berpengaruh. Jikascript2.sh
baris pertama adalah#!/usr/games/nibbles
, menjalankansh script2.sh
tidak akan mencoba membuka skrip dinibbles
(tetapi./script2.sh
akan).Anda akan melihat bahwa dalam kedua kasus itu ekstensi skrip (
.sh
), jika ada, berdampak pada bagaimana skrip dijalankan. Dalam sistem seperti Unix, ini biasanya tidak mempengaruhi bagaimana skrip dijalankan. Pada beberapa sistem lain, seperti Windows,#!
garis shebang mungkin diabaikan sepenuhnya oleh sistem, dan ekstensi mungkin menentukan apa yang menjalankan skrip. (Ini tidak berarti Anda harus memberikan ekstensi skrip Anda, tetapi itu adalah salah satu alasan mengapa jika Anda melakukannya, itu harus benar.)#!
dipilih untuk melayani tujuan ini justru karena#
memulai komentar. The#!
line untuk sistem, tidak interpreter, dan itu harus diabaikan oleh interpreter.Garis Shebang untuk Skrip Bash
Anda (awalnya) mengatakan Anda gunakan
#!/bin/sh
untukbash
skrip. Anda hanya harus melakukan itu jika skrip tidak memerlukanbash
ekstensi apa pun -sh
harus dapat menjalankan skrip.sh
tidak selalu merupakan symlink kebash
. Seringkali, termasuk pada semua sistem Debian dan Ubuntu terbaru dari jarak jauh ,sh
adalah symlink kedash
.Baris Shebang untuk Skrip Python
Anda juga mengatakan (dalam versi pertama pertanyaan Anda, sebelum diedit) bahwa Anda memulai skrip Python Anda
#!/bin/sh read by the interpretor
. Jika Anda benar-benar bermaksud demikian, maka Anda harus berhenti melakukannya. Jikahello.py
dimulai dengan baris itu, menjalankan./hello.py
dijalankan:/bin/sh
akan mencoba untuk mengeksekusi skrip yang disebutread
(denganby the interpretor hello.py
argumennya), tidakread
akan (semoga) tidak ditemukan, dan skrip Python Anda tidak akan pernah dilihat oleh juru bahasa Python.Jika Anda membuat kesalahan ini tetapi tidak memiliki masalah yang saya jelaskan, Anda mungkin menggunakan skrip Python Anda dengan secara eksplisit menentukan penerjemah (mis.,
python hello.py
), Sehingga baris pertama diabaikan. Saat Anda mendistribusikan skrip Anda ke orang lain, atau menggunakannya beberapa saat kemudian, mungkin tidak jelas bahwa ini perlu bagi mereka untuk bekerja. Yang terbaik untuk memperbaikinya sekarang. Atau setidaknya menghapus baris pertama sepenuhnya, sehingga ketika mereka gagal dijalankan dengan./
pesan kesalahan akan masuk akal.Untuk skrip Python, jika Anda tahu di mana juru bahasa Python berada (atau akan menjadi), Anda dapat menulis
#!
baris dengan cara yang sama:Atau, jika skrip Python 3, Anda harus menentukan
python3
, karenapython
hampir selalu Python 2 :Namun, masalahnya adalah bahwa sementara
/bin/sh
seharusnya selalu ada, dan/bin/bash
hampir selalu ada pada sistem di manabash
datang dengan OS, Python mungkin ada di berbagai tempat.Oleh karena itu, banyak programmer Python yang menggunakan ini:
(Atau
#!/usr/bin/env python3
untuk Python 3.)Ini membuat skrip mengandalkan
env
berada di "tempat yang tepat" daripada mengandalkanpython
berada di tempat yang tepat. Itu hal yang baik, karena:env
hampir selalu terletak di/usr/bin
.python
harus menjalankan skrip Anda adalah yang muncul pertama kali diPATH
. Dimulaihello.py
dengan#!/usr/bin/env python
make./hello.py
run/usr/bin/env python hello.py
, yang (hampir) setara dengan runningpython hello.py
.Alasan Anda tidak dapat menggunakan
#!python
adalah:/
).python
di direktori saat ini . Mencari path ketika perintah tidak mengandung garis miring adalah perilaku shell tertentu.Kadang-kadang sebuah Python atau skrip lain yang bukan skrip shell akan memiliki garis shebang dimulai dengan di
#!/bin/sh ...
mana...
beberapa kode lainnya. Ini kadang-kadang benar, karena ada beberapa cara untuk memanggil shell Bourne-compatible (sh
) dengan argumen untuk membuatnya memanggil juru bahasa Python. (Salah satu argumen mungkin akan berisipython
.) Namun, untuk sebagian besar tujuan,#!/usr/bin/env python
lebih sederhana, lebih elegan, dan lebih mungkin untuk bekerja seperti yang Anda inginkan.Garis Shebang dalam Bahasa Lainnya
Banyak bahasa pemrograman dan skrip, dan beberapa format file lainnya, digunakan
#
sebagai komentar. Untuk salah satu dari mereka, file dalam bahasa dapat dijalankan oleh program yang menganggapnya sebagai argumen dengan menentukan program di baris pertama setelahnya#!
.Dalam beberapa bahasa pemrograman,
#
biasanya bukan komentar, tetapi sebagai kasus khusus, baris pertama diabaikan jika dimulai dengan#!
. Ini memfasilitasi penggunaan#!
sintaks meskipun#
tidak membuat baris komentar.Garis Shebang untuk File yang Tidak Berjalan Sebagai Skrip
Meskipun kurang intuitif, file apa pun yang format file dapat mengakomodasi baris pertama dimulai dengan
#!
diikuti oleh path lengkap dari executable dapat memiliki garis shebang. Jika Anda melakukan ini, dan file ditandai dapat dieksekusi, maka Anda dapat menjalankannya seperti sebuah program ... menyebabkannya dibuka seperti dokumen.Beberapa aplikasi menggunakan perilaku ini dengan sengaja. Misalnya, di VMware,
.vmx
file menentukan mesin virtual. Anda dapat "menjalankan" mesin virtual seolah-olah itu adalah skrip karena file-file ini ditandai dapat dieksekusi dan memiliki garis shebang yang menyebabkan mereka dibuka dalam utilitas VMware.Garis Shebang untuk File yang Tidak Berjalan sebagai Skrip tetapi Bertindak Seperti Skrip
rm
menghapus file. Ini bukan bahasa scripting. Namun, file yang dimulai#!/bin/rm
dan ditandai dapat dieksekusi dapat dijalankan, dan ketika Anda menjalankannya,rm
dipanggil, dihapus.Ini sering dikonseptualisasikan sebagai "file menghapus dirinya sendiri." Tetapi file tersebut tidak benar-benar berjalan sama sekali. Ini lebih seperti situasi yang dijelaskan di atas untuk
.vmx
file.Namun, karena
#!
baris memfasilitasi jalannya perintah sederhana (termasuk argumen baris perintah), Anda dapat melakukan beberapa skrip dengan cara ini. Sebagai contoh sederhana dari "skrip" yang lebih canggih daripada#!/bin/rm
, pertimbangkan:Ini mengambil input pengguna secara interaktif, menggaungkannya kembali ke baris demi baris pengguna, dan menambahkannya ke akhir file "skrip".
Berguna? Tidak terlalu. Secara konseptual menarik? Sama sekali! Iya. (Agak.)
Konsep Pemrograman / Skrip yang Mirip (hanya untuk bersenang-senang)
Skrip / program yang terdiri dari beberapa bahasa sekaligus , misalnya, untuk mensimulasikan fungsi hashbang di OS yang tidak memilikinya .
(Program-program ini disebut polyglot , tetapi ini tidak harus disamakan dengan pengertian polyglot lainnya dalam pengembangan perangkat lunak , program / proyek di mana bagian-bagian yang berbeda ditulis dalam bahasa yang berbeda.)
Metacommands di QBasic / QuickBASIC, yang memberi sinyal ke opsi kompiler (untuk kode yang dikompilasi) untuk pembuatan kode, tetapi merupakan bagian dari komentar dan karenanya diabaikan selama kompilasi / interpretasi aktual.
sumber
-x
bendera Python ?-x
"lewati [s] baris pertama ..." baris ke-2 diberi nomor1
alih-alih2
, baris ke-32
alih-alih3
, dll. Inilah sebabnya Anda tidak boleh menggunakan bendera itu. ;)-x
adalah untuk skrip pada OS non-Unix-like yang tidak memiliki sintaks seperti shebang yang dimulai dengan#
(sehingga bukan komentar Python).perl script.pl
vs../script.pl
) maka penerjemah akan membaca baris shebang ke parse flags seperti-w
. Namun tidak disarankan untuk mengandalkan fitur ini.Shebang adalah urutan karakter yang terdiri dari tanda nomor karakter dan tanda seru (misalnya "#!") Ketika itu terjadi sebagai dua karakter awal pada baris awal naskah.
Di bawah sistem operasi * nix, ketika skrip dimulai dengan shebang dijalankan, program loader mem-parsing sisa baris awal skrip sebagai arahan juru bahasa; program penerjemah tertentu dijalankan sebagai gantinya, meneruskannya sebagai argumen jalur yang awalnya digunakan ketika mencoba menjalankan skrip. Sebagai contoh, jika sebuah skrip dinamai dengan path "path / to / your-script", dan itu dimulai dengan baris berikut:
kemudian program loader diinstruksikan untuk menjalankan program "/ bin / sh" sebagai gantinya misalnya Bourne shell atau shell yang kompatibel, melewati "path / to / your-script" sebagai argumen pertama.
Oleh karena itu, skrip dinamai dengan path "path / to / python-script" dan dimulai dengan baris berikut:
maka program yang dimuat diinstruksikan untuk menjalankan program "/ bin / python" sebagai gantinya misal juru bahasa Python, dengan meneruskan "path / ke / python-script" sebagai argumen pertama.
Singkatnya "#" akan mengomentari satu baris sementara urutan karakter "#!" terjadi sebagai dua karakter pertama pada baris awal naskah memiliki makna yang diuraikan di atas.
Untuk detail, lihat Mengapa beberapa skrip memulai dengan #! ...?
Sumber: Beberapa bagian dari jawaban ini berasal (dengan sedikit modifikasi) dari Shebang (Unix) di Wikipedia bahasa Inggris (oleh kontributor Wikipedia ). Artikel ini dilisensikan di bawah CC-BY-SA 3.0 , sama dengan konten pengguna di AU, jadi derivasi ini diizinkan dengan atribusi.
sumber
#!
disebutshebang
ketika itu terjadi sebagai dua karakter awal pada baris awal skrip. Ini digunakan dalam skrip untuk menunjukkan penerjemah untuk dieksekusi. Inishebang
untuk sistem operasi (kernel), bukan untuk shell; jadi itu tidak akan ditafsirkan sebagai komentar.Courtesy: http://en.wikipedia.org/wiki/Shebang_%28Unix%29
Info Lengkap: http://wiki.bash-hackers.org/scripting/basics#the_shebang
sumber
Tidak, ini hanya digunakan oleh
exec
system call dari kernel Linux, dan diperlakukan sebagai komentar oleh penerjemahKetika Anda melakukannya di bash:
di Linux, ini memanggil
exec
system call dengan path./something
.Baris kernel ini dipanggil pada file yang diteruskan ke
exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25Itu membaca byte pertama file, dan membandingkannya
#!
.Jika perbandingannya benar, maka seluruh baris diuraikan oleh kernel Linux, yang membuat
exec
panggilan lain dengan path/usr/bin/env python
dan file saat ini sebagai argumen pertama:dan ini berfungsi untuk bahasa skrip apa pun yang digunakan
#
sebagai karakter komentar.Dan ya, Anda dapat membuat loop tanpa batas dengan:
Bash mengenali kesalahan:
#!
Kebetulan bisa dibaca manusia, tapi itu tidak wajib.Jika file dimulai dengan byte yang berbeda, maka
exec
panggilan sistem akan menggunakan penangan yang berbeda. Handler internal terpenting lainnya adalah file yang dapat dieksekusi ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 yang memeriksa byte7f 45 4c 46
(yang juga merupakan manusia dapat dibaca untuk.ELF
). Mari kita konfirmasi dengan membaca 4 byte pertama/bin/ls
, yang merupakan executable ELF:keluaran:
Jadi ketika kernel melihat byte-byte itu, ia mengambil file ELF, memasukkannya ke dalam memori dengan benar, dan memulai proses baru dengannya. Lihat juga: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Akhirnya, Anda dapat menambahkan penangan shebang Anda sendiri dengan
binfmt_misc
mekanismenya. Misalnya, Anda dapat menambahkan penangan khusus untuk.jar
file . Mekanisme ini bahkan mendukung penangan melalui ekstensi file. Aplikasi lain adalah untuk menjalankan executable dari arsitektur yang berbeda dengan QEMU .Saya tidak berpikir POSIX menentukan shebangs: https://unix.stackexchange.com/a/346214/32558 , meskipun ia menyebutkan bagian rasional, dan dalam bentuk "jika skrip yang dapat dieksekusi didukung oleh sistem, sesuatu mungkin terjadi".
sumber