Zkrátka:
-
Existuje několik shellů, které implementují nadmnožinu specifikace POSIX sh. Na různých systémech
/bin/sh
může být odkaz na ash, bash, pomlčka, ksh, zsh atd. (Vždy však bude kompatibilní s sh – nikdy csh nebo fish.) -
Pokud se budete držet
sh
pouze funkce, můžete (a pravděpodobně byste dokonce měli) použít#!/bin/sh
a skript by měl fungovat dobře, bez ohledu na to, o jaký shell se jedná. -
Pokud začnete používat funkce specifické pro bash (např. pole), měli byste konkrétně požádat o bash – protože i když
/bin/sh
již vyvolává bash na vaše systému, nemusí to být na všech ostatních systému a váš skript se tam nespustí. (Totéž samozřejmě platí pro zsh a ksh.) Shellcheck můžete použít k identifikaci bashismů. -
I když je skript pouze pro osobní použití, můžete si všimnout, že některé OS se mění
/bin/sh
při upgradu – např. na Debianu to býval bash, ale později byl nahrazen velmi minimálním pomlčkou. Skripty, které používaly bashismy, ale měly#!/bin/sh
náhle se zlomil.
Nicméně:
-
Dokonce
#!/bin/bash
není příliš správné. Na různých systémech může bash žít v/usr/bin
nebo/usr/pkg/bin
nebo/usr/local/bin
. -
Spolehlivější možností je
#!/usr/bin/env bash
, který používá $PATH. (Přestožeenv
ani samotný nástroj není přísně zaručen,/usr/bin/env
stále funguje na více systémech než/bin/bash
ano.)
Použijte shebang odpovídající shellu, který jste skutečně použili k vývoji a ladění skriptu. Tj. pokud je váš přihlašovací shell bash
a spustíte skript jako spustitelný v terminálu, použijte #!/bin/bash
. Nepředpokládejte to, protože jste nepoužili pole (nebo cokoli bash
funkce, které jste si vědomi), můžete si bezpečně vybrat, co se vám líbí. Mezi shelly je mnoho jemných rozdílů (echo
, funkce, smyčky, co si jen vzpomenete), které nelze bez řádného testování objevit.
Zvažte toto:pokud ponecháte #!/bin/bash
a vaši uživatelé jej nemají, zobrazí se jim jasná chybová zpráva, něco jako
Error: /bin/bash not found
Většina uživatelů to dokáže opravit do jedné minuty instalací příslušného balíčku. Na druhou stranu, pokud nahradíte shebang #!/bin/sh
a otestujte jej na systému, kde je /bin/sh
je symbolický odkaz na /bin/bash
, vaši uživatelé, kteří nemají bash
bude mít potíže. S největší pravděpodobností se jim zobrazí záhadná chybová zpráva jako:
Error in script.sh line 123: error parsing token xyz
To může trvat hodiny, než se to opraví, a nebude tušení, jaký shell měli použít.
Není mnoho důvodů, proč byste chtěli v shebangu použít jiný shell. Jedním z důvodů je, když shell, který jste použili, není rozšířený. Další možností je získat výkon s sh
což je na některých systémech výrazně rychlejší A váš skript bude překážkou výkonu. V takovém případě svůj skript důkladně otestujte s cílovým shellem a poté změňte shebang.
Vždy byste měli používat pouze #! /bin/sh
.
Ve skriptu shellu byste nikdy neměli používat rozšíření bash (nebo zsh, fish, nebo ...).
Měli byste vždy psát pouze skripty shellu, které fungují s jakýmkoli implementace jazyka shellu (včetně všech "utilitních" programů, které jsou součástí samotného shellu). V těchto dnech můžete pravděpodobně vezměte POSIX.1-2001 (ne -2008) jako autoritativní pro to, čeho jsou shell a nástroje schopny, ale uvědomte si, že jednoho dne můžete být vyzváni k portování skriptu na starší systém (např. Solaris nebo AIX), jehož shell a nástroje byly zmrazeny přibližně v roce 1992.
Co, vážně?!
Ano, vážně.
Tady je věc:Shell je strašný programovací jazyk. Jediná věc, kterou má, je /bin/sh
je jediný a jediný interpret skriptů, který každý Instalace Unixu je zaručena.
Tady je další věc:nějaká iterace základního interpretu Perl 5 (/usr/bin/perl
) je více pravděpodobně bude k dispozici na náhodně vybrané unixové instalaci než (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash
je. Další dobré skriptovací jazyky (Python, Ruby, node.js atd. – v porovnání s shellem do této kategorie zahrnu i PHP a Tcl) jsou také zhruba stejně dostupné jako bash a další rozšířené shelly.
Pokud tedy máte možnost napsat bash skript, máte možnost místo toho použít programovací jazyk, který není hrozný.
Nyní jednoduché shellové skripty, takové, které pouze spouštějí několik programů v sekvenci z úlohy cron nebo tak něco, není nic špatného na tom, když je necháte jako shell skripty. Ale jednoduché shell skripty nepotřebují pole ani funkce nebo [[
dokonce. A měli byste psát pouze složitě shell skripty, když nemáte jinou možnost. Autoconf skripty, například, jsou správně stále skripty shellu. Ale tyto skripty se musí spouštět každý inkarnace /bin/sh
který je relevantní pro konfigurovaný program. a to znamená, že nemohou používat žádná rozšíření. V dnešní době vás pravděpodobně nemusí zajímat staré proprietární Unixy, ale pravděpodobně byste měli starat se o aktuální open-source BSD, z nichž některé neinstalují bash
ve výchozím nastavení a vestavěná prostředí, která vám poskytují pouze minimální shell a busybox
.
Na závěr, ve chvíli, kdy zjistíte, že chcete funkce, která není k dispozici v přenosném jazyce shellu, což je známka toho, že skript se stal příliš komplikovaným na to, aby zůstal skriptem shellu. Místo toho jej přepište do lepšího jazyka.