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

Linux学习笔记之七(shell脚本的基本语法)

Shell

  • 1、Shell脚本
  • 2、常用运算符
  • 2、特殊语法
  • 4、关于变量的一些命令
    • 4.1、echo
    • 4.2、export
    • 4.3、read
    • 4.4、declare/typeset
    • 4.5、local
    • 4.6、unset
  • 5、基本逻辑语法
    • 5.1、if判断
    • 5.2、for循环
    • 5.3、while循环
    • 5.4、case语句
  • 6、函数定义
  • 7、多脚本链接

1、Shell脚本

学习shell脚本开发之前,必须得有一些基础的Linux相关知识,比如环境变量和shell指令的等内容。
了解Linux的系统环境变量和shell命令可以看看我之前发过的两篇文章。
Shell命令(Linux操作命令笔记)
Linux学习笔记之二(环境变量)

再说回shell脚本和shell命令,简单来说,我们在Linux终端中敲下的大多数指令都是shell指令,比如cd , ls, pwd之类的。而 shell脚本就是在一个文件中把这些shell指令依次写在一起,然后让其自动依次执行。这样我们就不需要在终端一条条的去执行了。来看个例子吧。
例程目的:我想切换到$HOME/target目录,并且列出target目录下的所有文件。
首先我先新建一个test.sh的文件,然后往里面写入对应的shell指令。shell脚本文件的第一句话必须是:

#! /bin/bash

写这句话相当于在告诉Linux系统,我写的这个文件是shell脚本,请用bash解释器来解释这个脚本。
在这里插入图片描述
最后执行这个脚本就可以看到我target文件夹下的所有文件了。
在这里插入图片描述
常用的shell指令不妨移步

2、常用运算符

等于号

-eq
note: equal

不等号

-ne
note: not equal

大于号

-gt
note: greater than

大于或等于号

-ge
note: greater than or equal to

小于号

-lt
note: less than

小于等于号

-le
note: less than or equal to

逻辑与

-a
eg: [ $a -eq $b -a $a -eq $c ]		#a等于b于a等于c

逻辑或

-o
eg: [ $a -eq $b -o $a -eq $c ]		#a等于b或a等于c

比较运算符号大概就这些,note后面是缩写符号的整体意思,希望能够帮助记忆。但一点需要值得注意,以上这些特殊字符之用于判断整数与整数之间的关系,而不能用于判断字符串。如果想要判断字符串还得用 = = == == ! = != !=号这些,同时这些常规符号也兼容整数判断。至于逻辑运算符则也可以用&&, ||代替上述的-a和-o。
下面举几个例子来看一下-eq和 = = == ==的区别。

name="lihua"
age=18
[ "$name" -eq "lihua" ];[ "$name" == "lihua" ];[ "$age" == 18 ];

此外,在用$符号对变量取值的时候,最后还是加上一对双引号,这样可以避免很多错误。比如下面这个例子:

name="li hua"
[ $name == "li hua" ][ "$name" == "li hua" ]

如果不加双引号,那$name等于li hua,第一条语句就变成了下面这个样子,显然会报错。

li hua == "li hua"

加了引号就变成。

"li hua" == "li hua"

并且加引号只是把这个变量视为一个整体。但是凡被括号括起来的数据,都会被转化为数据串类型。。。
那么再提一句,如果想把字符串转化为整形,可以利用双括号的作用。

var="05"
num=$((var))
echo $num

2、特殊语法

  • -r:判断给定文件是否是可读文件。
  • -w:判断给定文件是否是可写文件。
  • -x:判断给定文件是否是可执行文件。
  • -d:判断给定参数是否是一个文件夹。
  • -f:判断给定参数是否是一个文件。
  • -s:判断一个文件是否存在并且是否非空。
  • -z:判断给定的字符串是否为空字符串。
  • -n:判断给定的字符串是否为非空字符串。

以上这些都是一些常见的单选项标记符。判断为真则返回1,否则返回。常用于if语句中,比如我们想判断home目录下的object_file是不是可执行文件,可以做如下操作。

