您的位置:首页 > 运维架构 > Shell

shell(bash)基础

2017-06-20 19:13 253 查看
Bash脚本:简单来说就是把许多的指令集和在一起,并提供循环、条件、判断等重要功能,语法简单实用,用以编写程序,大大简化管理员的操作,并可以完成图形工具所无法实现的功能。

1、创建一个bash脚本

我们通常用vim来编辑一个脚本,它通常命名为 *.sh 。

如:vim test.sh

#!/bin/bash
echo "hello"


第一行是指定的命令解释器,常用的有#!/bin/bash 或#!/bin/sh,意思是告诉系统使用什么解释器来执行下面的语句。其他的以#开头的都是一些注释。

2、执行脚本

一般,刚写好的脚本文件的权限是:-rw-r–r–

在运行我们写出来的脚本前,需要给它执行权限chmod +x scripts(脚本名称)

(给所有用户执行权限,或按需要给其他权限)

(1)以绝对路径的方式去执行shell脚本

/mnt/test.sh

在shell脚本所在目录下,直接执行

cd /mnt/

./test.sh

(2)直接使用sh来执行脚本(在这种情况下,可以不必写第一行命令解释器,也可以不用修改权限)

sh test.sh 或 sh /mnt/test.sh



3、脚本调式模式

修改#!/bin/bash -x 或使用sh -x *.sh



4、特殊字符

(1)注释 #

(2)命令分隔符 ; (可以在一行写多个命令)

(3)反引号 ` (在执行一条命令时,会先将反引号内的语句当成命令先执行)

(4)引用和转译

弱引用(双引号““)
强引用 (单引号‘‘)
强引和弱引都是将引号内的字符看作普通字符
但强引用是将其中任何字符都看作普通字符,
弱引用不包括$、`、\
转译(\)一般转译后面的单个字符


例 test1.sh

#!/bin/bash
AA=date
BB=`date`
echo hello!! ; echo happy
#echo this is zhushi
echo abc \#def #ght
echo "$AA ; $BB ; `date` ; \$BB"
echo '$AA ; $BB ; `date` ; \$BB'


运行结果:



5、for循环

for循环的一般格式为

for 变量 in 列表 ;do ;done

例:test2.sh

(循环输出数字1-5)

#!/bin/bash
for NUM in {1..5}
do
echo $NUM
done


运行结果:



6、&& ||

格式:cmd1 && cmd2 || cmd3

若cmd1执行完毕且正确执行,则执行cmd2;若cmd1执行错误,则执行cmd3

例:ping.sh

(ping ip 地址172.25.254.220 - 224,

通了显示:ip is up;不通显示:ip is down)

#!/bin/bash
for NUM in {220..224}
do
ping -c1 -w1 172.25.254.$NUM &> /dev/null && echo 172.25.254.$NUM is up ||echo 172.25.254.$NUM is down
done


运行结果:



7、命令替换

格式:$(command)`command`

如:TODAY=$(date +%Y-%m-%d)——DODAY就表示以年月日为格式的日期

例:将/etc下所有以.conf结尾的备份到 /mnt/etcconfig-(date)

