Pourquoi sh (pas bash) se plaint-il des fonctions définies dans mon .bashrc?

11

Je reçois celui-ci lorsque j'ouvre une session de terminal:

sh: erreur lors de l'importation de la définition de fonction pour `read.json '

sh: erreur lors de l'importation de la définition de fonction pour `ts-project '

sh n'aime pas ces fonctions car elles ressemblent à:

read.json(){
   ::
}

et

ts-project(){
   ::
}

la vraie question est - pourquoi shtoucher / interpréter ces fichiers? Je suis sur MacOS et j'ai déjà vu ça, c'est un tel mystère. Je pense que seul bash chargerait ces fichiers.

mise à jour : bash et sh n'ont rien d'extraordinaire. quand je tape bash dans le terminal, j'obtiens ceci:

alex$ bash
beginning to load .bashrc
finished loading .bashrc
bash-3.2$ 

quand je tape shdans le terminal, j'obtiens ceci:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
Alexander Mills
la source
1
Peut-être que / bin / sh est bash sur ce système?
Jeff Schaller
1
aucun d'eux ne s'approvisionne, j'ai découvert que c'était une mauvaise pratique à la dure. cependant, ~ / .profile recherche un fichier bash partagé, alors peut sh- être quelles sont les sources du fichier .profile?
Alexander Mills
1
Les informations sur la possession d'un fichier ~ / .profile qui source le fichier partagé me semblent importantes.
Jeff Schaller
3
Ce que je voulais dire par / bin / sh étant bash, c'est qu'il est possible qu'il soit lié de manière symbolique ou liée à bash. Bash émule alors sh, mais aussi des sources ~ / .profile. Je ne sais tout simplement pas comment les packages OSX sh et bash.
Jeff Schaller
3
Ils sont construits à partir de la même bashsource, l'un avec STRICT_POSIX, l'autre sans.
mosvy

Réponses:

20

Cette erreur se produit lorsque le bashmasquage comme un shell POSIX essaie d'importer ces fonctions à partir de l'environnement, pas lors de leur chargement en interprétant un fichier comme ~/.bashrcou tel. Exemple simplifié:

foo.bar(){ true; }; export -f foo.bar; bash --posix -c true
bash: error importing function definition for `foo.bar'

Je m'attendais à bashne pas charger les fonctions de l'environnement en mode posix, mais il le fait et ne se plaint que lorsque leurs noms contiennent des caractères amusants.

Notez que bashcela s'exécutera également en mode posix lorsque la variable d'environnement POSIXLY_CORRECTor POSIX_PEDANTICest définie, ou lorsqu'elle a été compilée avec --enable-strict-posix-default/ STRICT_POSIX.

Ce dernier semble être le cas pour /bin/shle MacOS (voir ici pour PRODUCT_NAME = sh), où j'attends cette erreur de déclencher également lors de l' utilisation des fonctions de bibliothèque comme popen(3)ou system(3).

mosvy
la source
3
La solution: n'exportez pas de fonctions dans l'environnement. C'est l'anti-fonctionnalité bash qui a conduit (ou plutôt était tout simplement) à Shellshock et elle aurait dû être supprimée, mais ce n'est pas parce que les gens l'utilisent bêtement. N'en fais pas partie.
R .. GitHub ARRÊTEZ D'AIDER LA GLACE
Le fait que bash importe des fonctions même lorsqu'il est appelé as shest ce qui a rendu la vulnérabilité shellshock / bashdoor bien pire.
Stéphane Chazelas
Voir aussi SHELLOPTS=posixet -o posixpour d'autres façons d'activer le mode posix.
Stéphane Chazelas
Notez également que set -a/ set -o allexportoblige également bash à exporter toutes les fonctions (et s'il est invoqué comme sh, provoque POSIXLY_CORRECTsa définition et son exportation!)
Stéphane Chazelas
( Les sh -acauses POSIXLY_CORRECTà fixer et exportés, set -aaprès shsans -aa démarré n'exporte pas POSIXLY_CORRECTparce qu'il a été mis en avant -aétait en vigueur).
Stéphane Chazelas
5

Pour répondre à la partie expliquant pourquoi read.jsonet ts-projectne sont pas des noms de fonction portables:

Selon POSIX, une définition de fonction doit être nommée par

un mot composé uniquement de traits de soulignement, de chiffres et d'alphabets du jeu de caractères portable. Le premier caractère d'un nom n'est pas un chiffre.

Également connu sous le nom d' identifiant , en langage C. Ou en regex:[_a-zA-Z][0-9_a-zA-Z]*

user2394284
la source
Mais POSIX n'interdit pas aux implémentations d'accepter d'autres noms pour les fonctions, donc bash n'a pas eu à imposer ces restrictions en mode POSIX. les noms de fonctions partagent le même espace de noms que les arguments de commande, il n'y a donc aucune raison d'accepter n'importe quoi (comme zsh/ rc/ fish...)
Stéphane Chazelas
@ StéphaneChazelas: Je sais, mais qu'est-ce que cela signifie d'être en mode POSIX, sinon "perdre toutes les extensions", comme "ne pas les accepter silencieusement"?
user2394284
@ user2394284 cela ne signifie certainement pas que bash, ou il n'importerait pas de fonctions de l'environnement en mode POSIX, ce qui n'est pas requis par la spécification POSIX ;-)
mosvy
@mosvy: Oui, il est évident que bash a échoué quelque part en cours de route - je dirais qu'il s'agit d'un simple shell POSIX, ce qui serait un bug.
user2394284
0

Donc, ce qui a causé cela, c'est que je cherche des scripts bash dans mon fichier ~ / .bashrc comme ceci:

for f in "$HOME/.oresoftware/bash/"*; do
   . "$f"
done;

donc je l'ai juste changé en:

for f in "$HOME/.oresoftware/bash/"*; do
  if [[ "$(basename "$0")" != 'sh' ]]; then
      # source only if not using sh
      . "$f"
  fi
done;

donc en théorie, s'il est appelé par, shil n'essaiera pas de source ces fichiers, mais pas sûr si cela fonctionne à 100% du temps.

Alexander Mills
la source