En taşınabilirlik için #! / Bin / sh vs #! / Bin / bash

cherouvim 08/30/2017. 3 answers, 2.821 views
linux bash shell sh

Genellikle Ubuntu LTS sunucularıyla çalışıyorum ki hangi sembolik bağ /bin/sh /bin/dash anlıyorum. Bir sürü dağıtım olsa da sembolik link /bin/sh to /bin/bash .

Bundan, bir komut dosyası üstte #!/bin/sh kullanıyorsa, tüm sunucularda aynı şekilde çalışmayabileceğini anlıyor muyum?

Bu komut dosyaları sunucular arasında maksimum taşınabilirlik istendiğinde komut dosyaları için hangi kabuğun kullanılacağı konusunda önerilen bir uygulama var mı?

1 Comments
Thorbjørn Ravn Andersen 08/01/2017
Çeşitli kabuklar arasında ufak farklar var. Taşınabilirlik sizin için en önemli ise, #!/bin/sh kullanın ve orijinal kabuğun sağladığı şeyden başka bir şey kullanmayın.

3 Answers


Gordon Davisson 08/01/2017.

Kabuk komut dosyaları için kabaca dört taşınabilirlik seviyesi vardır (shebang hattı söz konusuysa):

  1. En taşınabilir: Bir #!/bin/sh shbang kullanın ve only POSIX standardında belirtilen temel kabuk sözdizimini kullanın. Bu hemen her POSIX / unix / linux sisteminde çalışmalıdır. (Aslında, eski miras Bourne kabuğuna sahip Solaris 10 ve önceki sürümleri, POSIX'i bu kadar uyumlu olmayan /bin/sh olarak geçirmiştir.)

  2. İkinci taşınabilirlik: #!/bin/bash (veya #!/usr/bin/env bash ) şabang hattı kullanın ve bash v3 özelliklerine sadık kalın. Bu bash (beklenen konumda) olan herhangi bir sistem üzerinde çalışacaktır.

  3. Üçüncü en taşınabilirlik: #!/bin/bash (veya #!/usr/bin/env bash ) şabang hattı kullanın ve bash v4 özelliklerini kullanın. Bash v3'u olan herhangi bir sistemde başarısız olur (örn. Lisans nedenleriyle kullanmak zorunda olan macOS).

  4. En az taşınabilir: Bir #!/bin/sh shbang kullanın ve POSIX kabuğu sözdizimine bash uzantıları kullanın. Bu, / bin / sh için bash'dan farklı bir sistemi olan herhangi bir sistemde başarısız olur (son Ubuntu sürümleri gibi). Bunu hiç yapma sakın. Bu sadece bir uyumluluk sorunu değil, sadece yanlış yanlıştır. Ne yazık ki, bu birçok insanın yaptığı bir hatadır.

Tavsiyem: senaryo için ihtiyacın olan tüm kabuk özelliklerini sağlayan ilk üçün en muhafazakarını kullanın. Maksimum taşınabilirlik için seçenek # 1 kullanın, ancak deneyimlerimde bazı bash özellikleri (diziler gibi) # 2 ile birlikte kullanacağım kadar yardımcı olur.

Yapabileceğiniz en kötü şey # 4, yanlış şaban kullanarak. Temel POSIX özellikleri ve hangilerinin bash uzantıları olduğundan emin değilseniz, bash shebang (seçenek # 2) ile sopa atın veya komut dosyasını çok temel bir kabukla (Ubuntu LTS sunucularınızdaki çizgi gibi) iyice test edin. Ubuntu wiki'nin dikkat etmesi gereken iyi bir bashism listesi var .

Unix & Linux sorusundaki geçmişi ve kabuklar arasındaki farklar hakkında bazı iyi bilgiler var "Sh ile uyumlu olması ne demek oluyor?" Ve "Şş ile bash arasındaki fark" başlıklı Stackoverflow sorusu.

