Pourquoi pas de shebang dans .bashrc / .bash_profile?

22

Enquête simple: je viens de réaliser que je n'ai jamais vu de shebang au dessus d'un .bashrcscript, ce qui m'amène à penser que le système utilise le shell par défaut pour le source lors de la connexion ( ${SHELL}). Je réfléchis aux raisons pour lesquelles c'est le cas, c'est-à-dire que c'est une mauvaise habitude d'utiliser autre chose que le shell par défaut pour exécuter le script de connexion.

amphibient
la source
1
Il y a une raison pour laquelle ça s'appelle bash rc ...
Ajedi32

Réponses:

28

.bashrcet ne .bash_profilesont PAS des scripts. Ce sont des fichiers de configuration qui proviennent chaque fois qu'ils bashsont exécutés de deux manières:

  • interactif
  • s'identifier

La section INVOCATION de la page de manuel bash est ce qui est pertinent.

Un shell de connexion est celui dont le premier caractère de l'argument zéro est un -, ou un a commencé avec l' --loginoption.

Un shell interactif est un shell démarré sans arguments sans option et sans l' -coption dont l'entrée standard et l'erreur sont toutes deux connectées à des terminaux (comme déterminé par isatty(3)), ou un démarré avec l' -i option. PS1 est défini et $-inclut iif bashest interactif, permettant un script shell ou un fichier de démarrage pour tester cet état.

Les paragraphes suivants décrivent comment bashexécute ses fichiers de démarrage. Si l'un des fichiers existe mais ne peut pas être lu, bash signale une erreur. Les tildes sont développés dans les noms de fichiers comme décrit ci-dessous sous Tilde Expansion dans la section EXPANSION .

Lorsque bash est invoqué en tant que shell de connexion interactif , ou en tant que shell non interactif avec l' --loginoption, il lit et exécute d'abord les commandes du fichier /etc/profile, si ce fichier existe. Après avoir lu ce fichier, il recherche ~/.bash_profile, ~/.bash_loginet ~/.profile, dans cet ordre, et lit et exécute les commandes de la première qui existe et est lisible. L' --noprofileoption peut être utilisée lorsque le shell est démarré pour inhiber ce comportement.

Lorsqu'un shell de connexion se ferme, bash lit et exécute les commandes du fichier ~/.bash_logout, s'il existe.

Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes de ~/.bashrc, si ce fichier existe. Cela peut être inhibé en utilisant l' --norcoption. L' --rcfile file option forcera bash à lire et à exécuter des commandes à partir du fichier au lieu de ~/.bashrc.

Vous pouvez contrôler leur chargement via les commutateurs de ligne de commande, --norcet --noprofile. Vous pouvez également remplacer l'emplacement d'où ils sont chargés à l'aide du --rcfilecommutateur.

Comme d'autres l'ont mentionné, vous pouvez imiter la façon dont ces fichiers sont chargés via l'utilisation de la source <file>commande ou l'utilisation de la . <file>commande.

Il est préférable de penser à cette fonctionnalité comme suit:

  1. bash démarre avec un environnement nu
  2. bash ouvre alors l'un de ces fichiers (selon la façon dont il a été invoqué comme interactif ou de connexion, puis ...
  3. ... ligne par ligne exécute chacune des commandes du fichier ...
  4. une fois terminé, donne le contrôle sous la forme d'une invite, en attente de saisie

Méthodes d'invocation

Ce sujet semble apparaître de temps en temps, voici donc un petit cheatsheet des différentes façons d'invoquer bashet de leur résultat. REMARQUE: pour vous aider, j'ai ajouté les messages "sourced $ HOME / .bashrc" et "sourced $ HOME / .bash_profile "dans leurs fichiers respectifs.

appels de base

  1. bash -i

    $ bash -i
    sourced /home/saml/.bashrc
  2. bash -l

    $ bash -l
    sourced /home/saml/.bashrc
    sourced /home/saml/.bash_profile
  3. bash -il -ou- bash -li

    $ bash -il
    sourced /home/saml/.bashrc
    sourced /home/saml/.bash_profile
  4. bash -c "..cmd .."

    $ bash -c 'echo hi'
    hi

    REMARQUE: notez que le -ccommutateur n'a source aucun des deux fichiers!

désactivation de la lecture des fichiers de configuration

  1. bash --norc

    $ bash --norc
    bash-4.1$ 
  2. bash --noprofile

    $ bash --noprofile
    sourced /home/saml/.bashrc
  3. bash --norc -i

    $ bash --norc -i
    bash-4.1$ 
  4. bash --norc -l

    $ bash --norc -l
    sourced /home/saml/.bashrc
    sourced /home/saml/.bash_profile
  5. bash --noprofile -i

    $ bash --noprofile -i
    sourced /home/saml/.bashrc
  6. bash --noprofile -l

    $ bash --noprofile -l
    bash-4.1$ 
  7. bash --norc -i -ou- bash --norc -l

    $ bash --norc -c 'echo hi'
    hi

