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

时间:2012-05-30 19:15:50

标签: shell unix

我有2个shell脚本。

第二个shell脚本包含以下功能 second.sh

func1 
func2

first.sh将使用一些参数调用第二个shell脚本  将使用特定于该函数的一些其他参数调用func1和func2。

以下是我所谈论的例子

second.sh

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

function func1 {

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

}

function func2 {

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


}

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery

我怎样才能实现它?

6 个答案:

答案 0 :(得分:108)

重构您的second.sh脚本,如下所示:

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

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

然后从脚本first.sh中调用这些函数,如下所示:

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

输出:

fun=love,book=horror
fun2=ball,book2=mystery

答案 1 :(得分:27)

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

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

. /path/to/functions.sh

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

答案 2 :(得分:11)

问题

目前接受的答案仅在重要条件下有效。鉴于...

<强> /foo/bar/first.sh

function func1 {  
   echo "Hello $1"
}

<强> /foo/bar/second.sh

#!/bin/bash

source ./first.sh
func1 World

仅当first.shfirst.sh所在的同一目录中执行时才有效。 IE浏览器。如果shell的当前工作路径为/foo,则尝试运行命令

cd /foo
./bar/second.sh

打印错误:

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

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

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

更通用的解决方案

...鉴于

<强> /foo/bar/first.sh

function func1 {  
   echo "Hello $1"
}

<强> /foo/bar/second.sh

#!/bin/bash

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

func1 World

然后

cd /foo
./bar/second.sh

打印

Hello World

如何运作

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

答案 3 :(得分:1)

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 存在,则源命令退出代码为 0,否则,如果找不到文件,则返回 1

其中需要重点关注的是 second,如果您使用 ABSOLUTE_PATH, #!/bin/bash,您实际上需要为文件提供 RELATIVE_PATH如果您是这种情况,则行不通,那么我的朋友,您只需要将路径更改为 ABSOLUTE_FILE_PATH

答案 4 :(得分:0)

如果你定义

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

在file1中(chmod 750 file1) 和file2

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

然后运行./file2你会得到的 来自file1的Fun1你好 来自file2的Fun1你好 惊喜!你用file1中的fun1覆盖file1中的fun1 ......为了不这样做,你必须

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

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

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

答案 5 :(得分:-5)

#vi function.sh

   #!/bin/bash
`enter code here`f1()

    {
echo "Hello $name"
}
f2(){
echo "Enter your name: "
read name
f1
}
f2
#sh function.sh
Here function 2 will call function 1