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


13

bash~/.bashrc文件中定义了一个函数。这使我可以在外壳端子中使用它。但是,当我从脚本中调用它时,它似乎不存在。

如何定义bash脚本也要使用的功能?


但是我的.bash_profile基本上读取.basrc文件,因此无论我使用登录还是非登录外壳,我都希望结果是相同的。
Onturenio

/bin/sh在shebang线上使用吗?
凯文

Answers:


9

~/.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。这更具可移植性,并且不依赖于以特定方式设置您的环境。


为什么不只声明像function myFunction { ... }in 这样的函数~/.bash_profile,您就可以开始了吗?
两栖游戏,

如果我正确理解了您的答案(关于使用该功能采购文件),这意味着我必须在每个脚本中显式地获取文件,这很烦人。这不仅比在每个脚本中复制粘贴函数本身复杂得多。我会保存一些行,当然,仅此而已。但是,该export解决方案似乎正常工作。谢谢。
Onturenio

@foampile,这恰好是我从脚本调用函数时所做的,并且不起作用。
Onturenio

1
@Onturenio:@ chris-down建议的第二种方法确实更好:1)当有人阅读脚本时,他们知道它需要某些脚本中的某些foo功能file2)file与确保调用外壳程序相比,您可以更好地控制脚本的内容foo在调用脚本之前没有变化。例如,您可以添加安全检查file以确保其不受干扰。(不容易,但可能)。(好吧,您也可以对已定义的foo函数进行检查...但是您得到的结果是^^我认为方法2更加干净。)3)file仅包含所需内容,而不仅仅是更多内容。
Olivier Dulac

8

.bashrc仅由交互式外壳读取。(实际上,这是一个过分的简化:bash在这方面很古怪。bash不管是不是.bashrc交互式登录外壳,都不会读取。甚至有一个例外:如果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"
}

+1用于自动加载,尽管我建议使用bash随附的工具。最新的一种支持延迟加载。
海星

0

需要功能吗?如果不是这样,请考虑在中将逻辑提取到单独的独立Bash脚本中$PATH。例如,我在~/.bashrc

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/bin在中$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会话中除外)。该脚本很好地封装了逻辑和文档。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.