Коли використовувати Bash і коли використовувати Perl / Python / Ruby? [зачинено]


78

Поки що ми робимо всі наші сценарії з Башем, але я починаю відчувати це трохи глупо. Хоча ми, звичайно, можемо робити все, що хочемо, з Bash (це досить потужно), я починаю замислюватися, чи не слід замість цього використовувати належну мову сценаріїв (у нашому випадку, швидше за все, Ruby).

Як ви вирішите, коли використовувати Perl / Python / Ruby over Bash для сценарію? Я не думаю, що сценарій init з Ruby має сенс, але як щодо трохи довшого сценарію, який додає облікові записи електронної пошти?


1
Якщо ви можете зробити це за допомогою будь-якого, чи це насправді має значення? Вибір цікавий лише в тому випадку, якщо отриманий сценарій представляє будь-які відмінності. Наприклад, час виконання може різко відрізнятися (це не проблема з обліковими записами електронної пошти).
Денніс

Відповіді:


44

Враховуючи проблему, з якою можуть впоратися обидва, вам захочеться використовувати ту, яка вам найбільше комфортна. Зрештою, є багато дрібних деталей, і лише досвід може навчити вас їх бачити.

Bash - це сценарій загальної мети, як і Python, Ruby, Perl, але кожен має різні переваги щодо решти. Perl досконалий у аналізі тексту, Python претендує на найелегантнішу групу, сценарії Bash чудово підходять до "обробці речей навколо", якщо ви знаєте, що я маю на увазі, а Рубі ... ну, Рубі трохи особливий способів.

Однак різниці між ними мають значення лише тоді, коли у вас з'явиться здоровий сценарій роботи під поясом. Я пропоную вам вибрати одну мову і підштовхнути її до меж, перш ніж перейти до наступної. Ви можете багато зробити в сценарії оболонки, більше, ніж визнає більшість людей. Будь-яка мова настільки ж складна, як ви хочете її вносити. Після того, як ви написали кілька речей у ньому, кожна мова вам "легка".

Знайомство з оболонкою швидко окупається, якщо ви живете в Linux, тому, можливо, ви хочете почати з цього. Якщо ви знайдете завдання, яке неможливо або недоцільно вирішити в сценарії оболонки, використовуйте щось інше.

Також майте на увазі, що вивчити сценарій оболонок дуже просто. Справжня сила цього полягає в інших програмах, таких як awk, sed, tr та ін.


У мене є досить досвід роботи з баш сценарієм, як і з Ruby, але я іноді все ще не знаю, що використовувати. Вибір на основі особистих уподобань у той момент часу здається дурним. Але ти маєш рацію, я запитаю себе, що я хочу зробити, і підберу найкращий інструмент для роботи.
futlib

Особисто я буду використовувати шкалу мов, які добре знаю, у порядку зростання складності та потужності, і використовую найпростішу, яка відповідатиме рахунку. Але насправді єдиний спосіб точно знати - це написання сценарію на всіх мовах та порівняння результатів. Це все більше почуття кишки, ніж певність. Через кілька років написання сценаріїв ви натрапите на більшість «типів проблем» і знаєте, яка мова вдало їх вирішила.
mkaito

Просто хотів додати, що за допомогою невеликих програм у пакеті GNU coreutils (як tr, сортування, uniq) та трубопроводу їх можна виконати багато завдань.
GMaster

58

TL; DR - використовуйте bash лише для встановлення кращої мови (якщо вона ще не доступна), інакше ви витрачаєте непоправний, дорогоцінний людський час. Якщо ви не можете зробити це в командному рядку вручну без помилок, не робіть сценарії з bash / shell.

