注意 : 在VIM中使用set paste格式化vim,再粘贴内容,格式就不会乱html
关系运算符mysql
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,若是是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,若是是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,若是是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,若是是,则返回 true。 | [ $a -le $b ] 返回 true。 |
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,不然返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
-lt #表示小于linux
-gt #表示大于nginx
-eq #表示等于git
-qw #表示是否github
-ne #表示非、不等于正则表达式
-ge #表示 大于等于sql
-b #表示判断是否是shell
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n "$a" ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
正则表达式元字符vim
特殊的元字符
扩展的正则表达式
Linux 教程
Linux 教程Linux 简介Linux 安装Linux 系统启动过程Linux 系统目录结构Linux 忘记密码解决方法Linux 远程登陆Linux 文件基本属性Linux 文件与目录管理Linux 用户和用户组管理Linux 磁盘管理Linux vi/vimlinux yum 命令
Shell 教程Shell 变量Shell 传递参数Shell 数组Shell 运算符Shell echo命令Shell printf命令Shell test 命令Shell 流程控制Shell 函数Shell 输入/输出重定向Shell 文件包含
Linux 命令大全Nginx 安装配置MySQL 安装配置
上一章节咱们学习了 Shell 的 echo 命令,本章节咱们来学习 Shell 的另外一个输出命令 printf。
printf 命令模仿 C 程序库(library)里的 printf() 程序。
printf 由 POSIX 标准所定义,所以使用 printf 的脚本比使用 echo 移植性好。
printf 使用引用文本或空格分隔的参数,外面能够在 printf 中使用格式化字符串,还能够制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,咱们能够手动添加 \n。
printf 命令的语法:
printf format-string [arguments...]
参数说明:
实例以下:
$ echo "Hello, Shell" Hello, Shell $ printf "Hello, Shell\n" Hello, Shell $
接下来,我来用一个脚原本体现printf的强大功能:
#!/bin/bash # author:菜鸟教程 # url:www.runoob.com printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
执行脚本,输出结果以下所示:
姓名 性别 体重kg 郭靖 男 66.12 杨过 男 48.65 郭芙 女 47.99
%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,若是不足则自动以空格填充,超过也会将内容所有显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。
更多实例:
#!/bin/bash # author:菜鸟教程 # url:www.runoob.com # format-string为双引号 printf "%d %s\n" 1 "abc" # 单引号与双引号效果同样 printf '%d %s\n' 1 "abc" # 没有引号也能够输出 printf %s abcdef # 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用 printf %s abc def printf "%s\n" abc def printf "%s %s %s\n" a b c d e f g h i j # 若是没有 arguments,那么 %s 用NULL代替,%d 用 0 代替 printf "%s and %d \n"
执行脚本,输出结果以下所示:
1 abc 1 abc abcdefabcdefabc def a b c d e f g h i j and 0
序列 | 说明 |
---|---|
\a | 警告字符,一般为ASCII的BEL字符 |
\b | 后退 |
\c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),并且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f | 换页(formfeed) |
\n | 换行 |
\r | 回车(Carriage return) |
\t | 水平制表符 |
\v | 垂直制表符 |
\\ | 一个字面上的反斜杠字符 |
\ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
\0ddd | 表示1到3位的八进制值字符 |
3一、题目要求 :获取网卡ip、 获取网卡ip显示颜色
提示用户输入网卡的 名字,而后咱们用脚本输出网卡的ip,须要考虑下面问题:
#!/bin/bash ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/eth.list while : do eths=`cat /tmp/eth.list |xargs` read -p "Please input a if name(The eths is `echo -e "\033[31m$eths\033[0m"`): " eth if [ -z "$eth" ] then echo "Please input a if name." continue fi if ! grep -qw "$eth" /tmp/eth.list then echo "The if name is error." continue else break fi done if_ip() { ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt n=`wc -l /tmp/$1.txt|awk '{print $1}'` if [ $n -eq 0 ] then echo "There is no ip address on the eth." else echo "The ip addreess is:" for ip in `cat /tmp/$1.txt` do echo -e "\033[33m$ip\033[0m" done fi } if_ip $eth
实例 :
[root@localhost ~]# # ip add # 查看机器上全部的网卡
[root@localhost ~]# # ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' #查看全部的网卡列表
[root@localhost ~]# # ip add show dev ens33 | grep ' inet ' |awk '{print $2}' #获取ens33网卡的IP,并精准截取IP所在的第二行。/24表示是IP地址的netmask网段
输入网卡的名字 ,运行脚本,查看结果,
若是输入了。错的网卡名字,会提示网卡名字错误。输入正确的网卡名字,就直接显示IP地址,而后退出。
未添加颜色,执行脚本以后,显示的结果。
注意 :
cat /tmp/eth.list |xargs #在脚本中表示列出全部的网卡的名字
[root@localhost ~]# echo "Please input a if name(The eths is 'cat /tmp/eth.list|xargs')" #查看网卡列表中的eth网卡
if [ -z "$eth" ] #表达的含义,是若是eth是空的,就提示用户 : Please input a if name.
if ! grep -qw "$eth" /tmp/eth.list #表达的含义,是若是eth是不在/tmp/eth.list 文件中,就提示用户 : The if name is error.
if_ip #函数的名字
ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt #显示IP网卡的IP地址,并把输出的结果存入/tmp/$1.txt临时文件中 ,$1表示第一个参数。
wc -l /tmp/$1.txt|awk '{print $1} #先统计/tmp/$1.txt临时文件中的行数。
if [ $n -eq 0 ] #若是eq等于0,那么提示用户 “There is no ip address on the eth.”
31.2 获取网卡ip显示颜色
案例
echo显示带颜色,须要使用参数-e
格式以下 :
echo -e "\033"[字背景颜色;文字颜色m字符串\033[0m
例如 :
echo -e"\033[41;37m TonyZhang \033[0m"
其中41的位置表明底色,37的位置是表明字的颜色
注 :
一、字背景颜色和文字颜色之间是英文的”""”
二、文字颜色后面有个m
三、字符串先后能够没有空格,若是有的话,输出也是一样有空格
例子 :
echo -e "/033[30m 黑色字 \033[0m"
echo -e "/033[31m 红色字 \033[0m"
echo -e "/033[30m 绿色字 \033[0m"
echo -e "/033[30m 黄色字 \033[0m"
echo -e "/033[30m 蓝色字 \033[0m"
echo -e "/033[30m 紫色字 \033[0m"
echo -e "/033[30m 蓝色字 \033[0m"
echo -e "/033[30m 白色字 \033[0m"
echo -e "/033[30m 黑底白色字 \033[0m"
echo -e "/033[30m红底 白字 \033[0m"
echo -e "/033[30m 绿底白字 \033[0m"
echo -e "/033[30m 黄底白字 \033[0m"
echo -e "/033[30m 蓝底白字 \033[0m"
为网卡的名称显示颜色。
#!/bin/bash ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/eth.list while : do eths=`cat /tmp/eth.list |xargs` read -p "Please input a if name(The eths is '/tmp/eth.list|xargs'): " eth if [ -z "$eth" ] then echo "Please input a if name." continue fi if ! grep -qw "$eth" /tmp/eth.list then echo "The if name is error." continue else break fi done if_ip() { ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt n=`wc -l /tmp/$1.txt|awk '{print $1}'` if [ $n -eq 0 ] then echo "There is no ip address on the eth." else echo "The ip addreess is:" `cat /tmp/$1.txt fi } if_ip $eth
添加颜色,执行脚本以后,显示的结果。
3二、题目要求 : 列出目录内容
写一个脚本,实现以下功能:
【核心要点】
$#参数个数
test -d filename #
find $d -type d #把当前文件下的文件所有列出来
#!/bin/bash if [ $# -eq 0 ] then echo "当前目录下的文件是:" ls . else for d in $@ do if [ -d $d ] then echo "目录$d下有这些子目录:" find $d -type d else echo "并无该目录:$d" fi done fi
实例 :
查看当前目录下的文件
显示tmp和/usr/local目录下的文件
3三、题目要求 : 下载文件
定义一个shell函数,能接受两个参数,知足如下要求:
#!/bin/bash if [ $# -ne 2 ] then echo "你必需要输入两个参数,第一个参数是网址,第二个参数是目录." exit 1 fi if [ ! -d $2 ] then while : do echo "你输入的第二个参数,并非一个存在的目录。是否要建立该目录呢?(y|n): "c case $c in y|Y) mkdir -p $2 ;; n|N) exit 51 ;; *) echo "请输入y或者n." continue ;; esac done else cd $2 wget $1 if [ $? -eq 0 ] then exit 0 else echo "下载失败." exit 52 fi fi
实例 :
运行脚本,获得结果是1,说明脚本没问题。返回52给调用脚本,给的目录不存在,则下载文件失败,
脚本解析失败,缘由后面没有两个参数,
输入两个参数,第一个参数是网址,第二个参数是目录时,就解析成功了。
查看下载的文件
注意 :
if [ $# -ne 2 ] #若是参数不等于2,提示 : 你必需要输入两个参数,第一个参数是网址,第二个参数是目录.
if [ ! -d $2 ] #若是$2是一个不存在的目录,提示 :你输入的第二个参数,并非一个存在的目录。是否要建立该目录呢?(y|n):
mkdir -p $2 #若是客户输入了y或者Y,建立这个目录。若是输入N|n,直接退出。
cd $2
wget $1 #表示若是没有,就cd切换到$2,而后wegt下载
if [ $? -eq 0 ] #若是$?等于0,表示下载成功就退出,不然就是下载失败。
报错缘由 : 未安装命令。解决办法 : yum install -y wget
3四、题目要求 : 猜数字
写一个shell脚本,能实现以下需求:
#!/bin/bash n=$[$RANDOM%101] while : do read -p "请输入一个0-100的数字:" n1 if [ -z "$n1" ] then echo "必需要输入一个数字。" continue fi n2=`echo $n1 |sed 's/[0-9]//g'` if [ -n "$n2" ] then echo "你输入的数字并非正整数." continue else if [ $n -gt $n1 ] then echo "你输入的数字小了,请重试。" continue elif [ $n -lt $n1 ] then echo "你输入的数字大了,请重试。" continue else echo "恭喜你,猜对了!" break fi fi done
实例 :
获取一个随机的数字
获取一个100之内的随机数字
运行0-99的脚本,输入一个正确的随机数字,就结束了。
35.一、题目要求 : 根据名字得数字
写一个shell脚本,能实现以下需求:
#!/bin/bash f=/tmp/user_number.txt while : do read -p "Please input a username: " u u1='echo $u|sed 's/[a-zA-Z0-9]//g'' if [ -n "$u1" ] then echo "你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合" continue else if [ -f $f ] then u_n=`awk -v uu=$u '$1==uu {print $2}' $f` if [ -n "$u_n" ] then echo "用户$u对应的数字是:$u_n" else n=$[$RAMDOM%100] echo "用户$u对应的数字是 : $n" echo $u $n >> $f fi else n=$[$RAMDOM%100] echo "用户$u对应的数字是:$n" echo $u $n >> $f fi fi done
实例 :
查看运行的结果,/tmp/user_number.txt文件没有建立。
当第二次执行脚本时,/tmp/user_number.txt就建立了。输入q或者大写的 Q,退出 运行的脚本。不建议使用ctrl +c.
注意 :
u_n #u_n的值为1
if [ -n "$u_n" ] #若是u_n不为空,那么$u对应的变量就是$u_n ;不然,从新创造一个随机数。
`echo $u|sed 's/[a-zA-Z0-9]//g'` #若是输入u的值,是空的,说明用户输入的名字是对的
-n "$u1" #若是输入的不为空,。提示 “你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合”
"$u $n" >>$f #将用户名和对应的数字,记录到/tmp/user_number.txt文件中
awk '{print $2}' $f|grep -qw $n #查找/tmp/user_number.txt文件中第二段截取出来,
u_n=`awk -v uu=$u '$1==uu {print $2}' $f` #求用户名中的行数,并截取/tmp/user_number.txt文件中第二段
35.2 根据名字得数字优化
#!/bin/bash f=/tmp/user_number.txt j_n() { while : do n=$[RANDOM%100] if awk '{print $2}' $f|grep -qw $n then continue else break fi done } while : do read -p "Please input a username: " u if [ -z "$u" ] then echo "请输入用户名." continue fi if [ $u == "q" ] || [ $u == "Q" ] then exit fi u1=`echo $u|sed 's/[a-zA-Z0-9]//g'` if [ -n "$u1" ] then echo "你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合" continue else if [ -f $f ] then u_n=`awk -v uu=$u '$1==uu {print $2}' $f` if [ -n "$u_n" ] then echo "用户$u对应的数字是:$u_n" else j_n echo "用户$u对应的数字是:$n" echo "$u $n" >>$f fi else j_n echo "用户$u对应的数字是:$n" echo $u $n >> $f fi fi done
注意 :
if awk '{print $2}' $f|grep -qw $n #表示查看/tmp/user_number.txt文件第二端,是否已经出现了$n随机数?
3六、题目要求 : 一个数字的行
系统logrotate工具,能够完成日志切割、归档。写一个shell脚本实现相似的归档功能。 举例: 假如服务的输出日志是1.log,要求天天归档一个,1.log次日就变成1.log.1,第三天1.log.2, 第四天 1.log.3 一直到1.log.5。
#!/bin/bash cd /data/logs log=1.log mv_log() { [ -f $1 ] && mv $1 $2 } [ -f 1.log.5 ] && rm -f 1.log.5 for i in `seq 4 -1 1` do j=$[$i+1] mv_log $log.$i $log.$j done mv 1.log 1.log.1
实例 :
统计行中出现的数字
注意 :
echo $line |sed 's/[^0-9]//g' |wc -L #统计全部的行,将全部的非数字所有删除,只剩下数字,并计算数字的个数。
3七、题目要求 : 日志切割归档
系统logrotate工具,能够完成日志切割、归档。写一个shell脚本实现相似的归档功能。 举例: 假如服务的输出日志是1.log,要求天天归档一个,1.log次日就变成1.log.1,第三天1.log.2, 第四天 1.log.3 一直到1.log.5。
#!/bin/bash cd /data/logs log=1.log mv_log() { [ -f $1 ] && mv $1 $2 } [ -f 1.log.5 ] && rm -f 1.log.5 for i in `seq 4 -1 1` do j=$[$i+1] mv_log $log.$i $log.$j done mv 1.log 1.log.1
实例 :
建立/data/logs目录 , 而后在1.log里面写入111
往2.log日志里面写入222,按照顺序,依次在日志里面写入对应的数字,如:3.log里面写333.
查看脚本是否有问题,在1.log日志文件中写入000.而后执行 “cat *”命令,查看运行结果。应该系统日志只有两个,因此显示的结果到222,就结束了。
注意 :
log=1.log #log是定义的变量
mv_log() #定义的函数
[ -f $1 ] && mv $1 $2 #若是$1存在,就把$1改为$2
[ -f 1.log.5 ] && rm -f 1.log.5 #若是1.log.5存在,就删除1.log.5
写一个shell脚本,把192.168.0.0/24网段在线的ip列出来。
#!/bin/bash for i in `seq 1 254` do if ping -c 2 -W 2 192.168.0.$i >/dev/null 2>/dev/null then echo "192.168.0.$i 是通的." else echo "192.168.0.$i 不通." fi done
实例 :
有两个IP地址,测试一个通的,返回ok,一个不通的,什么都不返回。
执行脚本,查看脚本运行的结果。由于这个网段,不通,因此所有都不通
注意 :
for i in `seq 1 254` #ping的IP地址范围1-254
if ping -c 2 -W 2 192.168.0.$i >/dev/null 2>/dev/null #把能ping通的IP地址写入到/dev/nul,错误的也写入/dev/null 。-c 2表示ping两次,-W 2 表示ping的时间为两秒
写一个shell脚本,检查指定的shell脚本是否有语法错误,如有错误,首先显示错误信息,而后提示用户输入q或者Q退出脚本,输入其余内容则直接用vim打开该shell脚本。
#!/bin/bash sh -n $1 2>/tmp/sh.err if [ $? -ne 0 ] then cat /tmp/sh.err read -p "请输入q/Q退出脚本。" c if [ -z "$c"] then vim $1 exit 0 fi if [ $c == q ] || [ $c == Q ] then exit 0 else vim $1 exit 0 fi else echo "脚本$1没有语法错误." fi
实例 :
脚本运行结果。
注意 :
sh -n $1 2>/tmp/sh.err #将错误的输出到/tmp/sh.err
if [ $? -ne 0 ] #$?不等于0,说明有语法错误。
40、题目要求 : 格式化数字
输入一串随机数字,而后按千分位输出。 好比输入数字串为“123456789”,输出为123,456,789。
#!/bin/bash n=`echo $1|wc -L` for d in `echo $1|sed 's/./& /g'` do n2=$[$n%3] if [ $n2 -eq 0 ] then echo -n ",$d" else echo -n "$d" fi n=$[$n-1] done |sed 's/^,//' echo
实例 :
sed实现数字之间的自动空一格
脚本正确执行的结果
注意 :
n=`echo $1|wc -L` #n表示计算数字的长度,$1是数字串。
for d in `echo $1|sed 's/./& /g'` #sed实现数字的自动空一格,&表明前面的点。
n2=$[$n%3] #$[$n%3] 表示$n除以3,而后添加逗号间隔。
if [ $n2 -eq 0 ] #0表示$n2可以被3整除
echo -n ",$d" #能被3整除的,添加逗号间隔。
echo -n "$d" #不能被3整除的,不添加逗号间隔。
来源 :https://github.com/aminglinux/shell100/blob/master/13.md