Bash ne zaman ve ne zaman Perl / Python / Ruby kullanılır? [kapalı]


78

Şimdiye kadar Bash ile yazdıklarımızı yapıyoruz, ama bunun hakkında biraz aptal hissetmeye başladım. Tabii ki Bash ile istediğimiz her şeyi yapabiliriz (oldukça güçlü), bunun yerine uygun bir betik dili kullanmamamız gerekip gerekmediğini merak ediyorum.

Bir komut dosyası için Perl / Python / Ruby'yi Bash üzerinde ne zaman kullanacağınıza nasıl karar verirsiniz? Ruby ile bir init betiğinin bir anlam ifade ettiğini düşünmüyorum, ancak e-posta hesapları ekleyen biraz daha uzun bir betiğe ne dersiniz?


1
İkisini de kullanarak yapabilirseniz, gerçekten önemli mi? Seçim, sonuçtaki komut dosyası farklılıklar gösterirse ilginçtir. Örneğin, yürütme süresi önemli ölçüde farklılık gösterebilir (e-posta hesaplarında sorun değil).
Dennis,

Yanıtlar:


44

Her ikisinin de başarabileceği bir sorun göz önüne alındığında, en rahat olanı kullanmak isteyeceksiniz. Sonuçta, birçok küçük ayrıntı vardır ve yalnızca deneyim onları görmeyi öğretebilir.

Bash, Python, Ruby, Perl gibi genel amaçlı bir betik dilidir, ancak diğerlerinin üzerinde farklı güçler vardır. Perl, metin analizinde mazeret görüyor, Python, grubun en zarif olduğunu iddia ediyor, Bash senaryoları, "ne demek istediğimi biliyorsan" etrafta dolaşıyorlar "ve Ruby ... çok iyi, Ruby çok özel Yollardan.

Bununla birlikte, aralarındaki farklar, yalnızca, kemerinizin altında sağlıklı bir miktarda kriptolama tecrübesine sahip olduğunuzda gerçekten önemlidir. Bir dili seçmenizi ve diğerine geçmeden önce sınırlarını zorlamanızı öneririm. Bir kabuk betiğinde, çoğu insanın kabul edebileceğinden daha fazlasını yapabilirsiniz. Herhangi bir dil yapmak istediğiniz kadar zor. İçinde birkaç şey yazdıktan sonra, her dil sizin için "kolaydır".

Linux'ta yaşarsanız, kabuğa aşina olmak hızlı bir şekilde karşılığını verir, bu yüzden belki de başlamak istersiniz. Bir kabuk betiğinde çözülmesi imkansız veya pratik olmayan bir görev bulursanız, başka bir şey kullanın.

Ayrıca, kabuk komut dosyası öğrenmenin çok basit olduğunu unutmayın. Bunun gerçek gücü, awk, sed, tr ve diğerleri gibi diğer programlarda yatmaktadır.


Ruby'de olduğu gibi bas komut dosyasıyla ilgili oldukça tecrübem var, ancak bazen ne kullanacağımı hala bilmiyorum. O zamanlar kişisel tercihinize göre seçim yapmak aptalca görünüyor. Ama haklısın, kendime ne yapmak istediğimi soracağım ve iş için en iyi aracı seçeceğim.
futlib

Şahsen, iyi tanıdığım dillerin bir skalasını, artan karmaşıklık ve güç sırasına göre kullanacağım ve tasarıya en uygun olanı kullanacağım. Ama gerçekten, kesin olarak bilmenin tek yolu, bülteninizi tüm dillerde yazmak ve sonuçları karşılaştırmak. Hepsi kesinliğin dışında bir içgüdü duygusundan daha fazlası. Senelerce senaryolar yazdıktan sonra, çoğu "problem türü" ile karşılaşacak ve hangi dilin bunları iyi çözdüğünü bileceksiniz.
mkaito

Sadece GNU coreutils paketindeki küçük programları kullanarak (tr, sort, uniq gibi) eklemek ve bunları bir çok işin gerçekleştirilmesinin mümkün olduğunu eklemek istedim.
GMaster

