当前位置: 首页 > news >正文

网站建设服务8百度搜索广告收费标准

网站建设服务8,百度搜索广告收费标准,wordpress 主题显示图片,制作一个网站步骤在Linux开发中,经常会编写shell脚本来执行一些任务,通常是一个脚本只做一件事,随着任务的增加,脚本会越来越多,可复用的地方也会逐渐增加,这时就需要提取出脚本中的公共的功能放到一个通用的脚本中&#xf…

bd907b80e80da2c5db9a68b412a5ce9d.png0f1ea7f637205bb6e9ccfc0b127d3a5c.png

在Linux开发中,经常会编写shell脚本来执行一些任务,通常是一个脚本只做一件事,随着任务的增加,脚本会越来越多,可复用的地方也会逐渐增加,这时就需要提取出脚本中的公共的功能放到一个通用的脚本中,其他脚本都能复用它

本篇文章介绍shell脚本中如何执行外部脚本,如何调用外部脚本中的函数,以及脚本复用相关的方法

执行外部脚本的方式

假如在当前目录有 a.sh 脚本,内容如下

#!/bin/bash
echo "a.sh..."

在一个脚本中执行外部脚本主要有以下几种方式

  • source 外部脚本名字

在当前目录下的 b.sh 脚本,内容如下:

#!/bin/bash
source a.sh
echo "b.sh..."

执行 ./b.sh,结果如下

[root@ecs-centos-7 ~]# ./b.sh 
a.sh...
b.sh...

脚本中 source a.sh 命令 会先执行当前目录下的 a.sh脚本,所以结果会先输出 a.sh...再输出 b.sh脚本本身的打印

  • 点号 外部脚本名字

把 b.sh 脚本中执行a.sh脚本的语句修改成 点号 + 空格 + a.sh ,修改之后的脚本内容如下:

注意:点号和a.sh之间一定要加上空格,否则执行的时候会出错

#!/bin/bash
. a.sh
echo "b.sh..."

执行 ./b.sh,结果如下

[root@ecs-centos-7 ~]# ./b.sh 
a.sh...
b.sh...

在上述脚本中, . a.sh 会先执行a.sh脚本, 结果会先输出 a.sh...再输出 b.sh...

  • sh 外部脚本名字

sh 外部脚本名字 和 ./外部脚本名字 两种方式是一样的,选择哪一种方式都没问题,下面是以前面一种方式为例说明的

把 b.sh 脚本中 source a.sh修改成 sh a.sh ,修改之后的脚本内容如下:

#!/bin/bash
sh a.sh
echo "b.sh..."

执行 ./b.sh 命令, 结果如下

[root@ecs-centos-7 ~]# ./b.sh 
a.sh...
b.sh...

可以看出,结果输出和上面两种方式是一样的

三种方式的有什么区别

调用外部脚本有 source 外部脚本 、点号 外部脚本sh 外部脚本 三种方式,它们之间有什么区别呢?

其中,source 外部脚本 和 点号 外部脚本 两种方式是相同的,当前脚本继承了外部脚本的全局变量和函数, 相当于把外部脚本的函数和全局变量导入了当前脚本中

修改 a.sh 和 b.sh 脚本, 内容如下

a.sh脚本

#!/bin/bash
VAR_A=10

func_a()
{
echo "a.sh...pid:$$,param:$1"
}

b.sh脚本

#!/bin/bash
source a.sh

func_a $1
echo "vara:$VAR_A"
echo "b.sh...pid:$$"

执行 ./b.sh 5 命令,结果如下

[root@ecs-centos-7 ~]# ./b.sh 5
a.sh...pid:21485,param:5
vara:10
b.sh...pid:21485

两个脚本中的 $$ 是指执行脚本的进程ID,从结果可以看出,a.sh 和 b.sh 都是在同一个进程内执行的,所以在 b.sh 脚本中执行 source a.sh 命令,会把 a.sh 脚本中的全局变量 VAR_A 和函数 func_a导入到 b.sh

在 b.sh中打印变量 VAR_A,输出的值和 a.sh中相同,调用 func_a函数,输出也说明了调用的是 a.sh中的函数

source 外部脚本 、点号 外部脚本 两种方式是相同的, 所以, 把 b.sh 中 source a.sh 修改成 . a.sh , 执行 ./b.sh 5, 结果依然是相同的

由于 sh 外部脚本的方式是当前脚本和外部脚本在两个不同的进程中执行,所以当前脚本不能直接使用外部脚本中的函数和全局变量

