Czy zaleca się używanie zsh zamiast skryptów bash? [Zamknięte]

25

Czy mogę założyć, że zshzainstalowano wystarczającą liczbę osób, aby uruchomić skrypty za pomocą

#!/usr/bin/env zsh

jak shebang?

A może sprawi to, że moje skrypty nie będą działać na zbyt wielu systemach?

Wyjaśnienie: Interesują mnie programy / skrypty, które użytkownik końcowy może chcieć uruchomić (np. W Ubuntu, Debian, SUSE, Arch i c.)

Profpatsch
źródło
4
Dziwne pytanie. Kto jest twoim celem? W niektórych kręgach (twórcy stron internetowych Ruby-on-Rails) zshmogą być popularne, podczas gdy w innych (sektor bankowy) jest to praktycznie niespotykane. Myślę, że powinieneś podać o wiele więcej informacji, jeśli potrzebujesz właściwej porady na ten temat.
rahmu
Ogólny świat użytkowników końcowych systemu Linux.
Profpatsch
2
WRT „ogólny świat użytkowników końcowych systemu Linux”, zsh jest niestandardowy. Nie jest instalowany domyślnie (na większości lub wszystkich dystrybucjach) ani wymagany przez cokolwiek, więc większość ludzi go nie będzie mieć.
goldilocks
3
Nie zshzainstalowałem na żadnym z moich systemów i nie zainstalowałbym go dla pojedynczego skryptu. Powinieneś nawet unikać bashism, mimo że bash jest zwykle dostępny.
frostschutz

Odpowiedzi:

29

W celu przenoszenia, nie. Chociaż zshmożna go skompilować na dowolnym systemie uniksowym lub podobnym do Unixa, a nawet Windowsie przynajmniej przez Cygwin, i jest pakowany dla większości uniksowych lajków typu Open Source i kilku komercyjnych, jednak na ogół nie jest zawarty w domyślnej instalacji.

bashz drugiej strony jest instalowany na systemach GNU (podobnie jak bashpowłoka projektu GNU), jak większość niewbudowanych systemów opartych na Linuksie, a czasami na systemach innych niż GNU, takich jak Apple OS / X. W komercyjnej stronie uniksową, Korn shell (wariant AT & T, choć bardziej ksh88jeden) jest normą, a zarówno bashi zshsą w opcjonalnych pakietów. Na BSD, preferowany interaktywna powłoka jest często tcshnatomiast shopiera się albo na Almquist skorupy lub pdkshi bashczy zshmuszą być zainstalowane jako opcjonalne pakiety, jak również.

zshjest instalowany domyślnie na Apple OS / X. Kiedyś /bin/shtam był. Domyślnie można go znaleźć w kilku dystrybucjach Linuksa, takich jak SysRescCD, Grml, Gobolinux i prawdopodobnie w innych, ale nie uważam żadnej z głównych.

Podobnie jak w przypadku bash, istnieje kwestia zainstalowanej wersji, aw konsekwencji dostępnych funkcji. Na przykład często zdarza się, że systemy znajdują się w bash3lub zsh3. Ponadto nie ma gwarancji, że skrypt, dla którego teraz piszesz, zsh5będzie działał, zsh6chociaż tak jak w przypadku, bashgdy starają się zachować kompatybilność wsteczną.

W przypadku skryptów mój pogląd jest następujący: użyj składni powłoki POSIX, ponieważ wszystkie Uniksy mają co najmniej jedną powłokę o nazwie sh(niekoniecznie w /bin), która jest w stanie zinterpretować tę składnię. Dzięki temu nie musisz się martwić o przenośność. A jeśli ta składnia nie jest wystarczająca dla twojej potrzeby, prawdopodobnie potrzebujesz więcej niż powłoki.

Następnie masz następujące opcje:

  • Perl, który jest wszechobecny (choć może być konieczne ograniczenie się do zestawu funkcji starych wersji i nie można zakładać domyślnie zainstalowanych modułów Perla)
  • Określ interpreter i jego wersję (python 2.6 lub nowszy, zsh 4 lub nowszy, bash 4.2 lub nowszy ...) jako zależność dla skryptu, budując pakiet dla każdego systemu docelowego, który określa zależność, lub określając ją w pliku README dostarczonym obok skryptu lub osadzonym jako komentarze u góry skryptu, lub dodając kilka wierszy w składni Bourne'a na początku skryptu, który sprawdza dostępność żądanego interpretera i wysyła bailer z wyraźnym błędem kiedy nie jest, tak jak ten skrypt wymaga Zsh 4.0 lub nowszej wersji .
  • Wyślij interpreter wraz ze skryptem (uważaj na konsekwencje związane z licencjonowaniem), co oznacza, że ​​potrzebujesz również jednego pakietu dla każdego docelowego systemu operacyjnego. Niektóre interpretatory ułatwiają to, oferując sposób na spakowanie skryptu i jego interpretera w jednym pliku wykonywalnym.
  • Napisz w skompilowanym języku. Ponownie, jeden pakiet na docelowy system.
