我可以从另一个shell脚本调用shell脚本的函数吗?
我有两个shell脚本 第二个shell脚本包含以下函数 第二,sh sh将使用一些参数和参数调用第二个shell脚本 将使用特定于该函数的其他一些参数调用func1和func2 这就是我所说的例子 第二,sh我可以从另一个shell脚本调用shell脚本的函数吗?,shell,unix,Shell,Unix,我有两个shell脚本 第二个shell脚本包含以下函数 第二,sh sh将使用一些参数和参数调用第二个shell脚本 将使用特定于该函数的其他一些参数调用func1和func2 这就是我所说的例子 第二,sh val1=`echo $1` val2=`echo $2` function func1 { fun=`echo $1` book=`echo $2` } function func2 { fun2=`echo $1` book2=`echo $2` } 第一,sh se
val1=`echo $1`
val2=`echo $2`
function func1 {
fun=`echo $1`
book=`echo $2`
}
function func2 {
fun2=`echo $1`
book2=`echo $2`
}
第一,sh
second.sh cricket football
func1 love horror
func2 ball mystery
如何实现它?您不能直接在另一个shell脚本中调用函数 您可以将函数定义移动到单独的文件中,然后使用
命令将其加载到脚本中,如下所示:
. /path/to/functions.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"
}
source ./second.sh
func1 love horror
func2 ball mystery
这将解释
functions.sh
,就好像此时文件中实际存在它的内容一样。这是实现shell函数共享库的常用机制。重构second.sh
脚本,如下所示:
. /path/to/functions.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"
}
source ./second.sh
func1 love horror
func2 ball mystery
然后首先从script调用这些函数。sh
如下:
. /path/to/functions.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"
}
source ./second.sh
func1 love horror
func2 ball mystery
输出:
func=love,book=horror
func2=ball,book2=mystery
function func1 {
echo "Hello $1"
}
#!/bin/bash
source ./first.sh
func1 World
function func1 {
echo "Hello $1"
}
#!/bin/bash
source $(dirname "$0")/first.sh
func1 World
这里函数f2
将调用函数f1
解决问题
目前公认的答案只有在重要条件下才有效。鉴于
/foo/bar/first.sh
:
func=love,book=horror
func2=ball,book2=mystery
function func1 {
echo "Hello $1"
}
#!/bin/bash
source ./first.sh
func1 World
function func1 {
echo "Hello $1"
}
#!/bin/bash
source $(dirname "$0")/first.sh
func1 World
及
/foo/bar/second.sh
:
func=love,book=horror
func2=ball,book2=mystery
function func1 {
echo "Hello $1"
}
#!/bin/bash
source ./first.sh
func1 World
function func1 {
echo "Hello $1"
}
#!/bin/bash
source $(dirname "$0")/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
是相对于当前工作路径的,而不是脚本的路径。因此,一种解决方案可能是利用子shell并运行
(cd /foo/bar; ./second.sh)
更通用的解决方案
鉴于
/foo/bar/first.sh
:
func=love,book=horror
func2=ball,book2=mystery
function func1 {
echo "Hello $1"
}
#!/bin/bash
source ./first.sh
func1 World
function func1 {
echo "Hello $1"
}
#!/bin/bash
source $(dirname "$0")/first.sh
func1 World
及
/foo/bar/second.sh
:
func=love,book=horror
func2=ball,book2=mystery
function func1 {
echo "Hello $1"
}
#!/bin/bash
source ./first.sh
func1 World
function func1 {
echo "Hello $1"
}
#!/bin/bash
source $(dirname "$0")/first.sh
func1 World
然后
印刷品
Hello World
工作原理
返回已执行脚本的相对或绝对路径$0
返回$0脚本所在目录的相对路径dirname
命令返回相对 执行脚本的目录路径,然后用作$(dirname“$0”)
命令的参数source
- 在“second.sh”中,
只是附加导入的shell脚本的名称/first.sh
将指定文件的内容加载到当前 壳source
#!/bin/bash
fun1(){
echo "Fun1 from file1 $1"
}
fun1 Hello
. file2
fun1 Hello
exit 0
在文件1中(chmod 750文件1)
和文件2
fun1(){
echo "Fun1 from file2 $1"
}
fun2(){
echo "Fun1 from file1 $1"
}
然后运行。/file2您将获得
Fun1来自file1你好
Fun1来自file2你好
惊喜您使用文件2中的fun1覆盖文件1中的fun1。。。为了不这样做,你必须
declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello
将以前的定义保存为fun1,并使用以前的名称将其恢复为删除不需要的导入定义。
每次从另一个文件导入函数时,您可能会记住两个方面:
second.sh
#/bin/bash
函数func1(){
fun=“$1”
book=“$2”
echo“$fun$book\n”
}
函数func2(){
fun2=“$1”
book2=“$2”
printf“$fun2,$book2\n”
}
first.sh
#/bin/bash
source/absolute\u path\u to/second.sh
爱情恐怖
足球之谜
在使用之前,你需要记住这些东西
- 关键字
和source
(一个句点)是同一个命令 - 如果
不是文件的完整路径,则该命令将在FILENAME
环境变量中指定的目录中搜索该文件。如果在$path
中找不到该文件,该命令将在当前目录中查找该文件$PATH
- 如果给出任何
,它们将成为参数
的位置参数文件名
- 如果
存在,则源命令退出代码为文件名
,否则,如果未找到该文件,将返回0
1
在这些点中,需要重点关注的点是第二点,如果您使用的是
,实际上需要为文件提供一个绝对路径
/bin/bash
,RELATIVE\u PATH
就是不起作用,如果你是这样的话,那么我的朋友,你只需要将路径更改为绝对文件\u PATH
复制-v=$(echo$1)
是完全多余的。只需写fun2=$1
。唯一的区别是,$()
(或backticks)将删除尾随的换行符。由于从shell脚本调用函数与从命令行调用函数没有什么不同,因此可以将此问题简化为“如何调用bash函数?”以避免意外的副作用,请注意,source
命令实际上会运行作为参数传递的脚本。@dvlcube如果您能建议一个替代方法,那就更好了。这个答案很清楚,也很好。重要的是,它描述了一些人可能遇到的问题,并提供了一个优雅的通用解决方案。@Alpha2k我不确定是否有替代方案。这句话的意思是“小心你把什么放进你的源文件中”这与公认的答案不一样吗,因为
是源代码的别名?好吧,我是先回答的,所以从技术上讲,公认的答案与此相同:)。另外,虽然在许多shell中,source
是
的别名,但情况并非总是如此。例如,Debian上提供/bin/sh
的dash
包没有source
命令。参考:太奇怪了,这条评论没有被提升为