linux新建脚本的程序代码,Linux自学笔记——shell脚本编程

本文详细介绍了Bash脚本的基本语法和核心概念,包括变量、算术运算、条件测试、循环结构、函数以及文件操作等。通过一系列练习题,读者可以掌握如何编写脚本来处理文件、检查用户类型、执行系统信息查询等任务,从而提升shell脚本编程能力。
摘要由CSDN通过智能技术生成

脚本文件格式:

第一行,顶格:#!/bin/bash

注释信息:#

代码注释:

缩进,适度添加空白行

语言:编程语法格式,库,算法和数据结构;

编程思想:

问题空间à解空间

变量:

局部变量

本地变量

环境变量

位置参数变量

特殊变量

数据类型:字符型、数值型

弱类型:字符型;

Bash中的算术运算:

+,-,*,/,%,**

实现算术运算:

1)let var=算术表达式;

2)var=$[算术表达式]

3)var=$((算术表达式))

4)var=$(expr arg1 arg2 arg3…)

乘法符号在有些场景中需要转义;

Bash有內建的随机数生成器;$RANDOM

增强型赋值:

+=,-=,*=,/=,%=

let varOPERvalue

例如:let count+=1

自增,自减:

let var+=1

let var++

let var-=1

let var—

练习1:写一个脚本,计算/etc/passwd文件的第10个用户和第20个用户的ID之和;

9d20c790908bc86a21f9bb62b39ea30a.png

练习2:写一个脚本,传递两个文件路径作为参数脚本,计算这两个文件中所有空白行之和;

8a7e3c6a4c812a768d6d184d0f39beeb.png

条件测试:

判断某需求是否满足,需要由测试机制来实现;

如何编写测试表达式以实现所需的测试:

1)执行命令,并利用命令状态返回值来判断;

0:成功;

1-255:失败;

2)专用的测试表达式需要由测试命令辅助完成测试过程;

测试命令:

test EXPRESSION

[ EXPRESSION ]

` EXPRESSION `

NOTE:expression前后必须有空白字符;

Bash的测试类型:

数值测试:数值比较

-gt:是否大于;

-ge:是否大于等于;

-eq:是否等于;

-ne:是否不等于;

-lt;是否小于;

-le:是否小于等于;

字符串测试:

==:是否等于;

>:是否大于

!=:是否不等于;

=~:左侧字符串是否能够被右侧的PATTERN所匹配;

Note:此表达式一般用于[[]]中;

-z“string”:测试字符串是否为空,空则真,不空则为假;

-n“string”:测试字符串是否为不空,不空则为真,空则为假;

Note:

1)用于字符串比较时的用到的操作数都应该使用引号;

2)要使用[[]];

文件测试:

存在性测试:

-a FILE

-e FILE

文件的存在性测试,存在则为真,否则则为假;

存在性及类型测试:

-b file:是否存在并且为块设备文件;

-c file:是否存在并且为字符设备文件;

-d file:是否存在并且为目录文件;

-f file:是否存在并且为普通文件;

-h file或 –L file:是否存在并且为符号链接文件;

-p file:是否存在并且为命名管道文件;

-S file:是否存在并且为套接字文件;

文件权限测试:

-r file:是否存在并且对当前用户可读;

-w file:是否存在并且对当前用户可写;

-x file:是否存在并且对当前用户可执行;

特殊权限测试:

-u file:是否存在并且拥有suid权限;

-g file:是否存在并且拥有sgid权限;

-k file:是否存在并且拥有sticky权限;

文件是否有内容:

-s file:是否有内容;

时间戳:

-N file:文件自从上一次读操作后是否被修改过;

从属关系测试:

-O file:当前用户是否为文件的属主;

-G file:当前用户是否为文件的属组;

双目测试;

File1 –ef file2:file1与file2是否指向同一个文件系统的相同inode的硬连接;

File1 –nt file2:file1是否新于file2;

File1 –ot file2:file1是否旧于file2;

组合条件测试:

逻辑运算:

方式一:

COMMAND1 && COMMAND2

COMMAND1 || COMMAND2

! COMMAND

[ -O FILE ] && [ -r file ]

方式二:

EXPRESSION1 –a EXPRESSION2