if [ -x $HOME/object_file ];thenecho "it is a execuate file"
fi

除了以上这些特殊标记符,还有许多特殊状态变量,如下:

  • $0:获取文件名
  • $n:获取输入的第n个参数
  • $?:获取上一条命令执行的结果,任何bash语句执行结果只有两种,执行成功为0,否则非0。
  • $#:获取传递的参数的总个数。
  • $*:获取脚本所有参数,加引号则表示“$1 $2 … $n ”。
  • $@:获取脚本所有参数,加引号则表示" $1 “,” $2 “,” $n "。 常用于for循环读取参数。
  • $!:获取上一个进程的pid号。
  • $$:获取当前shell脚本的pid号。
  • $_:获取上一次命令的最后一个参数。

看来$ 这个符号在Linux中还挺重要的,个人感觉它有点”取值“的意味,我们取一个变量也会用到$, 比如 $variable 。
最后我写一个脚本把这些特殊状态变量都用上,来看看以上这些特殊变量到底怎么用的。
在这里插入图片描述
执行一下看看效果:
在这里插入图片描述

4、关于变量的一些命令

下面介绍一些出现频率比较高的命令,但我仅讲一些常见的应用,不求全面详细。

4.1、echo

echo常用于打印变量。可以选择是否添加e和n参数,前者使echo可以识别转移字符,后者让echo打印之后不换行(echo默认打印后换行)。
举几个例子:

echo "hello"
echo -e "hello\n"		#可以识别\n
echo -n "hello"			#打印后不换行
echo -en "hello\t"		#识别转义字符且不换行
echo -ne "hello\t"		#效果同上

从上面例子可以看出,echo的参数可以自由组合,且不必考虑顺序,实现效果叠加。其他命令也同样可以。

4.2、export

export可以将变量转化成环境变量,所以我们经常在配置环境变量的时候用到这个命令。

export PATH=$PATH:$HOME/

4.3、read

在shell脚本中使用read命令正如在C语言中使用scanf命令或在python中使用input一样,可以获取用户的输入字符串。它可选的两个参数有p和t两个参数,前者可以显示提示符,后者可以设置等待用户输入的时间。
上个例子,这里我编写一个read.sh的脚本。

#! /bin/bashread -p "please enter a number: " num_1read -p "please enter another number: " -t 5 num_2echo -e "\nthe first number is $num_1"if [ -n "$num_2" ];thenecho "the second number is $num_2" 
elseecho "there is no the second number"
fi

接着,我故意第二个参数不输入,我们来看看结果。
在这里插入图片描述

4.4、declare/typeset

declare和typeset的功能基本一样,所以这里只说declare。
由于shell和python一样,都是弱定义型语言,即变量的类型取决于它所接受到值的类型,无需提前规定好。但弱定义偶尔也有一些不好地方,比如我们本来希望它是一个整型变量,它却因各种原因变成字符串类型。比如read会把数字也视为字符串。。
而declare的主要作用就是声明变量类型,让变量的类型不至于”跑偏“。它常用的参数有以下这些:

  • -a:将变量定义成数组类型。
  • -i:将变量定义成整数类型。
  • -x:将变量定义成环境变量。
  • -r:将变量定义为只读变量,同时该变量无法被unset。

看个例子:

declare -i num				
read -p "please enter a number: " num

这样就可以保证num这个变量就是一个整型了。
再来看看数组怎么用:

#! /bin/bashdeclare -a num
read -p "please enter a number: " num[0]
read -p "please enter another number: " -t 5 num[1]
echo -e "\nthe first number is ${num[0]}"
if [ -n "$num[1]" ];thenecho "the second number is ${num[1]}" 
elseecho "there is no the second number"
fi

其实还是用[ ]来索引数组里面的值,但由于$的优先级高于[ ],所以记得用{ }来使num先索引再取值。除了用declare定义,我们也可以用弱定义的方式定义一个固定长度的数组。

num[0]=1
num[1]=2
..

4.5、local