58

TL; DR - bash'ı yalnızca daha iyi bir dil yüklemek için kullanın (zaten mevcut değilse), aksi takdirde kurtarılamaz, değerli insan zamanını boşa harcarsınız. Komut satırında hatasız el ile yapamıyorsanız, bash / shell ile komut yazmayın.

2015, bu yüzden aşağıdakileri göz önünde bulundururum:

  1. bellek yükü

    • Ruby / Python çalışma zamanı bash ile karşılaştırıldığında genel gider hafızası küçüktür (paylaşılan kütüphaneler nedeniyle), ancak biri önemsiz olmayan bash betiğini yine de koruyamaz (örn.> 100 satır olanı) - bu nedenle bellek kullanımı bir faktör değildir
  2. başlama zamanı

    • Ruby / Python'un başlatılması biraz daha yavaş olabilir, ancak olasılıkla saniyede 100 kez çok fazla sayıda Ruby / Python işlemi gerçekleştirmeyeceksiniz (bu tür ihtiyaçlarınız varsa, bash / shell Zaten çok fazla ek yük ve muhtemelen C / C ++ 'a bırakmanız gerekir.
  3. verim

    • Neredeyse tüm tipik veri toplama işlemleri Ruby / Python'da daha hızlı olacaktır - ya da en azından karşılaştırılabilir (ya da yine de C / C ++ / Haskel / OCaml / her neyse)
    • uygulamadaki gerçek performans / tıkanıklık (veya hatta üretkenlik) neredeyse hiç bir zaman "bash / shell kullanma eksikliği" (başlangıç ​​için Ubuntu anahtarlama teli bile olsa, aslında bash sorununun ne olduğunu gösterir - ve bir meşgul kutusu muhtemelen tek kullanımlık durumdur) orada çünkü olduğunu yazmak ve kod çalıştırmasına 'bash' ve 'vi' başka bir şey, ve) ekleyin / indirme veya başka bir şey saklamak için hiçbir şekilde sık sık var
    • işi yapmak için başka işlemleri yürütmek (sed / awk / grep gibi) aslında bellekteki bir canlı nesnede bir yöntem çağırmaktan daha büyük bir değerdir
  4. verimlilik

    • Bash / Shell'de Ruby / Python'da "real" yöntem, parametre, değişken ve istisnalar kullanmaktan başka hata yapmak çok kolaydır.
    • Çevik geneldir, Bash'in desteği yoktur (birim test kabiliyetleri, kütüphaneler, OO, modülerlik, astarlama, iç gözlem, kayıt, metaprogramlama, bir şeyi kırmadan neredeyse refaktör yapmak imkansızdır)
    • Diğer kabuklarla çok fazla uyumsuzluk olsa da, küçük ortam değişkenleri bir senaryoyu tamamen bozabilir (ve Puppet gibi bazı önemli aygıtlar shebang satırlarını görmezden gelir ve önemli kabuk değişkenlerini geçirir veya yeniden yazar), Ruby / Python iyi tanımlanmış nispeten düzgün bir göç gösterir. Büyük sürüm değişiklikleri için bile yollar
    • yeni bir dil öğrenmek, kabuğa özgü sorunlar nedeniyle (özellikle değişken isimler, booleans yok, istisnalar yok) alternatif olarak harcanan kabuk komut dosyalarının harcadığı zamanın bir kısmını alır.
    • başlangıç ​​komut dosyaları bile bir mayındır ( özellikle sistem başlangıcında başarısız olabilirler ) ve en son güvenlik açığı verilen bash ile ilgili olarak, düz C (iyi kitaplıklarla) kullanarak daha iyi olabilirsiniz - evet, C'nin derlenmesi, yapılandırılması vb. , fakat basit bir kabuk betiğinin bile bir depoya, daha sonra versiyonlamaya ve daha sonra paketlemeye ihtiyacı olabilir.
    • ne olursa olsun / grep olasılıkla zaten Yakut / Python yerleşik sed / Awk kullanılabilir - bir bağımlılık veya platformlarda bu araçları sürümleri arasındaki "fark" (yani çalışıp çalışmadığını nasıl olmadan senin kurulum)
  5. iş güvenliği
    • Sevmediğiniz bir işi güvence altına almanın amacı nedir? (bu saatlerin hepsini hata ayıklaması zor ancak önemsiz hale getirilmiş kabuk komut dosyası hataları harcamayı sevmiyorsanız)

