命令行之巅:Linux Shell编程的至高艺术(上)
文章一览
- 前言
- 一、shell概述
- 1.1 shell的特点和类型
- 1.1.1 **shell的特点:**
- 1.1.2 常用shell类型
- 1.2 shell脚本的建立和执行
- 1.2.1 建立shell脚本
- 1.2.2 执行shell脚本的方式
- 1.2.3 shell程序实例
- 二、shell变量与算数运算
- 2.1 简单shell变量
- 2.1.1 简单变量定义和赋值
- 2.1.2 引用变量值
- 2.1.3 删除变量
- 2.2 数组
- 2.3 位置参数
- 2.3.1 位置参数
- 2.3.2 shift命令
- 2.3.3 用set命令为位置参数赋值
- 2.4 预先定义的特殊变量
- 2.5 环境变量
- 2.6 运算
- 2.6.1 let命令
- 2.6.2 运算符及其优先级和结合性
- 2.6.3 关系运算符
- 2.6.4 算数运算符
- 2.6.5 布尔运算符
- 2.6.6 逻辑运算符
- 2.6.7 字符串运算符
- 获取字符串长度
- 2.6.8 文件测试运算符
前言
在浩瀚的数字世界中,Linux以其坚不可摧的内核和无限的可能性,成为了开发者和系统管理员的挚爱。而在这个由代码编织的宇宙里,Shell程序就像是一把钥匙,能够解锁Linux操作系统的无尽潜能。今天,我们将一同探索Linux中的shell程序设计,这是一段既充满挑战又令人兴奋的旅程。
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。
实际上Shell是一个命令解释器, 它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。 Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。
本篇文章将介绍什么是shell以及shell的中的变量运算。
一、shell概述
1.1 shell的特点和类型
1.1.1 shell的特点:
- 组合新命令很简单;
- 提供了文件名扩展字符;
- 可以直接使用shell的内置命令 ;
- 允许灵活地使用数据流 ;
- 结构化的程序模块 ;
- 提供了在后台(&)执行命令 ;
- 提供了可配置的环境;
- 提供了一个高级的命令语言 。
1.1.2 常用shell类型
- Bourne shell(简称sh)
- C—shell(简称csh)
- Korn shell(简称ksh)
- Bourne Again shell(简称bash)
1.2 shell脚本的建立和执行
1.2.1 建立shell脚本
建立shell脚本的步骤同建立普通文本文件的方式相同,如:
vi ex1
1.2.2 执行shell脚本的方式
执行shell脚本的常用方式基本上有两种:
(1)以脚本名作为参数。其一般形式是:
$ bash 脚本名 [参数]
$ · 脚本名 [参数]
(2)将shell脚本的权限设置为可执行,然后在提示符下直接执行它。
$ chmod a+x ex2
$ PATH=$PATH:•
$ ex2 或者 $ •/ex2
1.2.3 shell程序实例
注意,一定要写成 ./test.sh
,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin
等在 PATH 里,我们的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要使用 ./test.sh 告诉系统在当前目录寻找。
二、shell变量与算数运算
2.1 简单shell变量
2.1.1 简单变量定义和赋值
变量名=字符串
注意:在赋值号“=”的两边没有空格 , 例如:
myfile=/home/cieeqc/ff/m1.c
变量名以字母或下线符打头的字母、数字和下线符序列,大小写字母意义不同。
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
2.1.2 引用变量值
- 在程序中引用变量值时,要在变量名前面加上一个“$”符号。
$ dir=/home/ciee/ff
$ echo $dir
/home/ciee/ff (显示变量dir的值)
$ echo dir
dir (显示一般的字符串常量dir)
$ echo $Dir
(显示一个空串)
$
- 如果在赋给变量的值中含有空格、制表符或换行符,那么,就应该用双引号把这个字符串括起来。
应注意的情况:
-
-
$ dir=/home/ci $ cat ${dir}ee/file1.c #将把文件/home/ciee/m1.c显示出来 3 而 $ cat $dirqc/file1.c #系统会给出错误信息
-
$ dir1=/home/ciee/ff/prog $ ls $dir1 $ cat $dir1/exam.c
- 变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java; doecho "I am good at ${skill}Script"
done
如果不给skill变量加花括号,写成echo “I am good at $skillScript”,解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
2.1.3 删除变量
使用 unset 命令可以删除变量。语法:
使用 unset 命令可以删除变量。语法:
变量被删除后不能再次使用。unset 命令不能删除只读变量
#!/bin/sh
myUrl="http://www.ipieuvre.com"
unset myUrl
echo $myUrl
以上实例执行后将没有任何输出。
2.2 数组
Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
与大部分编程语言类似,数组元素的下标由0开始。
- 对数组元素赋值的一般形式是:
数组名[下标]=值
$ city[0]=Beijing
$ city[1]=Shanghai
$ city[2]=Tianjin
-
用declare命令显式声明一个数组,一般形式是:
declare -a
-
数组名读取数组元素值的一般格式是:
${数组名[下标]}
例如:$ echo ${city[0]}
-
数组初始化的一般形式是:
数组名=(值1 值2 … 值n) $ A=(this is an example of shell script)
$ A=(this is an example of shell script)
$ echo ${A[0]} ${A[2]} ${A[3]} ${A[6]}
this an example script
$ echo ${A[8]}
(A[8]超出了数组A的范围,所以它的值是空串。)
$ ▌
使用*或@作为下标,则表示数组中所有元素。
2.3 位置参数
2.3.1 位置参数
exam m1 m2 m3 m4$0 $1 $2 $3 $4 $5 $6 $7 $8 $6 ${10} ${11}
这种变量不能用赋值语句直接赋值,只能通过命令行上对应位置的实参传值。
$0始终表示命令名或shell脚本名。
2.3.2 shift命令
用shift命令移动位置参数
$0
:脚本的名称。$1
到$9
:传递给脚本的第一个到第九个参数。$#
:传递给脚本的参数总数。$*
和$@
:所有的位置参数,区别在于,$*
会将所有参数视为一个整体,而$@
会将每个参数视为独立的元素,这在循环遍历参数时非常有用。
示例:
假设你有一个名为 script.sh
的脚本,并且你通过以下命令调用它:
shell
./script.sh arg1 arg2 arg3
在这个例子中,arg1
、arg2
和 arg3
是传递给脚本的位置参数。在脚本内部,你可以这样访问它们:
$1
的值是arg1
。$2
的值是arg2
。$3
的值是arg3
。$#
的值是3
,因为有3个参数。$*
的值是arg1 arg2 arg3
,所有参数作为一个整体。$@
的值是arg1 arg2 arg3
,每个参数作为独立的元素。
以下是如何在脚本中使用这些位置参数的一个简单示例:
#!/bin/bash# 打印脚本名称
echo "Script name: $0"# 循环遍历所有参数
echo "Looping through all arguments:"
for arg in "$@"; doecho "Argument: $arg"
done# 打印参数总数
echo "Total number of arguments: $#"# 打印所有参数作为一个整体
echo "All arguments as a whole: $*"
2.3.3 用set命令为位置参数赋值
$ cat exam4
#!/bin/bash
# exam4: shell script to combine files and count lines
# using command set to set positional parameters
set file1.c file2.c
cat $1 $2 $3 | wc -l
# end
$ exam4
????
$ ▌
2.4 预先定义的特殊变量
⑴$#——除脚本名外,命令行上参数的个数。
⑵$?——上一条前台命令执行后的返回值(也称“退出码”等)。 0表示没有错误,其他任何值表示有错误。
⑶$$——当前进程的进程号(ID号)。
⑷$!——上一个后台命令对应的进程号。
⑸$*——表示在命令行上实际给出的所有实参。如输入下面的命令行:
exam3 A B C D E F G H I J K
# 则$* 就是:A B C D E F G H I J K
#而“$*”就等价于:
#"$1 $2 $3……",即:" A B C D E F G H I J K"。
⑹$@——它与$基本功能相同。但“$@”与“$”不同。
“$@”就等价于: “$1” “$2”……,在上面情况下,就是"A" “B” “C”……“K”。
(7) $- 显示shell的当前选项,与set
命令功能相同
2.5 环境变量
(1)HOME:用户主目录的全路径名。如/home/myname
(2)LOGNAME:即用户注册名
(3)PWD:当前工作目录的路径。
(4)PATH:shell查找命令的路径(目录)列表,各个目录用冒号(:)隔开。
#用户可以设置它:
$ PATH=$PATH:$PWD
(5)PS1:shell的主提示符。 \$ PS1="$LOGNAME> "
(6)SHELL:当前使用的shell。通常,它的值是/bin/bash。
-
可以用env命令列出当前环境下的所有环境变量及其值,也可用echo命令察看任何一个环境变量的值。
-
当更改了环境变量的值以后,往往利用export命令将这些变量输出,使它们成为公用量。例如:
$ export HOME PATH PS1
2.6 运算
2.6.1 let命令
bash中执行整数算术运算的命令是let,其语法格式为: let arg …
其中,arg是单独的使用C语言语法的算术表达式。如 let "j=i6+2" let 命令的替代表示形式是: ((算术表达式)) 如 ((j=i6+2))
2.6.2 运算符及其优先级和结合性
其运算符及其优先级和结合性基本上与C语言的相同。
当表达式中有shell的特殊字符时,必须用双引号将其括起来。例如,let “val=a|b”
。只有使用**$((算术表达式))**形式才能返回表达式的值,例如 :
$ echo "((12*9))"
((12*9))
$ echo "$((12*9))"
108
2.6.3 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
2.6.4 算数运算符
注意:条件表达式要放在方括号之间,并且要有空格,例如: [ a = = a== a==b] 是错误的,必须写成 [ $a == $b ]。
2.6.5 布尔运算符
2.6.6 逻辑运算符
2.6.7 字符串运算符
获取字符串长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
2.6.8 文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
其他检查符:
-S: 判断某文件是否 socket。
-L: 检测文件是否存在并且是一个符号链接。
eg:变量 file 表示文件shellf.sh,它的大小为 100 字节,具有 rwx 权限。
相关文章:

