108 votes

Quand dois-je utiliser #!/bin/bash et quand #!/bin/sh ?

Quand est-ce que #!/bin/bash plus approprié que #!/bin/sh dans un Shell Shell ?

56 votes

Lorsque vous utilisez bash plutôt qu'aux fonctions et à la syntaxe de l sh les fonctions et la syntaxe.

6 votes

3 votes

Si cela peut aider quelqu'un, j'ai remarqué que vim mettra en lumière bash -ismes si votre script possède la fonction #!/bin/sh shebang. Je le change seulement en bash si les choses deviennent suffisamment compliquées pour nécessiter des fonctions de base.

153voto

James Mertz Points 390

En bref :

  • Il existe plusieurs shells qui implémentent un sur-ensemble de la spécification POSIX sh . Sur différents systèmes, /bin/sh peut être un lien vers ash, bash, dash, ksh, zsh, &c. (Il sera cependant toujours compatible avec sh - jamais avec csh ou fish).

  • Tant que vous vous en tenez à sh uniquement, vous pouvez (et devriez même) utiliser les fonctions #!/bin/sh et le script devrait fonctionner correctement, quel que soit le script.

  • Si vous commencez à utiliser des fonctionnalités spécifiques à bash (par exemple, les tableaux), vous devez demander spécifiquement bash - parce que, même si /bin/sh invoque déjà bash sur votre système, il pourrait ne pas l'être sur ceux de tous les autres et votre script ne s'y exécutera pas. (La même chose s'applique bien sûr à zsh et ksh.) Vous pouvez utiliser shellcheck pour identifier les bashismes.

  • Même si le script n'est destiné qu'à un usage personnel, vous pouvez remarquer que certains systèmes d'exploitation modifient /bin/sh pendant les mises à jour - par exemple, sur Debian, c'était bash, mais il a été remplacé plus tard par un dash très minimal. scripts qui utilisaient des bashismes mais avaient des #!/bin/sh s'est soudainement brisé.

Cependant :

  • Même #!/bin/bash n'est pas très correct. Sur différents systèmes, bash pourrait vivre dans /usr/bin o /usr/pkg/bin o /usr/local/bin .

  • Une option plus fiable est #!/usr/bin/env bash qui utilise $PATH. (Bien que le env L'outil lui-même n'est pas strictement garanti non plus, /usr/bin/env fonctionne toujours sur plus de systèmes que /bin/bash fait.)

10 votes

Belle réponse. Vouliez-vous en faire un CW ?

3 votes

Juste une remarque si bash est exécuté à partir de /bin/sh il essaiera alors d'imiter sh (voir page de manuel ), mais il n'est pas certain que les fonctionnalités spécifiques à bash soient disponibles dans ce mode. env l'outil est un outil posix il devrait se trouver dans la plupart des distributions, mais je n'en suis pas certain car certaines ne respectent pas posix.

0 votes

@Brice : Est-ce que POSIX exige qu'il soit dans /usr/bin ?

18voto

Dmitry Grigoryev Points 8663

Utilisez le shebang correspondant au Shell que vous avez effectivement utilisé pour développer et déboguer votre Shell. C'est-à-dire que si votre Shell de connexion est bash et vous lancez votre script comme exécutable dans votre terminal, utilisez #!/bin/bash . Ne présumez pas que, puisque vous n'avez pas utilisé de tableaux (ou autre) bash que vous connaissez), vous pouvez choisir n'importe quel Shell que vous voulez. Il existe de nombreuses différences subtiles entre les shells ( echo (fonctions, boucles, etc.) qui ne peuvent être découverts sans un test approprié.

Considérez ceci : si vous laissez #!/bin/bash et que vos utilisateurs ne l'ont pas, ils verront un message d'erreur clair, quelque chose comme

Error: /bin/bash not found

La plupart des utilisateurs peuvent résoudre ce problème en moins d'une minute en installant le paquet approprié. D'un autre côté, si vous remplacez le shebang par #!/bin/sh et le tester sur un système où /bin/sh est un lien symbolique vers /bin/bash vos utilisateurs qui n'ont pas bash sera en difficulté. Ils verront probablement un message d'erreur cryptique du genre :

Error in script.sh line 123: error parsing token xyz

Cela peut prendre des heures à réparer, et il n'y aura aucun indice sur le Shell qu'ils auraient dû utiliser.

Il n'y a pas beaucoup de raisons pour lesquelles vous voudriez utiliser un Shell différent dans le shebang. Une raison est lorsque le Shell que vous avez utilisé n'est pas répandu. Une autre est de gagner en performance avec sh qui est nettement plus rapide sur certains systèmes, ET votre script sera un goulot d'étranglement en termes de performances. Dans ce cas, testez votre script minutieusement avec le script cible, puis changez le shebang.

0 votes

@Hastur Je ne comprends pas votre commentaire. Le shebang définira certainement quel Shell sera utilisé pour exécuter le Shell, pensez-vous que ma réponse implique le contraire ?

1 votes

Oubliez cela. J'ai mal compris la partie "pourquoi vous voudriez utiliser " ...

4voto

mckenzm Points 817

Généralement, si le temps est plus important que la fonctionnalité, vous utiliserez le plus rapide Shell. sh est souvent aliasé en dash et tend à être utilisé pour les tâches cron de root ou les opérations par lots où chaque (nano) seconde compte.

2 votes