Ruby / Python kurulu ise Bash / Shell'i kullanmak için hiçbir neden yoktur.

Muhtemelen Ruby / Python'u kurmak, ilk başta bir bash betiğine bile ihtiyaç duymaz (busybox hariç, bazı sistem araçları Python / Perl'in zaten mevcut olmasına bağlıdır).

Bir kabuk senaryosu yazdığınızda, daha güçlü / üretken bir şey öğrenmek yerine, tam olarak bunu yaparak "pratik yapıyorsunuz".

İnsanlar bugünlerde neden Bash kullanıyor? Çünkü bu korkunç, yıkılması zor bir alışkanlık. Bir senaryo, ilk birkaç dakika sonra nadiren “sonsuza dek tamamlanır” - insanlar ne kadar güçlü bir şekilde böyle düşünürse düşünülsün. Yanında "bu senaryoda son hata" haksızlığı ile birlikte.

Sonuç: bash / shell'i sadece ( kesinlikle , meşgul kutusu gibi ) kesinlikle zorunlu olduğunuzda kullanın ~/.bashrc, çünkü günümüzde neredeyse hiç bir zaman "iş için doğru araç" değildir.


28

Birincil odağım dosya işlemeyken bash kullanıyorum. Bu, dosyaları taşımak, kopyalamak ve yeniden adlandırmak, ayrıca dosyaları diğer programlar için giriş olarak kullanmak veya başka programların çıktısını dosyalara depolamayı içerebilir. Nadiren bir dosyanın içeriğini inceleyen veya bir dosyaya yazmak için çıktı üreten bash kodu yazıyorum; Bunu bash ile başlattığım diğer programlara (Perl veya python'da yazabileceğim) bırakıyorum.

Birincil odağım dosyalardan veri okuma, bu verileri bir şekilde işleme koyma ve dosyalara çıktı yazma konusunda Perl ve python kullanıyorum. Kendimi (Perl'de) systemkomutunu kullanırken bulursam , geri subprocessmodülü çok yoğun bir şekilde tıklatır (python'da) , komut dosyasını bash olarak yazmayı düşünürüm. Öte yandan, bazen bir bash betiğine çok fazla işlevsellik eklemeye başlıyorum, sonuçta değişken kapsam, fonksiyonlar, veri yapıları vb. İçin sınırlı sınırlı (karşılaştırma yoluyla) destekle uğraşmak yerine Perl / python'da yeniden yazmak daha mantıklı geliyor. .


2
Ne zaman dosya okuma / metin oluşturma gerektiğinde t0'ı da kefaletle kullandım, ancak =~operatör tarafından öğrenilen operatörü öğrendikten sonra basit dosya okuması [[ ]]için beni bazı Bash'leri seviyorum
Freedom_Ben

16

Bu blog yazısında belirtilen kriterleri seviyorum .

  • Girilecek herhangi bir argüman yoksa, muhtemelen bir kabuk betiğidir.
  • Kontrol mantığı için fazla bir şey yoksa (tek bir döngü dışında veya if / else) muhtemelen bir kabuk betiğidir.
  • Görev komut satırı talimatlarının otomasyonu ise neredeyse kesinlikle bir kabuk betiğidir.

8

Perl'e karşı Bash analizini faydalı buldum ...

http://blogs.perl.org/users/buddy_burden/2012/04/perl-vs-shell-scripts.html

Kolaylık sağlamak için, yazarın 1) bash daha iyi bulgular olduğunda 2) ve perl daha iyi bir sonuç olduğunda ...

