- shell使用户与Linux操作系统之间沟通的桥梁,用户可以通过输入命令执行,又可以利用shell脚本编程去运行
- Linux shell种类
- bourne shell(usr/bin/sh或/bin/sh)
- bourne again shell(/bin/bash)
- C shell(/usr/bin/csh)
- K shell(/usr/bin/ksh)
- shell for root(/sbin/sh)
- 不同的shell语言的语法有所不同,一般不能交换使用,最常用的shell是bash,也就是bourne again shell(/bin/bash).bash由于易用和免费,是大多数操作系统默认的shell环境
- 简单来说,shell是一个整体的概念,shell编程与shell脚本统称为shell编程,shell命令是shell编程底层具体的语句和实现方法
shell脚本及Hello World
- shell脚本编程注意事项:
- shell脚本名称命名一般为英文的大写、小写
- 不能使用特殊符号、空格来命名
- shell脚本后缀以.sh结尾
- 不建议shell命名为纯数字,一般以脚本功能命名
- shell脚本内容首行需要以#!/bin/bash开头
- shell脚本中变量名称尽量使用大写字母,字母间不可以使用"-",可以使用"_"
- shell脚本变量名称不能以数字、特殊符号开头
- 第一个shell编程脚本,脚本名称为first_shell.sh
-
!bin/bash:固定格式,定义该脚本所使用的的shell类型
-
# This is my First shell
:#表示注释,没有任何意义,shell不会解析 - echo "Hello World":shell脚本主命令,执行该脚本所呈现的内容
-
#!bin/bash
# This is my First shell
echo "Hello World"
- shell脚本编写完毕,如果运行该脚本,运行用户需要有执行权限,可以使用chomd o+x first_shell.sh赋予可执行权限.然后./first_shell.sh执行即可,还可以使用命令/bin/sh first_shell.sh直接运行脚本,不需要执行权限,最终执行显示效果一样
shell编程之变量
- shell属于非类型的解释型语言,在使用变量时不像C++、JAVA语言编程时需要事先声明变量,shell给一个变量赋值,实际上就是定义了变量,在Linux支持的所有shell中,都可以用赋值符合"="为变量赋值,shell为弱类型语言,定义变量不需要声明变量类型,如果在使用时需要明确变量的类型,可以使用declare指定类型,declare常见参数如下:
- +/-:"-"可以用来指定变量的属性,"+"为取消变量所设的属性
- -f:仅显示函数
- r:将变量设置为只读
- x:指定的变量会变为环境变量,可供shell以外的程序来使用
- i:指定类型为数值,字符串或运算式
- shell编程中变量分为3种:系统变量、环境变量、用户变量,其中系统变量在对参数判断和命令返回值判断时使用,而环境变量则主要是在程序运行时需要设置,用户变量又称为局部变量,多使用在shell脚本内部或者临时局部
- shell变量名在定义时,首个字符必须为(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线"_",不能使用"-",也不能使用标点符号等
- 例如定义变量A=apple,定义这样一个变量,A为变量名,apple是变量的值,变量名有规范格式,变量的值可以随意指定.变量定义完成,如需要引用变量,可以使用$A
#!bin/bash
A=apple
echo "这个变量的值是$A"
# 执行该脚本,显示的结果为-------这个变量的值是apple
- shell常见的系统变量、环境变量、用户变量
- 系统变量
- $0:当前脚本名称
- $n:当前脚本的第n个参数
- $*:当前脚本的所有参数(不包括程序本身)
- $#:当前脚本的参数个数(不包括程序本身)
- $?:命令或程序执行完后的状态,返回0表示执行成功
- $$:程序本身的PID号
- 环境变量
- PATH:命令所示路径,以冒号为分割
- HOME:打印用户家目录
- SHELL:显示当前shell类型
- USER:打印当前用户名
- ID:打印当前用户ID信息
- PWD:显示当前所在路径
- TERM:打印当前终端类型
- HOSTNAME:显示当前主机名
- 用户变量
- A=apple
- 系统变量
if条件语句
- if条件判断语句,通常以if开头,fi结尾.也可以加入else或者elif进行多条件的判断,if表达式如下
if (表达式)
语句1
else
语句2
fi
- 比较两个整数大小
#!/bin/bash
NUM=100
if (( $NUM>4 ));then
echo "数字$NUM大于4"
else
echo "数字$NUM小于4"
fi
- 判断系统目录是否存在
#!/bin/bash
if [ ! -d /data/0326 ];then
mkdir -p /data/0326
else
echo '目录或文件已存在'
fi
-
if常见的判断逻辑运算符
- -f:判断文件是否存在,例如if[-f filename]
- -d:判断目录是否存在,例如if[-d dir]
- -eq:等于,应用于整型比较,即equal
- -ne:不等于,应用于整型比较,即not equal
- -lt:小于,应用于整型比较,即letter
- -gt:大于,应用于整型比较,即greater
- -le:小于等于,应用于整型比较
- -ge:大于等于,应用于整型比较
- -a:双方都成立(and),用法为逻辑表达式-a
- -o:单方成立(or),用法为逻辑表达式-o
- -z:空字符串
- ||:单方成立
- &&:双方都成立表达式
多条件判断
#!/bin/bash
scores=$1
if [[ $scores -eq 100 ]];then
echo "very good"
elif [[ $scores -gt 85 ]];then
echo "good"
elif [[ $scores -gt 60 ]];then
echo "pass"
else
echo "no pass"
fi
if判断括号区别
- ():用于多个命令组、命令替换、初始化数组
- (()):整数扩展、运算符、重定义变量值、算术运算比较
-
[]
:bash内部命令,"["与test是等同的,正则字符范围、引用数组元素编号,不支持"+"、"-"、"*"、"/"数学运算符,逻辑测试使用-a、-o -
[[]]
:bash程序语言的关键字,不是一个命令,[[]]结构比[]结构更加通用,不支持"+"、"-"、"*"、"/"数学运算符,逻辑测试使用&&、|| - {}:主要用于命令集合或者范围,例如mkdir -p /data{1..10}
MySQL数据库备份脚本
#!/bin/bash
# auto backup mysql
BAK_DIR=/data/backup/mysql/`date +%F`
MYSQLDB=test
NYSQLPW=123456
MYSQLUSR=root
# must use root user run scripts 必须使用root用户运行,$UID为系统变量
if [ $UID -ne 0 ];then
echo "This script must use the root user "
sleep 2
exit 0
fi
# Define DIRand mkdir 判断目录是否存在,不存在则创建
if [ ! -d $BAK_DIR ];then
mkdir -p $BAK_DIR
fi
# Use mysqldump backup Databases
/usr/local/mysql/bin/mysqldump -u$MYSQLUSR -p$NYSQLPW -d $MYSQLDB > $BAK_DIR/db.sql
echo "The mysql backup successfully"
for循环语句
- for循环语句主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表.其语法格式以for...do开头,done结尾
for var in (表达式);do
语句
done
- 循环打印1-100数字,seq表示列出数据范围
#!/bin/bash
for num in `seq 1 10`;do
echo $num
done
- for循环求1-100的和
#!/bin/bash
SUM=0
for (( i=1;i<=100;i++ ));do
SUM=`expr $i + $SUM`
done
echo $SUM
- 对系统日志文件进行打包
#!/bin/bash
for i in `find /var/log -type f -name '*.log'`;do
tar zcf `date +%F`.tar.gz $i
done
- for循环批量远程主机文件传输
#!/bin/bash
for i in `seq 100 200`;do
scp -r /tmp/file.txt [email protected].$i:/data
done
- for循环批量远程主机执行命令
#!/bin/bash
for i in `seq 100 200`;do
ssh -l root 10.0.0.$i 'ls /opt'
done
- for循环打印10s等待提示
#!/bin/bash
for (( i=1;i<=10;i++ ));do
echo -ne "\033[32m-\033[0m"
sleep 1
done
echo
while循环语句
- while循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环,其语法格式以while...do开头,done结尾
while (表达式);do
语句
done
- 循环打印文件中的域名
cat test.txt
www.baidu.com
www.ali.com
www.qq.com
vim pra.sh
#!/bin/bash
while read line;do
echo $line
done < test.txt
- while无限每秒输出Hello World
#!/bin/bash
while sleep 1;do
echo -e "\033[32mHello World.\033[0m"
done
- 循环打印1-100数字,expr用于逻辑运算
#!/bin/bash
i=1
while (( i<=100 ));do
echo $i
i=`expr $i + 1`
done
- while循环求1-100的和
#!/bin/bash
NUM=1
SUM=0
while (( NUM<=100 ));do
SUM=`expr $NUM + $SUM`
(( NUM++ ))
done
echo $SUM
- while逐行读取文件
#!/bin/bash
while read line;do
echo $line
done < /root/test/test.txt
- 每5秒判断/etc/passwd是否被非法修改
#!/bin/bash
FILE_PATH=/etc/passwd
while true;do
echo "The Time is `date +%F`"
OLD=`md5sum $FILE_PATH|cut -d" " -f 1`
sleep 5
NEW=`md5sum $FILE_PATH|cut -d" " -f 1`
if [[ $OLD != $NEW ]];then
echo "The $FILE_PATH has been modified"
fi
done
- 每10s循环判断用户是否登录系统
#!/bin/bash
USER=test
while true;do
echo "The Time is `date +%F`"
sleep 10
NUM = `who|grep "$USER"|wc -l`
if [[ $NUM -ge 1 ]];then
echo "The $USER is login in system"
fi
done
case选择语句
- case选择语句主要用于对多个选择条件进行匹配输出,与if...elif语句结构类似,通常用于脚本传递输出参数,打印出输出结果及内容,其语法格式以case...in开头,esac结尾
#!/bin/bash
case $1 in
Pattern1)
语句1
;;
Pattern2)
语句2
;;
Pattern3)
语句3
;;
esac
- 打印monitor及archive选择菜单
#!/bin/bash
case $1 in
monitor)
monitor_log
;;
archive)
archiver_log
;;
help)
echo -e "\033[32mUsage:{$0 monitor |archive |help}\033[0m"
;;
*)
echo -e "\033[32mUsage:{$0 monitor |archive |help}\033[0m"
esac
select选择语句
- select选择语句一般用于选择,常用于选择菜单的创建,可以配合PS3来打印菜单的输出信息,其语法格式以select...in do开头,done结尾
select i in (表达式);do
语句
done
- 打印操作系统选择
#!/bin/bash
PS3="select system"
select i in Centos Ubuntu Windows;do
echo "your select system: "$i
done
- 打印LAMP选择菜单
#!/bin/bash
PS3="select system"
select i in http MySQL PHP quit;do
case $i in
http)
echo Test Httpd
;;
MySQL)
echo Test MySQL
;;
PHP)
echo Test PHP
;;
quit)
echo The System exit
exit
esac
done
shell编程函数
- shell允许将一组命令集或者语句形成一个可用块,这些块称为shell函数,shell函数的好处在于只需定义一次,后期随时使用,无须在shell脚本中添加重复的语句块,其语法格式为以"function name(){"开头,以"}"结尾
- shell编程函数默认不能将参数传入()内部,shell函数参数传递在调用函数名称时传递,例如name argv1 argv2
function name(){
command1
command2
...
}
name argv1 argv2
- 创建Apache软件安装函数,给函数Apache_install传递参数1
#!/bin/bash
H_FILES=httpd-2.2.31.tar.bz2
HFILES_DIR=httpd-2.2.31
H_PREFIX=/usr/local/apache
H_URL=http://mirrors.cnnic.cn/apache/httpd/
function apache_install(){
if [[ $1 -eq 1 ]];then
wget -c $H_URL/$H_FILES && tar -xf $H_FILES && cd $HFILES_DIR &&./configure --prefix=$H_PREFIX
if [[ $? -eq0 ]];then
make && make install
echo -e "\n\033[32m---------------------------\033[0m"
echo -e "\033[32mThe $HFILES_DIR Server Install Success!\033[0m"
else
echo -e "\033[32mThe $HFILES_DIR Make or Make install ERROR,Please Check..."
exit 0
fi
fi
}
apache_install 1
shell数组编程
- 数组是相同数据类型的元素按一定顺序排列的集合,把有限个类型相同的变量用一个名字命名,然后用编号区分它们变量的集合,这个名称即为数组名,编号即为下标.Linux shell编程中常用一维数组
- 数组的设计实际上是为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式,以减少重复频繁的单独定义
- 定义数组一般以小括号的方式来定义,数组的值可以随机指定,以下为一维数组的定义、统计、引用和删除
- 一维数组的定义及创建
CITY=(
beijing
tianjin
shanghai
)
LAMP=(httpd php php-devel php-mysql mysql mysql-server)
- 数组下标一般从0开始,引用数组的方法为
- echo ${CITY[0]}:引用第一个数组变量
- echo ${CITY[1]}:引用第二个数组变量
- echo ${CITY[@]}:显示该数组所有参数
- echo ${#CITY[@]}:显示该数组参数个数
- echo ${#CITY[0]}:显示beijing字符长度
- echo ${CITY[@]:0}:打印所有数组的值
- echo ${CITY[@]:1}:打印从第二个值开始的所有值
- echo ${CITY[@]:0:2}:打印第一个值与第二个值
- echo ${CITY[@]:1:2}:打印第二个值与第三个值
- 数组替换操作
- CITY=([0]=www1 [1]=www2 [2]=www3):数组赋值
- echo ${CITY[@]/beijing/nanjing}:将数组值beijing替换为nanjing
- NEWCITY=
echo ${CITY[@]/beijing/nanjing}
- 数组删除操作
- unset array[0]:删除数组第一个值
- unset array[1]:删除数组第二个值
- unset array:删除整个数组