声明一个变量是一个局部变量,由于shell语言中不同于大多数程序语言,在其函数内部声明的变量不会被自动视为局部变量。所以有时候为了使函数中的变量是局部变量就会用到local命令。
比如下面这个例子,在test这个函数内声明了一个var的局部变量,如果在函数外打印它就会报错。

#! /bin/bashfunction test{local var=1
}echo "$var"

4.6、unset

unset就比较简单了,其功能是删除一个变量。如下,删除var变量之后再调用echo是会报错的。

#! /bin/bashvar="test"
unset var
echo "$var"

看到unset便自然的想到是否有set,其实是有的,只不过它们的功能大相径庭,set主要用于显示所有环境变量。所以与unset相反的作用的更像是typeset。

5、基本逻辑语法

5.1、if判断

基本用法如下,注意该空格的地方不能省略,不该空格的地方不能多加。

#! /bin/bashage=18
if [ "$age" -gt 18 ];thenecho "adult"
elseecho "child"
fi

在shell脚本中的中括号的主要用于条件测试,我们在看看if和逻辑预算符号一起使用的例子。

#! /bin/bashage=21
if [ "$age" -eq 18 ] && [ "$age" -lt 20 ];
thenecho "yes"
elseecho "no"
fi

5.2、for循环

#! /bin/bashfor i in {1..4};
doecho "$i"
done

shell中的大括号用处挺多的,但这里的大括号表示生成一系列可能的集合,即1,2,3,4。另外,在也可借助双引号的能力来像C语言那样实现从1到4的遍历。

for((i=1; i<=4; i++));
doecho "$i"
done

5.3、while循环

#! /bin/bashcounter=0
while [ "$counter" -le 5 ]
doecho "Counter: $counter"((counter++))
done

counter++外面必须包裹两个小括号,因为双括号用于逻辑运算和数学操作。

5.4、case语句

fruit="apple"case "$fruit" in"apple")echo "You chose an apple.";;"banana")echo "You chose a banana.";;"orange"|"grape")echo "You chose an orange or a grape.";;*)echo "You chose something else.";;
esac

其中,“ * ) ”表示默认。在这里指如果fruit不是apple, banana, orange, grape其中一个就执行 “ * ) ”之后的操作。

6、函数定义

shell中的函数定义就比较奇怪了,主要体现在参数传输这一块。我们可以直接看看代码。

#! /bin/bashfunction name()
{name="$1"age="$2"echo "his name is $name"echo "his age is $age"
}name "xaioming" "18"

可以看到,上述例程所定义的函数之前有一个function的关键字,但其实这个是可有可无的。其次,可以用"$1"之类的符号来获得传入的参数。另外,即便调用该函数的时候传入了两个参数,但只拿除一个来用也无所谓。

#! /bin/bashname()
{name="$1"#age="$2"echo "his name is $name"#echo "his age is $age"
}name "xaioming" "18"

还有几点需要注意的,其一就是shell脚本和python一样,调用该函数必须在该函数定义之后。其二,在函数里面定义的变量如何不用local声明,那么是会被认为是全局变量的,这样可能会照成很多麻烦。

7、多脚本链接

前面提到shell脚本的编写逻辑和python有点像,调用函数之前必须在先定义函数。那么当定义的函数多了,就势必导致代码变成非常混乱和难读,这时候就需要学会多脚本链接了。
在一个名为script_1.sh的脚本写一个函数:

#! /bin/bashfunction hello()
{name="$1"echo "hello, i am $name"
}

在一个名为script_2.sh的脚本调用hello函数,并且传入名字:

#! /bin/bashsource ./script_1.shhello "li hua"

当你在script_2.sh中执行source script_1.sh这句代码的时候,它会引入script_1.sh的文件的代码并执行它。

相关文章:

Linux学习笔记之七(shell脚本的基本语法)

Shell 1、Shell脚本2、常用运算符2、特殊语法4、关于变量的一些命令4.1、echo4.2、export4.3、read4.4、declare/typeset4.5、local4.6、unset 5、基本逻辑语法5.1、if判断5.2、for循环5.3、while循环5.4、case语句 6、函数定义7、多脚本链接 1、Shell脚本 学习shell脚本开发之…...