Bash daha iyi olduğunda ...

  • İş Arızası
  • Çıkış Komutları
  • İş çıktı satırlarının işlenmesi
  • İşte Belgeler
  • Dosya Denklikleri
  • Dosya Zaman Damgası Karşılaştırmaları
  • Tilde Genişlemesi

Perl Daha İyi Olduğunda ...

Perl, çoğu uygulama için hala saçmalıktan kurtuluyor. Perl'i tercih edebileceğim sebepler arasında şunlar yer almaktadır (ancak bunlarla sınırlı değildir):

  • Daha hızlı olacak. Esas olarak, yapmak istediğim birçok şey için aslında yeni süreçler başlatmam gerekmiyor (temel ad ve dizin adı en açık örneklerdir, ancak genel olarak kesilmiş, grep, sıralama ve wc de tamamen ortadan kaldırılabilir).
  • Bash'de string kullanımı en iyi ihtimalle ilkel, ve tüm $ IFS olayı süper topaklı.
  • Kabuk betiklerinde yer alan şartlamalar riskli olabilir.
  • Kabuk yazılarında alıntı yapmak bir kabus olabilir.
  • bash'ın davası, basit vakaların (NPI) ötesinde arzulanan çok şey bırakıyor.
  • Bash dizilerde emmek. Bash'deki karmaşalar (bash'ınızın onları alabilecek kadar yeni olduğu varsayılarak) daha da zorlaşır.
  • Dosyaları işledikten veya komut çıktısı yukarıda listelediğim basit durumdan sonra, Perl gerçekten sigara içmeye başlar.
  • CPAN.

Yani kısa sürede Perl’e devralmayacak. Ama yine de, bunca yıldan sonra, çoğu zaman basit bir kabuk betiğinin bazen basit bir Perl betiğinden daha basit olabileceğini düşünüyorum. Dediğim gibi, beni başka türlü ikna etme girişimlerinden memnuniyet duyarım. Ancak, o zaman yine, araç kutunuzda birkaç farklı araca sahip olmanın yanlış bir tarafı yoktur.


İlginç bir şekilde, Ruby'de noktaların tümü (?) Geçerli değildir, çünkü Ruby'de at_exit (), realpath (), expand_path (), stat (), heredocs ve istisnalar ( fail "error" unless system("foobar")) bulunur.
Cezary Baginski

5

Tecrübelerime göre bash ve python karşısında gelişim zamanı ile esneklik arasında bir denge var. Bir probleme ilkel çözüm, genellikle bir bash betiğinde bir python betiğinde olduğundan daha hızlı bir şekilde ortaya çıkar.

Python, çözümünüzün yapısı hakkında, eşdeğer bash betiğinden daha fazla düşünmenizi sağlar. Python bir bash betiğinden daha anlamlı bir güce sahiptir ve bu nedenle zamanla daha iyi ölçeklendirme ve değiştirme eğilimindedir. Ayrıca, genel olarak daha okunaklı kalmaktadır.

Bash dosya sistemine daha yakındır ve iyi tanımlanmamış sorunlara ilk taslak çözümler için harika olabilir. Bu nedenle, bir bash betiği, problem daha iyi anlaşıldığında bir şeyi onu python'a taşıma niyetiyle prototip yapmak için iyi bir ilk seçenek olabilir.


4

Bash, bir kodlama dili içeren bir Unix kabuğudur. Daha çok komut işlemcisi. komutları nasıl çalıştıracağını kontrol ediyorsun, aslında onları çalıştırıyorsun.

Perl / Ruby / Python genel amaçlı dillerdir.

Bir kabuk betiği istediğinizde Bash kullanın

Daha karmaşık bir iş istiyorsanız veya kabukla ilgili değilseniz. Python vb. Kullanın.

Aslında bu dilleri asla karşılaştırmam. Python vb. Taşınabilir. Onları herhangi bir yerde çalıştırabilirsin. Bash yalnızca Unix içindir.

Python vb milyonlarca görevi çözen tonlarca yeniden kullanılabilir kütüphaneye sahiptir.