EXPRESSION1 –o EXPRESSION2

! EXPRESSION

[ -O FILE –a –x FILE ]

练习:将当前主机名称保存至hostName变量中,如果主机名为空,或者为localhost.localdomain,则将其设置为www.claude666.com;

3b68249a8ab83ced2d259eaba649b7a1.png

脚本的状态返回值:

默认是脚本中执行的最后一条件命令的状态返回值;

自定义状态退出状态码:

exit [n]:n为自己指定的状态码;

note:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;

向脚本传递参数:

位置参数变量

myscript.sh  argu1 argu2

引用方式:

$1,  $2, ..., ${10}, ${11}, ...

轮替:

Shift [n]:位置参数轮替

练习:写一脚本,通过命令传递两个文本文件路径给脚本,计算其空白行数之和;

fd0f549014de7e8cdfb494d7a4f1a4f3.png

过程式编程语言的代码执行顺序;

顺序执行:逐条执行;

选择执行;

代码有一个分支;条件满足时才会执行;

两个或以上的分支:只会执行其中一个满足条件的分支;

循环执行;

代码片段(循环体)要执行0、1或多个来回;

选择执行:

单分支的if语句:

if测试条件;then

代码分支

fi

双分支的if语句:

if测试条件;then

条件为真时执行的分支

else

条件为假时执行的分支

fi

多分支的if语句

if  CONDITION1; then

条件1为真分支

elif  CONDITION2; then

条件2为真分支

elif  CONDITION3; then

条件3为真分支

...

elif  CONDITIONn; then

条件n为真分支

else

所有条件均不满足时的分支

Fi

Note:即便多个条件同时满足,分支只会执行其中的一个,首先测试为“真”

示例1:脚本参数传递一个问文件路径给脚本,判断此文件的类型;

1c223d6a9b961fec977348cb372d55bb.png

练习:写一个脚本

1)传递一个参数给脚本,此参数为用户名;

2)根据其id号来判断用户类型;

0:管理员

1-999:系统用户

1000+:普通用户

0f4ea9aa3640ba876bdb55af68bbf6ae.png

练习:写一个脚本

1)列出如下菜单给用户;

disk) show disks info;

mem) show memory info;

cpu) show cpu info;

*) exit

2)提示用户给出自己的选择,而后显示对应其选择的相应系统信息;

b9a51cd07c9dec827bb4e476338d262e.png

示例2:通过参数传递一个用户名给脚本,此用户不存在时,则添加之,如果存在,显示用户已存在;

0bc353eb46d76965a42a0317eae7ce34.png

练习1:通过命令行给定两个数字,输出其中较大的值;

方法一:

dbf051589c2f6b5f9f007b50c7eca0e4.png

方法二:

969df2b360ecf9506c172c85cc8f8e36.png

练习2:通过命令行参数给定一个用户名,判断其ID号是偶数还是奇数;

6629a24daebc362e2a92ef59aeb214a8.png

练习3:通过命令行参数给定两个文本文件名,如果某文件不存在,则结束脚本执行;都存在时返回每个文件的行数,并说明其中行数较多的文件;

8e449a84df804412744c734e81ec320e.png

练习4:写一个脚本完成如下功能;

1)列出当前系统识别到的所有磁盘设备;

2)如磁盘数量为1,则显示其空间使用信息;否则,则显示左后一个磁盘上的空间信息;

4694779c97f8ac22adc006e307f955c4.png

在虚拟机再添加一块硬盘重新测试:

90302192c10af543ba80e8c806257533.png

Bash脚本编程之用户交互:

read [option]… [name …]

-p 'PROMPT'后面跟提示信息,即在输入前打印处提示信息;

-t TIMEOUT后面跟秒数,意思为输入命令的等待秒数;

bash -n /path/to/some_script

检测脚本中的语法错误

bash -x /path/to/some_script

调试执行

示例1:输入一个磁盘分区,查看是否存在,存在则输出磁盘信息:

27603918879c6b965833d488d67ad782.png

示例2:添加用户及设置密码;

56fae7f9f4ee84ae2b755eb8eca9c1a7.png

循环执行:将一段代码重复执行0、1或多次;