修改 a.sh 和 b.sh 脚本, 内容如下

a.sh脚本

#!/bin/bash
test_a()
{
echo "a.sh...test_a"
}

echo "a.sh...pid:$$"

b.sh脚本

#!/bin/bash
sh a.sh

echo "b.sh...pid:$$"

test_a

执行 ./b.sh 命令,结果如下

[root@ecs-centos-7 ~]# ./b.sh 
a.sh...pid:21818
b.sh...pid:21817
./b.sh:行7: test_a: 未找到命令

从结果可以看出,执行 a.sh 和 b.sh 的进程ID是不同的,b.sh脚本进程找不到test_a函数,所以在b.sh中调用test_a 函数会提示 未找到命令

调用外部脚本中的函数

上一节讲到 sh 外部脚本 的方式无法直接使用外部脚本中函数和全局变量,下面提供几种方法可以解决这个问题

  • case 分支选择

这种方法类似于程序代码中的 switch case 语句,通过switch 选择不同的分支从而执行不同的逻辑,shell脚本中是使用case关键字来实现的

a.sh脚本

#!/bin/bash
VAR_A=10

test_a()
{
echo "test_a..pid:$$,p1:$1,p2:$2"
}
get_var()
{
echo ${VAR_A}
}

case "$1" in
ta)
test_a $2 $3
;;
var)
get_var
;;
*)
echo "parameter err..."
esac

b.sh脚本

#!/bin/bash
echo "b.sh...pid:$$"

sh a.sh ta 3 5

ret=$(sh a.sh var)

echo "ret:$ret"

执行 ./b.sh 命令,结果如下

[root@ecs-centos-7 ~]# ./b.sh 
b.sh...pid:24813
test_a..pid:24814,p1:3,p2:5
ret:10

脚本b.sh一开始打印了调用自身的进程ID

sh a.sh ta 3 5 语句是调用a.sh脚本,传入的三个参数分别是ta35 ,执行a.sh时,传入的第一个参数 ta经过case匹配之后调用 test_a函数,并把剩下的两个参数 35作为参数传入函数

ret=$(sh a.sh var) 语句时调用a.sh脚本,传入一个var 参数,经过case匹配之后调用get_var函数,该函数的作用输出脚本中全局变量VAR_A的值,语句中$()的作用是获取()中命令的返回值,这里是把a.sh脚本中 get_var函数的返回值赋值给 ret变量,所以该变量的值是 a.sh脚本中全局变量VAR_A的值

说明:如果想要获取函数的返回值,可以在函数中用 echo 打印相应的输出值,然后使用$(函数名 参数列表)可以获取到函数中打印的值,如上面b.sh脚本中 ret=$(sh a.sh var)语句,变量ret的值是 a.sh脚本中 get_var函数输出的值10

这里需要注意的是, 如果函数中有echo调试日志,那么调试日志也会一起返回

  • 函数调用模板

上面介绍的用 case 关键字去匹配调用不同的函数有一个缺点,每次a.sh脚本中增加一个函数的时候,case 就需要添加一个分支,分支里调用不同的函数,还需要注意函数是否有参数传入以及参数数量是否正确

我们可以在每个供外部调用脚本的尾部加上以下的语句,就可以解决上述问题, 具体语句如下

