简介
这篇文章主要描述如何通过主脚本去调用其他脚本中的方法,调用的过程中可能出现哪些坑,如何避免。
目录
1. 主脚本调用其他脚本的方法
1.1. bash方法
1.2. source方法
2. 避坑技巧
2.1. 路径配置无效
2.2. source变量冲突
3. 总结
1. 主脚本调用其他脚本的方法
使用主脚本调用其他脚本通常使用2种方法:
- bash 脚本名
- source 脚本名
还有一种 . 脚本名 的方法与 source 脚本名 差不多,但偶尔会出现无法调用的问题,这里就不解释了。
1.1. bash方法
使用传统的 bash 方法就是在当前脚本中执行 bash 去调用另一个脚本。来看一下例子
【主脚本代码】
#!/bin/bash
echo "============= 我是主脚本, 准备去调用其他脚本 ============="bash ./scr.sh # 调用其他脚本echo "============= 我是主脚本, 其他脚本已执行完成 ============="
【另一个脚本代码】
#!/bin/bash
echo "我是其他脚本"
来执行主脚本,看一下结果:可以正常调用
这种方法虽然可以调用另一个脚本,但另一个脚本却无法共享主脚本的变量
【主脚本代码】
#!/bin/bash
var=10 # 定义一个变量
echo "我是主脚本, 变量var的值是: ${var}"bash ./scr.sh # 调用其他脚本
【另一个脚本代码】
#!/bin/bash
echo "我是其他脚本, 变量var的值是: ${var}"
主脚本中定义的变量无法作用到其他脚本中
虽然这里的变量无法作用到其他脚本,但可以通过传参的方式拿过去
【主脚本代码】
#!/bin/bash
var=10
echo "我是主脚本, 变量var的值是: ${var}"bash ./scr.sh "${var}" # 向另一个脚本传递参数
【另一个脚本代码】
#!/bin/bash
var="$1" # 接收一个位置参数
echo "我是其他脚本, 变量var的值是: ${var}"
结果如下:参数传递成功
注意:这种方法只适用于少量参数
1.2. source方法
source 与 bash 方法完全不同,bash 是直接去执行另一个脚本,而 source 是将另一个脚本的代码读取过来。还记得为什么配置环境变量到 ~/.bashrc 后,需要执行 source ~/.bashrc 才生效吗,就是为了将 ~/.bashrc 中的配置信息读取到本地才能生效,所以使用 source 执行其他脚本文件也是同样的道理。
使用与上面同样的方法,在主脚本中配置一个变量,然后 source 另一个脚本
【主脚本代码】
#!/bin/bash
var=10
echo "我是主脚本, 变量var的值是: ${var}"source ./scr.sh # 调用其他脚本
【另一个脚本代码】
#!/bin/bash
echo "我是其他脚本, 变量var的值是: ${var}"
为什么说 source 是将另一个变量的代码读取到本地,看一下这个例子就明白了。
【主脚本代码】
#!/bin/bash
echo "我是主脚本"source ./scr.sh # 调用其他脚本
Func # 调用另一个脚本的函数
【另一个脚本代码】
#!/bin/bash
# 只定义函数,不调用
Func(){echo "我是另一个脚本的函数Func"}
我们在主脚本中使用 source 另一个脚本后,在主脚本调用另一个脚本中的函数。而在另一个脚本中只定义函数,不调用。
- 通过这两个例子可以确定,使用 source 后,两个脚本的变量和函数都可以共用。需要共享变量较多时,使用 source 最佳。
2. 避坑技巧
2.1. 路径配置无效
在平时写代码时,一般会指定一个当前路径。喜欢用 pwd 的伙伴注意了,这会出现问题。
【主脚本代码】
#!/bin/bash
init_path=$(pwd) # 使用pwd来定义当前路径
scr_path="${init_path}/scr.sh" # 通过当前路径连接另一个脚本的路径echo "我是主脚本"source ${scr_path} # 调用其他脚本
【另一个脚本代码】
#!/bin/bash
echo "我是另一个脚本"
在当前路径下执行是没问题的
但如果我们当前是在另一个路径下,无法调用另一个脚本
看吧,报了一个找不到文件的错误,而且路径也不是我们希望的那个位置。这是因为脚本中使用 pwd 定义初始路径导致的问题,pwd 这个命令表示当前终端在哪个路径下,而不是脚本在哪个路径下,所以在执行时路径发生了变化。
要解决这个问题也非常简单,将 pwd 改成
init_path=$(dirname $0) # dirname $0 表示脚本的目录
或者
init_path=$(dirname ${BASH_SOURCE})
使用 $0 后,主脚本只能使用 bash 执行,使用 source 报错
使用 ${BASH_SOURCE} 同时支持 bash 和 source
2.2. source变量冲突
在前面的《目录 1.2》中提到过,source 另一个脚本后,变量和函数是共享的,所以也会导致变量被修改。
【主脚本代码】
#!/bin/bash
var=10echo "我是主脚本, 当前var为: ${var}"source ./scr.sh # 调用其他脚本echo "我是主脚本, 调用另一个脚本后, 当前var为: ${var}"
【另一个脚本代码】
var=20
echo "我是另一个脚本, 这里的var为: ${var}"
由于变量共享,所以其他脚本的全局变量名与当前脚本的全局变量名相同的话,是会被修改的。
避免的方法
- 如果不需要共享变量的情况下,建议使用 bash,不使用 source
- 如果需要共享大量变量的情况下,使用 source,但非主脚本的变量全部定义为局部变量。
【主脚本代码】
#!/bin/bash
var=10echo "我是主脚本, 当前var为: ${var}"source ./scr.sh # 调用其他脚本echo "我是主脚本, 调用另一个脚本后, 当前var为: ${var}"
【另一个脚本代码】
Func(){local var=20 # 定义局部变量echo "我是另一个脚本, 这里的var为: ${var}"}
Func
非主脚本的代码都使用函数封装,并且将所有变量定义为局部变量,即使变量名称相同也不会发生冲突。
3. 总结
1、当需要共享大量变量的情况下,使用 source 调用另一个脚本。但另一个脚本的代码尽量都使用函数封装,将函数中的变量定义为局部变量,避免名称冲突。
2、当不需要共享变量时,或者少量变量时,可以使用 bash 调用另一个脚本。当然,这还是看个人习惯吧。
3、不论是主脚本还是其他脚本,都可以 source 或 bash 多个其他脚本。如果是 source,则全部共享。