Dans les scripts de configuration shell, comment puis-je tenir count des différences entre les coreutils sur BSD par rapport à GNU?

Jusqu'à ce mois-ci, les configurations de mon shell étaient assez simples (juste un .bashrc ou un .bash_profile avec quelques alias principalement), mais je l'ai refactorisé pour que je puisse avoir un comportement différent selon que j'utilise zsh ou bash. Ils fournissent d'abord un file de configuration de shell générique qui devrait fonctionner pour n'importe quoi, puis se spécialisent pour le shell spécifique utilisé (je symlink à cela).

J'ai été surpris aujourd'hui quand il a cessé de travailler. Il s'est avéré que pendant refactoring .bashrc , il y avait un alias

 alias ls='ls --color=always' 

c'était casser des choses pour ls dans bash sur Terminal dans OSX. Une fois que j'ai vu que BSD ls aime -G pour la couleur, mais GNU (ou tout ce qui était sur Ubuntu) aime – --color , il était clair que pas mal d'options diffèrent.

Ma question est la suivante: quelle est la meilleure façon de rendre count des différences dans les options et entre BSD et GNU coreutils? Dois-je tester une variable env dans des blocs pour voir quel OS est utilisé et appliquer un comportement correct? Ou est-il plus logique de créer des files de configuration distincts pour chaque operating system?

Bien que les réponses à ces questions puissent être subjectives, il semble que les différences entre BSD et GNU coreutils et les stratégies pour contourner ce problème afin de rendre une configuration générique utilisable sur la plupart * nix soient assez objectives.

Le seul moyen fiable d'écrire des scripts prenant en charge différents systèmes d'exploitation consiste à utiliser uniquement les fonctionnalités définies par POSIX.

Pour des choses comme vos configurations de shell personnelles, vous pouvez utiliser des hacks qui correspondent à votre cas d'utilisation spécifique. Quelque chose comme le suivant est laide, mais accomplira le but.

 if ls --version 2>/dev/null | grep -q 'coreutils'; then alias ls='ls --color=always' else alias ls='ls -G' fi 

Si l'on lit le code avec des instructions if pour effectuer un basculement sur le type de coreutils , la solution de programmation propre pour traiter différents types est d'utiliser le polymorphism . Puisqu'il s'agit de Bash, nous n'avons pas de polymorphism en soi, mais je me suis penché sur un moyen de le tromper. La seule condition est que votre file .bashrc , etc. soit organisé en fonctions.

Je crée d'abord un test pour le type de plate-forme coreutils :

 get_coreutils_platform() { local ls_version="$(ls --version 2>/dev/null)" if [[ "$ls_version" == *"GNU coreutils"* ]]; then echo gnu else echo bsd fi } 

Ensuite, nous pouvons expédier en fonction du type:

 platform=$(get_coreutils_platform) define_standard_aliases_$platform configure_shell_vars_$platform 

Voici l'implémentation de BSD :

 define_standard_aliases_bsd() { define_standard_aliases } configure_shell_vars_bsd() { configure_shell_vars export CLICOLOR=1 } 

(Notez que nous utilisons la variable CLICOLOR pour activer les colors au lieu d'utiliser un alias , ce qui semble un peu plus propre)

Et la mise en œuvre de GNU :

 define_standard_aliases_gnu() { define_standard_aliases alias ls='ls --color=auto' } configure_shell_vars_gnu() { configure_shell_vars } 

Pour l'exhaustivité, voici un exemple de mise en œuvre de la «base abstraite»:

 define_standard_aliases() { alias ll='ls -l' alias l.='ls -d .*' } configure_shell_vars() { export EDITOR=vim } 

Pas une réponse directe à votre question, mais j'ai des scripts wrapper pour gérer des choses comme ça plutôt que complication supplémentaire dans le .bashrc Par exemple voici mon script qui gère votre cas ici d'une manière multiplateforme:

http://www.pixelbeat.org/scripts/l