Pertanyaan yang cukup sederhana: Di Linux, mengapa Python membutuhkan baris
#!/usr/bin/python
pada awal file python, karena Windows tidak?
Apa fungsinya? Karena deskripsi "Tautan ke Python" agak kabur ...
python myscript.py
sebagai gantinya.
Pertanyaan yang cukup sederhana: Di Linux, mengapa Python membutuhkan baris
#!/usr/bin/python
pada awal file python, karena Windows tidak?
Apa fungsinya? Karena deskripsi "Tautan ke Python" agak kabur ...
python myscript.py
sebagai gantinya.
Jawaban:
Python tidak memiliki persyaratan khusus seperti itu di Linux. Ini adalah program yang loader pada Unix / Linux yang menggunakan "peristiwa" line, seperti disebut. Ini sebenarnya adalah fitur daripada batasan, tetapi kita akan membahasnya sebentar lagi. Halaman Wiki pada "shebang" memiliki lebih banyak detail, tetapi saya akan mencoba memberikan tinjauan umum serta perbandingan dengan Windows di sini.
Pertama, mari kita lihat situasi di Windows:
.
Dalam kasus file Python, ini biasanya .py
..py
file harus dibuka menggunakan Python aplikasi yang baru diinstal (yaitu interpreter Python)..exe
, dan .bat
file dieksekusi sebagai skrip batch Windows..py
file menggunakan python.exe
, itu harus membukanya dengan beberapa program lain, seperti editor teks notepad.exe
.
python <scriptname>.py
(atau menulis .bat
file untuk melakukan ini untuk Anda).Sekarang, apa yang terjadi jika ada garis shebang ( #!/usr/bin/python
atau #!/usr/bin/env python
) di bagian atas skrip Python? Nah, karena #
merupakan baris komentar dalam Python, interpreter Python mengabaikannya. Ini adalah salah satu alasan mengapa sebagian besar bahasa scripting yang digunakan di dunia Unix / Linux digunakan #
untuk memulai baris komentar.
Jadi agak menyesatkan untuk mengatakan bahwa Windows "tidak perlu" #!
saluran; Windows tidak melihat itu #!
line, dan pada kenyataannya bergantung pada file-ekstensi untuk memberitahu apa yang harus dilakukan. Ini memiliki beberapa kelemahan:
.py
di bagian akhir agar dapat dikenali secara otomatis..py
file, Windows tidak akan lagi secara otomatis menjalankan skrip tersebut dengan Python. Perhatikan bahwa ini dapat dilakukan tanpa disengaja.Sekarang, mari kita lihat bagaimana Unix / Linux meluncurkan skrip:
Hal pertama yang perlu diperhatikan adalah Unix / Linux, tidak seperti Windows, tidak mencoba untuk "membuka" skrip Python menggunakan program tertentu, setidaknya secara konseptual; OS tahu bahwa skrip adalah sesuatu yang dapat dieksekusi karena sesuatu yang disebut "eksekusi bit" (yang berada di luar cakupan jawaban ini). Jadi, jika Anda tidak sengaja mengetik #!/usr/bin/pthon
bukan #!/usr/bin/python
, Anda akan mendapatkan pesan error yang mencakup teks ini:
/usr/bin/pthon: bad interpreter: No such file or directory.
Kata "interpreter" memberi kita petunjuk tentang peran garis shebang (meskipun secara teknis program yang ditentukan dapat berupa sesuatu selain interpreter, seperti cat
atau editor teks). Saat Anda mencoba mengeksekusi file, inilah yang terjadi:
#!
, maka loader menginterpretasikan sisa dari garis shebang (tidak termasuk shebang itu sendiri) sebagai perintah untuk meluncurkan juru bahasa untuk menjalankan isi file sebagai skrip.Ini memiliki beberapa keunggulan:
Perhatikan, akhirnya, bahwa Unix / Linux tidak memerlukan baris shebang untuk menjalankan skrip Python. Ingatlah bahwa semua baris shebang sebenarnya adalah memungkinkan pemuat program untuk memilih seorang juru bahasa. Tetapi seperti halnya di Windows, ini dapat dilakukan secara manual:
python <myscript>
.py2
dan .py3
ekstensi untuk skrip Python 2 / Python 3. Jadi Linux (+ x bit) dan Windows (ekstensi file) membutuhkan metadata di sistem file. Perbedaan utama adalah bahwa + x bit lebih mudah hilang dalam perjalanan. Ini belum tentu downside.
/usr/bin/i686/python
dan /usr/bin/amd64/python
? Sangat masuk akal, tetapi skrip python rusak yang memiliki asumsi hardcoded /usr/bin/python
. Pilihan penerjemah bukan pilihan penulis skrip tetapi dari pengguna skrip, Penulis skrip hanya dapat memilih bahasa (dialek).
/usr/bin/env
, untuk, bersama dengan skrip env-setup. Apa versi Windows ini? Menjalankan regedit
skrip tepat sebelum Anda meluncurkan .py
file untuk memastikan bahwa Anda mendapatkan juru bahasa yang Anda inginkan?
Baris yang Anda tunjukkan digunakan untuk memberi tahu komputer program / juru bahasa apa yang digunakan saat menjalankan file / skrip secara langsung, dan argumen apa pun yang harus diteruskan ke program tersebut saat skrip dijalankan. Ini bukan, bagaimanapun, persyaratan Python , ini persyaratan dari kernel linux / sistem jika Anda bermaksud untuk menjalankan skrip secara langsung (dan tidak meneruskannya ke Python dengan sintaks di bawah).
Tidak diperlukan jika Anda akan mengeksekusi python script.py
atau serupa. Ini hanya diperlukan jika Anda bermaksud menjalankan skrip / file secara langsung, tanpa juga menyediakan juru bahasa untuk digunakan (seperti python
).
Untuk skrip Bash, akan ada sesuatu seperti ini:
#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;
Ini akan menunjukkan ke sistem bahwa, ketika ini berjalan, itu harus dijalankan melalui /bin/bash
yang merupakan salah satu bahasa shells / shell-script pada sistem.
Untuk kode Python, di sini, Anda akan ingin agar file yang dapat dieksekusi dijalankan melalui Python, jadi Anda memberi tahu penerjemah apa yang ingin Anda jalankan di dalamnya.
#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()
Ini, seperti untuk Bash, menunjukkan bahwa /usr/bin/python
harus digunakan (ini kemungkinan Python 2 atau Python 3, tergantung pada konfigurasi sistem Anda sendiri).
Dengan cara ini, Anda dapat menjalankan ./filename.py
atau ./executable
atau ./scripttorun
langsung.
Tanpa baris itu di awal, dan dengan asumsi Anda telah mengatur file / skrip untuk dieksekusi, dan dengan asumsi Anda bekerja dengan skrip Python, Anda harus menjalankan python filename.py
atau serupa jika Anda tidak memiliki #!/usr/bin/python
baris. (Untuk skrip Bash, Anda harus melakukannya bash script.sh
, atau mirip dengan skrip / bahasa lain, seperti Perl, Ruby, dll.)
Menyoroti sintaksis di atas adalah spesifik bahasa di setiap bagian, meskipun itu tidak terlalu penting.
#!/bin/bash -x
, #!/usr/bin/perl -lan
, dll).
/usr/bin/env python
untuk mendapatkan python yang benar.
env
, tetapi masalahnya tampaknya bukan jumlah argumen: #!/usr/bin/perl -l -a -n
ada tiga argumen tetapi berhasil. Meskipun lagi, saya tidak dapat mengatasi masalah yang sebenarnya.
./
. Dengan kata lain, hanya python filename.py
atau bash script.sh
akan berfungsi dengan baik. Satu-satunya alasan untuk memasukkan ./
adalah dalam nama perintah, ketika Anda ingin memberi tahu shell untuk tidak mencari $PATH
(yang mungkin tidak akan menemukan file dalam direktori saat ini) tetapi mengambil jalan yang Anda tentukan apa adanya. Tapi itu tidak berlaku untuk argumen perintah.
env
menerima sisa argumen dari kernel. Mereka semua bisa dianggap sebagai satu argumen besar tanpa spasi yang dilakukan. Maaf untuk artikulasi, saya tidak ingat detail ini dengan baik lagi
Garis:
#!/usr/bin/python
disebut 'shebang' dan ini menunjukkan path ke binary interpreter yang akan digunakan untuk menafsirkan sisa perintah dalam file. Ini biasanya merupakan baris pertama naskah.
Jadi baris #!/usr/bin/python
menunjukkan bahwa konten file akan ditafsirkan oleh python
biner yang terletak di /usr/bin/python
.
Perhatikan bahwa baris shebang diuraikan oleh kernel dan kemudian skrip akhirnya akan disebut sebagai argumen:
python script_name
Demikian pula dalam hal #!/bin/bash
:
bash script_name
shebang
. Karena kata tersebut dibentuk dari "hash" dan "bang," ejaan Anda tidak begitu jelas, karena sepertinya itu kombinasi dari "dia" dan "bang".
hashbang
( #
= "hash") atau shebang
( #
= "tajam"), tergantung pada bagaimana Anda memberi nama #
karakter. Namun, shebang
memang lebih umum. @KyleStrand
Secara teknis, itu tidak memerlukannya. Ini membutuhkan jalur ke lingkungan tempat skrip Anda dijalankan. Script masa depan Anda akan lebih baik untuk memasukkan / usr / bin / env kemudian, tentukan python. Ini menjamin bahwa skrip Anda berjalan di lingkungan python di mana pun python diinstal. Anda ingin melakukan ini karena alasan kompatibilitas, Anda tidak dapat memastikan orang berikutnya yang Anda bagikan kode Anda akan memasang python di usr / bin / python, atau mereka akan memiliki izin untuk file sistem tersebut.
Ini adalah T&J yang serupa dari stack overflow .
Seperti apa bentuknya dalam skrip Anda:
#!/usr/bin/env python
Saya juga melihat beberapa kekhawatiran tentang cara menentukan python3. Inilah cara melakukannya:
#!/usr/bin/env python3
Di Linux, Python mungkin atau mungkin tidak memerlukan baris #!
(shebang). Ini tergantung pada bagaimana kode Python ditangani, baik menjalankan kode dalam mode interaktif Python atau dalam skrip Python.
Mode interaktif Python memungkinkan pengguna untuk mengetik dan menjalankan kode Python secara langsung, yang tidak memerlukan garis shebang. Untuk menjalankan mode interaktif, buka Terminal dan ketik python
untuk Python 2.X atau python3
untuk Python 3.X.
$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
$ python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Skrip Python memungkinkan pengguna untuk menulis dan menyimpan kode Python dalam file teks biasa, kemudian menjalankan kode nanti. Ini mungkin atau mungkin tidak memerlukan garis shebang. Namun, ada dua alasan yang diketahui ketika garis shebang diperlukan untuk menggunakan skrip Python di Linux.
untuk menjalankan kode Python dalam skrip yang dapat dieksekusi yaitu mendefinisikan bagaimana kode harus dijalankan dan menggunakan penerjemah apa;
untuk menjalankan kode Python sehubungan dengan versi tertentu dari Python yaitu menjalankan kode yang kompatibel dengan Python 2.X atau Python 3.X saja
Berlatih dengan skrip Python
Di bawah ini adalah daftar dan konten file, yang saya gunakan untuk menunjukkan kasus bahwa #!
baris (shebang) diperlukan atau tidak diperlukan.
$ ls -ln *.py
-rw-rw-r-- 1 1000 1000 94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py
$ file *.py
hello1.py: ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py: Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py: Python script, ASCII text executable
hello1.py
hanya mengandung kode sumber.
import sys
sys.stdout.write("Hello from Python %s\n" % (sys.version,))
print("Hello, World!")
hello2.py
berisi kode sumber dan baris shebang.
#!/usr/bin/env python
import sys
sys.stdout.write("Hello from Python %s\n" % (sys.version,))
print("Hello, World!")
hello2e.py
mengandung sama dengan hello2.py
dan dibuat executable.
hello3.py
mengandung sama dengan hello2.py
, kecuali itu disesuaikan untuk dijalankan dengan Python 3 dengan mengganti nama baris pertama menjadi #!/usr/bin/env python3
.
hello3e.py
mengandung sama dengan hello3.py
dan dibuat executable.
hello3m.py
mengandung sama seperti hello3.py
dan dibuat executable, kecuali disimpan dengan Write Unicode BOM
opsi di editor teks yaitu Mousepad.
Di luar titik ini, pengguna akan disajikan dengan dua metode untuk menjalankan skrip Python. Kedua metode telah ditunjukkan sebagai berikut.
Metode 1: Jalankan dengan program Python
Di bawah ini adalah perintah dan keluaran saat menjalankan kode sumber dengan Python 2 dan Python 3.
$ python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2]
Hello, World!
$ python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09)
[GCC 4.8.4]
Hello, World!
Kedua versi Python berhasil menjalankan skrip. Oleh karena itu, baris shebang tidak diperlukan saat menjalankan skrip Python via python
atau python3
perintah.
Metode 2: Jalankan sebagai skrip Python
Di bawah ini adalah perintah dan keluaran ketika menjalankan kode sumber dengan baris shebang, yang tidak diadaptasi menjadi, Python 2 dan Python 3, termasuk case yang tidak dapat dieksekusi dan yang dapat dieksekusi.
$ ./hello1.py
bash: ./hello1.py: Permission denied
$ ./hello2.py
bash: ./hello2.py: Permission denied
$ ./hello3.py
bash: ./hello3.py: Permission denied
$ ./hello2e.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2]
Hello, World!
$ ./hello3e.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09)
[GCC 4.8.4]
Hello, World!
Tiga skrip pertama gagal karena skrip ini tidak dapat dieksekusi, terlepas dari apakah memiliki garis shebang atau tidak (Untuk bukti pendukung, lihat Contoh tambahan di bawah). Dua skrip terakhir memiliki baris shebang dan dapat dieksekusi.
Rupanya, skrip yang telah dibuat dapat dieksekusi pada dasarnya tidak berguna tanpa garis shebang. Oleh karena itu, baris shebang diperlukan dan skrip harus dapat dieksekusi ketika menjalankan kode Python dalam skrip yang dapat dieksekusi.
Ketika shebang tidak bekerja
Dalam contoh saya yang disiapkan dan diuji, menjalankan hello3m.py
sebagai skrip yang dapat dieksekusi telah gagal dan mengembalikan kesalahan.
$ ./hello3m.py
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory
Ini adalah batasan yang diketahui bahwa shebang tidak berfungsi atau menjadi tidak valid. Ketika file disimpan sebagai Unicode BOM (Byte Order Mark), itu akan gagal berjalan secara normal sebagai skrip Python yang dapat dieksekusi.
Contoh tambahan
Contoh tambahan ini akan diperlakukan sebagai bukti pendukung saja. Pengguna harus menghindari menjalankan contoh ini, meskipun hasilnya tidak berbahaya.
Saya telah membuat file lain yang disebut hello1e.py
, yang berisi file yang sama dengan hello1.py
dan dapat dieksekusi. Menjalankan skrip ini menghasilkan kesalahan sintaksis.
$ ./hello1e.py
./hello1e.py: line 2: syntax error near unexpected token `"Hello from Python %s\n"'
./hello1e.py: line 2: `sys.stdout.write("Hello from Python %s\n" % (sys.version,))'
Saat menjalankan skrip ini, pada awalnya, kursor mouse akan diubah menjadi tanda tambah dan tidak terlihat apa-apa. Kesalahan sintaksis tidak akan ditampilkan sampai saya membuat klik pada jendela Desktop atau Terminal. Kemudian, skrip ini akan membuat sys
file dalam direktori yang sama dengan skrip.
$ file sys
sys: PostScript document text conforming DSC level 3.0, Level 1
The sys
file telah diidentifikasi sebagai berkas PostScript, tanpa ekstensi file. File ini dapat dibuka di document viewer yaitu Evince, dan file tersebut sebenarnya berisi screenshot dari jendela yang telah saya klik sebelumnya. Dalam pengalaman saya, file bisa sebesar beberapa Megabytes.
Sekali lagi, baris shebang diperlukan dan skrip harus dapat dieksekusi ketika menjalankan skrip Python sebagai skrip yang dapat dieksekusi. Jika tidak, skrip akan berperilaku buruk seperti dijelaskan di atas.
Catatan tambahan
Istilah "dapat dieksekusi" atau "harus dapat dieksekusi" mengacu pada izin untuk menjalankan skrip. Ini dilakukan dengan menjalankan chmod +x FILENAME
perintah di Terminal, atau dengan mencentang opsi "Izinkan file ini untuk dijalankan sebagai program" atau sesuatu yang serupa di jendela Properties , di dalam file manager.
Sementara jawaban lain yang ada telah mencakup hampir semuanya, jawaban ini telah mengambil pendekatan yang berbeda dengan menggunakan contoh-contoh praktis untuk menjelaskan masalah ini. Sintaks kode telah ditulis dengan hati-hati, sehingga contoh-contohnya dapat dijalankan dengan Python 2 atau Python 3, sebagaimana adanya.
Kode Python telah diadaptasi dari Menggunakan Python pada Windows dan Menggunakan Python pada platform Unix , dengan kode satu-baris tambahan dari kata-kata "Halo, Dunia!" program.
Semua kode dan perintah telah sepenuhnya diuji dan berfungsi di sistem Xubuntu 14.04, yang memiliki Python 2.7 dan Python 3.4 diinstal secara default.
Itu berarti bahwa ketika file itu dieksekusi, komputer Anda tahu untuk mengeksekusinya dengan program /usr/bin/python
, itulah cara Anda membedakannya dari bahasa lain, seperti bash di mana Anda akan melakukannya #!/bin/bash
. Ini agar Anda bisa menjalankan:
./[file-to-execute]
Dan ia akan tahu file mana yang harus dieksekusi, daripada Anda sendiri yang harus menentukan dengan sesuatu seperti:
python ./[file-to-execute].py
Bagian #!
ini biasanya disebut sebagai shebang atau bang crunch .
Jika Anda memiliki beberapa versi Python diinstal, /usr/bin/env
akan memastikan penerjemah yang digunakan adalah yang pertama di lingkungan Anda $PATH
. Alternatifnya adalah dengan hardcode sesuatu seperti #!/usr/bin/python
;
Di Unix, file yang dapat dieksekusi yang dimaksudkan untuk ditafsirkan dapat menunjukkan penerjemah apa yang harus digunakan dengan memiliki #!
pada awal baris pertama, diikuti oleh penerjemah (dan bendera apa pun yang mungkin diperlukan).
Aturan ini hanya berlaku untuk sistem berbasis UNIX.
membantu untuk OS seperti Linux di mana Python 2.x masih standar, tetapi kebanyakan orang juga mengunduh 3.x.
2.x akan berjalan secara default. Jadi kode 3.x saya, saya awali dengan #! / Usr / bin / env python3 sehingga 3.x menjalankan kode tersebut. Saya bahkan dapat menentukan ke revisi kecil (python 3.xyz) jika saya memilih untuk memiliki rilis beta atau hanya versi yang sedikit lebih tua.
.
) untuk menentukan jenis file apa itu. Bahkan Windows menjauh dari ini: memeriksa beberapa baris pertama dari file Microsoft Word, dan itu akan menyatakan bahwa itu sebenarnya, file Microsoft Word.