####脚本####
Bash脚本基础
BASH = GNU Bourne-Again Shell,BASH 是 GNU 组织开发和推广的一个项目。Bash脚本类似批处理,简单来讲就是把许多的指令集合在一起,并提供循环、条件、判断等重要功能,语法简单实用,用以编写程序,大大简化管理员的操作,并可以完成图形工具所无法实现的功能。
1.脚本通常以.sh结尾
2.编写脚本是通常写到
#!/bin/bash ##/bin/bash为解释器,解释原文件名中的内容
#!/bin/sh ##/bin/sh也为解释器
[[email protected] mnt]# chmod +x /mnt/haha.sh
[[email protected] mnt]# /mnt/haha.sh ##直接执行脚本内容(使用脚本内部中写的解释器)
hello
[[email protected] mnt]# ps f ##查看从属关系
PID TTY STAT TIME COMMAND
4114 pts/1 Ss 0:00 -bash
4417 pts/1 T 0:00 \_ /bin/bash /mnt/ha.sh ##使用bash解释器执行此脚本
4418 pts/1 T 0:00 | \_ cat
4427 pts/1 R+ 0:00 \_ ps f
4060 tty6 Ss+ 0:00 -bash
1867 pts/0 Ss+ 0:00 -bash
1678 tty1 Ss+ 0:05 /usr/bin/Xorg :0 -background none -ve
1993 ttyS0 Ss+ 0:00 /sbin/agetty --keep-baud ttyS0 115200
3.脚本调试模式:
[[email protected] mnt]# cat /mnt/ha.sh
#!/bin/bash -x ##添加-x是为了脚本调试,会同时输出本来需要输入的内容
echo hello
[[email protected] mnt]# /mnt/ha.sh
+ echo hello
hello
如果脚本中不添加-x时
sh -x /mnt/ha.sh ##-x会输出文件本来的输入内容
4.引用和转义
引用和转义在shell解析字符串时用于去除字符串中特殊字符或保留词语的特殊含义。这会导致按字面处理字符串,而不是展开变量或将其部分内容视作具有特殊含义。
引用有三种类型:
1)
弱引用
将字符串放置在双引号中,保留字符串中所有字符的文字值,$、`、\和!字符除外。换言之,变量扩展和命令扩展在双引号内仍起作用。
echo “can I have a $FRUIT”
echo “The current time is $(date +%r).”
$i ##指变量值
i ##指变量
$ ##变量取值
` ##让指令先执行
\ ##引用单个字符
"" ##引用部分字符(‘‘ $ ! 这三个均不引用)————这个为弱引用
2)
强引用
将字符串放置在单引号中,保留字符串中所有字符的文字值,同时禁用所有扩展:
‘ ##转译所有的字符
3)
转义
非引用的\是转义字符。它保留了下一个字符的文字值。(例如,\$PATH是确切的字符串$PATH,而
不是PATH变量的内容。)
\ ##转译单个字符
测试:
[[email protected] ~]# echo # not a comment #
[[email protected] ~]# echo \# not a comment #
# not a comment
[[email protected] ~]# echo \# not a comment \#
# not a comment #
[[email protected] ~]# echo ‘# not a comment #‘
# not a comment #
[[email protected] ~]# echo ‘$HOME‘
$HOME
[[email protected] ~]# echo ‘`pwd`‘
`pwd`
[[email protected] ~]# echo ‘"Hello,world"‘
"Hello,world"
[[email protected] ~]# echo "$HOME"
/root
[[email protected] ~]# echo "`pwd`"
/root
[[email protected] ~]# echo ""Hello, world""
Hello, world
[[email protected] ~]# echo "\$HOME"
$HOME
[[email protected] ~]# echo "\`pwd\`"
`pwd`
[[email protected] ~]# echo "\"Hello, world\""
"Hello, world"
5.Shell变量
shell变量用于为稍后在脚本中使用的名称指定值,并且仅限于shell命令行或从中声明变量的脚本。
若要定义或指定值:
FRUIT=apple
若要参考或使用变量:
$FRUIT
${FRUIT}
[[email protected] ~]# FIRST=John
[[email protected] ~]# LAST=Doe
[[email protected] ~]# echo $FIRST $LAST
John Doe
[[email protected] ~]# echo $FIRST_$LAST
Doe
[[email protected] ~]# echo ${FIRST}_$LAST
John_Doe
6.循环
for NUM in 1 hello 2 westos 3 lee;do echo$NUM ; done ##NUM后面是6个数
for NUM in 1 hello 2 westos 3 lee;do echo$NUM ;sleep 1; done ##执行完上一个的时候停一秒执行下一个
[[email protected] ~]# for HOST in host{1..3};do echo $HOST;done
host1
host2
host3
7.条件语句
a=1
while [ "$a" -ge "1" -a "$a" -lt "10" ]; do echo yes; break;done ##当a大于等于1,小于10的时候输出yes
yes
-ge 大于等于
-gt 大于
-lt 小于
实验:
1)要求:测试1~10主机是否能ping
[[email protected] mnt]# vim haha.sh
[[email protected] mnt]# cat haha.sh
#!/bin/bash
for i in {1..10}
do ping -c1 -w1 172.25.254.$i &> /dev/null && echo 172.25.254.$i is up || echo 172.25.254.$i is down ##-c1执行次数,-w1等待时间
done
[[email protected] mnt]# /mnt/haha.sh
172.25.254.1 is up
172.25.254.2 is up
172.25.254.3 is up
172.25.254.4 is up
172.25.254.5 is up
172.25.254.6 is up
172.25.254.7 is up
172.25.254.8 is down
172.25.254.9 is up
172.25.254.10 is up
##脚本调试模式的测试
[[email protected] mnt]# sh -x /mnt/haha.sh
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.1
+ echo 172.25.254.1 is up
172.25.254.1 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.2
+ echo 172.25.254.2 is up
172.25.254.2 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.3
+ echo 172.25.254.3 is up
172.25.254.3 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.4
+ echo 172.25.254.4 is up
172.25.254.4 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.5
+ echo 172.25.254.5 is up
172.25.254.5 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.6
+ echo 172.25.254.6 is up
172.25.254.6 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.7
+ echo 172.25.254.7 is up
172.25.254.7 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.8
+ echo 172.25.254.8 is down
172.25.254.8 is down
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.9
+ echo 172.25.254.9 is up
172.25.254.9 is up
+ for i in ‘{1..10}‘
+ ping -c1 -w1 172.25.254.10
+ echo 172.25.254.10 is up
172.25.254.10 is up
[[email protected] mnt]#
2)要求:自动建立用户
[[email protected] mnt]# cat /mnt/username
xiao
ha
xi
[[email protected] mnt]# cat create_user.sh
#!/bin/bash
for name in `cat /mnt/username` 或者 for name in `cat $1`
do useradd $name
done
[[email protected] mnt]# sh create_user.sh username
[[email protected] mnt]# id xiao
uid=1001(xiao) gid=1001(xiao) groups=1001(xiao)
[[email protected] mnt]# id xi
uid=1003(xi) gid=1003(xi) groups=1003(xi)
[[email protected] mnt]# id ha
uid=1002(ha) gid=1002(ha) groups=1002(ha)
3)要求:将/etc/*.conf 文件复制到/mnt/$BACKDIR下
vim /mnt/backup.sh
#!/bin/bash
BACKDIR=etcconfig-`date +%Y-%m-%d-%S`##年月日秒
mkdir -p /mnt/$BACKDIR
cp /etc/*.conf /mnt/$BACKDIR
chmod +x backup.sh
/mnt/backup.sh
cd /mnt
ls
4)要求:倒计时5秒
[[email protected] mnt]# cat text3.sh
#!/bin/bash
for ((i=5;i>0;i--))
do
echo -n After ${i}s is end
echo -ne "\r\r"
sleep 1
done
[[email protected] mnt]# chmod +x /mnt/text3.sh
[[email protected] mnt]# /mnt/text3.sh
After 4s is end
5)要求:70s倒计时
[[email protected] mnt]# cat text4.sh
#!/bin/bash
MIN=1
for ((SEC=10;SEC>=0;SEC--))
do
while [ "$SEC" -eq "0" -a "$MIN" -eq "0" ]
do
echo "TIME is END"
exit 0
done
while [ "$SEC" -eq "0" -a "$MIN" -ge "0" ]
do
(( MIN-- ))
SEC=59
echo -n "After ${MIN}min:${SEC}s is end "
sleep 1
echo -ne "\r\r"
done
echo -n "After ${MIN}min:${SEC}s is end "
echo -ne "\r\r"
sleep 1
done
[[email protected] mnt]# /mnt/text4.sh
TIME is END
6)要求:脚本mysql的备份
#!/bin/bash
for DB in $(mysql -uroot -e "show databases" -E -N | grep -v ‘^*‘ | grep -v ‘schema$‘)
do
echo "Backing up $DB"
mysqldump -uroot $DB > /dbbackup/$DB-`date +%Y-%m-%d`.dump##备份到这块(重定向)
done
echo ""
for DBDUMP in /dbbackup/*
do
SIZE=$(stat --printf "%s\n" $DBDUMP)
echo "$DBDUMP $SIZE"
done
[[email protected] mnt]# /mnt/text5.sh
Backing up mysql
Backing up test
Backing up westos
/dbbackup/mysql-2017-06-11.dump 514670
/dbbackup/test-2017-06-11.dump 1261
/dbbackup/westos-2017-06-11.dump 1835
7)要求:查找设备ip
[[email protected] mnt]# vim change_show.sh
#!/bin/bash
read -p "please give me a interface:"
ifconfig eth0 | grep netmask | awk -F " " ‘{print $2}‘
[[email protected] mnt]# /mnt/change_show.sh
please give me a interface:eth0
172.25.254.113
带提示的查找:
[[email protected] mnt]# vim text6.sh
#!/bin/bash
echo `ifconfig | grep flags | cut -d : -f 1`
read -p "please give me a interface:"
ifconfig $1 | grep netmask | awk -F " " ‘{print $2}‘
[[email protected] mnt]# /mnt/text6.sh eth0
eth0 eth1 eth2 lo team0
please give me a interface:eth0
172.25.254.113
8)要求:输入ip判断网是否通畅
[[email protected] mnt]# vim text7.sh
#!/bin/bash
while [ "$#" -eq "0" ]
do
echo "please give me a ip address!"
exit 1
done
ping -c 1 -w 1 $1 > /devnull && echo "$1 is up" || echo "$1 is down"
[[email protected] mnt]# chmod +x text7.sh
[[email protected] mnt]# /mnt/text7.sh
please give me a ip address!
[[email protected] mnt]# /mnt/text7.sh 172.25.254.13
172.25.254.13 is up
[[email protected] mnt]# /mnt/text7.sh 172.25.254.77
172.25.254.77 is down
退出状态
Linux命令完成时,将返回退出状态。成功完成程序时,将返回0的推出状态。这被bash当作逻辑True值。非零退出状态通常表示发生了错误,并且被bash当作逻辑False值。
例如:grep的退出状态的含义:
0 – 在指定的文件中找到了模式
1 – 在指定的文件中未找到模式
>1 – 一些其他错误(无法打开文件、错误的搜索表达式等)
推出状态的值被存储在"?"中,可以使用以下命令查看:
# echo $?