bash脚本

单元 十二

Bash脚本条件判断和控制流结构

.Bash位置参数

有两种简单的方法可以将用户输入读入bash中的变量。第一个方法是使用read提示用户输入(使用-p选项)并将其直接存储到一个或多个变量:

交互式输入

# read -p 'Enter your first and last name: ' FIRST LAST

另一个方法是使用位置参数来读取传递给脚本的命令行参数或选项输入。各种特殊变量存储传递的选项编号Bash解析的个别参数或整个原始命令行。

指定的位置参数总数:$#

位置参数自身:$0、$1、$2、$3....

所有位置参数: $@、$*

3退出状态

Linux命令完成时,将返回退出状态。成功完成程序时,将返回0的推出状态。这被bash当作逻辑True值。非零退出状态通常表示发生了错误,并且被bash当作逻辑False值。

例如:grep的退出状态的含义:

0 – 在指定的文件中找到了模式

1 – 在指定的文件中未找到模式

>1 – 一些其他错误(无法打开文件、错误的搜索表达式等)

推出状态的值被存储在"?"中,可以使用以下命令查看:

# echo $?

www.westos.org

4test条件判断

test命令可用于评估bash脚本中的表达式。它评估其参数所指定的表达式,如果表达式为true,返回零退出状态,如果表达式为false,则返回非零退出状态。test具有替代语法,使用方括号"[]"将表达式括起来,这样更易于阅读。

语法:test EXPRESSION 或 [EXPRESSION]

非零或零长度字符串运算符:test -{n|z} STRING

[root@server0 ~]# [ -n westos ]; echo $?

0

[root@server0 ~]# [ -z westos ]; echo $?

1

5字符串比较运算符:=、!=

[root@server0 ~]# [ abc = abc ]; echo $?

0

[root@server0 ~]# [ abc = ABC ]; echo $?

1

[root@server0 ~]# [ abc != ABC ]; echo $?

0

数字比较运算符:-eq、-ne、-lt、-le、-gt、-ge

[root@server0 ~]# [ 1 -eq 1 ]; echo $?

0

[root@server0 ~]# [ 1 -ne 1 ]; echo $?

1

[root@server0 ~]# [ 1 -gt 2 ]; echo $?

1

6文件状态运算符:test -{b|c|e|f|d|r|w|x|s|L} FILE/DIRECTORY

[root@server0 ~]# [ -b /dev/sda ]; echo $?

1

[root@server0 ~]# [ -c /dev/zero ]; echo $?

0

[root@server0 ~]# [ -e /etc/passwd ]; echo $?

0

[root@server0 ~]# [ -f /etc/passwd ]; echo $?

0

[root@server0 ~]# [ -d /etc/passwd ]; echo $?

1

[root@server0 ~]# [ -L /etc/passwd ]; echo $?

1

www.westos.org

7二进制文件运算符:-ef、-nt、-ot

[root@server0 bin]# [ /bin/mount -ef /usr/bin/mount ]; echo $?

0

[root@server0 bin]# [ /bin/mount -nt /usr/bin/mount ]; echo $?

1

[root@server0 bin]# [ /bin/mount -ot /usr/bin/mount ]; echo $?

1

逻辑运算符:-o、-a、!、&&、||

[root@server0 bin]# [ 2 -gt 1 -a 1 -gt 2 ]; echo $?

1

[root@server0 bin]# [ 2 -gt 1 -o 1 -gt 2 ]; echo $?

0

[root@server0 bin]# [ ! 2 -gt 1 ]; echo $?

1

8if语句

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

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

10case语句

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

11expect语句

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

12#!/usr/bin/expect

这一行告诉操作系统脚本里的代码使用那一个shell来执行。

set timeout 10

设置后面所有的expect命令的等待响应的超时时间,单位为秒。

spawn talk

spawn是expect的内部命令,作用是给后面的shell指令加个壳,用来传递交互指令。

expect "who"

判断上次输出结果里是否包含“who”的字符串,如果有则立即返回,否则等待超时时间后返回。

send "westos\n"

执行交互动作,相当于手工输入"westos"。

expect eof

作用是在输出中搜索文件结束符,如果没有这一行,脚本会立即退出,得不到正确结果。

interact

执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。否则退出登录。

$argv 参数数组

expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个....参数。

13环境变量

