1. shell解释器
简单来说shell脚本就是通过vim编辑器把linux命令按照顺序依次写入文件,该文件就是shell脚本,一般为了区分脚本和其他类型的文件shell脚本会以.sh结尾,当然写shell脚本之前要了解当前系统默认的解释器,也可以在脚本中说明该脚本需要的解释器
例如:告诉计算机该脚本的解释器为bash时:
#!/bin/bash
另外:还有其他解释器
#!/bin/sh
#!/bin/ksh
2. 接收参数
shell脚本内设了用于接收参数的变量,变量之间用空格间隔
表2-1 变量及意义
| 变量 | 意义 |
|---|---|
| $0 | 当前shell脚本的的名称 |
| $# | 接收参数的数量 |
| $* | 所有接收参数的值 |
| $? | 上一个命令的执行返回值 |
| $n | n为数字,代表第n个位置的参数值 |
例如:
# 编写一个脚本,脚本名称 example.sh 脚本内容:
#!/bin/bash
echo "当前脚本的名称:$0"
echo "用户输入参数的个数:$#\n分别是:$*"
echo "第一个参数是:$1,第3个参数是:$3"
# 执行这个脚本:
sh example.sh 1 2 3 4 5 6
执行结果:
当前脚本的名称:example.sh
用户输入参数的个数:6
分别是:1 2 3 4 5 6
第一个参数是:1,第3个参数是:3
3.条件测试语句
当然shell脚本不能缺少条件判断,而条件测试语句就可以判断表达式是否成立。
条件测试语句的格式:[ 条件表达式 ]
切记条件表达式两边都有一个空格
按照测试对象可以将将其分为:
- 文件测试语句
- 逻辑测试语句(与、或、非)
- 数值比较语句
- 字符比较语句
表3-1 文件测试所用的参数
| 运算符 | 作用 |
|---|---|
| -d | 测试文件是否为目录类型 |
| -e | 测试文件是否存在 |
| -f | 判断文件是否为一般文件 |
| -r | 测试当前用户是否有权限读取 |
| -w | 测试当前用户是否有权限写入 |
| -x | 测试当前用户是否有权限执行 |
表3-2 数值比较所用的参数
| 运算符 | 作用 |
|---|---|
| -eq | 是否等于 |
| -ne | 是否不等于 |
| -gt | 是否大于 |
| -lt | 是否小于 |
| -le | 是否小于或等于 |
| -ge | 是否大于或等于 |
表3-3 字符比较所用的参数
| 运算符 | 作用 |
|---|---|
| = | 比较字符串内容是否相同 |
| != | 比较字符串内容是否不同 |
| -z | 判断字符串内容是否为空 |
| -n | 判断字符串内容是否为非空(变量要用双引号引起来) |
举例:
#判断/etc/f是否为目录
[ -d /etc/f ]
#判断/etc/f是否为一般文件
[ -f /etc/f ]
#判断/etc/f文件是否存在,若存在则输出“存在”,不存在则创建
[ -e /etc/f ] && echo "存在" || mkdir /etc/f
#判断10是否大于10
[ 10 -gt 10]
#判断系统内存可用量是否小于1024M,小于就输出“内存不足”
FREE=`free -m | grep Mem: | awk '{print $4}'`
[ $FREE -lt 1024 ] && echo "内存不足"
#判断系统语言环境变量LANG是不是空
[ -z $LANG ] && echo "系统未定义变量LANG"
#判断系统语言环境变量LANG的值是不是en.US
[ $LANG != "en.US" ] && echo "not en.US"
关于括号和引号:
1.对于变量来说:
- [ -z “$pid” ] 单对中括号变量可以加双引号
- [[ -z $pid ]] 双对括号,变量不用加双引号
- [ -n “$pid” ] 单对中括号,变量必须要加双引号
- [[ -n $pid ]] 双对中括号,变量不用加双引号
2.对于多个条件判断(与或非):
- 单中括号可以使用 -a 、-o,但是必须在 [ ] 中括号内 。例如:[ 5 -lt 3 -o 3 -gt 2 ]
- 如果想在中括号外判断两个条件,必须用&& 和 || 。例如:[5 -lt 3 ] || [ 3 -gt 2]
- || 和 && 不能在中括号内使用,只能在中括号外使用
3.当判断某个变量的值是否满足正则表达式的时候,必须使用[[ ]] 双对中括号
4.流程控制语句
① if条件判断语句
格式:
if 条件判断1
then
命令序列1
elif 条件判断2
then
命令序列2
...
else
命令序列n
fi
举例:用if写一个判断主机是否在线的shell脚本
#!/bin/bash
ping -c 3 -i 0.5 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "主机在线"
else
echo "主机不在线"
fi
② case条件判断语句
格式:
case 变量值 in
值1)
命令序列1
;;
值2)
命令序列2
;;
...
*)
命令序列n(默认命令序列)
esac
举例:判断学生成绩区间
#!/bin/bash
read -p "请输入你的成绩:" GRADE
case "$GRADE" in
[ $GRADE -ge 90 ] && [ $GRADE -le 100 ])
echo "优秀"
;;
[ $GRADE -ge 80 ] && [ $GRADE -le 90 ])
echo "良好"
;;
[ $GRADE -ge 60 ] && [ $GRADE -le 80 ])
echo "中等"
;;
*)
echo "不及格"
esac
③ for条件循环语句
格式:
for 变量名 in 取值列表
do
命令序列
done
举例:循环打印1-9
#!/bin/bash
for i in {1..9}
do
echo $i
done
#另外一种写法:
#!/bin/bash
for((i=1;i<=9;i++))
do
echo $i
done
④ while条件循环语句
格式:
while 条件测试语句(进入循环条件)
do
命令序列
done
举例:猜数字
#!/bin/bash
NUM=$(expr $RANDOM % 1000)
TIMES=0
echo "猜数字游戏,请输入1~1000之间的数字:"
while true
do
read -p "请输入:" INT
let TIMES++
if [ $INT -eq $NUM ] ; then
echo "恭喜你您在$TIMES次后猜中了"
exit 0
elif [ $INT -gt $NUM ] ; then
echo "太大了"
else
echo "太小了"
fi
done
⑤ until条件循环语句
格式:
until 条件测试语句(退出循环条件)
do
命令序列
done
举例:循环打印1到9
#!/bin/bash
declare -i i=1;
until ((i>9))
#until [ $i -gt 9 ]
do
echo $i
#let i++
#i=$((i+1))
((i++))
done
5. 终止符(EOF)
EOF是END Of File的缩写,表示自定义终止符.既然自定义,那么EOF就不是固定的,可以随意设置别名,在linux按 ctrl+d 就代表EOF。
其用法如下:
<<EOF #开始
....
EOF #结束
还可以自定义,比如自定义:
<<LBS #开始
....
LBS #结束
例如:
写一个自动创建分区和挂载的脚步
#!/bin/bash
fdisk /dev/sdb <<EOF
n
p
1
wq
EOF
read -p "输入文件系统" F
read -p "请输入挂载点:" D
mkfs.$F /dev/sdb1 && mkdir -p $D && mount /dev/sdb1 $D
echo "LABEL=data_disk $D $F defaults 0 2" >> /etc/fstab
6.shell读文件
方式一:
#!/bin/bash
f=./data.txt
while read line
do
echo $line
done < $f
方式二:
#!/bin/bash
for i in `cat data.txt`
do
$i
done
方式三:
#!/bin/bash
f=./data.txt
cat $f | while read line
do
echo $line
done
7.shell脚本操作Oracle数据库
oracle用户下将dept表数据保存到TXT文件中
#!/bin/bash
sqlplus -S scott/scott >> dept.txt <<EOF
set heading off
select deptno||','||dname||','||loc from dept
exit
EOF
oracle用户下读取文件中SQL传入Oracle并将查询结果保存到TXT文件中
#!/bin/bash
read -p "oracle username:" USER #输入Oracle用户名
read -p "password:" -s PASSWD #输入该用户密码
awk '{for (i=2 ;i<=NF;i++) printf $i " "; printf "\n" }' 1.sql >> sql.txt #如果文件里面有序号取序号之后的SQL语句放入新文件sql.txt中
f=./sql.txt #遍历该文件
cat $f |while read line
do
sqlplus -S /nolog >> $PWD/data.txt << EOF
conn $USER/$PASSWD
set heading off
set verify off
set pagesize 100
set linesize 500
$line
exit
EOF
done
oracle数据库备份脚本
#!/bin/bash
dmpdir=/home/oracle/dmp
logdir=/home/oracle/log
zipdir=/home/oracle/zip
bakdir=/home/oracle/bak
time=`date "+%Y_%m_%d_%H%_M_%S"`
#导出数据库文件
exp scott/scott file=$dmpdir/db_${time}.dmp log=$logdir/db.log owner=scott &> /dev/null
#将文件压缩
cd $dmpdir
tar -zvcf db_${time}.dmp.tar.gz db_${time}.dmp > /dev/null
mv db_${time}.dmp.tar.gz $zipdir
#将文件拷贝到备份服务器
read -p "输入备份服务器的ip地址:" IP
read -p "输入备份服务器的用户名:" NAME
read -p "密码:" -s PASSWD
scp $zipdir/db_${time}_bak.* ${NAME}/${PASSWD}@${IP}:$bakdir
写一个shell脚本传入一个部门编号,查询该部门下的员工
#!/bin/bash
let dno=$1
sqlplus -S /nolog<<EOF
conn scott/scott
set heading off
set verify off
set pagesize 100
set linesize 500
select * from emp where deptno=${dno};
exit
EOF

13万+

被折叠的 条评论
为什么被折叠?



