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
例程目的:我想切换到$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开发环境搭建时常见的一些问题及解决方案,并收集一些相关资源 1、winutils.exe问题 报错摘要: WARN Shell: Did not find winutils.exe: {} ja…...
supervisor管理启动重启,Java,Go程序Demo
简介 Supervisor 是一款 Python 开发的进程管理系统,允许用户监视和控制 Linux 上的进程,能将一个普通命令行进程变为后台守护进程,异常退出时能自动重启 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学习教程九:空间连接 空间连接(spatial joins)是空间数据库的主要组成部分,它们允许你使用空间关系作为连接键(join key)来连接来自不同数据表的信息。我们认为“标准GIS分析”的大部分内容可以表示…...
C++ day56 两个字符串的删除操作 编辑距离
题目1:583 两个字符串的删除操作 题目链接:两个字符串的删除操作 对题目的理解 返回使两个单词word1和word2相同的最少删除多少个元素,两个单词至少包含一个字母,且仅包含小写字母 思路1:这道题与昨天的不同子序列…...
Android studio中如何生成jar包?
文章目录 需求背景目录结构gradle结构makeJar的语法解析 执行makeJar 任务拿到jar包 需求背景 别部门做C语言开发的同学开发了一个库,需要给我们Android端去调用。 我们拿到源码,首先需要做的是通过CMake去把C源码编译链接成动态库。 当然静态库也行&am…...
【2】基于多设计模式下的同步异步日志系统-设计模式
6. 相关技术知识补充 6.1 不定参函数 在初学C语⾔的时候,我们都⽤过printf函数进⾏打印。其中printf函数就是⼀个不定参函数,在函数内部可以根据格式化字符串中格式化字符分别获取不同的参数进⾏数据的格式化。 ⽽这种不定参函数在实际的使⽤中也⾮常…...
第十五届蓝桥杯模拟赛B组(第二期)C++
前言: 第一次做蓝桥模拟赛的博客记录,可能有很多不足的地方,现在将第十五届蓝桥杯模拟赛B组(第二期)的题目与代码与大家进行分享,我是用C做的,有好几道算法题当时自己做的也是一脸懵,…...
企业ERP软件定制开发要注意|app小程序搭建
企业ERP软件定制开发要注意|app小程序搭建 企业ERP软件定制开发是一项复杂而且关键的任务,它需要深入理解企业的需求和流程,并且以此为基础进行设计和开发。以下是一些关于企业ERP软件定制开发的注意事项。 首先,我们必须确保在进行定制开发之…...
系统架构设计-权限模块的设计
系统架构-权限模块的设计 如何评估一个研发人员技术水平,在大部分的情况下不是看其完成业务代码的好坏,更多的时候还是需要看这个研发人员从零构建一个完整项目的能力,在大公司中这样的机会可能相对较少,大部分的时间里都是对现有…...
IDEA切换Python虚拟环境
前言 因为之前一直使用的IDEA开发,换到VSCODE之后各种不习惯,特别是DEBUG的操作,特别难受,因此决心换回IDEA 环境配置 已有项目调整 进入Project 选择SDKs,新建Python 配置Conda以及虚拟环境 有就选择一个虚拟环境…...
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测
1、前言 边缘检测: 图像边缘检测是指在图像中寻找灰度、颜色、纹理等变化比较剧烈的区域,它们可能代表着物体之间的边界或物体内部的特征。边缘检测是图像处理中的一项基本操作,可以用于人脸识别、物体识别、图像分割等多个领域。 边缘检测…...
prime靶机打靶记录
靶机下载地址 https://download.vulnhub.com/prime/Prime_Series_Level-1.rar nmap搜索目标 使用nmap -sn 192.168.41.0/24找到目标靶机192.168.41.136 扫描端口,因为是靶机,所以速率直接调了10000 扫出来两个端口22和80,进行详细的扫描 没…...
树莓派,linux换清华源
清华源网址 https://mirrors.tuna.tsinghua.edu.cn/help/raspbian/ 更换软件源 鉴于国内网络环境下载各大镜像,软件包速度慢的问题,需要更换软件源,以防下载慢,且在本教程中,统一更换为清华源。 2.3.1 更换树莓派软…...
公有云迁移研究——AWS DMS
大纲 1 什么是DMS2 DMS的作用3 DMS在迁移的时候都做些什么4 在使用DMS的时候我们需要做些什么5 操作5.1 创建两个数据库终端节点5.2 创建迁移任务 6 可能遇到的问题7 总结 在本地机房或其他云往AWS上做迁移时,往往会遇到数据库迁移的任务。如果数据量不是特别大&…...
一起学docker系列之十七Docker Compose 与手动操作的比较与优势分析
目录 1 前言2 不使用 Docker Compose2.1 启动 MySQL 容器2.2 启动 Redis 容器2.3 启动微服务容器 3 使用 Docker Compose4 使用 Docker Compose 的优势5 结语参考地址 1 前言 在当今容器化应用的开发与部署中,容器编排工具的选择对于简化流程、提高效率至关重要。本…...
IP地址定位不准确的情况研究
在互联网的浩瀚海洋中,每一台连接到网络的设备都被赋予了一个独特的标识符,这就是IP地址。它就像是我们在线身份的一部分,帮助我们与他人进行通信,获取信息,以及享受各种网络服务。然而,由于各种原因&#…...
武汉凯迪正大KDZD5289硫化曲线测试仪(电脑无转子硫化仪)
电脑无转子硫化仪 硫化时间测试仪 硫化曲线仪 硫化曲线测试仪 武汉凯迪正大KDZD5289产品概述 KDZD5289硫化曲线测试仪(电脑无转子硫化仪)采用电脑控制进口温控仪进行准确控温,计算机适时进行数据处理并可进行统计、分析、存储对比等ÿ…...
Topic和Partition
作用 主题作为消息的一级分类, 分区是对二级分类。分区是Kafka可伸缩性和水平扩展的关键, 也是多副本机制保证可用性的基础。分区可以有一到多个副本, 每个副本对应1个日志文件, 每个日志文件对应1到多个日志分段。每个日志分段又可以细分为日志文件, 索引文件和快照文件。 创…...
算法通关村第十四关|黄金挑战|数据流的中位数
数据流的中位数 原题:力扣295. 设计一种数据结构可以支持添加整数和返回中位数的操作。 之前写过找中间用两个堆,这道题就可以使用一个大顶堆和一个小顶堆。 大顶堆存储比较小的元素,小顶堆存储比较大的元素。 class MedianFinder {Prio…...
挑选数据可视化工具:图表类型、交互功能与数据安全
作为一名数据分析师,我经常需要使用各种数据可视化工具来将数据以直观、清晰的方式呈现出来,以便更好地理解和分析。在市面上的众多可视化工具中,我根据实际需求和项目特点进行选择。本文将从以下几个角度对市面上的数据可视化工具进行对比&a…...
华纳云:有效解决服务器宕机的办法
服务器宕机可能是由多种原因引起的,包括硬件故障、软件问题、网络问题等。以下是一些简单的解决服务器宕机问题的办法: 检查硬件连接: 确保服务器的所有硬件连接正常。检查电源线、网络连接、存储设备连接等,确保没有松动或断开的…...
坦克大战-部分
通过键盘操控坦克移动,转弯,射击 消灭所有敌人可以过关 23个类,3个gif图片 wsad控制移动 j射击 砖墙限制移动,可以打穿;铁墙,限制移动,不能打穿;水&#x…...
OracleRac跨网段修改Public IP/VIP/Private IP/Scan IP
本验证于测试环境,生产操作需谨慎 现为测试环境,机器有且仅有两个网卡存在,需求修改Public IP/VIP/Private IP/Scan IP,把Public IP/VIP/Scan IP的网段改为Private IP的网段,Private IP于Public IP网段互换。 先停掉两…...
使用Pytorch从零开始实现BERT
生成式建模知识回顾: [1] 生成式建模概述 [2] Transformer I,Transformer II [3] 变分自编码器 [4] 生成对抗网络,高级生成对抗网络 I,高级生成对抗网络 II [5] 自回归模型 [6] 归一化流模型 [7] 基于能量的模型 [8] 扩散模型 I, 扩散模型 II…...
Python爬虫-新能源汽车销量榜
前言 本文是该专栏的第11篇,后面会持续分享python爬虫案例干货,记得关注。 本文以懂车平台的新能源汽车销量榜单为例,获取各车型的销量排行榜单数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。 废话不多说,跟着笔者直接往下看正文详细内容。(附带…...
外包干了8个月,技术退步明显.......
先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...
<JavaEE> volatile关键字 -- 保证内存可见性、禁止指令重排序
目录 一、内存可见性 1.1 Java内存模型(JMM) 1.2 内存可见性演示 二、指令重排序 三、关键字 volatile 一、内存可见性 1.1 Java内存模型(JMM) 1)什么是Java内存模型(JMM)?Java内存模型即Java Memory Model,简…...
docker安装mysql8
docker安装mysql8 docker search mysql:8 #搜索可以使用的msyql8的镜像 docker pull mysql:8.0.27 #拉去mysql8的镜像 创建挂载的宿主机目录 mkdir -p /data/mysql/mysql8/conf # 配置文件目录 mkdir -p /data/mysql/mysql8/data # 数据目录 touch /data/mysql/mysql8/conf/my.…...
旅游景区英文网站建设研究/seo属于什么职业部门
很棒的插件,开发中能大大节省时间,喜欢的童鞋可自行下载研究源码 点击下载 名人不说暗话,上图...
学校网站建设工作方案/关键词排名关键词优化
所谓的死工资,其实是个相对的数值而不是绝对的,更多的时候指的是咱们一成不变的内心,和被社会职场打磨的毫无棱角的随波逐流。 1 今天下班回家,和往常无数个不加班的周五一样,差不多的时间,重复着差不多的故…...
网站 黄色/如何做网站建设
核心代码 File file new File(PATH_LOGCAT);if (!file.exists()) {file.mkdirs();Log.e("wy","创建文件夹1");}全部代码 private void init(Context context) {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保…...
运城网站建设公司有多少/搜索引擎营销案例分析题
Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。Python的特点:优雅、明确、简单。Python适合的领域:Web网站和各种网络服务、系统工具和脚本、作为“胶水”…...
飞沐网站设计/营销推广方案
我有一个网络,我正在使用vis.js构建,但它在宽度方面太大,无法放入页面的容器中.网络从左到右运行,包含有关特定进程的步骤.当一个人完成任务时,服务器会提供新的JSON记录来更新颜色.由于布局,我无法更改容器大小.当网络加载时,它会导致字体非常小且不可读.有没有办法可以将缩放…...
哪家网络公司做网站好/友情链接的形式有哪些
前言 前后端分离架构下,如何实现请求调用? 本文就此问题就行了初步的探究。 在前后端分离的情况下,目前主流技术是通过 axios发起请求。 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。 主要功能 从浏览器…...