文章目录

  • 前言
    • 1. 脚本格式和执行方式
      • 1.1 脚本格式
      • 1.2 第一个Shell脚本
      • 1.3 常用执行方式
        • (1)采用bash/sh加脚本的相对路径或绝对路径(不用赋予脚本执行权限即可)
        • (2)采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限)
    • 2. 变量
      • 2.1 系统预定义变量
      • 2.2 自定义变量
      • 2.3 特殊变量
    • 3. 字符串、运算符、注释
      • 3.1 字符串
        • (1) 单引号
        • (2) 双引号
      • 3.2 运算符
      • 3.3 注释
    • 4. 条件判断
      • 4.1 语法
      • 4.2 常用判断条件
    • 5. 流程控制
      • 5.1 if判断
      • 5.2 case语句
      • 5.3 for循环
      • 5.4 while循环
    • 6. read读取控制台输入
    • 7. 函数
      • 7.1 系统函数
        • (1)basename 获取文件名
        • (2)dirname 获取目录
        • (3)提取文件后缀
      • 7.2 自定义函数
    • 8. Shell工具
      • 8.1 cut
      • 8.2 awk
      • 8.3 sort
    • 9. 正则表达式
      • 9.1 概念
      • 9.2 常规匹配
      • 9.3 常用特殊字符
    • 10. 邮件发送(以163邮箱为例)
      • 10.1 163邮箱启用smtp服务
      • 10.2 linux服务器发送邮件
    • 工作中常用脚本(使用crontab定时调度)
      • 1. 删除文件脚本
      • 2. 读取服务器可用内存数量,发送邮件

前言

  Shell 是一个用 C 语言编写的程序,是用户使用 Linux 的桥梁,既是一种命令语言,又是一种程序设计语言。Shell 是Linux系统的用户界面,提供用户与内核的一种交互方式,接收用户输入的命令,并把它送入内核去执行

Linux提供的Shell解析器

/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh


Centos默认的解析器是bash:


1. 脚本格式和执行方式

1.1 脚本格式

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

1.2 第一个Shell脚本

编写脚本,文件后缀为.sh,输出当前时间:

#!/bin/bash
echo "当前时间:"
date "+%Y-%m-%d %H:%M:%S"

1.3 常用执行方式

(1)采用bash/sh加脚本的相对路径或绝对路径(不用赋予脚本执行权限即可)
 sh var.sh

bash var.sh

(2)采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限)

  若脚本没有指定路径,linux 系统会遍历$PATH 即环境变量寻找脚本
(a)赋予脚本执行权限

chmod u+x var.sh

(b)执行脚本
相对路径执行:

./var.sh

注:
  方法一,本质是使用bash解析器执行脚本,所以脚本不需要执行权限
  方法二,本质是脚本需要自己执行,所以需要执行权限
  


2. 变量

2.1 系统预定义变量

常用系统变量$HOME、$PWD、$SHELL、$USER

注:

显示当前Shell中所有变量:

set

如:

(a)查看环境变量:

set |grep path


(b)查看自定义变量

set |grep tomcat

2.2 自定义变量

(1)语法
  定义变量:变量=值
  撤销变量:unset 变量
  声明静态变量:readonly 变量 (不能unset)

如:
(a)给变量A重新赋值

#!/bin/bash
A=5
A=8
echo $A

(b)撤销变量A

#!/bin/bash
A=5
unset A
echo $A

(c)声明静态的变量B=2,unset

#!/bin/bash
readonly B=5
echo $B
unset B=6
echo $B
B=9


(d)用语句给变量赋值

A=$(ls /etc/profile.d)
B=`ls /etc/profile.d/`

#!/bin/bash
#for file in $(ls /etc/profile.d)
for file in `ls /etc/profile.d/`
do
echo $file
done

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

如:

(a)变量是字符串类型,无法直接进行数值运算

#!/bin/bash
A=5
B=6
C=$A+$B
echo $C
D=`expr $A + $B`
echo $D

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

#!/bin/bash
A=i love you
B="i love you"
echo $A
echo $B

(3)使用变量

${变量名}

  变量名外面的花括号可选,加不加都行,加花括号是为了帮助解释器识别变量的边界

如:

(a)定义变量A,按照变量A拼接s cz输出

#!/bin/bash
A=5
echo ${A}s cz

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

export 变量名

2.3 特殊变量

2.3.1 $n
  n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}

