|
原创-n 字符数
-s 不显示
-t 超时(默认单位秒) read -t 5 a
1054 read -p "Input your name:" name
1055 echo $name
1056 read -s -p "Input your password:" pass
1057 echo $pass
1058 read -n 5 -p "Input your name:" name
1059 echo $name
1060 read -t 3 -p "Input your name:" name
1061 echo $name
1062 read -t 3 -p "Input your name:" name
1063 echo $name
10、其他变量:
一个“#”代表从左往右去掉一个指定字符
两个“#”代表从左往右最大去掉指定字符
一个“%”代表从右往左去掉一个指定字符
两个“%”代表从右往左最大去掉指定字符
取出一个目录下的目录和文件
A=/root/Desktop/shell/mem.txt
echo $A
/root/Desktop/shell/mem.txt
dirname $A 取出目录
/root/Desktop/shell
basename $A 取出文件
mem.txt
echo ${A%/} 从右往左去掉“/”内容
/root/Desktop/shell
echo ${A%%.} 从右往左最大长度去掉.后的内容
/root/Desktop/shell/mem
echo ${A%%.txt} 从右往左最大长度去掉.txt内容
/root/Desktop/shell/mem
echo ${A##//} 从左往右最大去掉所有"//"
mem.txt
echo ${A#/*/}
Desktop/shell/mem.txt
1071 aaa=/shell/shell01/dir1/file.txt
1072 echo $aaa
1073 dirname $aaa
1074 basename $aaa
1075 echo ${aaa#/*/}
1076 echo ${aaa##/*/}
1077 echo ${aaa%.*}
1078 echo ${aaa%%.*}
1079 echo ${aaa%/*/}
1080 echo ${aaa%/*}
1081 echo ${aaa%%/*}
===变量内容的替换===
[root@vm1 Desktop]# a=www.taobao.com
[root@vm1 Desktop]# echo ${a/taobao/baidu}
www.baidu.com
[root@vm1 Desktop]# a=www.taobao.com
[root@vm1 Desktop]# echo ${a/a/A}
www.tAobao.com
[root@vm1 Desktop]# echo ${a//a/A} 贪婪替换
www.tAobAo.com
===变量的替代===
echo ${var1-aaaaa}
aaaaa
var2=111
echo ${var2-bbbbb}
111
var3=
echo ${var3-ccccc}
${变量名:-新的变量值}
变量没有被赋值(包括空值):都会使用“新的变量值“ 替代
变量有被赋值: 不会被替代
简单的四则运算
算术运算:
默认情况下,shell就只能支持简单的整数运算
$(()) | $[] | expr | let
Bash shell 的算术运算有四种方式:
1、使用 $(( ))
2、使用$[ ]
3、使用 expr 外部程式
4、使用let 命令
加法:
n=10
let n=n+1
或者let n+=1
echo $n
乘法:
let m=n*10
echo $m
除法:
let r=m/10
echo $r
求余数:
let r=m%7
echo $r
乘冪:
let r=m**2
echo $r
注意:
n=1
let n+=1 等价于let n=n+1
思考:能不能用shell做小数运算?
echo 1+1.5|bc
2.5
i++ 和 ++i (了解)
对变量的值的影响:
[root@vm1 Desktop]# i=1
[root@vm1 Desktop]# let i++
[root@vm1 Desktop]# echo $i
2
[root@vm1 Desktop]# j=1
[root@vm1 Desktop]# let ++j
[root@vm1 Desktop]# echo $j
2
对表达式的值的影响:
[root@vm1 Desktop]# unset i j
[root@vm1 Desktop]# i=1
[root@vm1 Desktop]# j=1
[root@vm1 Desktop]# let x=i++ 先赋值,再运算
[root@vm1 Desktop]# echo $i
2
[root@vm1 Desktop]# echo $x
1
[root@vm1 Desktop]# let y=++j 先运算,再赋值
[root@vm1 Desktop]# echo $j
2
[root@vm1 Desktop]# echo $y
2
条件判断
语法结构:
if [ condition ];then
command
command
fi
if [ condition ];then
command1
else
command2
fi
if [ condition1 ];then
command1 结束
elif [ condition2 ];then
command2 结束
else
command3
fi
如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2;如果条件1和条件2都不满足执行命令3.
if [ condition1 ];then
command1
if [ condition2 ];then
command2
fi
else
if [ condition3 ];then
command3
elif [ condition4 ];then
command4
else
command5
fi
fi
如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5
判断语法:
1、test 条件表达式
2、[ 条件表达式 ]
3、[[ 条件表达式 ]] 匹配正则 =~
cat if3.sh
#!/bin/bash
aaa=$1
[[ $aaa = 'hello' ]] && echo world
[root@node1 shell01]# bash -x if3.sh
if3.sh: line 3: [: =: unary operator expected
[root@node1 shell01]# bash -x if3.sh hello
- aaa=hello
- '[' hello = hello ']'
- echo world
world
[root@node1 shell01]# vim if3.sh
[root@node1 shell01]# bash -x if3.sh
- aaa=
- [[ '' = \h\e\l\l\o ]]
man test去查看,很多的参数都用来进行条件判断
与文件存在与否的判断
-e 是否存在 不管是文件还是目录,只要存在,条件就成立
-f 是否为普通文件
-d 是否为目录
-S socket
-p pipe
-c character
-b block
-L 软link
文件权限相关的判断
-r 当前用户对其是否可读
-w 当前用户对其是否可写
-x 当前用户对其是否可执行
-u 是否有suid
-g 是否sgid
-k 是否有t位
-s 是否为空白文件 说明:-s表示非空,! -s 表示空文件
[ -s file1 ] file1文件内容不为空,条件成立
[ ! -s file1 ] file1文件内容为空,条件成立
两个文件的比较判断
file1 -nt file2 比较file1是否比file2新
file1 -ot file2 比较file1是否比file2旧
file1 -ef file2 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
整数之间的判断
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
字符串之间的判断
-z 是否为空字符串 字符串长度为0,就成立
-n 是否为非空字符串 只要字符串非空,就是成立
string1 = string2 是否相等
string1 != string2 不等
! 结果取反
多重条件判断
逻辑判断符号:
-a 和 && 逻辑与 [ 条件1 -a 条件2 ] 只有两个条件都成立,整个大条件才成立
[ 1 -eq 1 ] && [ 2 -ne 3 ]
[ 1 -eq 1 -a 2 -ne 3 ]
-o 和 || 逻辑或 [ 条件1 -o 条件2 ] 只要其中一个条件成立,整个大条件就成立
[ 1 -eq 1 -o 2 -ne 2 ]
[ 1 -eq 1 ] || [ 2 -ne 2 ]
! 逻辑非 优先级最低
-a 优先级 比 -o 优先级要高
cat if4.sh
#!/bin/bash
aaa=id -u
[ $aaa -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户"
[ $(id -u) -eq 0 ] && echo "当前是超级用户"
$ [ $UID -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户"
((1==2));echo $? C语言风格的数值比较
((1>=2));echo $?
demo1:
判断一个IP是否通ping通
方法1:
#!/bin/bash
read -p "请输入你要ping额IP地址:" ip
ping -c1 $ip &>/dev/null 或者 >/dev/null 2>&1
if [ $? -eq 0 ];then
echo "当前主机与所输入的IP网络ok"
else
echo "当前主机与所输入的IP网络不ok"
fi
方法2:
ping -c1 $1 &>/dev/null
test $? -ne 0 && echo "当前主机与所输入的IP网络不ok" || echo "当前主机与所输入的IP网络ok"
demo2:
判断一个进程是否存在
1、ps -ef|grep vsftpd |grep -v grep
2、pidof 程序名称
3、pgrep -l 程序名称
#!/bin/bash
ps -ef|grep vsftpd|grep -v grep &>/dev/null
if [ $? -eq 0 ];then
echo "该进程存在"
else
echo "该进程不存在"
fi
read -p "请输入你需要判断的进程名字:" name
pidof $name &>/dev/null
[ $? -eq 0 ] && echo "该进程存在" || echo "该进程不存在"
pidof $1 &>/dev/null
test $? -ne 0 && echo "该进程不存在" || echo "该进程存在"
需求:使用该脚本判断所输入的进程是否存在(多个进程名,至少2个)
#!/bin/bash
[ $# -eq 0 ] && echo "该脚本$0的用法是:$0 pidname" || pidname=($*)
for i in ${pidname[@]}
do
pidof $i &>/dev/null
test $? -ne 0 && echo "该进程不存在" || echo "该进程存在"
done
pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
选项
-o:仅显示找到的最小(起始)进程号;
-n:仅显示找到的最大(结束)进程号;
-l:显示进程名称;
-P:指定父进程号;pgrep -p 4764 查看父进程下的子进程id
-g:指定进程组;
-t:指定开启进程的终端;
-u:指定进程的有效用户ID。
demo3:
判断一个服务是否正常(以httpd为例):
1、可以判断进程是否存在,用/etc/init.d/httpd status判断状态等方法
2、最好的方法是直接去访问一下,通过访问成功和失败的返回值来判断
#!/bin/bash
wget -P /tmp http://localhost &>/dev/null
[ $? -eq 0 ] && echo "该服务正常" || echo "该服务不正常"
课堂练习:
1、写一个脚本判断一个用户是否存在
2、完善上一个脚本的bug,要求当没有给脚本传参数或者参数个数不等于1个时,提示脚本的用法:usage:xxx.sh ip
#!/bin/bash
[ $# -ne 1 ] && echo "usage:basename $0 username" && exit
id $1 &>/dev/null
test $? -eq 0 && echo "该用户$1存在" || echo "该用户$1不存在"
#!/bin/bash
[ $# -ne 1 ] && echo "usage:basename $0 ipaddr" && exit
wget http://$1 &>/dev/null
[ $? -eq 0 ] && echo 'httpd服务正常' || echo "httpd服务不正常"
3、判断vsftpd软件包是否安装,如果没有则自动安装
4、判断vsftpd服务是否启动,如果启动,输出以下信息:
vsftpd服务器已启动...
vsftpd监听的地址是:
vsftpd监听的端口是:
#!/bin/bash
ftp=vsftpd
rpm -q $ftp &>/dev/null
[ $? -ne 0 ] && yum -y install $ftp &>/dev/null
pgrep -l $ftp &>/dev/null
[ $? -ne 0 ] && service $ftp start &>/dev/null && echo "服务已经启动..."
ip=netstat -nltp|grep $ftp|cut -d: -f1|cut -c21-
port=netstat -nltp|grep $ftp|cut -d: -f2|cut -d' ' -f1
echo "vsftpd监听的地址是:$ip"
echo "vsftpd监听的端口是:$port"
作业:
1、 判断/tmp/run文件是否存在,如果不存在就建立,如果存在就删除目录里所有文件
#!/bin/bash
dir=/tmp/run
[ -d $dir ] && rm -rf $dir/* || mkdir $dir
dir=/tmp/run
[ -f $dir ] && mv $dir $dir.bak
[ -d $dir ] && rm -rf $dir/* || mkdir $dir
2、 输入一个路径,判断路径是否存在,而且输出是文件还是目录,如果是字符连接,还得输出是有效的连接还是无效的连接
#!/bin/bash
read -p "请输入绝对路径:" path
if [ -e "$path" -a -L "$path" ];then
echo "该文件是一个有效连接文件"
elif [ ! -e "$path" -a -L "$path" ];then
echo "该文件是一个无效连接文件"
elif [ -d $path ];then
echo "该文件是一个目录"
elif [ -f $path ];then
echo "该文件是一个普通文件"
elif [ -e $path ];then
echo "其他文件"
else
echo "路径不存在"
fi
3、交互模式要求输入一个ip,然后脚本判断这个IP 对应的主机是否 能ping 通,输出结果类似于:
Server 10.1.1.20 is Down! 最后要求把结果邮件到本地管理员root@localhost和mail01@localhost
4、写一个脚本/home/program,要求当给脚本输入参数hello时,脚本返回world,给脚本输入参数world时,脚本返回hello。而脚本没有参数或者参数错误时,屏幕上输出“usage:/home/program hello or world”
#!/bin/bash
if [ "$1" = "hello" ];then
echo world
elif [ "$1" = "world" ];then
echo hello
elif [ $# -ne 1 ];then
echo "usage:$0 hello or world"
else
echo "usage:$0 hello or world"
fi
5、写一个脚本自动搭建nfs服务
#!/bin/bash
#1.安装软件
#2.确认软件是否安装
#3.配置
#(1).新建共享目录,授本地权限
#(2).发布共享目录/etc/exports
#4.启动服务
#5.设置下次开机自动启动
#配置网络,测试网络
ping -c 1 192.168.0.254 &> /dev/null && echo "##############网络OK###############"
#配置network yum
rm -fr /etc/yum.repos.d/*
cat > /etc/yum.repos.d/dvd.repo /dev/null && echo "##############软件安装OK###############"
#2.xx
#3.配置
#(1).新建共享目录,授本地权限
#read -p "请输入你的共享目录" dir
mkdir -p $1
chmod 777 $1 && echo "##############本地授权OK###############"
|
|
|