shell编程

1.什么是shell编程

shell命令解释器

  • bach
  • dash 用于Ubuntu系统
  • csh tcsh 用于unix系统


    image.png

2.开发语言中程序代码的分类

  • 编译型:开发书写的代码 无法直接运行 需要编译 (代码 - 命令)c语言
  • 解释型:书写完成代码 通过命令执行(shell脚本)shell 书写脚本 然后可以直接运行

3.执行脚本

(1)方法一:
直接运行脚本加上x权限

[root@m01 /server/scripts]# vim touch.sh
[root@m01 /server/scripts]# ll touch.sh 
-rw-r--r-- 1 root root 52 Sep  5 17:45 touch.sh
[root@m01 /server/scripts]# chmod +x touch.sh 
[root@m01 /server/scripts]# . /server/scripts/touch.sh
[root@m01 ~]# tree /oldboy
/oldboy
└── oldboy01

0 directories, 1 file

(2)方法er:
sh 执行

[root@m01 ~]# sh /server/scripts/touch.sh
[root@m01 ~]# tree /oldboy
/oldboy
└── oldboy01

0 directories, 1 file

(3)方法三:
source 或 . 替你在当前环境中执行一次脚本

[root@m01 /server/scripts]# . touch.sh
[root@m01 /server/scripts]# tree /oldboy
/oldboy
└── oldboy01

0 directories, 1 file
[root@m01 /server/scripts]# source touch.sh 
[root@m01 /server/scripts]# tree /oldboy
/oldboy
└── oldboy01

0 directories, 1 file
image.png

(4)方法4
输入重定向方法

[root@m01 /server/scripts]# sh <touch.sh 
[root@m01 /server/scripts]# tree /oldboy
/oldboy
└── oldboy01

0 directories, 1 file