Stéphane Chazelas
źródło
„zsh-man” mówi „nie”, jestem z ciebie dumny! ^^ Przenośność ftw! (ze wszystkimi zastrzeżeniami ...). +1.
Olivier Dulac
9

Nie, nie możesz. Gwarantowana dostępność to /bin/shprzede wszystkim oryginalna skorupa Bourne'a. Prawie wszystkie (zwróć uwagę na „prawie”!) Instalacje Linuksa będą miały bash, ale w systemach * BSD jest to rzadkie (przekonanie BSD ma poważne obawy dotyczące kodu GPL, takiego jak bash). Nie wiem, jaka jest standardowa powłoka na Macu, ale znowu są wątpliwości co do GPL. To samo dotyczy Solaris.

zsh jest niszową powłoką, nie ma jej w domyślnej instalacji Fedory (i nie sądzę, aby była domyślna dla większości głównych dystrybucji).

vonbrand
źródło
6
Z pewnością nie oryginalna powłoka Bourne Shell, ale raczej powłoka Posix w systemach zgodnych z Posix, która w wielu systemach to / bin / sh, ale niekoniecznie tak (w Solarisie <= wersja 10 jest to / usr / xpg4 / bin / sh)
Skrutinizer
Cóż, „domyślna” instalacja nie ma znaczenia. Liczy się to, czy w ogóle jest zainstalowane.
Profpatsch
@Profpatsch, wtedy domyślna instalacja jest bardzo istotna (przypuszczalnie dystrybucja określiła, co ludzie naprawdę używają).
vonbrand
2
@StephaneChazelas, „niszowy” jak w „niewielu użytkownikach go używa” / „niewiele instalacji go ma”. Może to być najlepsza skorupa od krojonego chleba, ale jeśli użyje go tylko niewielka część, nie można liczyć, że zostanie zainstalowany wszędzie.
vonbrand
1
Zwróć uwagę, że jeśli weźmiesz pod uwagę, że większość wdrożeń Linuksa jest obecnie osadzona (pomyśl Android, drukarki, routery, telewizory, żarówki ...), ogromna większość systemów opartych na Linuksie nie ma bash(chociaż te systemy prawdopodobnie nie są główne cel OP miał na myśli jego pytanie)
Stéphane Chazelas
2

Myślę, że to naprawdę zależy od tego, jakich dodatkowych funkcji zsh używasz i gdzie. Jeśli planujesz rozpowszechniać swój skrypt między różnymi użytkownikami i systemami, sugerowałbym użycie bash, a nawet sh .

W tym samym czasie, jeśli skrypt został zaprojektowany do wykonywania w całej organizacji i masz konwencję, aby mieć zsh na swoich komputerach (na przykład ten sam podstawowy AMI), a twoje zadanie ma wyraźne korzyści z rozszerzeń takich jak zaawansowane selektory plików lub inne rzeczy z http: / /www.rayninfo.co.uk/tips/zshtips.html Powiedziałbym, śmiało!

AB
źródło
1

Jak wspomniano, bashjest powszechnie dostępny w domyślnej instalacji dla wielu dystrybucji. Twój skrypt nie osiągnie największej liczby użytkowników, polegając na nim zsh.

Ważnym pytaniem, na które należy odpowiedzieć przed zaprojektowaniem skryptu, jest „ Dlaczego ma znaczenie, w której powłoce jest wykonywany skrypt?

Różne powłoki używają innej składni lub oferują dodatkowe funkcje powłoki, które mogą nie być obsługiwane przez inne powłoki. Aby napisać skrypt dla „ogólnego świata użytkowników końcowych systemu Linux”, określ, czy twój skrypt korzysta z funkcji składni lub powłoki zależnych od określonego środowiska powłoki.

Na przykład bashpowłoka obsługuje niektóre rozszerzenia, które nie są obsługiwane przez dashpowłokę Bourne'a lub cokolwiek innego, na co /bin/shwskazuje system użytkownika.

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

Spróbuj wykonać echo {1..10}w /bin/shporównaniu do, /bin/basha otrzymasz bardzo różne dane wyjściowe.

To samo dotyczy zsh, chociaż obsługuje większość bashskładni, oferuje dodatkowe rozszerzenie i składnię, które nie są obsługiwane przez bashpowłokę. Zobacz te tabele porównujące powłoki dla konkretnych przykładów.