命令行之巅:Linux Shell编程的至高艺术(上)
文章一览 前言一、shell概述1.1 shell的特点和类型1.1.1 **shell的特点:**1.1.2 常用shell类型 1.2 shell脚本的建立和执行1.2.1 建立shell脚本1.2.2 执行shell脚本的方式1.2.3 shell程序实例 二、shell变量与算数运算2.1 简单shell变量2.1.1 简单变量定义和赋值2.1…...
【gulp】gulp 的基本使用
gulp 是一个基于node的自动化打包构建工具,前端开发者可以使用它来处理常见任务: 创建项目 进入项目 npm init -ynpm i gulp -g (使用命令 gulp)npm i gulp -D # 开发依赖(前端工具都是开发依赖 本地安装 代…...
Linux 下处理 ^M 字符的最佳实践
Linux 下处理 ^M 字符的最佳实践 一、快速解决方案 按照优先级排序的三种解决方案: 1. 使用 dos2unix(推荐) # 安装 sudo apt-get install dos2unix # Ubuntu/Debian sudo yum install dos2unix # CentOS# 使用 dos2unix 文件名2. 使用 sed sed...

【优选算法】—复写零(双指针算法)
云边有个稻草人-CSDN博客 每天至少一道算法题,接着干,以额现在的实力想完成那个目标确实难。算法题确实烧脑,挺煎熬的,但脑子烧多了是不是就该好些了?。。。 记得那句话,必须有为成功付出代价的决心&#x…...
2024国赛A问题三和四
问题三 最小螺距单目标优化模型的建立 问题二考虑了在螺距固定的条件下计算舞龙队盘入的终止时间,问题三在第二问的基础提出了改变螺距的要求,即求解在螺距最小为多少时,龙头前把手能够沿着相应的螺线盘入到调头空间的边界。故可将其转换为…...

