Linux学习记录(四)Shell编程
0、学习shell的目的:
-
方便运维;
-
编写shell程序管理集群、提高开发效率;
1、Shell概述
(1)shell是解释器;
核心:硬件系统(主机+外设);
外层:操作系统;
内核:操作系统的核心——直接操作硬件(对用户不友好)
外层:用户接口,操作系统一部分(文本编辑器、浏览器等、ls命令等),KED, GNOME等;用户可
以操作,但内核不能理解
Shell:解释层,将用户命令转换为内核命令
(2)Shell是命令行解释器,用于接受用户(程序)命令,然后调用系统内核;
(3)脚本: 在Linux系统中,可以将命令逐条解释执行,也可以将多条命令放到一个文件中,交由系统执行。这样的文件称脚本。
总结:Shell还是一个功能强大的编程语言,易编写,易调试,灵活性强
2、Shell环境
Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
- ……
本教程关注的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。
在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
3、Shell解析器
-
Linux提供的Shell解析器:
[root@localhost ~]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin
-
Bash和sh的关系:
[root@localhost ~]# cd /bin/ [root@localhost bin]# ll | grep bash -rwxr-xr-x. 1 root root 960472 8月 3 2017 bash lrwxrwxrwx. 1 root root 10 5月 21 12:58 bashbug -> bashbug-64 -rwxr-xr-x. 1 root root 6964 8月 3 2017 bashbug-64 lrwxrwxrwx. 1 root root 4 5月 21 12:58 sh -> bash # sh最后转为bash去解析,所以一般不区分sh与bash
-
CentOS默认的解析器是bash;
[root@localhost bin]# echo $SHELL /bin/bash
4、Shell脚本入门
-
脚本格式:以 # !/bin/bash 开头(指定解析器)
-
第一个shell脚本:helloworld
(1)脚本代码:
# !/bin/bash echo "hello,world!" echo "This is the first shell application."
(2)脚本执行方式:
① bash / sh + 相对路径/绝对路径(解析器执行不用赋予脚本 + x 权限)
[root@localhost c-work]# bash /root/vscode-work/c-work/hello.sh hello,world! This is the first shell application. [root@localhost c-work]# sh hello.sh hello,world! This is the first shell application.
② . / hello.sh (需要赋予sh文件权限:chmod 777 hello.sh )
[root@localhost c-work]# chmod 777 hello.sh [root@localhost c-work]# ./hello.sh hello,world! This is the first shell application.
-
多命令处理
[root@localhost c-work]# touch batch.sh #!/bin/bash cd /root/vscode-work/c-work/ touch batchdemo.txt echo "i love aust" >> batchdemo.txt # >> 重定向到文件 [root@localhost c-work]# cat batchdemo.txt i love aust
5、Shell变量
系统变量
-
常用系统变量:$HMOE,$PWD,$SHELL,$USER等
-
实操案例
-
# 查看系统变量 [root@localhost c-work]# echo $HOME /root
-
# 显示当前Shell中所有变量 [root@localhost c-work]# set BASH=/bin/bash BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=()
-
自定义变量
-
基本语法:
-
定义变量:变量=值(不含空格)
[root@localhost c-work]# A=2 [root@localhost c-work]# echo $A 2
-
只读变量:readonly 变量名=值(不可修改)
[root@localhost c-work]# readonly A=1 [root@localhost c-work]# A=2 -bash: A: 只读变量 # 删除只读变量 [root@localhost c-work]# cat << EOF | gdb > attach $$ > call unbind_variable("变量名") > detach > EOF
-
全局变量:export 变量名=值(可供其他shell程序使用)
[root@localhost c-work]# D="這是變量D" [root@localhost c-work]# ./hello.sh hello,world! This is the first shell application. [root@localhost c-work]# export D [root@localhost c-work]# ./hello.sh hello,world! This is the first shell application. 這是變量D
-
撤销变量:unset 变量
[root@localhost c-work]# unset A [root@localhost c-work]# echo $A
-
引用变量:$变量名
注意:在bash中,变量默认字符串类型,无法直接进行数值运算;
-
特殊变量$n
-
功能描述:n为数字,$0代表脚本名称,$1-$9代表第一到第九个参数,10以上用${12} ;
-
实例:
[root@localhost c-work]# touch prm.sh [root@localhost c-work]# vi prm.sh # 代码段 #!/bin/bash echo "$0 $1 $2 $3" [root@localhost c-work]# sh prm.sh prm.sh [root@localhost c-work]# sh prm.sh love prm.sh love [root@localhost c-work]# sh prm.sh love ppp prm.sh love ppp
特殊变量$#
- 功能描述:获取所有输入参数个数,常用于循环
- 实例:
特殊变量$*、$@
-
功能描述:获取所有位置参数内容;$* 把所有参数看成一个整体、$@把每个参数区分对待
-
实例:
[root@localhost c-work]# touch prm1.sh [root@localhost c-work]# vi prm1.sh #!/bin/bash echo "$0 $1 $2 $3" echo $# echo $* echo $@ [root@localhost c-work]# sh prm1.sh 1 2 3 prm1.sh 1 2 3 3 1 2 3 1 2 3
特殊变量$?
-
功能描述:最后一次执行的命令的返回值状态,0表示上一命令正确执行,非0表示不正确执行
-
实例:
[root@localhost c-work]# ./hello.sh hello,world! This is the first shell application. [root@localhost c-work]# echo $? 0
6、Shell运算符
基本语法:
- “$((运算式))”或“$[运算式]”
- expr +,-,\*,/,% 加减乘除取余
- 注意:expr 运算符之间必须有空格
运算实例:
-
计算4+5的值
[root@localhost c-work]# expr 4 + 5 9
-
计算(2+3)*4的值
- expr一步计算
[root@localhost c-work]# expr `expr 2 + 3` \* 4 20
- $[运算式]方式
[root@localhost c-work]# echo $[(2+3)*4] 20
7、Shell条件判断
基本语法:
- [ condition ]前后要有空格
- 条件非空即为true,[atguigu]返回true,[]返回false
常用条件判断:
-
两个数字之间的比较=字符串比较
-lt 小于(less than) -le 小于等于(less equal) -eq 等于(equal) -gt 大于(greater than) -ge 大于等于(greater equal) -ne 不等于(not equal)
-
按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write) -x 有执行的权限(execute)
-
按照文件类型进行判断
-f 文件存在且是一个常规文件(file) -e 文件存在(existence) -d 文件存在并且是一个目录(directory)
-
多条件判断:
- &&表示前一条命令执行成功时才执行后一条命令
- || 表示上一条命令执行失败后才执行下一条命令
8、流程控制
if 判断
-
基本语法:
if [ 条件表达式 ];then 程序 fi 或者 if [ 条件表达式 ] then 程序 fi #注意:[ 条件表达式 ]必须有空格 #if 后要有空格 if [ 条件表达式 ] then 程序 elif [ 条件表达式 ] then 程序 else 程序 fi
#!/bin/bash echo Enter a number: read NUM if [ $NUM -eq 1 ] then echo this is 1 elif [ $NUM -eq 2 ] then echo this is 2 else echo no! fi [root@localhost vscode-work]# sh if.sh Enter a number: 1 this is 1 [root@localhost vscode-work]# sh if.sh Enter a number: 3 no!
case 分支语句
-
基本语法:
case $变量名 in “值1”) 程序 ;; “值2”) 程序 ;; ...省略其他case分支... *) 如果以上都未执行,则执行此处程序 esac
#!/bin/bash echo enter a munber read NUM case $NUM in "1") echo this is 1 ;; "2") echo this is 2 ;; *) echo this is none ;; esac [root@localhost vscode-work]# ./case.sh enter a munber 0 this is none [root@localhost vscode-work]# ./case.sh enter a munber 2 this is 2
for循环
-
基本语法:
for 变量名 in 数值1 数值2 数值3... do 程序 done 或者 for ((初始值;条件;值变化)) do 循环执行的命令串 done
#从1加到10 #!/bin/bash s=0 for ((i=1;i<=10;i++)) do s=$[$s+$i] done echo $s [root@localhost vscode-work]# sh for.sh 55 ----------------------------------------- #!/bin/bash echo this is "$""*" for i in $* do echo "bbb $i" done echo this is "$""@" for j in $@ do echo "bbb $j" done [root@localhost vscode-work]# sh forest.sh 1 2 3 this is $* bbb 1 bbb 2 bbb 3 this is $@ bbb 1 bbb 2 bbb 3
while循环语法
-
基本语法:
while 循环条件命令串 do 循环执行的命令串 done
#计算1-9的平方 #!/bin/bash R=1 while [ $R -le 9 ] do RE=`expr $R\*$R` echo $R * $R = $RE R=`expr $R + 1` done [root@localhost vscode-work]# sh while.sh 1 case.sh c-work for.sh if.sh shell while.sh 1 = 1*1 2 case.sh c-work for.sh if.sh shell while.sh 2 = 2*2 3 case.sh c-work for.sh if.sh shell while.sh 3 = 3*3 4 case.sh c-work for.sh if.sh shell while.sh 4 = 4*4 5 case.sh c-work for.sh if.sh shell while.sh 5 = 5*5 6 case.sh c-work for.sh if.sh shell while.sh 6 = 6*6 7 case.sh c-work for.sh if.sh shell while.sh 7 = 7*7 8 case.sh c-work for.sh if.sh shell while.sh 8 = 8*8 9 case.sh c-work for.sh if.sh shell while.sh 9 = 9*9
read读入控制台输入
-
基本语法:read(选项)(参数)
-
选项:-p:指定读取值的提示符
-t:指定读取值时等待的时间(秒)
-
参数:变量:指定读取值的变量名
-
9、函数
系统函数
-
basename 基本语法:删掉所有前缀、包括最后一个字符,然后将字符串显示出来
-
basename [string/pathname] [suffix]:如果suffix后缀被指定,则会把string/pathname中后缀去掉
-
可以对多个符号串同时处理(使用-a参数)
[root@localhost vscode-work]# basename /root/vscode-work/ban.txt ban.txt [root@localhost vscode-work]# basename /root/vscode-work/ban.txt .txt ban
-
dirname 基本语法:从给定的文件路径中,去掉文件名,只返回路径
[root@localhost vscode-work]# dirname /root/vscode-work/ban.txt .txt /root/vscode-work
自定义函数
-
基本语法:
function funname[()] { 程序 return 返回值 } funname # 在调用之前声明函数,shell脚本是逐行执行,不会编译 # 函数可以有返回值(通常0~255),也可以没有返回值,这时,shell以函数中最后一条命令的执行结果作为函数返回结果
10、Shell工具(重点)
awk
-
功能描述:把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理;
非交互处理工具awk:基于模式匹配算法的文本行处理算法,支持print
-
基本用法:
awk 选项 ’pattern{action}...' filename pattern:表示awk在数据中查找到的内容,即匹配模式(可不写,无匹配查找) action:在找到匹配内容时执行的一系列命令 # 例如↓ # 在/etc/passwd文件中,以':'为分隔符,打印第1,第2列 awk -F ":" '{print $1, $2}' /etc/passwd awk -F: '{print $1":" $2}' /etc/passwd
参数说明:
选项参数 功能描述 - F 指定文件拆分符号 - v 赋值一个用户定义变量 - f 表示调用awk脚本处理,f 后跟脚本文件 -
代码实现:
[root@localhost awk]# cp /etc/passwd ./ # 拷贝passwd文件到当前目录 [root@localhost awk]# ls passwd [root@localhost awk]# cat passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin nzw:x:1000:1000:nzw:/home/nzw:/bin/bash root123:x:1001:1001::/home/root123:/bin/bash # 搜索passwd文件义root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”分割 [root@localhost awk]# awk -F: '/^root/{print $1","$7}' passwd root,/bin/bash root123,/bin/bash # 搜索passwd文件义root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”分割 # 所有行前面添加列user,shell,在最后一行添加“BBB,PPP” [root@localhost awk]# awk -F: 'BEGIN{print "user,shell"}/^root/{print$1","$7}END{print "BBBB,PPP"}' passwd user,shell root,/bin/bash root123,/bin/bash BBBB,PPP #BEGIN在所有数据读取之前执行,END在所有数据操作之后执行 # 切分IP地址 [root@localhost ~]# ifconfig ens33 | grep "inet" | awk -F " " '{print $2}' 192.168.146.140 fe80::316b:ac5c:b6f1:cae2
sed
-
功能描述:文本流处理工具,默认不修改源文件,在缓冲区中进行修改,将修改后结果提供给用户;
详细解释
sed是一种流编辑器,一次处理一行内容。处理时把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区的内容,处理完成后,把缓冲区的内容送往屏幕,接着再处理下一行,知道文件末尾。
注意:这里的文件内容没有改变,除非使用重定向存储输出;
-
基本用法:
sed 选项参数 ‘comand’ filename # 常使用带前置命令的如下 comand | sed 选项参数 ‘comand’ filename
选项参数:
选项参数 功能描述 - n 屏蔽默认输出(全部内容) - i 直接修改文件内容(不仅仅是在缓冲区修改) - f 指定sed脚本进行处理,后跟脚本文件 - e 指定多个操作动作 - r 启用扩展的正则表达式,要在所有参数最前面使用 {} 组合多个命令,用分号区分 命令功能:
命令 功能 p 打印行 d 删除行 s 字符替换 命令详解
p:打印行 '2, 4p':打印第2~4行;'2p; 4p':打印第2行,第4行
d:删除行 '2, 4d':删除第2~4行
s:字符替换
s/newword/oldword/:用新内容替换旧内容一次(每行第一次出现)
s/newword/oldword/3:用新内容替换旧内容1次(每行第三次出现)
s/newword/oldword/g:用新内容替换所有旧内容
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)