我可以从另一个 shell 脚本调用一个 shell 脚本的函数吗?

我有2个 shell 脚本。

第二个 shell 脚本包含以下函数 第二,嘘

func1
func2

Sh 将使用一些参数调用第二个 shell 脚本,并且 将使用特定于该函数的一些其他参数调用 function 1和 function 2。

这就是我所说的例子

第二,嘘

val1=`echo $1`
val2=`echo $2`


function func1 {


fun=`echo $1`
book=`echo $2`


}


function func2 {


fun2=`echo $1`
book2=`echo $2`




}

首先

second.sh cricket football


func1 love horror
func2 ball mystery

我怎样才能做到呢?

164054 次浏览

不能在另一个 shell 脚本中直接调用函数。

您可以将函数定义移动到一个单独的文件中,然后使用 .命令将它们加载到脚本中,如下所示:

. /path/to/functions.sh

这将解释 functions.sh,就好像此时它的内容实际上出现在您的文件中一样。这是实现 shell 函数共享库的常用机制。

像下面这样重构你的 second.sh脚本:

func1 {
fun="$1"
book="$2"
printf "func=%s,book=%s\n" "$fun" "$book"
}


func2 {
fun2="$1"
book2="$2"
printf "func2=%s,book2=%s\n" "$fun2" "$book2"
}

然后像这样从脚本 first.sh调用这些函数:

source ./second.sh
func1 love horror
func2 ball mystery

产出:

func=love,book=horror
func2=ball,book2=mystery
#vi function.sh


#!/bin/bash
f1() {
echo "Hello $name"
}


f2() {
echo "Enter your name: "
read name
f1
}
f2


#sh function.sh

这里函数 f2将调用函数 f1

问题是

目前公认的答案只有在重要条件下才有效。

返回文章页面

function func1 {
echo "Hello $1"
}

还有

返回文章页面

#!/bin/bash


source ./first.sh
func1 World

只有在从 first.sh所在的同一目录中执行 first.sh时,这种方法才有效。我。如果 shell 的当前工作路径是 /foo,则尝试运行命令

cd /foo
./bar/second.sh

打印错误:

/foo/bar/second.sh: line 4: func1: command not found

这是因为 source ./first.sh是相对于当前工作路径的,而不是脚本的路径。因此,一种解决方案可能是利用 subshell 并运行

(cd /foo/bar; ./second.sh)

更通用的解决方案

鉴于..。

返回文章页面

function func1 {
echo "Hello $1"
}

还有

返回文章页面

#!/bin/bash


source $(dirname "$0")/first.sh


func1 World

那么

cd /foo
./bar/second.sh

指纹

Hello World

它是如何工作的

  • $0返回执行脚本的相对或绝对路径
  • dirname返回 $0脚本所在目录的相对路径
  • dirname "$0"命令返回相对值 路径到执行脚本的目录,然后用作 source命令的参数
  • 在“ second. sh”中,/first.sh只是附加了导入的 shell 脚本的名称
  • source将指定文件的内容加载到当前 Shell

如果你定义

    #!/bin/bash
fun1(){
echo "Fun1 from file1 $1"
}
fun1 Hello
. file2
fun1 Hello
exit 0

在 file1中(chmod 750 file1) 及档案2

   fun1(){
echo "Fun1 from file2 $1"
}
fun2(){
echo "Fun1 from file1 $1"
}

然后运行./file2 Fun1来自文件1你好 Fun1来自文件2你好 令人惊讶! ! ! 您用 file2中的 fun1覆盖了 file1中的 fun1... ... 为了避免这样做,您必须这样做

declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello

它将以前的定义保存为 fun1,并使用以前的名称恢复它,删除不需要导入的名称。 每次从另一个文件导入函数时,您可能会记住两个方面:

  1. 你可以用相同的名称覆盖现有的名称(如果你想要的东西,你必须保存它们如上所述)
  2. 导入导入文件的所有内容(函数和全局变量也是) 小心! 这是危险的程序

second.sh

#!/bin/bash


function func1() {
fun="$1"
book="$2"
echo "$fun, $book\n"
}


function func2() {
fun2="$1"
book2="$2"
printf "$fun2, $book2\n"
}

first.sh

#!/bin/bash


source /absolute_path_to/second.sh
func1 love horror
func2 ball mystery

在使用它之前,你需要把这些事情记在心里

  • 关键字 source.(句点)是同一个命令。
  • 如果 FILENAME不是文件的完整路径,该命令将在 $PATH环境变量中指定的目录中搜索该文件。如果在 $PATH中找不到该文件,命令将在工作目录中查找该文件。
  • 如果给定任何 ARGUMENTS,它们将成为 FILENAME的位置参数。
  • 如果存在 FILENAME,则源命令 exit 代码为 0,否则,如果找不到该文件,它将返回 1

在这些点中需要关注的是 second,你实际上需要提供一个 ABSOLUTE_PATH到文件,如果你使用的是 #!/bin/bashRELATIVE_PATH就是不工作,如果是这样的话,那么我的朋友你只需要改变路径到 ABSOLUTE_FILE_PATH

我知道这是一个非常古老的职位。然而,我发现我不能源另一个文件,即使它是在同一个目录。

line 3: ./functions.bash: No such file or directory

然后我想起来我已经为这种情况准备好了一个方法,因为我从一个 ini 文件导入。因此,下面是我的解决方案,它允许我从任何地方(显然是源文件)运行程序,而无需硬编码路径。

app="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
source $app/functions.bash

我不能接受这个功劳,这是一段时间,我不记得我从哪里得到的线,否则我会信用他们,但这是我用来源文件。