如何定义可供不同脚本使用的 Bash 函数

如何定义可供不同脚本使用的 Bash 函数

我在我的文件中定义了一个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 的父进程是rshdor 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 会话中)。该脚本很好地封装了逻辑和文档。

相关内容