我在我的文件中定义了一个bash
函数。~/.bashrc
这允许我在 shell 终端中使用它。但是,当我从脚本中调用它时,它似乎不存在。
如何定义bash
脚本也可以使用的函数?
答案1
~/.bash_profile
并且~/.bashrc
不被脚本读取,并且默认情况下不导出函数。为此,您可以export -f
像这样使用:
$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; }
$ export -f foo
$ ./script
works
export -f foo
也可以调用~/.bash_profile
此函数,以便在登录后可用于脚本。请注意,它export -f
不可携带。
更好的解决方案是使用. file
.这更加便携,并且不依赖于以特定方式设置的环境。
答案2
.bashrc
只能由交互式 shell 读取。 (实际上,这是一个过于简单化的问题:bash 在这方面很奇怪。无论.bashrc
是否是交互式登录 shell,Bash 都不会读取。而且即使是例外也有一个例外:如果 bash 的父进程是rshd
or sshd
,那么 bash 会读取.bashrc
,无论是否是交互式的。)
将函数定义放在已知位置的文件中,并使用.
(也拼写为source
)内置函数将该文件包含在脚本中。
$ cat ~/lib/bash/my_functions.bash
foo () {
…
$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar
如果需要,您可以遵循 ksh 的自动加载功能。将每个函数定义放在与该函数同名的文件中。列出变量中包含函数定义的目录FPATH
(以冒号分隔的目录列表)。这是 ksh 的粗略近似,autoload
它实际上立即加载该函数,而不是按需加载:
autoload () {
set -- "$(set +f; IFS=:;
for d in $FPATH; do
if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
done)"
[[ -n $1 ]] && . "$1"
}
答案3
你需要一个函数?如果没有,请考虑将逻辑提取到$PATH
.例如,我的~/.bashrc
:
# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'
~/bin
在 my 中$PATH
,所以我~/bin/wanip
使用以下内容创建:
#!/bin/bash
# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com
并运行chmod 0755 ~/bin/wanip
使其可执行。现在我可以wanip
从其他脚本执行。
我喜欢使用wanip
独立的 Bash 脚本。它提醒我,我希望这种逻辑普遍可用(除了在我当前的交互式 Bash 会话中)。该脚本很好地封装了逻辑和文档。