shell 如何调用多个脚本

news2024/9/29 1:23:54

简介

    这篇文章主要描述如何通过主脚本去调用其他脚本中的方法,调用的过程中可能出现哪些坑,如何避免。

        

目录

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=10

echo "我是主脚本, 当前var为: ${var}"

source ./scr.sh    # 调用其他脚本

echo "我是主脚本, 调用另一个脚本后, 当前var为: ${var}"

 【另一个脚本代码】

var=20
echo "我是另一个脚本, 这里的var为: ${var}"

由于变量共享,所以其他脚本的全局变量名与当前脚本的全局变量名相同的话,是会被修改的。

        

避免的方法

  1. 如果不需要共享变量的情况下,建议使用 bash,不使用 source
  2. 如果需要共享大量变量的情况下,使用 source,但非主脚本的变量全部定义为局部变量。

    【主脚本代码】

#!/bin/bash
var=10

echo "我是主脚本, 当前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,则全部共享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1333785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工具系列:TensorFlow决策森林_(5)使用文本和神经网络特征

文章目录 设置使用原始文本作为特征使用预训练的文本嵌入同时训练决策树和神经网络构建模型训练和评估模型 欢迎来到 TensorFlow决策森林( TF-DF)的 中级教程。 在本文中,您将学习有关 TF-DF的一些更高级的功能,包括如何处理自…

SQL进阶理论篇(二十一):基于SQLMap的自动化SQL注入

文章目录 简介获取当前数据库和用户信息获取MySQL中的所有数据库名称查询wucai数据库中的所有数据表查看heros数据表中的所有字段查询heros表中的英雄信息总结参考文献 简介 从上一小节,可以发现,如果我们编写的代码存在着SQL注入的漏洞,后果…

HarmonyOS的装饰器之BuilderParam 理解

BuilderParam 装饰器 使用时间:当定义了一个子组件,并且子组件的build()中有一个布局在不同的父组件,实现效果不一样的时候,可以在子组件中用这个BuilderParam装饰器, 在父组件用Builder 装饰器进行实现,然…

Lua的垃圾回收机制详解

Lua 是一种轻量级的编程语言,广泛用于嵌入到其他应用程序中,尤其是在游戏开发领域。Lua 的内存管理机制采用了自动垃圾收集(Garbage Collection)的方法。以下是Lua内存管理的一些关键方面: 垃圾收集原理概述 Lua 使用…

我的软考之路

缘起 2016年,入职了一家业务相对稳定的公司。技术栈的切换使得刚入职的时光格外忙碌。然而当所有工作所需技术逐步掌握并渐渐精通,摸鱼的时间也相对多了起来。 这样的日子一多,危机感开始蔓延,毕竟35是谁都绕不过的一道坎。程序猿…

SQL实践篇(一):使用WebSQL在H5中存储一个本地数据库

文章目录 简介本地存储都有哪些?如何使用WebSQL打开数据库事务操作SQL执行 在浏览器端做一个英雄的查询页面如何删除本地存储参考文献 简介 WebSQL是一种操作本地数据库的网页API接口,通过它,我们可以操作客户端的本地存储。 WebSQL曾经是H…

【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)

目录 一、C/C内存分布二、new和delete的使用方式2.1 C语言内存管理2.2 C内存管理2.2.1 new和delete操作内置类型2.2.2 new和delete操作自定义类型 三、new和delete的底层原理3.1 operator new与operator delete函数3.2 原理总结3.2.1 内置类型3.2.2 自定义类型 四、定位new表达…

OpenAI开发者大会简介

文章目录 GPT-4 Turbo 昨天晚上 OpenAI的首届开发者大会召开 Sam Altman也做了公开演讲,应该说 这是继今年春天发布GPT-4之后 OpenAI在AI行业又创造的一个不眠夜 过去一年 ChatGPT绝对是整个科技领域最热的词汇 OpenAI 也依靠ChatGPT取得了惊人的成绩 ChatG…

模拟生物自然进化的基因遗传算法

基因遗传算法(Genetic Algorithm,GA)是一种通过模拟生物进化过程来寻找最优解的优化算法。它是一种常见的启发式搜索算法,常用于优化、搜索和机器学习等领域。 生物基因遗传 生物的基因遗传是指父母通过基因传递给子代的过程。基因…

基于STM32的DS1302实时时钟模块应用及原理介绍

在嵌入式系统中,实时时钟模块是一个常见的功能模块,用于记录和管理系统的时间信息。DS1302是一款低功耗、具有多种功能的实时时钟芯片,被广泛应用于各种电子产品中。本文将介绍基于STM32微控制器的DS1302实时时钟模块的应用及原理&#xff0c…

C++类的继承

目录 什么是继承? 父类与子类对象的赋值转换 继承中的作用域问题 子类的默认成员函数问题 如何使一个类不能被继承? 父类的友元和静态成员变量 多重继承与菱形继承 继承和组合 什么是继承? 继承 (inheritance) 机制是面向对象程序设…

基于FPGA的图像Robert变换实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 fpga的结果导入到matlab显示: 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 ..................................…

obsidian使用分享

ob对比其他软件 上文提到obsidian,这里对obsidian做一个简要的总结 优点:对比notion,语雀这些软件,内容存储在应用商的服务器上。它是存在本地的。 对比思源笔记。说一下思源笔记的不足。思源是块来控制的,回车就是一…

基于Arduino和HC-SR04的超声波测距系统设计

本文介绍了如何使用Arduino和HC-SR04超声波传感器设计并构建一个简单的超声波测距系统。我们将详细讨论硬件连线和编程步骤,并提供完整的Arduino代码。此系统可以应用于各种需要测量距离的项目,例如智能车辆、机器人和安防系统。 引言: 超声…

【Python】pip管理Python包

命令&#xff1a;pip install <包名> 安装指定的包。 pip install ipython #或者 pip install ipython -i https://mirrors.aliyun.com/pypi/simple/ 命令&#xff1a;pip uninstall <包名> 删除指定的包。 pip uninstall ipython 命令&#xff1a;pip list 显…

XxIJob入门-示例

一、部署 xxlJob (一) 下载地址&#xff0c; git clone 到本地。 http://gitee.com/xuxueli0323/xxl-job https://github.com/xuxueli/xxl-job (二) 插入 xxl_job 的sql脚本&#xff1a; 在项目的 /xxl-job/doc/db/tables_xxl_job.sql &#xff0c;找到sql脚本&#xff0c…

使用ACL与prefix-list匹配路由 distribute-list过滤路由

一、实验拓扑 二、实验目的 熟练掌握ACL和prefix-list在ospf匹配路由的应用 三、实验配置 第一步&#xff1a;配置全局基本ip地址 R1 Ruijie(config)#hostname R1 Ruijie(config)#hostname R1 R1(config)#interface gigabitEthernet 0/0 R1(config-if-GigabitEthernet 0/0)#n…

nodejs微信小程序+python+PHP的4s店客户管理系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

反注入技术:防范非法 Call 调用的探讨

DLL 注入是一种常见的技术&#xff0c;用于向目标进程注入外部的动态链接库&#xff08;DLL&#xff09;&#xff0c;以执行某些特定的操作。这种技术在恶意软件、游戏作弊等场景中被广泛使用&#xff0c;因此&#xff0c;研究和实施一些反注入技术对于提高应用程序的安全性是至…

案例136:基于微信小程序的公交信息在线查询系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…