Настав 2015 рік, тому я б врахував наступне:

  1. пам'ять накладні

    • Накладні витрати Ruby / Python на обсяг пам’яті в порівнянні з bash є невеликими (через спільні бібліотеки), хоча, мабуть, не можна підтримувати нетривіальний скрипт bash (тобто такий, який має> 100 рядків) - тому використання пам'яті не є фактором
  2. час запуску

    • Запуск Ruby / Python може бути трохи повільнішим, але, швидше за все, ви не збираєтеся виконувати багато повних процесів Ruby / Python у тісному циклі 100 разів на секунду (якщо у вас є такі потреби, bash / shell є все-таки занадто багато накладних витрат, і вам, ймовірно, доведеться перейти до C / C ++)
  3. виконання

    • майже всі типові стискання даних будуть швидшими в Ruby / Python - або принаймні порівнянні (або вам потрібен C / C ++ / Haskel / OCaml / як би там не було)
    • реальна продуктивність / вузьке місце у виконанні (або навіть продуктивність) майже ніколи не буде "відсутністю використання bash / shell" (навіть перемикання Ubuntu тире для запуску показує, наскільки насправді проблема bash - а зайнятий ящик, мабуть, єдиний випадок використання , тому що для написання та запуску коду є не що інше, як "bash" і "vi", і часто немає способу додати / завантажити або зберегти що-небудь інше)
    • запуск інших процесів для виконання роботи (наприклад, sed / awk / grep) насправді набагато повільніше, ніж виклик методу на живий об’єкт в пам'ять
  4. продуктивність

    • надто просто помилитися в Bash / shell в порівнянні з використанням "реальних" методів, параметрів, змінних та винятків у Ruby / Python
    • Agile - це мейнстрім, тоді як Bash не підтримує його (відсутність можливостей тестування одиниць, бібліотеки, OO, модульність, підключення, самоаналіз, реєстрація, метапрограмування; майже неможливо переробити рефактор, не порушивши щось)
    • тому занадто багато несумісностей з іншими оболонками, незначні змінні середовища можуть повністю порушити скрипт (а деякі важливі інструменти розробки, такі як Лялька, ігнорують лінії shebang і передають або переписують важливі змінні оболонки), тоді як Ruby / Python мають чітко визначені відносно плавні міграції шляхи навіть для основних змін версії
    • вивчення нової мови займає частину часу, який альтернативно витрачається на налагодження сценаріїв оболонок через специфічні для оболонки проблеми (зокрема - імена змінних, ніяких булевих винятків, жодних винятків тощо)
    • навіть сценарії запуску є міною ( особливо тому, що вони можуть вийти з ладу під час запуску системи ), а враховуючи останні недоліки безпеки з bash, вам може бути краще використовувати звичайний C (з хорошими бібліотеками) - так, C потребує компіляції, конфігурації тощо. , але навіть простий скрипт оболонки може потребувати сховища, то версії, а потім упаковки.
    • все, що є в наявності з sed / awk / grep, ймовірно, вже вбудоване в Ruby / Python - без того, щоб це було залежністю або "відмінностями" між версіями цих інструментів на платформах (так що, якщо це працює у вашому налаштуванні)
  5. безпека роботи
    • який сенс забезпечити роботу, яка вам не подобається? (якщо ви не любите витрачати всі ці години, важко налагоджуючи, але банальні помилки сценарію оболонки)

Я вважаю, що немає причини використовувати Bash / Shell, якщо у вас встановлений Ruby / Python.

І, ймовірно, для встановлення Ruby / Python в першу чергу навіть не потрібен скрипт bash (за винятком busbox, деякі системні інструменти залежать від наявності Python / Perl у будь-якому випадку).

І кожного разу, коли ви пишете сценарій оболонки, ви "практикуєте" робити саме це - замість того, щоб вчитися чомусь більш потужному / продуктивного.

Чому люди сьогодні використовують Bash? Бо це жахлива, важко розбита звичка. Сценарій рідко «закінчується назавжди» через перші кілька хвилин - як би сильно люди не думали так. Поряд з помилкою "це остання помилка в цьому сценарії".

Висновок: використовуйте bash / shell тільки тоді, коли ви абсолютно змушені (наприклад ~/.bashrc, зайнятий ящик), оскільки це майже ніколи не є "правильним інструментом для роботи".


28

Я використовую bash, коли моя основна увага приділяється обробці файлів. Це може включати переміщення, копіювання та перейменування файлів, а також використання файлів як вхідних даних для інших програм або зберігання результатів іншої програми у файлах. Я рідко пишу bash-код, який фактично вивчає вміст файлу або генерує висновок для запису у файл; Я залишаю це іншим програмам (які я можу написати в Perl або python), які запускаю через bash.

Я використовую Perl та python, коли моя основна увага приділяється читанню даних з файлів, певній обробці цих даних та запису виводу у файли. Якщо я опинився надто широко використовувати systemкоманду, зворотні тики або (в python) subprocessмодуль, я розглядаю можливість написання сценарію в bash. З іншого боку, я інколи починаю додавати стільки функціональних можливостей до скрипту bash, що врешті-решт має сенс переписати його в Perl / python, а не мати справу з обмеженою (порівнянням) підтримкою bash для змінних масштабів, функцій, структур даних тощо. .


2
Я використовував t0 також підручник на Bash, коли було потрібно читання файлів / генерування тексту, але після вивчення =~оператора, який підтримує, [[ ]]я любив мене трохи Bash для простого читання файлів
Freedom_Ben

16

