Linux系统的核心是内核。内核控制着计算机系统上的所有硬件和软件,在必要时为应用程序分配硬件, 并根据需要执行程序中的代码。 内核主要负责以下四种功能:
系统内存管理软件程序管理硬件设备管理文件系统管理 简单来说Shell是一种特殊的交互式工具,核心是命令提示符,允许输入文本命令,解释命令,并在内核中执行命令。本质上来说: shell: 一个可以解释shell规定的语法命令的解释器。 解释器负责将应用程序发送的指令,进行检查,合法后交给内核解释执行!返回结果! shell命令: shell解释器要求的指定语法编写的命令。 shell脚本: 多条shell命令,可以编写在一个文件中,文件中的指令,可以按照顺序执行。将这个文件称为shell脚本!
使用$SHELL 变量查看当前系统默认的解释器类型
shell支持多种不同风格的解释器,通过/etc/shells文件查看 Centos默认的解析器是bash
在终端中输入: cat /etc/shells , 等价于/bin/bash -c ‘cat /etc/shells’。 默认/bin/bash必须接一个脚本,作为输入!如果是一条命令,需要加-c (command)
使用echo $PATH查看linux系统中的环境变量。 本质上来说,我们所执行的命令都是一些文件。如pwd,cd,echo等,它们都在/bin目录下。 之所以它们可以在任何目录下能以 文件名 参数的形式运行,是应为它们的根目录在环境变量中。 如,我们自己编写一个shell文件,保存在/home/shell目录下 文件内容为 我们在使用source命令的方式运行该脚本文件,发现跳转到了/usr/local目录并显示了该目录下文件内容 但是如果在其他目录中直接以文件名运行,会显示未找到命令。这是应为该 除此之外,还可以用./文件名方式执行该文件。 先给该脚本文件赋上权限,再执行该文件 发现该脚本文件执行成功。 但我们离开该目录,用 文件名的方式执行该文件 发现找不到该命令 我们将该文件复制到某个环境遍历目录下,如/bin目录。 运行该文件,则发现执行成功!
在/home/shell目录下创建一个文件test01.sh 编辑该文件,内容如下 保存并退出 执行该文件的三种方式
bash或者sh + 脚本 特点: 新开一个bash执行脚本,一旦脚本执行完毕,bash自动关闭!./脚本文件,前提是当前用户对脚本有执行权限,使用当前默认的解释器执行脚本 特点: 新开一个bash执行脚本,一旦脚本执行完毕,bash自动关闭source +脚本 或者 . +脚本 。应为.就是source的缩写定义一个变量a=1,查看该变量 把变量a的值修改为2并打印 查看所有的变量 set
删除变量a的值
变量的生命周期:
在第一次新增时产生变量在执行unset时,撤销,失效!关闭当前bash,所有定义的变量也不会存在!重新连接后,该变量消失 注意:
变量赋值时,值全部以字符串存在,无法进行运算赋值的值中有空格,需要使用引号引起来。单引号:不能识别$等特殊字符。双引号:可以使用 $字符 ``的作用是将引号中的命令执行的结果赋值给变量 `命令` 等价于 $(命令)注意:expr运算符间要有空格; *号需要转义为 \*,否则会被视为通配符; 运算指的都是整数的运算,浮点运算需要借助其他的命令!
[ condition ](注意condition前后要有空格) 注意:条件非空即为true,[ atguigu ]返回true ,[] 返回false。在linux中true为0,false为1
多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
注意:then必须另起一格。如果非要和if [条件判断式]写在一行,则需要在then的左侧加上 ; 例:写一个简单的bash文件,要求:若用户输入的是1,则输出用户输出的是1;用户输入的是2,则输出用户输入的是2;若用户输入的是3,则输出用户输出的是3,若用户输入的是其他字符,则输出用户输入的不是1,2 ,3
# ! bin/bish #若用户输入的是1,则输出用户输出的是1;用户输入的是2,则输出用户输入的是2;若用户输入的是3,则输出用户输出的是3 if [ $1 -eq 1 ] then echo 用户输入的是1 elif [ $1 -eq 2 ] then echo 用户输入的是2 elif [ $1 -eq 3 ] then echo 用户输入的是3 else echo 用户输入的不是1,2,3 fi测试 注意:
若使用linux风格的条件判断语句,if、then、等和 [ 条件判断 ]之间必须要有空格。且then要另起一行或者在then的左侧加上 ;若使用C语言风格的条件判断,则无需考虑这些。但C语言风格的判断需要写两个括号,如判断第一个参数是否等于1,if(($1==1))基本语法
case $变量名 in "值1") 如果变量的值等于值1,则执行程序1 ;; "值2") 如果变量的值等于值2,则执行程序2 ;; …省略其他分支… *) 如果变量的值都不是以上的值,则执行此程序 ;; esac注意事项:
case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。双分号“;;”表示命令序列结束,相当于java中的break。最后的“*)”表示默认模式,相当于java中的default例:输入一个字符串,如果是guest,则输出欢迎游客,如果是admin,则输出欢迎管理员,如果是其它,输出不欢迎
#! /bin/bash/ #判断用户谁让的参数,若为guest,则输出欢迎游客登录,如果是admin,则输出欢迎管理员,如果是其他,则输出不欢迎 case $1 in guest) echo 欢迎游客登录 ;; admin) echo 欢迎管理员 ;; *) echo 不欢迎 ;; esac测试结果
基本语法
for (( 初始值;循环控制条件;变量变化 )) do 程序 done 或 for (( 初始值;循环控制条件;变量变化 )); do 程序; done例:计算1到100之间的和
#!/bin/bash #计算1到100之间的和 sum=0 for((i=1;i<=100;i++)) do sum=$[$sum+$i] done echo 1~100之间的和为: $sum测试结果
基本语法
for 变量 in 值1 值2 值3… do 程序 done 或 for 变量 in 1 2 3; do 程序; done 或 for 变量 in {1..3}; do 程序; done例1:遍历集合中每个元素的值
#!/bin/bash #遍历输出集合中每个元素的值 for i in 张三 李四 王五 do echo $i 是个好人 done测试结果 例2:遍历用户指定输入的集合
#!/bin/bash #遍历输出集合中每个元素的值 for i in $* do echo $i 是个好人 done注意: $* 和$@都是获取用户输入的参数列表,但它们有略微的区别。 当脚本文件中的in后面的参数集不加双引号时,它们是没有区别的。但是如果in后面的参数集加了双引号,$*会把参数集作为一条数据,而$@仍会把参数集作为一个集合。 如
#!/bin/bash #遍历输出集合中每个元素的值 echo '=======$*带引号======' for i in "$*" do echo $i 是个好人 done echo '=======$@带引号的结果集======' for i in "$@" do echo $i 是个好人 done1.基本语法
while [ 条件判断式 ] do 程序 done 或 while((表达式)) do 程序 done例:计算1到100的和
#! /bin/bash #计算1到100之间的和 sum=0 i=1 while(($i<=100)) do sum=$[$i+$sum] # linux中认为 i++是一个字符串,所以我们不能直接写成i++ # 方式一: i=$[$i+1] # 方式二: let i++ let i++ done echo 1到100之间的和为:$sum例:read -p 请输入参数 -t 10 num 表示:提示符为请输入参数,等待时间为10秒,若10秒内未接收到参数则退出。用户输入的参数用num接收。
basename [string / pathname] [suffix] (功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。 选项: suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。 例:截取/home/shell/while.sh路径的文件名称
[root@localhost shell]# basename /home/shell/while.sh while.sh [root@localhost shell]# basename /home/shell/while.sh .sh while [root@localhost shell]#例:获取 /home/shell/while.sh 文件的路径
[root@localhost shell]# dirname /home/shell/while.sh /home/shell基本语法
function funname[()] { Action; [return int;] } funname注意:
必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255) 例:自定义一个执行两个参数的加法操作的函数 #!/bin.bash #自定义一个执行两个参数的加法操作的函数 function add() { result=$[$1+$2] echo 两数之和为:$result #如果没有定义return,返回函数中最后一条语句执行的返回值 #return } #读取用户输入的参数作为函数的参数 read -p 请输入第一个参数: num1 read -p 请输入第二个参数: num2 add num1 num2wc命令用来计算。利用wc指令我们可以计算文件的Byte数、字数或是列数,若不指定文件名称,或是所给予的文件名为“-”,则wc指令会从标准输入设备读取数据。
基本语法 wc [选项参数] filename 参数说明 选项参数功能-l统计文件行数-w统计文件的单词数-m统计文件的字符数-c统计文件的字节数例:查看文件test01.sh中的信息 注意:
wc命令中,是以空格来区分单词的数量。案例中第一行注释没有空格,则认为它是一个单词。wc命令不认为空格是字符cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
基本语法 cut [选项参数] filename 说明:默认分隔符是制表符选项参数说明 选项参数功能-ff为fileds,列号,提取第几列-dd为Descriptor分隔符,按照指定分隔符分割列例1:以:为间隔,切割PATH环境变量的第一列 例2:以:为间隔,切割PATH环境变量的第二、三列 例3:选取系统PATH变量值,第2个“:”开始后的所有路径: 例4:以:为间隔,切割PATH环境变量的第一到三列,和第五列
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
基本用法 sed [选项参数] ‘command’ filename 选项参数说明 参数选项功能-e直接在指令列模式上进行sed的动作编辑。 命令功能描述 命令功能描述a新增,a的后面可以接字串,在下一行出现d删除e查找并替换 数据准备 [root@localhost shell]# touch sed.txt [root@localhost shell]# vim sed.txt zhang san li si wang wu w w zhao liu tian qi 将“ni hao”这个单词插入到sed.txt第二行下,打印 [root@localhost shell]# sed '2a ni hao' sed.txt zhang san li si ni hao wang wu w w zhao liu tian qi注意:文件并没有改变。操作的是流值的值
删除sed.txt文件第二行 删除sed.txt文件最后一行 删除sed.txt文件第二行至最后一行 将sed.txt文件中w替换为S 注意:‘g’表示global,全部替换,不加g只会替换第一个匹配到的字符。将sed.txt文件中的第二行删除并将w替换为Ssort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。默认情况以第一个字符串的字典顺序来排序.
基本语法 sort(选项)(参数) 选项说明-n依照数值的大小排序-r以相反的顺序来排序-t设置排序时所用的分隔字符,默认使用TAB-k指定需要排序的列-uu为unique的缩写,即如果出现相同的数据,只出现一行参数:指定待排序的文件列表.
准备数据
[root@localhost shell]# touch sort.sh bb:40:5.4 bd:20:4.2 xz:50:2.3 cls:10:3.5 ss:30:1.6 按照“:”分割后的第三列倒序排序。一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法 awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename pattern:表示AWK在数据中查找的内容,就是匹配模式 action:在找到匹配内容时所执行的一系列命令选项参数说明 选项参数功能-F指定输入文件折分隔符-v赋值一个用户定义变量 案例 数据准备,将/etc/password 拷贝至当前目录下 sudo cp /etc/passwd ./例1: 搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
awk -F: '/^root/{print $7}' passwd 结果: /bin/bash例2:搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
awk -F: '/^root/{print $1","$7}' passwd 返回结果:root,/bin/bash注意:只有匹配了patter的行才会执行action 例3:只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"zhangsan,/bin/lisi"
awk -F : 'BEGIN{print "user,shell"}{print $1","$7}END {print "zhangsan,/bin/lisi"}' passwd 结果: user,shell root,/bin/bash bin,/sbin/nologin 。。。 chrony,/sbin/nologin rabbitmq,/sbin/nologin zhangsan,/bin/lisi注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。 例4:将passwd文件中的用户id增加数值1并输出
awk -v i=1 -F: '{print $3+i}' passwd 结果: 1 2 3 4 5 。。。 awk的内置变量 变量说明FILENAME文件名NR已读的记录数(行号)NF浏览记录的域的个数(切割后列的个数)例1 :统计passwd文件名,每行的行号,每行的列数
awk -F: '{print "filename:" FILENAME",linenumber:"NR",columns:"NF}' passwd 结果: filename:passwd,linenumber:1,columns:7 filename:passwd,linenumber:2,columns:7 filename:passwd,linenumber:3,columns:7 filename:passwd,linenumber:4,columns:7例2 切割IP
ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'例3 查询sed.txt中空行所在的行号
awk '/^$/{print NR}' sed.txt 结果:4