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

学会用bash在linux写脚本 (一)

本章主要介绍如何使用bash写脚本。
  • 了解通配符
  • 了解变量
  • 了解返回值和数值运算
grep的用法是“grep 关键字 file”,意思是从file中过滤出含有关键字的行。
例如,grep root /var/log/messages,意思是从/var/log/messages 中过滤出含有root
的行。这里很明确的是过滤含有“root”的行。
如果想在/var/log/messages 中过滤出含有IP地址的行呢?IP地址就是一类字符,例如,
1.1.1.1是一个IP,192.168.26.100也是一个IP,那么用什么能表示出来这一类字符呢?
不管是通配符还是正则表达式,都是为了模糊匹配,为了匹配某一类内容,而不是具体的
某个关键字。通配符一般用在shell语言中,正则表达式一般用在其他语言中。
不管是通配符还是正则表达式,主要是理解它们的元字符,然后用元字符来组合成我们想
要的那一类字符,本章主要讲解通配符的使用。
像我们平时说的张某某,这个某就是一个元字符,不是一个定值。指的是姓张,名字含有
2个字。张某某可能匹配到张二狗,也可能匹配到张阿猫,但是无法匹配到李阿三,也匹配
不了张三,因为张某某匹配的是姓名为3个字的,但是张三这个姓名只有2个字。
如果说有一个人姓“张”名“某”,那么需要匹配“张某”这个人,而不是要匹配张三、
张四,可以用张\某,某前加个“\”表示转义的意思。
22.1 通配符
通配符一般用在shell语言中,通配符中常见的元字符如下。
(1)[]:匹配一个字符,匹配的是出现在中括号中的字符。
(2)[abc]:匹配一个字符,且只能是a或b或c。
(3)[a-z]:“-”有特殊意义,表示“到”的意思,这里表示a~z,即匹配任一字母。
(4)[0-9]:表示匹配任一数字。
如果想去除含有特殊意义的字符,前面加“\”表示转义,即去除此字符的特殊意义。 (5)[a\-z]:这里的“-”就没有“到”的意思了,匹配的是“a”或“-”或“z”这三个
中的一个。
如果想表示“除了”的意思,则在第一个中括号后面加“!”或“^”。
(6)[!a-z]、[^a-z]:表示除字母外的其他字符。
(7)?:表示一个任意字符,这里强调是一个,不是0个也不是多个,但不能匹配表示隐藏
文件的点。
(8)*:表示任意多个任意字符,可以是0个,也可以是1个或多个,但不能匹配表示隐藏
文件的点。
练习:先创建目录xx并在目录中创建如下几个测试文件,命令如下。
[root@pp ~]# mkdir xx
[root@pp ~]# cd xx
[root@pp xx]# touch 1_aa aa11 Aa11 _aaa aa.txt f1aa u_12 flaa
[root@pp xx]# 
找出首字符是字母、第二个字符是数字的文件,命令如下。
[root@pp xx]# ls [a-z][0-9]*
f1aa
[root@pp xx]# 
找出首字符是字母、第二个字符不是数字的文件,命令如下。
[root@pp xx]# ls [a-z][^0-9]*
aa11  Aa11  aa.txt  flaa  u_12
[root@pp xx]# 
如果要更精确,可以用如下元字符。
(1)[[:upper:]]:纯大写。
(2)[[:lower:]]:小写。
(3)[[:alpha:]]:字母。 (4)[[:alnum:]:字母和数字。
(5)[[:digit:]]:数字。
列出首字符是小写字母、第二个字符是数字的文件,命令如下。
[root@pp xx]# ls [[:lower:]][0-9]*
f1aa
[root@pp xx]# 
列出首字符是大写字母、第二个字符是数字或字母的文件,命令如下。
[root@pp xx]# ls [[:upper:]][[:alnum:]]*
Aa11
[root@pp xx]# 

22.2 变量
所谓变量,指的是可变的值,并非具体的值。例如,我自己嘴中发出的“我”,指的是我
自己,张三嘴中发出的“我”,指的是张三,那么这个“我”就是一个变量。
变量可以分为本地变量、环境变量、位置变量和预定义变量。
22.2.1 本地变量
定义本地变量的格式如下。
1 变量名=值
定义变量有以下几点需要注意。
(1)变量名可以包含_、数字、大小写字母,但不能以数字开头。
(2)“=”两边不要有空格。
(3)“值”如果含有空格,要使用单引号''或双引号""引起来。
(4)定义变量时,变量名前是不需要加$的,引用变量时需要在变量名前加$。
本章实验都放在~/yy中练习,命令如下。
[root@pp ~]# mkdir yy ; cd yy
[root@pp yy]# 
下面开始练习定义变量,命令如下。
[root@pp yy]# 1aa=123
bash: 1aa=123: 未找到命令..
这里定义变量不正确,因为变量名不能以数字开头,这里定义变量不正确,因为变量名不能以数字开头
这里正确地定义了一个变量。
在使用本地变量时,变量名前需要加$,命令如下。
[root@pp yy]# aa=123
[root@pp yy]# echo $aa
123
[root@pp yy]# 
本地变量的特点是只能影响当前shell,不能影响子shell。
[root@pp yy]# echo $aa
123
[root@pp yy]# echo $$
3070
[root@pp yy]# 
当前shell的PID是3070。下面打开一个子shell。
[root@pp yy]# bash
[root@pp yy]# echo $$
3372
[root@pp yy]# 
这个子shell 的PID是3372。
可以看到,没有aa变量。
[root@pp yy]# echo $aa[root@pp yy]# exit
[root@pp yy]# echo $aa
123
[root@pp yy]# 
再次退回到原来的bash,又有了aa变量,情形如图
定义变量除刚才显式的定义外,还可以使用如下两
种方法。
方法1:把一个命令的结果赋值给一个变量,这个
变量要使用$()括起来,或者用反引号“引起来。这里是反引号,与波浪号~是同--个键,不是
单引号。
例如,定义一个名称是ip的变量,对应的值是ens160的IP,命令如下。
[root@pp yy]# ip=$(ifconfig ens160 | awk '/inet /{print $2}')
[root@pp yy]# echo $ip
192.168.248.45
[root@pp yy]# 
方法2:通过read命令来获取变量。
read的用法如下。
1 read ‐p "提示信息" 变量
当遇到read命令时,系统会等待用户输入,用户所输入的值会赋值给read后面的变量,
命令如下。
[root@pp yy]# read -p "请输入你的名字" aa
请输入你的名字iu
[root@pp yy]# echo $aa
iu
[root@pp yy]# 
当执行read这条命令时,系统会提示用户输人一些内容,所输入的内容会赋值给aa变
量。这里我们输入的是 tom,所以打印aa变量时,看到的值是tom。
这样的用法比较适合写需要和用户交互的脚本。
22.2.2 环境变量
定义环境变量的注意点和本地变量是一样的。在定义环境变量时,前面加上export 即可,
命令如下。
[root@pp yy]# export bb=123
[root@pp yy]# 
要想查看所有的环境变量,可以执行env命令。
环境变量的特点是可以影响子shell,这里强调的是子shell,不能影响父shell。
[root@pp yy]# echo $$
3070
[root@pp yy]# echo $bb
123
[root@pp yy]# 
当前shell的PID是3828,里面有一个环境变量 bb。
[root@pp yy]#  bash
[root@pp yy]# echo $$
3828
[root@pp yy]# echo $bb
123
[root@pp yy]# 
打开一个子shell,里面可以看到bb变量的值,说明环境变量已经影响到
子shell 了。
在子 shell中重新给bb赋值为456,然后退回到父shell。
[root@pp yy]# export bb=456
[root@pp yy]# exit
exit
[root@pp yy]# echo $bb
123
[root@pp yy]# 
可以看到,在父shell 中,bb的值仍然是123,说明在子shell 中定义的变量不会影响到父
shell,如图22-2所示。
系统中默认已经存在很多个变量,如下所示。
(1)UID:表示当前用户的uid。
(2)USER:表示当前用户名。
(3)HOME:表示当前用户的家目录。 分别显示这些变量的值,命令如下。
[root@pp yy]# echo $UID
0
[root@pp yy]# echo $USER
root
[root@pp yy]# 
22.2.3 位置变量和预定义变量
运行脚本时,有时后面是需要加上参数的。但是我们在写脚本时并不能预知后期在脚本后
面跟上什么参数,这时就能用到位置变量了,位置变量如下。
$0:表示脚本的名称。
$1:表示第1个参数。
$2:表示第2个参数。
...... ${10}:表示第10个参数。
......
这里$后面的数字如果不是个位数,则要用{}括起来。
系统中还内置了一些预定义变量。
$#:表示参数的个数。
$*:表示所有的参数。
例1:写一个带参数的脚本,内容如下。
[root@pp yy]# cat scl.yaml 
#/bin/bash
echo "这是我第一个脚本,脚本名称是 $0"
echo "第 1 个参数是:$1"
echo "第 2 个参数是:$2"
echo "第 3 个参数是:$3"
echo "此脚本一共有 $# 个参数,它们分别是:$*"
[root@pp yy]# 
给这个脚本加上可执行权限,并加参数运行,命令如下。
[root@pp yy]# chmod +x scl.yaml 
[root@pp yy]# ./scl.yaml tom bob mary
这是我第一个脚本,脚本名称是 ./scl.yaml
第 1 个参数是:tom
第 2 个参数是:bob
第 3 个参数是:mary
此脚本一共有 3 个参数,它们分别是:tom bob mary
[root@pp yy]# 
运行这个脚本时,共指定了3个参数:tom、bob、mary,它们分别赋值给了
$1、$2、$3。这里S#被自动赋值为3,因为总共有3个参数,所有的参数被赋值给$*。
22.3 返回值
执行某命令之后,结果不是正确的就是错误的。命令正确执行了,返回值为0,如果没有
正确执行则返回值为非零。返回值为非零,不一定是语法错误,执行结果如果有“否定”的
意思,返回值也为非零。例如, ping 192.168.26.3,语法没有错误,但是没有ping通,返回值
也为非零。
返回值记录在$?中,且$?只记录刚刚执行过命令的返回值。因为$?的值会被新执行命令
的返回值覆盖。
练习:先执行一个 xxx命令,命令如下。
[root@pp yy]# xxx
bash: xxx: 未找到命令...
[root@pp yy]# echo $?
127
[root@pp yy]# echo $?
0
[root@pp yy]# 
先执行一个xxx命令,这个命令是错误的命令,$?记录的是刚刚执行过xxx命令的返回值。
所以,查看$?的值是127,是一个非零的值。再次查看$?的值时,却变成了0,因为这个$?
记录的不再是xxx命令的返回值,而是它前面执行过的echo $?命令的返回值。 逻辑上“否定”的意思也是可以体现出来的。例如,下面的例子。
[root@pp yy]# grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@pp yy]# echo $?
0
[root@pp yy]# 
这里在/etc/passwd过滤行开头为root的行,结果找到了,所以返回值为0。
[root@pp yy]# grep ^rootxxx /etc/passwd
[root@pp yy]# echo $?
1
[root@pp yy]# 
这里在/etc/passwd过滤行开头为rootxxx的行,结果没有找到,即使语法没有错误,但
是逻辑上有“否定”的意思,所以返回值为非零。
22.4数值运算
在写脚本时,有时我们经常要做一些数学运算。数学运算的符号如下。
(1)+:表示加。
(2)-:表示减。
(3)*:表示乘。
(4)/:表示除。
(5)**:表示次方。
进行数学运算的表达式有$(())、$[]、let等,命令如下。
[root@pp yy]# echo $((2+3))
5
[root@pp yy]# 
其中$(O)和$[]的用法是一样的,如果不用这样的表达式,看如下代码。
[root@pp yy]# echo 2**3
2**3
[root@pp yy]# 
可以实现定义aa为整数类型,然后再做数学运算,命令如下。
[root@pp yy]# declare -i aa
[root@pp yy]# aa=1+2
[root@pp yy]# echo $aa
3
[root@pp yy]# 
首先declare -i aa把aa定义为一个整数,所以1+2等于3,然后赋值给aa.所以aa的值为3。
以上表达式不能求得小数,如果要得到小数需要使用 bc 命令,用法如下。
1 echo "scale=N ; 算法 | bc"
这里N是一个数字,表示小数点后面保留几位。
计算2/3,小数点后面保留3位,命令如下。
[root@pp yy]# echo "scale=3 ; 2/3" | bc
.666
[root@pp yy]# 
这里得到的结果是0.666,整数部分的0没有显示。
计算7/6,小数点后面保留3位,命令如下。
[root@pp yy]# echo "scale=3 ; 7/6" | bc
1.166
[root@pp yy]# 

相关文章:

学会用bash在linux写脚本 (一)

本章主要介绍如何使用bash写脚本。 了解通配符 了解变量 了解返回值和数值运算 grep的用法是“grep 关键字 file”,意思是从file中过滤出含有关键字的行。 例如,grep root /var/log/messages,意思是从/var/log/messages 中过滤出含有root …...

Leetcode 2949. Count Beautiful Substrings II

Leetcode 2949. Count Beautiful Substrings II 1. 解题思路2. 代码实现 Leetcode 2949. Count Beautiful Substrings II 1. 解题思路 这一题真的很丢脸,居然没有搞定,是看了大佬们的思路之后才想明白的,就感觉丢脸丢大了…… 这道题讲道…...

【Python系列】Python函数

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

自定义TypeHandler 将mysql返回的逗号分隔的String转换到List

sql执行如下&#xff1a; 这里我定义的接受类&#xff1a; 但是这里报了错JSON parse error: Cannot deserialize value of type java.util.ArrayList<java.lang.String>from Object value (token JsonToken.START_OBJECT); nested exception is com.fasterxml.jackson…...

Spring 高级装配详解

一、环境与profile ​ 在3.1版本中&#xff0c;Spring引入了bean profile的功能。要使用profile&#xff0c;首先要将所有不同的bean定义整理到一个或者多个pofile之中&#xff0c;再将应用部署到每个环境时&#xff0c;确保对应的profile处于激活状态。 在Java配置中&#xf…...

mapbox Marker添加自定义html

思路就是先渲染出空div使用getElementsByClassName找到点&#xff0c;之后使用insertAdjacentHTML(‘beforeend’, div) 加自定义内容。 const el document.createElement(div);// 添加一个标记el.className j_icon;const itemIcon new MapboxGl.Marker({element: el,}).set…...

Linux UUCP命令教程:如何在Linux系统中进行文件复制(附实例详解和注意事项)

Linux UUCP命令介绍 UUCP&#xff08;Unix-to-Unix Copy&#xff09;是一套允许远程执行命令和传输文件的程序。UUCP命令是该套件中的一个程序&#xff0c;它为请求文件复制操作提供了用户界面。UUCP套件还包括uux&#xff08;远程命令执行的用户界面&#xff09;、uucico&…...

【android开发-21】android中调用系统摄像头camera拍照和相册的用法详解

1&#xff0c;调用摄像头 在Android中&#xff0c;调用系统摄像头拍照需要使用Intent来启动Camera应用&#xff0c;并在应用中设置相应的权限。下面是一个简单的例子&#xff1a; // 创建一个Intent对象&#xff0c;指定要执行的动作是拍照 Intent intent new Intent(Medi…...

最新版本——Hadoop3.3.6单机版完全部署指南

大家好&#xff0c;我是独孤风&#xff0c;大数据流动的作者。 本文基于最新的 Hadoop 3.3.6 的版本编写&#xff0c;带大家通过单机版充分了解 Apache Hadoop 的使用。本文更强调实践&#xff0c;实践是大数据学习的重要环节&#xff0c;也能在实践中对该技术有更深的理解&…...

理解自我效能感:你的内在动力来源

1. 自我效能感&#xff1a;开启个人潜能的心理动力 想象一下&#xff0c;面对生活的挑战和机遇时&#xff0c;是什么内在力量驱使你去采取行动&#xff0c;或者让你犹豫不决&#xff1f;这种力量&#xff0c;与我们的心理状态紧密相关&#xff0c;其中一个关键因素就是我们的自…...

Java第二十一章

一.网络程序设计基础 1.网络协议 网络协议规定了计算机之间连接的物理、机械(网线与网卡的连接规定)、电气(有效的电平范围)等特征&#xff0c;计算机之间的相互寻址规则&#xff0c;数据发送冲突的解决方式&#xff0c;长数据如何分段传送与接收等内容.就像不同的国家有不同的…...

Redis交互速度慢,CPU占用100%,集群方案,报错等问题

Redis交互速度很慢&#xff0c;达到几十到一百毫秒一次 问题描述&#xff1a; 执行top命令发现redis占用达到100% redis交互速度慢&#xff0c;一次要几十到一百毫秒一次 解决思路 查看redis数据量&#xff0c;比如我这里达到了30万 经过本地测试&#xff0c;redis交互的速…...

wpf 系统在显示器分辨率和缩放设置为非1920*1080和100%时,SelectionChanged事件响应问题分析?

系统在显示器分辨率和缩放设置为1920*1080和100%时&#xff0c;窗口四分格能正常响应SelectionChanged事件&#xff0c;但是当缩放为125%时&#xff0c;或是分辨率大于1920*1080时四分格其中一个格子的下侧和右侧点击不响应&#xff0c;什么原因&#xff1f; 描述的问题可能由以…...

刷题记录--算法--简单

第一题 2582. 递枕头 已解答 简单 相关标签 相关企业 提示 n 个人站成一排&#xff0c;按从 1 到 n 编号。 最初&#xff0c;排在队首的第一个人拿着一个枕头。每秒钟&#xff0c;拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾&#xff0c;传递…...

条码生成器与Zint使用

文章目录 目的条形码zint支持条形码种类下载编译qt pro配置code保存条形码目的 1: 了解条形码数据理论知识 2: 了解zint第三方库相关, 如何编译引用到项目中 条形码 条形码(Barcode)一维码 和二维码(QR code)都是用于存储信息的图形化表示方式,通常应用于商品标识、库…...

C#winform上下班打卡系统Demo

C# winform上下班打卡系统Demo 系统效果如图所示 7个label控件(lblUsername、lblLoggedInEmployeeId、lab_IP、lblCheckOutTime、lblCheckInTime、lab_starttime、lab_endtime)、3个按钮、1个dataGridView控件、2个groupBox控件 C#代码实现 using System; using System.Dat…...

P1 Qt的认识及环境配置

目录 前言 01 下载Qt Creator windows下载安装包拷贝到Linux Linux直接下载 02 Linux 安装Qt 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类…...

单元测试Nunit的几种断言

Nunit提供了一些辅助函数用于确定好某个被测试函数是否正常工作。通常把这些函数称为断言 断言是单元测试最基本的组成部分。因此&#xff0c;NUnit程序库以Assert类的静态方法的形式提供了不同形式的多种断言 1. Assert.AreEqual&#xff1a;比较两个值是否相等。用于比较数…...

前端中的响应式布局与各个端适配

什么是响应式布局&#xff1f; 响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局。在移动互联网高度发达的今天&#xff0c;我们在桌面浏览器上开发的网页已经无法满足在移动设备上查看的需求。传统的开发方式是PC端开发一套页面&#xff0c;手机端再开发一套页面。但是…...

2023年5个自动化EDA库推荐

EDA或探索性数据分析是一项耗时的工作&#xff0c;但是由于EDA是不可避免的&#xff0c;所以Python出现了很多自动化库来减少执行分析所需的时间。EDA的主要目标不是制作花哨的图形或创建彩色的图形&#xff0c;而是获得对数据集的理解&#xff0c;并获得对变量之间的分布和相关…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...