Bir betiği çalıştırmak için ./ ve sh arasındaki fark nedir?


71

Basit bir senaryo yazdım. Çalıştırdığımda sh <myscriptname.sh>doğru çıktıyı aldım, fakat çalıştırdığımda ./<myscriptname.sh>bir hatayla karşılaştım.

Yaptığım zaman shve arasındaki fark nedir ./?


15
Sadece "Bir hata alıyorum" demek yerine, hatanın ne söylediğini yapıştırırsanız yardımcı olur.
SpashHit

Yanıtlar:


67

Herhangi bir komut dosyasını dosya adını komut dosyası tercüman programına ileterek çalıştırdığınızda, tercüman programını komut dosyasıyla, kendisine aktarılan bir argüman olarak çalıştırıyorsunuzdur. Örneğin, bu 'sh' işlemi ile 'dosyaadı.sh' argümanına benziyor. shTercüman dosyasını açıyor.

Öte yandan, komut dosyasını kendiniz çalıştırırsanız, sistem belirtilen tercüman programına çağrı yapar ve komut dosyalarının içeriğini besler. Bu durumda, işlem argüman olmadan 'dosyaadı.sh' gibi görünür.

Patlama çizgisi olduğundan emin olmalısın:

#!/bin/bash
# bash script here

Bir komut satırı , komut dosyasındaki ilk satırdır ve aynı iki karakterle başlar #!, bunlar komut dosyasını çalıştırmaya çalıştığında sistemin okuduğu şeydir ve sistem komut dosyasını derhal programa geçirir. Bu çizginin bash ile ilgisi olmadığını ve çok farklı diller olmasına rağmen python ve perl için de iyi çalıştığını unutmayın. #!/usr/bin/pythonÖrneğin kullanır ve sonra python kodunu izlersiniz.

Komut dosyanızı aldıktan sonra, yürütme izinlerini ayarladığınızdan emin olun:

chmod a+x filename.sh

Sonra betiği kendi işlemi olarak çalıştırabilirsiniz:

./filename.sh

Veya dosyayı güzel bir program adıyla bilinen bir konuma yerleştirin, ister /usr/sbinve istediğiniz yerden çalıştırın:

sudo cp filename.sh /usr/sbin/program-name
program-name

Ve bu gerçekten de bang hattını doğru izinlerle kullanmanın pratik yararıdır - hepsi konuşlandırma ile ilgilidir . Betiği hangi programla çalıştıracaklarını hatırlamaları gerekirse, kullanıcıların bir betiği çalıştırmalarını sağlamak çok zordur. Her çalıştırmak istediklerinde komut dosyasına tam bir yol vermeyi unutmayın. Nerede koyarak olarak /usr/local/binörneğin ve yürütülebilir yapma, Senaryonu kullanmaya çalışan insanlar için keder çok şey kaydedebilirsiniz. Bu programlar daha sonra bilgisayarınızdaki tüm kullanıcılar için uygun hale gelir .

Aynı zamanda tanımlama için iyi. Eğer içine giderseniz topprogramda, patlama hattı olmayan bir senaryo çalıştırmak sadece tercüman yani adı olacaktır bash, perlya da python. Ancak bir komut dosyası doğru izinlerle çalıştırılıyorsa, komut dosyasının adı gösterilir.

Not: Herkese açık bir betiği dağıtmak istiyorsanız, lütfen yüklemek için bir adam sayfası ve bir deb paketi oluşturun. Çevrimiçi olarak rastgele komut dosyalarının sayısını azaltmamız ve kaldırılabilecek dosya sayısını arttırmamız gerekiyor.


1
Ayrıca kişisel bir bin klasörü de kullanabilirsiniz: giriş klasörünüzde bir bin klasörü oluşturun ve oturumu kapatın ve tekrar giriş yapın. Bu klasörde sh veya ./ olmadan herhangi bir komut dosyasını çalıştırabilmelisiniz.
papukaija

Tabii ki, fakat ev klasörünü PATH'nize eklemeniz biraz başağrısı olarak görülebilir. Eşyaları monte etsen iyi olur. Yerel kullanıcının paketleri yüklemesine izin vermek için varsayılan olarak yola ~ / .local / bin ekleme konusunda bir konuşma yapılmış olmasına rağmen.
Martin Owens -doctormo

Varsayılan tercümanın basholmadığını unutmayın sh.
Nathan Osman

1
Uzantıları komut dosyalarına koymayın, özellikle içine koyduğunuzda değil PATH.
geirha

1
/usr/local/bino zaman muhtemelen daha iyidir /usr/sbin- programın dağıtımın bir parçası olmak yerine bu makinede yerel olduğunu gösterir.
glenn jackman

41