Мені подобаються критерії, викладені в цій публікації в блозі .

  • Якщо немає ніяких аргументів для передачі, можливо, це сценарій оболонки.
  • Якщо для логіки управління не так багато (крім одного циклу або if / else), це, мабуть, сценарій оболонки.
  • Якщо завдання - автоматизація інструкцій командного рядка, це майже напевно сценарій оболонки.

8

Я вважаю цей аналіз Перла проти Баша корисним ...

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

Для зручності я копіюю резюме цього автора 1) коли bash - кращі результати та 2) коли perl - кращий висновок ...

Коли Баш краще ...

  • Невдача на роботу
  • Команди на виході
  • Обробка ліній вихідних завдань
  • Ось документи
  • Файлові еквіваленти
  • Порівняння часових міток файлів
  • Тильда розширення

Коли Perl краще ...

У більшості застосунків Perl все ще б'є лайно. Причини, які я можу віддати перевагу Perl, включають (але не обмежуються ними):

  • Це буде швидше. Головним чином, тому, що мені фактично не потрібно запускати нові процеси для багатьох речей, які я хочу зробити (базові назви та ім’я dirname є найбільш очевидними прикладами, але, як правило, вирізати, grep, сортувати та wc можна також усунути).
  • Обробка струн в баші в кращому випадку є рудиментарною, і вся річ у $ IFS є надзвичайно незграбною.
  • Умови в скриптах оболонки можуть бути непростими.
  • Цитування в скриптах оболонок може бути кошмаром.
  • Заява Баша залишає бажати кращого поза простими випадками (NPI).
  • Масиви в баші смокчуть. Хеши в баш (якщо припустити, що ваш баш достатньо новий, щоб їх взагалі було смоктати) ще важче.
  • Після того як обробка файлів або вихідних команд виходить за рамки простого випадку, який я перераховував вище, Perl починає дійсно курити.
  • CPAN.

Тож це не так, як незабаром Bash перейде на Perl. Але я все-таки вважаю, що через всі ці роки багато разів простий скрипт оболонки іноді може бути простішим, ніж простий сценарій Perl. Як я кажу, я вітаю всі спроби переконати мене в іншому. Але, знову ж таки, немає нічого поганого в тому, що у вашій панелі інструментів є кілька різних інструментів.


Цікаво, що в Ruby всі (?) Пунктів не застосовуються, оскільки у Ruby є at_exit (), realpath (), expand_path (), stat (), heredocs та винятки ( fail "error" unless system("foobar")).
Чезарій Багінський

5

На мій досвід, баш проти пітона є компромісом між часом розробки та гнучкістю. Рудиментарне рішення проблеми зазвичай може бути встановлено в скрипті bash швидше, ніж у сценарії python.

Python, як правило, змусить вас більше задуматися про структуру вашого рішення, ніж еквівалентний сценарій bash. Python має більш виражену силу, ніж баш сценарій, і тому він має тенденцію до масштабування та модифікації з часом краще. Він також залишається більш читабельним загалом.

Bash ближче до файлової системи і може бути чудовим для першого проекту рішення для проблем, які НЕ чітко визначені. З цієї причини, bash-скрипт може бути хорошим першим вибором для прототипування чогось із повним наміром переслати його на python, як тільки проблема буде краще зрозуміла.


4

Bash - оболонка Unix, вона включає мову сценаріїв. Це швидше командний процесор. ви керуєте тим, як ви запускаєте команди, ви фактично їх запускаєте.

Perl / Ruby / Python - мови загального призначення.

Коли вам потрібно сценарій оболонки, ви використовуєте Bash

Якщо ви хочете більш складне завдання або не пов'язане з оболонкою. Використовуйте Python тощо.

Я б ніколи фактично не порівнював ці мови. Python тощо є портативними. Ви можете запустити їх будь-де. Bash призначений лише для Unix.

У Python тощо є багато бібліотек для багаторазового використання, які вирішують мільйони завдань.

Це майже те саме, якщо ви запитаєте. "Коли використовувати Paint і коли використовувати Photoshop"

Для обробки електронних листів я б знову використовував Ruby, оскільки він має багато бібліотек для багаторазового використання.

Але найкращим способом було б поєднувати баш та рубін. Це було б правильно. Як і ви створюєте сценарій обробки електронної пошти в рубіні та bash-скрипті, він би викликав цей сценарій рубіну та запускав інші комунальні записи.

Отже, коли вам потрібен командний процесор, ви використовуєте bash. Ви запускаєте команди Unix та керуєте ними.

ОНОВЛЕННЯ через 7 років (березень 2019 р.)

