La bash par défaut sur macOS est toujours bash v3:

$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.

Tout récemment, bash v5 a été publié. La divergence vient du fait que bash est sous licence GPL v3 depuis la version 4. Apple n’inclut pas les outils sous licence GPL v3 avec macOS.

Cependant, rien ne vous empêche de télécharger et d’installer la dernière version de bash.

Les nouvelles fonctionnalités comprennent, entre autres, des tableaux associés (c’est-à-dire des dictionnaires) et une meilleure configuration de l’autocomplétion.

Bien que vous pensiez que c’est un désir commun, la plupart des pages que j’ai trouvées vont simplement pointer vers Homebrew pour télécharger et installer une version plus récente de bash.

Le principal défi avec l’utilisation de brew est qu’il ne fonctionne pas à l’échelle dont les MacAdmins ont besoin. brew est conçu pour une installation mono-utilisateur, où l’utilisateur a des privilèges d’administrateur. Les flux de travail de brew ne sont pas à l’échelle des grands déploiements contrôlés avec un système de gestion.

Idéalement, il y aurait un installateur de paquets pour la dernière version de bash. Malheureusement, le projet bash n’en fournit pas.

Dans ce billet, je vais montrer comment vous pouvez installer la dernière version de bash sans brewet comment construire un paquet d’installation pour le déploiement.

Installation manuelle

Cela nécessite l’installation de Xcode ou des outils de ligne de commande du développeur.

D’abord, téléchargez la source de la dernière version de bash à partir de cette page. Au moment où nous écrivons ces lignes, la dernière version est bash-5.0 et le fichier que vous voulez est bash-5.0.tar.gz. Une fois téléchargé, vous pouvez développer l’archive dans le Finder en double-cliquant.

Mise à jour : j’ai un post avec des instructions mises à jour pour inclure les correctifs de bash 5.0.

Ouvrir une fenêtre de Terminal et changer de répertoire vers le répertoire bash-5.0 nouvellement développé. Ensuite, exécutez le script configure là.

$ cd ~/Downloads/bash-5.0$ ./configure

Le processus de configuration prendra un certain temps, il y aura beaucoup de messages montrant la progression.

Une fois que le processus configure est terminé. Vous pouvez construire bash avec la commande make.

$ make

Ceci va construire le binaire bash et les fichiers de support dans le répertoire courant. Ce n’est pas là où nous le voulons à la fin, mais c’est probablement une bonne idée de voir si le processus de construction fonctionne. Cela va (encore) prendre un certain temps. Il y aura quelques avertissements d’apparence étrange, mais vous pouvez les ignorer.

Lorsque make réussit, vous pouvez effectivement installer bash v5 avec

$ sudo make install

Ceci va construire et installer le binaire bash et les fichiers de support dans /usr/local/bin et /usr/local. sudo est nécessaire pour modifier /usr/local.

Si vous cherchiez simplement un moyen d’installer bash v5 sans brew, vous avez terminé!

Il y a plus d’informations utiles dans le reste du post, cependant, alors continuez à lire!

Comment le nouveau et l’ancien bash interagissent

Par défaut, le binaire bash v5 est appelé bash et sera installé dans /usr/local/bin. Le macOS par défaut PATH liste /usr/local/bin avant /bin où se trouve le binaire bash v3 par défaut, également appelé bash.

Cela signifie, que lorsqu’un utilisateur tape bash dans un shell, la version dans /usr/local/bin sera préférée à la bash v3 pré-installée.

Vous pouvez tester ce comportement dans Terminal. Comme le shell par défaut n’a pas encore été modifié depuis /bin/bash, le Terminal s’ouvre toujours sur bash v3. Vous pouvez le tester en montrant la variable d’environnement BASH_VERSION:

$ echo $BASH_VERSION3.2.57(1)-release

Mais lorsque vous exécutez ensuite bash, il invoquera /usr/local/bin/bash, donc il exécutera le nouveau bash v5. Il le montrera dans le prompt, mais vous pouvez également vérifier le BASH_VERSION.

$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release

Ce pourrait être la configuration que vous voulez, lorsque vous voulez utiliser bash v5 toujours. Il pourrait conduire à un comportement inattendu pour certains utilisateurs, cependant.

Une option pour éviter cette ambiguïté est de renommer le binaire dans /usr/local/bin en bash5. Mais alors d’autres outils tels que env (mentionné ci-dessous) ne trouveront plus le binaire.

  • Scripter OS X : D’où viennent les PATH

Note : le PATH dans d’autres contextes ne contiendra probablement pas /usr/local/bin et rendra les choses encore plus confuses.

bash v5 et Scripting

Les scripts utilisant bash, devraient avoir le chemin complet du binaire dans le shebang. De cette façon, l’auteur du script peut contrôler si un script est exécuté par le bash v3 (/bin/bash) par défaut ou le plus récent bash v5 (/usr/local/bin/bash ou /usr/local/bin/bash5).

Il est souvent recommandé d’utiliser la commande env dans le shebang:

#!/usr/bin/env bash

La commande env déterminera le chemin d’accès au binaire bash dans l’environnement actuel. (c’est-à-dire en utilisant le PATH actuel) Cela est utile lorsque le script doit s’exécuter dans divers environnements où l’emplacement du binaire bash est inconnu, en d’autres termes sur plusieurs plateformes Unix et Unix-like. Cependant, cela rend imprévisible la version réelle de bash qui interprétera le script.