Kısa versiyon:

  • shkomut satırı yorumlayıcısıdır (çizgi).
    Koşmak sh my_scriptdash'in betiği yorumlamasını sağlar.

  • ./Hangi tercümanın kullanılacağını ilk satıra bakarak bulmaya çalışır. Örneğin #!/bin/bash, hatta #!/bin/ruby(koşmanın aksine ruby my_script).


7
Gerçekten bir ./şey bulamaz, dosyanın ilk iki baytına bakan sistem yürütme yöntemidir.
Martin Owens -doctormo

9
Kesinlikle. İşte her şeyin çok uzun bir açıklaması . Ben pragmatik yapıyorum :)
Stefano Palazzo

Kullandığınızda shve dosya bir sha-bang içeriyorsa, bu sha-bang'in yoksayılacağı anlamına mı geliyor, yoksa shbağlantıların da açılacağı anlamına gelir ve sonra belki başka bir kabuk veya ne işe yarar :)?
Ini

5

Yaptığın fark,

  • ile shbunu size terminalin interaktif isteminde bunları yazmış olurdu gibi komut dosyanızda çizgileri yorumlayacaktır bir program çalıştırıyorsanız,

  • ile ./komut dosyası size oturuyorsun VE (örneğin size verilen çünkü çalıştırılabilir olacak geçerli dizinde sadece burada olduğunu varsayarak bir kısayol yapıyoruz chmod +x myscript.sh:-) gelecek zamanlar için size çok değerli zamandan tasarruf)


3
Dosyanın çalıştırılabilir olması gerektiğini kesin olarak belirten tek kişi olarak +1.
Mikel

2
shDosya ile mutlaka çalıştırılabilir olması gerekmediğini unutmayın .
Ini

3

Hata yapmanın üç ana nedeni vardır:

  • dosyayı düzeltmek için
    çalıştırılabilir bir dosya değilchmod +x <myscriptname.sh>
  • bölüm çalışan komut dosyalarına izin vermiyor (" noexec" eklenmiş )
    komut dosyasını kopyala/usr/local/bin
  • #!hat bir hata vardır
    ilk satırı olduğundan emin olun #!/bin/shveya#!/bin/bash

İlk satırınız düzgün görünüyorsa, ancak hala çalışmıyorsa, dosyanın DOS satırı sonları olmadığından emin olun.

Hata şöyle bir şeye benzeyebilir:

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

Sen çalıştırarak tamir edebiliriz dos2unix <myscriptname.sh>bunu yoksa, ya da
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>.


0

Cevap şu ki, sh çok popüler bir kabuk için isimdir. Ama modası geçmiş ve başkaları tarafından değiştirildi. Günümüzde sh makinede kurulu diğer mermilerle bağlantılıdır. Mesela oraya bir bash koydum. Herhangi bir kabuğun sh'den çalıştırılması genellikle orijinal 'kabuk' davranışı ile bazı 'uyumluluk' modlarını tetikler.

Yani çözüm oldukça basit. Sh komutunun arkasında ne olduğuna bakın (ls -al / bin / sh) ve #! / Bin / whatever_you_find_there'yi ilk satır olarak koyun (veya komut dosyanızda buna benzer bir şey varsa düzenleyin).

Alternatif olarak, betiğin kendisinde bir hata olabilir. Sh tarafından karşılanan, ancak gerçekten kullanılan tercüman olmayan bağımlılık gibi.


0
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

Değil /usr/sbin, bu gerekli olmayan idari araçlar için, /usr/local/bineğer sahip olmak istemezseniz daha iyi bir seçim olabilir ~/bin/, ancak sudomümkün olduğunca kaçınmanız tavsiye edilir.


Ubuntu’da, varsayılan ayar ~/.profilezaten ~/binvarsa ekleme kodunu içerir PATH. Başka bir notta, komut dosyalarına uzantı eklemeyin.
geirha

1
<Myscriptname.sh> dosyasına başvuruyordum, ancak komut dosyalarına uzantı eklememenin nedeni nedir? Genelde öyle yapıyorum, çünkü düz metin dosyalarının böyle görünmesi beni ~ / bin / içinde tuttuğum ikili dosyaları düzenlemeye çalışmamı engelliyor. ( ls ~/bin/|wc -l = 428) Oraya pek çok şey koydum;)
Joey1978

Belirli bir görevi başarmak için bir komut dosyası yazdığınızı hayal edin. Sonra bu özel betiği python ile yazmanın çok daha etkili olacağını fark edersiniz, bu yüzden python ile yeniden yazarsınız. Şimdi iki seçeneğin var. 1) Şimdi çok yanıltıcı .sh uzantısını bırakın veya 2) betiği yeniden adlandırın ve yeni adı kullanmak için betiğin tüm kullanımlarını arayın ve değiştirin. İçinde komut bakarsak /binve /usr/binonlar uzantıları kullanmayın göreceksiniz.
geirha
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.