Linux云自动化运维第十九课
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux云自动化运维第十九课相关的知识,希望对你有一定的参考价值。
第十一单元 Bash Scripts
一、Bash脚本基础
1.BASH = GNU Bourne-Again Shell,BASH是GNU组织开发和推广的一个项目。
2.Bash脚本类似批处理,简单来讲就是把许多的指令集合在一起,并提供循环、条件、判断等重要功能,语法简单实用,用以编写程序,大大简化管理员的操作,并可以完成图形工具所无法实现的功能。
3.如何创建新shell脚本?
1)创建包含bash命令的文本文件。文件的第一行应为:
#!/bin/bash
2)使文件可执行(使用chmod +x scripts)
3)将文件放置在用户的$PATH的目录中
~/bin – 用于用户的私有程序
/usr/local/bin – 本地开发、系统上的其他人使用的脚本
/usr/local/sbin - 本地开发、由root使用的脚本直接运行脚本和使用source命令运行脚本是不同的!
4)脚本调试模式:
#!/bin/bash -x
# bash -x scripts
5)示例:
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash -x
echo "Hello world!"
[[email protected] mnt]# sh test.sh
Hello world!
[[email protected] mnt]# bash test.sh
Hello world!
[[email protected] mnt]# chmod +x test.sh
[[email protected] mnt]# bash -x test.sh
+ echo ‘Hello world!‘
Hello world!
[[email protected] mnt]# ./test.sh
+ echo ‘Hello world!‘
Hello world!
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
cat
[[email protected] mnt]# sh test.sh
^Z
[1]+ Stopped sh test.sh
[[email protected] mnt]# ps ef
PID TTY STAT TIME COMMAND
2068 pts/0 Ss 0:00 -bash [email protected]=ibus LANG=en_US.UTF-8 USER=root
2108 pts/0 T 0:00 \_ sh test.sh XDG_SESSION_ID=2 HOSTNAME=localhost.lo
2109 pts/0 T 0:00 | \_ cat XDG_SESSION_ID=2 HOSTNAME=localhost.local
2110 pts/0 R+ 0:00 \_ ps ef XDG_SESSION_ID=2 HOSTNAME=localhost.localdo
1844 tty1 Ss+ 0:00 -bash HOME=/root USER=root SHELL=/bin/bash TERM=linux
[[email protected] mnt]# fg
sh test.sh
^C
[[email protected] mnt]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
[[email protected] mnt]# bash -x test.sh
+ cat
^C
4.引用和转义
引用和转义在shell解析字符串时用于去除字符串中特殊字符或保留词语的特殊含义。这会导致按字面处理字符串,而不是展开变量或将其部分内容视作具有特殊含义。引用有三种类型:
1)弱引用
将字符串放置在双引号中,保留字符串中所有字符的文字值,$、`、\和!字符除外。换言之,变量扩展和命令扩展在双引号内仍起作用。
echo “can I have a $FRUIT”
echo “The current time is $(date +%r).”
2)强引用
将字符串放置在单引号中,保留字符串中所有字符的文字值,同时禁用所有扩展:
echo “Make $$$ Fast”
rm ‘untitled folder‘
3)转义
非引用的\是转义字符。它保留了下一个字符的文字值。(例如,\$PATH是确切的字符串$PATH,而不是PATH变量的内容。)
echo Make \$\$\$ Fast\!
ls untitled\ folder
[[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"
www.westos.org
6[[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"
4)示例
[[email protected] mnt]# a=1
[[email protected] mnt]# echo $a
1
[[email protected] mnt]# echo \$a
$a
[[email protected] mnt]# echo "$a"
1
[[email protected] mnt]# echo ‘$a‘
$a
[[email protected] mnt]# echo $a $a $a
1 1 1
[[email protected] mnt]# echo \$a $a $a
$a 1 1
[[email protected] mnt]# echo ‘$a $a $a‘
$a $a $a
[[email protected] mnt]# echo "$a $a $a"
1 1 1
[[email protected] mnt]# echo ‘$a0 $a $a‘
$a0 $a $a
[[email protected] mnt]# echo ${a}0 \$a $a
10 $a 1
[[email protected] mnt]# echo * * * * *
createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile
[[email protected] mnt]# echo "* * * * *"
* * * * *
[[email protected] mnt]# echo ‘* * * * *‘
* * * * *
[[email protected] mnt]# echo "!"
-bash: !: event not found
[[email protected] mnt]# echo ‘!‘
!
[ro[email protected] mnt]# echo "$"
$
[[email protected] mnt]# echo "$a"
1
[[email protected] mnt]# echo ‘$a‘
$a
[[email protected] mnt]# echo "`"
> 1
> ^C
[[email protected] mnt]# echo ‘`‘
`
[[email protected] mnt]# echo "\"
> a
> ^C
[[email protected] mnt]# echo ‘\‘
\
[[email protected] mnt]# echo your hostname is `hostname`
your hostname is localhost.localdomain
[[email protected] mnt]# echo ***** your hostname is `hostname` *****
createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile your hostname is localhost.localdomain createuser.sh deluser.sh exit.sh iduser.sh num.sh passwdfile show_ip.sh test.sh userfile
[[email protected] mnt]# echo ‘***** your hostname is `hostname` *****‘
***** your hostname is `hostname` *****
[[email protected] mnt]# echo "***** your hostname is `hostname` *****"
***** your hostname is localhost.localdomain *****
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
示例:
[[email protected] mnt]# a=1
[[email protected] mnt]# echo $a
1
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# sh test.sh
root
[[email protected] mnt]# cat test.sh
#!/bin/bash
echo $USER
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# sh test.sh
LOCAL USER is root
[[email protected] mnt]# cat test.sh
#!/bin/bash
NAME="LOCAL USER is"
echo $NAME $USER
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
NAME="LOCAL USER is"
echo $NAME $USER
FIRSTNAME=student
FAMNAME=duck
echo my name is $FIRSTNAME_$FAMNAME
[[email protected] mnt]# sh test.sh
LOCAL USER is root
my name is duck
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
NAME="LOCAL USER is"
echo $NAME $USER
FIRSTNAME=student
FAMNAME=duck
echo my name is ${FIRSTNAME}_$FAMNAME
[[email protected] mnt]# sh test.sh
LOCAL USER is root
my name is student_duck
[[email protected] mnt]# ls
test.sh
[[email protected] mnt]# vim show_ip.sh
[[email protected] mnt]# cat show_ip.sh
#!/bin/bash
IP=`ifconfig ens3 | grep inet | grep inet6 -v | awk -F " " ‘{print $2}‘`
echo "your ipaddress is : $IP"
[[email protected] mnt]# sh show_ip.sh
your ipaddress is : 172.25.254.64
6.命令替换
命令替换在子shell中执行指定命令并用命令输出替换脚本中的命令替换。
语法:
$(shell command)
示例:
touch datafile.$(id -un)
TODAY=$(date +%Y-%m-%d)
[[email protected] ~]# TAROUTPUT=$(tar cvf /tmp/backup.tar $(find /etc -type f -mtime 1))
tar: Removing leading `/‘ from member names
[[email protected] ~]# 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
示例:
[[email protected] mnt]# hostname
localhost.localdomain
[[email protected] mnt]# vim show_ip.sh
[[email protected] mnt]# cat show_ip.sh
#!/bin/bash
IP=`ifconfig ens3 | grep inet | grep inet6 -v | awk -F " " ‘{print $2}‘`
echo "$(hostname)‘s ipaddress is : $IP"
[[email protected] mnt]# sh show_ip.sh
localhost.localdomain‘s ipaddress is : 172.25.254.64
7.算术运算符
算术运算符指的是可以在程序中实现加、减、乘、除等数学运算的运算符。
operator meaning
<VARIABLE>++ 增量后
<VARIABLE>-- 减量后
- 减法
+ 加法
** 幂运算
* 乘法
/ 除法
% 余数
+= 加等
-= 减等
1)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
2)示例
[[email protected] mnt]# echo $[1+2]
3
[[email protected] mnt]# echo $[2+2]
4
[[email protected] mnt]# echo $[5*2]
10
[[email protected] mnt]# echo $[5**2]
25
[[email protected] mnt]# echo $[10/2]
5
[[email protected] mnt]# echo $[9%2]
1
[[email protected] mnt]# echo $[3%5]
3
[[email protected] mnt]# echo `expr 5 \+ 2`
7
[[email protected] mnt]# echo `expr 5 \- 2`
3
[[email protected] mnt]# echo `expr 5 \* 2`
10
[[email protected] mnt]# echo `expr 5 \/ 2`
2
[[email protected] mnt]# echo `expr 5 \% 2`
1
[[email protected] mnt]# let A=1+2
[[email protected] mnt]# echo $A
3
[[email protected] mnt]# let A=3-1
[[email protected] mnt]# echo $A
2
[[email protected] mnt]# let A=2*5
[[email protected] mnt]# echo $A
10
[[email protected] mnt]# let A=5%2
[[email protected] mnt]# echo $A
1
[[email protected] mnt]# let A=5/2
[[email protected] mnt]# echo $A
2
8.循环:for循环用于值列表中的相同命令的重复。
[[email protected] ~]# for HOST in host{1..3};do echo $HOST;done
host1
host2
host3
[[email protected] ~]# for NUM in $(seq 2 2 8);do echo $NUM;done
2
4
6
8
1)循环与计算结合:
#!/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
2)数据库备份示例:
#!/bin/bash
for DB in $(mysql -e "show databases;" -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
3)示例:
[[email protected] mnt]# vim num.sh
[[email protected] mnt]# sh num.sh
1
2
3
4
5
[[email protected] mnt]# cat num.sh
#!/bin/bash
for NUM in {1..5}
do
echo $NUM
done
[[email protected] mnt]# vim num.sh
[[email protected] mnt]# cat num.sh
#!/bin/bash
for NUM in $(seq 1 2 10)
do
echo $NUM
done
[[email protected] mnt]# sh num.sh
1
3
5
7
9
[[email protected] mnt]# vim exit.sh
[[email protected] mnt]# cat exit.sh
#!/bin/bash
for NAME in /etc/hello /etc/passwd /etc/group
do
ls -l $NAME &> /dev/null && echo $NAME is exit || echo $NAME is not exit
done
[[email protected] mnt]# sh exit.sh
/etc/hello is not exit
/etc/passwd is exit
/etc/group is exit
[[email protected] mnt]# vim exit.sh
[[email protected] mnt]# cat exit.sh
#!/bin/bash
for NAME in {1..5}
do
ping -c1 -w1 172.25.254.$NUM &> /dev/null && echo 172.25.254.$NUM is up || echo 172.25.254.$NUM down
done
[[email protected] mnt]# sh exit.sh
172.25.254. down
172.25.254. down
172.25.254. down
172.25.254. down
172.25.254. down
[[email protected] mnt]# ls
createuser.sh exit.sh num.sh show_ip.sh userfile
deluser.sh iduser.sh passwdfile test.sh
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# sh test.sh
1
2
3
4
5
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=1;i<=5;i++))
do
echo $i
done
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=1;i<=5;i++))
do
echo $i
((i++))
done
[[email protected] mnt]# sh test.sh
1
3
5
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=10;i>0;i--))
do
echo $i
((i--))
done
[[email protected] mnt]# sh test.sh
10
8
6
4
2
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=1;i<10;i++))
do
((j+=i))
echo $j
done
[[email protected] mnt]# sh test.sh
1
3
6
10
15
21
28
36
45
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=10;i>0;i--))
do
echo $i
sleep 1
done
[[email protected] mnt]# sh test.sh
10
9
8
7
6
5
4
3
2
1
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=10;i>0;i--))
do
echo "After ${i}s is end"
sleep 1
done
[[email protected] mnt]# sh test.sh
After 10s is end
After 9s is end
After 8s is end
After 7s is end
After 6s is end
After 5s is end
After 4s is end
After 3s is end
After 2s is end
After 1s is end
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
for ((i=10;i>0;i--))
do
echo -ne "After ${i}s is end \r"
sleep 1
done
[[email protected] mnt]# sh test.sh
[[email protected] mnt]#
9.示例:
[[email protected] mnt]# vim userfile
[[email protected] mnt]# cat userfile
lee
westos
linux
loo
[[email protected] mnt]# vim passwdfile
[[email protected] mnt]# cat passwdfile
123
234
345
456
[[email protected] mnt]# vim createuser.sh
[[email protected] mnt]# cat createuser.sh
#!/bin/bash
COUNT=`wc -l /mnt/userfile | cut -d " " -f 1`
for NUM in $(seq 1 $COUNT)
do
USERNAME=`sed -n ${NUM}p $1`
PASSWD=‘sed -n ${NUM}p $2‘
useradd $USERNAME
echo $PASSWD | passwd --stdin $USERNAME
done
[[email protected] mnt]# cp -p createuser.sh deluser.sh
[[email protected] mnt]# vim deluser.sh
[[email protected] mnt]# cat deluser.sh
#!/bin/bash
COUNT=`wc -l /mnt/userfile | cut -d " " -f 1`
for NUM in $(seq 1 $COUNT)
do
USERNAME=`sed -n ${NUM}p $1`
userdel $USERNAME
done
[[email protected] mnt]# cp -p deluser.sh iduser.sh
[[email protected] mnt]# vim iduser.sh
[[email protected] mnt]# cat iduser.sh
#!/bin/bash
COUNT=`wc -l /mnt/userfile | cut -d " " -f 1`
for NUM in $(seq 1 $COUNT)
do
USERNAME=`sed -n ${NUM}p $1`
id $USERNAME
done
[[email protected] mnt]# sh createuser.sh userfile passwdfile
Changing password for user lee.
passwd: all authentication tokens updated successfully.
Changing password for user westos.
passwd: all authentication tokens updated successfully.
Changing password for user linux.
passwd: all authentication tokens updated successfully.
Changing password for user loo.
passwd: all authentication tokens updated successfully.
[[email protected] mnt]# sh iduser.sh userfile
uid=1001(lee) gid=1001(lee) groups=1001(lee)
uid=1002(westos) gid=1002(westos) groups=1002(westos)
uid=1003(linux) gid=1003(linux) groups=1003(linux)
uid=1004(loo) gid=1004(loo) groups=1004(loo)
[[email protected] mnt]# sh deluser.sh userfile
[[email protected] mnt]# sh iduser.sh userfile
id: lee: no such user
id: westos: no such user
id: linux: no such user
id: loo: no such user
二、Bash位置参数
1.有两种简单的方法可以将用户输入读入bash中的变量。第一个方法是使用read提示用户输入(使用-p选项)并将其直接存储到一个或多个变量:交互式输入
# read -p ‘Enter your first and last name: ‘ FIRST LAST
2.另一个方法是使用位置参数来读取传递给脚本的命令行参数或选项输入。各种特殊变量存储传递的选项编号Bash解析的个别参数或整个原始命令行。
指定的位置参数总数:$#
位置参数自身:$0、$1、$2、$3....
所有位置参数: [email protected]、$*
3.示例:
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
echo $1
echo $2
echo $3
echo $*
echo $#
echo [email protected]
[[email protected] mnt]# ./test.sh
0
[[email protected] mnt]# ./test.sh hello
hello
hello
1
hello
[[email protected] mnt]# ./test.sh hello world
hello
world
hello world
2
hello world
[[email protected] mnt]# ./test.sh hello world linux
hello
world
linux
hello world linux
3
hello world linux
[[email protected] mnt]#
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# ./test.sh
Give me a world: hello linux world
hello linux world
[[email protected] mnt]# cat test.sh
#!/bin/bash
read -p "Give me a world: " HELLO
echo $HELLO
[[email protected] mnt]#
[[email protected] mnt]# vim id_check.sh
[[email protected] mnt]# cat id_check.sh
#!/bin/bash
read -p "Please input your name : " username
check=`getent passwd $username`
[ -n "$check" ] && (
echo "the user is exit"
) || (
read -p "Please input your passwd : " passwd
useradd $username
echo $passwd | passwd --stdin $username
)
[[email protected] mnt]# sh id_check.sh
Please input your name : student
the user is exit
[[email protected] mnt]# sh id_check.sh
Please input your name : linux
Please input your passwd : linux
Changing password for user linux.
passwd: all authentication tokens updated successfully.
[[email protected] mnt]# id linux
uid=1005(linux) gid=1005(linux) groups=1005(linux)
[[email protected] mnt]#
三、退出状态
1.Linux命令完成时,将返回退出状态。成功完成程序时,将返回0的推出状态。这被bash当作逻辑True值。非零退出状态通常表示发生了错误,并且被bash当作逻辑False值。
2.例如:grep的退出状态的含义:
0 – 在指定的文件中找到了模式
1 – 在指定的文件中未找到模式
>1 – 一些其他错误(无法打开文件、错误的搜索表达式等)
3.退出状态的值被存储在"?"中,可以使用以下命令查看:
# echo $?
四、test条件判断
1.test命令可用于评估bash脚本中的表达式。它评估其参数所指定的表达式,如果表达式为true,返回零退出状态,如果表达式为false,则返回非零退出状态。test具有替代语法,使用方括号"[]"将表达式括起来,这样更易于阅读。
2.语法:test EXPRESSION 或 [EXPRESSION]
1)非零或零长度字符串运算符:test -{n|z} STRING
[[email protected] ~]# [ -n westos ]; echo $?
0
[[email protected] ~]# [ -z westos ]; echo $?
1
2)字符串比较运算符:=、!=
[[email protected] ~]# [ abc = abc ]; echo $?
0
[[email protected] ~]# [ abc = ABC ]; echo $?
1
[[email protected] ~]# [ abc != ABC ]; echo $?
0
3)数字比较运算符:-eq、-ne、-lt、-le、-gt、-ge
[[email protected] ~]# [ 1 -eq 1 ]; echo $?
0
[[email protected] ~]# [ 1 -ne 1 ]; echo $?
1
[[email protected] ~]# [ 1 -gt 2 ]; echo $?
1
4)文件状态运算符:test -{b|c|e|f|d|r|w|x|s|L} FILE/DIRECTORY
[[email protected] ~]# [ -b /dev/sda ]; echo $?
1
[[email protected] ~]# [ -c /dev/zero ]; echo $?
0
[[email protected] ~]# [ -e /etc/passwd ]; echo $?
0
[[email protected] ~]# [ -f /etc/passwd ]; echo $?
0
[[email protected] ~]# [ -d /etc/passwd ]; echo $?
1
[[email protected] ~]# [ -L /etc/passwd ]; echo $?
1
5)二进制文件运算符:-ef、-nt、-ot
[[email protected] bin]# [ /bin/mount -ef /usr/bin/mount ]; echo $?
0
[[email protected] bin]# [ /bin/mount -nt /usr/bin/mount ]; echo $?
1
[[email protected] bin]# [ /bin/mount -ot /usr/bin/mount ]; echo $?
1
6)逻辑运算符:-o、-a、!、&&、||
[[email protected] bin]# [ 2 -gt 1 -a 1 -gt 2 ]; echo $?
1
[[email protected] bin]# [ 2 -gt 1 -o 1 -gt 2 ]; echo $?
0
[[email protected] bin]# [ ! 2 -gt 1 ]; echo $?
1
7)示例:
[[email protected] mnt]# [ "1" = "2" ] && echo yes || echo no
no
[[email protected] mnt]# [ "1" -lt "2" ] && echo yes || echo no
yes
[[email protected] mnt]# [ "1" -gt "2" ] && echo yes || echo no
no
[[email protected] mnt]# [ "1" -le "2" ] && echo yes || echo no
yes
[[email protected] mnt]# [ "1" -le "1" ] && echo yes || echo no
yes
[[email protected] mnt]# [ "1" -ge "2" ] && echo yes || echo no
no
[[email protected] mnt]# [ "1" -ne "2" ] && echo yes || echo no
yes
[[email protected] mnt]# [ "1" -eq "2" ] && echo yes || echo no
no
[[email protected] mnt]# [ "$a" -gt "0" -a "$a" -lt "10" ] && echo yes || echo no
yes
[[email protected] mnt]# a=100
[[email protected] mnt]# [ "$a" -gt "0" -a "$a" -lt "10" ] && echo yes || echo no
no
[[email protected] mnt]# vim test.sh
[[email protected] mnt]# cat test.sh
#!/bin/bash
MIN=1
for ((i=3;i>0;i--))
do
while
[ "$i" -eq "0" -a "$MIN" -gt "0" ]
do
echo "After ${MIN}:${i} is end"
i=5
((MIN--))
done
echo "After ${MIN}:${i} is end"
sleep 1
done
[[email protected] mnt]# sh test.sh
After 1:3 is end
After 1:2 is end
After 1:1 is end
[[email protected] mnt]#
[[email protected] mnt]# getent passwd user1
user1:x:1003:1003::/home/user1:/bin/bash
[[email protected] mnt]# getent passwd student
student:x:1000:1000:Student User:/home/student:/bin/bash
[[email protected] mnt]# CHECK=`getent passwd student`
[[email protected] mnt]# [ -n "$CHECK" ] && echo yes || echo no
yes
[[email protected] mnt]#
[[email protected] mnt]# vim ip_check.sh
[[email protected] mnt]# cat ip_check.sh
#!/bin/bash
ping -c1 -w1 $1 &> /dev/null && echo $1 is exit || echo $1 is not exit
[[email protected] mnt]# sh ip_check.sh 172.25.254.100
172.25.254.100 is exit
[[email protected] mnt]# sh ip_check.sh 172.25.254.242
172.25.254.242 is not exit
[[email protected] mnt]#
五、if语句
if命令检查if后面的命令或列表的退出值。如果第一个命令评估为true/零,则运行then之后的命令列表,直至任一else。如果第一个命令评估为false/非零,则运行else与fi之间的命令列表(反向平写if,标记if块的结束)。
语法:if command; then command; command2; else command3; fi
示例:
if test “$USER” != ‘root‘ ; then
echo you are not logged in as root
fi
if [ $(id -u) -lt 9 ] ; then
echo “The number $(id -u) is less than 9!”
fi
www.westos.org
9if grep “^${USER}:” /etc/passwd &> /dev/null ; then
echo “${USER} is a local user on the system.”
else
echo “${USER} is not a local user.”
fi
systemctl is-active mariadb > /dev/null 2>&1 ; MARIADB_ACTIVE=$?
systemctl is-active postgresql > /dev/null 2>&1 ; POSTGRESQL_ACTIVE=$?
if [ $MARIADB_ACTIVE -eq 0 ];then
mysql
elif [ $POSTGRESQL_ACTIVE -eq 0 ];then
psql
else
sqlite3
fi
练习:
[[email protected] mnt]# vim createuser.sh
[[email protected] mnt]# cat createuser.sh
#!/bin/bash
if
[ -n "$1" -a -n "$2" ]
then
NUM1=`wc -l $1 | cut -d " " -f 1`
NUM2=`wc -l $2 | cut -d " " -f 1`
if
[ "$NUM1" -eq "$NUM2" ]
then
for NUM in `seq 1 $NUM1`
do
USERNAME=`sed -n ${NUM}p $1`
PASSWD=`sed -n ${NUM}p $2`
CHECK=`getent passwd $USERNAME`
if
[ -z "$CHECK" ]
then
useradd $USERNAME
echo $PASSWD | passwd --stdin $USERNAME
else
echo "The $USERNAME is exist"
fi
done
else
echo "error:$1‘s line is different $2,Please check $1 or $2"
fi
else
echo "error:Please give me username file and passwd file!!!"
fi
[[email protected] mnt]# vim userfile
[[email protected] mnt]# cat userfile
username1
username2
username3
username4
username5
username6
username7
username8
[[email protected] mnt]# vim passfile
[[email protected] mnt]# cat passfile
password1
password2
password3
password4
password5
password6
password7
password8
[[email protected] mnt]# sh createuser.sh
error:Please give me username file and passwd file!!!
[[email protected] mnt]# sh createuser.sh userfile passfile
The username1 is exist
The username2 is exist
The username3 is exist
The username4 is exist
The username5 is exist
The username6 is exist
The username7 is exist
The username8 is exist
[[email protected] mnt]# userdel -r username1
[[email protected] mnt]# userdel -r username2
[[email protected] mnt]# userdel -r username3
[[email protected] mnt]# userdel -r username4
[[email protected] mnt]# sh createuser.sh userfile passfile
Changing password for user username1.
passwd: all authentication tokens updated successfully.
Changing password for user username2.
passwd: all authentication tokens updated successfully.
Changing password for user username3.
passwd: all authentication tokens updated successfully.
Changing password for user username4.
passwd: all authentication tokens updated successfully.
The username5 is exist
The username6 is exist
The username7 is exist
The username8 is exist
[[email protected] mnt]#
[[email protected] mnt]# vim check_num.sh
[[email protected] mnt]# cat check_num.sh
#!/bin/bash
A=10
B=0
if
[ -n "$1" ]
then
if
[ "$1" -le "$A" -a "$1" -ge "$B" ]
then
echo ${1}属于0-10
else
echo ${1}不属于0-10
fi
else
echo "ERROR:give me a num!!!"
fi
[[email protected] mnt]# sh check_num.sh
ERROR:give me a num!!!
[[email protected] mnt]# sh check_num.sh 1
1属于0-10
[[email protected] mnt]# sh check_num.sh -7
-7不属于0-10
[[email protected] mnt]# sh check_num.sh 17
17不属于0-10
[[email protected] mnt]#
六、case语句
case语句 :它能够把变量的内容与多个模板进行匹配,再根据成功匹配的模板去决定应该执行哪部分代码。
case "$1" in
start)
systemctl start $2
;;
stop)
systemctl stop $2
;;
reload|restart)
systemctl stop $2
systemctl start $2
;;
*)
echo "Usage: $0 (start|stop|restart|reload)"
;;
esac
示例:
[[email protected] mnt]# vim case_file.sh
[[email protected] mnt]# cat case_file.sh
#!/bin/bash
case "$1" in
-b)
if
[ -b "$2" ]
then
echo "$2 is a block"
else
echo "$2 is not a block"
fi
;;
-f)
if
[ -f "$2" ]
then
echo "$2 is a file"
else
echo "$2 is not a file"
fi
;;
-d)
if
[ -d "$2" ]
then
echo "$2 is a dir"
else
echo "$2 is not a dir"
fi
;;
*)
echo "I Don‘t Know"
;;
esac
[[email protected] mnt]# sh case_file.sh
I Don‘t Know
[[email protected] mnt]# sh case_file.sh -d
is not a dir
[[email protected] mnt]# sh case_file.sh -d /etc/
/etc/ is a dir
[[email protected] mnt]# sh case_file.sh -d /etc/passwd
/etc/passwd is not a dir
[[email protected] mnt]# sh case_file.sh -f /etc/passwd
/etc/passwd is a file
[[email protected] mnt]# sh case_file.sh -b /dev/vda1
/dev/vda1 is a block
[[email protected] mnt]#
七、expect语句
在shell中利用expect实现自动应答脚本。
# cat talk
echo "who are you?"
read who
echo "hello, $who"
echo "are you
happy?"
read answer
echo "why?"
read answer
# cat auto
#!/usr/bin/expect
#set timeout 10
spawn ./talk
expect "who"
send "firefly\n"
expect "happy?"
send "Yes,I am happy.\n"
expect "why?"
send "任性!\n"
expect eof
exit
1)#!/usr/bin/expect
这一行告诉操作系统脚本里的代码使用那一个shell来执行。
2)set timeout 10
设置后面所有的expect命令的等待响应的超时时间,单位为秒。
3)spawn talk
spawn是expect的内部命令,作用是给后面的shell指令加个壳,用来传递交互指令。
4)expect "who"
判断上次输出结果里是否包含“who”的字符串,如果有则立即返回,否则等待超时时间后返回。
5)send "westos\n"
执行交互动作,相当于手工输入"westos"。
6)expect eof
作用是在输出中搜索文件结束符,如果没有这一行,脚本会立即退出,得不到正确结果。
7)interact
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。否则退出登录。
8)$argv 参数数组
expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个....参数。
9)示例:
[[email protected] mnt]# vim 233.exp
[[email protected] mnt]# cat 233.exp
#!/usr/bin/expect
spawn ssh [email protected]
expect {
"(yes/no)?" {send "yes\r";exp_continue};
"password:" {send "westos\r"};
}
interact
[[email protected] mnt]# chmod +x 233.exp
[[email protected] mnt]# ./233.exp
spawn ssh [email protected]
The authenticity of host ‘172.25.254.42 (172.25.254.42)‘ can‘t be established.
ECDSA key fingerprint is f2:5e:9f:f4:87:12:4b:10:7a:42:16:1f:a0:3a:9a:53.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘172.25.254.42‘ (ECDSA) to the list of known hosts.
[email protected]‘s password:
Last login: Wed Apr 26 15:51:51 2017
[[email protected] ~]#
八、环境变量
1.shell和脚本使用变量来存储数据 ,有些变量可以连同它们的内容传递给子进程,这些变量我们称之为环境变量。
[[email protected] ~]# LINUX=redhat
[[email protected] ~]# echo $LINUX
redhat
[[email protected] ~]# bash
[[email protected] ~]# echo $LINUX
[[email protected] ~]# exit
exit
[[email protected] ~]# export LINUX
[[email protected] ~]# bash
[[email protected] ~]# echo $LINUX
redhat
[[email protected] ~]# exit
exit
使用env命令显示所有环境变量
使用set命令现实所有本地定义的shell变量
2.Bash启动脚本
在用户登录的时候,会运行全局变量文件/etc/profile,和用户自定义变量文件
~/.bash_profile去初始化它们的环境变量。
/etc/profile
\_ /etc/profile.d/*.sh
~/.bash_profile
\_ ~/.bashrc
\_ /etc/bashrc
3.使用别名
alias命令可以用来自定义属于自己的系统命令,写入~/.bashrc 文件永久生效。
1)查看别名:
# alias
alias ls=‘ls --color=auto‘
alias mv=‘mv -i‘
alias rm=‘rm -i‘
...
2)设置别名:
# alias mycom=‘echo hello;hostname‘
# mycomm
hello
server0.example.com
3)删除别名:
unalias mycomm
4.使用函数
pathmunge () {
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
}
...
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
5.示例:
[[email protected] mnt]# LINUX=redhat
[[email protected] mnt]# echo $LINUX
redhat
[[email protected] mnt]# bash
[[email protected] mnt]# echo $LINUX
[[email protected] mnt]# exit
exit
[[email protected] mnt]# export LINUX
[[email protected] mnt]# bash
[[email protected] mnt]# echo $LINUX
redhat
[[email protected] mnt]# exit
exit
[[email protected] mnt]# echo $LINUX
redhat
[[email protected] mnt]# bash
[[email protected] mnt]# echo $LINUX
redhat
[[email protected] mnt]# exit
exit
[[email protected] mnt]# vim /etc/profile
[[email protected] mnt]# cd
[[email protected] ~]# vim .bash_profile
[[email protected] ~]# alias
alias cp=‘cp -i‘
alias egrep=‘egrep --color=auto‘
alias fgrep=‘fgrep --color=auto‘
alias grep=‘grep --color=auto‘
alias l.=‘ls -d .* --color=auto‘
alias ll=‘ls -l --color=auto‘
alias ls=‘ls --color=auto‘
alias mv=‘mv -i‘
alias rm=‘rm -i‘
alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde‘
[[email protected] ~]# alias mycom=‘echo hello;hostname‘
[[email protected] ~]# mycom
hello
localhost
[[email protected] ~]# unalias mycom
[[email protected] ~]# mycom
bash: mycom: command not found...
[[email protected] ~]#
以上是关于Linux云自动化运维第十九课的主要内容,如果未能解决你的问题,请参考以下文章