Le chargement d'un interprète Shell supplémentaire à partir du système de fichiers peut annuler cet avantage, et tout ce qui concerne les nanosecondes (qui sont du même ordre de grandeur qu'un cycle machine réel) est le domaine des programmeurs en langage C et en langage d'assemblage.

0 votes

Les nanosecondes ne font une différence dans les tâches cron que si vous en avez des milliards, et cron ne sera de toute façon pas en mesure d'en gérer autant.

1 votes

Même si mckenzm a un peu exagéré, il est indéniable qu'il est préférable d'être plus performant ! Ne vous attardez pas sur la partie "nano". (Les nanosecondes ne comptent même pas en C, à moins qu'il ne s'agisse d'une boucle interne sur un système en temps réel ou autre).

4voto

zwol Points 1230

Vous ne devriez jamais utiliser #! /bin/sh .

Vous ne devez pas utiliser les extensions bash (ou zsh, ou fish, ou ...) dans un Shell Shell, jamais.

Vous ne devriez jamais écrire Shell Shell qui fonctionnent avec tout implémentation du langage Shell (y compris tous les programmes "utilitaires" qui vont de pair avec le Shell lui-même). De nos jours, vous pouvez probablement prendre POSIX.1-2001 ( no -2008) comme faisant autorité pour ce dont le Shell et les utilitaires sont capables, mais soyez conscient que vous pouvez un jour être appelé à porter votre Shell sur un système hérité (par exemple Solaris ou AIX) dont le Shell et les utilitaires ont été gelés vers 1992.

Quoi, sérieusement ? !

Oui, sérieusement.

Voilà le truc : Shell est un terrible le langage de programmation. La seule chose qu'il a en sa faveur est que /bin/sh est le seul et unique interprète de script qui chaque L'installation Unix est garantie.

Autre chose : une itération de l'interpréteur Perl 5 de base ( /usr/bin/perl ) est plus susceptibles d'être disponibles sur une installation Unix sélectionnée au hasard que (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash est. D'autres bons langages de script (Python, Ruby, node.js, etc. - j'inclurai même PHP et Tcl dans cette catégorie lors de la comparaison avec Shell) sont également à peu près aussi disponibles que bash et d'autres shells étendus.

Par conséquent, si vous avez la possibilité d'écrire un script bash, vous avez la possibilité d'utiliser un langage de programmation qui n'est pas terrible, à la place.

Maintenant, simple Shell Shell, le genre qui exécute juste quelques programmes dans une séquence à partir d'un travail cron ou autre, il n'y a rien de mal à les laisser comme Shell Shell. Mais les simples Shell Shell n'ont pas besoin de tableaux ou de fonctions ou de [[ même. Et vous devriez seulement écrire compliqué Shell Shell quand vous n'avez pas d'autre choix. Les Shell d'Autoconf, par exemple, sont toujours correctement Shell Shell. Mais ces Shell doivent s'exécuter sur chaque l'incarnation de /bin/sh qui est pertinent pour le programme en cours de configuration. et cela signifie qu'ils ne peuvent pas utiliser d'extensions. Vous n'avez probablement pas à vous soucier des vieux Unix propriétaires de nos jours, mais vous avez probablement devrait se soucier des BSDs open-source actuels, dont certains n'installent pas bash par défaut, et des environnements intégrés qui ne vous donnent qu'un Shell minimal et des busybox .

En conclusion, au moment où vous vous trouvez voulant une fonctionnalité qui n'est pas disponible dans le langage portable Shell, c'est un signe que le Shell est devenu trop compliqué pour rester un Shell Shell. Réécrivez-le dans un meilleur langage à la place.

4 votes

Désolé, mais c'est un peu idiot. Oui, si vous écrivez quelque chose qui sera i) distribué et ii) dans différents environnements, vous devriez vous en tenir à la version de base. sh . Cela ne signifie pas pour autant qu'il faille affirmer qu'il faut nunca utiliser d'autres coquilles. Il y a des milliers (probablement beaucoup plus) de scripts écrits chaque jour et la grande majorité d'entre eux ne s'exécutera jamais que sur une seule machine. Votre conseil a du sens pour le code de production, mais pas pour les tâches quotidiennes de "sysdaminy" pour lesquelles la plupart des scripts sont écrits. Si je sais que mon scripts ne sera jamais utilisé que par moi et sur une machine Linux, bash est parfait.

1 votes

@terdon Le fait est que si vous avez la possibilité d'écrire un script bash, alors vous avez également la possibilité d'écrire un script perl (ou autre), et ceci est toujours le meilleur choix.

0 votes

@terdon La réponse n'est sûrement pas idiote, votre commentaire au contraire est tout simplement naïf. Shell Shell est terriblement difficile à déboguer comparé à Perl et autres, pour lesquels on peut facilement utiliser des IDE complets avec débogage graphique et tout le reste. De plus, la plupart des Shell écrits chaque jour pour une petite chose à faire ont tendance à être modifiés et modifiés encore et encore, à grandir, à être copiés comme exemples à des collègues ou sur le net, etc. Il n'y a probablement aucune raison de prendre un tel risque.

3voto

Spencer Williams Points 161

Pour être encore plus bref, utilisez sh si la portabilité à travers la plupart des systèmes est la plus importante et bash si vous souhaitez utiliser certaines de ses fonctionnalités spécifiques, comme les tableaux, si la version de bash le supporte.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X