Хоча основна частина моєї відповіді не змінилася, я хотів би зазначити це.

Bash - теж потужна сценарна мова. Для обробки тексту це може бути абсолютним законним вибором.

Прочитайте коментарі mkaito нижче. Всі вони абсолютно правдиві.


1
Підмножина сценаріїв Баша так само загальна, як і будь-яка сценарна мова загального призначення. Додайте загальні програми, такі як sed, у суміш, і ви отримаєте покриття на 90% усіх потреб у сценаріях.
mkaito

1
bash - це командний процесор, тому його повноваження полягає у виконанні інших команд і програм Unix у своїх скриптах. як ви згадали, і т. д. Він запитує, коли вибрати певну мову
bakytn

1
Оболонка справді - це прославлений запуск програми, але можливості сценарію набагато вищі за це. Я пропоную вам вивчити деякі справжні сценарії оболонок.
mkaito

Я можу спати на підлозі, але я вважаю за краще зробити це на ліжку. Мови не можна порівнювати, вони мають різні цілі.
bakytn

2
Що ж, якщо Баш - це підлога, щось на кшталт Haskell повинно бути нейлбордом :-)
mkaito

1

Сценарії оболонки, такі як bash, ksh, zsh, sh, і fish, є надзвичайно дивними, порівняно з мовами загального призначення високого рівня, такими як Ruby, Python або Perl. Хоча сценарій оболонки може починати своє життя як коротший файл, ніж еквівалентний сценарій загального призначення, сюрпризи призводять до безлічі оборонних коду обертання, наприклад, set -euo pipefailдля включення строгих режимів.

Для Exampmle більшість мов оболонок продовжують виконувати рядки в сценарії оболонки, навіть коли одна з команд не працює. Навпаки, мова загального призначення виходить з ладу відразу при першій помилці, а часто й навантаженні, що призводить до більш безпечної, передбачуваної поведінки в сценаріях навіть легкої складності.


1

Стаття дуже упереджена.

Я не знаходжу баш, щоб бути таким важким для налагодження. Python часто дуже жорсткий, тоді як bash дозволяє бути дуже креативним. Якщо ви хороший нестандартний мислитель, вам сподобається баш.

Я запускаю bash-скрипти на мільйонах послідовності ДНК, прочитаних у тисячах файлів, і це мені просто чудово. І всупереч тому, що всі кажуть, одні і ті ж версії скриптів на C ++ насправді не працюють так швидко (за кілька хвилин розділяють їх).

Я думаю, що bash, як і perl, - не найзручніший / легкий для читання. Це відлякує людей, оскільки більшість людей не є великими абстрактними мислителями. Але яскравіші, більш креативні програмісти, як правило, люблять його і часто використовують його. Якщо ви знаєте себе і знаєте, що маєте мозок, не лякайтеся баш. Якщо ви основний мислитель, можливо, дотримуйтесь чогось подібного до Python. Кожному своє.


0

З "Книги Лами"

  • Randal L. Schwartz, Tom Phoenix та Brian d foy, Learl Perl (Севастополь, Каліфорнія: O'Reilly, 2011), гол. 1.2 "Що означає Perl?" , §§ "Чому Ларрі [творець Perl] просто не використовував якусь іншу мову?", Стор. 5:

Perl намагається заповнити розрив між програмуванням низького рівня (наприклад, у C або C ++ або складання) та програмуванням високого рівня (наприклад, програмуванням на оболонку [наприклад, bash]). Програмування низького рівня, як правило, важко писати і негарно, але швидко і необмежено; важко перемогти швидкість добре написаної програми низького рівня на даній машині. І не так багато, що ти там не можеш зробити. Програмування на високому рівні, з іншого боку, має тенденцію бути повільним, жорстким, негарним та обмеженим; Є багато речей, які взагалі неможливо зробити з програмуванням оболонок або пакетів, якщо у вашій системі немає жодної команди, яка забезпечує необхідну функціональність. Perl легкий, майже необмежений, здебільшого швидкий і некрасивий.


0

Як правило, великі пальці використовуйте найпростішу мову, яка має досить хороші показники для вашого завдання під рукою. І його особливості лише вкрай вони справді корисні.

А щодо читабельності, Bash жахливий, якщо ваш стиль програмування жахливий. Якщо ви просто перекинете туди код, він стає незрозумілим.

Але якщо ви розділите код на найкоротші функції та назвете речі просто зрозумілою манерою, це найясніша мова, яку ви можете знайти. Тому що це дуже лаконічно.

Як зразок, це мій останній код у Bash. Зауважте, як це легко зрозуміти та набрати:

#! /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 "${@}"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.