Dans mon .profile
, j'utilise le code suivant pour m'assurer que les alias et les fonctions liés à Bash ne proviennent que si le shell de connexion est en fait Bash :
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
Je suis actuellement en train de mettre mes fichiers de configuration shell, mes scripts et mes fonctions sous contrôle de version. J'ai également récemment commencé le processus de suppression des bashismes occasionnels des scripts shell qui ne bénéficient pas des fonctionnalités spécifiques à Bash, par exemple, le remplacement function funcname()
par funcname()
.
Pour mon référentiel de fichiers shell, j'ai configuré un hook de pré-validation qui exécute l' checkbashisms
utilitaire à partir du paquet devscripts de Debian sur chaque sh
fichier du référentiel pour m'assurer que je n'introduis pas par inadvertance la syntaxe spécifique à Bash. Cependant, cela soulève une erreur pour mon .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
Je me demandais s'il y avait un moyen de vérifier quel shell fonctionnait qui ne déclencherait pas d'avertissement checkbashisms
.
J'ai vérifié la liste des variables liées au shell répertoriées par POSIX dans l'espoir que l'une d'entre elles puisse afficher le shell actuel. J'ai également examiné les variables définies dans un shell Dash interactif mais, encore une fois, je n'ai pas réussi à trouver un candidat approprié.
Pour le moment, j'ai exclu .profile
d'être traité par checkbashisms
; c'est un petit fichier donc il n'est pas difficile de le vérifier manuellement. Cependant, après avoir étudié le problème, j'aimerais toujours savoir s'il existe une méthode compatible POSIX pour déterminer quel shell est en cours d'exécution (ou au moins une manière qui ne provoque pas checkbashisms
d'échec).
Contexte / clarification supplémentaire
L'une des raisons pour lesquelles je mets mes fichiers de configuration shell sous contrôle de version est de configurer régulièrement mon environnement sur tous les systèmes auxquels je me connecte actuellement: Cygwin, Ubuntu et CentOS (5 et 7, utilisant Active Directory pour l'utilisateur authentification). Je me connecte le plus souvent via X Windows / environnements de bureau et SSH pour les hôtes distants. Cependant, j'aimerais que ce soit à l'épreuve du temps et que je me fie le moins possible aux dépendances du système et à d'autres outils.
J'ai utilisé checkbashisms
comme un simple test de santé mentale automatisé pour la syntaxe de mes fichiers liés au shell. Ce n'est pas un outil parfait, par exemple, j'ai déjà appliqué un patch pour qu'il ne se plaint pas de l'utilisation de command -v
dans mes scripts. Pendant mes recherches, j'ai appris que le but réel du programme est d'assurer la conformité avec la politique Debian qui, si je comprends bien, est basée sur POSIX 2004 plutôt que 2008 (ou sa révision de 2013).
la source
.bash_profile
qui source à la fois.profile
et (conditionnellement).bashrc
.Réponses:
Votre
le code est entièrement conforme à POSIX et le meilleur moyen de vérifier que vous êtes en cours d'exécution
bash
. Bien sûr, la$BASH_VERSION
variable est spécifique à bash, mais c'est précisément pourquoi vous l'utilisez! Pour vérifier que vous courezbash
!Notez que
$BASH_VERSION
sera défini sibash
est appelé commebash
oush
. Une fois que vous avez affirmé que vous exécutezbash
, vous pouvez utiliser[ -o posix ]
comme indicateur que le shell a été appelésh
(bien que cette option soit également définie lorsque POSIXLY_CORRECT est dans l'environnement oubash
est appelé avec-o posix
, ou avec SHELLOPTS = posix dans l'environnement. Mais dans tous ces cas,bash
se comportera comme s'il était appelé commesh
).Une autre variable que vous pourriez utiliser à la place
$BASH_VERSION
et quicheckbashism
ne semble pas vous plaindre à moins que l'-x
option ne soit passée$BASH
. Cela est également spécifique àbash
celui que vous devriez également pouvoir utiliser pour déterminer si vous exécutezbash
ou non.Je dirais également que ce n'est pas vraiment une bonne utilisation de
checkbashisms
.checkbashisms
est un outil pour vous aider à écrire dessh
scripts portables (selon lash
spécification de la politique Debian, un surensemble de POSIX), il aide à identifier la syntaxe non standard introduite par les personnes écrivant des scripts sur des systèmes oùsh
est un lien symboliquebash
.A
.profile
est interprété par différents shells, dont beaucoup ne sont pas conformes à POSIX. En règle générale, vous n'utilisez passh
votre shell de connexion, mais des shells commezsh
,fish
oubash
avec des fonctionnalités interactives plus avancées.bash
etzsh
, lorsqu'ils ne sont pas appelés au fursh
et à mesure que leur fichier de session de profil respectif (.bash_profile
,.zprofile
) n'est pas conforme à POSIX (en particulierzsh
) mais qu'il est toujours lu.profile
.Ce n'est donc pas la syntaxe POSIX que vous recherchez,
.profile
mais une syntaxe compatible avec POSIX (poursh
),bash
etzsh
si vous devez utiliser ces shells (peut-être même Bourne car le shell Bourne lit également.profile
mais n'est pas communément trouvé sur les systèmes Linux) ).checkbashisms
vous aiderait certainement à trouver des bashismes, mais pourrait ne pas indiquer la syntaxe POSIX qui n'est pas compatible aveczsh
oubash
.Ici, si vous souhaitez utiliser du
bash
code spécifique (comme le contournement de cebash
bogue qui ne lit pas~/.bashrc
dans les shells de connexion interactifs), une meilleure approche serait de le~/.bash_profile
faire (avant ou après le sourcing~/.profile
où vous placez votre session commune initialisations).la source
checkbashisms
cause de la variable utilisée.$0
dans ce cas particulier?sh
et un autre shell appelé assh
.dash
ou un autre shell non-bash a été appelé incorrectementargv[0] == "bash"
, ce qui est tout à fait légal, si peu probable.Habituellement, on utilise
$0
à cette fin. Sur le site que vous avez lié, il se trouve:la source
$0
pour le nom d'un script shell, que j'ai nettoyé oublié qu'il peut également faire référence au shell actuel. Merci!exec
famille car ils permettent au programme appelant d'identifier le binaire à exécuter séparément de la chaîne à passer en argument. 0.Habituellement, la variable d'environnement SHELL vous indique le shell par défaut. Vous ne devriez pas avoir besoin de source manuellement le fichier .bashrc (pas vrai voir la mise à jour ci-dessous), bash devrait le faire automatiquement juste assurez-vous qu'il se trouve dans le répertoire $ HOME.
L'autre option est de faire quelque chose comme:
qui vous indiquera la commande (sans arguments, le = sans valeur n'affichera pas les en-têtes de colonne) du processus en cours. Exemple de sortie:
MISE À JOUR:
Je me suis trompé! :)
Le .bashrc n'est pas toujours fourni comme cela a été mentionné dans les commentaires ci-dessous et /programming/415403/whats-the-difference-between-bashrc-bash-profile-and-environment
Vous pouvez donc déplacer votre .bashrc vers .bash_profile et voir si cela fonctionne sans avoir à faire le test. Sinon, vous avez le test ci-dessus.
la source
.bashrc
n'est pas réellement fourni par un shell de connexion mais.profile
(s'il existe) ou l'.bash_profile
est.SHELL
n'est pas spécifié par POSIX et malheureusement, l'cmd
option de formatage ne l'est pas non plusps
.ps -o cmd= $$
devrait fonctionner à peu près partout, la$SHELL
variable est complètement hors de propos. Il s'agit du shell par défaut de l'utilisateur et n'a aucune incidence sur le shell en cours d'exécution ou sur le shell exécutant un script de shell.~/.profile
au démarrage en tant que shells de connexion. Ainsi, par exemple, vous$SHELL
pourriez l'êtrecsh
et vous courezbash -l
. Cela démarrera bash en tant que shell de connexion, il sera donc lu~/.profile
, mais votre$SHELL
pointera toujours verscsh
. De plus,.profile
peut provenir explicitement d'un autre script. Étant donné que l'OP vise une robustesse maximale, toutes sortes de cas doivent être pris en compte. Dans tous les cas,$SHELL
ne fournit aucune information utile sur le shell en cours d'exécution.SHELL
ne pas être spécifié par POSIX: pubs.opengroup.org/onlinepubs/9699919799/basedefs/…La question demande le shell de connexion de l'utilisateur ainsi que le shell actuel de manière apaisante
checkbashisms
. Si cela est censé être le shell sur lequel l'utilisateur s'est connecté, j'utiliserais celui de/etc/passwd
, par exemple,Les utilisateurs peuvent bien sûr démarrer un nouveau shell après s'être connecté. Bien sûr, si l'un est bash et l'autre pas, les tests des variables d'environnement de bash peuvent ne pas aider.
Certains voudront peut-être utiliser
getent
plutôt quepasswd
fichier (mais cela ne serait pas dans le cadre de la question).Sur la base du commentaire sur LDAP et de la suggestion de
logname
, ce formulaire alternatif pourrait être utilisé:En le testant, j'ai remarqué qu'il
logname
n'aime pas son entrée redirigée (j'ai donc laissé l'expression divisée). Une vérification rapidegetent
devrait fonctionner sur les plateformes mentionnées (bien que cela aurait dû être fourni dans la question d'origine):la source
$(logname)
).id
ou une variable modifiable par l'utilisateur est un choix différent.$(logname)
non$LOGNAME
. L'ID utilisateur et le shell de connexion sont tous deux dérivés du nom d'utilisateur utilisé lors de la connexion. Vous ne pouvez pas revenir de l'ID utilisateur au shell de connexion, sauf sur les systèmes où il n'y a qu'un seul nom d'utilisateur par ID utilisateur. Ou IOW, la clé primaire dans la base de données utilisateur est le nom d'utilisateur, pas l'uid.