Des moyens plus ésotériques d'appeler bash

  1. bash --rcfile $ HOME / .bashrc

    $ bash -rcfile ~/.bashrc 
    sourced /home/saml/.bashrc
  2. bash --norc --rcfile $ HOME / .bashrc

    $ bash --norc -rcfile ~/.bashrc 
    bash-4.1$ 

Ces échecs

  1. bash -i -rcfile ~ / .bashrc

    $ bash -i -rcfile ~/.bashrc 
    sourced /home/saml/.bashrc
    sourced /home/saml/.bash_profile
    bash: /home/saml/.bashrc: restricted: cannot specify `/' in command names
  2. bash -i -rcfile .bashrc

    $ bash -i -rcfile .bashrc
    sourced /home/saml/.bashrc
    sourced /home/saml/.bash_profile
    bash: .bashrc: command not found

Il y en a probablement plus, mais vous comprenez bien, j'espère ...

Quoi d'autre?

Enfin, si vous êtes tellement fasciné par ce sujet que vous souhaitez en lire / explorer davantage, je vous suggère fortement de jeter un œil au Guide du débutant Bash, en particulier la section: 1.2. Avantages du Bourne Again SHell . Les différentes sous-sections sous celle-ci, "1.2.2.1. Invocation" à "1.2.2.3.3. Comportement interactif du shell" expliquent les différences de bas niveau entre les différentes manières que vous pouvez invoquer bash.

slm
la source
@amphibient - désolé, il a un peu perdu le contrôle, j'espère que les gens apprécieront sa valeur et ne le puniront pas avec des votes négatifs. Avec cela ici, nous pouvons maintenant le référencer dans une autre réponse sur la route. 8-). J'envisageais de faire un tableau pour montrer ça mais ça aurait été fou 8-).
slm
Les avez-vous testés? J'ai essayé une fois de suivre ce que ma bash fait dans Squeeze et il ne s'est pas comporté comme le suggère le manuel
Bananguin
@Bananguin - chacune de ces commandes a été exécutée par moi et c'est la sortie qui a été produite sous les commandes. La seule "chose" potentielle avec ma configuration pourrait être que my .bash_profileinclut une ligne pour la source du fichier .bashrc. Mais je pense que c'est très typique des configurations.
slm
Cela pourrait être subjectif mais je ne dirais pas cela .bashrcet ce .bash_profilene sont pas des scripts . À mon humble avis, ce sont des scripts spécifiques qui sont implicitement fournis lors de l'initialisation de bash ou explicitement lorsque vous devez appliquer leurs modifications. Ils ne configurent pas seulement l'environnement bash (variables, fonctions, alias ...) comme prévu à partir des fichiers de configuration. Ils peuvent effectuer n'importe quelle action comme dans les scripts courants. Par exemple, ils peuvent démarrer diverses actions comme des tâches d'arrière-plan, écrire des enregistrements de journal, initialiser certains programmes, etc. Merci de toute façon pour le résumé détaillé!
pabouk
Cette réponse est encore meilleure que toutes les réponses ici stackoverflow.com/questions/415403/… !
Jacob Tomlinson
13

.bashrcles scripts ne sont exécutés que par bashlui-même. Ils ne sont pas autonomes et ne sont pas destinés à être execproférés par le système. (En fait, ils ne sont généralement pas marqués comme exécutables et, comme vous le dites, ils n'ont pas de ligne de shebang.)

Ces scripts sont censés être sourced, car ils font généralement des choses comme changer les variables d'environnement ( $PATH, par exemple), qui devraient persister après la fin du script. Il serait donc vraiment inutile d'essayer d'en exécuter un dans un sous-shell.

rici
la source
5

En plus des autres réponses, notez que si vous le souhaitez, rien ne vous interdit de mettre un shebang au début de ces fichiers de configuration.

Cela ne nuirait pas à leur approvisionnement car le shebang sera traité comme un commentaire normal, c'est-à-dire ignoré.

Cela pourrait aider les éditeurs qui utilisent la coloration syntaxique à comprendre quel langage de programmation est utilisé dans le fichier.

Notez que certains éditeurs aiment vimfournir des moyens alternatifs comme les modelines pour ces derniers. c'est-à-dire que vous pouvez toujours mettre des lignes de mode à la fin du ~/.bashrcet ~/.bash_profileainsi de suite:

...
<code in ~/.bashrc>
...
# vim: ft=sh :
jlliagre
la source
1
La réponse acceptée de @slm ci-dessus est excellente, mais c'est ce que je cherchais, en ce qui concerne l'ajout d'un shebang au début de ma .bash_profilesur une recommandation de ShellCheck.
jlucktay
1

Je lis ça n'importe où je ne sais pas exactement où mais c'est vrai

Le manuel de Bash est un peu déroutant dans ce domaine, mais Bash n'effectue pas ~ / .bash_profile comme un script shell. Il lit le fichier puis exécute les commandes qu'il contient (vous pouvez faire quelque chose de similaire en exécutant source ~ / .bash_profile).

Rahul Patil
la source