脚本基础学习
1.脚本————Bash脚本类似批处理,简单来讲就是把许多的指令集合在一起,并提供循环、条件、判断等重要功能,语法简单实用,用以编写程序,大大简化管理员的操作,并可以完成图形工具所无法实现的功能。
2.如何创建新shell脚本?
1)创建包含bash命令的文本文件。文件的第一行应为:
#!/bin/bash
2)使文件可执行(使用chmod +xscripts)
3)将文件放置在用户的$PATH的目录中
~/bin–用于用户的私有程序
/usr/local/bin–本地开发、系统上的其他人使用的脚本
/usr/local/sbin -本地开发、由root使用的脚本
[root@desktop6 mnt]# vim test.sh ##.sh结束表示脚本
#!/bin/bash ##/bin/bash指定脚本类型
cat ##脚本内容
[root@desktop6 mnt]# chmod +x test.sh ##授权
[root@desktop6 mnt]# /mnt/test.sh ##执行命令
^Z ##ctrl+z打入后台
[1]+ Stopped /mnt/test.sh
[root@desktop6 mnt]# ps f ##查看进程
PIDTTY STAT TIME COMMAND
2209pts/0 Ss 0:00 -bash
6307pts/0 T 0:00 \_ /bin/bash /mnt/test.sh
6308pts/0 T 0:00 | \_ cat
6310pts/0 R+ 0:00 \_ ps f
598tty1 Ss+ 0:01 /usr/bin/Xorg :0 -background none-verbose -auth /run
[root@desktop6 mnt]# vim test.sh
[root@desktop6 mnt]# cat test.sh
#!/bin/bash
echo hello
[root@desktop6 mnt]# sh -x test.sh ##执行命令时加-x可以显示脚本执行过程
+ echo hello
hello
3.引用和转义
引用和转义在shell解析字符串时用于去除字符串中特殊字符或保留词语的特殊含义。这会导致按字面处理字符串,而不是展开变量或将其部分内容视作具有特殊含义。
引用有三种类型:弱引用强引用 转义
弱引用————将字符串放置在双引号中,保留字符串中所有字符的文字值,$、`、\和!字符除外。换言之,变量扩展和命令扩展在双引号内仍起作用。
echo “can I have a $FRUIT“
echo“The current time is $(date +%r).”(echo“The current timeis `date +%r`.”)
[root@desktop6 mnt]# TIME=date
[root@desktop6 mnt]# echo $TIME ##输出TIME代表的字符
date
[root@desktop6 mnt]# TIME=`date` ##反单引号表示先执行此命令
[root@desktop6 mnt]# echo $TIME
Mon Jun 12 10:19:49 EDT 2017
[root@desktop6 mnt]# echo \$TIME ##\表示引用字符的文字值,且为弱引用
$TIME
强引用—————将字符串放置在单引号中,保留字符串中所有字符的文字值,同时禁用所有扩展:
echo “Make $$$ Fast”
rm 'untitled folder'
转义——————非引用的\是转义字符。它保留了下一个字符的文字值。(例如,\$PATH是确切的字符串$PATH,而不是PATH变量的内容。)
echo Make \$\$\$ Fast\!
ls untitled\ folder
[root@desktop6 mnt]# echo'###date###=`date`' ##单引号为强引用,单引号中的字符串保留原有的文字值
###date###=`date`
[root@desktop6 mnt]# echo ###date###=`date`##井号将后面的内容注释掉,无内容显示
[root@desktop6 mnt]# echo"####date####=`date`" ##双引号为弱引,去掉了#的引用,却没有去掉单引号的引用,在这里#保留原来的文字值,而单引号则为特殊字符,表示执行函数
####date####=Mon Jun 12 19:34:50 EDT 2017
[root@desktop6 mnt]# echo"###date###=$date" ##双引号为弱引,去掉了#的引用,却没有去掉$的引用,在这里#保留原来的文字值,而$则为特殊字符,表示变量,因为变量没有被赋值,所以显示为空
###date###=
[root@desktop6 mnt]# echo"###date###=\date"##双引号为弱引,\为转义字符,表示保留下一个字符的文字值
###date###=\date
[root@desktop6 mnt]# echo"###date###=$(date)" ##$()和``的用法相同,表示执行此函数
###date###=Mon Jun 12 19:35:53 EDT 2017
4.Shell变量
shell变量用于为稍后在脚本中使用的名称指定值,并且仅限于shell命令行或从中声明变量的脚本。
若要定义或指定值:
FRUIT=apple
若要参考或使用变量:
$FRUIT
${FRUIT}
[root@server0 ~]# FIRST=John
[root@server0 ~]# LAST=Doe
[root@server0 ~]# echo $FIRST $LAST
John Doe
[root@server0 ~]# echo $FIRST_$LAST
Doe
[root@server0 ~]# echo ${FIRST}_$LAST
John_Doe
5.命令替换
命令替换在子shell中执行指定命令并用命令输出替换脚本中的命令替换。
语法:
$(shell command)
示例:
touch datafile.$(id -un)
TODAY=$(date +%Y-%m-%d)
[root@server0 ~]# TAROUTPUT=$(tar cvf/tmp/backup.tar $(find /etc -type f -mtime 1))
tar: Removing leading `/' from member names
[root@server0 ~]# echo $TAROUTPUT
/etc/hosts.allow /etc/hosts.deny/etc/sysconfig/iptables /etc/xinetd.d/tftp /etc/rht
/etc/firewalld/zones/public.xml.old/etc/firewalld/firewalld.conf.old /etc/xinetd.conf
6.算术运算符
算术运算符指的是可以在程序中实现加、减、乘、除等数学运算的运算符。
operator meaning
<VARIABLE>++增量后
<VARIABLE>--减量后
-减法
+加法
**幂运算
*乘法
/除法
%余数
+=加等
-=减等
7.Shell计算命令:
用$[]表示数学运算。
# echo $[1+2]
# a=1; echo $[$[$a+1]*2]
用expr表示数学运算。
# echo `expr 1 + 2`
用let指示数学运算。
# let A=1+2
# echo $A
用(())表示数学运算。bash内建功能,效率高。
#!/bin/bash
for ((i=1;i<10;i++))
do
((j+=i))
done
echo $j
8.循环
for循环用于值列表中的相同命令的重复。
[root@desktop6 mnt]# for NUM in 1 two 3four 5 six ;do echo $NUM ;done ##循环显示变量NUM的值
1
two
3
four
5
six
[root@desktop6 mnt]# for NUM in 1 two 3four 5 six ;do echo $NUM;sleep 1 ;done ##sleep1表示隔一秒显示一次
1
two
3
four
5
six
[root@desktop6 mnt]# for NUM in {1..6};doecho $NUM ;done ##循环显示1到6的值
1
2
3
4
5
6
[root@desktop6 mnt]# for NUM in `seq 1 26`;do echo $NUM ;done##seq 1 2 6 表示从1到6,隔两个显示一次
1
3
5
脚本示例
执行效果:用脚本检测主机1到10的网络是否通着,通着的小时该主机ip is up,否则显示down
[root@desktop6 mnt]# vim test.sh
#!/bin/bash
for NUM in {1..10}
do
ping-c1 -w1 172.25.254.$NUM &> /dev/null && echo 172.25.254.$NUM isup || echo 172.25.254.$NUM is down
done
[root@desktop6 mnt]# sh test.sh
172.25.254.1 is down
172.25.254.2 is down
172.25.254.3 is down
172.25.254.4 is down
172.25.254.5 is down
172.25.254.6 is up
172.25.254.7 is down
172.25.254.8 is down
172.25.254.9 is down
172.25.254.10 is down
执行效果:用create_user.sh脚本自动建立username文件中的所有用户,remove_user.sh脚本自动删除username文件中的所有用户
[root@desktop6 mnt]# vim username
user1
user2
user3
[root@desktop6 mnt]# vim create_user.sh
#!/bin/bash
for NAME in `cat $1`
do
useradd$NAME
done
[root@desktop6 mnt]# chmod +xcreate_user.sh
[root@desktop6 mnt]# sh create_user.shusername
[root@desktop6 mnt]# id user1
uid=1001(user1) gid=1001(user1)groups=1001(user1)
[root@desktop6 mnt]# vim remove_user.sh
#!/bin/bash
for NAME in `cat $1`
do
useradd$NAME
done
[root@desktop6 mnt]# vim remove_user.sh
#!/bin/bash
for NAME in `cat $1`
do
userdel-r $NAME
done
[root@desktop6 mnt]# chmod +xremove_user.sh
[root@desktop6 mnt]# sh remove_user.shusername
[root@desktop6 mnt]# id user1
id: user1: no such user
实现效果:用脚本cp_file.sh实现将/etc/所有以.conf结尾的文件复制到目录/mnt/的一个目录并以复制文件的时间为目录名,名格式为etc.conf-年-月-日-秒
[root@desktop6 mnt]# vim cp_file.sh
#!/bin/bash
NAME=etc.conf-`date +%Y-%m-%d-%S`
mkdir -p /mnt/$NAME
cp /etc/*.conf /mnt/$NAME
[root@desktop6 mnt]# chmod +x cp_file.sh
[root@desktop6 mnt]# sh cp_file.sh
[root@desktop6 mnt]# ls
cp_file.sh etc.conf-2017-06-12-57 multiuser nfsshare
实现效果:10s倒计时
[root@desktop6 mnt]# vim time.sh ##-n表示不换行
#!/bin/bash
for ((SEC=10;SEC>0;SEC--))
do
echo-n After ${SEC}s is end
echo-ne "\r\r"
sleep1
done
[root@desktop6 mnt]# chmod +x time.sh
实现效果:1分10s倒计时
步骤:
1.分钟不变,妙递减
2.当分钟等于0,秒等于0,脚本立即退出
3.分钟大于等于0,秒等于0时,分钟-1,秒=59
9.循环与计算结合:
#!/bin/bash
for ((i=1;i<=100;i++))
do
((j+=i))
#j=`expr $j + $i`
#let j+=i
#j=$[j+=i]
done
echo $j
也可以写成一行:
# for((i=0; i<=100; i++));do j=`expr $j+ $i` ;done;echo $j
13.数据库备份示例:
#!/bin/bash
for DB in $(mysql -e "showdatabases;" -E -N | grep -v '^*' | grep -v 'schema$')
do
echo "Backing up $DB"
mysqldump $DB > /dbbackup/$DB.dump
done
echo ""
for DBDUMP in /dbbackup/*
do
SIZE=$(stat --printf "%s\n"$DBDUMP)
echo "$DBDUMP
$SIZE"
done
[root@server6 ~]# mysql -uroot -pfentiao -e"show databases;" -N -E | grep -E '\*|schema$' -v
#显示数据库不包括以schema结尾的
mysql
westosinfo
[root@server6 ~]# stat --print"%s\n" /etc/passwd##统计文件字节数/byte
2239
[root@server6 ~]# wc -c /etc/passwd
2239 /etc/passwd
[root@server6 ~]# du /etc/passwd
4 /etc/passwd
[root@server6 ~]# du -h /etc/passwd##大小/k
4.0K /etc/passwd
脚本实现:备份数据库并显示大小,并以时间命名
[root@server6 mnt]# vim cp_mysql.sh
#!/bin/bash
mkdir -p /mnt/DB_BACK
for DB in `mysql -uroot -e "show databases;" -N -E | grep-E '\*|schema$' -v`
do
DBNAME=$DB-`date +%Y-%m-%d-%S`
echo "Backing up $DB"
mysqldump $DB > /mnt/DB_BACK/$DBNAME
done
for DBNAME in `ls /mnt/DB_BACK/*`
do
SIZE=`stat--print "%s\n" $DBNAME`
echo"$DBNAME is $SIZE byte"
done
脚本实现:给一个ip判断网络是否可以通,没有给ip提示输入ip
[root@desktop6 mnt]# vim test.sh
#!/bin/bash
while [ "$#" -eq "0" ]
do
echo"please give me a ip address!"
exit1
done
ping-c1 -w1 $1 >/dev/null && echo "$1 is up" || echo "$1is down"
[root@desktop6 mnt]# sh test.sh
please give me a ip address!
[root@desktop6 mnt]# sh test.sh 172.25.6.11
172.25.6.11 is up
[root@desktop6 mnt]# sh test.sh 172.25.6.10
172.25.6.10 is up
[root@desktop6 mnt]# sh test.sh 172.25.6.90
172.25.6.90 is down
脚本实现:判断文件或目录是否存在
[root@desktop6 mnt]# vim check_file.sh
#!/biin/bash
ls $1 &> /dev/null
[ "$?" -eq "0" ]&& echo $1 is exist || echo $1 is not exist
[root@desktop6 mnt]# chmod +x check_file.sh
[root@desktop6 mnt]# sh check_file.sh /mnt
/mnt is exist
[root@desktop6 mnt]# sh check_file.sh /ll
/ll is not exist