Ayrıca, kabuğun farklı sistemler arasında farklı olan tek şey olmadığını da unutmayın; Linux'a alıştıysanız, diğer unix sistemlerinde (örneğin, bsd, macOS) bulamayabileceğiniz çok sayıda standart dışı uzantıya sahip olan GNU komutlarına alıştınız. Maalesef burada basit bir kural yok, yalnızca kullandığınız komutların varyasyon aralığını bilmeniz gerekiyor.

Taşınabilirlik bakımından en iğrenç komutlardan biri en temel özelliklerden biridir: echo . Herhangi bir seçenekle ( echo -n veya echo -e ) herhangi bir zaman kullanırsanız veya dizeye yazdırmak için herhangi bir kaçış (ters eğik çizgi) ile farklı sürümler farklı şeyler yapacaktır. Ardından bir satır besleme olmadan bir dize yazdırmak istediğinizde veya dizedeki kaçışlarla yazdırmak istediğinizde bunun yerine printf kullanın (ve nasıl çalıştığını öğrenin - echo daha karmaşıktır). ps komutu da karışıklıktır .

İzlenecek diğer bir genel şey, son / GNUish'in komut seçeneği sözdizimine uzantılarıdır: eski (standart) komut biçimi, komutun seçeneklerle (tek çizgi ile ve her seçenek tek bir harfle) ardından gelmesinin ardından Komut argümanları. Yakın zamandaki (ve çoğu kez taşınabilir olmayan) türevler, seçeneklerin argümanlardan sonra gelmesine izin veren ve seçenekleri argümanlardan ayırmak için -- kullanarak uzun seçenekler (genellikle -- ile birlikte verilir) içerir.

5 comments
12 pabouk 07/30/2017
Dördüncü seçenek sadece yanlış bir fikir. Lütfen kullanmayın.
3 Gordon Davisson 07/30/2017
@pabouk Tamamen katılıyorum, bu yüzden daha net hale getirmek için cevabımı düzenledim.
1 jlliagre 07/30/2017
İlk ifadeniz biraz yanıltıcıdır. POSIX standardı, dışındaki şablon hakkında belirtilmeyen, belirtilmemiş davranışa neden olan kullanımını anlatıyor. Üstelik, POSIX, posix kabuğunun nerede bulunması gerektiğini belirtmez, yalnızca adı ( sh ), bu nedenle /bin/sh doğru yol olarak garanti edilmez. En taşınabilir o halde, herhangi bir şabanı belirtmemek ya da shebang'ı kullanılan işletim sistemine uyarlamak için değildir.
2 Michael Kjörling 07/30/2017
Son zamanlarda bir senaryomla # 4'e düştüm ve neden çalışmadığını anlamadım; Ne de olsa, aynı komutlar sağlam bir şekilde çalıştı ve bunları doğrudan kabukta denediğimde yaptıklarını yaptı. #!/bin/sh #!/bin/bash olarak değiştirir değiştirmez, komut dosyası mükemmel çalışıyordu. (Savunmam için, bu senaryo, zaman içinde yalnızca gerçekten yalnızca ihtiyaç duyulan şeylerden bash benzeri davranışlara dayanan bir kata doğru gelişti.)
2 jlliagre 07/30/2017
@ MichaelKjörling (true) Bourne kabuğu neredeyse hiçbir zaman Linux dağıtımı ile paketlenmemiş ve POSIX uyumlu değildir zaten. POSIX standart kabuğu Bourne değil, ksh davranışından oluşturuldu. FHS'yi takip eden çoğu Linux dağıtımı yapmak /bin/sh , POSIX uyumluluğu sağlamak için seçtikleri kabuğun simgesel bir bağlantısıyken, genellikle bash veya dash .

Kaz 07/31/2017.

Yapı için TXR dilini hazırlayan ./configure komut dosyasında daha taşınabilirlik için aşağıdaki önsözü yazmıştım. #!/bin/sh , POSIX uyumlu olmayan eski bir Bourne Kabuğu olsaydı bile betik kendini önyükleyecektir. (Her sürümü bir Solaris 10 VM üzerine inşa ediyorum).

#!/bin/sh

