Что такое исходная функция оболочки?

#bash #nvm

#bash #nvm

Вопрос:

В nvm README.markdown говорится

Пожалуйста, обратите внимание, что which nvm это не будет работать, поскольку nvm это исходная функция оболочки, а не исполняемый двоичный файл.

Я обнаружил, что процесс установки nvm обновит .bashrc с

 [ -s "$NVM_DIR/nvm.sh" ] amp;amp; . "$NVM_DIR/nvm.sh"  # This loads nvm
  

Каким-то образом это делает nvm команду доступной для оболочки. Мой вопрос в том, что такое «исходная функция оболочки» и что именно выполняет команда nvm?

Комментарии:

1. Если вы хотите знать, что nvm делает названная функция, запустите type nvm , чтобы распечатать ее текст после того, как она была определена

2. Кстати, я предполагаю в своем ответе, что вы знаете, что такое функция оболочки в целом. В настоящее время вопрос не проясняет, является ли это предположение обоснованным.

3. В стороне: если bash-специфичен, nvm.sh название неверно и должно быть вместо nvm.bash ; хотя использование .sh в общем случае довольно неудачно в лучшие времена , это откровенно вредно, когда ложно подразумевает совместимость с другими оболочками POSIX — ksh, dash, ash и т.д. — Для скрипта, который, будучи вызванным не через shebang, не может указать свой собственный интерпретатор.

4. (На самом деле обычно для чего-либо, предназначенного для исходного кода, можно увидеть несколько версий рядом друг с другом с разными расширениями: a foo.ksh , a foo.bash , a foo.csh и т.д., С версиями, совместимыми с разными оболочками)

5. @danmaze, … в истории есть несколько промежуточных шагов, которые вы пропускаете. Bash действительно является воспроизведением названия оболочки Bourne, но он не совместим с оригинальной оболочкой Bourne 1970-х годов. Вместо этого он совместим со стандартом POSIX sh начала 1990-х годов, а также использует множество функций из ksh эпохи 1980-х годов, часто с совместимым синтаксисом. Есть код, который работает в Bourne 1970-х годов, который не работает в bash; код, который работает в POSIX sh 1991 года, который не работает в Bourne 1970-х годов, и множество функций в современном bash, которых у Bourne нет.

Ответ №1:

Это словосочетание неаккуратно. nvm это просто функция оболочки, определяемая путем поиска файла, в котором определена эта функция. Это никак качественно не меняет функцию: это была бы та же функция с тем же поведением, если бы вы ввели ее вручную, поэтому применение «sourced» в качестве модификатора немного вводит в заблуждение; было бы точнее сказать, что nvm.sh это исходный скрипт, который определяет функцию оболочки с именем nvm .


Что касается конкретного синтаксиса:

 . somefile
  

является ли более переносимым способом записи

 source somefile
  

…которая выполняет действия в somefile текущей оболочке, в отличие от отдельной оболочки, запускаемой как подпроцесс.

Таким образом, исходящий скрипт может модифицировать ваш текущий интерпретатор — устанавливать переменные, изменять его рабочий каталог и, да, определять псевдонимы и функции — способами, которые недоступны для выполнения внешней программы.


Для пояснения: если вы запустили bash somefile , то любые функции, определенные в somefile , существуют только в течение срока действия этой конкретной копии bash — когда она завершится и вернет вас к вашему приглашению, функции, определенные в somefile , больше не будут доступны. В отличие от этого, когда вы source somefile , поскольку содержимое somefile выполняется в вашем текущем экземпляре оболочки, это содержимое может сохраняться.

Комментарии:

1. Эффект от поиска скрипта почти идентичен эффекту от ввода каждой команды в нем в вашу интерактивную оболочку вручную. Таким образом, если вы можете определить функцию, введя ее в свою командную строку, вы можете определить эту функцию, используя скрипт, содержащий ее определение.

2. Имеет смысл, чувствую себя неловко, что мне это не пришло в голову : (

3. nvm.sh есть исходный скрипт, который определяет функцию оболочки с именем nvm : это имеет гораздо больше смысла. Если бы это было сформулировано таким образом более ясно и точно, это было бы легче понять.