一、Shell介绍
Shell是linux系统中相当强悍的软件,他类似于windwos下的cmd.exe.在linux下,shell作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的结构控制,包括循环和分支。
二、初识shell脚本
Linux系统下的shell默认为bash,所以在写脚本的时候首行一定要是#!/bin/bash,这一行用于声明使用/bin/bash作为脚本语言。
脚本文件中,所有以#开头的行均为注释行,不会被执行。
这是一个脚本,实现功能的很简单,显示This is a test shell
vim shell.sh
#!/bin/bash
# Discribe:This is a test shell.
# Version 0.0.1
# Author:Myb
# DATE 2014-3-24
echo " This is a test shell."
:wq保存退出
bash –n shell.sh检查脚本的语法错误,不执行脚本。如果没有错误,则不会显示任何信息。
在linux下没有返回信息很多时候都会是最好的消息。
chmod +x shell.sh赋予shell.sh执行权
./shell.sh或者/bin/bash shell.sh执行脚本
[root@myb362 ~]# bash -n shell.sh
[root@myb362 ~]# chmod +x shell.sh
[root@myb362 ~]# ./shell.sh
This is a test shell.
[root@myb362 ~]#
这就是一个非常简单的脚本。当然我们也可以稍微填充一下刚才的脚本。
比如,添加一个用户名user1,密码与用户名相同。
如果不使用脚本的话,这也是一个非常简单的操作。
[root@myb362 ~]# useradd user1
[root@myb362 ~]# echo user1 | passwd --stdin user1
Changing password for user user1.
passwd: all authentication tokens updated successfully.
[root@myb362 ~]#
这样就添加了一个用户user1,,并且密码与用户名相同。
写入脚本中,就会是这样的
#!/bin/bash
# Discribe:This is a test shell.
# Version 0.0.1
# Author:Myb
# DATE 2014-3-24
echo " This is a test shell for add user user2."
useradd user2
echo user2 | passwd --stdin user2
:wq保存退出,执行./shell.sh,查看passwd文件看出user2已经添加成功。
[root@myb362 ~]# ./shell.sh
This is a test shell for add user user2.
Changing password for user user2.
passwd: all authentication tokens updated successfully.
[root@myb362 ~]# cat /etc/passwd | grep "^user2"
user2:x:6007:6007::/home/user2:/bin/bash
简单来讲,shell脚本就是很多命令的堆积,比如,我们需要添加user1到user10这10个用户,那么我们完全可以在上边的脚本中将两行命令复制10次,从user1一直添加到user10.虽然这种方式可以完成我们的要求,但是非常的繁琐,如果是添加100或者1000个用户呢?那可能就要疯了。
那针对这种循环执行的命令,shell脚本中,可以使用for、while和until来控制循环语句。
for循环
事先提供一个元素列表,而后,使用变量去遍历此元素列表,每访问一个元素,就执行一次循环体,直到元素访问完毕。
用法格式:
for VAR_NAME in 元素1 元素2 …;do
语句1;
语句2;
…
done
那添加3个用户user3、user4、user5就可以使用for循环语句来实现添加
useradd.sh脚本
#!/bin/bash
#
#
for i in user3 user4 user5;do #for循环控制遍历列表为user3 user4 user5 将遍历列表中的值传参给i
useradd $i #添加用户$i,$i 从遍历列表中逐个取出
echo $i | passwd --stdin $i #给用户赋予密码 --stdin将echo中的值传参给passwd命令
done
:wq保存退出
sh –n useradd.sh检查语法错误,赋予执行权限chmod +x useradd.sh并执行./useradd.sh
[root@myb362 ~]# sh -n useradd.sh
[root@myb362 ~]# chmod +x useradd.sh
[root@myb362 ~]# ./useradd.sh
Changing password for user user3.
passwd: all authentication tokens updated successfully.
Changing password for user user4.
passwd: all authentication tokens updated successfully.
Changing password for user user5.
passwd: all authentication tokens updated successfully.
[root@myb362 ~]# grep "^user" /etc/passwd
user2:x:6007:6007::/home/user2:/bin/bash
user3:x:6008:6008::/home/user3:/bin/bash
user4:x:6009:6009::/home/user4:/bin/bash
user5:x:6010:6010::/home/user5:/bin/bash
[root@myb362 ~]#
用户user3,user4,user5添加成功
这样可以大大的减少我们需要输入的命令,其实这个脚本还有一个地方是可以进行优化的,因为我们的遍历列表中user3、user4、user5只有最后一位数字变化,那么我们为了减少输入字符的长度,还可以这样写。
#!/bin/bash
#
for i in 3 4 5;do
useradd user$i
echo user$i | passwd –-stdin user$i
done
这样也是可以执行成功的,前提是你需要删除你的user3、4、5用户
userdel –r user3
userdel –r user4
userdel –r user5
使用for循环语句可以高效的完成工作,但是这种列表方式有时也会给我们的工作带来很多麻烦,比如需要添加100个用户,将100个用户写入列表中,实在是太麻烦了。
列表的生成方式:
1、逐个给出,如:user1 user2 user3
2、使用通配符实现文件通配,如:for File in /var/*
3、使用命令生成列表,如:for File in `ls /var`
4、生成数字序列
{}:{起始数字..结束数字},例如{1..100}表示从1到100
`seq [起始数字] [步长]结束数字`
例如:`seq 1 2 100`从1开始,步长为2,到100结束
结果:1 3 5 7 9 …
如何使用通配符实现文件通配:
常用的列表生成方式,比如我想要查看/var目录下的所有文件类型
使用for语句查看
[root@myb362 ~]# vi filetype.sh
#!/bin/bash
#
#
for File in /var/*;do
file $File
done
添加执行权限chmod +x filetype.sh ./filetype.sh查看文件类型
[root@myb362 ~]# ./filetype.sh
/var/cache: directory
/var/cvs: directory
/var/db: directory
/var/empty: directory
/var/games: directory
/var/lib: directory
/var/local: directory
/var/lock: directory
/var/log: directory
/var/mail: symbolic link to `spool/mail'
/var/nis: directory
/var/opt: directory
/var/preserve: directory
/var/run: directory
/var/spool: directory
/var/tmp: sticky directory
/var/yp: directory
使用命令生成列表
还以上一个示例来说,这次使用命令生成列表的方式完成
#!/bin/bash
for File in `ls /var/` ;do # ls /var/ 列出var目录下的所有文件当遍历列表
file /var/$File #这里别忘记了在$File前面加上文件的目录/var/
done
显示结果一样
[root@myb362 ~]# ./filetype2.sh
/var/cache: directory
/var/cvs: directory
/var/db: directory
/var/empty: directory
/var/games: directory
/var/lib: directory
/var/local: directory
/var/lock: directory
/var/log: directory
/var/mail: symbolic link to `spool/mail'
/var/nis: directory
/var/opt: directory
/var/preserve: directory
/var/run: directory
/var/spool: directory
/var/tmp: sticky directory
/var/yp: directory
生成数字列表
太好用的列表生成方式了
比如:使用for循环添加10个用户,用户名从user11-20,并添加密码,密码同用户名。
[root@myb362 ~]# vi useradd2.sh
#!/bin/bash
#
#
for User in `seq 11 20`;do
useradd user$User
echo user$User | passwd --stdin user$User
done
:wq保存退出
chmod +x添加执行权限./useradd2.sh执行脚本
[root@myb362 ~]# chmod +x useradd2.sh
[root@myb362 ~]# ./useradd2.sh
Changing password for user user11.
passwd: all authentication tokens updated successfully.
Changing password for user user12.
passwd: all authentication tokens updated successfully.
Changing password for user user13.
passwd: all authentication tokens updated successfully.
Changing password for user user14.
passwd: all authentication tokens updated successfully.
Changing password for user user15.
passwd: all authentication tokens updated successfully.
Changing password for user user16.
passwd: all authentication tokens updated successfully.
Changing password for user user17.
passwd: all authentication tokens updated successfully.
Changing password for user user18.
passwd: all authentication tokens updated successfully.
Changing password for user user19.
passwd: all authentication tokens updated successfully.
Changing password for user user20.
passwd: all authentication tokens updated successfully.
[root@myb362 ~]# cat /etc/passwd | grep "^user"
user2:x:6007:6007::/home/user2:/bin/bash
user3:x:6008:6008::/home/user3:/bin/bash
user4:x:6009:6009::/home/user4:/bin/bash
user5:x:6010:6010::/home/user5:/bin/bash
user11:x:6011:6011::/home/user11:/bin/bash
user12:x:6012:6012::/home/user12:/bin/bash
user13:x:6013:6013::/home/user13:/bin/bash
user14:x:6014:6014::/home/user14:/bin/bash
user15:x:6015:6015::/home/user15:/bin/bash
user16:x:6016:6016::/home/user16:/bin/bash
user17:x:6017:6017::/home/user17:/bin/bash
user18:x:6018:6018::/home/user18:/bin/bash
user19:x:6019:6019::/home/user19:/bin/bash
user20:x:6020:6020::/home/user20:/bin/bash
添加成功。
由于输出信息很多,我们不想让信息输出到屏幕上,就可以在命令后添加&>/dev/null,信息就不会输出到屏幕上。
如下
[root@myb362 ~]# vi useradd2.sh
#!/bin/bash
#
#
for User in `seq 11 20`;do
useradd user$User &>/dev/null
echo user$User | passwd --stdin user$User &>/dev/null
done
这样无论错误输出和标准输出都不会输出到屏幕上了。如有疑问,请自行google标准输入、标准输出、错误输出、输入重定向和输出重定向
看到这里,是不是想起了一个非常经典的题目,从1加到100,计算总和。
首先,我们要知道怎么在shell脚本中进行算术运算。
1、shell不支持浮点数、计算结果中的浮点数会被圆整为整数:1.23=1 1.99=1
2、shell运算符
+(加)
-(减)
*(乘)
/(除)
%(取余)
3、算术运算的实现方式:假如A=5,B=9
$[expression]:例如:$[$A+$B]
$((expression)):例如:$(($A+$B))
let expression:例如:let E=$A+$B
expr expression:例如:F=`expr $A + $B`
一般在脚本中比较常用的是第一种和第三种方式。
好了,写一个脚本计算1加到100的值
#/bin/bash
#
#
Sum=0 # 定义一个变量等于0
for i in {1..100};do #定义列表范围从1-100
Sum=$[$Sum+$i] #
done
echo “Sum is $Sum”
保存退出,赋予执行权限,执行脚本。结果如下
[root@myb362 ~]# ./sum.sh
Sum is 5050
[root@myb362 ~]#
Sum=$[$Sum+$i]解释:
第一次循环时,$Sum=0 $i=1 $[$Sum+$i]=1然后将1重新赋值给Sum,
第二次循环时,$Sum=1 $i=2 $[$Sum+$i]=3然后将3重新赋值给Sum,
第三次循环时,$Sum=3 $i=3 $[$Sum+$i]=6然后将6重新赋值给Sum,
……
直至循环体结束。
那求100以内所有奇数的和、偶数的和也是使用这种方法。
[root@myb362 ~]# vi sum2.sh
#!/bin/bash
#
#
EvenSum=0
OddSum=0
for i in `seq 1 2 100`;do #列表为1 3 5 7 9 …
OddSum=$[$OddSum+$i]
done
for i in `seq 2 2 100`;do
EvenSum=$[$EvenSum+$i] #列表为2 4 6 8 10 …
done
echo "OddSum:$OddSum"
echo "EvenSum:$EvenSum"
赋予权限,执行。结果如下:
[root@myb362 ~]# chmod +x sum2.sh
[root@myb362 ~]# ./sum2.sh
OddSum:2500
EvenSum:2550
这是使用for循环语句来实现1到100之间的奇偶数之和的方法,以后我们还会学到很多简单的方法。
结束:
for循环体在shell编程中非常的好用,他可以使我们快速便捷的完成一些需要重复操作的工作。当然还有while和until这种循环体,后边会专门写。感谢各位的围观,希望能够帮助需要的人,如果有错误的地方,希望大家能够指出,不胜感激。