Экспорт функции в оболочке


пожалуйста, скажите мне, как экспортировать функцию в родительской оболочке (bash, sh или ksh), чтобы функция была доступна для всех дочерних процессов, запущенных из родительского процесса?

6 78

6 ответов:

The export -f функция специфична для Bash:

родитель

#!/bin/bash
plus1 () { echo $(( + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

ребенок

#!/bin/bash
echo $(plus1 $(( * )) )

In sh, Это не можно экспортировать функцию, как отметил Чарльз Даффи.

если вы используете ksh или zsh:

вы можете использовать переменную среды FPATH, в котором вы можете разместить все свои функции.

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

Так, вы можете разместить все свои функции в месте в FPATH, и дочерние скрипты также смогут найти его.

можно использовать autoload команда в скриптах оболочки для загрузки необходимых функций:

autoload fun_a fun_b

в zsh,autoload требуется FPATH на работу. на ksh и его близких родственников, я считаю, что это просто вызывает функции, определенные в FPATH чтобы переопределить обычную команду в вашем Путь, как если бы они были определены непосредственно.

подробнее о FPATH и autoload:

если вы создаете подобласти с ( ) затем они наследуют снимок всех определений, параметров и переменных оболочки.

если вы выполняете их как программы, то вы можете поместить определения в .bashrc.

если вы пытаетесь подделать существующий скрипт для выполнения оболочки или замены команды PATH, то .bashrc будет работать в зависимости от деталей исполнения. Если нет, вы можете вместо этого выполнить сценарий-оболочку, который просто выполняет . или source файла include, который определяет функции, а затем делает то же самое с сценарием оболочки с командами, которые будут заменены.

скрипт может выглядеть примерно так:

script=
shift
. include.sh
. $script "$@"

идея заключается в том, что первый параметр-это имя реального скрипта, а остальные параметры-это args, тогда вместо этого запускается приведенный выше скрипт.

declare -x -f NAME

Подробнее

-f        restrict action or display to function names and definitions
-x        to make NAMEs export

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

func="$(typeset -f funcname)"
export func

чтобы импортировать функцию, переопределите ее из экспортированной строки:

# in subshell
eval "$func"