4.shell编程基础知识

  • 书写脚本 加上第一行命令解释器
  • 版权说明
  • 不要加中文
  • 成对符号提前敲好
  • """" `` '' {} [] ()
  • 脚本文件名:尽量不要包含服务名称 看见文件名 知道脚本作用

5.shell中的变量

举例 x+y=20 已知x=30 y=? 未知数
变量

  • 用一个固定的字符串,替代更多更复杂的内容
  • 存放在脚本中经常用到的内容 ip 时间
  • 变量的本质是内存中的区域 变量名称区域的地址
    wangk 变量名称 相当于武功秘籍
    echo $wangk 相当于看武功秘籍
    wangk=“动作 成功” 修改变量内容

6.变量的命名规则:

  • 不能以数字开头
  • 变量表示作用: name=oldboy age=18 input_name

7.sh与source (.)区别

[root@m01 /server/scripts]# cat shon.sh
#!/bin/bach

echo $OLDBOY
[root@m01 /server/scripts]# OLDBOY=666

[root@m01 /server/scripts]# sh shon.sh

[root@m01 /server/scripts]# source shon.sh
666
  • sh 执行脚本生成子 shell 而这个变量在子shell中没有定义
  • source include 把这个脚本仔当前shell环境中运行

8.应用场景:

  • sh日常执行脚本
  • source 一般用来 实现include功能 或配置环境变量 别名后生效
调用系统命令测试shell
. /etc/init.d/functions
[root@m01 /server/scripts]# . /etc/init.d/functions
[root@m01 /server/scripts]# action '服务OK' /bin/true
服务OK                                                     [  OK  ]
[root@m01 /server/scripts]# action '服务挂了' /bin/talse
服务挂了 -bash: /bin/talse: No such file or directory
                                                           [FAILED]

9.变量

  • 变量本质 内存中的一块区域 变量名 位置
  • 存放经常用到的内容
  • linux下面的变量直接使用即可
  • 数据类型 (变量在内存中 所占多少空间 变量类型) 不同类型的变量存放不同类型的数据
    变量赋值
[root@m01 ~]# oldboy='oldboy 666'
[root@m01 ~]# echo $oldboy
oldboy 666

变量中的符号

单引号 所见即所得 原封不动的输出
双引号 与单引号类似 对特殊符号进行解析(() `` !)
无引号 与双引号类似 支持通配符 ({} * *.)
反引号 优先执行 优先执行里面的命令

10.变量分类

  • 环境变量(全局变量)
  • 普通变量 (局部变量)
  • 特殊变量

1.环境变量(全局变量)

  • 系统定义
  • 大写字母
  • 在系统中 各个地方基本都是用
env
env命令时gnu的coreutils包内的一个软件,它的功能是:在一个修改后的环境里执行命令。
declare
declare为shell指令,在第一种语法中可用来声明变量并设置变量的属性([rix]即为变量的属性),在第二种语法中可用来显示shell函数。若不加上任何参数,则会显示全部的shell变量与函数(与执行set指令的效果相同)。
export 
Linux export命令用于设置或显示环境变量。
在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该次登陆操作。
image.png
  • env set declare
  • unset 取消变量
  • export 创建或这只环境变量

2.普通变量(局部变量)

  • 命名规则
  • 不能以数字开通
  • 不要占用系统的环境变量
[root@m01 ~]# day=7
[root@m01 ~]# echo $day
7
[root@m01 ~]# echo $dayday

[root@m01 ~]# echo ${day}day
7day

11.与变量相关的文件

  • 每次登陆系统 每次切换用户
image.png
  • ./etc/profile
  • /etc/bashrc
  • ~/.bashrc
  • ~/.bash_profile
  • /etc/profile.d/*.sh
    目录每次用户登录系统 都会运行目录下面.sh脚本结尾

12.特殊变量

  • 提高书写脚本 及脚本执行效率
  • 判断服务状态

13.特殊重要变量位置

image.png

1.$0

  • 一般用来 在脚本执行错误的时候(参数写错 不对) 给用户进行提示
    Usage: $0
[root@m01 /server/scripts]# cat shos.sh
#!/bin/bash
echo $0
[root@m01 /server/scripts]# sh shos.sh
shos.sh
[root@m01 /server/scripts]# sh /server/scripts/shos.sh 
/server/scripts/shos.sh

2.$n 数字

  • 脚本的
  • 命令行中的内容 传递到脚本中
  • /etc/init.d/network restart
[root@m01 /server/scripts]# cat shoy.sh 
#!/bin/bash
echo "Usage: $0 {start|stop|restart}"
echo "$1 $2 $3"
[root@m01 /server/scripts]# sh shoy.sh a b c
Usage: shoy.sh {start|stop|restart}
a b c

故障预警:
n n超过9 从10开始 需要使用{10}

3.$#

  • 脚本参数的个数
  • 应用场景: 参数个数等于0 则显示错误提示
[root@m01 /server/scripts]# cat shoq.sh  
#!/bin/bash
if [ $# -eq 0 ];then 
echo "Usage: $0  {start|stop|restart}" 
fi


[root@m01 /server/scripts]# sh shoq.sh 
Usage: shoq.sh  {start|stop|restart}

4.*@

  • $* 取出所有参数 双引号: 1个参数一个整体
  • $@ 取出所有的参数:双引号:每个参数独立

14.特殊位置变量

image.png

15.特殊变量 状态

? 上一条命令的执行的结果 为0正确 非0失败 $$ 当前运行脚本的pid! 上一个运行脚本的pid
$_ 上一个ming6ling或脚本的最后一个参数esc+.

1.$?

  • 检查命令pid

2.$$

  • 用于记录脚本的pid 号码
  • 方便进行kill 或查询状态
  • tee 配合管道 信息输出到屏幕 信息写入到文件
  • sh pang.sh & 让脚本后台运行
  • 脚本中记录脚本的pid号码 写入到文件中
  • 后面可以方便查看或根据pid结束进程

16.变量子串

  • parameter 变量名字(参数)
  • 使用时候 遇到 含义 去哪里查找
  • man bash 参考 parameter Expansion(参数展开)
    image.png

    image.png

    基础用法
  • ${变量}
  • ${#变量} 统计变量中内容的字数(字符数)
[root@m01 ~]# oldboy=xiaolv
[root@m01 ~]# echo $oldboy
xiaolv
[root@m01 ~]# echo ${oldboy}
xiaolv
[root@m01 ~]# echo ${#oldboy}
6
[root@m01 ~]# 

1. 统计字符数方法

[root@m01 ~]# echo ${oldboy}
xiaolv
[root@m01 ~]# echo ${oldboy} |wc -L
6
[root@m01 ~]# echo ${oldboy} |awk '{print length()}'
6

面试题: I am oldboy linux,welcome to our training. 显示这串字符中 单 词字符数大于6的单词
方法一

[root@m01 /server/scripts]# cat stat.sh
#!/bin/bash
stat='I am oldboy linux,welcome to our training' 
for n in $stat
do
 if [ ${#n} -gt 6 ];then
    echo $n
fi
done
[root@m01 /server/scripts]# sh stat.sh
linux,welcome
training

2.按照范围cut

  • ${变量:起点}
  • ${变量:起点:长度}
[root@m01 /server/scripts]# test='I am oldboy teacher'
[root@m01 /server/scripts]# echo $test |cut -c1-4
I am
[root@m01 /server/scripts]# echo ${test:4}
oldboy teacher
[root@m01 /server/scripts]# echo ${test:2}
am oldboy teacher
[root@m01 /server/scripts]# echo ${test:2:4}
am o
[root@m01 /server/scripts]# echo ${test:4:6}
oldbo

3.删除

[root@m01 /server/scripts]#  test='I am oldboy teacher' 
[root@m01 /server/scripts]#  echo "${test#o}" 
I am oldboy teacher
[root@m01 /server/scripts]#  echo "${test#I}" 
 am oldboy teacher
[root@m01 /server/scripts]#  echo "${test#*o}" 
ldboy teacher
[root@m01 /server/scripts]#  echo "${test##*o}" 
y teacher     
#相当于正则^
[root@m01 /server/scripts]#  test='I am oldboy teacher' 
[root@m01 /server/scripts]#  echo "${test%o*}" 
I am oldb
[root@m01 /server/scripts]#  echo "${test%%o*}" 
I am 
%百分号从末尾开始删除

4.替换(sed)

[root@m01 /server/scripts]#  test='I am oldboy teacher' 
[root@m01 /server/scripts]# echo ${test/oldboy/oldgirl/}
I am oldgirl/ teacher
[root@m01 /server/scripts]# echo ${test/o/}
I am ldboy teacher
[root@m01 /server/scripts]# echo ${test//o/}
I am ldby teacher
[root@m01 /server/scripts]# echo ${test//[a-z]/}

[root@m01 /server/scripts]# echo ${test//[a-z]/666}
666 666666 666666666666666666 666666666666666666666

17.变量扩展

内容
含义
${parameter:-word}
如果parameter没有被赋值或者其值为空,那么
就以word作为其值。
如果parameter没有被赋值或者其值为空,那么
${parameter:=word}
就以word作为其值,且将word赋值给
parameter。
如果parameter没有被赋值或者其值为空,那么
${parameter:?word}
就把word作为错误输出否则显示parameter内
容
如果parameter没有被赋值或者其值为空,就什
${parameter:+word}
么都不做否则用word替换变量内容

1.${parameter:-word}

如果parameter没有被赋值或者其值为空,那么就以word作为其值 给变量设置默认值(初始值) 删除操作的时候 设置1个默认的目

[root@m01 /server/scripts]# test='I am oldboy teacher'
[root@m01 /server/scripts]# echo ${test:-var not define}
I am oldboy teacher
[root@m01 /server/scripts]# unset test
[root@m01 /server/scripts]# echo $test

[root@m01 /server/scripts]# echo ${test:-var not define}
var not define

2.${parameter:=word

[root@m01 /server/scripts]# test='I am oldboy teacher'
[root@m01 /server/scripts]# echo ${test:=I am linux teacher}
I am linux teacher
[root@m01 /server/scripts]# unset test
[root@m01 /server/scripts]# echo ${test:=I am linux define}
I am linux define
[root@m01 /server/scripts]# echo $test
I am linux define

3.${parameter:?word}

[root@m01 /server/scripts]# echo ${test:=?I am linux define}
I am linux define
[root@m01 /server/scripts]# echo $?
0
[root@m01 /server/scripts]# unset test
[root@m01 /server/scripts]# echp ${test:?I am linux teacher}
-bash: test: I am linux teacher
[root@m01 /server/scripts]# echo $?
1

4. ${parameter:+word}

[root@m01 /server/scripts]# echo $test

[root@m01 /server/scripts]# echo ${test:+oldboyedu}

[root@m01 /server/scripts]# test=xiaolv
[root@m01 /server/scripts]# echo ${test:+oldboyedu}
oldboyedu
[root@m01 /server/scripts]# echo $test
xiaolv

18.运算

- 运算符
+ -  * 、 %(取余)
&&
||
+=
a+=1 <->a=a+1
8/4 =2 余0
7/4 =1 余3
image.png
  • 运算方法

方法1. (())

[root@m01 /server/scripts]# a=1
[root@m01 /server/scripts]# b=2
[root@m01 /server/scripts]# echo $a+$b
1+2
[root@m01 /server/scripts]# ((c=a+b))
[root@m01 /server/scripts]# echo $c
3

方法2.let

[root@m01 /server/scripts]# let c=a+b
[root@m01 /server/scripts]# let c=a+b+b+b
[root@m01 /server/scripts]# echo $c
7

方法3.expr

* 乘号有特殊含义
[root@m01 /server/scripts]# expr 1 + 2
3
[root@m01 /server/scripts]# expr 2 * 3
expr: syntax error
[root@m01 /server/scripts]# expr 2 \* 3
6
判断参数是否为数字

方法4.bc

[root@m01 /server/scripts]# echo 10/3 |bc -l
3.33333333333333333333

方法5.$[]

不能计算小数点
[root@m01 /server/scripts]# echo $[1/3]
0
[root@m01 /server/scripts]# echo $[10**3]
1000

方法6.awk

[root@m01 /server/scripts]# awk 'BEGIN{print 1/3}'
0.333333

linux下面的计算方法统计:

种类 方法
awk 'BEGIN{}
echo + bc -l
$(())
let
expr
$[]·

1.书写简单计算器

  • 从命令行输入 2个参数 sh cal.sh 10 20

  • 计算他们的+ - * / 显示出来

  • 基础提高:参数个数不对 提示使用帮助并退出脚本

  • lnb提高:

  • 必须输入的是数字

  • 基础功能+判断 参数个数

[root@m01 /server/scripts]# cat cal-v1.sh
#!/bin/bash
num1=$1
num2=$2
echo "$1 + $2" |bc -l
echo "$1 * $2" |bc -l
echo "$1 - $2" |bc -l
echo "$1 / $2" |bc -l
[root@m01 /server/scripts]# sh cal-v1.sh 10 20
30
200
-10
.50000000000000000000
  • 基础功能+参数个数+参数是否为数字
第一种方法:
[root@m01 /server/scripts]# cat cal-v1.sh
#!/bin/bash
num1=$1
num2=$2
if [ $# -ne 2 ]
then
 echo "Usage:$0 num1 num2"
 exit 1
fi
expr $num1 + $num2 + 666 &>/dev/null
if [ $? -ne 0 ]
echo "Usage: $0 num1 num2"   
exit 2 
fi 
echo "$1 + $2" |bc -l
echo "$1 * $2" |bc -l
echo "$1 - $2" |bc -l
echo "$1 / $2" |bc -l
使用:
[root@m01 /server/scripts]# sh cal-v1.sh 1 2
3
2
-1
.50000000000000000000
第二种方法:
#!/bin/bash
read -p "请输入2个参数" num1 num2

expr $num1 + $num2 + 666 &>/dev/null
if [ $? -ne 0 ]
then
    echo "Usage: $0 num1 num2" ? 
exit 2
fi
echo "$num1 + $num2" |bc -l
echo "$num1 * $num2" |bc -l
echo "$num1 - $num2" |bc -l
echo "$num1 / $num2" |bc -l
使用
[root@m01 /server/scripts]# sh cal-v1.sh
请输入2个参数1 2
3
2
-1
.50000000000000000000

计算器书写注意方式

  • 从命令行输入两个参数 sh +脚本名称 10 20
  • 参数个数不对 提示使用帮助 并退出脚本
  • 必须输入的是数字
  • 计算他们的+-*/ 显示出来

**项目分析:(拆解)1 2 3

  • 输入两个参数
  • 判断参数个数
  • 判断这些参数是否为数字
  • 进行计算
image.png

19.条件测试语

  • 以后用于各种判断中的条件
  • 文件相关表达式
  • 字符串对比
    格式
    test <条件>
    [<条件>] 一般情通用
    [[<条件>]] [] 升级版 支持正则表达式
    ((<条件>))

1.文件

  • 与文件相关的判断 /条件
名称 含义
-d directory 目录是否存在
-f file 文件是否存在
-e exist 是否存在
-r read 文件是否存在 并且 是否有r权限
-w write 文件是否存在 并且 是否有w权限
-x execute 文件时候存在 并且 是否有x权限
-s size 文件是否存在 并且 是否为空 大于0成立
-L Symlink (symbolic link) 判断文件是否存在 是否为软连接
/etc/hosts 文件存在 输出1 不存在输出0
[root@m01 ~]# test -f /etc/hosts && echo 1 || echo 0
1
/etc/ho 文件存在 输出1 不存在输出0
[root@m01 ~]# test -f /etc/hos && echo 1 || echo 0
0
/etc/ho 目录存在 输出1 不存在输出0
[root@m01 ~]# test -d /etc/hos && echo 1 || echo 0
0
文件是否存在并且拥有x权限输出1 否则输出0
[root@m01 ~]# test -x /etc/rc.local && echo 1 || echo 0
0
文件是否存在并且拥有x权限输出1 否则输出0
[root@m01 ~]# [ -x /etc/rc.d/rc.local ] && echo 1 || echo 0
0

系统脚本判断案列:

如果不是文件 退出并输出6 
#!/bin/bash

if [ ! -f /etc/sysconfig/network ];then
   exit 6
fi
[root@m01 /server/scripts]# sh then.sh
[root@m01 /server/scripts]# echo $?
0

** 常用的格式**

满足条件 执行某个命令
[ 条件 ] && 命令

满足条件 执行多条命令
[ 条件 ] && {
cmd1
cmd2
}
[ 条件 ] || 命令
[ 条件 ] || {
cmd1
cmd2
}

20.字符串

表达式 含义
-n not zero 如果变量/字符串不是空的
-z zero 如果变量/字符串是空
"串1 "= 判断两个字符串/变量内容 是否一致 如果相等 则 成立
"串2 " true 温馨提示加上双引号
"串1"! = 判断两个字符串 /变量内容 是否一致 如果不相等 则成立
"串2" true
没有定义变量  为空 输出1
[root@m01 /server/scripts]# [ -z "$oldboy" ] && echo 1 || echo 0
1
定义了变量 不为空 输出0
[root@m01 /server/scripts]# oldboy=1
[root@m01 /server/scripts]# [ -z "$oldboy" ] && echo 1 || echo 0
0
为18输出1 不为输出0
[root@m01 /server/scripts]# oldboy=28
[root@m01 /server/scripts]# [ "x$oldboy" = "x18" ] && echo 1 || echo 0
0

字符串比较注意事项

  • 字符串比较必须加引号
  • 使用!=或=使用空格
  • !=或=比较字符串是否相同
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,381评论 0 5
  • Shell入门 什么是shell? Shell其实是一个命令解释器,作用是解释执行用户输入的命令以及程序等,用户每...
    酷酷的伟阅读 425评论 0 1
  • 搭配《linux就该这样学》第四章内容 1.shell历史 Shell的作用是解释执行用户的命令,用户输入一条命令...
    木鱼_cc阅读 846评论 0 10
  • 本文是对Linux shell编程的一个学习比较,共包括如下章节的内容: 概述 基本语法 结构化语句 函数 小结 ...
    我是老薛阅读 830评论 0 5
  • Bash内置基本变量 PWD : 显示当前的工作目录 OLDPWD : 显示上一次的工作目录 ~:用户家目录 - ...
    魏镇坪阅读 1,525评论 0 6