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

avi*_*rup 72 unix shell

我有2个shell脚本.

第二个shell脚本包含以下函数 second.sh

func1 
func2
Run Code Online (Sandbox Code Playgroud)

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`


}
Run Code Online (Sandbox Code Playgroud)

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现它?

anu*_*ava 124

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}"
}
Run Code Online (Sandbox Code Playgroud)

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

source ./second.sh
func1 love horror
func2 ball mystery
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

fun=love,book=horror
fun2=ball,book2=mystery
Run Code Online (Sandbox Code Playgroud)

  • 为避免无意的副作用,请注意`source`命令实际上将运行作为参数传递的脚本. (10认同)
  • @dvlcube 如果你能建议一个替代方案会更好。 (3认同)
  • @Alpha2k 我不太确定是否有替代方案。这个想法是“小心你在源文件中放入的内容” (2认同)

lar*_*sks 34

您无法直接在另一个shell脚本中调用函数.

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

. /path/to/functions.sh
Run Code Online (Sandbox Code Playgroud)

这将解释functions.sh为此时内容实际存在于您的文件中.这是实现shell函数共享库的常用机制.

  • 好吧,我首先回答,因此从技术上讲,可接受的答案与此:)相同。同样,尽管在许多shell中`source`是`.`的别名,但并非总是如此。例如,Debian上提供`/ bin / sh`的`dash`软件包没有`source`命令。 (5认同)
  • 这与接受的答案不一样吗,因为 `.` 是 `source` 的别名吗? (3认同)

Pat*_*tas 13

问题

目前接受的答案仅在重要条件下有效.特定/foo/bar/first.sh

function func1 {  
   echo "Hello $1"
}
Run Code Online (Sandbox Code Playgroud)

/foo/bar/second.sh

#!/bin/bash

source ./first.sh
func1 World
Run Code Online (Sandbox Code Playgroud)

这仅适用first.sh于从所在的同一目录中执行的first.sh情况.IE浏览器.如果shell的当前工作路径是/foo,则尝试运行命令

cd /foo
./bar/second.sh
Run Code Online (Sandbox Code Playgroud)

打印错误:

/foo/bar/second.sh: line 4: func1: command not found
Run Code Online (Sandbox Code Playgroud)

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

(cd /foo/bar; ./second.sh)
Run Code Online (Sandbox Code Playgroud)

更通用的解决方案

特定 /foo/bar/first.sh

function func1 {  
   echo "Hello $1"
}
Run Code Online (Sandbox Code Playgroud)

/foo/bar/second.sh

#!/bin/bash

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

func1 World
Run Code Online (Sandbox Code Playgroud)

然后

cd /foo
./bar/second.sh
Run Code Online (Sandbox Code Playgroud)

版画

Hello World
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

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

  • `$(dirname "$0")` 解决了这个问题,即 `second.sh` 的名称中可能包含空格。但如果 **path** 包含空格,例如“/foo bar/second.sh”,则它不起作用。您应该使用 `source "$(dirname "$0")/first.sh"` 来代替。 (7认同)

Ayu*_*ush 6

second.sh

#!/bin/bash

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

function func2() {
   fun2="$1"
   book2="$2"
   printf "$fun2, $book2\n"
}
Run Code Online (Sandbox Code Playgroud)

first.sh

#!/bin/bash

source /absolute_path_to/second.sh
func1 love horror
func2 ball mystery
Run Code Online (Sandbox Code Playgroud)

使用前你需要牢记这些事情

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

在这些要点中,要重点关注的一点是second,如果您正在使用 ,您实际上需要ABSOLUTE_PATH向文件提供 a #!/bin/bashRELATIVE_PATH如果您是这种情况,则不起作用,那么我的朋友,您只需更改路径即可ABSOLUTE_FILE_PATH