asp.net 高校学生勤工俭学系统设计与实现
博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…...

《计算机组成及汇编语言原理》阅读笔记:p116-p120
《计算机组成及汇编语言原理》学习第 7 天,p116-p120 总结,总计 5 页。 一、技术总结 1.CPU优化 (1)increase overall performance number 例如:16位电脑提升到32位电脑。 (2)multiprocessing One way to make computers more useful i…...

C# OpenCvSharp DNN 卡证检测矫正
目录 说明 效果 模型 项目 代码 下载 参考 说明 源码地址:https://modelscope.cn/models/iic/cv_resnet_carddetection_scrfd34gkps 在实人认证、文档电子化等场景中需要自动化提取卡证的信息,以便进一步做录入处理。这类场景通常存在两类问题&…...
Spring Boot 中 Map 的最佳实践
在Spring Boot中使用Map时,请遵循以下最佳实践: 1.避免在Controller中 直接使用Map。应该使用RequestBody 接收-个DTO对象或者 RequestParam接收参数,然后在Service中处 理Map。 2.避免在Service中 直接使用原始的Map。应该使用Autowired 注入-个专门…...
J-LangChain - 智能链构建
介绍 j-langchain是一个Java版的LangChain开发框架,旨在简化和加速各类大模型应用在Java平台的落地开发。它提供了一组实用的工具和类,使得开发人员能够更轻松地构建类似于LangChain的Java应用程序。 依赖 Maven <dependency><groupId>i…...

