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

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

[root@server0 ~]# echo # not a comment #

[root@server0 ~]# echo \# not a comment #

# not a comment

[root@server0 ~]# echo \# not a comment \#

# not a comment #

[root@server0 ~]# echo '# not a comment #'

# not a comment #

[root@server0 ~]# echo '$HOME'

$HOME

[root@server0 ~]# echo '`pwd`'

`pwd`

[root@server0 ~]# echo '"Hello,world"'

"Hello,world"

www.westos.org

6[root@server0 ~]# echo "$HOME"

/root

[root@server0 ~]# echo "`pwd`"

/root

[root@server0 ~]# echo ""Hello, world""

Hello, world

[root@server0 ~]# echo "\$HOME"

$HOME

[root@server0 ~]# echo "\`pwd\`"

`pwd`

[root@server0 ~]# echo "\"Hello, world\""

"Hello, world"

5.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

6.命令替换

命令替换在子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

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

8.循环:for循环用于值列表中的相同命令的重复。

[root@server0 ~]# for HOST in host{1..3};do echo $HOST;done

host1

host2

host3

[root@server0 ~]# 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

 

二、示例

 

[root@localhost mnt]# vim  test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

cat

[root@localhost mnt]# sh test.sh

^Z

[1]+  Stopped                 sh test.sh

[root@localhost mnt]# ps ef

  PID TTY      STAT   TIME COMMAND

 2068 pts/0    Ss     0:00 -bash XMODIFIERS=@im=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

[root@localhost mnt]# fg

sh test.sh

^C

[root@localhost mnt]# cat /etc/shells

/bin/sh

/bin/bash

/sbin/nologin

/usr/bin/sh

/usr/bin/bash

/usr/sbin/nologin

[root@localhost mnt]# bash -x test.sh

+ cat

^C

[root@localhost mnt]# a=1

[root@localhost mnt]# echo $a

1

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# sh test.sh

root

[root@localhost mnt]# cat test.sh

#!/bin/bash

echo $USER

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# sh test.sh

LOCAL USER is root

[root@localhost mnt]# cat test.sh

#!/bin/bash

NAME="LOCAL USER is"

echo $NAME $USER

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

NAME="LOCAL USER is"

echo $NAME $USER

FIRSTNAME=student

FAMNAME=duck

echo my name is $FIRSTNAME_$FAMNAME

[root@localhost mnt]# sh test.sh

LOCAL USER is root

my name is duck

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

NAME="LOCAL USER is"

echo $NAME $USER

FIRSTNAME=student

FAMNAME=duck

echo my name is ${FIRSTNAME}_$FAMNAME

[root@localhost mnt]# sh test.sh

LOCAL USER is root

my name is student_duck

[root@localhost mnt]# ls

test.sh

[root@localhost mnt]# vim show_ip.sh

[root@localhost mnt]# cat show_ip.sh

#!/bin/bash

IP=`ifconfig eth0 | grep inet | grep inet6 -v | awk -F " " '{print $1}'`

echo "your ipaddress is : $IP"

[root@localhost mnt]# sh show_ip.sh

show_ip.sh: line 2: ifconfig: command not found

your ipaddress is :

[root@localhost mnt]# ifconfig

-bash: ifconfig: command not found

[root@localhost mnt]# yum search ifconfig

Loaded plugins: product-id, search-disabled-repos, subscription-manager

This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.

rhel7.2                                                  | 4.1 kB     00:00     

(1/2): rhel7.2/group_gz                                    | 136 kB   00:00     

(2/2): rhel7.2/primary_db                                  | 3.6 MB   00:00     

============================== Matched: ifconfig ===============================

net-tools.x86_64 : Basic networking tools

[root@localhost mnt]# yum install net-tools.x86_64 -y