2.3.2 $#
  获取所有输入参数个数,常用于循环

2.3.3 $*、$@
  代表命令行中所有的参数,$*把所有的参数看成一个整体,而$@把每个参数区分对待


注:

$*、$@都表示传递给函数或脚本的所有参数,不被双引号包含时,都以$1 $2 …$n的形式输出所有参数
当被双引号包含时,$*会将所有的参数作为一个整体,以"$1 $2 …$n"的形式输出所有参数;$@会将各个参数分开,以"$1" "$2"…"$n"的形式输出所有参数

2.3.4 $?
  最后执行的命令的返回状态。如果返回的值为0,证明上一个命令正确执行;如果值为非0(具体数字取决于命令),则证明上一个命令执行不正确

2.3.5 数组
  用括号( )来表示数组,不支持多维数组,数组元素之间用空格来分隔;获取数组元素的值,使用${数组名[下标]}; 使用@或*可以获取数组中的所有元素${数组名[*]} ${数组名[@]},下标由 0 开始编号

(1)定义数组

数组名=(值1 值2 ... 值n)

单独定义数组的元素:

数组名[下标]=值

如:
定义一个数组,修改下标0值为10:

arr=(5 10 20 30)
echo ${arr[*]}
arr[0]=10
echo ${arr[*]}


(2)读取数组

${数组名[下标]}

如:

遍历一个数组:


(3)获取数组的长度

length=${#数组名[@]}

length=${#数组名[*]}

如:
获取数组arr的长度:

arr=(10 2 5 78)
echo ${#arr[*]}
echo ${#arr[@]}


3. 字符串、运算符、注释

3.1 字符串

(1) 单引号

规则:
  单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用

如:

单引号内变量无效:

一个单引号不能单独出现:

(2) 双引号

规则:
  双引号里可以有变量
  双引号里可以出现转义字符

获取字符串长度

echo ${#字符串变量}

提取子字符串(第一个字符的索引值为 0)

echo ${字符串变量:1:4}

查找字符出现的位置 (子字符串为fd则查找字符 f 或 d的位置(哪个字母先出现就计算哪个))

echo `expr index $字符串变量 子字符串`

如:

3.2 运算符

(1)原生bash不支持简单的数学运算,但是可以通过其他命令来实现。expr 是一款表达式计算工具,使用它能完成表达式的求值操作

如:
计算 2 + 2:

#!/bin/bash
var=`expr 2 + 2`
echo ${var}

注: expr 表达式和运算符之间要有空格,如 2+2 是不对的,必须写成 2 + 2;

计算10*2:

var=`expr 10 \* 2`
echo $var

注:乘号*前边必须加反斜杠(\)才能实现乘法运算

(2)算术运算符

$((运算式))

$[运算式]

如:
计算(2+3)乘以50

 A=$[(2+3)*50]echo $A


unset A
A=$(((2+3)*50))
echo $A

3.3 注释

  以 # 开头的行就是注释,会被解释器忽略;多行注释:<<EOF 注释内容 EOF

#!/bin/bash
#注释
:<<EOF
注释
注释
EOF


4. 条件判断

4.1 语法

test condition

[ condition ]

(注意condition前后要有空格)

注:条件非空即为true,[ rng ]返回true,[] 返回false

4.2 常用判断条件

(1)两个整数之间比较

== 等于
-lt 小于(less than)
-le 小于等于(less equal)
-eq 等于(equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
-ne 不等于(Not equal)


(2)按照文件权限进行判断

-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)

(3)按照文件类型进行判断

-f 存在一个文件(file)
-e 文件存在(existence)
-d 存在一个目录(directory)

(4)字符串比较
  假定变量 a 为 “A”,变量 b 为 “a”:

运算符 说明
= 检测两个字符串是否相等,相等返回 true
!= 检测两个字符串是否不相等,不相等返回 true

如:

(1)-1和-5大小比较


[ -5 -ge -1 ]
echo $?test -1 -ge -5
echo $?

(2)var.sh是否具有写权限

test -w var.sh
echo $?

(3)/root/a.txt 目录中的文件是否存在

[ -e /root/a.txt ]
echo $?

(4)多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)

[ 5 -eq 5 ] && echo $USER || echo no


(5)比较字符串A和a

5. 流程控制

5.1 if判断

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

或者

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

注:
[ 条件判断式 ] 中括号和条件判断式之前必须有空格 ; if后有空格

如:
输入参数为1,则输出中国

#!/bin/bash
echo $0
if [ $1 -eq 1  ]then
echo "中国"
fi

输入参数为1,则输出中国;输入2为美国;其余为英国

#!/bin/bash
echo $0
if [ $1 -eq 1  ]then
echo "中国"
elif [ $1 -eq 2 ]
then
echo "美国"
else
echo "英国"
fi

5.2 case语句

case ${变量名} in "值1") 程序1 ;; "值2") 程序2 ;; *) 默认则执行此程序 ;;
esac

注:
case行尾必须为单词 in,每一个模式匹配必须以右括号结束
双分号;;表示命令序列结束,相当于java中的break
最后的*)表示默认模式,相当于java中的default