# use your own variable name instead of txr_shell;
# adjust to taste: search for your favorite shells

if test x$txr_shell = x ; then
  for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
    if test -x $shell ; then
       txr_shell=$shell
       break
    fi
  done
  if test x$txr_shell = x ; then
    echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
    txr_shell=/bin/sh
  fi
  export txr_shell
  exec $txr_shell $0 ${@+"$@"}
fi

# rest of the script here, executing in upgraded shell 

Buradaki fikir, altında çalıştığımızdan daha iyi bir kabuk bulmamız ve bu kabuğu kullanarak komut dosyasını yeniden çalıştırmamızdır. txr_shell çevre değişkeni ayarlanır; böylece, yeniden çalıştırılan komut dosyası yeniden yinelenen tekrarlanan örneğini bilir.

(Benim txr_shell , txr_shell değişkeni tam olarak iki amaca yönelik olarak da kullanılır: öncelikle betiğin çıktısında bilgilendirici bir mesajın bir parçası olarak basılmıştır.İkincisi, Makefile SHELL değişkeni olarak kurulur, böylece make bu kabuğu tarifleri yürütmek make de kullanacaktır.)

/bin/sh çizgi olduğu bir sistemde, yukarıdaki mantığın /bin/bash dosyasını bulacağını ve betiği bununla yeniden çalıştıracağını görebilirsiniz.

Bir Solaris 10 kutusunda, Bash bulunursa, /usr/xpg4/bin/sh başlatılacaktır.

Önsöz, varoluş testleri için test ve bazı kırık eski kabukları ikram etmek için argümanları genişletmek için ${@+"$@"} hükmü kullanarak muhafazakar bir kabuk lehçesinde yazılmıştır (eğer varsa "$@" olurdu) POSIX uyumlu bir kabukta).

2 comments
Charles Duffy 07/31/2017
Uygun alıntılama kullanılıyorsa, x hackery'ine ihtiyacı olmaz; çünkü bu deyimin zorunlu kıldığı durumlar -a veya -o ile birden çok testi birleştiren kullanılmayan test çağrılarında bulunur.
Kaz 07/31/2017
@CharlesDuffy Nitekim; test x$whatever yaparsam yapayım, vernikte soğan gibi görünüyor. Kırılmış eski kabuğa alıntı yapmak için güvenemezsek, son ${@+"$@"} girişimi anlamsız olur.

zwol 07/31/2017.

Bourne kabuk dilinin tüm çeşitleri, Perl, Python, Ruby, node.js ve hatta (tartışmasız) Tcl gibi modern komut dosyası dillerine kıyasla objektif olarak korkunçtur. Hatta biraz karmaşık bir şey yapmak zorunda kalırsanız, kabuk komut dosyası yerine yukarıdakilerden birini kullanırsanız, uzun vadede daha mutlu olacaksınız.

Kabuk dilinin hâlâ yeni dillere kıyasla sahip olduğu tek avantaj, kendisini /bin/sh olarak adlandıran bir şeyin Unix olduğunu ileri sürülen herhangi bir şey üzerinde olması garantisi olmasıdır. Bununla birlikte, bir şey bile POSIX uyumlu olmayabilir; Eski tescilli Unix'lerin birçoğu Unix95'in talep ettiği değişikliklerden prior (evet, Unix95, yirmi yıl önce ve sayım yaparak) /bin/sh ve yardımcı programların uyguladığı dili dondurdu. Şanslıysanız Unix95 veya POSIX.1-2001 setleri olabilir, varsayılan PATH (örneğin /usr/xpg4/bin ) değil bir dizinde bulunan araçlar ancak bunların var olması garanti edilmez.