PySpark开发环境搭建常见问题及解决

PySpark环境搭建常见问题及解决 1、winutils.exe问题2、SparkURL问题3、set_ugi()问题 本文主要收录PySpark开发环境搭建时常见的一些问题及解决方案&#xff0c;并收集一些相关资源 1、winutils.exe问题 报错摘要&#xff1a; WARN Shell: Did not find winutils.exe: {} ja…...

supervisor管理启动重启,Java,Go程序Demo

简介 Supervisor 是一款 Python 开发的进程管理系统&#xff0c;允许用户监视和控制 Linux 上的进程&#xff0c;能将一个普通命令行进程变为后台守护进程&#xff0c;异常退出时能自动重启 1、安装 yum -y install supervisor2、配置默认配置文件 echo_supervisord_conf &g…...

HarmonyOs 4 (三) ArkTS语言

目录 一 认识ArkTs语言1.1 ArkTs1.2 基本结构 二 基本语法2.1 声明式UI2.1.1 创建组件2.1.1.1 无参数2.1.1.2 有参数2.1.1.3 组件样式2.1.1.4 组件方法2.1.1.5 组件嵌套 2.1.2 自定义组件2.1.2.1 基本结构2.1.2.2 成员函数/变量2.1.2.3 自定义组件的参数规定2.1.2.4 Build函数2…...

PostGIS学习教程九:空间连接

PostGIS学习教程九&#xff1a;空间连接 空间连接&#xff08;spatial joins&#xff09;是空间数据库的主要组成部分&#xff0c;它们允许你使用空间关系作为连接键&#xff08;join key&#xff09;来连接来自不同数据表的信息。我们认为“标准GIS分析”的大部分内容可以表示…...

C++ day56 两个字符串的删除操作 编辑距离

题目1&#xff1a;583 两个字符串的删除操作 题目链接&#xff1a;两个字符串的删除操作 对题目的理解 返回使两个单词word1和word2相同的最少删除多少个元素&#xff0c;两个单词至少包含一个字母&#xff0c;且仅包含小写字母 思路1&#xff1a;这道题与昨天的不同子序列…...

Android studio中如何生成jar包?

文章目录 需求背景目录结构gradle结构makeJar的语法解析 执行makeJar 任务拿到jar包 需求背景 别部门做C语言开发的同学开发了一个库&#xff0c;需要给我们Android端去调用。 我们拿到源码&#xff0c;首先需要做的是通过CMake去把C源码编译链接成动态库。 当然静态库也行&am…...

【2】基于多设计模式下的同步异步日志系统-设计模式

6. 相关技术知识补充 6.1 不定参函数 在初学C语⾔的时候&#xff0c;我们都⽤过printf函数进⾏打印。其中printf函数就是⼀个不定参函数&#xff0c;在函数内部可以根据格式化字符串中格式化字符分别获取不同的参数进⾏数据的格式化。 ⽽这种不定参函数在实际的使⽤中也⾮常…...

第十五届蓝桥杯模拟赛B组(第二期)C++

前言&#xff1a; 第一次做蓝桥模拟赛的博客记录&#xff0c;可能有很多不足的地方&#xff0c;现在将第十五届蓝桥杯模拟赛B组&#xff08;第二期&#xff09;的题目与代码与大家进行分享&#xff0c;我是用C做的&#xff0c;有好几道算法题当时自己做的也是一脸懵&#xff0c…...

企业ERP软件定制开发要注意|app小程序搭建

企业ERP软件定制开发要注意|app小程序搭建 企业ERP软件定制开发是一项复杂而且关键的任务&#xff0c;它需要深入理解企业的需求和流程&#xff0c;并且以此为基础进行设计和开发。以下是一些关于企业ERP软件定制开发的注意事项。 首先&#xff0c;我们必须确保在进行定制开发之…...

系统架构设计-权限模块的设计