[root@localhost mnt]# ifconfig

ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

        inet 172.25.254.64  netmask 255.255.255.0  broadcast 172.25.254.255

        inet6 fe80::5054:ff:feb4:9bda  prefixlen 64  scopeid 0x20<link>

        ether 52:54:00:b4:9b:da  txqueuelen 1000  (Ethernet)

        RX packets 1932  bytes 143545 (140.1 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 1140  bytes 170323 (166.3 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10<host>

        loop  txqueuelen 0  (Local Loopback)

        RX packets 4  bytes 344 (344.0 B)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 4  bytes 344 (344.0 B)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

[root@localhost mnt]# vim show_ip.sh

[root@localhost mnt]# cat show_ip.sh

#!/bin/bash

IP=`ifconfig ens3 | grep inet | grep inet6 -v | awk -F " " '{print $1}'`

echo "your ipaddress is : $IP"

[root@localhost mnt]# sh show_ip.sh

your ipaddress is : inet

[root@localhost mnt]# vim show_ip.sh

[root@localhost mnt]# cat show_ip.sh

#!/bin/bash

IP=`ifconfig ens3 | grep inet | grep inet6 -v | awk -F " " '{print $2}'`

echo "your ipaddress is : $IP"

[root@localhost mnt]# sh show_ip.sh

your ipaddress is : 172.25.254.64

[root@localhost mnt]#

[root@localhost mnt]# hostname

localhost.localdomain

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# vim show_ip.sh

[root@localhost 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"

[root@localhost mnt]# sh show_ip.sh

localhost.localdomain's ipaddress is : 172.25.254.64

[root@localhost mnt]#

[root@localhost mnt]# vim num.sh

[root@localhost mnt]# sh num.sh

1

2

3

4

5

[root@localhost mnt]# cat num.sh

#!/bin/bash

for NUM in {1..5}

do

echo $NUM

done

[root@localhost mnt]# vim num.sh

[root@localhost mnt]# cat num.sh

#!/bin/bash

for NUM in $(seq 1 2 10)

do

echo $NUM

done

[root@localhost mnt]# sh num.sh

1

3

5

7

9

[root@localhost mnt]# vim exit.sh

[root@localhost 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

[root@localhost mnt]# sh exit.sh

/etc/hello is not exit

/etc/passwd is exit

/etc/group is exit

[root@localhost mnt]# vim exit.sh

[root@localhost 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

[root@localhost mnt]# sh exit.sh

172.25.254. down

172.25.254. down

172.25.254. down

172.25.254. down

172.25.254. down

[root@localhost mnt]#

[root@localhost mnt]# vim userfile

[root@localhost mnt]# cat userfile

lee

westos

linux

loo

[root@localhost mnt]# vim passwdfile

[root@localhost mnt]# cat passwdfile

123

234

345

456

[root@localhost mnt]# vim createuser.sh

[root@localhost 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

[root@localhost mnt]# cp -p createuser.sh deluser.sh

[root@localhost mnt]# vim deluser.sh

[root@localhost 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

[root@localhost mnt]# cp -p deluser.sh iduser.sh

[root@localhost mnt]# vim iduser.sh

[root@localhost 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

[root@localhost 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.

[root@localhost 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)

[root@localhost mnt]# sh deluser.sh userfile

[root@localhost 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

[root@localhost mnt]#

[root@localhost mnt]# a=1

[root@localhost mnt]# echo $a

1

[root@localhost mnt]# echo \$a

$a

[root@localhost mnt]# echo "$a"

1

[root@localhost mnt]# echo '$a'

$a

[root@localhost mnt]# echo $a $a $a

1 1 1

[root@localhost mnt]# echo \$a $a $a

$a 1 1

[root@localhost mnt]# echo '$a $a $a'

$a $a $a

[root@localhost mnt]# echo "$a $a $a"

1 1 1

[root@localhost mnt]# echo '$a0 $a $a'

$a0 $a $a

[root@localhost mnt]# echo ${a}0 \$a $a

10 $a 1

[root@localhost 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

[root@localhost mnt]# echo "* * * * *"

* * * * *

[root@localhost mnt]# echo '* * * * *'

* * * * *

[root@localhost mnt]# echo "!"

-bash: !: event not found

[root@localhost mnt]# echo '!'

!

[root@localhost mnt]# echo "$"

$

[root@localhost mnt]# echo "$a"

1

[root@localhost mnt]# echo '$a'

$a

[root@localhost mnt]# echo "`"

> 1

> ^C

[root@localhost mnt]# echo '`'

`

[root@localhost mnt]# echo "\"

> a

> ^C

[root@localhost mnt]# echo '\'

\

[root@localhost mnt]# echo your hostname is `hostname`

your hostname is localhost.localdomain

[root@localhost 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

[root@localhost mnt]# echo '***** your hostname is `hostname` *****'

***** your hostname is `hostname` *****

[root@localhost mnt]# echo "***** your hostname is `hostname` *****"

***** your hostname is localhost.localdomain *****

[root@localhost mnt]# echo $[1+2]

3

[root@localhost mnt]# echo $[2+2]

4

[root@localhost mnt]# echo $[5*2]

10

[root@localhost mnt]# echo $[5**2]

25

[root@localhost mnt]# echo $[10/2]

5

[root@localhost mnt]# echo $[9%2]

1

[root@localhost mnt]# echo $[3%5]

3

[root@localhost mnt]# echo `expr 5 \+ 2`

7

[root@localhost mnt]# echo `expr 5 \- 2`

3

[root@localhost mnt]# echo `expr 5 \* 2`

10

[root@localhost mnt]# echo `expr 5 \/ 2`

2

[root@localhost mnt]# echo `expr 5 \% 2`

1

[root@localhost mnt]# let A=1+2

[root@localhost mnt]# echo $A

3

[root@localhost mnt]# let A=3-1

[root@localhost mnt]# echo $A

2

[root@localhost mnt]# let A=2*5

[root@localhost mnt]# echo $A

10

[root@localhost mnt]# let A=5%2

[root@localhost mnt]# echo $A

1

[root@localhost mnt]# let A=5/2

[root@localhost mnt]# echo $A

2

[root@localhost mnt]#

[root@localhost mnt]# ls

createuser.sh  exit.sh    num.sh      show_ip.sh  userfile

deluser.sh     iduser.sh  passwdfile  test.sh

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# sh test.sh

1

2

3

4

5

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=1;i<=5;i++))

do

echo $i

done

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=1;i<=5;i++))

do

echo $i

((i++))

done

[root@localhost mnt]# sh test.sh

1

3

5

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=10;i>0;i--))

do

echo $i

((i--))

done

[root@localhost mnt]# sh test.sh

10

8

6

4

2

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=1;i<10;i++))

do

((j+=i))

echo $j

done

[root@localhost mnt]# sh test.sh

1

3

6

10

15

21

28

36

45

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=10;i>0;i--))

do

echo $i

sleep 1

done

[root@localhost mnt]# sh test.sh

10

9

8

7

6

5

4

3

2

1

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=10;i>0;i--))

do

echo "After ${i}s is end"

sleep 1

done

[root@localhost 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

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

for ((i=10;i>0;i--))

do

echo -ne "After ${i}s is end \r"

sleep 1

done

[root@localhost mnt]# sh test.sh

[root@localhost mnt]#

[root@localhost mnt]# ["1"="2"] && echo yes || echo no

-bash: [1=2]: command not found

no

[root@localhost mnt]# ["1" = "2"] && echo yes || echo no

-bash: [1: command not found

no

[root@localhost mnt]# [ "1" = "2" ] && echo yes || echo no

no

[root@localhost mnt]# [ "1" -lt "2" ] && echo yes || echo no

yes

[root@localhost mnt]# [ "1" -gt "2" ] && echo yes || echo no

no

[root@localhost mnt]# [ "1" -le "2" ] && echo yes || echo no

yes

[root@localhost mnt]# [ "1" -le "1" ] && echo yes || echo no

yes

[root@localhost mnt]# [ "1" -ge "2" ] && echo yes || echo no

no

[root@localhost mnt]# [ "1" -ne "2" ] && echo yes || echo no

yes

[root@localhost mnt]# [ "1" -eq "2" ] && echo yes || echo no

no

[root@localhost mnt]# [ "$a" -gt "0" -a "$a" -lt "10" ] && echo yes || echo no

yes

[root@localhost mnt]# a=100

[root@localhost mnt]# [ "$a" -gt "0" -a "$a" -lt "10" ] && echo yes || echo no

no

[root@localhost mnt]# vim test.sh

[root@localhost 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

[root@localhost mnt]# sh test.sh

After 1:3 is end

After 1:2 is end

After 1:1 is end

[root@localhost mnt]# 

posted @ 2017-04-25 21:08  Virgo_sept  阅读(223)  评论(0编辑  收藏  举报