进入条件:条件满足才进入循环;

退出条件:每个循环都应该应该有退出条件,以有机会推出循环;

Bash脚本:

For循环

While循环

Until循环

for循环:

两种格式;

1)遍历列表;

2)控制变量;

遍历列表:

for VARAIBLE in LIST;do

循环体

done

进入条件:只要列表有元素,即可进入循环;

退出条件:列表中的元素遍历完成;

LIST的生成方式:

1)直接给出;

2)整数列表

a){start..end}

b)seq [start [incremtal] last]

3)返回列表的命令;

4)glob

5)变量引用;$@,$*

练习:批量添加用户(for)

820ea263fdabf5fa9b377a170d71ac73.png

练习:求100以内所有正整数之和;

ecbd8d4b28e6e226ae09ba291cf159ff.png

练习:判断/var/log目录下的每一个文件的内容类型

4b05d1e99e6a73b721c3bda528db2d3c.png

练习:

1)分别求100以内所有偶数之和,以及所有奇数之和;

0a68c934cd838d9d8217745c7485f127.png

2)计算当前系统上的所有id之和;

2c7b1cebfbb12feaf978bb10b9ad2532.png

3)通过脚本参数传递目录给脚本,而后计算此目录下所有文本文件的行数之和;并说明此类文件的总数;

88c96666530a4e9dd4008461d4e2fb88.png

while循环:

while CONDITION;do

循环体

循环控制变量修正表达式

done

进入条件:CONDITION测试为“真”

退出条件:CONDITION测试为“假”

until循环:

until CONDITION;do

循环体

循环控制变量修正表达式

done

进入条件:CONDITION测试为“假”

退出条件:CONDITION测试为“真”

示例:求100以内所有正整数之和;

方法一:while循环

477f1ee8131523e9fb50f41823508cdc.png

方法二:until循环;

8b58659ea22890cc2819b4e80fffc93b.png

练习:分别用for,while,until实现

1.分别求100以内所有偶数之和,100以内所有奇数之和;

方法一:for循环

0c8d423c2ae2ac75623350929029e248.png

方法二:while循环

028aa05e339d0cbe93cffa3fd1a07734.png

方法三:until循环

bd6ad0855def0004dbf4dabc6665c293.png

2.创建10个用户,user101-user110;密码同用户名;

方法一:for循环

6a4352f5790f2392005656db107c567f.png

方法二:while循环

411d28f8d2cfc267f65dd44dc3dcfd14.png

方法三:until循环

e3ae6b5d30cb68852506c1325ab04594.png

3.打印九九乘法表;

方法一:for循环

b158569649a375e6c63b13c4d7a04b51.png

方法二:while循环

d6006e33dccd32fbcd85eb3c9d0ee4ef.png

方法三:until循环

b95360d6606994fbe2699d479797ebc8.png

4.打印逆序的九九乘法表;

方法一:for循环

9fd56fde4c40abc4fb4a63850d3e02cf.png

方法二:while循环

298f717ab24ea111a52dc620e68ac542.png

方法三:until循环

1f973f7425ba4d4f4cc8f996ec74bbc5.png

循环控制语句:

continue:提前结束本轮循环,而直接进入下一轮循环判断;

while CONDITION;do

CMD1

if CONDITION2;then

continue

fi

CMDn

done

示例:求100以内所有偶数之和:

ffb66dcde29f5f562e016765cbf44461.png

Break:提前跳出循环

While CONDITION1;do

CMD1

if CONDITION2;then

break

fi

done

创建死循环:

while true;do

循环体

done

退出方式;某个测试条件满足时,让循环执行break命令;

示例:求100以内所有奇数之和;

ea35dae571f12b19d8a1da9884a49e89.png

sleep命令:

delay for a specified amount of time

sleep number

练习:每隔3秒到系统上获取已经登录的用户的用户信息;其中,如果cladue用户登录系统,则记录于日志中,并退出;

7669781a09ee1601ef9f1f95be12b052.png

While循环的特殊用法(遍历文件的行)

While read VARIABLE;do

循环体

done < /PATH/FROM/SOMEFILE

一次读取/PATH/FROM/SOMEFILE文件中的每一行,且将基赋值给VARIABLE变量;

