“Bash script.sh” ve “./script.sh” çalıştırmak arasındaki fark nedir?


42

Eğer script.sh sadece tipik bir şeyse

#!/bin/bash
echo "Hello World!"

Komut dosyasını çalıştırmanın tercih edilen bir yolu var mı? Sanırım ilk önce chmod yapman gerekiyor, böylece çalıştırılabilir hale geliyor?

Yanıtlar:


56

Özel komut dosyanız için ./script.sh, yürütme ve okunabilir bitler gerektirmesi dışında , bash script.shyalnızca okunabilir bit gerektirmesi dışında her iki yol da çalışır .


İzin gereksinimi farkının nedeni, betiğinizi yorumlayan programın nasıl yüklendiğine bağlıdır:

  • ./script.sh kabuğunuzun dosyayı normal bir çalıştırılabilirmiş gibi çalıştırmasını sağlar.

Kabuk kendisini çatallar ve execveişletim sisteminin çatallanmış işlemdeki dosyayı çalıştırmasını sağlamak için bir sistem çağrısı (örn. ) Kullanır . İşletim sistemi, dosyanın izinlerini kontrol eder (bu nedenle, yürütme bitinin ayarlanması gerekir) ve isteği , dosyayı inceleyen ve nasıl yürütüleceğini belirleyen program yükleyiciye iletir . Linux'ta derlenen çalıştırılabilir kodlar bir ELF sihir numarası ile başlarken, scriptler bir #!( hashbang ) ile başlar. Bir hashbang üstbilgisi, dosyanın bir komut dosyası olduğu ve hashbang'dan sonra belirtilen program tarafından yorumlanması gerektiği anlamına gelir. Bu, komut dosyasının kendisinin sisteme komut dosyasını nasıl yorumlayacağını söylemesini sağlar.

Komut dosyanızla birlikte, program yükleyici komut satırı argümanı olarak yürütülür /bin/bashve ./script.shiletilir.

  • bash script.shkabuğunuzun çalışmasını bashve script.shkomut satırı argümanı olarak geçmesini sağlar

Böylece işletim sistemi yüklenecek bash(bakmadan bile script.sh, çünkü sadece bir komut satırı argümanı). Oluşturulan bashişlem daha sonra script.shkomut satırı argümanı olarak iletildiği için yorumlayacaktır . Çünkü script.shsadece tarafından okunan bashdüzenli bir dosya olarak, yürütme biti gerekli değildir.


./script.shYine de kullanmanızı öneririm , çünkü komut dosyasının hangi tercümanı gerektirdiğini bilmiyor olabilirsiniz. Öyleyse program yükleyici sizin için bunu belirlesin.


3
Çalıştırılabilir bit ayarlı, ayrıca yaparak senaryoyu çalıştırabilir "./script.sh."
Köpek Kedi dünyayı yemek

1
@ Doğru mu? Nokta, komut dosyasını geçerli bash işleminde çalıştıran yerleşik 'kaynak' komutunun kısayolu. Bu yüzden sadece okunabilir bit gereklidir.
SkyDan

5
@Dogeatcatworld bu doğru iken, koşmak . ./script.shaynı şey değildir bash script.sh(veya ./script.sh. #!/usr/bin/python -V<newline> betiğini düşünün print test.
casey 21

12
Bir betiğin kaynağının etkileşimli oturumun kirlenmesine neden olabileceğine dikkat edin. Örneğin, bir komut dosyası PATH ortam değişkenini değiştirdiğinde, bu değişiklik kaynağı izleyen komutları etkiler. Bu yaklaşım, yan etkilere (ortam düzenleme komut dosyaları ve benzeri) bağlı olduğunuz durumlar için gerçekten ayrılmalıdır. İzinleri değiştiremeyeceğiniz diğer durumlar için, komut dosyasını shebang satırında çalıştırmak, komut dosyası adının ardından en güvenli yaklaşımdır.
ctt

6
Bu, geçerli dizinde bir script kaynak varsa, kullanımda gerekmez Not ./ ; sadece söyle . script.sh. Ancak, .bu şekilde çağrılması amaçlanmayan senaryolar komutunu kullanmaktan vazgeçen insanlarla aynı fikirdeyim . Senaryo exitkomutlar içeriyorsa ve siz onu kaynaklıyorsanız, oturumunuzu kapattığını kimse söylememişse şaşırdım . Senaryo a yaparsa, daha az bir sıkıntı problemi de olur cd, çünkü ana (etkileşimli) kabuğu da etkiler.
Scott

18

bash script.shbetiği doğrudan bash kullanarak çağırır.
./script.shshebang'ı #!/bin/bashnasıl çalıştırılacağını belirlemek için kullanıyor .

Gerçekten bilmek istersen, hangisini çalıştırırsan yapsan bash script.shöğrenebilirsin which bash.

Yani örneğinizde hiç farketmez. Evet, chmod +x script.shdirekt olarak gerçekleştirebilmelisiniz ./script.sh.


2
Bunun senin içinde /bin/bashilk olduğunu varsaymak farketmez . bash$PATH
cjm

Haklısın. Ve #!/bin/bash/bin/bash
Shebang

Sistemimdeki Bash (sürüm 4.2.37), yürütme bit kümesi olmadan bile komut dosyalarını çalıştırır. Neden icra biti gerektiğini söylüyorsunuz?
SkyDan

Evet, yürütme biti sadece üzerinden çağrılarak gerekir ./script.sh.
xx4h

4

Bir dosya oluşturun Delete_Self.sh böyle:

 #!/bin/rm

 echo I am still here!

sh Delete_Self.shGördüğünüz gibi bu betiği çalıştırın "Hala buradayım!" geri yankılandı.

Çalıştırılabilir hale getirin ./Delete_Self.shve dosyanın Delete_Self.shkendisi gittiğinde hiçbir şeyin geri çevrilmediğini göreceğiniz gibi çalıştırın .

Yani fark şu ki:

  • bash script.sh# görmezden gelecek! çünkü bash, script.sh komutunu çalıştıracak program olarak belirtilir.
  • ./script.sh# okuyacak! Çalıştırılacak programı belirlemek için satır script.sh.

Güzel bir örnek için +1
ThisaruG,

1

Diğer cevaplara ek olarak, bir komut dosyasını ./script.sh(i) ile kaynak ./script.sh(ii) üzerinden çalıştırmak arasındaki farkı bilmek faydalıdır - (i) sürümü, komutun çalıştırılacağı yeni bir kabuk oluşturur, oysa (ii) komutun içinde Geçerli kabuk - yürütülebilir dosya çalıştırıldıktan sonra korunması gereken ortam değişkenlerini değiştirirse zorunlu olabilir. Örneğin, bir python conda ortamını etkinleştirmek için aşağıdakiler kullanılmalıdır:

source activate my_env

NB başka alternatif sourcekarşılaşabileceğiniz olmasıdır .yerleşik, yani

. activate my_env
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.