系统架构-权限模块的设计 如何评估一个研发人员技术水平&#xff0c;在大部分的情况下不是看其完成业务代码的好坏&#xff0c;更多的时候还是需要看这个研发人员从零构建一个完整项目的能力&#xff0c;在大公司中这样的机会可能相对较少&#xff0c;大部分的时间里都是对现有…...

IDEA切换Python虚拟环境

前言 因为之前一直使用的IDEA开发&#xff0c;换到VSCODE之后各种不习惯&#xff0c;特别是DEBUG的操作&#xff0c;特别难受&#xff0c;因此决心换回IDEA 环境配置 已有项目调整 进入Project 选择SDKs&#xff0c;新建Python 配置Conda以及虚拟环境 有就选择一个虚拟环境…...

《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测

1、前言 边缘检测&#xff1a; 图像边缘检测是指在图像中寻找灰度、颜色、纹理等变化比较剧烈的区域&#xff0c;它们可能代表着物体之间的边界或物体内部的特征。边缘检测是图像处理中的一项基本操作&#xff0c;可以用于人脸识别、物体识别、图像分割等多个领域。 边缘检测…...

prime靶机打靶记录

靶机下载地址 https://download.vulnhub.com/prime/Prime_Series_Level-1.rar nmap搜索目标 使用nmap -sn 192.168.41.0/24找到目标靶机192.168.41.136 扫描端口&#xff0c;因为是靶机&#xff0c;所以速率直接调了10000 扫出来两个端口22和80&#xff0c;进行详细的扫描 没…...

树莓派,linux换清华源

清华源网址 https://mirrors.tuna.tsinghua.edu.cn/help/raspbian/ 更换软件源 鉴于国内网络环境下载各大镜像&#xff0c;软件包速度慢的问题&#xff0c;需要更换软件源&#xff0c;以防下载慢&#xff0c;且在本教程中&#xff0c;统一更换为清华源。 2.3.1 更换树莓派软…...

公有云迁移研究——AWS DMS

大纲 1 什么是DMS2 DMS的作用3 DMS在迁移的时候都做些什么4 在使用DMS的时候我们需要做些什么5 操作5.1 创建两个数据库终端节点5.2 创建迁移任务 6 可能遇到的问题7 总结 在本地机房或其他云往AWS上做迁移时&#xff0c;往往会遇到数据库迁移的任务。如果数据量不是特别大&…...

一起学docker系列之十七Docker Compose 与手动操作的比较与优势分析

目录 1 前言2 不使用 Docker Compose2.1 启动 MySQL 容器2.2 启动 Redis 容器2.3 启动微服务容器 3 使用 Docker Compose4 使用 Docker Compose 的优势5 结语参考地址 1 前言 在当今容器化应用的开发与部署中&#xff0c;容器编排工具的选择对于简化流程、提高效率至关重要。本…...

IP地址定位不准确的情况研究

在互联网的浩瀚海洋中&#xff0c;每一台连接到网络的设备都被赋予了一个独特的标识符&#xff0c;这就是IP地址。它就像是我们在线身份的一部分&#xff0c;帮助我们与他人进行通信&#xff0c;获取信息&#xff0c;以及享受各种网络服务。然而&#xff0c;由于各种原因&#…...

武汉凯迪正大KDZD5289硫化曲线测试仪(电脑无转子硫化仪)

电脑无转子硫化仪 硫化时间测试仪 硫化曲线仪 硫化曲线测试仪 武汉凯迪正大KDZD5289产品概述 KDZD5289硫化曲线测试仪&#xff08;电脑无转子硫化仪&#xff09;采用电脑控制进口温控仪进行准确控温&#xff0c;计算机适时进行数据处理并可进行统计、分析、存储对比等&#xff…...

Topic和Partition

作用 主题作为消息的一级分类, 分区是对二级分类。分区是Kafka可伸缩性和水平扩展的关键, 也是多副本机制保证可用性的基础。分区可以有一到多个副本, 每个副本对应1个日志文件, 每个日志文件对应1到多个日志分段。每个日志分段又可以细分为日志文件, 索引文件和快照文件。 创…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...