执行一个脚本,往往需要加个权限
结构开头: # ! /bin/bash
[root@cenots003 sbin]# cd /usr/local/sbin/
[root@cenots003 sbin]# vim first.sh
#! /bin/bash
## This is my first shell script.
## Writen by Aming 2013-05-24.
ls /tmp/
echo "this is the first script"
date
echo "hello world"
保存退出
其执行方法:2
1 [root@cenots003 sbin]# bash first.sh = sh first.sh 执行脚本
[root@cenots003 sbin]# ./first.sh 相对路劲执行
[root@cenots003 sbin]#sh -x first.sh 查看脚本执行过程
2.[root@cenots003 sbin]# chmod a+x first.sh 增加执行权限
[root@cenots003 sbin]# ./first.sh
3[root@cenots003 sbin]# pwd 用绝对路径直接也可以执行
/usr/local/sbin
[root@cenots003 sbin]# /usr/local/sbin/first.sh
date
yum install -y ntp
[root@cenots003 sbin]# date -s "2014-12-20 13:26:56"
[root@cenots003 sbin]# ntpdate time.windows.com 校正时间
root@cenots003 sbin]# ntpdate ntp.fudan.edu.cn 负担大学时间校正
[root@cenots003 sbin]# date +%F
2017-03-21
[root@cenots003 sbin]# date +%T
16:51:32
date在脚本中最常用的几个用法:1种是
data +%Y 以四位数字格式打印年份
date +%y 以两位数字格式打印年份
date +%m 月份
date +%d 日期
date +%H 小时
date +%M 分钟
date +%S 秒
date +%w 星期几
date +%W 第多少周
date +%s 距离1970年1月1日的零点零分零秒 至 今 时间串 1490086533 单位秒
date +%w 星期,如果结果显示0 则表示周日
# date +"%F-%T"
2017-03-21-16:58:20
#date -d "-2 days " +%F
# date -d "-2 day" +%d
# date -d "-2 hour" +%H
# date -d "-2 min" +%M
脚本中使用到了反引号,你是否还记得它的作用? ‘d’ 和 ‘d1’ 在脚本中作为变量出现,
定义变量的格式为: 变量名=变量的值
当在脚本中引用变量时需要加上 ‘$’ 符号,
这跟前面讲的在shell中自定义变量是一致的。下面看看脚本执行结果吧:
# vim 2.sh 写入:# vim 2.sh Shell脚本和用户交互
#! /bin/bash
read -t 10 -p "please input a number: " number
echo $number
保存退出
#sh 2.sh # vim 2.sh
[root@cenots003 sbin]# sh 2.sh 每执行一次命令,才有效
please input a number: 3243243 等待10秒,没有输入自动退出命令
3243243
# vim 3.sh 写入:
#!/bin/bash
echo "\$1=$1"
echo "\$2=$2"
echo "\$3=$3"
echo "\$0=$0"
echo "\$4=$4"
echo "\$5=$5"
[root@cenots003 sbin]# sh 3.sh zz xx cc vvvv fff
$1=zz
$2=xx
$3=cc
$0=3.sh
$4=vvvv
$5=fff
加法运算,比如:
[root@cenots003 sbin]# a=1
[root@cenots003 sbin]# b=2
[root@cenots003 sbin]# sum=$[$a+$b]
[root@cenots003 sbin]# wo=$[$a+$b]
[root@cenots003 sbin]# echo $wo
3
在shell脚本中我们同样可以使用 if 逻辑判断。在shell中if判断的基本语法为: if case
#!/bin/bash
a=5
if [ $a -gt 3 ]
then
echo "a>3"
fi
:wq保存退出
名词解释:
> -gt :大于
< -lt :小于
== -eq :等于
!= -ne :不等于
>= -ge :大于或等于
<= -le :小于或等于
#!/bin/bash
a=5
if [ $a -gt 10 ]
then
echo "a>10"
else
echo "a<=10"
fi
#!/bin/bash
a=5
if [ $a -gt 10 ]
then
echo "a>10"
elif [ $a -lt 4 ]
echo "a<=10"
then
echo "a<4"
else
echo "4>a<10"
fi
# vim 2.sh
[root@cenots003 sbin]# touch 1.txt
[root@cenots003 sbin]# if [ -f 1.txt ]; then echo ok; fi 如果1.txt是个文件则显示ok。否则不显示
ok
[root@cenots003 sbin]#
[root@cenots003 sbin]# if [ -r 1.txt ]; then echo ok; fi 是否可读
ok
[root@cenots003 sbin]# if [ -w 1.txt ]; then echo ok; fi 是否可写
ok
[root@cenots003 sbin]# if [ -x 1.txt ]; then echo ok; fi
[root@cenots003 sbin]#
变量是否为数字:
#!/bin/bash
read -p "please input a number: " n
m=`echo $n|sed 's/[0-9]//g'`
if [ -n "$m" ]
then
echo "The character you input is not anumber, please retry."
else
echo $n
fi
变量是否为空:
#!/bin/bansh
read -p "请输入一个数字:" n
n2=`echo $n|grep -c '[^0-9]'`
if [ $n2 -eq 1 ]
then
echo "你输入的不是纯数字请重新输入"
exit 1
fi
n1=$[$n%2]
if [ $n1 -eq 0 ]
then
echo "你输入的是偶数"
else
echo "你输入的是奇数"
fi
read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”
[root@cenots003 sbin]# grep '^mysql:' /etc/passwd 结果过滤出
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
[root@cenots003 sbin]# if grep -q '^mysql:' /etc/passwd;then echo "you A.";fi 没有mysql用户则显示
you A.
[root@cenots003 sbin]# if grep -q '^mysql2:' /etc/passwd;then echo "you A.";fi 有mysql2用户则显示,没有这用户默认不显示。
[root@cenots003 sbin]#
[root@cenots003 sbin]# if [ -d /tmp/ ] && [ -f 1.txt ];then echo ok;fi
ok
如果/tmp/是个目录 并且 1.txt是个文件,是就ok。
[root@cenots003 sbin]# rm 1.txt
rm:是否删除普通空文件 "1.txt"?y
[root@cenots003 sbin]# if [ -d /tmp/ ] && [ -f 1.txt ];then echo ok;fi
[root@cenots003 sbin]# if [ -d /tmp/ ] || [ -f 1.txt ];then echo ok;fi 或者
ok
# vim 2.sh
[root@cenots003 sbin]# if [ -d /tmp/ -o -f 1.txt ];then echo ok;fi or或者的意思
ok
[root@cenots003 sbin]# if [ -d /tmp/ -a -f 1.txt ];then echo ok;fi and的意识
在shell脚本中我们同样可以使用 if 逻辑判断。在shell中if判断的基本语法为: case
在脚本中太多的if则用case结构:
#! /bin/bash
read -p " please input a number: " n
m=$[$n%2]
#echo "除2的余数为: $m"
case $m in
1)
echo " the number is Ji_shu."
;;
0)
echo "the number is Ou_shu. "
;;
*)
echo "It is not jishu ou oushu wa."
esac
Shell脚本中也算是一门简易的编程语言了,当然循环是不能缺少的。常用到的循环有for循环和while循环。下面就分别介绍一下两种循环的结构。
for whlie
[root@cenots003 sbin]# vim for.sh
#!/bin/bash
for i in `seq 1 10`
do
echo $i
done
:wq保存退出
#!/bin/bash
for i in {1..10}
do
echo $i
done
:wq保存退出
#!/bin/bash
sum=0
for i in {1..10}
do
sum=$[$sum+$i]
done
echo $sum
:wq保存退出
#!/bin/bash
sum=0
for i in {1..100};do
let sum+=$i
done
echo $sum
:wq保存退出
#touch 1.txt# vim 2.sh # cat /etc/passwd > 1.txt 把每一行做为循环的条件,写入:
#!/bin/bash
for l in `cat 1.txt`
do
echo $l
done
:wq保存退出
# vim 2.txt 写入:
1 2 3
4ksldfjkl
aaa bbb
vim 2.txt
1 2 3
4ksldfjkl
aaa bbb
:wq
[root@cenots003 sbin]# for l in `cat 2.txt`; do echo $l ;done
1
2
3
aaa
bbb
# vim 3.txt
[root@cenots003 sbin]# for ip in `cat 3.txt`;do echo $ip;done
192.168.1.113
192.168.1.114
192.168.1.118
192.168.1.119
[root@cenots003 sbin]# for file in `ls`;do echo $file; done 以文件名字循环
[root@cenots003 sbin]# for file in `ls`;do echo $file; du -sh $file;done 查看并查看大小
# vim while.sh 写个死循环脚本,每隔3秒报一次时间
#!/bin/bash
while :
do
date +%T
sleep 3
done
当不是数字时,请继续输入数字。
#!/bin/bash
while :
do
read -p " please input a number: " m
n=`echo $m |sed 's/[0-9]//g'`
if [ -z "$n" ]
then
echo $m
exit
fi
done
如果不是数字,一直到你输入数字为止。死循环:
#!/bin/bash
n=1
while [ ! -z "$n" ]
do
read -p " please input a number : " m
n=`echo $m |sed 's/[0-9]//g'`
echo $m
done
函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段代码时直接调用这个小单元的名字即可。有时候脚本中的某段代总是重复使用,如果写成函数,每次用到时直接用函数名代替即可,这样就节省了时间还节省了空间。
控制循环:
break continue exit
当循环结果为4时,结束
#!/bin/bash
for i in `seq 1 10`
do
echo $i
if [ $i -eq 4 ]
then
break
fi
echo $i
done
# vim 2.sh
#!/bin/bash
for i in `seq 1 10`
do
echo $i
if [ $i -eq 4 ]
then
break
fi
echo $i
done
echo "jie_shu"
当为4时,只显示一次,初次各显示俩次:
#!/bin/bash
for i in `seq 1 10`
do
echo $i
if [ $i -eq 4 ]
then
continue
fi
echo $i
done
echo "for done"
找到4就直接退出,不执行下面的脚本了
#!/bin/bash
for i in `seq 1 10`
do
echo $i
if [ $i -eq 4 ]
then
exit
fi
echo $i
done
echo "for done"
function 加法运用,
#!/bin/bash
function mysum() {
sum=$[ $1+$2]
echo $sum
}
a=1
b=2
mysum $a $b
#!/bin/bash
function mysum() {
local sum=$[ $1+$2]
echo $sum
}
a=1
b=2
mysum $a $b
echo $sum
[root@cenots003 sbin]# a=(1 2 3 4 5 6 a sd f o)
[root@cenots003 sbin]# echo ${a[@]}
[root@cenots003 sbin]# echo ${a[2]}
3
# a[10]=19 增加变量a里面的数组,排第10的位置为19,从0排位算起
# unset a[4] 删除变量a里面的数组,从0算开始排第四的位置为wu
[root@cenots003 sbin]# echo ${#a[@]}
12
[root@cenots003 sbin]# for i in `seq 0 9`; do a[ $i]=$RANDOM;done;echo ${a[@]} 0到9谁机组立10个数字组
5873 20806 768 12405 26668 17902 8401 12884 18914 9919 19 18
# for i in `seq 0 9`; do a[ $i]=$RANDOM;done;echo ${a[@]} |sed 's/ /\n/g 默认从大到小排
# for i in `seq 0 9`; do a[ $i]=$RANDOM;done;echo ${a[@]} |sed 's/ /\n/g'|sort -n 从小到大排序
# echo ${a[@]:0:3} 输出3组数字
# echo ${a[@]:0:5} 输出5组数字
# echo ${a[@]:2:5} 输出5组数字,从第二为排起
Shell脚本大体上就介绍这么多了,笔者所举的例子都是最基础的,所以即使你把所有例子完全掌握也不代表你的shell脚本编写能力有多么好。所以剩下的日子里你尽量要多练习,多写脚本,你写的脚本越多,你的能力就越强。希望你能够找专门介绍shell脚本的书籍深入的去研究一下它。随后笔者将给你留几个shell脚本的练习题,你最好不要偷懒。
1. 编写shell脚本,计算1-100的和;
2. 编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求,如果输入的数字小于1,则重新输入,直到输入正确的数字为止;
3. 编写shell脚本,把/root/目录下的所有目录(只需要一级)拷贝到/tmp/目录下;
4. 编写shell脚本,批量建立用户user_00, user_01, … ,user_100并且所有用户同属于users组;
5. 编写shell脚本,截取文件test.log中包含关键词’abc’的行中的第一列(假设分隔符为”:”),然后把截取的数字排序(假设第一列为数字),然后打印出重复次数超过10次的列;
6. 编写shell脚本,判断输入的IP是否正确(IP的规则是,n1.n2.n3.n4,其中1<n1<255, 0<n2<255, 0<n3<255, 0<n4<255)。
以下为练习题答案:
1. #! /bin/bash
sum=0
for i in `seq 1 100`; do
sum=$[$i+$sum]
done
echo $sum
2. #! /bin/bash
n=0
while [ $n -lt "1" ]; do
read -p "Please input a number, it must greater than "1":" n
done
sum=0
for i in `seq 1 $n`; do
sum=$[$i+$sum]
done
echo $sum
3. #! /bin/bash
for f in `ls /root/`; do
if [ -d $f ] ; then
cp -r $f /tmp/
fi
done
4. #! /bin/bash
groupadd users
for i in `seq 0 9`; do
useradd -g users user_0$i
done
for j in `seq 10 100`; do
useradd -g users user_$j
done
5. #! /bin/bash
awk -F':' '$0~/abc/ {print $1}' test.log >/tmp/n.txt
sort -n n.txt |uniq -c |sort -n >/tmp/n2.txt
awk '$1>10 {print $2}' /tmp/n2.txt
6. #! /bin/bash
checkip() {
if echo $1 |egrep -q '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' ; then
a=`echo $1 | awk -F. '{print $1}'`
b=`echo $1 | awk -F. '{print $2}'`
c=`echo $1 | awk -F. '{print $3}'`
d=`echo $1 | awk -F. '{print $4}'`
for n in $a $b $c $d; do
if [ $n -ge 255 ] || [ $n -le 0 ]; then
echo "the number of the IP should less than 255 and greate than 0"
return 2
fi
done
else
echo "The IP you input is something wrong, the format is like 192.168.100.1"
return 1
fi
}
rs=1
while [ $rs -gt 0 ]; do
read -p "Please input the ip:" ip
checkip $ip
rs=`echo $?`
done
echo "The IP is right!"
读取一个文件,然后打印出来,然后没打印一行在空一行出来,还要打印没行行号。
#!/bin/bash
linenumber=1 #行号从数字1开始
read oneline #从文件、etc passwd 中读取第一行
while [ "$oneline" != "" ] #如果读到的是一个空行则退出循环
do
echo -e " $linenumber:$oneline\n" #打印行号及这行数据:然后打印一个空行符
linenumber=`expr $linenumber + 1` #行号加1
read oneline #从文件etc passwd中读取下一行
done
exit 0