命令行之巅: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 个优势:首先,编写简单的工具脚本对前端工程师来说额外的学习成本很低甚至可以忽略不计,其…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
