Чи рекомендується використовувати zsh замість bash-скриптів? [зачинено]


25

Чи можу я припустити, що достатньо людей zshвстановлено для запуску скриптів із a

#!/usr/bin/env zsh

як shebang?

Або це зробить мої сценарії невиконаними на занадто багатьох системах?

Пояснення: мене цікавлять програми / скрипти, які може захотіти запустити кінцевий користувач (наприклад, на Ubuntu, Debian, SUSE, Arch та c.)


4
Дивне питання. Хто ваша ціль? У деяких колах (веб-розробники Ruby-on-Rails) zshможуть бути популярними, а в інших (банківський сектор) це практично не чутно. Я думаю, ви повинні дати набагато більше інформації, якщо вам потрібні відповідні поради щодо цього.
rahmu

Загальний світ кінцевого користувача Linux.
Profpatsch

2
WRT "загальний кінцевий користувач Linux", zsh є нестандартним. Він не встановлений за замовчуванням (у більшості чи всіх дистрибутивах) або вимагається будь-чим, тому більшість людей його не матимуть.
goldilocks

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

Відповіді:


29

Для портативності немає. Хоча zshйого можна компілювати в будь-якому Unix або Unix-подібному і навіть Windows, принаймні за допомогою Cygwin, і пакується для більшості подібних до Open Source Unix і декількох комерційних, як правило, це не включається до встановлення за замовчуванням.

bashз іншого боку, він встановлений на системах GNU (як bashі оболонка проекту GNU), як і більшість невбудованих систем на базі Linux, а іноді й на таких системах, як Apple OS / X. У комерційній стороні Unix оболонка Korn (варіант AT&T, хоча і більше той ksh88) є нормою і обох, bashі zshвони є у факультативних пакетах. На BSDs, краща інтерактивна оболонка часто в tcshтой час як shна основі яких Almquist оболонки або pdkshі bashабо zshнеобхідності , а також для установки в якості додаткових пакетів.

zshвстановлено за замовчуванням в Apple OS / X. Це навіть раніше було /bin/shтам. Його можна знайти за замовчуванням у кількох дистрибутивах Linux, таких як SysRescCD, Grml, Gobolinux та, ймовірно, інших, але я не думаю, що жоден з основних.

Як і для bash, виникає питання про встановлену версію, і як наслідок наявних функцій. Наприклад, не рідкість знайти системи з bash3або zsh3. Крім того, немає гарантії, що сценарій, для якого ви зараз пишете, zsh5буде працювати, zsh6хоча так, як bashвони намагаються підтримувати зворотну сумісність.

