请告诉我如何在父shell(bash,sh或ksh)中导出函数,以便该函数可用于从父进程启动的所有子进程?
答案 0 :(得分:102)
export -f
功能特定于Bash:
父
#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21
子
#!/bin/bash
echo $(plus1 $(($1 * $2)) )
答案 1 :(得分:8)
在sh
中,导出某个功能 <{3}}。
答案 2 :(得分:3)
如果您使用的是ksh或zsh:
您可以使用环境变量FPATH
,您可以在其中放置所有功能。
如果在交互式解释器上设置了FPATH
,并且在当前shell环境或PATH
中找不到命令或函数,则会在其中列出的目录中搜索是否存在名为失踪后的命令。如果找到一个,它将在当前的shell环境中获得,并期望定义该函数。
因此,您可以将所有功能放在FPATH
中的某个位置,子脚本也可以找到它。
您可以在shell脚本中使用autoload
命令来加载所需的功能:
autoload fun_a fun_b
在zsh中,autoload
需要FPATH
才能正常工作。在ksh
及其近亲中,我认为它只会导致FPATH
中定义的函数1}}覆盖PATH中的常规命令,如果直接定义它们。
FPATH
和autoload
的一些详细信息:
答案 3 :(得分:1)
如果使用( )
创建子shell,则它们将继承所有定义,参数和shell变量的快照。
如果您像程序一样执行它们,那么您可以将定义放在.bashrc
。
如果您试图欺骗现有脚本执行包装器或替换PATH命令,那么.bashrc
将根据执行的细节而起作用。如果没有,您可以执行一个包装器脚本,该脚本只执行定义函数的包含文件的.
或source
,然后使用要替换的命令对shell脚本执行相同的操作。
包装器脚本可能类似于:
script=$1
shift
. include.sh
. $script "$@"
我们的想法是第一个参数是真实脚本的名称,剩下的参数是args,然后运行上面的脚本。
答案 4 :(得分:1)
declare -x -f NAME
更多信息
-f restrict action or display to function names and definitions -x to make NAMEs export
答案 5 :(得分:0)
功能本质上不可导出。但是你可以导出字符串,所以我在这里有一个小技巧:
func="$(typeset -f funcname)"
export func
要导入该函数,请从导出的字符串中重新定义它:
# in subshell
eval "$func"