Neden bir komut dosyasının başına #! / Bin / bash koymanız gerekiyor?


486

Daha önce Bash senaryoları yaptım ve hepsi #!/bin/bashbaşlangıçta iyi çalıştı .

Onu koymanın anlamı nedir? İşler farklı mı olurdu?

Ayrıca, nasıl telaffuz edersin #? Bunun !"patlama" olarak telaffuz edildiğini biliyorum .

Nasıl #!telaffuz edilir?


8
Gerek yok ve başka seçeneğin olmadıkça yapmamalısın. Yapabileceğiniz gibi '#! / Bin / sh' kullanın ve (POSIX) kabuğu ile bash arasındaki farkı öğrenin. Kendinizi farklı bir kabuğa sahip bir sistemde bulacağınız ve komut dosyalarınızın çalışmasını istediğinizde, özgeçmişinizin çok daha fazla büyümesinden bir gün önce gelecektir.
Jens

50
"Hash-Bang" veya "She-Bang" olarak telaffuz edilir.
Beachhouse

22
Bence bu sadece senaryonuzu bir çalıştırılabilir dosya olarak çalıştırdığınızda yürütüldüğünü belirtmek gerekir. Bu nedenle, çalıştırılabilir bayrağı ayarlarsanız ve sonra ./yourscript.extensionörneğin ./helloworld.pyveya yazarsanız ./helloworld.sh, bu üst satırda yorumlayıcı arayacak #!/bin/pythonveya !#/bin/bashkomut dosyası gibi yürütülürken python helloworld.py, ilk satır, dışarı. Bu yüzden kabuk / çekirdek için özel bir dizidir.
JFA

@JFA, python ve #! İçin! # Kullanırken bash ve python arasında sırayla bir değişiklik var. bash için?
AAI

1
@AjeyaAnand hayır bir yanlış, iyi yakalamak oldu
JFA

Yanıtlar:


426

Bu bir kural * nix kabuğu ne tür bir tercüman çalıştırılacağını biliyor.

Örneğin, eski ATT lezzetleri varsayılan olarak sh (Bourne kabuğu) iken, BSD'nin eski sürümleri varsayılan olarak csh (C kabuğu) idi.

Bugün bile (sistemlerin çoğunun bash, "Bourne Again Shell" çalıştırdığı yerlerde ) komut dosyaları bash, python, perl, ruby, PHP, vb. Olabilir. Örneğin, #!/bin/perlveya görebilirsiniz #!/bin/perl5.