Для сценаріїв, на мій погляд, використовуйте синтаксис оболонки POSIX, оскільки всі Unices мають принаймні одну оболонку, яку називають sh(не обов'язково /bin), яка здатна інтерпретувати цей синтаксис. Тоді вам не доведеться так сильно турбуватися про портативність. І якщо цього синтаксису недостатньо для ваших потреб, то, ймовірно, вам потрібно більше ніж оболонка.

Тоді ваші варіанти:

  • Perl, який є всюдисущим (хоча знову ж таки, вам, можливо, доведеться обмежитися набором функцій старих версій, і ви не можете робити припущення щодо встановлених за замовчуванням модулів Perl)
  • Вкажіть інтерпретатора та його версію (python 2.6 або вище, zsh 4 або вище, bash 4.2 або вище ...), як залежність від вашого сценарію, або будуючи пакет для кожної цільової системи, який визначає залежність, або встановлюючи її у файлі README, що надсилається поряд із вашим сценарієм або вбудовується як коментарі у верхній частині вашого сценарію, або додаючи кілька рядків у синтаксис Bourne на початку вашого сценарію, який перевіряє наявність запитуваного інтерпретатора та видає з явною помилкою коли це не так, як цей скрипт потребує zsh 4.0 або вище .
  • Додайте інтерпретатора разом із вашим сценарієм (будьте обережні щодо наслідків ліцензування), що означає, що вам також потрібен один пакет для кожної цільової ОС. Деякі перекладачі полегшують це, пропонуючи спосіб упаковки сценарію та його перекладача в один виконуваний файл.
  • Напишіть це складеною мовою. Знову один пакет на цільову систему.

"zsh-man" кажучи "ні", я пишаюся тобою! ^^ Переносність ftw! (з усіма його застереженнями ...). +1.
Олів'є Дулак

9

Ні, ви не можете. Що гарантовано є /bin/sh, по суті, оригінальна оболонка Bourne. Практично всі (зверніть увагу на "майже"!) Інсталяції Linux матимуть удар, але в * BSD системах це рідко (переконання BSD має серйозні побоювання щодо GPL-коду, як bash). Я не знаю, що таке стандартна оболонка на Mac, але, знову ж таки, є сумніви щодо GPL. Те саме для Solaris.

zsh - це нішева оболонка, її немає в установці Fedora за замовчуванням (і я не вважаю, що це за замовчуванням для будь-якого великого дистрибутива).


6
Безумовно, не оригінал Bourne Shell, а скоріше оболонка Posix на сумісних системах Posix, яка для багатьох систем є / bin / sh, але це не обов'язково (для Solaris <= версія 10 це / usr / xpg4 / bin / sh)
Scrutinizer

Ну, встановлення за замовчуванням насправді не має значення. Важливо, якщо він взагалі встановлений.
Profpatsch

@Profpatsch, тоді встановлення за замовчуванням дуже актуально (імовірно, дистрибутив визначав, чим люди реально користуються).
vonbrand

2
@StephaneChazelas, "ніша", як у "мало хто користується нею" / "у кількох установок є". Це може бути найкраща оболонка, оскільки нарізаний хліб, але якщо його використовує лише невелика частка, ви не можете порахувати, що він буде встановлений скрізь.
фонбранд

1
Зверніть увагу , що якщо ви вважаєте , що більшість Linux розгортання вбудовується в даний час (думає , андроїд, принтери, маршрутизатори, телевізори, лампочки ...), переважна більшість систем на базі Linux ніяк НЕ має bash(хоча ці системи, ймовірно , не є основними цільова ОП мала на увазі його питання)
Стефан Шазелас

2

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

У той же час, якщо ваш сценарій призначений для виконання у вашій організації, і ви домовились мати zsh на своїх машинах (наприклад, той самий базовий AMI), і ваше завдання має чіткі переваги від розширень, як розширені селектори файлів або інші речі з http: / /www.rayninfo.co.uk/tips/zshtips.html Я б сказав, що йти вперед!


1

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

Важливе питання, на який потрібно відповісти перед розробкою сценарію, - це " Чому важливо, в якій оболонці виконується сценарій? "

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

Наприклад, bashоболонка підтримує певні розширення, які не підтримуються dash, оболонка Bourne або будь-яке інше, що /bin/shвказує на систему користувача.

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

Спробуйте виконати echo {1..10}в /bin/shпорівнянні з, /bin/bashі ви отримаєте дуже різний вихід.

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

Ви можете розширити свою потенційну базу користувачів за межами bash, дотримуючись сценаріїв, які працюють при виклику #!/bin/sh -u. Однак це породжує ще одне важливе запитання: " Що жертвують в обмін на більшу портативність? "

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

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

Також майте на увазі, що ви в кінцевому рахунку не маєте контролю над тим, як користувач виконує сценарій (також корисно для налагодження сценаріїв у різних оболонках ):

Пам’ятайте, що якщо ви використовуєте оболонку для читання скрипта оболонки ("sh scriptname"), замість того, щоб виконувати її безпосередньо ("./scriptname"), оболонка буде розглядати всі коментарі на початку сценарію оболонки як коментарі. Зокрема, коментар, який визначає інтерпретатора, який слід використовувати під час виконання сценарію ("#! / Bin / sh -u"), буде ігноруватися, як і всі параметри, перелічені поруч із цим перекладачем.

Отже, найкраще, що ви можете зробити для цього, - це зробити свої сценарії портативними, доки немає великих жертв у тому, як вони функціонують.

Можливо, ви також побачите конвенції кодування Bash - Переповнення стека .


1
"Що приносять у жертву" ... подивіться на autoconf. Вони націлили / bin / sh, як у "Оригінальній оболонці Борна", оскільки всі оболонки підтримують цей (крихітний) набір функцій. І вони за це сильно страждали.
Юрген А. Ерхард

1

Єдине, що можна майже гарантувати - це те, що є /bin/sh. Це може бути фактично статична пов'язана оболонка, або це може бути посилання на іншу оболонку. Ця інша оболонка зазвичай виявляє, що вона викликається sh і працюватиме в режимі сумісності.

Зауважте майже в першому реченні.

Кожна система Unix, як я коли-небудь працював, мала її. У багатьох з них також був встановлений bash (але не у всіх . Наприклад, bash він не встановлений за замовчуванням на деяких BSD. Деякі дистрибутивні пристрої Linux із DASH , замість цього оболонка Debian Almquist.

Що ви можете гарантувати - це ваші інструкції щодо встановлення. Ви можете додати рядок до файлу README, вказавши, що потрібно zsh. Якщо ви будуєте пакет, то ви можете позначити zsh як залежність. Ви можете перевірити це за допомогою інструментів autoconf / automake. Ви можете перевірити, чи знайдено zsh у скрипті встановлення (почніть з / bin / sh і спробуйте знайти zsh, якщо знайдене продовжувати. Якщо не відображається помилка. Наприклад, "Попередження: ZSH не встановлено. Будь ласка, прочитайте файл інструкцій із встановлення! ".)

Я впевнений, що забув ще кілька варіантів. Але ключові моменти:

  • Ви нічого не можете гарантувати, поки не перевірите.
  • Ви майже гарантовані, що / bin / sh присутній, і що ви можете зробити перевірку з цим.

POSIX вимагає / bin / sh, AFAIU. Начебто це вимагає декількох інших розумних утиліт. Перевірте реквізити автоматичної конфіскації GNU.
фонбранд

@vonbrand. POSIX не вимагає /bin/sh. Він вимагає того, shщо в правильному середовищі (яке не повинно бути середовищем за замовчуванням) поводиться так, як зазначено. /bin/shможе не бути оболонкою POSIX. Наприклад, на Solaris 10 і раніше, вона все ще була оболонкою Борна, і стандарт shбув в /usr/xpg4/bin.
Stéphane Chazelas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.