İsterseniz neredeyse aynı. "Paint ne zaman ve Photoshop ne zaman kullanılır"

E-postaları işlemek için Ruby'i tekrar kullanırdım çünkü çok fazla tekrar kullanılabilir kütüphaneye sahiptir.

Ancak en iyi yol bash ve yakutu birleştirmektir. Bu doğru olurdu. Yakut ve bash komut dosyasında bir e-posta işleme komut dosyası oluşturduğunuz gibi bu yakut komut dosyasını çağırır ve diğer commans ds komutunu çalıştırır.

Bu yüzden ne zaman bir komut işlemcisine ihtiyacınız olursa bash kullanırsınız. Unix komutlarını çalıştırıyor ve kontrol ediyorsunuz.

7 yıl sonra GÜNCELLEME (Mar 2019)

Cevabımın ana kısmı değişmediyse, bunu belirtmek isterim.

Bash de güçlü bir betik dilidir. Metin işleme için mutlak bir yasal seçim olabilir.

Mkaito adlı kullanıcının yorumlarını lütfen okuyunuz. Hepsi tamamen doğru.


1
Bash'in komut dosyası alt kümesi, herhangi bir genel amaçlı komut dosyası dili kadar genel bir amaçtır. Karışıma sed gibi genel programlar ekleyin ve sahip olacağınız tüm scriptleme gereksinimlerinin% 90'ını kendiniz karşılayın.
mkaito

1
bash bir komut işlemcisidir, bu yüzden gücü diğer unix komutlarını ve programlarını komut dosyalarında çalıştırmaktır.
Sed'in dediğin gibi.

1
Kabuk gerçekten yüceltilmiş bir program başlatıcısı, ancak komut dosyası yazma yetenekleri bunun çok ötesinde. Bazı gerçek kabuk komut dosyası öğrenmenizi öneririm.
mkaito

Yerde uyuyabilirim ama bir yatakta yapmayı tercih ederim. Dillerin farklı amaçlara sahip oldukları ile kıyaslanamaz.
bakytn

2
Eh, Bash yerdeyse, Haskell gibi bir yazı tahtası olmalı :-)
mkaito

1

Bass, ksh, zsh, sh ve balık gibi Shell scriptleri, Ruby, Python veya Perl gibi yüksek düzey genel amaçlı dillerle karşılaştırıldığında, şaşırtıcı bir şekilde şaşırtıcıdır. Bir kabuk betiği, kendi hayatına, eşdeğer genel amaçlı betiğe göre daha kısa bir dosya olarak başlasa da, sürprizler, set -euo pipefailkatı kipleri mümkün kılmak gibi birçok savunma sarma koduna yol açar .

Örnek için, çoğu kabuk dili, komutlardan biri başarısız olsa bile bir kabuk komut dosyasında satırları çalıştırmaya devam eder. Buna karşılık, genel amaçlı bir dil, ilk hatada hemen başarısız olur ve genellikle yüklenir ve hafif karmaşıklıktaki komut dosyalarında daha güvenli, öngörülebilir davranışlarla sonuçlanır.


1

Yüksek önyargılı makale.

Hata ayıklamak o kadar zor olmak için bash bulamıyorum. Python genellikle çok katıdır, oysa bash çok yaratıcı olmanıza izin verir. Kullanıma hazır bir düşünür iseniz, bash seveceksiniz.

Binlerce dosyadaki milyonlarca DNA dizilimini okuyan bash scriptlerini çalıştırıyorum ve bana gayet iyi hizmet ediyor. Ve herkesin söylediğinin tersine, C ++ 'daki komut dosyalarının aynı sürümleri aslında bu kadar hızlı çalışmamaktadır (birkaç dakika içinde bunları ayırınız).

Bence bash, perl gibi en kullanıcı dostu / okunması kolay değil. Bu insanları korkutur çünkü çoğu insan soyut düşünür değildir. Ancak daha parlak, daha yaratıcı programcılar onu sevmeye ve sık kullanmaya meyillidir. Kendini tanıyorsan ve beynin olduğunu biliyorsan, bashtan korkma. Temel bir düşünürseniz, Python gibi bir şeye bağlı kalabilirsiniz. Her birine kendi.


