编程逻辑处理方式
顺序执行:程序按从上到下顺序执行
选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
循环执行:程序执行过程中需要重复执行多次某段语句
shell 脚本基本结构
shell脚本编程:是基于过程式、解释执行的语言
编程语言的基本结构:
各种系统命令的组合
数据存储:变量、数组
表达式:a + b
控制语句:if
shell脚本:包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell脚本创建过程
第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列:#!
示例:
#!/bin/bash
添加注释,注释以#开头
第二步:加执行权限
给予执行权限,在命令行上指定脚本的绝对或相对路径
第三步:运行脚本
直接运行解释器,将脚本作为解释器程序的参数运行
shell 脚本注释规范
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明
第一个 shell 脚本
#!SHEBANG
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE
#执行方法1
[root@centos8 ~]# bash /data/hello.sh
#执行方法2
[root@centos8 ~]# cat /data/hello.sh | bash
#执行方法3
[root@centos8 ~]# bash < /data/hello.sh
#执行方法4
[root@centos8 ~]# chmod +x /data/hello.sh
#绝对路径
[root@centos8 ~]#/data/hello.sh
#相法路径
[root@centos8 ~]# cd /data/
[root@centos8 ~]#./hello.sh
#执行方法5,本方法可以实现执行远程主机的shell脚本
[root@centos8 ~]# yum -y install httpd
[root@centos8 ~]# systemctl start httpd
[root@centos8 ~]# mv /data/hello.sh /var/www/html/
[root@centos8 ~]# curl http://10.0.0.8/hello.sh
范例:执行远程主机的脚本
[root@centos8 ~]# curl http://10.0.0.8/hello.sh 2>/dev/null |bash
hello, world
Hello, world!
[root@centos8 ~]# curl http://10.0.0.8/hello.sh >/dev/null |bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 388 100 388 0 0 378k 0 --:--:-- --:--:-- --:--:-- 378k
[root@centos8 ~]# wget -qO - http://www.wangxiaochun.com/testdir/hello.sh | bash
hello, world
Hello, world!
备份脚本
#!/bin/bash
#
#********************************************************************
#Author: xuanlv
#QQ: xxxxxxxxxx
#Date: 2021-04-18
#FileName: backup.sh
#URL: https://www.cnblogs.com/xuanlv-0413/
#Description: The test script
#Copyright (C): 2021 All rights reserved
#********************************************************************
echo -e " 33[1;32mStarting backup... 33[0m"
sleep 2
cp -av /etc/ /data/etc`date +%F`/
echo -e " 33[1;32mBackup is finished 33[0m"
shell 脚本调试
只检测脚本中的语法错误,但无法检查出命令错误,但不真正执行脚本
bash -n /path/to/some_script
调试并执行
bash -x /path/to/some_script
范例:
root@long:~# cat -A test.sh
#!/bin/bash$
#$
#********************************************************************$
#Author:^I^Ixuanlv$
#QQ: ^I^I^I3xxxxxx$
#Date: ^I^I^I2021-04-18$
#FileNameM-oM-<M-^Z^I^Itest.sh$
#URL: ^I^I^Ihttps://www.cnblogs.com/xuanlv-0413/$
#DescriptionM-oM-<M-^Z^I^IThe test script$
#Copyright (C): ^I2021 All rights reserved$
#********************************************************************$
echo line$
hostname$
cat > test.txt <<EOF $
aaa$
fadf$
ccc$
ddd$
EOF $
$
echo line233$
root@long:~# bash -n test.sh
test.sh: line 21: warning: here-document at line 14 delimited by end-of-file (wanted `EOF')
总结:脚本错误常见的有三种
语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的
命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进行观察
逻辑错误:只能使用 bash -x 进行观察
变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据
变量类型
内置变量,如:PS1,PATH,UID,HOSTNAME,$$,BASHPID,PPID,$?,HISTSIZE
用户自定义变量
不同的变量存放的数据不同,决定了以下
数据存储方式
参与的运算
表示的数据范围
变量数据类型:
字符
数值:整型、浮点型,bash 不支持浮点数
编程语言分类
静态和动态语言
静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查,如:java,c
动态编译语言:不用事先声明,可随时改变类型,如:bash,Python
强类型和弱类型语言
强类型语言:不同类型数据操作,必须经过强制转换才同一类型才能运算,如java , c# ,
python
如:参考以下 python 代码
print('magedu'+ 10) 提示出错,不会自动转换类型
print('magedu'+str(10)) 结果为magedu10,需要显示转换类型
弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会
自动进行隐式类型转换;变量无须事先定义可直接调用
如:bash ,php,javascript
Shell中变量命名法则
命名要求
区分大小写
不能使程序中的保留字和内置变量:如:if, for
只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
命名习惯
见名知义,用英文单词命名,并体现出实际作用,不要用简写,如:ATM
变量名大写
局部变量小写
函数名小写
大驼峰StudentFirstName
小驼峰studentFirstName
下划线: student_name
变量定义和引用
变量的生效范围等标准划分变量类型
普通变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
变量赋值:
name='value'
value 可以是以下多种形式
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
变量引用
$name
${name}
弱引用和强引用
"$name " 弱引用,其中的变量引用会被替换为变量值
'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
范例:变量的各种赋值方式和引用
root@long:~# TITLE='cto'
root@long:~# echo $TITLE
cto
root@long:~# echo I am $TITLE
I am cto
root@long:~# echo "I am $TITLE"
I am cto
root@long:~# echo 'I am $TITLE'
I am $TITLE
root@long:~#
root@long:~# NAME=$USER
root@long:~# echo $NAME
root
root@long:~# USER=`whoami`
root@long:~# echo $USER
root
root@long:~# FILE=`ls /home`
root@long:~# echo $FILE
long
root@long:~#
root@long:~# FILE=/etc/*
root@long:~# echo $FILE
/etc/acpi /etc/adduser.conf /etc/alternatives /etc/apm /etc/apparmor /etc/apparmor.d /etc/apport /etc/apt /etc/at.deny /etc/bash.bashrc /etc/bash_completion /etc/bash_completion.d /etc/bindresvport.blacklist /etc/binfmt.d /etc/byobu /etc/ca-certificates
root@long:~# seq 10
1
2
3
4
5
6
7
8
9
10
root@long:~# NUM=`seq 10`
root@long:~# echo $NUM
1 2 3 4 5 6 7 8 9 1
root@long:~# echo "$NUM"
1
2
3
4
5
6
7
8
9
10
root@long:~# NAMES="long
> wang
> zhi
> shi"
root@long:~# echo $NAMES
long wang zhi shi
root@long:~# echo "$NAMES"
long
wang
zhi
shi
范例:变量引用
root@long:~# NAME=long
root@long:~# AGE=20
root@long:~# echo $NAME
long
root@long:~# echo $AGE
20
root@long:~# echo $NAME $AGE
long 20
root@long:~# echo $NAME$AGE
long20
root@long:~# echo $NAME_$AGE
20
root@long:~# echo ${NAME}_$AGE
long_20
范例:变量的间接赋值和引用
root@long:~# TITLE=cto
root@long:~# NAME=long
root@long:~# TITLE=$NAME
root@long:~# echo $NAME
long
root@long:~# echo $TITLE
long
root@long:~# NAME=wang
root@long:~# echo $NAME
wang
root@long:~# echo $TITLE
long
范例:变量追加值
root@long:~# TITLE=cto
root@long:~# TITLE+=:long
root@long:~# echo $TITLE
cto:long
范例:利用变量实现动态命令
root@BJ-long:~# CMD=hostname
root@BJ-long:~# $CMD
BJ-long.longUbuntu.local
显示已定义的所有变量:
set
删除变量:
unset <name>
范例:
root@BJ-long:~# vim backup2.sh
#!/bin/bash
#
#********************************************************************
#Author: xuanlv
#QQ: xxxxxxx
#Date: 2021-04-18
#FileName: backup2.sh
#URL: https://www.cnblogs.com/xuanlv-0413/
#Description: The test script
#Copyright (C): 2021 All rights reserved
#********************************************************************
COLOR='echo -e E[1;35'
END='E[0m'
BACKUP=/backup
SRC=/etc
DATE=`data +%F`
${COLOR}Starting backup...$END
sleep 2
cp -av $SRC ${BACKUP}${SRC}_$DATE
${COLOR}Backup is finished$END