Bununla birlikte, Perl'in temelleri, Bash'den çok keyfi olarak seçilmiş bir Unix kurulumunda more likely . ("Perl'in temelleri" ile /usr/bin/perl ve Perl 5'in some eski, muhtemelen eski versiyonudur ve şanslıysanız tercümanın bu versiyonuyla birlikte gönderilen modüller seti de mevcut.)

Bu nedenle:

Unix olduğunu düşündüğünüz everywhere ("configure" komut dosyası gibi) bir şeyler yazıyorsanız, #! /bin/sh #! /bin/sh kullanıyorsanız ve herhangi bir uzantı kullanmamalısınız. Günümüzde bu durumda POSIX.1-2001 uyumlu kabuk yazardım, ancak birisi paslı demir desteği istediğinde POSIX'leri düzeltmeye hazır olacağım.

Ancak, her yerde çalışması gereken bir şey yazmıyorsanız, herhangi bir Başsyizliği kullanmak için cazip olduğunuz andan itibaren, her şeyi yerine daha iyi bir betik dili ile yeniden yazmalısınız. Gelecekteki benliğiniz sana teşekkür edecek.

(Bash uzantılarını kullanmak ne zaman uygundur? Birinci mertebeye asla: ikinci derecede: yalnızca Bash etkileşimli ortamını genişletmek için - örneğin akıllı sekme tamamlama ve fantezi komut istemleri sağlamak için.)


HighResolutionMusic.com - Download Hi-Res Songs

1 (G)I-DLE

POP/STARS flac

(G)I-DLE. 2018. Writer: Riot Music Team;Harloe.
2 Ariana Grande

​Thank U, Next flac

Ariana Grande. 2018. Writer: Crazy Mike;Scootie;Victoria Monét;Tayla Parx;TBHits;Ariana Grande.
3 Imagine Dragons

Bad Liar flac

Imagine Dragons. 2018. Writer: Jorgen Odegard;Daniel Platzman;Ben McKee;Wayne Sermon;Aja Volkman;Dan Reynolds.
4 Backstreet Boys

Chances flac

Backstreet Boys. 2018.
5 Clean Bandit

Baby flac

Clean Bandit. 2018. Writer: Jack Patterson;Kamille;Jason Evigan;Matthew Knott;Marina;Luis Fonsi.
6 BTS

Waste It On Me flac

BTS. 2018. Writer: Steve Aoki;Jeff Halavacs;Ryan Ogren;Michael Gazzo;Nate Cyphert;Sean Foreman;RM.
7 Fitz And The Tantrums

HandClap flac

Fitz And The Tantrums. 2017. Writer: Fitz And The Tantrums;Eric Frederic;Sam Hollander.
8 BlackPink

Kiss And Make Up flac

BlackPink. 2018. Writer: Soke;Kny Factory;Billboard;Chelcee Grimes;Teddy Park;Marc Vincent;Dua Lipa.
9 Calum Scott

No Matter What flac

Calum Scott. 2018. Writer: Toby Gad;Calum Scott.
10 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
11 Kelly Clarkson

Never Enough flac

Kelly Clarkson. 2018. Writer: Benj Pasek;Justin Paul.
12 Imagine Dragons

Machine flac

Imagine Dragons. 2018. Writer: Wayne Sermon;Daniel Platzman;Dan Reynolds;Ben McKee;Alex Da Kid.
13 Diplo

Close To Me flac

Diplo. 2018. Writer: Ellie Goulding;Savan Kotecha;Peter Svensson;Ilya;Swae Lee;Diplo.
14 Cher Lloyd

None Of My Business flac

Cher Lloyd. 2018. Writer: ​iamBADDLUCK;Alexsej Vlasenko;Kate Morgan;Henrik Meinke;Jonas Kalisch;Jeremy Chacon.
15 Ashley Tisdale

Voices In My Head flac

Ashley Tisdale. 2018. Writer: John Feldmann;Ashley Tisdale.
16 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
17 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
18 Little Mix

Woman Like Me flac

Little Mix. 2018. Writer: Nicki Minaj;Steve Mac;Ed Sheeran;Jess Glynne.
19 Little Mix

Told You So flac

Little Mix. 2018. Writer: Eyelar;MNEK;Raye.
20 Frida Sundemo

Apologize flac

Frida Sundemo. 2018.

Related questions

Hot questions

Language

Popular Tags