开源低代码平台-Microi吾码 打印引擎使用
引言 在开发中,会遇到很多记录的表单数据需要下载打印下来使用到线下各种应用场景中。在传统的方法中可能是需要先导出数据,然后将数据填入word表格中在打印下来。 但Microi吾码提供了一项新功能,便是打印引擎。打印引擎即可在线设计…...

【MySQL】索引 面试题
文章目录 适合创建索引的情况创建索引的注意事项MySQL中不适合创建索引的情况索引失效的常见情况 索引定义与作用 索引是帮助MySQL高效获取数据的有序数据结构,通过维护特定查找算法的数据结构(如B树),以某种方式引用数据…...

【高阶数据结构】AVL树
AVL树 1.AVL的概念2.AVL树的实现1.AVL树的结构2.AVL树的插入1.更新平衡因子2.旋转1.右单旋2.左单旋3.左右双旋4.右左双旋 3.AVL树的查找4.AVL树的平衡检测5.AVL树的性能分析6.AVL树的删除 3.总代码1.AVLTree.h2.Test.cpp 1.AVL的概念 AVL树是最先发明的自平衡⼆叉查找树&#…...
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
Spring框架是一个非常流行的应用程序框架,它通过控制反转(IoC)和依赖注入(DI)来简化企业级应用的开发。Spring容器是其核心部分,负责管理对象的创建、配置和生命周期。在Spring中,XML配置是一种…...
docker mysql5.7安装
一.更改 /etc/docker/daemon.json sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","https://docker.m.daocloud.io","https:/…...

HDR视频技术之十一:HEVCH.265 的 HDR 编码方案
前文我们对 HEVC 的 HDR 编码优化技术做了介绍,侧重编码性能的提升。 本章主要阐述 HEVC 中 HDR/WCG 相关的整体编码方案, 包括不同应用场景下的 HEVC 扩展编码技术。 1 背景 HDR 信号一般意味着使用更多比特,一般的 HDR 信号倾向于使用 10…...

最新的强大的文生视频模型Pyramid Flow 论文阅读及复现
《PYRAMIDAL FLOW MATCHING FOR EFFICIENT VIDEO GENERATIVE MODELING》 论文地址:2410.05954https://arxiv.org/pdf/2410.05954 项目地址: jy0205/Pyramid-Flow: 用于高效视频生成建模的金字塔流匹配代码https://github.com/jy0205/Pyram…...
Effective C++ 条款 11:在 `operator=` 中处理“自我赋值”
文章目录 条款 11:在 operator 中处理“自我赋值”核心问题示例:使用地址比较示例:copy-and-swap 技术设计建议总结 条款 11:在 operator 中处理“自我赋值” 核心问题 自我赋值风险 如果赋值操作符没有处理自我赋值(…...

19、鸿蒙学习——配置HDC命令 环境变量
一、下载Command Line Tools 可参考上篇《鸿蒙学习——配置OHPM、hvigor环境变量》 二、配置hdc环境变量 hdc命令行工具用于HarmonyOS应用/元服务调试所需的工具,该工具存放在命令行工具自带的sdk下的toolchains目录中。为方便使用hdc命令行工具,请将…...

初始 ShellJS:一个 Node.js 命令行工具集合
一. 前言 Node.js 丰富的生态能赋予我们更强的能力,对于前端工程师来说,使用 Node.js 来编写复杂的 npm script 具有明显的 2 个优势:首先,编写简单的工具脚本对前端工程师来说额外的学习成本很低甚至可以忽略不计,其…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...