如:

输入参数为1,则输出中国;输入2为美国;其余为英国

#!/bin/bash
echo $0
case $1 in"1")
echo 中国
;;"2")
echo 美国
;;*)
echo 英国
;;esac

5.3 for循环

语法1:

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

语法2:

for 变量 in 值1 值2 值ndo 程序 done

如:
(1)从1加到100

#!/bin/bash
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo $s

(2)打印所有输入参数

#!/bin/bash
echo $0
for i in "$@"
do
echo $i
done


5.4 while循环

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

如:
从1加到100

#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s


6. read读取控制台输入

read (选项) (参数)

选项:

-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)

参数

变量:指定读取值赋予的变量

如:
提示7秒内,读取控制台输入的名称

#!/bin/bash
read -p "7秒内输入密码:" -t 7 passwd
echo $passwd


7. 函数

7.1 系统函数

(1)basename 获取文件名

  basename命令会删掉所有的前缀包括最后一个/字符,然后将字符串显示出来;suffix为后缀,如果被指定,basename会将path的后缀去掉

basename [path] [suffix]

如:
截取输入参数 /root/var.sh 的文件名称

#!/bin/bash
basename $1 .sh

(2)dirname 获取目录

  从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

dirname 文件绝对路径

如:
截取输入参数 /root/var.sh 的文件目录

#!/bin/bash
dirname $1

