Untuk skrip csh, Anda harus menggunakan #!/bin/csh -f; the -fmemberi tahu shell untuk tidak mencari pengguna .logindan .cshrc, yang membuat skrip berjalan lebih cepat dan menghindari ketergantungan pada penyiapan pengguna. (Atau lebih baik lagi, jangan menulis skrip csh.) Jangan gunakan -funtuk skrip sh atau bash; itu tidak memiliki arti yang sama.
Anda tidak perlu @ @Kolob Canyon, tetapi dapat membantu beberapa editor dengan penyorotan sintaks (walaupun biasanya ada cara lain untuk mencapai hal yang sama): unix.stackexchange.com/a/88730/193985
Braham Snyder
42
The #!garis memberitahu kernel (khusus, pelaksanaan execvesystem call) bahwa program ini ditulis dalam bahasa ditafsirkan; nama jalur absolut yang mengikuti mengidentifikasi penerjemah. Program yang dikompilasi ke kode mesin dimulai dengan urutan byte yang berbeda - pada kebanyakan Unix modern, 7f 45 4c 46( ^?ELF) yang mengidentifikasinya seperti itu.
Anda dapat menempatkan jalur absolut ke program apa pun yang Anda inginkan setelahnya #!, selama program itu sendiri bukan #!skrip. Kernel menulis ulang pemanggilan
./script arg1 arg2 arg3 ...
di mana ./scriptdimulai dengan, katakanlah #! /usr/bin/perl, seolah-olah baris perintah itu benar-benar ada
/usr/bin/perl ./script arg1 arg2 arg3
Atau, seperti yang Anda lihat, Anda dapat menggunakan #! /bin/shuntuk menulis skrip yang dimaksudkan untuk ditafsirkan oleh sh.
The #!garis hanya diproses jika Anda langsung memanggil script ( ./scriptpada baris perintah); file tersebut juga harus dapat dieksekusi ( chmod +x script). Jika Anda melakukannya sh ./scriptdengan #!garis tidak perlu (dan akan diabaikan jika ada), dan file tidak harus dieksekusi. The titik fitur ini adalah untuk memungkinkan Anda untuk langsung menjalankan program ditafsirkan-bahasa tanpa harus mengetahui bahasa apa yang mereka ditulis dalam. (Do grep '^#!' /usr/bin/*- Anda akan menemukan bahwa banyak program saham besar sebenarnya menggunakan fitur ini.)
Berikut beberapa aturan untuk menggunakan fitur ini:
The #!harus dua pertama byte dalam file. Secara khusus, file harus dalam pengkodean yang kompatibel dengan ASCII (mis. UTF-8 akan berfungsi, tetapi UTF-16 tidak) dan tidak boleh dimulai dengan "tanda urutan byte", atau kernel tidak akan mengenalinya sebagai #!naskah.
Jalur setelahnya #!harus jalur absolut (dimulai dengan /). Tidak boleh berisi spasi, tab, atau karakter baris baru.
Ini adalah gaya yang bagus, tetapi tidak diharuskan, untuk memberi spasi antara #!dan /. Jangan meletakkan lebih dari satu tempat di sana.
Anda tidak dapat meletakkan variabel shell pada #!baris tersebut, mereka tidak akan diperluas.
Anda dapat meletakkan satu argumen baris perintah setelah jalur absolut, dipisahkan darinya dengan satu spasi. Seperti jalur absolut, argumen ini tidak boleh berisi spasi, tab, atau karakter baris baru. Terkadang hal ini diperlukan untuk membuat semuanya bekerja ( #! /usr/bin/awk -f), terkadang hanya berguna ( #! /usr/bin/perl -Tw). Sayangnya, Anda tidak dapat meletakkan dua atau lebih argumen setelah jalur absolut.
Beberapa orang akan memberitahu Anda untuk menggunakan #! /usr/bin/env interpreterbukan #! /absolute/path/to/interpreter. Ini hampir selalu merupakan kesalahan. Itu membuat perilaku program Anda bergantung pada $PATHvariabel pengguna yang memanggil skrip. Dan tidak semua sistem ada envdi tempat pertama.
Program yang membutuhkan setuidatau setgidhak istimewa tidak dapat digunakan #!; mereka harus dikompilasi ke kode mesin. (Jika Anda tidak tahu apa setuiditu, jangan khawatir tentang ini.)
Mengenai csh, ini shkira-kira berhubungan dengan apa yang dilakukan Nutrimat Advanced Tea Substitute terhadap teh. Ini memiliki (atau lebih tepatnya memiliki; implementasi modern shtelah menangkap) sejumlah keunggulan dibandingkan shuntuk penggunaan interaktif, tetapi menggunakannya (atau turunannya tcsh) untuk skrip hampir selalu merupakan kesalahan . Jika Anda baru mengenal skrip shell secara umum, saya sangat menyarankan Anda mengabaikannya dan fokuslah sh. Jika Anda menggunakan cshkerabat sebagai shell login Anda, alihkan ke bashatau zsh, sehingga bahasa perintah interaktif akan sama dengan bahasa skrip yang Anda pelajari.
Versi terbaru Linux memungkinkan interpreter yang ditentukan menjadi skrip. Merupakan praktik umum untuk menghilangkan spasi setelah #!; tidak ada komentar apakah itu gaya yang bagus. Lihat pertanyaan ini dan jawaban saya untuk diskusi tentang pro dan kontra #!/usr/bin/envperetasan.
Keith Thompson
@KeithThompson Saya mendapat kesan bahwa Linux adalah satu - satunya varian Unix umum yang memungkinkan interpreter menjadi skrip, jadi masih belum bisa diandalkan. Sejak saya menulis ini, saya sendiri mengalami situasi di mana #!/usr/bin/envHal yang Benar, tetapi menurut saya itu hampir selalu merupakan ide yang buruk.
zwol
4
Ini mendefinisikan shell (command interpreter) apa yang Anda gunakan untuk menafsirkan / menjalankan skrip Anda. Setiap shell sedikit berbeda dalam cara berinteraksi dengan pengguna dan menjalankan skrip (program).
Saat Anda mengetikkan perintah pada prompt Unix, Anda sedang berinteraksi dengan shell.
Misalnya, #!/bin/cshmengacu pada C-shell, /bin/tcsht-shell, /bin/bashbash shell, dll.
Anda dapat mengetahui shell interaktif mana yang Anda gunakan
echo$SHELL
perintah, atau alternatif
env | grep -i shell
Anda dapat mengubah shell perintah Anda dengan chshperintah.
Masing-masing memiliki set perintah yang sedikit berbeda dan cara menugaskan variabel dan rangkaian konstruksi pemrogramannya sendiri. Misalnya pernyataan if-else dengan bash terlihat berbeda dari yang ada di C-shell.
Halaman ini mungkin menarik karena "menerjemahkan" antara perintah / sintaks bash dan tcsh.
Menggunakan direktif dalam skrip shell memungkinkan Anda menjalankan program menggunakan shell yang berbeda. Misalnya saya menggunakan tcshshell secara interaktif, tetapi sering menjalankan skrip bash menggunakan / bin / bash di file skrip.
Ke samping:
Konsep ini meluas ke skrip lain juga. Misalnya jika Anda memprogram dengan Python, Anda akan memasukkan
Jadi apakah itu wajib? Bagaimana saya tahu shell mana yang sebenarnya saya gunakan?
One Two Three
Jadi jika saya menulis skrip untuk digunakan seseorang di mesin mereka, dan saya tidak tahu shell apa yang mereka gunakan. (Sayangnya, orang ini tidak tahu apa-apa tentang hal ini, sehingga yang dapat dia lakukan hanyalah menjalankan skrip tanpa mengubah apa pun). Bisakah saya melakukan sesuatu seperti itu #! $SHELL? Apakah ini akan menempatkan cangkang yang benar di Sebang?
One Two Three
1
@OneTwoThree Kebanyakan sistem memiliki shell standar, jika Anda menulis skrip bash atau csh, Anda akan baik-baik saja. Shell apa yang mereka gunakan secara interaktif tidak masalah, itulah keindahan dari eg, !#/bin/bashdirective. Ini memberi tahu sistem shell apa yang akan digunakan untuk menjalankan skrip shell Anda.
Levon
Nilai dari $SHELLtidak selalu memberi tahu Anda shell mana yang Anda jalankan saat ini; itu biasanya memberi tahu Anda shell default Anda . tcsh set $versiondan $tcsh; set pesta $BASH_VERSION. Tidak semua cangkang memiliki mekanisme yang sama.
Keith Thompson
1
@OneTwoThree: #!Baris harus cocok dengan sintaks skrip, bukan shell interaktif yang digunakan oleh siapa pun yang menjalankan skrip.
#!/bin/csh -f
; the-f
memberi tahu shell untuk tidak mencari pengguna.login
dan.cshrc
, yang membuat skrip berjalan lebih cepat dan menghindari ketergantungan pada penyiapan pengguna. (Atau lebih baik lagi, jangan menulis skrip csh.) Jangan gunakan-f
untuk skrip sh atau bash; itu tidak memiliki arti yang sama.Jawaban:
Ini dikenal sebagai
Shebang
:http://en.wikipedia.org/wiki/Shebang_(Unix)
Sebuah shebang hanya relevan jika skrip memiliki izin eksekusi (misalnya chmod u + x script.sh).
Ketika shell mengeksekusi skrip itu akan menggunakan interpreter yang ditentukan.
Contoh:
#!/bin/bash # file: foo.sh echo 1 $ chmod u+x foo.sh $ ./foo.sh 1
sumber
The
#!
garis memberitahu kernel (khusus, pelaksanaanexecve
system call) bahwa program ini ditulis dalam bahasa ditafsirkan; nama jalur absolut yang mengikuti mengidentifikasi penerjemah. Program yang dikompilasi ke kode mesin dimulai dengan urutan byte yang berbeda - pada kebanyakan Unix modern,7f 45 4c 46
( ^?ELF) yang mengidentifikasinya seperti itu.Anda dapat menempatkan jalur absolut ke program apa pun yang Anda inginkan setelahnya
#!
, selama program itu sendiri bukan#!
skrip. Kernel menulis ulang pemanggilandi mana
./script
dimulai dengan, katakanlah#! /usr/bin/perl
, seolah-olah baris perintah itu benar-benar adaAtau, seperti yang Anda lihat, Anda dapat menggunakan
#! /bin/sh
untuk menulis skrip yang dimaksudkan untuk ditafsirkan olehsh
.The
#!
garis hanya diproses jika Anda langsung memanggil script (./script
pada baris perintah); file tersebut juga harus dapat dieksekusi (chmod +x script
). Jika Anda melakukannyash ./script
dengan#!
garis tidak perlu (dan akan diabaikan jika ada), dan file tidak harus dieksekusi. The titik fitur ini adalah untuk memungkinkan Anda untuk langsung menjalankan program ditafsirkan-bahasa tanpa harus mengetahui bahasa apa yang mereka ditulis dalam. (Dogrep '^#!' /usr/bin/*
- Anda akan menemukan bahwa banyak program saham besar sebenarnya menggunakan fitur ini.)Berikut beberapa aturan untuk menggunakan fitur ini:
#!
harus dua pertama byte dalam file. Secara khusus, file harus dalam pengkodean yang kompatibel dengan ASCII (mis. UTF-8 akan berfungsi, tetapi UTF-16 tidak) dan tidak boleh dimulai dengan "tanda urutan byte", atau kernel tidak akan mengenalinya sebagai#!
naskah.#!
harus jalur absolut (dimulai dengan/
). Tidak boleh berisi spasi, tab, atau karakter baris baru.#!
dan/
. Jangan meletakkan lebih dari satu tempat di sana.#!
baris tersebut, mereka tidak akan diperluas.#! /usr/bin/awk -f
), terkadang hanya berguna (#! /usr/bin/perl -Tw
). Sayangnya, Anda tidak dapat meletakkan dua atau lebih argumen setelah jalur absolut.#! /usr/bin/env interpreter
bukan#! /absolute/path/to/interpreter
. Ini hampir selalu merupakan kesalahan. Itu membuat perilaku program Anda bergantung pada$PATH
variabel pengguna yang memanggil skrip. Dan tidak semua sistem adaenv
di tempat pertama.setuid
atausetgid
hak istimewa tidak dapat digunakan#!
; mereka harus dikompilasi ke kode mesin. (Jika Anda tidak tahu apasetuid
itu, jangan khawatir tentang ini.)Mengenai
csh
, inish
kira-kira berhubungan dengan apa yang dilakukan Nutrimat Advanced Tea Substitute terhadap teh. Ini memiliki (atau lebih tepatnya memiliki; implementasi modernsh
telah menangkap) sejumlah keunggulan dibandingkansh
untuk penggunaan interaktif, tetapi menggunakannya (atau turunannyatcsh
) untuk skrip hampir selalu merupakan kesalahan . Jika Anda baru mengenal skrip shell secara umum, saya sangat menyarankan Anda mengabaikannya dan fokuslahsh
. Jika Anda menggunakancsh
kerabat sebagai shell login Anda, alihkan kebash
atauzsh
, sehingga bahasa perintah interaktif akan sama dengan bahasa skrip yang Anda pelajari.sumber
#!
; tidak ada komentar apakah itu gaya yang bagus. Lihat pertanyaan ini dan jawaban saya untuk diskusi tentang pro dan kontra#!/usr/bin/env
peretasan.#!/usr/bin/env
Hal yang Benar, tetapi menurut saya itu hampir selalu merupakan ide yang buruk.Ini mendefinisikan shell (command interpreter) apa yang Anda gunakan untuk menafsirkan / menjalankan skrip Anda. Setiap shell sedikit berbeda dalam cara berinteraksi dengan pengguna dan menjalankan skrip (program).
Saat Anda mengetikkan perintah pada prompt Unix, Anda sedang berinteraksi dengan shell.
Misalnya,
#!/bin/csh
mengacu pada C-shell,/bin/tcsh
t-shell,/bin/bash
bash shell, dll.Anda dapat mengetahui shell interaktif mana yang Anda gunakan
echo $SHELL
perintah, atau alternatif
Anda dapat mengubah shell perintah Anda dengan
chsh
perintah.Masing-masing memiliki set perintah yang sedikit berbeda dan cara menugaskan variabel dan rangkaian konstruksi pemrogramannya sendiri. Misalnya pernyataan if-else dengan bash terlihat berbeda dari yang ada di C-shell.
Halaman ini mungkin menarik karena "menerjemahkan" antara perintah / sintaks bash dan tcsh.
Menggunakan direktif dalam skrip shell memungkinkan Anda menjalankan program menggunakan shell yang berbeda. Misalnya saya menggunakan
tcsh
shell secara interaktif, tetapi sering menjalankan skrip bash menggunakan / bin / bash di file skrip.Ke samping:
Konsep ini meluas ke skrip lain juga. Misalnya jika Anda memprogram dengan Python, Anda akan memasukkan
#!/usr/bin/python
di bagian atas program Python Anda
sumber
#! $SHELL
? Apakah ini akan menempatkan cangkang yang benar di Sebang?!#/bin/bash
directive. Ini memberi tahu sistem shell apa yang akan digunakan untuk menjalankan skrip shell Anda.$SHELL
tidak selalu memberi tahu Anda shell mana yang Anda jalankan saat ini; itu biasanya memberi tahu Anda shell default Anda . tcsh set$version
dan$tcsh
; set pesta$BASH_VERSION
. Tidak semua cangkang memiliki mekanisme yang sama.#!
Baris harus cocok dengan sintaks skrip, bukan shell interaktif yang digunakan oleh siapa pun yang menjalankan skrip.