Not: Ünlem işareti ( !) sevgiyle "patlama" denir . Kabuk yorum sembolü ( #) bazen "karma" olarak adlandırılır .

PPS: Hatırla - bir sadece * nix altında bir dosya türü ile bir sonek ilişkilendirerek olan kongre değil, bir "kural" . Bir çalıştırılabilir bir ikili program, bir milyon komut dosyası türünden herhangi biri ve diğer şeyler olabilir. Dolayısıyla ihtiyaç #!/bin/bash.


1
Başka bir şey öğrendim, $ #. Buna ne denir?
node ninja

91
Mesele bir kabuk sözleşmesi değildir , sistem çağrısı yapılırken çekirdek tarafından yorumlanır execve(2); bu yüzden mesele bir çekirdek kuralı, bir kabuk değil.
Basile Starynkevitch

10
Ayrıca, Vim gibi bazı düzenleyicilerin, dosyanın bir uzantısı yoksa sözdizimi vurgulama dilini belirlemesine yardımcı olur. Mesele olmadan, Vim düz metin dosyasıyla aynı bir bash betiği görüntüler.
Aaron Blenkush

1
Yüklü#!/bin/sh gibi .profileşeyler ve şeyler eklemeniz gerekip gerekmediğini merak ediyor
Kolob Canyon

5
Yani ... hash-bang-slash-bin-slash-bash ?
Bernat

134

İçin olması daha hassas bu shebang #! bir ilk iki bayt olduğunda, yürütülebilir ( x mod ) dosyası, tarafından yorumlanır execve (2) sistem çağrısı (ki programları çalıştırmak). Ama POSIX belirtimi içinexecve sapmadan bahsetmiyorum.

Bunu, yürütülebilir BT yorumlayıcısının bir dosya yolu izlemelidir (BTW göreli bile olabilir, ancak çoğu zaman mutlaktır).

Güzel bir numara (ya da belki pythonKullanıcının içinde bir tercüman (örneğin ) bulmak için güzel bir de çok hoş olmayan ) $PATH, envprogramı (her zaman /usr/bin/envtüm Linux'ta) örn.

 #!/usr/bin/env python

Herhangi bir ELF yürütülebilir dosyası bir tercüman olabilir. Hatta kullanabilirsiniz#!/bin/cat ya #!/bin/trueda istersen! (ancak bu genellikle işe yaramaz)


8
Bilgisayar korsanlığı tartışması için bu soruya bakın #!/usr/bin/env.
Keith Thompson

python için nasıl bir argüman geçmek istiyorsanız bunu nasıl yapmak gerçekten yürütmek istiyorum #!/usr/bin/env bash -x. Bunu nasıl yaparım ?
indianwebdevil

onun basit ben kendim buldum, sadece bundan sonra param ekleyin#!/usr/bin/env bash -x
indianwebdevil

bashneredeyse her zaman olduğunu /bin/bashyani senin #!/bin/bash -x
shebang

49

Buna shebang denir . Unix-speak'de # keskin (müzikte olduğu gibi) veya karma (twitter üzerindeki hashtag'ler gibi) olarak adlandırılır ve! bang denir. (Aslında bang-bang adı verilen !! ile önceki shell komutunuza başvurabilirsiniz). Bir araya getirildiğinde, haSH-BANG veya shebang alırsınız.

#! Unix'e çalıştırmak için hangi programı kullanacağını söyler. Belirtilmezse, bash (veya sh veya zsh veya $ SHELL değişkeniniz ne olursa olsun) ile dener, ancak varsa bu programı kullanır. Ayrıca, # çoğu dilde bir yorumdur, bu nedenle sonraki yürütmede satır yok sayılır.


2
Zaten bash'taysam, #! / Bin / bash görürse başka bir bash örneği başlatır mı? Ya zaten bashtayım ve dışarıda kalırsam? Fark var mı?
node ninja

2
@javascriptninja her iki şekilde de yeni bir bash kabuğu başlatır. Bash durumunda, bash'ı kullandığınız sürece gerçekten hiçbir fark yoktur. Mesele sadece (a) python veya perl gibi sadece bir kabuk olmayan bir şeyde koşmanız gerekiyorsa veya (b) bash kabuğunu kullanmamanız (yani zsh kullanmanız) durumunda önemlidir. bash'da koşmayı gerektiren bir şey yürütmek.
austin1howard

Ancak, bence, shebang'u dahil etmek iyi bir uygulamadır, bu yüzden kodu okuyan biri neler olduğunu biliyor.
austin1howard

2
Yanlış: execve(2)syscall $SHELLdeğişkeni kullanmaz . Mesele yorumlayan çekirdek.
Basile Starynkevitch

1
@BasileStarynkevitch doğru, çekirdek elf yükleyici shebang yorumlamaktadır. Hiçbir shebang sağlandı eğer $ SHELL kullanılacak olacağını belirtti.
austin1howard

19

Shebang sonra belirtilen programı kullanmak için yükleyici bir yönerge olduğunu #!bunu gerçekleştirmenin çalıştığınızda söz konusu dosya için tercüman olarak. Bu nedenle, üstte foo.sholan adlı bir dosyayı çalıştırmayı denerseniz, çalışan #!/bin/bashgerçek komut/bin/bash foo.sh . Bu, farklı programlar için farklı tercümanlar kullanmanın esnek bir yoludur. Bu, sistem düzeyinde uygulanan bir şeydir ve kullanıcı düzeyi API, shebang konvansiyonudur.

Ayrıca, duygunun sihirli bir sayı olduğunu bilmeye değer - dosyayı verilen yorumlayıcı için bir komut dosyası olarak tanımlayan insan tarafından okunabilir.

Bu konuda mesele "çalışma" bile mesele olmadan sadece söz konusu program kullandığınız ile aynı kabuk için yazılmış bir kabuk komut dosyası olmasıdır. Örneğin, çok iyi bir javascript dosyası yazabilir ve sonra bir #! /usr/bin/js(veya benzer bir şey) javascript "Shell betiği" koymak için koyabilirsiniz .


18

İşletim sistemi, kabuk betiğinizi çalıştırmak için varsayılan kabuğu alır. betiğin başlangıcında kabuk yolundan bahsedersek, işletim sisteminden o kabuğu kullanmasını istersiniz. Taşınabilirlik için de kullanışlıdır .


15

Her dağıtımın varsayılan bir kabuğu vardır. Bash, sistemlerin çoğunda varsayılan değerdir. Farklı bir varsayılan kabuğa sahip bir sistemde çalışırsanız, komut dosyaları Bash için özel olarak yazılmışlarsa amaçlandığı gibi çalışmayabilir.

Bash kodu alarak yıllar içinde gelişti kshve sh.

#!/bin/bashKomut dosyanızın ilk satırı olarak eklenmesi , İşletim Sistemine shellkomut dosyasında izlenen komutları yürütmesi için belirtileni çağırmasını söyler .

#! "has-bang", "she-bang" veya "sha-bang" olarak anılır.


9

Buna shebang denir . Bir sayı işareti ve bir ünlem işareti karakteri (#!) Ve ardından / bin / bash gibi yorumlayıcıya giden tam yolu içerir. UNIX ve Linux altındaki tüm komut dosyaları, ilk satırda belirtilen yorumlayıcıyı kullanarak yürütülür.



0

Bu kitaplığı hazır olmayan farklı bir sistem kullanan biri için yararlı olabilir. Bu bildirilmezse ve komut dosyanızda bu sistem tarafından desteklenmeyen bazı işlevleriniz varsa, # / bin / bash bildirmeniz gerekir. Daha önce işte bu problemle karşılaştım ve şimdi sadece bir uygulama olarak ekliyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.