Linux学习(四)Shell编程

  • Shell概述
  • Shell脚本入门
  • 变量
    • 系统预定义变量
    • 自定义变量
    • 特殊变量
  • 运算符
  • 条件判断
  • 流程控制(重点)
    • if判断
    • case语句
    • for循环
    • while循环
  • read读取控制台输入(附$()命令替换 )
  • 函数
    • 系统函数
    • 自定义函数
  • 正则表达式匹配
  • 文本处理工具
    • cut
    • awk

Shell概述

Shell是一个命令行解释器,它能接收应用程序/用户命令,然后调用操作系统内核。
同时Shell还是一门功能相当强大的编程语言,易编写、易调试、灵活性强。

  • Linux 提供的Shell解析器如下:

  • bash和sh的关系

  • Centos默认的解析器是bash

Shell脚本入门

  • 脚本格式

脚本以#!/bin/bash开头(指定解析器)

  • 第一个Shell脚本:helloworld.sh

需求:创建一个Shell脚本,输出helloworld

案例实操:

在helloworld.sh中第一行输入#!/bin/bash,第二行输入echo "hello,world"

脚本的常用执行方式

第一种:采用bash或者sh加上脚本的绝对路径或者相对路径
使用命令 sh 脚本绝对路径

使用命令sh 脚本相对路径

使用命令bash 脚本绝对路径

使用命令bash 脚本相对路径

第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
使用相对路径

使用绝对路径

注意:第一种执行方法,本质上是bash解释器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。

第三种:在脚本路径前加上" . " 或者 source
使用绝对路径

使用相对路径

前两种方式都是在当前 shell 中打开一个子 shell 来执行脚本内容,当脚本内容结束,则子 shell 关闭,回到父 shell 中。
第三种,也就是使用在脚本路径前加“.”或者 source 的方式,可以使脚本内容在当前shell 里执行,而无需打开子 shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需要 source 一下的原因。
开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子shell 中设置的当前变量,父 shell 是不可见的。

变量

变量存放在内存中,随着变量个数的增加所占用的内存就越大。可以使用unset 变量名删除变量。
当终端关闭时,由于变量存放在内存中,当前终端下自定义变量也会被删除。

系统预定义变量

  • 常用系统变量

$HOME、$PWD、$SHELL、$USER等等

  • 案例实操

使用命令echo $USER查看系统变量的值

使用命令set显示当前Shell中所有变量


使用命令env查看当前Shell中的系统全局变量

使用命令printenv 环境变量名称 查看环境变量。如果不加环境变量名称效果和env一样。

自定义变量

  • 基本语法

定义变量:变量名=变量值,注意:等号=前后不能有空格
撤销变量:unset 变量名
申明静态变量:readonly 变量,注意:不能unset

  • 变量定义规则

1.变量名可以由字母、数字和下划线组成,但不能以数字开头,环境变量名建议大写。
2.等号两侧不能有空格
3.在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
4.变量的值如果有空格,需要使用双引号或者单引号括起来

  • 案例实操

1.定义变量A

2.给变量A重新赋值

3.撤销变量A

申明readonly变量B=2,不能被unset

在bash中,变量默认类型都是字符串类型,无法直接进行数值运算

变量的值如果有空格,需要使用双引号或单引号括起来

可以把局部变量提升为全局环境变量,可供其他Shell程序使用

在helloworld.sh文件中增加echo $B
将变量B提升为全局环境变量然后运行helloworld.sh文件

特殊变量

  • $n

基本语法
$n 功能描述,n为数字,$0代表该脚本的名称,$1-$9代表第一个到第九个参数,两位数以上的参数,需要用大括号括起来,比如 ${15}表示第十五个参数。

案例实操
使用命令vim helloworld.sh编辑脚本内容如下:

#!/bin/bash
echo "hello,wolrd"
echo $B
echo '#######$n的使用#######'
echo $0
echo $1
echo $2

执行脚本,查看结果

  • $#

基本语法
$# 可以获取输入参数的个数,擦汗给你用于循环,判断参数的个数是否正确以及加强脚本的健壮性。

案例实操

  • $*$@

基本语法
$* 这个变量代表命令行中所有的参数,它把所有变量看作一个整体
$@ 这个变量也是代表命令行中的所有的参数,不过它把每个参数分开对待。

案例实操

  • $?

基本语法
$? 是最后一次执行命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0,则证明上一条命令执行出错。

案例实操

运算符

基本语法
使用命令$((运算式))或者$[运算式]

案例实操
计算(2+3)*4

条件判断