#!/bin/bash
TODAY=etcconfig-`date +%Y-%m-%d-%S`
mkdir -p /mnt/$TODAY
cp /etc/*.conf /mnt/$TODAY


(%Y(年)-%m(月)-%d(日)-%S(秒))

执行几次后,可以在/mnt/目录下看见:



8、shell计算

算术运算符:

运算符意思
< VARIABLE >++自加
< VARIABLE >- -自减
+加法
-减法
*乘法
**幂运算
/除法
%余数
+=加等
-=减等
计算命令:

(1)用$[]表示数学运算



(2)用expr表示数学运算

(注意数字与运算符之间要有空格,不能用于乘法,幂运算)



(3)用let表示数学运算



(4)用(())表示数学运算

如:((i=1;i<10;i++)) 从i=1开始,i进行自加,直到不满足i<10结束。

例:一个简单的倒计时

#!/bin/bash
for ((i=5;i>0;i--))
do
echo -n  "After ${i}s is end!"   #-n,输出不换行
echo -ne "\r   \r"           # 刷新这一行
sleep 1
done


运行结果:会在同一行显示倒计时“After 5s is end!“,数字由5到1结束。

9、while

while用来作条件判断,也可以用于循环。

语法:while [条件] ;do ;done

(注意条件与[]之间要有空格)

例:判断a是否等于1,是的话输出yes,不是输出no(-eq:等于)



10、参数read -p

read -p可以用来读取屏幕输入

常用方法:read -p “提示语” 变量(可以是多个)

(变量用来接收从shell界面输入的字符串)

例:

#!/bin/bash
read -p "What's your name:" name
read -p "what's your age and sex:" age sex
echo "$name is a $age-years-old $sex!!"


按提示输入相应的信息后,我们可以看到



11、位置参数

位置参数指的就是从命令行中传进来的参数, $0, $1, $2, $3…)(10及以后的位置参数要用${10},${11}…)

如:test.sh a b c

脚本文件的名字:$0(test.sh )

指定的位置参数总数:$#(即\$1,\$2等有多少个,没有是0)(3)

位置参数自身:$1,$2,$3… ( $1:a ,\$2:b …)

所有位置参数:$@,$*(a b c…)

例:用$#做判断,脚本后是否跟有参数,没有则提示输入一个ip,$1传递一个ip,判断该ip是否是通的。

#!/bin/bash
while [ "$#" -eq "0" ]
do
echo "Please give me a ip address!"
exit 1
done

ping -c 1 -w 1 $1 >/dev/null && echo "$1 is up" ||echo "$1 is down"


运行结果:



12、退出状态

我们常用“ $? “来判断上一个命令是否正确执行。

正常执行时,它的值为0,不正常时,值不为0

例:ls filename ; echo $? 可以用它来判断一个文件是否存在

#!/bin/bash
ls $1 &>/dev/null
[ "$?" -eq "0" ]&& echo $1 is exist || echo $1 is not exist


运行结果:



13、条件判断test命令

test条件判断可以做各种判断,这里列举一些常用的

(上面的退出状态“ $? “也是一种条件判断)

(1)判断字符串是否为空

判断字符串是否为空:-z

判断字符串是否为非空:-n



(2)字符串比较运算符

字符串 1 = 字符串2——判断字符串1是否和字符串2相等

字符串 1 != 字符串2——判断字符串1是否和字符串2不相等



(3)数字比较运算符

等于:-eq

不等于:-ne

大于:-gt

大于等于:-ge

小于:-lt

小于等于:-le



(4)二进制文件运算符

file1 -ef file2 判断file1和file2是否为硬链接

file1 -nt file2 判断file1的修改时间是否比file2的新

file1 -ot file2 判断file1的修改时间是否比file2的旧



(5)逻辑运算符

逻辑与:-a 判断1和判断2都成立,结果为真

逻辑或:-o 判断1和判断2有一个成立,结果为真

逻辑非:! 使原始的判断式取反

&& ,|| (见6)

(6)文件状态运算符

a、判断文件权限r,w,x

b、判断文件类型

判断文件是否存在:-e

判断文件是否为普通文件:-f

判断文件是否为目录:-d

判断文件是否为连接文件:-L

判断文件是否为块设备文件:-b

判断文件是否为字符设备文件:-c

判断文件是否为套接字文件:-S

例:check_file.sh(判断文件类型)

#!/bin/bash
while [ -z "$*" ]
do
echo "Please give a filename/directory
like: [ /mnt/check_file.sh /mnt/file" ]
exit 1
done
[ -e $1 ]|| (echo $1 is not exist!!!;exit 1)
[ -L $1 ]&& echo "$1 is a link"
[ -d $1 ]&& echo "$1 is a directory"
[ -b $1 ]&& echo "$1 is a block file"
[ -S $1 ]&& echo "$1 is a socket file"
[ -c $1 ]&& echo "$1 is a charactor file"
[ -f "$1" -a ! -L "$1" ]&& echo "$1 is a regular file"


运行结果:



14、if else语句

该语句的格式为:

if [满足的条件]

then

elif []

then



else

fi #结束标记

下面是一个简单的例子:(判断一个数是正数,负数,还是0)

#!/bin/bash
if
[ -z "$*" ]
then
echo "Please give a number"
elif
[ "$1" -lt "0" ]
then
echo "$1 is a negative number!"
elif
[ "$1" -gt "0" ]
then
echo "$1 is a positive number!"
else
echo "It is 0!!!"
fi


运行结果:



15、函数

在实现一个功能时,我们可能有很多代码都是重复的,这时,我们可以定义一个函数,让程序的结构更加清楚,代码利用率更高。

函数的定义

fun () { #fun是函数的名称

}

例子:

#!/bin/bash
#函数定义,里面的$1,$2是调用函数时,后面跟的变量
fun () {
echo "$1+$2=$(($1+$2))"
echo "$1-$2=$(($1-$2))"
echo "$1*$2=$(($1*$2))"
echo "$1/$2=$(($1/$2))"
}

#函数调用
fun 2 3
fun 5 1


运行结果:



16、case语句

case语句:它能把变量的值和多个模板进行匹配,在根据成功匹配的模板去判断应该执行哪部分代码。

格式:

case 变量 in

模式1)

command

;;

模式2)

command

;;

*) #表示在上面没有匹配的,用*表示

command

;;

esac

例子:

#!/bin/bash
case "$1" in
create)
touch $2
;;
delete)
rm -f $2
;;
*)
echo "use: /mnt/case.sh <create|delete> filename"
esac


运行结果:



17、expect

expect可以实现自动交互。在使用它之前,我们需要先安装它:

yum install -y expect

下面来实现ssh的自动连接,不需要输入密码

#!/usr/bin/expect表示使用expect的shell交互模式

set 定义变量

spawn在expect下执行shell脚本,命令等

expect对通过spawn执行的shell脚本的返回进行判断,是否包含“”中的字段

send:如果expect监测到了包含的字符串,将输入send中的内容,\n相当于回车

interact:退出expect返回终端,可以继续输入,否则将一直在expect不能退出到终端

#!/usr/bin/expect
set ip [ lindex $argv 0 ]
spawn ssh root@$ip
expect {
"yes/no" {send "yes\r";exp_continue}
"password" {send "123456\r"}
}
interact


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: