Shell编程

Posted longblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell编程相关的知识,希望对你有一定的参考价值。

 

1  Shell脚本编程注意事项

1)  Shell脚本名称命名一般为英文的大写、小写

2)  不能使用特殊符号、空格来命名

3)  Shell脚本后缀以.sh结尾

4)  不建议shell命名为纯数字,一般以脚本功能命名

5)  Shell脚本内容首行需以#!/bin/bash开头

6)  Shell脚本中变量名称尽量使用大写字母,字母间不能使用“-”,可以使用“_”

7)  Shell脚本变量名称不能以数字、特殊符号开头

2  Shell变量、数组、运算、括号与引号

Shell定义变量不需要声明类型,可以使用赋值符号“=”为变量赋值;

引用变量,可以使用$变量名,例:A=123,引用:$A或${A};

如果需要明确变量的类型,可以使用declare指定类型,declare常见参数:

  • +/-:“-”可用来指定变量的属性,“+”为取消变量所设置的属性
  • -f:仅显示函数
  •  r:将变量设置为只读
  •  x:指定的变量会成为环境变量,可供shell以外的程序来使用
  •  i:指定类型为数字,字符串或运算式

  技术分享图片

2.1  shell编程中变量分为3种

系统变量、环境变量、用户变量

2.1.1   常见的系统变量

1)$0:当前脚本的名称

2)$n:当前脚本的第n个参数,n=1,2…,9

3)$*:当前脚本的所有参数(不包括程序本身),所有的参数作为一个整体

4)[email protected]:当前脚本的所有参数(不包括程序本身),所有的参数分别作为个体

5)$#:当前脚本的参数个数(不包括程序本身)

6)$?:命令或程序执行完后的状态,返回0表示执行成功

7)$$:程序本身的PID号

2.1.2   常见的环境变量

1)  PATH:命令所示路径,以冒号为分割

2)  HOME:打印用户家目录

3)  SHELL:显示当前shell类型

4)  USER:打印当前用户名

5)  ID:打印当前用户ID信息

6)  PWD:显示当前所在路径

7)  TERM:打印当前终端类型

8)  HOSTNAME:显示当前主机名

2.1.3    用户变量

1)自定义名称

例:IP=192.168.1.1

2)read命令设置变量

read从标准输入中读取变量值,使用-p选项可以添加相应的提示

例:read -p “Please input a number:” P_NUMBER

2.2  数组

Bash提供了一维数组变量的功能,数组中的所有变量都会被编录成索引,数组的索引是以0开始的整数,且没有大小限制

2.2.1   创建数组变量

1)  name[subscript]=value

例:A[0]=00    A[1]=11

2)  name=(value1 value2 value3 … valuen)

例:B=(00 11 22 33 44)

2.2.2   调用数组

${name[subscript]}   #subscripts是@或者*符号,将调用所有的数组成员

${#name[subscript]}  #返回元素的长度;当subscript是@或者*符号,返回数组中元素的个数

2.2.3  删除数组

unset name[sbuscript]

unset name  #删除整个数组

2.3  算术运算

1)  使用$((expression)),expression为算术表达式

$((x+y)) 加法;其他-、*、/、%

$((x++)) 自加1运算

$((x--)) 自减1运算

$((x**y)) 幂运算

2)  命令工具expr

expr arg1 + agr2

2.4  常见的判断逻辑运算符

1)  -f:判断文件是否存在,例 if [ -f filename ]

2)  -d:判断目录是否存在,例if [ -d dir ]

3)  -eq:等于,应用于整型比较

4)  -ne:不等于,应用于整型比较

5)  -lt:小于,应用于整型比较

6)  -gt:大于,应用于整型比较

7)  -le:小于或等于,应用于整型比较

8)  -ge:大于或等于,应用于整型比较

9)  -a:双方都成立(and)

10)-o:单方成立(or)

11)-z:空字符串

12)||:单方成立

13)&&:双方都成立

2.5  判断括号区别

1)  ():用于多个命令组、命令替换、初始化数组

2)  (()):整数扩展、运算符、重定义变量值,算术运算比较

3)  []:bash内部命令,“[”与test是等同的,正则字符范围、引用数组元素编号,不支持“+”、“-”、“*”、“/”数学运算符,逻辑测试使用-a、-o

4)  [[]]:bash程序语言的关键字,不是一个命令,[[]]结构比[]结构更加通用,不支持“+”、“-”、“*”、“/”数学运算符,逻辑测试使用&&、||

5)  {}:主要用于命令集合或范围,例如:mkdir –p /data/201{7,8}/  #创建2017、2018目录

 {0..10}  #0到10数字

{0..10..2 } #0,2,4,6,8,10数字

{2..-1}  #2,1,0,-1数字

2.6  引号

2.6.1  单引号

单引号可以将它中间的所有任意字符还原为字面意义,实现屏蔽Shell元字符的功能

[[email protected]]# echo ‘$aa‘

$aa

2.6.2  双引号

双引号类似于单引号,但不会屏蔽`、和$这三个元字符的含义,如果需要屏蔽这些字符,须前置一个符号,其他字符的功能将被屏蔽(包括单引号)

[[email protected]]# echo "This‘s"

This‘s

[[email protected]]# echo "$HOME"

/root

[[email protected]]# echo "$HOME"

$HOME

2.6.3 反引号

使用反引号进行命令替换,命名替换使Shell可以将命令字符替换为命令执行结果的输出内容。也可以使用$()实现

[[email protected]]# echo `date +%D`

10/28/18

[[email protected]]# echo $(date +%D)

10/28/18

3  Shell语句语法与函数

3.1  if条件判断语句

3.1.1  if语法

if (表达式1);then

         语句1

elfi (表达式2)                    #可省略,可有多个

         语句2

else                            #可省略

         语句3

fi

3.1.2  例子

技术分享图片

技术分享图片

技术分享图片

3.2  for循环语句

for循环语句主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表

3.2.1  for语法

for i in (表达式)

do

         语句

done

3.2.2  例子

1)循环打印网址

技术分享图片

技术分享图片

2)循环打印1~10的数字,seq列出数据范围

技术分享图片

技术分享图片

3)循环求和

技术分享图片

3.3  while循环语句

主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环

3.3.1  while语法

while (表达式)

do

         语句

done

3.3.2  例子

1)  循环打印文件中的网址(read指令用于读取行或者读取变量)

技术分享图片

技术分享图片

2)  循环打印1~100(expr用于运算逻辑工具)

技术分享图片

3.4  case选择语句

主要用于对多个选择条件进行匹配输出,通常用于脚本传递输入参数,打印出输出结果及内容

3.4.1 case语法

case 变量 in

变量1)

语句1

;;

变量2)

语句2

;;

*)

语句3

;;

Esac

3.4.2  例子

1)  输入参数并显示

技术分享图片

运行结果:

技术分享图片

3.5  select选择语句

一般用于选择,常用于选择菜单的创建

3.5.1 select语句

select i in (表达式)

do

语句

done

3.5.2  例子

1)  选择操作系统

技术分享图片

运行结果:

技术分享图片

3.6  Shell编程函数

shell函数的好处在于只需定义一次,后期随时使用,无须在shell脚本中添加重复的语句块

3.6.1            Shell函数语法

function name(){语句}

shell函数默认不能将参数传入()内部,shell函数参数传递在调用函数名称时传递

调用shell函数:

name argv1 argv2

3.6.2  例子

技术分享图片

4  Shell编程find、sed、awk

4.1  find

主要用于操作系统文件、目录的查找

1)  find语法:

find path –option [-print] [-exec -ok command] {} ;

         其中option常用参数

        -name filename:查找名为filename的文件

         -type b/d/c/p/l/f:查找块设置、目录、字符设备、管道、符号链接、普通文件

         -size n[c]:查找长度为n块[或n字节]的文件,-n则为小于n块/字节,+n为大于n块/字节

         -mtime –n +n:按文件更改时间来查找文件,-n指n天以内,+n指n天以前

         -atime –n +n:按文件访问时间来查找文件

         -ctime –n +n:按文件创建时间来查找文件

         -mmin、-amin、-cmin:已分钟来查找文件

2)  例子:

  •   -name

  find /data/ -name “*.txt”   #查找/data/目录以.txt结尾的文件

  •   -type

  find /data/ ! –type d  #查找/data/目录下的非文件夹

  find /data/ -type f|xargs chmod 644 –R  #查找文件类型并将权限设置为644

  •   -size

  查找文件大于、等于、小于10M的文件

  find /data/ -size +10M

  find /data/ -size 10M

  find /data/ -size -10M

  •  -mtime

  find /data/ -mtime +30 -name “*.log”  #查找30天以前的log

  find /data/ -mtime -30 -name “*.log”  #查找30天以内的log

  find /data/ -mtime 30 -name “*.log”  #查找第30天的log

  •  -exec

  查找30天以前的log并删除

  find /data/ -mtime +30 -name “*.log” -exec rm -rf {} ;

4.2  Sed

Sed是一个非交互式文本编辑器,可以对文本文件和标准输入进行编辑,标准输入可以来自键盘输入、文本重定向、字符串、变量和管道的文本,一次处理一行内容

在处理文本时把当前处理的行存储在临时缓冲区中,称为“模式空间”,sed命令处理缓冲区中的内容,处理完成后把缓冲区的内容输出至屏幕或者写入文件;对文件彻底修改需要加-i参数

1)  Sed语法

sed [-options] [‘commands’] filename

2)  sed参数与指令

  •  参数

  -n:静默输出,默认情况下,sed程序在所有的脚本指令执行完毕后,将自动打印模式空间中的内容,该选项可以屏蔽自动打印

  -e:允许多个脚本指定被执行

  -f:从文件中读取脚本指令

  -i:直接修改源文件

  •   指令

  p:打印匹配行

  a:在定位行号之后追加文本信息

  i:在定位行号之前插入文本信息

  d:删除定位行

  s:使用替换模式替换相应模式

3)  例子

sed ‘s/old/new/g’ test.txt   #test.txt文本中所有的old替换为new,g为所有匹配,没g则只替换第一次匹配

sed -n ‘1,3p’ test.txt  #打印1到3行

sed ‘/old/,$d’ test.txt  #删除匹配行到最后一行

sed ‘/old/anew’ test.txt  #查找old行并在其下一行添加new

sed ‘www/s/^/&new’ test.txt  #查找www的行并在其行首添加字符串new;&在sed表示添加

4.3  awk

awk是一个文本处理工具,原理是逐行处理文件中的数据,查找与命令行中所给定内容相匹配的模式,如果发现匹配内容,则进行下一个编程步骤,如果找不到匹配内容,则继续处理下一行

1)  awk语法

awk ‘pattern + {action}’ file

2)  awk参数、变量、函数与BEGIN、END

  •   参数

  ‘’:单引号是为了和shell命令区分开

  {}:大括号表示一个命令分组

  patter:表示匹配patter条件的行才进行action处理

  action:处理的动作,常见动作是print

  patter和action可以只有其一,但不能两者都没有

  •   内置变量

  FS:分隔符,默认为空格

  OFS:输出分隔符

  NR:当前行数,从1开始

  FNR:当前输入文档的当前记录编号(当前行数),尤其是当有多个输入文档时有用

  NF:当前记录字段个数

  $0:当前记录

  $1~$n:当前记录第n个字段(列)

  •  内置函数

  gsub(r,s):在$0中用s代替r

  index(s.t):返回s中t的第一个位置

  length(s):s的长度

  match(s,r):s是否匹配r

  split(s,a,fs):在fs上将s分成序列a

  substr(s,p):返回s从p开始的字串

  •  BEGIN{}是在文件开始扫描前进行的操作 ,END {}是扫描结束后进行的操作 ;一般的操作都是需要在BEGIN 设置一个初始的量

3)  awk流程控制语句

  •   if (表达式) {语句1} else {语句2}
  •   while (表达式) {语句}
  •   do {语句} while (表达式)
  •   for (变量;条件;计数器) {语句}
  •   break:跳出循环   ; continue:终止当次循环

4)  例子

  •   打印硬盘设备名称

  技术分享图片

  •   以空格、 、冒号、分号为分割

  技术分享图片

  •   打印文件的3到5行;打印文件的第3行和第5行

  技术分享图片

  •   打印前3行第一列

  技术分享图片

  •  格式化输出passwd内容,printf打印字符串,%格式化输出分隔符,s表示字符串类型,-12表示12个字符,-6表示6个字符

  技术分享图片

  • awk与if结合,判断数字比较

  技术分享图片

  •   统计passwd文件用户数

  awk -F ":" ‘BEGIN {count=0};{name[count]=$1;count++};END{for (i=0;i<NR;i++) print i,name[i]}‘ /etc/passwd

以上是关于Shell编程的主要内容,如果未能解决你的问题,请参考以下文章

初识shell编程

linux12shell编程 --> shell基础01

Shell编程Shell中多分支case条件语句

Shell编程Shell中for循环while循环until循环语句

Shell编程Shell中for循环while循环until循环语句

1shell编程(shell脚本)_理解编程和变量