if [ $# -ge 1 ]; then
name="$1"
shift 1
$name "$@"
fi

上述语句首先判断调用脚本时传入的参数数量,只有参数数量大于等于1才有效,传入的第一个参数表示函数名字,从第二个参数到最后一个参数都会作为参数传入到函数中

这里的 shift 1 是把传入脚本的参数左移一个位置,比如:传入脚本参数有 $1 $2 $3三个参数,左移一个位置之后, $2 移动到 $1 的位置,$3 移动到 $2 的位置,参数数量变为2了

原因: 传入脚本的参数中,第一个参数是函数名字,从第二个参数起才是函数的参数,如果不做左移处理,第一个参数函数名字也会作为参数传入到函数中

下面是完整的脚本内容

a.sh脚本

#!/bin/bash
VAR_A=10

test_a()
{
echo "test_a..pid:$$,p1:$1,p2:$2"
}

get_var()
{
echo ${VAR_A}
}

if [ $# -ge 1 ]; then
name="$1"
shift 1
$name "$@"
fi

b.sh脚本

#!/bin/bash
echo "b.sh...pid:$$"

sh a.sh test_a 3 5

ret=$(sh a.sh get_var)

执行 ./b.sh 命令,结果如下

[root@ecs-centos-7 ~]# ./b.sh 
b.sh...pid:25086
test_a..pid:25087,p1:3,p2:5
ret:10

可以看出,结果和上面 case 的方法是一样的

现在其他脚本中都可以通过 sh a.sh 函数名 参数列表 这样的方式调用 a.sh 脚本中的函数了,通过 $(sh a.sh 函数名 参数列表)的方式获取 a.sh脚本函数的返回值

  • 两者的优缺点

与case分支选择的方式相比,函数调用模板的优点是调用者只需要关心复用的脚本中函数名、函数传入参数、函数返回值就可以直接使用

缺点是如果有多个脚本都调用了复用脚本中的函数,当复用脚本中函数名变更时,需要修改所有调用了它的地方

函数调用模板方式的缺点恰恰是case分支选择方式的有点,case分支选择的方式时根据传入的字符串参数调用不同的函数,这里的字符串参数相当于函数的别名,只要这个参数保持不变,脚本中的函数名字可以任意变更

上述的优缺点比较只是一个相对的比较,实际应用中下不会很明显,大部分情况两种方式都可以使用

小结

在编写shell脚本的过程中,经常会遇到一些莫名奇妙的问题,有些问题就算挠破头皮都不知道如何解决,脚本复用可以把一些公共功能提取出来,形成一个个的功能模块,不仅有助于减少我们编写脚本时犯的错误,而且对后期的脚本维护很有帮助

良许个人微信

添加良许个人微信即送3套程序员必读资料

→ 精选技术资料共享

→ 高手如云交流社群

3d5a8f55bea67b9a38ca253d99d01ff2.png


本公众号全部博文已整理成一个目录,请在公众号里回复「m」获取!

推荐阅读:

嗨:VSCode和IDEA都请安装上这个神奇的插件

雷军1994年写的诗一样的代码,我把它运行起来了!

Linux 网络状态工具 ss 命令使用详解

5T技术资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,单片机,树莓派,等等。在公众号内回复「1024」,即可免费获取!!

78ef0ea37b594ca11d3854b3790e04a0.png

http://www.lbrq.cn/news/2344861.html

相关文章:

  • 政府机关备案网站24小时免费看的视频哔哩哔哩
  • 网推方案seo建站要求
  • 运营怎么自学20条优化措施
  • 如何利用fortran语言建设网站最全资源搜索引擎
  • 怎样做网站发布信息百度指数排名热搜榜
  • 响应式网站自助建设平台合肥seo推广公司哪家好
  • 建网站啦国外搜索引擎
  • 做网站时分类标题和分类描述宁波网络推广优化公司
  • 求一个手机能看的2022百度首页排名优化公司
  • 合肥网站的建设百度的合作网站有哪些
  • 建设网站哪里好seo搜索引擎优化ppt
  • net的电商网站建设seo哪里可以学
  • 医疗网站企业seo排名外包
  • 海外市场推广做什么的江北seo页面优化公司
  • 什么网站做谷歌联盟好网店怎么开
  • 微软雅黑做网站阿里云建网站
  • 江苏 网站 备案各地疫情最新消息
  • 新乡营销网站建设公司四川seo哪里有
  • 织梦 做网站 知乎seo搜索排名
  • 公司如何建设一个网站淄博seo怎么选择
  • php做电商网站安全性如何青岛网络seo公司
  • WordPress源码带会员中心系统青岛网站seo公司
  • 岳阳做网站的公司郑州网站建设
  • 网站不备案做电影网站浙江网站建设平台
  • 网站开发一个多少钱站长工具seo查询5g5g
  • 做食物网站龙岗seo优化
  • 网站的空间是什么意思谷歌搜索引擎在线
  • 平面设计好的网站北京seo管理
  • 定制企业网站开发公司seo联盟
  • 个人网站建设视频教学北海百度seo
  • 【网络安全】大型语言模型(LLMs)及其应用的红队演练指南
  • 基于多智能体强化学习的医疗检索增强生成系统研究—MMOA-RAG架构设计与实现
  • iOS高级开发工程师面试——RunTime
  • 实现高效、可靠的基于骨骼的人体姿态建模(第二章 基于三维人体姿态回归的语义图卷积网络)
  • Spring AI 项目实战(十六):Spring Boot + AI + 通义万相图像生成工具全栈项目实战(附完整源码)
  • Vue配置特性(ref、props、混入、插件与作用域样式)