基本语法
使用命令test 条件 或者 [ 条件 ]
注意:1.中括号和条件之间一定要有空格!!!2.条件非空即为true ,比如[ itheima ]返回为true,[ ]返回为false

常用判断条件

  • 两个整数之间的比较
参数 含义
-eq 等于
-lt 小于
-gt 大于
-ue 不等于
-le 小于等于
-ge 大于等于
  • 按照文件权限进行判断
参数 含义
-r 有读的权限
-w 有写的权限
-x 有执行的权限
  • 按照文件类型进行判断
参数 含义
-e 文件存在
-f 文件存在并且是一个常规的文件
-d 文件存在并且是一个目录

案例实操

  1. 23是否大于等于22

  2. helloworld.sh是否具有写权限

  3. /home/atguigu/目录是否存在

  4. 多条件判断(短路与和短路或,可以实现类似java中的三元表达式)

流程控制(重点)

if判断

基本语法

1.单分支

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

或者

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

2.多分枝

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

案例实操
输入一个数字,如果是1,则输出:1! 5!;如果是2,则输出:L!T!C!;既不是1也不是2则输出:理塘猛虎!

if [ $1 -eq 1 ]
thenecho -e "1!\t5!"
elif [ $1 -eq 2 ]
thenecho -e "L!T!C!"
elseecho "理塘最强猛虎"
fi

case语句

基本语法

case $变量名 in
"值1")如果变量的值等于值1,执行该部分
;;
"值2")如果变量的值等于值2,执行该部分
;;
*)如果变量的值都不是以上的值,则执行此部分
;;
esac

注意事项:
1.case行尾必须为单词in,每一个模式匹配必须以右括号)结束。
2.双分号::表示命令序列化结束,相当于java中的break
3.最后的*)表示默认情况,相当于java中的default

案例实操
输入一个数字,如果是1,则输出:1! 5!;如果是2,则输出:L!T!C!;既不是1也不是2则输出:理塘最强猛虎!

for循环

基本语法1

for (( 初始值;循环控制条件;变量变化 ))
do 程序
done

案例实操
从1加到100

sum=0
for ((i=1;i<=100;i++))
dosum=$[$sum+$i]
done
echo $sum


基本语法2

for 变量 in 值1 值2 值3...
do程序
done

案例实操
打印所有输入的参数

for i in $1 $2 $3
doecho $i
done


比较$*$@的区别

当它们(指$*$@)不被双引号包括时:
两者没有区别。

当它们(指$*$@)被双引号包括时:
$* 会将所有的参数作为一个整体,如果使用for循环来循环参数,只会执行一次。
$@会将每个参数当成是独立的个体,如果使用for循环,那么循环的次数会等于参数个数。

while循环

基本语法

while [ 条件判断式 ]
do程序
done

案例实操
从1加到100

i=1
sum=0
while [ $i -le 100 ]
dosum=$[$sum+$i];i=$[$i+1]
done
echo $sum

read读取控制台输入(附$()命令替换 )

基本语法
read (选项) (参数)

选项说明

选项 功能
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒),如果-t不加则一直等待

参数说明
指定读取值的变量名

案例实操
提示7秒内,读取控制台输入的名字

#!/bin/bash
read -t 7 -p "请输入你的姓名:" username
echo $username 

  • $()命令替换
echo $(echo 123)

函数

系统函数

  • basename

基本语法
basename [string/pathname] [suffix] 功能:basename命令会删掉所有的前缀包括最后一个"/"字符,然后将字符串显示出来
可以理解为取路径里的文件名称。

选项说明
suffix为后缀,如果suffix被指定了,basename会将pathname或者string中的suffix去掉。

案例实操
截取/root/helloworld.sh路径中的文件名称

basename /root/read_test.sh

截取/root/helloworld.sh路径中的文件名称,同时截去文件类型

basename /root/read_test.sh .sh

  • dirname

基本语法
使用命令dirname 文件绝对路径 从欸顶的包含绝对路径的文件名中除去文件名,然后返回剩下的路径
dirname 可以理解成取文件路径的绝对路径名称。

案例实操
获取helloworld.sh文件的路径

自定义函数

基本语法

[function] funname[()]
{Action;[return int;]
}

经验技巧

  1. 必须在调用函数之前,先声明函数,shell脚本是逐行运行。不会像其他语言那么先编译后运行。
  2. 函数返回值,只能通过$?系统变量获得,如果有return返回,则以return作为返回值,返回值必须为0~255中的一个数字。如果没有return,则以最后一条命令运行结果作为返回值。

案例实操
计算两个输入参数的值。