示例:找出ID号为偶数的用户,显示其用户名、ID以及默认shell;

c2962d5a8d0259479667d4d6bc28b1dd.png

for循环的特殊用法:

for((控制变量初始化;条件判断表达式;控制变量的修正语句));do

循环体

done

控制变量初始化:仅在循环代码开始运行时执行一次;

控制变量的修正语句:每轮循环结束会先进行控制变量修正运算,而后再做条件判断;

示例:求100以内所有正整数之和;

6af20f49e2d64d96a4103d55942cae1f.png

示例;打印九九乘法表;

fe18718970bf77cadff3e3ba37cad842.png

case语句:

case语句的语法格式:

case $VARAIBLE in

PAT1)

分支1

;;

PAT2)

分支2

;;

*)

分支n

;;

esac

case支持的glob风格的通配符:

*:任意长度的任意字符;

?:任意单个字符;

[]:范围内任意单个字符;

a|b:a或b

示例1:显示一个菜单给用户;

cpu) display cpu information

mem) display memoryinformation

disk) display disksinformation

quit) quit

要求:(1) 提示用户给出自己的选择;

(2)正确的选择则给出相应的信息;否则,则提示重新选择正确的选项;

82caa0ec0bb9550fd4d4bbd1508e4400.png

示例:写一个服务框架脚本:

$lockfile,值/var/lock/subsys/SCRIPT_NAME

1)接受参数start,stop,restart,status四个参数之一;

2)如果参数非此四者,则提示使用帮助后退出;

4)Start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除此文件再创建文件,而后显示重启完成;status,如果lockfile存在,显示running,否则,显示stoped。

fe6dd71dd5b5a79db85b49926c7f2926.png

Note:第一行代码basename $0.获取脚本的名字。想对哪个服务管理,将脚本改成对应的名字即可;

函数:function

过程式编程:代码重用

模块化编程

结构化编程

把一段独立功能的代码当作一个整体,并为之一个名字;命名的代码段,此即为函数;

Note:定义函数的代码段不会自动执行,在调用时执行;所谓调用函数在代码中给定函数名即可;

函数名出现的任何位置,在代码执行时,都会被自动替换成函数代码;

语法一:

function f_name {

…函数体…

}

语法二:

f_name() {

…函数体…

}

函数的生命周期:每次被调用时创建,返回时终止;

其状态返回结果为函数体中运行的最后一条命令的状态结果;

自定义状态返回值,需要使用return

return [0-255]

0:成功

1-255:失败

示例:给定一个用户名,取的用户的id号和默认shell;

53ec5fde4594a215a031afa51fa3954d.png

示例2:上述例子的服务脚本框架(用函数)

f0b46108d88dc127c88e63a178033f9d.png

函数返回值:

函数的执行结果返回值;

1)使用echo或print命令进行输出;

2)函数体中调用的命令的执行结果;

函数的退出状态码:

1)默认取决于函数体中执行的最后一条命令的退出状态码;

2)自定义:return

函数可以接受参数:

传递参数给函数:

在函数体当中,可以使用$1,$2,…引用传递给函数的参数,还可以函数中使用$*或$@引用所有的参数,$#引用传递的参数的个数;

在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,testfunc arg1 arg2 arg3…

示例:添加10个用户,添加用户的功能使用函数实现,用户名作为参数传递给函数;

2b7ac05c0cc0df4a755475948a3cd861.png

练习:写一个脚本,使用函数ping一个主机来测试主机的在线状态;主机地址通过参数传递给函数;

主程序:测试192.168.19.129-192.168.19.139范围内主机的在线状态;

a5733823ec831fdd29913041f233f2b2.png

练习:打印N*N乘法表;

0c340fc9ec1eeaf82353d3442242e62e.png

变量作用域:

局部变量:作用域是函数的生命周期;在函数结束时被自动销毁;

定义局部变量的方法:localVARIABLE=VALUE

本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用范围为当前shell脚本程序文件;

示例程序:

d1108032076ac3428944169e53f2a2ed.png

函数递归:

函数直接或间接调用自身:

示例:求10!

03d6d18e208d1f1da02b90abcf22e1ef.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值