Dlaczego sh (nie bash) narzeka na funkcje zdefiniowane w moim .bashrc?

11

Otrzymuję ten, gdy otwieram sesję terminalową:

sh: błąd podczas importowania definicji funkcji dla `read.json '

sh: błąd podczas importowania definicji funkcji dla `ts-project '

sh nie lubi tych funkcji, ponieważ wyglądają jak:

read.json(){
   ::
}

i

ts-project(){
   ::
}

prawdziwe pytanie brzmi - dlaczego shdotykanie / interpretowanie tych plików? Jestem na MacOS i widziałem to wcześniej, to taka tajemnica. Myślę, że tylko bash ładowałby te pliki.

aktualizacja : bash i sh nie są niczym niezwykłym. kiedy wpisuję bash w terminalu, otrzymuję to:

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

kiedy piszę shw terminalu, otrzymuję to:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
Alexander Mills
źródło
1
Być może / bin / sh to bash w tym systemie?
Jeff Schaller
1
żadne z nich się nie pozyskiwało, odkryłem, że ciężka praktyka była złą praktyką. jednak ~ / .profile pozyskuje udostępniony plik bash, więc może shjest to, z jakich źródeł plik .profile?
Alexander Mills
1
Ważna jest dla mnie informacja o posiadaniu pliku ~ / .profile, który pobiera udostępniony plik.
Jeff Schaller
3
Rozumiem przez to, że / bin / sh jest bashiem, to możliwe, że jest on symlinkowany lub hardlinkowany do basha. Bash następnie emuluje sh, ale także źródła ~ / .profile. Po prostu nie wiem, jak pakiety OSX sh i bash.
Jeff Schaller
3
Są zbudowane z tego samego bashźródła, z tego jednego STRICT_POSIXbez drugiego.
mosvy

Odpowiedzi:

20

Ten błąd występuje, gdy bashpodszywanie się pod powłokę POSIX próbuje zaimportować te funkcje ze środowiska, a nie podczas ładowania ich przez interpretację takiego ~/.bashrclub podobnego pliku . Uproszczony przykład:

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

Spodziewałem się, że bashnie będę ładować funkcji ze środowiska, gdy jest w trybie posix, ale tak jest i tylko narzekam, gdy ich nazwy zawierają śmieszne postacie.

Zauważ, że bashbędzie również działać w trybie posix kiedy POSIXLY_CORRECTlub POSIX_PEDANTICzmienna jest ustawiona, lub gdy został skompilowany z --enable-strict-posix-default/ STRICT_POSIX.

To ostatnie wydaje się być w przypadku /bin/shna MacOS (patrz tutaj dla PRODUCT_NAME = sh), gdzie spodziewam się ten błąd również wywołać przy użyciu funkcji bibliotecznych jak popen(3)i system(3).

mosvy
źródło
3
Poprawka: nie eksportuj funkcji w środowisku. Jest to anty-funkcja bash, która doprowadziła do (a raczej po prostu była) Shellshock i powinna była zostać usunięta, ale nie dlatego, że ludzie głupio z niej korzystają. Nie bądź jednym z nich.
R .. GitHub ZATRZYMAJ LÓD
Fakt, że import bash działa nawet po wywołaniu, shsprawia, że ​​luka w shellshock / bashdoor jest znacznie gorsza.
Stéphane Chazelas
Zobacz także SHELLOPTS=posixi -o posixinne sposoby włączenia trybu posiksowego.
Stéphane Chazelas
Zauważ też, że set -a/ set -o allexporttakże powoduje, że bash eksportuje wszystkie funkcje (a jeśli zostanie wywołany jako sh, powoduje POSIXLY_CORRECTustawienie i eksport!)
Stéphane Chazelas
( sh -apowoduje POSIXLY_CORRECTustawienie i wyeksportowanie; funkcja „ set -apo shbez” -anie eksportuje, POSIXLY_CORRECTponieważ została ustawiona wcześniej -a).
Stéphane Chazelas
5

Aby odpowiedzieć na część dotyczącą nazw funkcji read.jsoni ts-projectnie są przenośnymi funkcjami:

Zgodnie z POSIX definicja funkcji musi być nazwana przez

słowo składające się wyłącznie z podkreślników, cyfr i alfabetu z przenośnego zestawu znaków. Pierwszy znak imienia nie jest cyfrą.

Znany również jako identyfikator w języku C. Lub w wyrażeniu regularnym:[_a-zA-Z][0-9_a-zA-Z]*

użytkownik2394284
źródło
Ale POSIX nie zabrania implementacjom przyjmowania innych nazw funkcji, więc bash nie musiał narzucać tych ograniczeń w trybie POSIX. nazwy funkcji mają tę samą przestrzeń nazw co argumenty poleceń, więc nie ma powodu, aby akceptować tylko cokolwiek (jak zsh/ rc/ fish...)
Stéphane Chazelas
@ StéphaneChazelas: Wiem, ale co to znaczy być w trybie POSIX, jeśli nie „zrzuć wszystkie rozszerzenia”, jak w „nie przyjmuj ich po cichu”?
user2394284,
@ user2394284 z pewnością nie oznacza to bash, że w trybie POSIX nie importuje funkcji ze środowiska, co nie jest wymagane przez specyfikację POSIX ;-)
mosvy
@mosvy: Tak, oczywiste jest, że bash nie udał się gdzieś po drodze - powiedziałbym, że będąc zwykłą powłoką POSIX, co byłoby błędem.
user2394284,
0

Co spowodowało, że pozyskałem niektóre skrypty bash w moim pliku ~ / .bashrc w następujący sposób:

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

więc właśnie zmieniłem to na:

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

więc teoretycznie, jeśli zostanie wywołany do shtego czasu, nie będzie próbował źródła tych plików, ale nie jest pewien, czy to zadziała przez 100% czasu.

Alexander Mills
źródło