Par exemple, supposons que vous avez bash v5 installé dans la configuration par défaut (comme /usr/local/bin/bash. Un script avec le shebang #!/usr/bin/env bash lancé dans l’environnement utilisateur (c’est-à-dire à partir du Terminal) utilisera le plus récent bash, car /usr/local/bin vient avant /bin dans l’ordre de recherche.

Lorsque vous lancez le même script dans un contexte différent, par exemple en tant que script d’installation, AppleScript ou système de gestion, /usr/local/bin ne fera probablement pas partie du PATH dans cet environnement. Alors le env shebang choisira /bin/bash (v3). Le script sera interprété et pourrait se comporter différemment.

Les administrateurs préfèrent la certitude dans leurs environnements gérés. Les administrateurs doivent connaître l’emplacement et les versions des binaires sur leurs systèmes. Pour les scripts de gestion, vous devez éviter env et utiliser le chemin complet approprié vers le binaire d’interprétation souhaité.

Les solutions pour résoudre l’ambiguïté sont

  • utiliser le chemin complet vers le binaire dans le shebang
  • gérer et mettre à jour la version personnalisée supplémentaire de bash avec un système de gestion
  • (facultatif) renommer le binaire bash plus récent en bash5 ou bash4 (cela vous permet également d’avoir bash v4 et bash v5 disponibles sur le même système)
  • Scripter OS X : Sur le Shebang
  • Scripter OS X : Définition du PATH dans les scripts

Changer le Shell par défaut d’un utilisateur en bash v5

Même si nous avons installé bash v5, le shell par défaut d’une nouvelle fenêtre de Terminal utilisera toujours le bash v3 intégré.

Le chemin du shell par défaut est stocké dans l’enregistrement de l’utilisateur. Vous pouvez modifier directement l’attribut UserShell avec dscl, dans les ‘Options avancées’ du volet de préférences ‘Utilisateurs & Groupes’, ou dans Directory Utility.

Il existe également une commande pour définir le shell par défaut :

$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell

La commande chsh (change shell) vérifiera les shells autorisés dans le fichier /etc/shells. Vous pouvez facilement ajouter une ligne avec /usr/local/bin/bash à ce fichier, et alors chsh fonctionnera bien.

$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: 

Note : si vous choisissez de renommer le binaire bash, vous devez utiliser le nom modifié dans /etc/shells et avec chsh.

N’oubliez pas que la simple exécution de chsh ne changera pas l’interpréteur de commandes dans la fenêtre actuelle du Terminal. Il est préférable de fermer l’ancienne fenêtre Terminal et d’en ouvrir une nouvelle pour obtenir le nouveau shell.

Packaging bash v5 for mass deployment

Bien que ces étapes pour installer et configurer bash v5 sur un seul Mac soient assez simples, elles ne fonctionneraient pas bien avec un système de gestion pour des centaines ou des milliers de Macs. Nous voulons envelopper tous les fichiers que make install crée dans une charge utile d’installateur de paquet.

L’option --help du script configure donne cette information utile:

Par défaut, make install' will install all the files in/usr/local/bin,/usr/local/libetc. You can specify an installation prefix other than/usr/localusing-prefix, for instance-prefix=$HOME`.

Lorsque nous exécutons le script configure avec l’option --prefix, il crée un dossier adapté comme charge utile pour un installateur de paquets. Nous pouvons alors utiliser pkgbuild pour construire pour créer un installateur pkg:

$ cd ~/Downloads/bash-5.0$ mkdir payload$ ./configure --prefix=/Users/armin/Downloads/bash-5.0/payload$ make install$ pkgbuild --root payload --install-location /usr/local --identifier org.gnu.bash --version 5.0 bash-5.0.pkgpkgbuild: Inferring bundle components from contents of payloadpkgbuild: Wrote package to bash-5.0.pkg

(Note : l’argument --prefix nécessite un chemin absolu.)

Automatiser la création du paquet

Donc, nous avons notre flux de travail pour construire un paquet d’installation pour distribuer et configurer bash v5 :

  • télécharger l’archive
  • extraire l’archive
  • exécuter configure avec l’argument --prefix
  • exécuter make install pour créer les fichiers dans un dossier payload
  • optionnel : renommer le binaire bash résultant en bash5 pour éviter les conflits
  • ajouter un script postinstall qui ajoute /usr/local/bin/bash à /etc/shells s’il n’est pas encore présent
  • construire l’installateur avec pkgbuild

Cela ressemble à un flux de travail mûr pour l’automatisation. Vous pouvez obtenir le script à partir de ce dépôt.

Vous pouvez passer un numéro de version bash différent (valide) comme argument au script, par exemple 4.4.18. (Je n’ai pas testé quelque chose de significativement plus ancien.) Le script ne détecte pas automatiquement la dernière version et utilise par défaut la version 5.0 lorsqu’aucun argument n’est fourni. Lorsqu’une mise à jour de bash v5 sera publiée, vous devrez modifier la ligne de version ou exécuter le script avec un argument.

Je n’ai pas (encore) trouvé comment détecter la dernière version à partir de la page web de téléchargement. Une autopkg recette devra attendre pour cela. (Si quelqu’un d’autre veut s’attaquer à cela, faites-le !)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.