Linux系统——shell脚本
shell脚本编程
作用:通过命令行解析的方式,自动执行设定好的程序或命令代码。(若将脚本挂到定时任务中,就会自动在非工作时间里自动触发执行程序)
Shell脚本文件以“.sh”结尾
规范的Shell脚本第一行会指出由哪个程序(解释器)来执行脚本中的内容。在linux bash编程中一般为:#!/bin/bash (表示该脚本运用/bin/bash命令进行解析)
Shell的输出用echo命令;
Python的输出用print命令
执行脚本的方式:
方法一:/bin/sh是bash的软链接,也就是说我么既可以用sh执行也可以用bash执行脚本
# sh yunjisuan.sh
# bash yunjisuan.sh
方法二:以绝对路径的方式执行脚本(前提:将该脚本添加x执行权限 )
# chmod +x yunjisuan.sh
# /root/benet/yunjisuan.sh
方法三:以source脚本路径的方式执行脚本(等同于“.脚本路径” )只在当前环境生效
# source yunjisuan.sh
# . yunjisuan.sh
方法四:以相对路径的方式执行脚本(前提:将该脚本添加x执行权限 )
# ./yunjisuan.sh
写脚本
(1)vim编辑yunjisuan.sh
(2)查看yunjisuan.sh脚本
(3)执行yunjisuan.sh脚本
脚本中书写的命令必须是非交互式的命令!!!
虽然脚本可以自动化执行,但脚本不会判断命令是否执行成功,因此需要进行逻辑判断
方法一:
test命令
判断该字符串表示为文件还是目录
-d 测试是否为目录
-e 测试目录或文件是否存在
-f 测试是否为文件
-l 测试是否为链接文件
-r 测试当前用户是否可读
-w 测试当前用户是否可写
-x 测试当前用户是否可执行
-s 测试文件大小非0时为真(若为非空文件,则为真)
-u 测试是否具有SUID属性
-g 测试是否具有SGID属性
-k 测试是否具有sticky bit 粘滞位属性
-z 测试字符串是否为空(zero)
file1 -nt file2测试第一个文件是否比第二个文件新(new then)
file1 -ot file2 测试第一个文件是否比第二个文件旧(old then)
file1 -ef file2 测试第一个文件是否与第二个文件为同一个文件(link之类的文件)
# test -d 目标路径
# echo $?判断是否是目录,若显示0表示真(是目录),若显示非0则假(不是目录)
# test -f 目标路径
判断目标是不是文件
# echo $?
$?返回值参考
0 表示运行成功
2 权限拒绝
1~125 表示运行失败,脚本命令,系统命令错误或参数传递错误;
126 找到该命令,但无法执行
127 未找到要运行的命令
128 命令被系统强制结束
方法二:
使用“[]”,表示开启判断条件(“[]”两边须有空格)
# xx=”welcome”
# [ $xx == welcome] && echo “0” || echo “1”
0
“[]”应用于整数 (格式:整数1 操作符 整数2)
-gt(great than)表示大于
-lt(less than)表示小于
-eq(equal)表示等于
-ne (not equal)表示不等于
-ge 表示大于等于
-le表示小于等于
&& 逻辑与,表示前一指令为真,执行后一指令,否则不执行
|| 逻辑或,表示前一指令为假,执行后一指令,否则不执行
# xx=”44”
# if [ -f "$file1" ];then echo 1;else echo 0;fi
相当于# [ -f "file1" ] && echo 1 ||echo 0
# [ $xx -eq 34 ] && echo “0” || echo “1”
1
字符串测试
[ -z “字符串” ] 字符串内容为空
[ -n “字符串” ] 字符串内容不为空
${#变量名} 求变量的字符串位数,判断字符串是否为空
# xx=”123411”
# echo ${#xx}
6
# xx=””
# echo ${#xx}
0
脚本的交互式输出模式
方法一:
执行脚本过程中,存在需要用户输入内容的情况,通过read命令进行交互式输入
添加注释给用户:
输入格式:read -p “文本提示” 变量名
输0出格式:echo $变量名
创建用户名和密码
#!/bin/bash
User="yunjisuan"
Passwd="123456"
read -p "请输入用户名" user
read -p "请输入密码" passwd
[ $User -eq $user ] && echo "YOU ARE RIGHT" || echo “YOU ARE WRONG”
[ $Passwd -eq $user ] && echo "YOU ARE RIGHT" || echo "YOU ARE WRONG"
逻辑测试
“[]”中,-a(&&) 表示并且;
-o (||)表示或者
!逻辑否
方法二:通过参数传递的方式进行交互式输入
/etc/init.d/ 服务启动脚本
服务启动脚本/etc/init.d/后面写的内容就是参数,通过这个参数进行交互式输入
$# 表示脚本要处理的的参数个数
$? 表示命令或脚本执行状态码
$* 表示横向罗列脚本要处理的所有参数(把所有参数视为整体)
$@ 表示横向罗列脚本要处理的所有参数(把所有参数视为单个参数的组合)
$0 表示脚本文件的绝对路径或相对路径(脚本文件的执行路径)
$1 第一个参数
$n 第n个参数
脚本中反引号“``”、“$()”的应用
变量的算数运算
变量的数值运算多用于脚本程序的过程控制,只能进行简单的整数运算,不支持小数运算,整数值得运算主要通过内部命令expr进行。
# x=11
# y=22
# expr $x \* $y
格式: expr 变量1 运算符 变量2...
++ -- 增加及减少,可前置也可放在结尾
! ~ 一元运算的正负号,非,逻辑与位的取反
\* 乘法
/ 除法
% 取余
** 幂运算
+ 加法
- 减法
<; <=;>; >= 比较符号
== 1+= 相等,不相等
<< 向左移动
>> 向右移动
>>> 填0右移
& 位的与AND
^ 位的异或
| 位的或
&& 位的AND
|| 位的OR
?: 条件表达式
=; += ;-= ;*=等 赋值运算符
(())用法(常用于简单的整数运算)
“(())”在命令行执行时不需要$符号,但是输出需要$符号
“(())”里所有字符之间有无或多个空格没有任何影响
# b=$((1+2**3-4%3))
# echo $b
8
# echo $((1+2**3-4%3))
8
a++,a--,++a,--a区别
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减。
# a=8
# echo $a
8(a赋值为8)
# echo $((a+=1)) #相当于a=a+1
9(a赋值为a+1=9)
# echo $((a++)) #a在前,先输出a的值,在加1
9(a赋值为上一值a为9)
# echo $a
10(a赋值上一值的9++,9+1为10)
# echo $((a--))
10(a取上一值a为10)
# echo $a
9(a取上一值10--,10-1为9)
# echo $((++a))
10(先+1,在取上一值9,1+9=10)
# echo $a
10(取上一值10)
# echo $((--a))
9(先-1,取上一值10,10-1=9)
# echo $a
9(取上一值9)
Shell脚本中不支持“i++”表达,可以用C语言的((i++))在shell中表示
或者“let h++”
If条件语句
格式(fi 表示结束)
(一)单分支条件判断语句
(1)
if 条件1
then
动作1
else
动作2
fi
(2)(用;分隔)
if 条件1;then
动作1
else
动作2
fi
在vim中编辑yunjisuan.sh脚本
#!/bin/bash
read -p "请输入一个数字:" num
if [ $num == 60 ];then
echo "猜对了"
fi
# sh yunjisuan.sh
请输入一个数字:60
猜对了
在vim中编辑yunjisuan.sh脚本
#!/bin/bash
read -p "请输入一个数字:" num
if [ $num == 60 ];then
echo "猜对了"
else
echo "猜错了"
fi
# sh yunjisuan.sh
请输入一个数字:45
猜错了
(二)多分支条件判断语句(elif就是else if)
if 条件1;then
动作1
elif 条件2;then
动作2
else
动作3
fi
查看当前文件的绝对目录
# dirname 目标文件的绝对路径
查看当前文件的基本文件名称
# basename 目标文件的绝对路径
自定义搭建本地yum仓库脚本
(1)移除光盘,再挂载
(2)判断光盘挂载
(3)挂载本地yum仓库脚本
(4)判断一级目录、二级目录是否存在
(5)配置文件手动生成,避免之前被修改过(重定向或echo -e)
#!/bin/bash
umount /dev/sr0&>/dev/null
[ -d /media/cdrom ]|| mkdir -p /media/cdrom(还可以用test和if的方法)
mount /dev/sr0 /media/cdrom &>/dev/null
if [ $? -ne 0 ];then
echo "请插入光盘"
exit
fi
[ -d /etc/yum.repos.d ] || mkdir -p /etc/yum.repos.d
cd /etc/yum.repos.d
mv * /tmp/
echo -e “[local]\nname=local\nbaseurl=file:///media/cdrom/\ngpgcheck=0\nenabled=1”>/etc/
yum.repos.d/localyum.repo
(或)
cat > /etc/yum.repos.d/localyum.repo << FOF
[local]
name=local
baseurl=file:///media/cdrom
gpgcheck=0
enabled=1
F0F
yum -y clean all &>/dev/null
yum makecache &>/dev/null
[ $? -eq 0 ] && echo "yum仓库搭建完毕" || echo "缓存建立失败!"
配置文件手动生成
用脚本手动生成配置文件,一般用重定向
输入重定向通过FOF标识(任意定义,但成对出现),将FOF之间的内容输入重定向到cat,cat再输出重定向给/etc/yum.repos.d/yum/repo文件
while循环语句
格式:
while 条件
do
循环体(指令)
done
休息命令:sleep 1 休息1秒,usleep 1000000 休息1秒,单位微妙
从1到100求和
#!/bin/bash
i=1
sum=0
while [ $i -lt 100 ]
do
((sum=sum+i))
((i++))
done
echo $sum
守护进程
#!/bin/bash
while true
do
uptime >> /var/log/uptime.log
sleep 2
done
倒计时
#!/bin/bash
i=10
while [ $i -gt 0 ]
do
echo $i
((i--))
done
无限循环
(1)
#!/bin/bash
read -p "输入:" i
while [ $i -gt 0 ]
do
echo $i
let i++
done
(2)
#!/bin/bash
read -p "输入:" i
while :
do
echo $i
let i++
done
强行中止
# exit
防止脚本执行中断的方法
1)sh while01.sh & #放在后台执行
2)screen 分离 ctrl+a+d 查看screen -ls进入screen -r num
3)nohup while01.sh &
for循环语句
格式:
for 变量名 in 变量取值列表
do
循环体(指令)
done
示例:循环
for ((i=0;i<10:i++))
do
echo $i
done
打印列表元素
for的三种输出方式
(1)
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
(2)
#!/bin/bash
for i in {1..5}
do
echo $i
done
(3)
#!/bin/bash
for i in `seq 5`
do
echo $i
done
#!/bin/bash
h=0
for i in {1..10}
do
echo $h
let h++
done
开机启动项优化
#!/bin/bash
for i in `chkconfig | grep "3:on" | awk '{print $1}'`
do
chkconfig $i off
done
if [ -e sysstat ]
then echo "sysstat exit"
else mkdir -p /media/cdrom
mount /dev/sr0 /media/cdrom
if [ $? -ne 0 ];then
echo "FAILED"
exit
else yum -y install sysstat
if [ $? -ne 0 ];then
echo "install error"
exit
else echo "install successed"
fi
fi
fi
for h in sshd network crond rsyslog sysstat
do
chkconfig $h on
done
[ $? == 0 ]&& echo "successed" || echo "failed"
在/yunjisuan目录批量创建文件
#!/bin/bash
Path=/yunjisuan
[ -d "$Path" ] || mkdir -p $Path
for i in `seq 10`
do
touch $Path/yunjisuan_$i.html
done
批量改名
#!/bin/bash
Path=/yunjisuan
[ -d "$Path" ] || mkdir -p $Path
for file in `ls $Path`
do
mv $Path/$file "$Path/"`echo $file | sed -r 's#yunjisuan(.*).html#linux\1.HTML#g'`
done
批量创建用户并设置密码
#!/bin/bash
User=yunjisuan
Path=/tmp
for user in ${User}{01..10}
do
useradd $user > /dev/null 2>&1
if [ $user -ne 0 ];then
echo "$user created failed"
echo "scripts begin to rollback"
for i in ${User}{01..10}
do
userder -r $i >/dev/null 2>&1
[ $? -eq 0 ] || exit 1
done
echo >$Path/usr_passwd
exit 1
else
passWD=`echo $RANDOM | md5sum | cut -c1-8` (表示取一大串随机数,从这串随机数前截取1-8位)
[ -d $Path ] || mkdir $Path
echo $passWD | passwd --stdin $user
echo "$user:$passWD">> $Path/user_passwd
fi
done
exit 0 表示正常运行程序并退出程序
exit 1 或exit -1 表示非正常运行导致退出程序
echo -n 不换行
获取当前目录下的目录名做为变量列表打印输出
#!/bin/bash
Path=`pwd`
echo $Path
for filename in `ls`
do
[ -d ${Path}/${filename} ] && echo $filename
done
九九乘法表
#!/bin/bash
for ((i=1;i<10;i++))
do
for ((j=1;j<=i;j++))
do
echo -n "$j * $j =$((i*j))"
echo -n " "
done
echo " "
done
显示出1-100的偶数
#!/bin/bash
for i in {1..100}
do
[ $(($i%2)) -eq 0 ] && echo $i
done
显示出1000-2000的质数
#!/bin/bash
for i in {1000..2000}
do
[ $(factor $i | awk '{print NF}') -le 2 ] && echo $i
done
factor命令:分解因数
Case语句
用途:菜单;启动脚本
case语句适合变量的值少,且为固定的数字或字符串集合。 系统服务启动脚本传参的判断多用case语句
格式:
case "字符串变量" in
值1)
指令1
;;
值2)
指令2
;;
*)
指令
esac
注意:case语句相当于一个if的多分支结构语句
值1的选项
apple)
echo -e "@RED_COLOR apple $RES"
;;
也可以这样写,输入2种格式找同一个选项
apple|APPLE)
echo -e "$RED_COLOR apple $RES"
;;
服务脚本框架
#!/bin/bash
. /etc/init.d/functions
case $1 in
start)
action "服务开始启动" /bin/true
;;
stop)
action "服务准备停止" /bin/false
;;
restart)
action "服务准备停止" /bin/true
action "服务来时启动" /bin/true
;;
*)
echo "请输入正确参数"
;;
esac
在当前脚本引用函数库(绝对路径)
Function对应的是action “ ” 路径
/bin/true 表示一个标志
设置脚本配置启动级别
(1)为脚本设置启动级别
将脚本复制到/etc/init.d/下,vim编辑/etc/init.d/cash.sh脚本
# chkconfig: 35 90 10
(2)在chkconfig中添加脚本
# chkconfig --add case.sh
# chkconfig --list case.sh
(3)设置关闭cash.sh
# chkconfig case.sh off
Shell函数
不论什么编程语言,基本只有三种编程的方法(指如何去编写代码的方法论)
1、面向过程
2、面向对象
3、函数式编程
在shell语言中,只能支持面向过程这种编程方法。
在shell中,function表示函数(function、return可以不写)
格式:
function 函数名(){
命令序列
[return x]
}
函数名
函数体只有被调用时才会启动,若要重复启动该函数,只需将函数名重复n遍
获取随机数的几种方法
(1)通过系统环境变量$RANDOM
# echo $RANDOM
6178
# echo $RANDOM
30890
# echo $((RANDOM%9)) #输出0~9之间随机数
2
# echo $((RANDOM%9))
# echo $((RANDOM%9))$((RANDOM%9)) #输出00~99 随机数
64
# echo $RANDOM|md5sum #随机数长短不一,可以用md5sum命令统一格式化
599e328a94329684ce5c92b850d32f26 -
(2)通过openssl产生
# openssl rand -base64 8
aND8WMRM6vQ=
# openssl rand -base64 8
RsRdRq/9vi4=
# openssl rand -base64 8|md5sum
b1108cafbc2291392e41d2c914360138 -
# openssl rand -base64 10
1frkA2kIJODxqQ==
(3)通过时间获得随机数(date命令详解见下页文档)
# echo $(date +%N)
361599138
# echo $(date +%t%N)
950526316
(4)Urandom
# head /dev/urandom | cksum
621330951 2535
# head /dev/urandom | cksum
404398617 2470
(5)UUID
# cat /proc/sys/kernel/random/uuid
8a6c5bbe-2d42-44ac-9ef1-3e7683a613e3
# cat /proc/sys/kernel/random/uuid
c828c209-5b5f-4bc7-917c-678ed4215988
# uuidgen
961dc354-81b2-4564-9b85-6095ed4bc7b5
循环控制语句break、continue、exit、return
作用:用于循环结构中控制循环语句
break n:n表示跳出循环的层数,如果省略n表示跳出整个循环(只跳出所在位置的循环)
continue n:n表示退出到第n层继续循环,如果省略n表示跳过本次循环,忽略本次循环剩余代码,进入循环的下一次循环exit n:退出当前shell程序,n为返回值,n也可以省略,在下一个shell里通过$?接收这个n值
return n:用在函数里,做为函数的返回值,用于判断函数执行是否正确。和exit一样,如果函数里有循环,也会直接退出循环,退出函数
break n:n表示跳出循环的层数,如果省略n表示跳出整个循环
#!/bin/bash
for ((i=0;i<=5;i++))
do
[ $i -eq 3 ] && break
echo $i
done
echo "ok"
break只跳出所在位置的一个整个循环循环
continue n:n表示退出到第n层继续循环,如果省略n表示跳过本次循环,忽略本次循环剩余代码,进入循环的下一次循环
#!/bin/bash
for ((i=0;i<=5;i++))
do
[ $i -eq 3 ] && continue
echo $i
done
echo "ok"
exit n:退出当前shell程序,n为返回值,n也可以省略,在下一个shell里通过$?接收这个n值
#!/bin/bash
for ((i=0;i<=5;i++))
do
[ $i -eq 3 ] && exit 2
echo $i
done
echo "ok"
return n:用在函数里,做为函数的返回值,用于判断函数执行是否正确。和exit一样,如果函数里有循环,也会直接退出循环,退出函数
#!/bin/bash
function xxx() {
for ((i=0;i<=5;i++))
do
[ $i -eq 3 ] && return 7
echo $i
done
echo "ok"
}
xxx
echo $?
shell脚本的调试
(1)使用dos2unix处理脚本
从windows编辑的脚本到Linux下需要使用这个命令
dos2unix windows.sh
(2)使用echo命令调试
在变量读取或修改的前后假如echo $变量,也可在后面使用exit退出脚本,这样可以不用注释后边代码
(3)利用bash的参数调试
sh [-nvx]
-n:不会执行该脚本,仅查询脚本语法是否有问题,并给出错误提示。可用于生产服务器那些只能执行一次不可逆的脚本。
-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也会给出错误提示。(一般不用)
-x:将执行的脚本内容及输出显示到屏幕上,常用
1)要记得首先用dos2unix对脚本格式化
2)直接执行脚本根据报错来调试,有时报错不准确。
3)sh -x调试整个脚本,显示执行过程。
4)set -x和set +x调试部分脚本(在脚本中设置)
5)echo输出变量及相关内容,然后紧跟着exit退出,不执行后面程序的方式,一步步跟踪脚本,对于逻辑错误比较好用。
ping -c 1 ip 只ping一次
#!/bin/bash
for ip in 192.168.214.{1..254}
do
ping -c 1 $ip &> /dev/null
if [$? -eq 0 ];then
echo "$ip正常状态"
fi
done
Linux系统——shell脚本的更多相关文章
- Linux系统Shell脚本编程
1. shell脚本概念:C语言编写的.命令解释器.编程语言. 是用户使用linux的桥梁. shell脚本语言非常擅长处理文本类型的数据. 2. shell脚本作用:自动化管理.监控管理.日志数据处 ...
- Linux系统——shell脚本应用示例
传入一个网段地址,自动找出本网段内存活的IP地址.2,将存活的IP地址当作密码来创建Linux用户,用户名格式为:你的名字_数字 3,有几个存活IP地址,就自动创建几个用户 4,最后将创建的用户名 ...
- linux服务器批量部署应用系统shell脚本(Tomcat/jetty)
linux服务器批量部署应用系统shell脚本: 1.请更换代码内的服务器地址(Tomcat或jetty服务器) serverRoot=/home/undoner/java_tool/apache-t ...
- 从windows到linux的shell脚本编码和格式问题
从windows到linux的shell脚本编码和格式问题 从windows到Linux的shell脚本编码和格式问题 1.异常问题 :set ff=unix 启动脚本在启动时报错比如执行sh s ...
- Linux简单Shell脚本监控MySQL、Apache Web和磁盘空间
Linux简单Shell脚本监控MySQL.Apache Web和磁盘空间 1. 目的或任务 当MySQL数据库.Apache Web服务器停止运行时,重新启动运行,并发送邮件通知: 当服务器磁盘的空 ...
- Linux:从windows到linux的shell脚本编码和格式
从windows到linux的shell脚本编码和格式问题 异常问题 :set ff=unix 启动脚本在启动时报错比如执行sh start.sh,时会报Command not found等等的错误, ...
- 详解Linux交互式shell脚本中创建对话框实例教程_linux服务器
本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息 ...
- 使用C#给Linux写Shell脚本(下篇)
在上篇的<使用C#给Linux写Shell脚本>结尾中,我们留下了一个关于C#如何调用BashShell的问题.在文章发布之后,我留意到有读者留言推荐使用“Pash”(一款类PowerSh ...
- Linux/Unix shell 脚本中调用SQL,RMAN脚本
Linux/Unix shell脚本中调用或执行SQL,RMAN 等为自动化作业以及多次反复执行提供了极大的便利,因此通过Linux/Unix shell来完成Oracle的相关工作,也是DBA必不可 ...
随机推荐
- javascript -- 阻止默认事件 阻止事件冒泡
1. event.preventDefault(); -- 阻止元素的默认事件.注:a元素的点击跳转的默认事件 , button,radio等表单元素的默认事件 , div 元素没有默认事件 例: ...
- thinkphp中phpexcel的使用
1.下载phpexcel文件(之前提到过!) 2.下载后将文件放到: 3.在控制器中引用: 4.部分实现的代码: public function OutputExcel($data) //导入订单 { ...
- Amazon(vpc)对等网络
对等连接测试 1.1 东京账户A创建对等连接 注意,双方的vpc网段不能重复,如果重复会造成无法配置路由表 输入双方信息 账户ID和VPC 1.2 东京账户A查看 查看连接信息 显示正在处理接受,需要 ...
- cocos2dx游戏--三国关羽传【角色扮演类】Demo的制作及实现
项目地址:https://github.com/moonlightpoet/GuanYuZhuan 主要类及其对应效果: MainScene:菜单界面(用于选择不同剧本) StoryScene:故事界 ...
- Zabbix-3.0.x使用OneAlert发送告警
导读 OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.它能以史上第二快的速度,对事件进行智能的组织. ...
- WEB安全番外第四篇--关于SQL盲注
一.SQL盲注: 看不到回显的,无法从返回直接读取到数据库内容的对数据的猜解,属于盲注. 二.第一种--基于布尔类型的盲注: 这种很简单,最典型的例子,就是挖SQL注入的时候常用的: ''' http ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- Docker修改时区
简介 docker容器打日志时间滞后8小时 方法 启动时修改时区 Docker修改默认时区 已启动的容器修改时区 进入容器docker exec -i -t [CONTAINNER] /bin/bas ...
- Hadoop 启动脚本分析与实战经验
start-all.sh脚本现在已经废弃,推荐使用start-dfs.sh和start-yarn.sh分别启动HDFS和YARN. 在新一代的Hadoop里面HDFS称为了统一存储的平台,而YARN成 ...
- poj1742 Coins【多重背包】【贪心】
Coins Time Limit: 3000MS Memory Limit: 30000K Total Submissions:43969 Accepted: 14873 Descriptio ...