09. Shell脚本

news/2025/2/4 20:09:47/文章来源:https://www.cnblogs.com/FlurryHeart/p/18698433

一、什么是Shell

  Shell 是操作系统中的一个 命令行解释器,主要功能是接收用户命令,然后将这些命令传递给操作系统内核去执行。 Shell 是用户与操作系统内核之间的接口,它允许用户通过命令行或脚本来与操作系统进行交互。同时,Shell 也是一种脚本语言,允许用户编写一系列命令脚本(Shell脚本)以实现自动化任务处理。

  我们可以查看 /etc/shells 文件查看 Linux 提供的 Shell 解释器有哪些。

cat /etc/shells

  然后,我们可以执行 echo $SHELL 命令查看默认使用的是哪个 Shell 解释器。

echo $SHELL

查看Shell解释器和默认使用的解释器

二、一个简易的Shell脚本

  这里,我们使用 vim 新建一个 Shell 脚本。然后,我们在 hello.sh 脚本文件中编写脚本。

#!/bin/bash
echo "Hello world!"

  编写完成之后,我们保存退出该脚本文件。然后,我们可以在终端中通过 sh 命令执行 Shell 脚本。

sh hello.sh

  我们也可以直接运行 hello.sh 脚本文件。

./hello.sh

  当我们直接运行脚本文件时会发现显示权限,这是因为,hello.sh 脚本文件默认没有执行权限。此时,我们可以通过 chmod 命令修改文件权限。

直接运行Shell脚本

三、变量

  在 Shell 编程中,变量是用于存储数据值的名称。我们可以使用 变量名=变量值 的方式 定义变量,然后通过 $变量名 的方式 获取变量的值。在定义变量时,变量名和等号之间不能有空格。如果变量后面不想使用的话,可以使用 unset 变量名 的方式撤销变量。如果我们要 定义只读变量,可以使用 readonly 变量名=变量值 的方式。只读变量不能使用 unset 撤销。如果我们想要变量 提升为全局变量 供给其它 Shell 程序使用,可以使用 export 变量名 的方式。

  同时,变量名的命名须遵循如下规则:

  • 只包含字母、数字和下划线:变量名可以包含字母(大小写敏感)、数字和下划线,不能包含其他特殊字符。
  • 不能以数字开头:变量名不能以数字开头,但可以包含数字。
  • 避免使用 Shell 关键字:不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
  • 避免使用空格:变量名中不应该包含空格,因为空格通常用于分隔命令和参数。

  在 Shell 中,变量值默认都是字符串,如果字符串直接包含空格,则要使用单引号或者双引号括起来。

变量的使用

  我们在使用 Shell 时,Shell 中有几个特殊字符用来处理参数:。

  • $n:在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为 $n,n 代表一个数字,0 是 执行的文件名,1 为执行脚本的第一个参数,是传入的第一个参数。2 为执行脚本的第二个参数。如果 n 大于 9,需要使用大括号括起来。
  • $#:传递到脚本的参数个数。
  • $*:以一个单字符串显示所有向脚本传递的参数。
  • $@:与 $* 相同,但是使用时加引号,并在引号中返回每个参数。
  • $?:显示最后命令的退出状态。0 表示没有错误,其它任何值表明有错误。
  • $$:脚本运行的当前进程 ID 号。
  • $-:显示 Shell 使用的当前选项,与 set 命令功能相同。
#!/bin/bashecho '---------- $n ----------'
echo $0
echo $1
echo $2
echo ${10}echo '---------- $# ----------'
echo $#echo '---------- $* ----------'
echo $*echo '---------- $@ ----------'
echo $@echo '---------- $? ----------'
echo $?echo '---------- $$ ----------'
echo $$echo '---------- $- ----------'
echo $-

特殊字符变量

四、运算符

  在 Shell 中,我们不能直接将运算式赋值给变量,这是因为变量值默认都是字符串。此时我们可以使用 $((运算式))$[运算式] 的方式赋值给变量。

运算式

五、条件判断

  我们可以使用 test 条件表达式[ 条件表达式 ] 进行条件判断。当条件表达式为真时输出 0,否则输出 1。我们还可以判断条件表达式是否为空,其中非空为真,空为假。

  常用的条件判断如下:

  • 两个整数之间的比较
    • -eq等于(equal)。
    • -ne不等于(not equal)。
    • -lt小于(less than)。
    • -le小于等于(less equal)。
    • gt大于(greater than)。
    • -ge大于等于(greater equal)。
  • 按文件权限进行判断
    • -r有读的权限(read)。
    • -w有写的权限(write)。
    • -x有执行的权限(execute)。
  • 按文件类型进行判断
    • -e文件存在(existence)。
    • -f文件存在并且是一个常规文件(file)。
    • -d文件存在并且是一个目录(directory)。

条件判断

  我们还可以进行多条件判断,其中 && 表示 前一条命令执行成功时,才执行后一条命令|| 表示 上一个命令执行失败后,才执行下一条命令

多条件判断

六、流程控制