Możesz poszerzyć swoją potencjalną bazę użytkowników bash, stosując się do skryptów, które działają po wywołaniu #!/bin/sh -u. Rodzi to jednak inne ważne pytanie: „ Co poświęca się w zamian za większą przenośność?

Ustal, czy różnice związane z kwestiami bezpieczeństwa, funkcjonalnością, wydajnością, czy cokolwiek innego, co Twoim zdaniem jest priorytetem dla twojego skryptu, byłoby warte poświęcenia. Skrypt ze znaną luką w zabezpieczeniach może nie być potrzebny tylko dlatego, że działa w większej liczbie środowisk.

Napisano tak wiele skryptów, bashdlatego obsługa tych skryptów jest używana jako kryterium przy porównywaniu powłok poleceń . Znacznie więcej osób będzie mogło uruchomić Twój skrypt, niż gdyby polegał on na zshjakiejkolwiek innej składni wyłącznej dla środowiska powłoki.

Pamiętaj też, że ostatecznie nie masz kontroli nad sposobem wykonywania skryptu przez użytkownika (przydatne również przy debugowaniu skryptów w różnych powłokach ):

Pamiętaj, że jeśli użyjesz powłoki do odczytania skryptu powłoki („sh nazwa skryptu”), zamiast wykonać go bezpośrednio („./scriptname”), powłoka potraktuje wszystkie komentarze na początku skryptu powłoki jako komentarze. W szczególności komentarz określający interpretera do użycia podczas wykonywania skryptu („#! / Bin / sh -u”) zostanie zignorowany, podobnie jak wszystkie opcje wymienione obok tego interpretera.

Najlepszym sposobem na zrobienie tego jest uczynienie skryptów przenośnymi, o ile nie ma wielkiego poświęcenia dla jego działania.

Możesz także zobaczyć konwencje kodowania Bash - Przepełnienie stosu .

iyrin
źródło
1
„Co jest poświęcane” ... spójrz na autoconf. Celowali w / bin / sh jak w „Original Bourne Shell”, ponieważ wszystkie powłoki obsługują ten (niewielki) zestaw funkcji. I bardzo za to cierpieli.
Jürgen A. Erhard
1

Jedyną rzeczą, którą możesz prawie zagwarantować, jest to, że istnieje /bin/sh. Może to być faktycznie statycznie połączona powłoka lub link do innej powłoki. Ta druga powłoka zwykle wykrywa, że ​​jest nazywana sh i będzie działać w trybie zgodności.

Zwróć uwagę na prawie w pierwszym zdaniu.

Każdy system uniksowy, na jakim kiedykolwiek pracowałem, miał to. Wiele z nich miało również zainstalowany bash (ale nie wszystkie . Na przykład bash nie jest domyślnie instalowany na niektórych BSD. Niektóre dystrybucje Linuksa są dostarczane z DASH , zamiast tego powłoką Debian Almquist.

Możesz zagwarantować instrukcje instalacji. Możesz dodać linię do pliku README, stwierdzającą, że wymaga zsh. Jeśli zbudujesz pakiet, możesz oznaczyć Zsh jako zależność. Możesz to sprawdzić za pomocą narzędzi autoconf / automake. Możesz sprawdzić, czy w skrypcie instalacyjnym znajduje się Zsh (zacznij od / bin / sh i spróbuj zlokalizować Zsh, jeśli zostanie znaleziony, kontynuuj. Jeśli nie wyświetli się błąd. Np. „Ostrzeżenie: ZSH nie jest zainstalowany. Przeczytaj plik instrukcji instalacji! „.)

Jestem pewien, że zapomniałem jeszcze kilku opcji. Ale kluczowe punkty to:

  • Nic nie możesz zagwarantować, dopóki tego nie sprawdzisz.
  • Masz prawie gwarancję, że / bin / sh jest obecny i że możesz to sprawdzić.
Hennes
źródło
POSIX wymaga / bin / sh, AFAIU. Podobnie jak wymaga kilku innych rozsądnych narzędzi. Sprawdź wymagania autokonfiskacji GNU.
vonbrand,
@vonbrand. POSIX nie wymaga /bin/sh. Wymaga to, shktóre we właściwym środowisku (które nie musi być środowiskiem domyślnym) zachowuje się tak, jak to określa. /bin/shmoże nie być powłoką POSIX. Na przykład w systemie Solaris 10 i wcześniejszych wersjach wciąż była to powłoka Bourne'a, a standard shbył w /usr/xpg4/bin.
Stéphane Chazelas