2010-10-08 26 views
3

La question principale ici est: existe-t-il une méthode standard d'écriture des scripts shell UNIX qui s'exécuteront sur plusieurs plates-formes UNIX. Par exemple, nous avons de nombreux hôtes exécutant différentes versions d'UNIX (Solaris, Linux) et différentes versions, avec des configurations de système de fichiers légèrement différentes. Certains hôtes ont whoami dans/usr/local/gnu/bin /, et d'autres dans/usr/bin /.Meilleure/méthode conventionnelle de traiter avec PATH sur plusieurs environnements UNIX

Tous nos scripts semblent traiter de manière légèrement différente. Certains ont des déclarations de cas sur l'architecture:

case "`/script/that/determines/arch`" in 
    sunos-*) WHOAMI=`/usr/local/gnu/bin/whoami` ;; 
    *)  WHOAMI=`/usr/bin/whoami` ;; 
esac 

Avec cette approche, vous savez exactement ce que binaire est en cours d'exécution, mais il est assez lourd s'il y a beaucoup de commandes en cours d'exécution.

Certains définissent simplement le PATH (basé sur le script de l'arc ci-dessus) et appellent les commandes simplement par leur nom. C'est pratique, mais vous perdez le contrôle sur la commande que vous exécutez, par ex. si vous avez:

/bin/foo 
/bin/bar 
/other/bin/foo 
/other/bin/bar 

Vous ne seriez pas en mesure d'utiliser les deux /bin/foo et /other/bin/bar.

Une autre approche que je pourrais envisager serait d'avoir un répertoire local sur chaque hôte avec des liens symboliques vers chaque binaire qui serait nécessaire sur chaque hôte. .: par exemple

hôte Solaris:

/local-bin/whoami -> /usr/local/gnu/bin/whoami 
/local-bin/ps -> /usr/ucb/ps 

hôte Linux:

/local-bin/whoami -> /usr/bin/whoami 
/local-bin/ps -> /usr/ps 

Quelles autres approches gens utilisent? S'il vous plaît, ne dites pas simplement écrire le script en Python ... il y a des tâches où bash est le moyen le plus succinct et le plus pratique d'accomplir une tâche simple.

Répondre

4

Je délègue tout cela à mon profil .profile, qui a une série élaborée de fonctions internes pour essayer les répertoires susceptibles d'être ajoutés au PATH. Sauf sur OSX, ce que je crois fondamentalement impossible parce que Darwin/Fink/Ports veut contrôler chacun votre PATH, cette approche fonctionne assez bien. Si je me souciais de l'ambiguïté (plusieurs instances de foo dans différents répertoires de mon PATH), je modifierais les fonctions afin d'identifier toutes les commandes ambiguës et exiger une résolution manuelle. Mais pour mon environnement, cela n'a jamais été un problème. Ma principale préoccupation a été d'avoir un seul fichier .profile qui fonctionne sur Debian, Red Hat, Solaris, BSD, et ainsi de suite. L'approche 'essayer tous les répertoires qui pourraient fonctionner' fonctionne assez bien.

+0

Ce n'est pas idéal, mais je suppose que c'est probablement le meilleur de tous les maux. – SimonC

+0

Juste pour clarifier, nous exécutons beaucoup de commandes avec sudo, et dans notre environnement, cela ne provoque pas la lecture du fichier .profile de l'utilisateur emprunté. Je ne suis pas sûr que ce soit le fonctionnement de sudo ou si nous n'avons pas J'ai quelque chose d'installé correctement. – SimonC

0

Pour définir PATH aux répertoires compatibles POSIX, vous pouvez faire ce qui suit au début de vos scripts Bash:

unset PATH 
PATH="$(PATH=/bin:/usr/bin getconf PATH)" 
export PATH 

Si vous savez que vous pouvez utiliser Bash à travers les différents systèmes Unix, vous pouvez utiliser builtins shell à la place des commandes externes pour améliorer la portabilité. Exemple:

help type 
type -a type 

type -P ls # replaces: which ls 

Pour désactiver recherche alias/fonction pour des commandes telles que trouver, ls, ... Bash vous pouvez utiliser la commande interne.Exemple:

help command 

command ls -l 

Si vous voulez être sûr à 100% d'exécuter une commande spécifique située dans un répertoire spécifique, en utilisant le chemin exécutable complet semble la voie à suivre. Le premier match gagne dans la recherche PATH!