shell和脚本使用变量来存储数据 ,有些变量可以连同它们的内容传递给子进程,这些量我们称之为环境变量。

[root@server0 ~]# LINUX=redhat

[root@server0 ~]# echo $LINUX

redhat

[root@server0 ~]# bash

[root@server0 ~]# echo $LINUX

[root@server0 ~]# exit

exit

[root@server0 ~]# export LINUX

[root@server0 ~]# bash

[root@server0 ~]# echo $LINUX

redhat

[root@server0 ~]# exit

exit

14使用env命令显示所有环境变量

使用set命令现实所有本地定义的shell变量

Bash启动脚本

在用户登录的时候,会运行全局变量文件/etc/profile,和用户自定义变量文件~/.bash_profile去初始化它们的环境变量。

/etc/profile

\_ /etc/profile.d/*.sh

~/.bash_profile

\_ ~/.bashrc

\_ /etc/bashrc

15使用别名

alias命令可以用来自定义属于自己的系统命令,写入~/.bashrc 文件永久生效。

查看别名:

# alias

alias ls='ls --color=auto'

alias mv='mv -i'

alias rm='rm -i'

...

设置别名:

# alias mycom='echo hello;hostname'

# mycomm

hello

server0.example.com

删除别名: unalias mycomm

16使用函数

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

举例:

1.read 提示用户输入

[root@localhost mnt]# ls

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# cat test.sh

#!/bin/bash

read -p "Give me a word:" HELLO

echo $HELLO

[root@localhost mnt]# sh test.sh

Give me a word:hello

hello

[root@localhost mnt]# sh test.sh

Give me a word:smile

smile

2.检测系统用户是否存在。如果不存在,则自动建立。

1).[root@localhost mnt]# vim check_user.sh

[root@localhost mnt]# sh check_user.sh

please input username:student

The user is exist

[root@localhost mnt]# sh check_user.sh

please input username:timmy

you can create the user

please input password:timmy

Changing password for user timmy.

passwd: all authentication tokens updated successfully.

[root@localhost mnt]# cat check_user.sh

#!/bin/bash

read -p "please input username:" USERNAME

CHECK=`getent passwd $USERNAME`

[ -n "$CHECK" ] && (

echo "The user is exist"

) || (

        echo "you can create the user"

read -p "please input password:" PASSWORD

useradd $USERNAME;echo $PASSWORD | passwd --stdin $USERNAME

        )

2).用if语句

[root@localhost mnt]# sh check_user1.sh

please input username:student

student is exist

[root@localhost mnt]# sh check_user1.sh

please input username:haha

please input password:haha

Changing password for user haha.

passwd: all authentication tokens updated successfully.

[root@localhost mnt]# cat check_user1.sh

#!/bin/bash

read -p "please input username:" USERNAME

CHECK_USER=`getent passwd $USERNAME`

if

[ -z "$CHECK_USER" ]

then

read -p "please input password:" PASSWORD

useradd $USERNAME

echo $PASSWORD | passwd --stdin $USERNAME

else

        echo "$USERNAME is exist"

fi  

3.比较userfile passfile文件行数,是否缺失。

[root@localhost mnt]# vim check_userfile.sh

[root@localhost mnt]# vim userfile

[root@localhost mnt]# vim passfile

[root@localhost mnt]# vim check_userfile.sh

[root@localhost mnt]# sh check_userfile.sh userfile passfile

error:userfile's line is different than passfile

[root@localhost mnt]# vim passfile

[root@localhost mnt]# sh check_userfile.sh userfile passfile

error:userfile's line is different than passfile

[root@localhost mnt]# vim passfile

[root@localhost mnt]# vim passfile

[root@localhost mnt]# sh check_userfile.sh userfile passfile

Changing password for user user1.

passwd: Authentication token manipulation error

Changing password for user user2.

passwd: Authentication token manipulation error

Changing password for user user3.

passwd: Authentication token manipulation error

[root@localhost mnt]# sh check_userfile.sh userfile passfile

error:user1 is exist

error:user2 is exist

error:user3 is exist

[root@localhost mnt]# vim passfile

[root@localhost mnt]# sh check_userfile.sh userfile passfile

error:userfile's line is different than passfile

[root@localhost mnt]# vim passfile

[root@localhost mnt]# vim userfile

[root@localhost mnt]# sh check_userfile.sh userfile passfile

error:userfile's line is different than passfile

4.查看目录类型

1)用if语句

[root@localhost mnt]# vim test1.sh

[root@localhost mnt]# sh test1.sh /dev/vdb

/dev/vdb is block

[root@localhost mnt]# sh test1.sh /etc/password

/etc/password is not exist

[root@localhost mnt]# sh test1.sh /etc/passwd

/etc/passwd is a file

[root@localhost mnt]# sh test1.sh /etc

/etc is a directory

[root@localhost mnt]# cat test1.sh

#!/bin/bash

if

[ ! -e $1 ]

then

echo $1 is not exist

elif

[ -L $1 ]

then

echo $1 is  a link

elif

[ -f $1 ]

then

echo $1 is a file

elif

[ -d $1 ]

then

echo $1 is a directory

elif

[ -b $1 ]

then

echo $1 is block

fi

2)用case语句

[root@localhost mnt]# vim test2.sh

[root@localhost mnt]# sh test2.sh  -f /etc/

/etc/ is not a file

[root@localhost mnt]# sh test2.sh  -f /etc/passwd

/etc/passwd is a file

[root@localhost mnt]# cat test2.sh

#!/bin/bash

CHECK () {

if

[ $1 $2 ]

then

echo $2 is a $3

else

echo $2 is not a $3

fi

}

case "$1" in

-f)

CHECK -f $2 file

;;

-b)

CHECK -b $2 block

;;

-d)

CHECK -d $2 directory

;;

*)

echo "error:please input a argment and file after command"

esac

5.实现自动应答脚本

[root@localhost mnt]# ls

[root@localhost mnt]# vim test.sh

[root@localhost mnt]# sh test.sh

Give me a word:hello

hello

[root@localhost mnt]# sh test.sh

Give me a word:smile

smile

(2)自动硬盘分区

[root@localhost mnt]# vim fdisk.sh

[root@localhost mnt]# sh fdisk.sh /dev/vdb

Welcome to fdisk (util-linux 2.23.2).

 

Changes will remain in memory only, until you decide to write them.

Be careful before using the write command.

 

Device does not contain a recognized partition table

Building a new DOS disklabel with disk identifier 0xd252008d.

 

Command (m for help): Partition type:

   p   primary (0 primary, 0 extended, 4 free)

   e   extended

Select (default p): Using default response p

Partition number (1-4, default 1): First sector (2048-20971519, default 2048): Using default value 2048

Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519): Partition 1 of type Linux and of size 100 MiB is set

 

Command (m for help): The partition table has been altered!

 

Calling ioctl() to re-read partition table.

Syncing disks.

[root@localhost mnt]# cat fdisk.sh

#!/bin/bash

fdisk $1 <<end

n

 

 

 

+100M

wq

end

3)自动问答,expect语句

[root@localhost mnt]# sh ask.sh

input your name: chenrongbo

input your age: 23

input your class: linux

input your feel: happy

chenrongbo is 23's years old and chenrongbo is linux student feel happy

[root@localhost mnt]# cat ask.sh

#!/bin/bash

read -p "input your name: " NAME

read -p "input your age: " AGE

read -p "input your class: " CLASS

read -p "input your feel: " FEEL

echo "$NAME is $AGE's years old and $NAME is $CLASS student feel $FEEL"

 

[root@localhost mnt]# cat answer.exp

#!/usr/bin/expect

spawn /mnt/ask.sh

expect {

"name:" {send "lee"\r;exp_continue};

"age:" {send "18\r";exp_continue};

"class" {send "linux\r";exp_continue};

"feel:" {send "happy\r"};

}

interact eof

(4)自动连接主机

[root@localhost mnt]# cat auto_connect.exp

#!/usr/bin/expect

spawn ssh root@172.25.254.237

expect {

"(yes/no)?" {send "yes\r";exp_continue};

"password:" {send "redhat\r"};

}

interact

6.环境变量

[root@localhost ~]# vim .bash_profile

[root@localhost ~]# cat .bash_profile

# .bash_profile

 

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

 

# User specific environment and startup programs

 

PATH=$PATH:$HOME/bin

 

export PATH

export PATH=$PATH:/mnt

[root@localhost ~]# source .bash_profile

[root@localhost ~]# echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/mnt

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值