6.1、分支结构

6.1.1、if分支结构

  我们可以使用 if 语句执行单分支结构。

if [ 条件判断式 ]; then程序
fi

  或

if [ 条件判断式 ]
then程序
fi

  如果我们要执行多分支逻辑,可以通过以下方式:

if [ 条件判断式 ]
then程序
elif [ 条件判断式 ]
then程序
else程序
fi
#!/bin/bashif [ $1 -eq 10 ]; thenecho "num == 10"
elif [ $1 -lt 10 ]
thenecho "num < 10"
elseecho "num > 10"
fi

if分支结构

6.1.2、case分支结构

  我们可以使用 case 分支结构判断变量的值是否等于某个值。

case $变量名 in
"值1")如果变量的值等于值1,则执行程序1
;;
"值2")如果变量的值等于值2,则执行程序2
;;...省略其它分支...
*)如果变量的值都不是以上的值,则执行此层序
;;
esac
#!/bin/bashcase $1 in"1")echo "the first";;"2")echo "the second";;"3")echo "the third";;*)  echo "loser";;
esac  

casse分支结构

  我们还可以使用 | 合并多个条件。

#!/bin/bashcase $1 in"0")echo "the number is 0";;"1" | "3" | "5" | "7" | "9")echo "this is an odd number less than 10";;"2" | "4" | "6" | "8")echo "this is an even number less than 10";;*)echo "this is other number";;
esac 

case合并多个条件

6.2、循环结构

6.2.1、for循环结构

  for 循环的语法格式如下:

for ((初始值;循环控制;迭代控制))
do程序
done
#!/bin/bashsum=0
for ((i = 0; i <= 10; i++)); dosum=$[$sum+$i]
doneecho $sum

  然后我们在终端中如下如下命令执行 Shell 脚本:

bash template.sh

  我们还可以使用如下语法遍历值:

for 变量 in 值1 值2 值3 ...
do程序
done
#!/bin/bashfor name in sakura mikoto shana
doecho "$name is a gril"
done

  $*$@ 都表示传递给函数或脚本的所有参数,不被双引号包含时都以 $1 $2 ... $n 的格式输出所有参数。但是如果用双引号括起来,"$*" 表示一个变量,"$@" 分为多个变量。

#!/bin/bashecho '---------- $* ----------'
for name in $*
doecho "$name is gril"
doneecho '---------- $@ ----------'
for name in $@
doecho "$name is gril"
doneecho '---------- "$*" ----------'
for name in "$*"
doecho "$name is gril"
doneecho '---------- "$@" ----------'
for name in "$@"
doecho "$name is gril"
done

特殊变量的区别

6.2.2、while循环结构

  while 循环结构的语法如下:

while [ 条件表达式 ]
do程序
done
#!/bin/bashi=1
sum=0while [ $i -le 100 ]
dosum=$[$sum+$i]i=$[$i+1]
doneecho $sum

  然后我们在终端中如下如下命令执行 Shell 脚本:

bash template.sh

七、控制台输入

  我们可以使用 read 命令读取控制台输入

read [选项] 参数

  read 命令可选的选项如下:

  • \p:指定读取值时的提示词。
  • \t:指定读取值等待的时间(单位为秒),如果 -t 不加表示一直等待。
#!/bin/bashread -t 7 -p "Pleases enter your name within 7 seconds:" nameecho "Hello $name"

控制台输入

八、函数

  在 Shell 中,我们可以自定义函数,它的格式如下:

function 函数名()
{函数体;return 函数返回值
}

  其中,function 表示是这是一个函数,可以省略。

  Shell 脚本是逐行运行的,因此在调用函数之前,必须先声明函数。Shell 脚本中,函数的返回值只能通过 $? 系统便两个获得,可以显示使用 return 函数返回值函数的返回值只能是 0 到 255 之间的数值,其中 0 表示运行成功,其它值都表示错误)的方式返回。如果不显示的返回,则将以最后一条命令运行结果作为函数返回值。

#!/bin/bashfunction sum()
{s=$[$1+$2]echo $s
}read -p "Please enter the first number:" n1
read -p "Please enter the second number:" n2sum $n1 $n2

自定义函数

九、Shell工具

9.1、cut工具

  cut 工具用来在文件中剪切数据,cut 命令从文件中每一行剪切字节、字符和字段并将这些字节、字符和字段输出。它的基本用法如下:

cut [选项] 文件名

  其中,它的选项可选值如下:

  • -f 列号:提取第几列。
  • -d 分隔符:分隔符,按照指定分隔符分割列,默认是制表符 \t
  • -c n:按字符进行切割,n 表示取第几列。

cut工具的使用

9.2、awk工具

  awk 是一个强大的文本分析工具,它把问嗯逐行的读入,以空格为默认的分隔符将每行切片,切开的部分在进行分析处理。

awk [选项] '/匹配模式/{匹配时所要执行的一系列命令}' 文件名

  其中,选项的可选值如下:

  • \F:指定输入文件的分隔符。
  • \v:赋值一个用户定义变量。

  匹配模式 如果省略,则 awk 将对所有行进行操作。匹配时所要执行的一系列命令 如果省略,则默认动作是打印整行。

