Почему sh (не bash) жалуется на функции, определенные в моем .bashrc?

11

Я получаю это, когда я открываю терминальную сессию:

sh: ошибка импорта определения функции для `read.json '

sh: ошибка импорта определения функции для `ts-project '

sh не любит эти функции, потому что они выглядят так:

read.json(){
   ::
}

и

ts-project(){
   ::
}

реальный вопрос - зачем shтрогать / интерпретировать эти файлы? Я на MacOS и видел это раньше, это такая загадка. Я думаю, что только bash будет загружать эти файлы.

Обновление : Bash и Sh ничего необычного. когда я набираю bash в терминал, я получаю это:

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

когда я печатаю shв терминале, я получаю это:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
Александр Миллс
источник
1
Возможно, / bin / sh - это bash в этой системе?
Джефф Шаллер
1
ни один из них не был источником друг для друга, я обнаружил, что это был плохой опыт. однако ~ / .profile получает общий файл bash, так что, может быть sh, из какого источника получен файл .profile?
Александр Миллс
1
Информация о наличии файла ~ / .profile, который является источником общего файла, кажется мне важной.
Джефф Шаллер
3
Я имею в виду, что / bin / sh означает bash: возможно, это символическая или жесткая ссылка на bash. Затем Bash эмулирует sh, а также sources ~ / .profile. Я просто не знаю, как OSX пакеты sh ​​и bash.
Джефф Шаллер
3
Они построены из одного bashисточника, один с STRICT_POSIXдругим, без него.
Мосви

Ответы:

20

Эта ошибка возникает, когда bashмаскарад под POSIX-оболочку пытается импортировать эти функции из среды, а не при загрузке их путем интерпретации файла ~/.bashrcили чего-то подобного. Упрощенный пример:

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

Я ожидал bashне загружать функции из окружения в режиме posix, но это происходит , и он жалуется только тогда, когда их имена содержат забавные символы.

Обратите внимание , что bashтакже будет работать в режиме Posix , когда POSIXLY_CORRECTили POSIX_PEDANTICпеременная среды, или когда он был скомпилирован с --enable-strict-posix-default/ STRICT_POSIX.

Последнее , как представляется, в случае /bin/shна MacOS (см здесь для PRODUCT_NAME = sh), где я ожидаю эту ошибку также триггер при использовании библиотечных функций , таких как popen(3)или system(3).

mosvy
источник
3
Исправление: не экспортируйте функции в среде. Это анти-функция bash, которая привела (или, скорее, просто была) к Shellshock, и ее следовало удалить, но не потому, что люди по глупости ее используют. Не будь одним из них.
R .. GitHub ОСТАНОВИТЬ ЛЬДА
Тот факт , что функции импорта Баш даже когда называют shэто то , что сделало SHELLSHOCK / bashdoor уязвимость намного хуже.
Стефан
Смотрите также SHELLOPTS=posixи -o posixдругие способы включения режима posix.
Стефан
Также обратите внимание, что set -a/ set -o allexportтакже заставляет bash экспортировать все функции (и, если вызывается как sh, вызывает POSIXLY_CORRECTустановку и экспорт!)
Стефан
( sh -aПричины POSIXLY_CORRECTдолжны быть установлены и на экспорт, set -aпосле того, как shне -aбыл запущен не экспортирует , POSIXLY_CORRECTпотому что он был установлен , прежде чем -aбыл в действительности).
Стефан
5

Чтобы ответить на часть о том, почему read.jsonи ts-projectне являются переносимыми именами функций:

Согласно стандарту POSIX, определение функции должны быть названы по

слово, состоящее исключительно из символов подчеркивания, цифр и алфавита из переносимого набора символов. Первый символ имени не является цифрой.

Также известный как идентификатор , в C lingo. Или в регулярном выражении:[_a-zA-Z][0-9_a-zA-Z]*

user2394284
источник
Но POSIX не запрещает реализациям принимать другие имена для функций, поэтому bash не нужно было навязывать эти ограничения в режиме POSIX. Имена функций имеют то же пространство имен, что и аргументы команды, поэтому нет причин принимать что- либо (например, zsh/ rc/ fish...)
Стефан
@ StéphaneChazelas: Я знаю, но что значит быть в режиме POSIX, если не «сбросить все расширения», как в «не принимать их молча»?
user2394284
@ user2394284 это, конечно, не означает, что в bash, или он не будет импортировать функции из среды в режиме POSIX, что не требуется спецификацией POSIX ;-)
mosvy
@mosvy: Да, очевидно, что bash где-то не получался - я бы сказал, что это простая оболочка POSIX, что было бы ошибкой.
user2394284
0

Так что это вызвало то, что я использую некоторые сценарии bash в моем файле ~ / .bashrc, например так:

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

поэтому я просто изменил его на:

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

так что в теории, если он вызывается к тому shвремени, он не будет пытаться получить эти файлы, но не уверен, будет ли это работать 100% времени.

Александр Миллс
источник