(3)提取文件后缀
m=`basename ./MySQL5.7/libaio-0.3.109-13.el7.x86_64.rpm`
echo ${m##*.}

7.2 自定义函数

定义函数

 function  方法名()
{逻辑脚本[return 整数值]
}

调用函数

方法名 [参数列表]

  必须在调用函数之前,先声明函数,shell脚本是逐行运行,不会像其它语言一样先编译
  函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

如:
计算两个输入参数的和

#!/bin/bash
function sum()
{total=$(($1+$2))
echo $total
}read -p "10s内输入参数1:" -t 10 num1
read -p "10s内输入参数2:" -t 10 num2
sum $num1 $num2

#!/bin/bash
function sum()
{return $[$1+$2]
}read -p "10s内输入参数1:" -t 10 num1
read -p "10s内输入参数2:" -t 10 num2
sum $num1 $num2


8. Shell工具

8.1 cut

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

语法: (默认分隔符是制表符,分隔符必须是单个字符)

cut [选项参数]  filename
选项参数 功能
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分割列
-c 指定具体的字符

如:
(1)数据准备 a.txt

第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

(2)切割第一列

cut -f 1 -d " " a.txt

(3)切割第二、三列

cut -f 2,3 -d " " a.txt


(4)切割第二列以后所有

cut -f 2- -d " " a.txt

(5)在文件中切割出"参数总数"所在列(grep搜索pattern匹配的行)

cat a.txt |grep "参数总数"

cat a.txt | grep "参数总数" | cut -d " " -f 1

(6)选取系统PATH变量值,第2个":"开始后的所有路径:

echo $PATH

echo $PATH|cut -d ":" -f 2-

(7)切割ifconfig 后打印的IP地址

ifconfig ens33|grep netmask|cut  -d "t" -f 2|cut -d " " -f 2


8.2 awk

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

awk [选项参数] 'pattern1{action1}  pattern2{action2} pattern3{action3}' 文件名

  pattern:表示AWK在数据中查找的内容,就是匹配模式
  action:在找到匹配内容时所执行的一系列命令

选项参数 功能
-F 指定输入文件折分隔符
-v 给一个用户定义变量 赋值

awk的内置变量

变量 说明
FILENAME 文件名
NR 已读的记录数(行数)
NF 浏览记录的域的个数(切割后,列的个数)

如:
(1)数据准备

cp /etc/passwd ./

(2)搜索passwd文件以root关键字开头的所有行,并以:分隔输出该行的第7列

awk  -F ":" '/^root/{print $7}' passwd

(3)搜索passwd文件以root关键字开头的所有行,并以:分隔输出该行的第1列和第7列,结果以,号分割

awk -F ":" '/^root/{print $1","$7}' passwd

(4)以:分隔输出/etc/passwd以root关键字开头的行的第一列和第七列,结果以逗号分割,且在所有行前面添加列名user,shell在最后一行添加 no

awk -F ":" 'BEGIN{print "user"} /^root/{print $1","$7} END{print "no"}' passwd

注:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行
(5)将passwd文件中的用户id增加数值1并输出

awk -F ":" -v a=1 '{print $3+a}' passwd


(6)统计以:分隔的passwd文件名,每行的行号,每行的列数

awk -F ":" '{print "文件名:" FILENAME " 行号:" NR "当前行列数:" NF }' passwd


(7)切割IP

ifconfig ens33 |awk -F "t" '/netmask/{print $2}'|awk -F " " '{print $1}'

8.3 sort

  sort命令将文件进行排序,并将排序结果标准输出。

sort (选项)    (参数)
选项 说明
-n 依照数值的大小排序
-r 以相反的顺序来排序
-t 设置排序时所用的分隔字符
-k 指定需要排序的列

参数:指定待排序的文件列表

如:

以:分隔的passwd倒序排序

sort -n -r -t : -k 3 passwd


9. 正则表达式

9.1 概念

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

9.2 常规匹配

  一串不包含特殊字符的正则表达式匹配它自己

cat /etc/passwd | grep rng

9.3 常用特殊字符

(1)^ 匹配一行的开头
如:

 cat /etc/passwd | grep ^root

匹配出所有以root开头的行
(2)$ 匹配一行的结束
如:

 cat /etc/passwd | grep t$

会匹配出所有以t结尾的行

注:^$ 匹配空行

(3). 匹配一个任意的字符
如:

cat /etc/passwd | grep r..t


(4)* 不单独使用,它和左边第一个字符连用,表示匹配上一个字符0次或多次
如:

 cat /etc/passwd | grep ro*t

(5)[ ] 表示匹配某个范围内的一个字符

[6,8]------匹配6或者8
[a-z]------匹配一个a-z之间的字符
[a-z]*-----匹配任意字母字符串
[a-c, e-f]-匹配a-c或者e-f之间的任意字符

如:

cat /etc/passwd | grep r[a,b,c]*t

(6)\ 表示转义,并不会单独使用,转义字符和特殊字符连用,来表示特殊字符本身


10. 邮件发送(以163邮箱为例)

10.1 163邮箱启用smtp服务

开启SMTP服务

获取授权码和服务器地址

10.2 linux服务器发送邮件

(1)查看mail (无此命令则yum安装)

mail


(2)配置发送邮箱

set from=邮箱@163.com
set smtp=smtp.163.com
set smtp-auth-user=邮箱@163.com
set smtp-auth-password=授权码
set smtp-auth=login

(3)发送邮件

如:


接收邮件成功:

工作中常用脚本(使用crontab定时调度)

1. 删除文件脚本

#!/bin/bash
#输入参数1为文件的目录 输入参数2为目录大小达到多少进行删除
A=`du -sm ./|cut  -f 1`
echo "$1大小为$A"
test $A -ge $2
echo $?
if [ $A -ge $2 ]
thenfor i in  `find $1 -type f`
do
m=`basename $i`
echo "-------"
echo $m
echo ${m##*.}
rm -rf $i
donefi

2. 读取服务器可用内存数量,发送邮件

#!/bin/bash
FreeMem=`free -m |awk 'NR==2 {print $NF}'`if [ $FreeMem  -lt $1 ]
then
echo "内存(M):$FreeMem " | tee /tmp/mes.txt
mail -s  "`date '+%Y-%m-%d %H:%M:%S'` $FreeMem" 地址@163.com < /tmp/mes.txtfi

linux Shell脚本指南(条件判断、expr执行运算、流程控制、使用函数处理文件、cut、awk、sort、邮件发送) 删除文件脚本 读可用内存发送邮件脚本相关推荐

  1. 不要在条件判断中执行复杂的语句

    除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量,以提高可读性. 说明:很多if语句内的逻辑相当复杂,阅读者需要分析条件表达 ...

  2. if判断用户名 linux,Shell脚本IF条件判断和判断条件总结

    前言:      无论什么编程语言都离不开条件判断.SHELL也不例外. if list then do something here elif list then do another thing ...

  3. linux脚本条件判断或,Shell脚本IF条件判断和判断条件总结

    前言:      无论什么编程语言都离不开条件判断.SHELL也不例外. if list then do something here elif list then do another thing ...

  4. Linux之Shell脚本的条件判断和函数

    一.条件判断 1.if判断 (1)基本语法 if [ 条件判断式 ] then程序 fi 注意事项: 1.[ 条件判断式 ]中括号和条件判断式之间必须有空格 2.if后要有空格 (2)实操 输入一个数 ...

  5. Shell脚本IF条件判断和判断条件总结

    IF条件判断 1.基本语法: if [ command ]; then 符合该条件执行的语句 fi 2.扩展语法: if [ command ];then 符合该条件执行的语句 elif [ comm ...

  6. linux判断搜索结果,shell编程之条件判断和find查询

    使用read 来把输入值分配给一个或多个shell 变量: -p指定要显示的提示 -t TIMEOUT read从标准输入中读取值,给每个单词分配一个变量 所有剩余单词都被分配给最后一个变量 read ...

  7. Shell脚本之条件判断

    1.基本语法 [ condition ](注意condition前后要有空格)注意:条件非空即为true,[ 666 ]返回true,[] 返回false. 2. 常用判断条件 (1)两个整数之间比较 ...

  8. Shell程序设计 | 基本语法 :变量、I/O、算术运算、条件判断、流程控制、函数

    文章目录 变量 环境变量 位置变量 特殊变量 自定义变量 数组 I/O printf / echo read 算术运算 let expr 条件判断 test 常用判断条件 流程控制 if case f ...

  9. shell中的条件判断和比较

    1  shell 的$! ,$?, $$,$@ $n        $1 the first parameter,$2 the second... $#        The number of co ...

  10. Shell基础之条件判断 分支判断

    条件判断式语句 文件类型判断 测试选项 作用 -d 文件 是否是目录 -e 文件 是否存在 -f 文件 是否是文件 整数之间的比较 测试选项 作用 整数1 -eq 整数2 相等 整数1 -ne 整数2 ...

最新文章

  1. Centos下源码安装git
  2. 【算法】集成学习原理
  3. vc socket api建立TCP连接(包括域名解析)并收发数据的代码模板
  4. h5 storage事件监听
  5. 宝塔搭建laravel所需要的lnmp环境linux-nginx-mysql-php-composer-git
  6. Ctrl + R 后,悲剧咯、、、、
  7. vmware安装linux.iso
  8. 美政府停摆或考验机场安检 携枪旅客曾无障碍登机
  9. 基于LabVIEW的轴承信号采集分析仪的设计
  10. 【文献阅读01】Eco-Vehicular Edge Networks for Connected Transportation: A Distributed Multi-Agent Reinfor
  11. 为什么循环队列要浪费一个存储空间
  12. 量子点表面修饰PEG/抗体/金属/细胞膜/无机材料标记与制备
  13. 猫抓m3u8,遇到该媒体已加密,请注意下载key文件
  14. MATLAB App Designer 计算器的设计
  15. 怎么查询英语四六级证书编号
  16. XMOS学习笔记1: XMOS基础知识
  17. EXCEL词典(xllex.dll)文件丢失或损坏的解决方法
  18. 思岚科技通用机器人底盘ZEUS将亮相2019 CES
  19. random.seed()以及random.shuffle()
  20. MT6763芯片最新参考设计MT6763芯片datasheetMT6763芯片规格书

热门文章

  1. Android MTK平台在电量低于15%后,打开闪光灯,拍照时闪光灯不亮,提示无法打开闪光灯
  2. 生存危机——我的工作会不会被机器取代
  3. 猪肉半夜发蓝光或因荧光增白剂 打击食品犯罪势在必行
  4. 10个有用的自定义钩子vue.js
  5. 10NIO高级编程与Netty入门
  6. 【Leetcode】斐波那契数列python实现
  7. 华为机考:二叉树的层序遍历
  8. java关键词组匹配算法
  9. kettle下载百度网盘地址含入门教程3(表间数据自定义传输)
  10. AV1代码学习1:aomenc的main函数