#!/bin/bash
function sum()
{s=0
s=$[$1+$2]
echo "$s"
}
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;

正则表达式匹配

正则表达式使用单个字符串,匹配一系列符合某个语法规则的字符串。在很多文本编辑器里。正则表达式通常被用来检索,替换那些符合某个模式的文本。在Linux中,grep、sed、awk等文本处理工具都支持通过正则表达式进行模式匹配。

  • 常规匹配

一串不包含特殊字符的正则表达式匹配它自己。例如
使用命令cat /etc/passwd | grep root 会匹配所有包含root的行

  • 常用特殊字符
特殊字符 功能及例子
^ 匹配一行的开头,比如grep ^a会匹配所有a开头的行
$ 匹配一行的结束,例如grep a$会匹配所有a结束的行
. 匹配一个任意的字符,例如grep r..t 可以匹配root,rbbt,ract等等
* 星号不单独使用,他表示匹配一个字符串0次或多次,grep .*表示一切
[ ] 中括号表示匹配某个范围的一个字符,比如[1-5]表示匹配1到5中的一个数字
\ 表示转义,比如有时我们想匹配星号,美元符号之类的可以使用\* 或者\$
{n} 配合其他特殊字符使用,n表达字符的个数,使用grep需要添加参数-E

注意:正则表达式是按匹配!!!

案例实操

文本处理工具

cut

cut的功能就是在文件中负责剪切数据用。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

  • 基本用法

cut [选项参数] filename
说明:默认分隔符是制表符(tab键)

  • 选项参数说明
选项参数 功能
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分割列,默认是制表符(tab)
-c 按字符进行切割 后面加n表示取第几列 比如-c 1
  • 案例实操

数据准备
使用vim编辑器在名为cut.txt的文件中添加如下内容

wen zhe
zhou jiang
wo wo
lai lai
le le

切割cut.txt第一列
使用命令cut -f 1 -d " " cut.txt

切割cut.txt第二列,第三列
使用命令cut -f 2,3 -d " " cut.txt

在cut.txt文件中切割出zhou
使用命令cat cut.txt | grep zhou | cut -f 1 -d " "

选取系统PATH变量值,第2个":"开始后的路径
使用命令echo $PATH | cut -d ":" -f 3

awk

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

  • 基本用法

使用命令 awk [选项参数] '/pattern1/{action1} /pattern2/{action2}... ' filename
pattern:表示awk在数据中查找的内容,就是匹配模式(正则表达式)
action:在找到匹配内容时所执行的一系列命令

  • 选项参数说明
选项参数 功能
-F 指定输入文件分隔符
-v 赋值一个用户定义变量
  • 案例实操

1.数据准备
使用命令cp /etc/passwd ./passwd

2.搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
使用命令awk -F ":" '/^root/{print $7}' passwd

3.搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以","号分割。
使用命令awk -F ":" '/^root/{print $1","$7}' passwd

注意!只有匹配了pattern的行才会执行action
4.只显示/etc/passwd的第1列和第7列,以逗号分隔,且在所有行前面添加列名user,shell在最后一行添加"dahaige,/bin/zuishuai"。
使用命令awk -F ":" 'BEGIN{print "user,shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd

注意!BEGIN 在所在数据读取行之前执行END在所在数据执行之后执行
5.将passwd文件中的用户id增加数值1并输出

  • awk的内置变量
变量 说明
FILENAME 文件名
NR 已读的记录数(当前行号)
NF 浏览记录的域的个数

(1)统计 passwd 文件名,每行的行号,每行的列数

[atguigu@hadoop101 shells]$ awk -F : '{print "filename:" FILENAME ",linenum:"NR ",col:"NF}' passwd
filename:passwd,linenum:1,col:7
filename:passwd,linenum:2,col:7
filename:passwd,linenum:3,col:7

(2)查询 ifconfig 命令输出结果中的空行所在的行号

[atguigu@hadoop101 shells]$ ifconfig | awk '/^$/{print NR}'
9
18
26

(3)切割 IP

[atguigu@hadoop101 shells]$ ifconfig ens33 | awk '/netmask/ {print $2}'
192.168.6.101

