Warum beschwert sich sh (nicht bash) über Funktionen, die in meiner .bashrc definiert sind?


11

Ich erhalte diese, wenn ich eine Terminalsitzung öffne:

sh: Fehler beim Importieren der Funktionsdefinition für "read.json"

sh: Fehler beim Importieren der Funktionsdefinition für "ts-project"

sh mag diese Funktionen nicht, weil sie so aussehen:

read.json(){
   ::
}

und

ts-project(){
   ::
}

Die eigentliche Frage ist: Warum werden shdiese Dateien berührt / interpretiert? Ich bin auf MacOS und habe das schon einmal gesehen, es ist so ein Rätsel. Ich würde denken, nur Bash würde diese Dateien laden.

Update : Bash und Sh sind nichts Außergewöhnliches. Wenn ich bash in das Terminal eingebe, erhalte ich Folgendes:

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

Wenn ich shdas Terminal eingebe, erhalte ich Folgendes:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 

1
Vielleicht / bin / sh ist bash auf diesem System?
Jeff Schaller

1
Keiner von ihnen beschafft sich gegenseitig. Ich stellte fest, dass dies auf die harte Tour eine schlechte Praxis war. ~ / .profile bezieht jedoch eine gemeinsam genutzte Bash-Datei. Woher stammt also möglicherweise shdie .profile-Datei?
Alexander Mills

1
Die Informationen über eine ~ / .profile-Datei, aus der die freigegebene Datei stammt, scheinen mir wichtig zu sein.
Jeff Schaller

3
Was ich damit gemeint habe, dass / bin / sh bash ist, ist, dass es möglich ist, dass es mit bash verknüpft oder fest verbunden ist. Bash emuliert dann sh, gibt aber auch ~ / .profile an. Ich weiß nur nicht, wie OSX-Pakete sh und bash.
Jeff Schaller

3
Sie sind aus derselben bashQuelle gebaut, die eine mit STRICT_POSIX, die andere ohne.
Mosvy

Antworten:


20

Dieser Fehler tritt auf, wenn beim bashMaskieren als POSIX-Shell versucht wird, diese Funktionen aus der Umgebung zu importieren, nicht beim Laden, indem eine Datei wie diese interpretiert wird ~/.bashrc. Vereinfachtes Beispiel:

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

Ich hatte erwartet bash, im Posix-Modus keine Funktionen aus der Umgebung zu laden, aber das tut es und beschwert sich nur, wenn ihre Namen lustige Zeichen enthalten.

Beachten Sie, dass dies bashauch im Posix-Modus ausgeführt wird, wenn die Variable POSIXLY_CORRECToder POSIX_PEDANTICumgebungs festgelegt ist oder wenn sie mit --enable-strict-posix-default/ kompiliert wurde STRICT_POSIX.

Diese letztere scheint der Fall zu sein , /bin/shauf MacOS (Blick hier für PRODUCT_NAME = sh), wo ich auch Trigger diesen Fehler erwarten , wenn Bibliothek Funktionen wie popen(3)oder system(3).


3
Das Update: Exportieren Sie keine Funktionen in die Umgebung. Es ist das Bash-Anti-Feature, das zu Shellshock geführt hat (oder besser gesagt war), und es hätte entfernt werden sollen, aber nicht, weil die Leute es dumm benutzen. Sei nicht einer von ihnen.
R .. GitHub STOP HELPING ICE

Die Tatsache , dass bash Importe Funktionen selbst wenn sie als genannt shist , was die Shellshock / bashdoor Verwundbarkeit ein gemachter viel schlimmer.
Stéphane Chazelas

Siehe auch SHELLOPTS=posixund -o posixfür andere Möglichkeiten, den Posix-Modus zu aktivieren.
Stéphane Chazelas

Beachten Sie auch, dass set -a/ set -o allexportauch bash veranlasst, alle Funktionen zu exportieren (und wenn es als aufgerufen wird sh, bewirkt POSIXLY_CORRECT, dass es gesetzt und exportiert wird!)
Stéphane Chazelas

( sh -abewirkt POSIXLY_CORRECT, dass festgelegt und exportiert wird; set -anach dem Start von shwithout -awird nicht exportiert, POSIXLY_CORRECTda es vor dem -aInkrafttreten festgelegt wurde).
Stéphane Chazelas

5

Um den Teil zu beantworten, warum read.jsonund ts-projectsind keine tragbaren Funktionsnamen:

Nach POSIX, eine Funktionsdefinition muss benannt nach

Ein Wort, das ausschließlich aus Unterstrichen, Ziffern und Alphabeten aus dem tragbaren Zeichensatz besteht. Das erste Zeichen eines Namens ist keine Ziffer.

Im C-Jargon auch als Kennung bekannt . Oder in Regex:[_a-zA-Z][0-9_a-zA-Z]*


Aber POSIX nicht verbietet Implementierungen akzeptieren andere Namen für Funktionen, so bash nicht haben , um diese Beschränkungen auferlegen , wenn sie in POSIX - Modus. Funktionsnamen haben denselben Namespace wie Befehlsargumente, daher gibt es keinen Grund, irgendetwas zu akzeptieren (wie zsh/ rc/ fish...)
Stéphane Chazelas

@ StéphaneChazelas: Ich weiß, aber was bedeutet es, im POSIX-Modus zu sein, wenn nicht "alle Erweiterungen ablegen", wie in "Nicht stillschweigend akzeptieren"?
user2394284

@ user2394284 es bedeutet sicherlich nicht, dass in bash, oder es würde keine Funktionen aus der Umgebung importieren, während im POSIX-Modus, was von der POSIX-Spezifikation nicht erforderlich ist
;-)

@mosvy: Ja, es ist offensichtlich, dass Bash irgendwo auf dem Weg fehlgeschlagen ist - ich würde sagen, dass es sich um eine einfache POSIX-Shell handelt, was ein Fehler wäre.
user2394284

0

Was es verursacht hat, war, dass ich einige Bash-Skripte in meiner ~ / .bashrc-Datei wie folgt beschaffe:

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

Also habe ich es einfach geändert in:

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

Wenn es also bis dahin aufgerufen wird, shwird es theoretisch nicht versuchen, diese Dateien zu beschaffen, aber nicht sicher, ob dies 100% der Zeit funktioniert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.