awk工具的使用

  我们还可以使用 BEGIN{}END{} 在匹配时所要执行的一系列命令添加前置操作和后置操作。

awt工具中使用begin和end

  awk 还内置了一些变量,例如:

  • FILENAME:文件名。
  • NR:以读的记录数(行号)。
  • NF:浏览记录的域的个数(切割后,列的个数)。
awk -F : '{print "filename: " FILENAME ", row:" NR ", col:" NF}' /etc/passwd

awk工具使用系统变量

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven安装、配置以及Idea使用本地Maven仓库

Maven的安装和配置 Maven是Java项目常用的依赖管理和构建工具,项目使用Maven的一个特点就是包含一个pom.xml文件。实际上,Idea在安装时会集成一个Maven,这里不使用这个集成的,而是记录一下如何在机器上单独安装并配置好。 首先,需要安装好jdk。然后,到搜索引擎上搜索Mave…

DeepSeek逆天,核心是 知识蒸馏(Knowledge Distillation, KD),一项 AI 领域的关键技术

本文原文链接 文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 …

Java初学者笔记-12、前端开发基础

未完待续 Web 三个组成部分:HTML:负责网页的结构(页面元素和内容)。 CSS:负责网页的表现(页面元素的外观、位置等页面样式,如:颜色、大小等)。 Javascript:负责网页的行为(交互效果)。高级技术:基于JS封装而来的高级框架——vue。 基于vue的桌面端组件库——Eleme…

Java笔记-13、Web后端基础 Maven

Maven是一款用于管理和构建Java项目的工具,是apache旗下的一个开源项目。基于项目对象模型(POM),通过一小段描述信息管理项目构建。依赖管理:方便快捷地管理项目依赖的资源(jar包)。 项目构建:标准化的跨平台自动化项目构建方式。Maven面板中Lifecycle中的compile用于编译…

直流有刷电机.

一、基础知识回顾 1.1 电路定律 1.1.1 基尔霍夫电流定律 在集总参数电路中的任一节点处,所有支路电流的代数和在任何时刻恒等于零,即\(\sum i=0\)。 对于正弦稳态交流电路,其相量形式为\(\sum {\dot I}=0\)。 其中,当支路电路的参考方向为流入、流出节点时,支路电流分别取…

用C# GDI编写粒子效果

C#语言能不能画一动画呢?闲来无事,特过一把编程瘾。一共写了6个例子特效动画,界面如下,程序在文末供下载。拿一个粒子效果“鼓泡泡效果”的类讲解,其他类似:using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; usi…

你说得对,但是我怎么没学过后缀科技啊???

后缀数组 (SA) 后缀数组(SA,Suffix Array)最基础的应用是,可以将给定串 \(S\) 的所有后缀串排序。 一点定义:\(sa_i\) 表示第 \(i\) 小的后缀的编号,\(rk_i\) 表示后缀 \([i,n]\) 的排名。显然 \(sa_{rk[i]}=rk_{sa[i]}=i\)。 后缀数组就是 \(sa\) 数组,我们可以利用后缀…

2025.2.4 鲜花

交通网络 题解?hzoi898 交通网络 题解?Underground 是那个纯音乐啦~Ans 注意到:一个只能说真话,一个绝不说假话。这题有四样读法,你知道么?出一个毒瘤 ds 的最好方式就是把序列问题直接出到树上,考察选手树剖能力。正确的题意:给定一棵树,在时刻 \([tl, tr]\) 链加,查…

云手机和模拟器究竟有什么区别?一分钟带你理清楚

云手机和模拟器究竟有什么区别?一分钟带你理清楚概念 云手机:是在云端运行的虚拟手机,基于云计算技术和端云一体虚拟化技术,通过云服务器实现云服务。具备真实的ARM硬件,和真实手机的架构几乎一样,用户通过网络连接,在不同终端设备上远程操作,可轻松安装、管理APP。 模…

函数笔记

想了很久还是来更这个了。 0x00 一次函数 一般式 \(y=kx+b\),特殊的,当 \(b=0\),称作正比例函数。 图象 一次函数的图像是过\(\left(0,b\right)\)、\(\left( -\dfrac{b}{k},0\right)\)的直线。 而正比例函数的图像则是过原点的一条直线。 根据参数的符号,我们可以确定图象…

java基础(中)

java基础 Scanner对象Scanner类是用于获取用户输入的import java.util.Scanner;public class Hello {public static void main(String[] args){// 创建一个scanner对象来接收键盘数据Scanner scanner = new Scanner(System.in);System.out.println("Enter your name: &qu…

java基础1

java基础2 Scanner对象Scanner类是用于获取用户输入的import java.util.Scanner;public class Hello {public static void main(String[] args){// 创建一个scanner对象来接收键盘数据Scanner scanner = new Scanner(System.in);System.out.println("Enter your name: &q…