【Linux】Linux学习(四)Shell编程相关推荐

  1. linux 程序实验总结,Linux实验报告(实验四) shell编程实验

    实验四 shell编程实验(二) 班级:姓名:学号:上机时间:年月日 任课教师:实验教师:实验成绩: 一.实验目的 综合Linux常用命令和vi编辑器的使用,熟练掌握shell脚本编程. 二.实验注意 ...

  2. Linux知识点回顾之shell编程

    Linux知识点回顾之shell编程 shell编程 1 基本介绍 1.1 Shell 脚本 1.2 Shell 环境 1.3 第一个shell编程 1.4 运行 Shell 脚本有两种方法: 1.5 ...

  3. Linux学习:Shell编程总结

    在学习L为什么要进行shell编程 在Linux系统中,虽然有各种各样的图形化接口工具,但是shell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集,而且是一门非常棒的编程语言.您可以通过使用 ...

  4. 第13章代码《跟老男孩学习Linux运维:Shell编程实战》

    本书历史上已出版最实战的Shell高级编程实战书籍,没有之一,和市面书籍不同,本书是作者经过18年的运维工作及教学工作后,创新类企业级实战书籍,适合所有学习及从事Linux相关工作的读者. <跟 ...

  5. Linux进阶之路———Shell 编程入门

    引言 通过 Shell 编程的学习,铺平架构师道路上的一块大砖. Shell 在Linux 系统中的定位如下所示: 一.第一个 Shell 脚本 我们通过一个简单的 Shell 脚本来感受一下. 在 ...

  6. 【Linux系统管理】10 Shell 编程进阶篇

    六 Shell 编程 6.1 正则表达式 6.1.1 概述 还记得我们在上一章说过正则表达式和通配符的区别(正则表达式用来在文件中匹配符合条件的字符串,通配符用来匹配符合条件的文件名)吗?其实这种区别 ...

  7. Linux高级命令和Shell编程

    1.Linux高级命令 该章节的所有操作都在/export/data/shell目录进行,请提前创建该目录. mkdir -p /export/data/shell/ 1.1.重定向命令 1.重定向& ...

  8. linux写程序四则运算,Shell编程之变量及四则运算

    Shell的学习目标 Shell的基本语法结构: 如:变量的定义.条件判断.循环语句(for.until.while).分支语句.函数和数组等. 基本正则表达式的应用 文件处理:grep.sed.aw ...

  9. 《linux命令行与shell编程大全》--读书笔记

    1.初识Linux shell 图片链接 2.走进shell 1.进入命令行,CLI(command line interface),也叫Linux控制台 通过Linux控制台终端访问CLI Ctrl ...

  10. 总结下linux中一些入门级shell编程实例

    在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集,而且是一门非常棒的编程语言.您可以通过使用shell使大量的任务自动化,shel ...

最新文章

  1. 太棒了!Jupyter 与 PyCharm 完美融合,Jupytext 来啦!
  2. python输入语句-Python中的模块导入和读取键盘输入的方法
  3. 基本拖拽效果,使用 mousedown , mousemove , mouseup实现
  4. Matplotlib实例教程(十七)3D山体图
  5. sql 数组_sql注入中级
  6. oom 如何避免 高并发_微博短视频百万级高可用、高并发架构如何设计?
  7. java 生成缩略图类_JAVA生成【缩略图】方法
  8. php 返回数组元素函数_php array_values 返回数组的所有值详解及实例
  9. c# 字典按ascii 排序_C语言 按ASCII码排序 求教大神
  10. 【渝粤教育】国家开放大学2018年秋季 0053-22T移动通信技术与移动通信设备 参考试题
  11. mybatis-基本架构
  12. selenium 定位一组元素
  13. 使用Mathpix snip软件 快捷复制PDF/图片中公式到Latex和word
  14. 为K8S集群申请Let‘s Encrypt证书
  15. SQL两表关联查询(两表会了,三表,四表都小意思)
  16. knockoutJs在项目中的使用
  17. python基础入门1:输入输出,二进制字符编码,数据类型与注释
  18. Wireless Power Tranmissions
  19. android qq存储方式,手机qq设置保存路径图解步骤
  20. matlab解比例导引法方程,[转载]比例导引法在三维制导中应用的程序详解与过程图解...

热门文章

  1. 持续领先,九州云位列中国边缘云解决方案市场TOP2
  2. Assetizr(图片快速处理软件)v2.1.1官方版
  3. python(scipy)实现填充孔洞的方法(非常类似于MATLAB的imfill)
  4. MySQL流水账(一)
  5. HijackThis日志细解【简明教程增强版】(二)
  6. 如何使用前端技术开发一个桌面跨端应用
  7. java毕业生设计大学生网络创业就业管理系统计算机源码+系统+mysql+调试部署+lw
  8. 微信网页授权报code been used, hints: [ req_id: XYv1Ha07042046 ]
  9. win10企业长期服务版key2018激活180天(唯一方法)
  10. 代码分析 | 单细胞转录组数据整合详解