0

"Lama Kitabı" ndan

Perl, düşük seviyeli programlama (C veya C ++ 'da olduğu gibi) ve yüksek seviyeli programlama (“kabuk” programlama [örn bash.] Gibi) arasındaki boşluğu doldurmaya çalışır . Düşük seviyeli programlama genellikle yazmak ve çirkin ancak hızlı ve sınırsızdır; Belirli bir makinede iyi yazılmış, düşük seviyeli bir programın hızını geçmek zor. Ve orada yapamayacağın bir şey yok. Yüksek seviyeli programlama, diğer uçta, yavaş, zor, çirkin ve sınırlı olma eğilimindedir; Sisteminizde gerekli işlevselliği sağlayan herhangi bir komut yoksa, kabuk veya toplu programlama ile yapamayacağınız pek çok şey vardır. Perl kolay, neredeyse sınırsız, çoğunlukla hızlı ve çirkin.


0

Başparmak kuralı olarak, elinizdeki görev için yeterince iyi performansı olan en basit dili kullanın . Ve sadece onlar uzatmak için özellikleri gerçekten yararlıdır.

Okunabilirlik hakkında, programlama stiliniz korkunçsa Bash korkunçtur. Oraya sadece kod atarsanız, belirsizleşir.

Ancak, kodu en kısa işlevlere bölerseniz ve şeyleri basit ve anlaşılır bir şekilde adlandırırsanız, bulabileceğiniz en net dildir. Çünkü çok özlü.

Örnek olarak, bu benim Bash'deki son kodum. Anlamanın ve yazmanın ne kadar kolay olduğuna dikkat edin:

#! /bin/bash


mainFunction () {
    file="${1}"

    checkFile "${file}"
    executeFile "${file}"
}


changeToThisProgramDir () {
    cd "$( dirname "${BASH_SOURCE[0]}" )"
}


checkFile () {
    file="${1}"

    checkFileNotEmpty "${file}"
    checkFileExist "${file}"
    checkFileIsExe "${file}"
}


checkFileExist () {
    file="${1}"

    if [ ! -f "${file}" ]; then
        echo "The file doesn't exist: ${file}" >&2
        echo "If the name was correct either type: exeCute \"pathToYourExeFile\""
        echo "Or just open with exeCute from the file manager"
        exit 1
    fi
}


checkFileIsExe () {
    file="${1}"
    mime=$(fileMime "${file}")

    if [ "${mime}" != "application/x-dosexec" ]; then
        echo "Not an exe: ${file}" >&2
        exit 1
    fi
}


checkFileNotEmpty () {
    file="${1}"

    if [ "${file}" == "" ]; then
        echo "No file specified" >&2
        echo "Either type this: exeCute \"pathToYourExeFile\""
        echo "Or just open with exeCute from the file manager"
        exit 1
    fi
}


execute () {
    function="${1}"
    command="${2}"
    error=$(eval "${command}" 2>&1 >"/dev/null")

    if [ ${?} -ne 0 ]; then
        echo "${function}: ${error}" >&2
        exit 1
    fi
}


executeFile () {
    file="${1}"
    type=$(fileType "${file}")

    if [ "${type}" == "MS-DOS executable" ]; then
        execute "executeFile" "dosbox \"${file}\" -forcescaler normal2x -exit -fullscreen"
    else
        execute "executeFile" "wine \"${file}\""
    fi
}


fileMime () {
    file="${1}"

    attributes=$(file --brief --mime "${file}")
    IFS=";" read -r -a attributes <<< "${attributes}"
    echo "${attributes[0]}"
}


fileType () {
    file="${1}"

    attributes=$(file --brief "${file}")
    IFS="," read -r -a attributes <<< "${attributes}"
    echo "${attributes[0]}"
}


changeToThisProgramDir
mainFunction "${@}"
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.