.sh belirleme uzantısı?


12

Neden bazı sistemler .shsadece dosya adını uzantısız belirterek bir dosyayı çalıştırır ve diğerleri de isim artı uzantı gerektirir? Benim durumumda bu talimatları izleyerek bir dizi komut yazmaya çalışıyorum .

Şimdi uzantıyı .shbelirtiyorum ancak komutları olmadan çalıştırabilmek tercih edilir.


4
Kullanımı .shbir uzantısı olarak kötü uygulama olarak kabul birçok durumda geçerli: O (çalıştırmak olmayan diğer komutlar nasıl adlandırıldığı aykırıdır ls.elf), genellikle (yanıltıcı işleminizse foo.shile başlar #!/bin/bash, daha sonra çalışan sh foo.sho için oluşturulan farklı bir tercüman ile çalışacak ) ve foo.shbir Python programı olarak yeniden yazarsanız , bu uzantıyı kullanmak, şimdi yanıltıcı adı korumak ve onu çağıran her programı yeniden yazmak arasında seçim yapmanız gerektiği anlamına gelir.
Charles Duffy

2
... nerede olduğunu değil komutları, en iyi uygulama kabuk kütüphaneler olduğunu +xseti - foo.shherhangi bir POSIX kabuk içine kaynaklı olabilir bir kütüphane olduğunu foo.bash, bash içine kaynaklı olabilir foo.kshvs. ksh, içine
Charles Duffy

Yanıtlar:


39

Kafan karıştı. .shUzantı yalnızca insanlara bir ipucu olduğunu ve sistem dosyasını nasıl işleyeceğini kesinlikle HAYIR etkiye sahiptir. Unix / Linux Windows'un gafletini yapmadı Secrets.pdf.exe.

Yazdığınızda şunlar olur foo:

  1. İçin Yönlendirme STDIN, STDOUTve STDERRkurulur.

  2. Kabuk, zaten bir $PATHgirdi bilip bilmediğini görmek için dahili karma tablosunu kontrol eder foo. Hiçbiri yoksa, kabuk, dizinlerinde arama yaparak dosya izinlerinde Yürütme biti ayarlanmış $PATHbir dosya arar foo. İlk fookazanır.

  3. Dosyanın ilk iki baytı fooise #!, sonraki dize çalıştırılacak bir yorumlayıcının adıdır. Böylece #!/bin/bashbir Bash betiği, #!/usr/bin/perlbir Perl betiği, vb.

  4. Dosya ile başlıyorsa \177ELF, bu bir ikili yürütülebilir dosyadır ve dosyayı başlatır ld.so.

Oku man execveve man ld.sobir daha ayrıntılı açıklama için.


15
Evet, Linux'ta aslında yürütülebilir bir ad olduğuna dair hiçbir ipucu olmadan Secrets.pdf dosyasına çift tıklayabilirsiniz;)
OrangeDog

1
@OrangeDog Şaka yaptığınızı biliyorum, ama yürütülebilir bit'in ( chmod +x) bunu hemen hemen çözdüğünü belirtmem gerektiğini hissediyorum , değil mi?
wchargin

3
@WChargin Dosya sisteminizin ne kadar iyi davrandığına bağlıdır (örneğin, bağlı bir ağ paylaşımı veya NTFS bölümü iyimser bir şekilde xher şeye ayarlayabilir ) ve dosyanın nereden geldiğini (dizinin kontrolüne sahip herhangi bir işlem izinleri ayarlamak için kandırılabilir) . Yani, hafifletiyor , ama çözdüğünü söyleyemem .
IMSoP

2
@WChargin, henüz, ama genellikle dosya yöneticileri yürütülebilir biti göstermek onun anlamı, yani bir uzantı gibi "insanlara ipucu" olduğunu düşünüyorum.
Paul Draper

1
Her zaman Secrets.pdf.exeaptal hide file extensionözelliği devre dışı
bıraktığım

12

Anahtar nokta şudur: Uzantılar herhangi bir Unix benzeri sistem sisteminde önemsizdir. Dosya adı sadece addır ve komut dosyasının veya derlenmiş yürütülebilir dosyanın çalıştırılıp çalıştırılmayacağı üzerinde hiçbir etkisi yoktur . Bir programcı, .shbir dosyanın kabuk komut dosyası olduğunu veya .pypython komut dosyası olduğunu belirtmek için bir uzantı ekleyebilir , ancak Windows'tan farklı olarak, herhangi bir unix adlandırmayı umursamaz, izinleri umursar.

Önemli olan, bir dosyaya verilen yürütülebilir izindir. Hangisini kontrol edebilirsiniz

ls -l /path/to/file

Yürütülebilir dosyalar

Komut dosyasını çalıştırmak için genellikle birkaç yol vardır.

  • Geçerli dizininiz komut dosyasıyla aynıysa ve komut dosyasının yürütülebilir izinleri varsa, bu şekilde çalıştırabilirsiniz ./my_script_name. .Geçerli dizini anlamına gelir.
  • Geçerli dizininiz farklıysa ve komut dosyasının yürütülebilir izinleri varsa, tam yolu belirterek dizini çalıştırabilirsiniz: /home/user/bin/my_script_name

(Yukarıdaki iki yöntem yürütülebilir izin kümesi olan itimat, dosya parçası olup olmadığını $PATHdeğişken önemsizdir varlığı. #!Hattının da önemli, aynı bu komut geçerli kabuk tarafından yürütülecek olmadan açtığınız ben varsa. cshSenaryoyu bu çizgi olmadan ve bash ile çalıştırmayı deneyin ./my_script.csh, başarısız olur)

  • Betiğiniz $PATHdeğişkeninizin bir parçası olan bir dizinde bulunuyorsa, yalnızca adı çağırarak çalıştırabilirsiniz. chmodKomut satırında komutu, /binklasörde olduğu için adını yazarak çağırabilirsiniz . /binher zaman $PATHdeğişkenin bir parçasıdır . Bu durumda, yürütülebilir izinler ve komut dosyasının konumu
  • Bir yorumlayıcıyı komut ve komut dosyası olarak bağımsız değişken olarak belirtme. Bu şekilde komut dosyası, tercümana girdi dosyası olarak hizmet edecektir.
  • Bir dosyanın kaynağı. . filename.shVeya source filename.shdoğrudan komut satırına yazdığınız sanki o klavye girişi, yani sanki komut tedavi edilebilir hale getirecektir. Bu durumda yürütülebilir izinler ve konum önemli değildir

Örnekler

İzinleri yürütmek için yorumlayıcı ile çalışan örnek 1

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

Örnek 2 - ./yürütülebilir izin kümesi ile çalışan , satır kümesi.

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

Örnek 3, shebang satır kümesi olmadan çalışıyor (başarısız, çünkü bash python komut dosyalarını okuyamıyor; hiçbir shebang satırı geçerli kabuğu yorumlayıcı olarak kabul etmiyor)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

Örnek 4, $PATHdeğişkenin bir parçası olan yürütülebilir izinleri ayarlanmış form klasörü olan komut dosyasını çalıştırma

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

5. örnek, uzantı kaldırılıyor, uzantılar önemli olmadığı için çalışıyor, ancak izinleri var ve aşağıdakilerin bir parçası $PATH:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

Komutu çalıştırdım ve bunu '-rwxr-x ---' alıyorum. Değerin ne okumasını istiyorum ve nasıl değiştirebilirim?
Philip Kirkbride

Yoksa sadece 'filename.sh' dosyasını 'filename' olarak yeniden adlandırmam gerektiğini mi söylüyorsunuz?
Philip Kirkbride

1
@PhilipKirkbride Adı alakasız. Komutunu nasıl çalıştırıyorsun? Nerede ? Dizin sizin bir parçanız PATHmı?
Sergiy Kolodyazhnyy

@PhilipKirkbride Cevabımı daha net hale getirmek için bir dakika içinde genişletmeme izin verin.
Sergiy Kolodyazhnyy

1
man chmodİzinlerin nasıl ayarlanacağını görmek için bir göz atın
Nick Mertin

6

Burada zaten iyi açıklamalar var. Sadece ideal olarak yürütülebilir dosyalar için dosya uzantıları kullanmamanız gerektiğini eklemek istedim.

Genellikle nispeten kolay bir şey başarmanız gerekir ve küçük bir kabuk komut dosyasıyla başlarsınız. Zaman içinde komut dosyanıza, sürdürülemez hale geldiği bir zamana kadar veya bir kabuk komut dosyası ile kolayca başaramayacağınız ve bu kabuk komut dosyasını başka bir dilde yeniden yazmayı düşünemediğiniz bir işleve ihtiyacınız olana kadar daha fazla işlevsellik eklemeye başlarsınız. , perl, ...?).

Sıfırdan yeniden yazma genellikle bir hata olarak kabul edilir, ancak komut dosyaları için mantıklı olabilir, çünkü genellikle o kadar büyük değildir veya çok fazla işlevselliğe sahiptirler. Ancak, ilk kabuk komut dosyasının işlevselliğini ve parametrelerini / bayraklarını koruyarak, başka bir dilde sıfırdan yeniden yazmanın mümkün olduğunu varsayalım.

Bu komut dosyasının kullanıcılarının bu dil değişikliğinin farkında olmaları gerekmez, aynı komutu yürütmeye devam ederler ve çalışmaya devam ederler.

Eğer betiğiniz isimlendirilmişse do-something.sh, devam etmeye devam edebilir do-something.sh, ancak şimdi python ile yazılmıştır (örneğin) ve böylece ilk ipucunuz şimdi tamamen yanıltıcıdır.


4

Bir uzantı olmadan dosyaları çalıştırmak için normalde fazla bir şey yapmanıza gerek yoktur, sadece ilk satırda (bash komut dosyalarında) doğru shebang satırına sahip olduğunuzdan emin olun:

#!/bin/bash

sonra da dosyayı sistem için yürütülebilir hale getirmek gerekir

chmod 755 yourfilename

Bu chmod +x yourfilenamerakamların kullanımı ile aynı kolay açıklanır.

Eklenen sekizlik sayıların üç katı, ilk sayı kullanıcı için, ikincisi grup için ve üçüncü sayı diğerleri için, daha fazla burada bulabilirsiniz .

Eğer senaryonuzla aynı dizindeyseniz şu şekilde kullanmayı unutmayın ./:

./yourfilename

Bunu denedim. Ne yazık ki orijinal sonuçlardan hiçbir fark yok.
Philip Kirkbride

@PhilipKirkbride gözden geçirilmiş cevabım bir göz atın bu muhtemelen daha fazla ışık tutacak.
Videonauth

0

.Sh soneki aslında yol alabilir, çünkü daha sonra çalıştırmak için sadece çalışmayan myscript yerine myscript.sh yazmanız gerekir. Sadece .sh soneki olmadan "myscript" olarak adlandırmak daha iyidir ve "dosya" komutunun hızlı kullanımı, bir ikili yürütülebilir dosya (linux üzerinde ELF formatı) veya bir kabuk komut dosyası veya başka herhangi bir komut dosyası olup olmadığını söyleyecektir.

QDOS (Hızlı ve Kirli İşletim Sistemi, daha sonra mirosoft korsanlayıp yasadışı olarak onlara sattıktan sonra IBM tarafından "DOS" olarak yeniden adlandırıldı) ve pencereler de dahil olmak üzere diğer ucuz CP / M ripoff'larını karıştırıyor, çünkü bu sistemlerde dosyalarda yürütme izinleri gibi bir şey. Bu, son 30-40 yıl içinde sayısız güvenlik sorunuyla sonuçlandı. Aslında sadece birkaç dakika önce MYPICTURE.JPG.zip olarak yeniden adlandırılan bir bubi tuzaklı zip dosyası ile birkaç önemsiz posta aldım :)

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.