赞
踩
实例
注:$ var1+$ var2并不能实现相加,$ var1,$ var2默认作为字符串来处理
当一条命令或脚本执行时,后面可以跟多个参数,我们使用位置参数变量来表示这些参数。
位置参数变量 | 描述 |
---|---|
$n | n 为数字,$ 0 代表Shell本身的文件名,$ 1〜$ 9 代表第 1 ~ 9 个参数,10 以上的参数需要用大括号包含, 如 $ {10} |
$* | 命令行所有参数,把所有的参数看成一个整体 |
$@ | 命令行中所有参数,但每个参数区别对待 |
$# | 命令行中所有参数的个数 |
实例
$ @和$ *都表示命令行所有参数,但是$ *将命令行的所有参数看成一个整体,而$ @则区分各个参数
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或多个应用程序将使用到的信息。Linux是一个多用户的操作系统,每个用户登录系统时都会有一个专用的运行环境,通常情况下每个用户的默认的环境都是相同的。这个默认环境就是一组环境变量的定义。每个用户都可以通过修改环境变量的方式对自己的运行环境进行配置。
分类
对所有用户生效的环境变量 /etc/profile
对特定用户生效的环境变量 ~ /.bashrc或者~/.bash_profile
临时有效的环境变量 export
常用环境变量
环境变量 | 含义 |
---|---|
PATH | 命令搜索的路径 |
HOME | 用户家目录的路径 |
LOGNAME | 用户登录名 |
PWD | 当前所在路径 |
HISTFILE | 历史命令的保存文件 |
HISTSIZE | 历史命令保存的最大行数 |
HOSTNAME | 主机名 |
SHELL | 用户当前使用的SHELL |
PS1 | 一级命令提示符 |
TMOUT | 用户和系统交互过程的超时值 |
IFS | 系统输入分隔符 |
OFS | 系统输出分隔符 |
实例
将一个命令的输出作为另一个命令的输入
实例
rpm -qa
rpm命令是RPM软件包的管理工具
rpm -qa | grep python
Linux grep 命令用于查找文件里符合条件的字符串。
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :打印匹配次数
-f 两个文件相同行 如,grep -f file1 file2
-h 不显示匹配行所在文件名
-i :忽略大小写的不同,所以大小写视为相同
-l 只显示匹配到的文件名
-n :顺便输出行号
-o 只显示匹配的字符
-v :只显示不匹配的行。
--color=auto :可以将找到的关键词部分加上颜色的显示喔!
rpm -qa | grep python | wc -l
Linux wc命令用于计算字数
-c或--bytes或--chars 只显示Bytes数。
-l或--lines 只显示行数。
-w或--words 只显示字数。
--help 在线帮助。
--version 显示版本信息。
所有的shell命令都使用退出状态吗来告知shell它已执行完毕
退出状态码是一个0~255的整数值
Linux提供了一个$?来捕获退出状态码的值,所以,可以通过echo语句测试命令是否运行成功。
一般来讲,退出状态 0 表示正常执行,没有遭遇任何问题。其他非零的状态码均表示失败。
状态码 | 描述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shell 命令 |
126 | 找到了该命令但无法执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与linux信号x相关的严重错误 |
130 | 通过ctrl+C终止的命令 |
255 | 正常范围之外的退出状态码 |
实例
退出状态码是以上一条指令的返回结果为准
使用exit命令改变退出状态码
exit $exit_code
exit 48 或者 exit 125 或者exit 0
语法:
if command | condition
then
commands
fi
实例
#!/bin/bash
if pwd
then
echo "It works"
fi
语法:
if command | condition
then
commands
else
commands
fi
实例
#!/bin/bash
if pwd
then
echo "It works"
fi
语法:
if command | condition
then
commands
elif command | condition
then
commands
else
commands
fi
语法:
if condition
then
commands
fi
或者
if condition;then
commands
fi
数值比较
数值比较 | 含义 |
---|---|
n1 -eq n2 | n1和n2相等,则返回true;否则返回false |
n1 -ne n2 | n1和n2不相等,则返回true;否则返回false |
n1 -gt n2 | n1大于n2,则返回true;否则返回false |
n1 -ge n2 | n1大于等于n2,则返回true;否则返回false |
n1 -lt n2 | n1小于n2,则返回true;否则返回false |
n1 -le n2 | n1小于等于n2,则返回true;否则返回false |
实例
#!/bin/bash
if [ $1 -eq $2 ];then
echo "$1 = $2"
elif [ $1 -gt $2 ];then
echo "$1 > $2"
elif [ $1 -lt $2 ];then
echo "$1 < $2"
fi
字符串比较
字符串比较 | 含义 |
---|---|
str1 = str2 | 相等比较 |
str1 != str2 | 不相等比较 |
str1 < str2 | str1小于str2为true |
str1 > str2 | str1大于str2为true |
-n str1 | str1长度不是0则为true |
-z str1 | str1长度是0则为true |
实例
#!/bin/bash
var1='hello'
var2='world'
if [ $var1 = $var2 ];then
echo "equal"
else
echo "not equal"
fi
#!/bin/bash
var1='hello'
var2='world'
if [ $var1 < $var2 ];then
echo "<"
else
echo ">"
fi
<被当作了重定向,需要进行转义
#!/bin/bash
var1='hello'var2='world'
if [ $var1 \< $var2 ];then
echo "<"
else
echo ">"
fi
#!/bin/bash
var1=''
var2='world'
if [ -n "$var1" ];then
echo "var1 is not null"
else
echo "var1 is null"
fi
文件比较
文件比较 | 含义 |
---|---|
-d file | file是否为目录 |
-f file | file是否为文件 |
-e file | file是否存在 |
-r file | file是否可读 |
-w file | file是否可写 |
-x file | file是否可执行 |
-s file | file存在且非空 |
file1 -nt file2 | file1比file2新为true |
file1 -ot file2 | file1比file2旧为true |
实例
#!/bin/bash
if [ -d /usr/local ];then
echo "yes"
else
echo "no"
fi
#!/bin/bash
if [ /usr/local/test1 -nt /usr/local/test2 ];then
echo "new"
else
echo "old"
fi
语法:
语法1 “与”
if condition1 && condition2
then
commands
fi
语法2 “或”
if condition1 || condition2
then
commands
fi
实例
#!/bin/bash
var1=56
var2=34
var3=89
if [ $var1 -gt $var2 ] && [ $var2 -lt $var3 ];then
echo " $var1 > $var2 并且 $var2 < $var3"
fi
使用双括号进行算术运算
语法:
if ((expression))
then
commands
fi
注:
双括号结构中,变量名引用可以加$,也可以不加
运算符前后可以有空格,也可以没有
可以用于if,for,while等循环控制结构中
多个运算符使用逗号分隔
可用运算符
运算符 | 含义 |
---|---|
value++ | 后增 |
value– | 后减 |
++value | 先增 |
–value | 先减 |
! | 逻辑求反 |
== | 相等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
&& | 逻辑与 |
实例
#!/bin/bash
a=10
((a+=10))
echo $a
单方括号语法
if [ $n1 -gt $n2 ] && [ $n2 -lt $n3 ]
then
commands
fi
改为双方括号语法
if [ [$n1 -gt $n2 && $n2 -lt $n3 ]]
then
commands
fi
注:
双括号结构中,变量名引用必须加$
[[后面必须要空格,]]前面必须有空格
语法:
case $var in
pattern1)
commands
;;
pattern2)
commands;
;;
esac
实例:
#!/bin/bash
case $1 in
jack)
echo "hello,jack"
;;
mike)
echo "hello,mike"
;;
*)
echo "hello everyone"
;;
esac
循环遍历一系列特定值,然后在结构体中针对每个特定值做处理
语法:
for var in list
do
commands
done
实例:
for循环读取列表值:
#!/bin/bash
for i in Beijing Shanghai Nanjing Guangzhou Zhengzhou
do
echo "Province is $i"
done
for i in {1..20}
do
echo "Number is $i"
done
for循环读取变量值:
#!/bin/bash
list="Zhangsan Lisi Mike Tom"
for i in $list
do
echo "Name is $i"
done
#!/bin/bash
IFS=$":" #分隔符,默认为空格或tab
list="Zhangsan:Lisi:Mike:Tom"
for i in $list
do
echo "Name is $i"
done
for循环从命令执行结果读取值
#!/bin/bash
FILE=$(ls /opt/)
for i in $FILE
do
echo "file is $i"
done
#!/bin/bash
for i in $(ls /opt/)
do
if [ -d /opt/$i ]
then
echo "$i is DIR"
elif [ -f /opt/$i ]
then
echo "$i is FILE"
fi
done
C语言风格的for循环
#!/bin/bash
for ((i=10;i<20;i++))
do
echo "Next Number is $i"
done
#!/bin/bash
sum=0
for (( i=1;i<101;i++))
do
(( sum+=$i ))
done
echo "sum is $sum"
语法:
while command
do
commands
done
实例:
#!/bin/bash
num=10
while [ $num -lt 20 ]
do
echo "number is $num"
((num++))
done
语法:
until command
do
commands
done
实例:
#!/bin/bash
num=10
until [ $num -eq 0 ]
do
echo "number is $num"
((num--))
done
实例:
#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
if ((i==5))
then
break
else
echo "number is $i"
fi
done
当有两层循环的时候,"break 1"跳出内循环; " break 2"跳出外循环
#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
for((j=1;j<=5;j++))
do
if ((j==3))
then
break 1
else
echo "$i $j"
fi
done
done
#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
for((j=1;j<=5;j++))
do
if ((j==3))
then
break 2
else
echo "$i $j"
fi
done
done
实例:
#!/bin/bash
num=10
for ((i=1;i<=30;i++))
do
if ((i>15 && i<25))
then
continue
else
echo "Number is $i"
fi
done
实例
#!/bin/bash
num=10
for ((i=1;i<=100;i++))
do
echo "Number is $i"
done > result.txt
#!/bin/bash
num=10
for ((i=1;i<=100;i++))
do
echo "Number is $i"
done | grep "5"
变量替换
语法 | 含义 |
---|---|
${变量名#匹配规则} | 从变量开头进行规则匹配,将符合最短的数据删除 |
${变量名##匹配规则} | 从变量开头进行规则匹配,将符合最长的数据删除 |
${变量名%匹配规则} | 从变量尾部进行规则匹配,将符合最短的数据删除 |
${变量名%%匹配规则} | 从变量尾部进行规则匹配,将符合最长的数据删除 |
${变量名/旧字符串/新字符串} | 变量内容符合旧字符串规则,则第一个旧字符串会被新字符串取代 |
${变量名//旧字符串/新字符串} | 变量内容符合旧字符串规则,则全部的旧字符串会被新字符串取代 |
实例
变量测试
实例
计算字符串长度
方法一:
${#string}
方法二:
expr length "$string" #string如果有空格,则必须加双引号
获取子串在字符串中的索引位置
语法
expr index $string $substring
$substring会被切割成字符,比如orl被切割成o,r,l,分别查找字符,哪个字符最先找到就会返回那个字符的位置,l最靠前,位置为3,返回3
计算子串长度
expr match $string substr
$string会从头开始匹配子串,不能从中间匹配
抽取子串
方法一:
${string:position} #从string中的position开始
方法二:
${string:position:length} #从position开始,匹配长度为length
方法三:
${string:-(position)} #从右边开始匹配
方法四:
${string:(position)} #从左边开始匹配
方法五:
expr substr $string $position $length #从position开始,匹配长度为length
练习
需求描述:
变量string=“Bigdata process framework is Hadoop,Hadoop is an open source project” 执行脚本后,打印输出string字符串变量,并给出用户以下选项:
用户输入数字1|2|3|4,可以执行对应项的功能;输入qlQ则退出交互模式
脚本:
read命令用于从标准输入中读取输入单行
-a:将分裂后的字段依次存储到指定的数组中,存储的起始位置从数组的index=0开始。
-d:指定读取行的结束符号。默认结束符号为换行符。
-n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
-N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
-p:给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"
-r:禁止反斜线的转义功能。这意味着"\"会变成文本的一部分。
-s:静默模式。输入的内容不会回显在屏幕上。
-t:给出超时时间,在达到超时时间时,read退出并返回错误。也就是说不会读取任何内容,即使已经输入了一部分。
-u:从给定文件描述符(fd=N)中读取数据。
#!/usr/bin/env bash string="Bigdata process framework is Hadoop,Hadoop is an open source project" function tips_info { echo "******************************************" echo "*** (1) 打印string长度" echo "*** (2) 在整个字符串中删除Hadoop" echo "*** (3) 替换第一个Hadoop为Mapreduce" echo "*** (4) 替换全部Hadoop为Mapreduce" echo "******************************************" } function print_len { if [ -z "$string" ];then echo "Error,string is null" exit 1 else echo "${#string}" fi } function del_hadoop { if [ -z "$string" ];then echo "Error,string is null" exit 1 else echo "${string//Hadoop/}" fi } function rep_hadoop_mapreduce_first { if [ -z "$string" ];then echo "Error,string is null" exit 1 else echo "${string/Hadoop/Mapreduce}" fi } function rep_hadoop_mapreduce_all { if [ -z "$string" ];then echo "Error,string is null" exit 1 else echo "${string//Hadoop/Mapreduce}" fi } while true do echo "【string=\"$string\"】" tips_info read -p "Pls input your choice(1|2|3|4|q|Q):" choice case "$choice" in 1) echo echo "Length Of String is: `print_len`" echo continue ;; 2) echo echo "删除Hadoop后的字符串为:`del_hadoop`" echo ;; 3) echo echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_first`" echo ;; 4) echo echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_all`" echo ;; q|Q) exit 0 ;; *) echo "error,unlegal input,legal input only in { 1|2|3|4|q|Q }" continue ;; esac done
语法格式
方法一
`command`
方法二
$(command)
$(())两个括号用来进行,包括加减乘除数据运算,引用变量前面可以加$,也可以不加$
案例
获取系统的所有用户并输出
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
参数:
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除
#!/bin/bash
index=1
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
echo "This is $index user: $user"
index=$(($index + 1))
done
根据系统时间计算今年或明年
Linux date命令可以用来显示或设定系统的日期与时间 时间方面: % : 印出 % %n : 下一行 %t : 跳格 %H : 小时(00..23) %I : 小时(01..12) %k : 小时(0..23) %l : 小时(1..12) %M : 分钟(00..59) %p : 显示本地 AM 或 PM %r : 直接显示时间 (12 小时制,格式为 hh:mm:ss [AP]M) %s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数 %S : 秒(00..61) %T : 直接显示时间 (24 小时制) %X : 相当于 %H:%M:%S %Z : 显示时区 日期方面: %a : 星期几 (Sun..Sat) %A : 星期几 (Sunday..Saturday) %b : 月份 (Jan..Dec) %B : 月份 (January..December) %c : 直接显示日期与时间 %d : 日 (01..31) %D : 直接显示日期 (mm/dd/yy) %h : 同 %b %j : 一年中的第几天 (001..366) %m : 月份 (01..12) %U : 一年中的第几周 (00..53) (以 Sunday 为一周的第一天的情形) %w : 一周中的第几天 (0..6) %W : 一年中的第几周 (00..53) (以 Monday 为一周的第一天的情形) %x : 直接显示日期 (mm/dd/yy) %y : 年份的最后两位数字 (00.99) %Y : 完整年份 (0000..9999) 参数说明: -d datestr : 显示 datestr 中所设定的时间 (非系统时间) --help : 显示辅助讯息 -s datestr : 将系统时间设为 datestr 中所设定的时间 -u : 显示目前的格林威治时间 --version : 显示版本编号
根据系统时间获取今年还剩下多少星期,已经过了多少星期
判定nginx进程是否存在,若不存在则自动拉起该进程
#!/bin/bash
nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ];then
systemctl start nginx
fi
declare和typeset命令
declare命令参数表
参数 | 含义 |
---|---|
-r | 将变量设为只读 |
-i | 将变量设为整数 |
-a | 将变量定义为数组 |
-f | 显示此脚本前定义过的所有函数及内容 |
-F | 仅显示此脚本前定义过的函数名 |
-x | 将变量声明为环境变量 |
输出数组内容: echo $array[@]} 输出全部内容 echo ${array[1]} 输出下标索引为1的内容 获取数组长度: echo ${#array} 数组内元素个数 echo ${#array[2]} 数组内下标索引为2的元素长度 给数组某个下标赋值: array[0]="lily" 给数组下标索引为1的元素赋值为lily array[20]="hanmeimei" 在数组尾部添加一个新元素 删除元素: unset array[2] 清除元素 unset array 清空整个数组 分片访问: ${array[@]:1:4} 显示数组下标索引从1开始到3的3个元素,不显内容替换: ${array[@]/an/AN}将数组中所有元素内包含an的子串替换为AN 数组遍历: for v in ${array[@]} do echo $v done
语法格式
方法一 expr $numl operator $num2
方法二 $(($num1 operator $num2))
expr操作符对照表
操作符 | 含义 |
---|---|
num1|num2 | num1不为空且非0,返回num1;否则返回num2 |
num1&num2 | num1不为空且非0,返回num1;否则返回0 |
num1<num2 | num1小于num2,返回1;否则返回0 |
num1<=num2 | num1小于等于num2,返回1;否则返回0 |
num1=num2 | num1等于num2,返回1;否则返回0 |
num1!=num2 | num1不等于num2,返回1;否则返回0 |
num1>num2 | num1大于num2,返回1;否则返回0 |
num1>=num2 | num1大于等于num2,返回1;否则返回0 |
num1+num2 | 求和 |
num1-num2 | 求差 |
num1*hum2 | 求积 |
num1/num2 | 求商 |
num1%num2 | 求余 |
在使用的时候需要进行转义
expr $numl \| $num2
expr $numl \& $num2
expr $numl \< $num2
expr $num1 \< $num2r
expr $numl \<=$num2
expr $num1 \>$num2
expr $numl \>=$num2
练习例子
提示用户输入一个正整数num,然后计算1+2+3+…+num的值;必须对num是否为正整数做判断,不符合应当再次允许输入
#!/bin/bash # while true do read -p "pls input a positive number: " num expr $num + 1 &> /dev/null if [ $? -eq 0 ];then if [ `expr $num \> 0` -eq 1 ];then for((i=1;i<=$num;i++)) do sum=`expr $sum + $i` done echo "1+2+3+....+$num = $sum" exit fi fi echo "error,input enlegal" continue done
bc介绍
bc操作符对照表
操作符 | 含义 |
---|---|
num1+num2 | 求和 |
num1-num2 | 求差 |
num1*num2 | 求积 |
num1/num2 | 求商 |
num1%num2 | 求余 |
num1^num2 | 指数运算 |
函数介绍
语法格式
第一种格式 name() { command1 command2 ...... commandn } 第二种格式 function name { command1 command2 ...... commandn }
如何调用函数
- 直接使用函数名调用,可以将其想象成Shell中的一条命令
- 函数内部可以直接使用参数$1、$2...$n
- 调用函数:function name $1 $2
实例
需求描述:写一个监控nginx的脚本;如果Nginx服务宕掉,则该脚本可以检测到并将进程启动,如果正常运行,则不做任何处理
#!/bin/bash this_pid=$$ while true do ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ];then echo "Nginx is running well" sleep 3 else systemctl start nginx echo "Nginx is down,Start it...." fi done
function name
{
echo "Hello $1"
echo "Hello $2"
}
函数调用:
name Lily Allen
实例
需求描述:
写一个脚本,该脚本可以实现计算器的功能,可以进行+ - * / 四种计算。
#!/bin/bash function calcu { case $2 in +) echo "`expr $1 + $3`" ;; -) echo "`expr $1 - $3`" ;; \\*) echo "`expr $1 \* $3`" ;; /) echo "`expr $1 / $3`" ;; esac } calcu $1 $2 $3
返回值的方式
方法一:
return
方法二:
echo
使用return返回值
实例
#!/bin/bash this_pid=$$ function is_nginx_running { ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ];then return else return 1 fi } is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"
使用echo返回值
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除
#!/bin/bash function get_users { users=`cat /etc/passwd | cut -d: -f1` echo $users } user_list=`get_users` index=1 for u in $user_list do echo "The $index user is : $u" index=$(($index+1)) done
全局变量
局部变量
#!/bin/bash var1="Hello world" function test { var2=87 } echo $var1 echo $var2 test echo $var1 echo $var2
#!/bin/bash var1="Hello world" function test { local var2=87 } test echo $var1 echo $var2
为什么要定义函数库
实例
定义一个函数库,该函数库实现以下几个函数
1、加法函数 add
2、减法函数 reduce
3、乘法函数 multiple
4、除法函数 divide
5、打印系统运行情况的函数sys_load,该函数可以显示内存情况
base_function function add { echo "`expr $1 + $2`" } function reduce { echo "`expr $1 - $2`" } function multiple { echo "`expr $1 \* $2`" } function divide { echo "`expr $1 / $2`" } function sys_load { echo "Memory Info" echo free -m echo echo "Disk Usage" echo df -h echo } test1.sh #! /bin/bash . /root/base_function add 12 23 reduce 90 30 multiple 12 12 divide 12 2 sys_load
总结
语法格式
find [路径] [选项] [操作]
选项参数对照表
选项 | 含义 |
---|---|
-name | 根据文件名查找 |
-perm | 根据文件权限查找 |
-prune | 通常和-path一起使用,用于将特定目录排除在搜索条件之外 该选项可以排除某些查找目录 |
-user | 根据文件属主查找 |
-group | 根据文件属组查找 |
-mtime | 根据文件更改时间查找 |
-nogroup | 查找无有效属组的文件 |
-nouser | 查找无有效属主的文件 |
-newer file1 !file2 | 查找更改时间比file1新但比file2旧IDE文件 |
-type | 按文件类型查找 |
-size | 按文件大小查找 |
-mindepth n | 从n级子目录开始搜索 |
-maxdepth n | 最多搜索到n级子目录 |
-exec | 对搜索到的文件执行特定的操作,格式为-exec command {} \; |
注:
1、{} 和 \ 之间有空格
2、\ 和 ; 之间没有空格!
实例
-type f 文件 find . -type f d 目录 find . -type d c 字符设备文件 find . -type c b 块设备文件 find . -type b l 链接文件 find . -type l p 管道文件 find .-type p 目录下以conf结尾的文件 find /etc -name '*conf' #-name不区分大小写 查找当前目录下文件名为aa的文件,不区分大小写 find . -iname aa 查找文件属主为hdfs的所有文件 find . -user hdfs 查找文件属组为yarn的所有文件 find . -group yarn 查找/etc目录下小于10000字节的文件 find /etc -size -10000c 查找/etc目录下大于1M的文件 find /etc -size +1M -mtime -n n天以内修改的文件 +n n天以外修改的文件 n 正好n天修改的文件 查找/etc目录下5天之内修改且以conf结尾的文件 find /etc -mtime -5 -name1 '*.conf' 查找/etc目录下10天之前修改且属主为root的文件 find /etc -mtime +10 -user root 查找/etc目录下30分钟之前修改的文件 find /etc -mmin +30 查找/etc目录下30分钟之内修改的目录 find /etc -mmin -30 -type d 在/etc下的3级子目录开始搜索 find /etc -mindepth 3 在/etc下搜索符合条件的文件,但最多搜索到2级子目录 find /etc -maxdepth 2 -type f -name '*.conf' 查找没有属主的用户 find . -type f -nouser 查找没有属组的用户 find .-type f -nogroup -perm例子: find.-perm 664 查找当前目录下所有普通文件,但排除test目录 find . -path ./etc -prune -o -type f 查找当前目录下所有普通文件,但排除etc和opt目录 find . -path . /etc -prune -o -path ./opt -prune -o -type f 查找当前目录下所有普通文件,但排除etc和opt目录,但属主为hdfs find . -path ./etc -prune -o -path ./opt -prune -o -type f -a -user hdfs 查找当前目录下所有普通文件,但排除etc和opt目录,但属主为hdfs,且文件大小必须大于500字节 find . -path ./etc -prune -o -path ./opt -prune -o -type f -a -user hdfs -a -size +500c 搜索/etc下的文件(非目录),文件名以conf结尾,且大于10k,然后将其删除 find . /etc/ -type f -name '*.conf' -size +10k -exec rm -f {} \; 将/var/1og/目录下以1og结尾的文件,且更改时间在7天以上的删除 find /var/log/ -name '*.log' -mtime +7 -exec rm -rf{} \; 搜索/etc下的文件(非目录),文件名以conf结尾,且大于10k,将其复制到/root/conf目录下 find . /etc/ -size +10k -type f -name '*.conf' -exec cp {} /root/conf/ \; -ok 和exec功能一样,只是每次操作都会给用户提示 逻辑运算符: -a 与 -o 或 -not | ! 非 查找当前目录下,属主不是hdfs的所有文件 find . -not -user hdfs | find . ! -user hdfs 查找当前目录下,属主属于hdfs,且大小大于300字节的文件 find . -type f -a -user hdfs -a -size +300c 查找当前目录下的属主为hdfs或者以xm1结尾的普通文件 find . -type f -a \( -user hdfs -o -name '*.xml' \)
locate命令
文件查找命令,所属软件包mlocate
不同于find命令是在整块磁盘中搜索,locate命令在数据库文件中查找
find是默认全部匹配,locate则是默认部分匹配
updatedb命令
用户更新/var/lib/mlocate/mlocate.db
所使用配置文件/etc/updatedb.conf
该命令在后台cron计划任务中定期执行
whereis命令
选项 | 含义 |
---|---|
-b | 只返回二进制文件 |
-m | 只返回帮助文档文件 |
-s | 只返回源代码文件 |
which命令
仅查找二进制程序文件
选项 | 含义 |
---|---|
-b | 只返回二进制文件 |
各命令使用场景推荐
命令 | 适用场景 | 优缺点 |
---|---|---|
find | 查找某一类文件,比如文件名部分一致 | 功能强大,速度慢 |
locate | 只能查找单个文件 | 功能单一,速度快 |
whereis | 查找程序的可执行文件、帮助文档等 | 不常用 |
which | 只查找程序的可执行文件 | 常用于查找程序的绝对路径 |
grep 命令用于查找文件里符合条件的字符串。
语法1:
grep [option] [ pattern] [file1, file2..]
语法2:
command | grep [option] [pattern]
选项 | 含义 |
---|---|
-v | 不显示匹配行信息 |
-i | 搜索时忽略大小写 |
-n | 显示行号 |
-r | 递归搜索 |
-E | 支持扩展正则表达式 |
-F | 不按正则表达式匹配,按照字符串字面意思匹配 |
-c | 只显示匹配行总数 |
-w | 匹配整词 |
-x | 匹配整行 |
-l | 只显示文件名,不显示内容 |
-s | 不显示错误信息 |
sed(Stream Editor),流编辑器。对标准输出或文件逐行进行处理
语法格式
语法一:
stdout |sed [option] "pattern command"
语法二:
sed [option] "pattern command" file
选项 | 含义 |
---|---|
-n | 只打印模式匹配行 |
-e | 直接在命令行进行sed编辑,默认选项 |
-f | 编辑动作保存在文件中,指定文件执行 |
-r | 支持扩展正则表达式 |
-i | 直接修改文件内容 |
edit.sed文件写入:
/python/p
pattern用法表
匹配模式 | 含义 |
---|---|
10command | 匹配到第10行 |
10,20command | 匹配从第10行开始,到第20行结束10, |
10,+5command | 匹配从第10行开始,到第16行结束 |
/pattern1/command | 匹配到pattern1的行 |
/pattern1/,/pattern2/command | 匹配到pattern1的行开始,到匹配到patern2的行结束 |
10,/pattern1/command | 匹配从第10行开始,到匹配到pettern1的行结束 |
/pattern1/,10command | 匹配到pattern1的行开始,到第10行匹配结束 |
实例
打印file文件的第17行 sed -n "17p" file 打印文件的10到20行 sed -n "10,20p" file 打印file文件中从第10行开始,往后面加5行 sed -n "10,+5p" file 打印file文件中以root开头的行 sed -n "/^root/p" file 打印file文件中第一个匹配到以ftp开头的行,到mail开头的行结束 sed -n "/^ftp/,/^mail/p" file 打印file文件中从第4行开始匹配,直到以hdfs开头的行结束 sed -n "4,/^hdfs/p" file 打印file文件中匹配root的行,直到第10行结束 sed -n "/root/,10p"file
编辑命令对照表
类别 | 编辑命令 | 含义 |
---|---|---|
查询 | p | 打印 |
= | 只显示行号 | |
增加 | a | 行后追加 |
i | 行前追加 | |
r | 外部文件读入,行后追加 | |
w | 匹配行写入外部文件 | |
删除 | d | 删除 |
修改 | s/old/new | 将行内第一个old替换为new |
s/old/new/g | 将行内全部的old替换为new | |
s/old/new/2g | 将行内从第2个old开始到剩下所有的old替换为new | |
s/old/new/ig | 将行内全部的old替换为new,忽略大小写 |
实例
先看一下例子
&和\1引用模式匹配到的整个串
两者区别在于只能表示匹配到的完整字符串,只能引用整个字符串;而\1可以使用()匹配到的字符
sed中引用变量时注意事项:
(1)、匹配模式中存在变量,则建议使用双引号
(2)、sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号
#!/bin/bash
old_str=hadoop
new_str=HADOOP
sed -i "s/$old_str"/"$new_str/g" abc.txt
需求描述:
处理一个类似MySQL配置文件my.cnf的文本,示例如下;编写脚本实现以下功能:输出文件有几个段,并且针对每个段可以统计配置参数总个数
my.cnf
# this is read by the standalone daemon and embedded servers [client] port=3306 socket=/tmp/mysql.socket #ThisSegmentForserver [server] innodb_buffer_pool_size=91750M innodb_buffer_pool_instances=8 innodb_buffer_pool_load_at_startup=1 innodb_buffer_pool_dump_at_shutdown=1 innodb_data_file_path=ibdata1:1G:autoextend innodb_flush_log_at_trx_commit=1 innodb_log_buffer_size=32M innodb_log_file_size=2G innodb_log_files_in_group=2 innodb_max_undo_log_size=4G innodb_undo_directory=undolog innodb_undo_tablespaces=95 #thisisonlyforthemysqldstandalonedaemon [mysqld] port=3306 socket=/tmp/mysql.sock basedir=/usr/local/mysql datadir=/data/mysql pid-file=/data/mysql/mysql.pid user=mysql bind-address=0.0.0.0 sort_buffer_size=16M join_buffer_size=16M thread_cache_size=3000 interactive_timeout=600 wait_timeout=600 #ThisSegmentFormysqld_safe [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid max_connections=1000 open_files_limit=65535 thread_stack=512K external-locking=FALSE max_allowed_packet=32M #thisisonlyforembeddedserver [embedded] gtid_mode=on enforce_gtid_consistency=1 log_slave_updates slave-rows-search-algorithms='INDEX_SCAN,HASH_SCAN' binlog_format=row binlog_checksum=1 relay_log_recovery=1 relay-log-purge=1 #usethisgroupforoptionsthatolderserversdon'tunderstand [mysqld-5.5] key_buffer_size=32M read_buffer_size=8M read_rnd_buffer_size=16M bulk_insert_buffer_size=64M myisam_sort_buffer_size=128M myisam_max_sort_file_size=10G myisam_repair_threads=1 lock_wait_timeout=3600 explicit_defaults_for_timestamp=1 innodb_file_per_table=1
预想输出结果:
1:client 2
2:server 12
3:mysqld 12
4:mysqld_safe 7
5:embedded 8
6:mysqld-5.5 10
脚本
#!/bin/bash FILE_NAME=/root/Desktop/dir2/my.cnf function get_all_segments { echo "`sed -n '/\[.*\]/p' $FILE_NAME |sed -e 's/\[//g' -e 's/\]//g'`" } function count_items_in_segment { echo "`sed -n '/\['$1'\]/,/\[.*\]/p' $FILE_NAME | grep -v ^# |grep -v ^$ |grep -v "\[.*\]" |wc -l `" } num=0 for seg in `get_all_segments` do num=`expr $num + 1` items_count=`count_items_in_segment $seg` echo "$num:$seg $items_count" done
删除配置文件中的所有注释行和空行
sed -i '/[:blank:]*#/d;/^$/d' nginx.conf
在配置文件中所有不以#开头的行前面添加*符号,注意:以#开头的行不添加
sed -i 's/^[^#]/\*&/g' nginx.conf
修改用法总结:
1、1s/old/new/
2、5,10s/old/new/
3、10,+10s/old/new/
4、/pattern1/s/old/new/
5、/pattern1/,/pattern2/s/old/new/
6、/pattern1/,20s/old/new/
7、15,/pattern1/s/old/new/
实例
修改/etc/passwd中第1行中第1个root为ROOT sed -i '1s/root/ROOT/' passwd 修改/etc/passwd中第5行到第10行中所有的/sbin/nologin为/bin/bash sed -i '5,10s/\/sbin\/nologin/\/bin\/bash/g' passwd 修改/etc/passwd中匹配到/sbin/nologin的行,将匹配到行中的login改为大写的LOGIN sed -i '/\/sbin\/nologin/s/login/LOGIN/g' passwd 修改/etc/passwd中从匹配到以root开头的行,到匹配到行中包含mail的所有行。修改内为将这些所有匹配到的行中的bin改为HADOOP sed -i '/^root/,/mail/s/bin/HADOOP/g' passwd 修改/etc/passwd中从匹配到以root开头的行,到第15行中的所有行,修改内容为将这些行中的nologin修改为SPARK sed -i '/^root/,15s/nologin/SPARK/g' passwd 修改/etc/passwd中从第15行开始,到匹配到以yarn开头的所有航,修改内容为将这些行中的bin换位BIN sed -i '15,/^yarn/s/bin/BIN/g' passwd
1、a 在匹配行后面追加
2、i 在匹配行前面追加
3、r 将文件内容追加到匹配行后面
4、w 将匹配行写入指定文件
实例
1、a append (1)、passwd文件第10行后面追加"Add Line Behind" sed -i '10a Add Line Begind' passwd (2)、passwd文件第10行到第20行,每一行后面都追加"Test Line Behind" sed -i '10,20a Test Line Behind' passwd (3)、passwd文件匹配到/bin/bash的行后面追加"Insert Line For /bin/bash Behind" sed -i '/\/bin\/bash/a Insert Line For /bin/bash Behind' passwd 2、i (1)、passwd文件匹配到以yarn开头的行,在匹配行前面追加"Add Line Before" sed -i '/^yarn/i Add Line Before' passwd (2)、passwd文件每一行前面都追加"Insert Line Before Every Line" sed -i 'i Insert Line Before Every Line' passwd 3、r (1)、将/etc/fstab文件的内容追加到passwd文件的第20行后面 sed -i '20r /etc/fstab' passwd (2)、将/etc/inittab文件内容追加到passwd文件匹配/bin/bash行的后面 sed -i '/\/bin\/bash/r /etc/inittab' passwd (3)、将/etc/vconsole.conf文件内容追加到passwd文件中特定行后面,匹配以ftp开头的行,到第18行的所有行 sed -i '//,18r /etc/vconsole.conf' passwd 4、w (1)、将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中 sed -i '/\/bin\/bash/w /tmp/sed.txt' passwd (2)、将passwd文件从第10行开始,到匹配到hdfs开头的所有行内容追加到/tmp/sed-1.txt sed -i '10,/^hdfs/w /tmp/sed-1.txt' passwd
awk是一个文本处理工具,通常用于处理数据并生成结果报告
awk 'BEGIN{} pattern{commands}END{}' file_name
standard output | awk 'BEGIN{}pattern{commands}END{}'
语法格式说明
语法格式 | 解释 |
---|---|
BEGIN{} | 正式处理数据之前执行 |
pattern | 匹配模式 |
{commands} | 处理命令,可能多行 |
END{} | 处理完所有匹配数据后执行 |
内置变量 | 含义 |
---|---|
$0 | 打印行所有信息 |
$1~$n | 打印行的第1到n个字段的信息 |
NF | Number Field 处理行的字段个数 |
NR | Number Row 处理行的行号,从1开始计数 |
FNR | File Number Row 多文件处理时,每个文件单独记录行号,都是从0康凯斯 |
FS | Field Separator 字段分割符,不指定时默认以空格或tab键分割 |
RS | Row Separator 行分隔符,不指定时以回车分割\n |
OFS | Output Filed Separator 输出字段分隔符。 |
ORS | Output Row Separator 输出行分隔符 |
FILENAME | 处理文件的文件名 |
ARGC | 命令行参数个数 |
ARGV | 命令行参数数组 |
格式符
格式符 | 含义 |
---|---|
%s | 打印字符串 |
%d | 打印10进制数 |
%f | 打印浮点数 |
%x | 打印16进制数 |
%o | 打印8进制数 |
%e | 打印数字的科学计数法格式 |
%c | 打印单个字符的ASCII码 |
修饰符 | 含义 |
---|---|
- | 左对齐 |
+ | 右对齐 |
# | 显示8进制在前面加o,显示16进制在前面加0x |
实例
1、以字符串格式打印/etc/passwd中的第7个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%s\n",$7}' /etc/passwd 2、以10进制格式打印/etc/passwd中的第3个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%d\n",$3}' /etc/passwd 3、以浮点数格式打印/etc/passwd中的第3个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%0.3f\n",$3}' /etc/passwd 4、以16进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' /etc/passwd 5、以8进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%#o\n",$3}' /etc/passwd 6、以科学计数法格式打印/etc/passwd中的第3个字段,以":"作为分隔符 awk 'BEGIN{FS=":"} {printf "%e\n",$3}' /etc/passwd
第一种
RegExp 按正则表达式匹配
第二种
关系运算匹配 按关系运算匹配
RegExp
匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
匹配/etc/passwd文件行中以yarn开头的所有行
awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd
运算符匹配
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于
~ 匹配正则表达式
!~ 不匹配正则表达式
实例
以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息 awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd 以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息 awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd 以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息 awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd 以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息 awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd 以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息 awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd
布尔运算符匹配:
|| 或
&& 与
! 非
实例
以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息
awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/passwd
以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd
运算符 | 含义 |
---|---|
+ | 加 |
/ | 除 |
% | 模 |
^或** | 乘方 |
++x | 在返回x变量之前,×变量加1 |
X++ | 在返回x变量之后,×变量加1 |
实例
使用awk计算/etc/services中的空白行数量
awk '/^$/{sum++}END{print sum}' /etc/services
计算学生课程分数平均值,学生课程文件内容如下:
Allen 80 90 96 98
Mike 93 98 92 91
Zhang 78 76 87 92
Jerry 86 89 68 92
Han 85 95 75 90
Li 78 88 98 100
awk '{total=$2+$3+$4+$4;AVG=total/4;printf "%-8s%5d%5d%5d%5d%0.2f\n",$1,$2,$3,$4,$5,AVG}' student.txt
条件语句:
if(条件表达式1)
动作
else if(条件表达式2)
动作
else
动作
以:为分隔符,只打印/etc/passwd中第3个字段的数值在50-100范围内的行信息
awk 'BEGIN{FS=":"}{if($3<50){ printf "%-20s%-20s%-5d\n","小于50的UID",$1,$3} else if($3>100) {printf "%-20s%-20s%-5d\n","大 于100的UID",$1,$3} else{ printf "%-20s%-20s%-5d\n","大于50 小于100的UID",$1,$3}}' /etc/passwd
循环语句:
while循环:
while(条件表达式)
动作
do while循环:
do
动作
while(条件表达式)
for循环:
for(初始化计数器;计数器测试;计数器变更)
动作
实例:
计算1+2+3+4+…+100的和,请使用while、do while、for三种循环方式实现
while
BEGIN{
while(i<=100) #不需要事先声明
{
sum+=i
i++
}
print sum
}
for
BEGIN{
for(i=0;i<=100;i++) #不需要事先声明
{
sum+=i
}
print sum
}
do while
BEGIN{
do
{
sum+=i
i++
}while(i<=100)
print sum
}
函数名 | 解释 |
---|---|
length(str) | 计算长度 |
index(str1,str2) | 返回在str1中查询到的str2的位置 |
tolower(str) | 小写转换 |
toupper(str) | 大写转换 |
split(str,arr,fs) | 分隔字符串,并保存到数组中 |
match(str,RE) | 返回正则表达式匹配到的子串的位置 |
substr(str,m,n) | 截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾 |
sub(RE,RepStr,str) | 替换查找到的第一个子串 |
gsub(RE,RepStr,str) | 替换查找到的所有子串 |
以:为分隔符,返回/etc/passwd中每行中每个字段的长度
root: x:0:0:root:/root:/bin/bash
4:1:1:1:4:5:9
BEGIN{ FS=":" } { i=0 while(i<=NF) { if(i==NF) printf "%d",length($i) else printf "%d:",length($i) i++ } print "" }
搜索字符串"I have a dream"中出现"ea"子串的位置
awk 'BEGIN{str=“I hava a dream”;location=index(str,“ea”);print location}
awk ‘BEGIN{str=“I hava a dream”;location=match(str,“ea”);print location}’
将字符串"Hadoop is a bigdata Framawork"全部转换为小写
awk ‘BEGIN{str=“Hadoop is a bigdata Framework”;print tolower(str)}’
将字符串"Hadoop is a bigdata Framawork"全部转换为大写
awk ‘BEGIN{str=“Hadoop is a bigdata Framework”;print toupper(str)}’
将字符串"Hadoop Kafka Spark Storm HDFS YARN Zookeeper",按照空格为分隔符,分隔每部分保存到数组array中
awk ‘BEGIN{str=“Hadoop Kafka Spark Storm HDFS YARN Zookeeper”;split(str,arr," ");for(a in arr) print arr[a]}’
搜索字符串"Tranction 2345 Start:Select * from master"第一个数字出现的位置
awk ‘BEGIN{str=“Tranction 2345 Start:Select * from master”;location=match(str,/[0-9]/);print location}’
截取字符串"transaction start"的子串,截取条件从第4个字符开始,截取5位
awk ‘BEGIN{str=“transaction start”;print substr(str,4,5)}’
替换字符串"Tranction 243 Start,Event ID:9002"中第一个匹配到的数字串为$符号
awk ‘BEGIN{str=“Tranction 243 Start,Event ID:9002”;count=sub(/[0-9]+/,"$",str);print count,str}’
awk ‘BEGIN{str=“Tranction 243 Start,Event ID:9002”;count=gsub(/[0-9]+/,"$",str);print count,str}’
选项 | 解释 |
---|---|
-v | 参数传递 |
-f | 指定脚本文件 |
-F | 指定分隔符 |
-V | 查看awk的版本号 |
shell中数组的用法:
打印元素: echo ${array[2]} 打印元素个数: echo ${#array[@]} 打印元素长度: echo ${#array[3]} 给元素赋值: array[3]="Li" 删除元素: unset array[2];unset array 分片访问: echo ${array[@]:1:3} 元素内容替换: ${array[@]/e/E}只替换第一个e; $tarray[@]//e/E}替换所有的e 数组的遍历: for a in array do echo $a done
awk中数组的用法
在awk中,使用数组时,不仅可以使用1.2…n作为数组下标,也可以使用字符串作为数组下标
当使用1.2.3…n时,直接使用array[2]访问元素;需要遍历数组时,使用以下形式:
str="Allen Jerry Mike Tracy Jordan Kobe Garnet"
split(str,array," ")
for(i=1;i<length(array);i++)
print array[i]
当使用字符串作为数组下标时,需要使用array[str]形式访问元素;遍历数组时,使用以下形式:
array["var1"]="Jin"
array["var2"]="Hao"
array["var3"]="Fang"
for(a in array)
print array[a]
netstat -an | grep tcp | awk '{array[$6]++} END{for(a in array) print a,array[a]}'
2. 计算横向数据总和,纵向数据总和
allen 80 90 87 91
mike 78 86 93 96
Kobe 66 92 82 78
Jerry 98 74 66 54
Wang 87 21 100 43
BEGIN{
printf "%-10s%-10s%-10s%-10s%-10s%-10s\n","Name","Yuwen","Math","English","Physical","Total"
}
{
total=$2+$3+$4+$5
yuwen_sum+=$2
math_sum+=$3
english_sum+=$4
physical_sum+=$5
printf "%-10s%-10d%-10d%-10d%-10d%-10d\n",$1,$2,$3,$4,$5,total
}
END{
printf "%-10s%-10d%-10d%-10d%-10d\n","total",yuwen_sum,math_sum,english_sum,physical_sum
}
测试数据
school.sql
--建表 --学生表 CREATE TABLE `student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s_birth` VARCHAR(20) NOT NULL DEFAULT '', `s_sex` VARCHAR(10) NOT NULL DEFAULT '', PRIMARY KEY(`s_id`) ); --课程表 CREATE TABLE `course`( `c_id` VARCHAR(20), `c_name` VARCHAR(20) NOT NULL DEFAULT '', `t_id` VARCHAR(20) NOT NULL, PRIMARY KEY(`c_id`) ); --教师表 CREATE TABLE `teacher`( `t_id` VARCHAR(20), `t_name` VARCHAR(20) NOT NULL DEFAULT '', PRIMARY KEY(`t_id`) ); --成绩表 CREATE TABLE `score`( `s_id` VARCHAR(20), `c_id` VARCHAR(20), `s_score` INT(3), PRIMARY KEY(`s_id`,`c_id`) ); --插入学生表测试数据 insert into student values('1001' , 'zhaolei' , '1990-1001-1001' , 'male'); insert into student values('1002' , 'lihang' , '1990-12-21' , 'male'); insert into student values('1003' , 'yanwen' , '1990-1005-20' , 'male'); insert into student values('1004' , 'hongfei' , '1990-1008-1006' , 'male'); insert into student values('1005' , 'ligang' , '1991-12-1001' , 'female'); insert into student values('1006' , 'zhousheng' , '1992-1003-1001' , 'female'); insert into student values('1007' , 'wangjun' , '1989-1007-1001' , 'female'); insert into student values('1008' , 'zhoufei' , '1990-1001-20' , 'female'); --课程表测试数据 insert into course values('1001' , 'chinese' , '1002'); insert into course values('1002' , 'math' , '1001'); insert into course values('1003' , 'english' , '1003'); --教师表测试数据 insert into teacher values('1001' , 'aidisheng'); insert into teacher values('1002' , 'aiyinsitan'); insert into teacher values('1003' , 'qiansanqiang'); --成绩表测试数据 insert into score values('1001' , '1001' , 80); insert into score values('1001' , '1002' , 90); insert into score values('1001' , '1003' , 99); insert into score values('1002' , '1001' , 70); insert into score values('1002' , '1002' , 60); insert into score values('1002' , '1003' , 80); insert into score values('1003' , '1001' , 80); insert into score values('1003' , '1002' , 80); insert into score values('1003' , '1003' , 80); insert into score values('1004' , '1001' , 50); insert into score values('1004' , '1002' , 30); insert into score values('1004' , '1003' , 20); insert into score values('1005' , '1001' , 76); insert into score values('1005' , '1002' , 87); insert into score values('1006' , '1001' , 31); insert into score values('1006' , '1003' , 34); insert into score values('1007' , '1002' , 89); insert into score values('1007' , '1003' , 98);
创建数据库
create database school default character set utf8;
mysql -u 用户名 -p 数据库名 < 数据库文件
查看数据库中的表,数据已经载入
赋予任意主机普通数据用户dbuser,查询、插入、更新、删除 数据库中school任意表的权利。
grant all on school.* to dbuser@'%' identified by '123456';
grant all on school.* to dbuser@localhost identified by '123456';
grant select on school.* to dbuser@'%' identified by '123456' ;
grant insert,on school.* to dbuser@'%' identified by '123456' ;
grant update on school.* to dbuser@'%' identified by '123456';
grant delete on school.* to dbuser@'%' identified by '123456';
-u 用户名
-p 用户密码
-h 服务器IP地址
-D 连接的数据库
-N 不输出列信息
-B 使用tab键代替默认交互分隔符
-e 执行SQL语句
其他选项
-E 垂直输出
-H 以HTML格式输出
-X 以XML格式输出
写一个脚本,该脚本可以接收两个参数,参数为数据库名称和需要执行的SQL语句
#!/bin/bash
user="dbuser"
password="123456"
db_name="$1"
SQL="$2"
mysql -u"$user" -p"$password" -D "$db_name" -e "$SQL"
需求1:处理文本中的数据,将文本中的数据插入Mysql中
文本数据
1010 jerry 1990-1001-1001 male
1011 mike 1990-12-21 female
1012 tracy 1990-1005-20 male
1013 kobe 1990-1008-1006 male
1014 allen 1989-1007-1001 female
1015 curry 1991-12-1001 female
1016 ztom 1992-1003-1001 female
插入前数据:
脚本
#!/bin/bash
user="dbuser"
password="123456"
mysql_conn="mysql -u"$user" -p"$password" "
cat data.txt | while read id name birth sex
do
$mysql_conn -e "insert into school.student values('$id','$name','$birth','$sex')"
done
需求2:
文本数据
2021|hao|1989-12-21|male
2022|zhang|1989-12-21|male
2023|ouyang|11989-12-21|male
2024|li|11989-12-21|female
脚本:
#!/bin/bash
user="dbuser"
password="123456"
IFS='|'
cat data.txt | while read id name birth sex
do
mysql -u"$user" -p"$password" -e "insert into school.student values('$id','$name','$birth','$sex')"
done
mysqldump
参数 | 含义 |
---|---|
-u | 用户名 |
-p | 密码 |
-h | 服务器IP地址 |
-d | 等价于–no-data 只导出表结构 |
-t | 等价于–no-create-info 只导出数据,不导出建表语句 |
-A | 等价于–all-databases |
-B | 等价于–databases 导出一个或多个数据库 |
mysqldump -udbuser -p123456 school >db.sql
open
与FTP服务器建立连接,例子:open 192.168.184.3
user
有权限登录FTP服务器的用户名和密码,例子:user ftp_user redhat
将school中的score表备份,并且将备份数据通过FTp传输到192.168.184.3的/data/backup目录下
#!/bin/bash db_user="dbuser" db_password="123456" ftp_user="ftp_user" ftp_password="redhat" ftp_host="192.168.184.3" dst_dir="/data/backup" time_date="`date+%Y%m%d%H%M%S`" file_name="school_score_${time_date}.sql" function auto_ftp { ftp -inv << EOF open $ftp_host user $ftp_user $ftp_password cd $dst_dir put $1 bye EOF } mysqldump -u"$db_user" -p"$db_password" -h"$db_host" school score > ./$file_name && auto_ftp ./$file_name
每隔一分钟执行一次
crontab是用来定期执行程序的命令。 -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe) -r : 删除目前的时程表 -l : 列出目前的时程表 * * * * * - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 7) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59) 实例 每一分钟执行一次 /bin/ls: * * * * * /bin/ls 在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次 /usr/bin/backup: 0 6-12/3 * 12 * /usr/bin/backup 每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha": 20 0-23/2 * * * echo "haha"
crontab -e
*/1 * * * * sh /root/test.sh &> /dev/null
1、实现一个脚本工具,该脚本提供类似supervisor功能,可以对进程进行管理;
2、一键查看所有进程运行状态
3、单个或批量启动进程,单个或批量停止进程
4、提供进程分组功能,可以按组查看进行运行状态,可以按组启动或停止该组内所有进程
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。
主要功能函数列表:
process.cfg
[GROUP_LIST] WEB DB HADOOP YARN [WEB] nginx httpd [DB] mysql postgresql oracle [HADOOP] datanode namenode journalnode [YARN] resourcemanager nodemanager [nginx] description="Web Server 1" program_name=tail parameter=-f /root/lesson/9.1/tmp/web-nginx.conf [httpd] description="Web Server 2" program_name=tail parameter=-f /root/lesson/9.1/tmp/web-httpd.conf [mysql] description="High Performance DataBase" program_name=tail parameter=-f /root/lesson/9.1/tmp/mysql.conf [postgresql] description="PG Server" program_name=tail parameter=-f /root/lesson/9.1/tmp/postgresql.conf [oracle] description="The Best DB Server In The World" program_name=tail parameter=-f /root/lesson/9.1/tmp/oracle.conf [datanode] description="NODE: Storage Data For HDFS" program_name=tail parameter=-f /root/lesson/9.1/tmp/hdfs-datanode.xml [namenode] description="NODE: Storage MetaData For HDFS" program_name=tail parameter=-f /root/lesson/9.1/tmp/hdfs-namenode.xml [journalnode] description="Data synchronization For NameNode" program_name=tail parameter=-f /root/lesson/9.1/tmp/hdfs-journalnode.xml [resourcemanager] description="Resource allocation, task scheduling" program_name=tail parameter=-f /root/lesson/9.1/tmp/yarn-resourcemanager.xml [nodemanager] description="Compute nodes to perform tasks assigned by RM" program_name=tail parameter=-f /root/lesson/9.1/tmp/yarn-nodemanager.xml
function get_all_group
说明:该函数无需输入任何参数;返回配置文件 process.cfg中所有的组信息,例如WEB、DB等
function get_all_group
{
if [ ! -e $HOME_DIR/$CONFIG_FILE ];then
echo "CONFIG_FILE is not exist .. PLease CHeck.."
EXIT 1
else
G_LIST=$(sed -n '/\[GROUP_LIST\]/,/\[.*\]/p' process.cfg | egrep -v "(^$|\[.*\])")
echo "$G_LIST"
fi
}
function get_all_process
说明:该函数无需输入任何参数;返回配置文件 process.cfg中所有的进程信息。
function get_all_process
{
for g in `get_all_group`
do
P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" process.cfg | egrep -v '^$|\[.*\]'`
echo $P_LIST
done
}
function get_process_info
function get_process_pid_by_name
说明:该函数接收一个参数,参数为进程名称;返回值是一个PID的列表,可能有一个PID,也可能有多个
function get_process_info_by_pid
说明:该函数接收一个参数,参数为进程PID;返回值是一个进程运行信息的列表,列表包含运行状态、CPU占用率、内存占用率、进程启动时间
function get_process_pid_by_name { if [ $# -ne 1 ];then return 1 else pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'` echo $pids fi } function get_process_info_by_pid { if [ `ps -ef | awk -v pid=$1 '$2==pid{print}' | wc -l` -eq 1 ] ;then pro_status="RUNNING" else pro_status="STOPED" fi pro_cpu=`ps aux | awk -v pid=$1 '$2==pid{print $3}'` pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'` pro_start_time=`ps -p $1 -o lstart | grep -v STARTED` }
function is_group_in_config
说明:该函数接收一个参数,参数为组的名称;返回值是0或1,0代表该组在配置文件中,1代表该组不在配置文件中
function is_group_in_config
{
for gn in `get_all_group`;do
if [ $gn = $1 ];then
return
fi
done
echo "Group $1 is not in process.cfg"
return 1
}
function get_all_process_by_group
说明:该函数接收一个参数,参数为组名称;返回值是对应组内的所有进程名称列表
function is_group_in_config { for gn in `get_all_group`;do if [ $gn = $1 ];then return fi done return 1 } function get_all_process_by_group { is_group_in_config $1 if [ $? -eq 0 ];then p_list=`sed -n "/\[$1\]/,/\[.*\]/p" process.cfg | egrep -v "(^$|\[.*\])"` echo $p_list else echo "GroupName $1 is not in process.cfg" fi }
function get_group_by_process_name
说明:该函数接收一个参数,参数是一个进程名称;返回值是一个组名
function get_group_by_process_name
{
for gn in `get_all_group`;do
for pn in `get_all_process_by_group $gn`;do
if [ $pn == $1 ];then
echo "$gn"
fi
done
done
}
function format_print
说明:该函数接收二个参数,第一个参数为process_name,第二个参数为组名称返回值,是针对每一个进程PID的运行信息
function format_print { ps -ef | grep $1 | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ];then pids=`get_process_pid_by_name $1` for id in $pids;do get_process_info_by_pid $id awk -v p_name=$1 \ -v g_name=$2 \ -v p_status=$pro_status \ -v p_cpu=$pro_cpu \ -v p_mem=$pro_mem \ -v p_start_time=$pro_start_time 'BEGIN{printf "%-10s%-10s%-5s%-5s%-5s%-5s%-15s\n",p_name,g_name,p_status,p_cpu,p_mem,p_start_time}' done else awk -v p_name=$1 -v g_name=$2 'BEGIN{printf "%-10s%-10s%-5s%-5s%-5s%-5s%-15s\n",p_name,g_name,"NULL","NULL","NULL","NULL","NULL"}' fi }
function is_process_in_config
说明:该函数接收一个参数,参数为进程名称;返回值是0或1,0代表该进程在配置文件中,1代表进程不在配置文件中
function is_process_in_config
{
for pn in `get_all_process`;do
if [ $pn = $1 ];then
return
fi
done
echo "Process $1 is not in process.cfg"
return 1
}
./app_status.sh 执行有三种情况:
if [ ! -e $HOME_DIR/$CONFIG_FILE ];then echo "CONFIG_FILE is not exist .. PLease CHeck.." exit 1 fi awk 'BEGIN{printf "%-16s%-10s%-10s%-10s%-10s%-10s%-20s\n","ProcessName---","GroupNmae---","Status---","Pid----","Cpu-----","Memory---","StartTime---"}' if [ $# -gt 0 ];then if [ "$1" == "-g" ];then shift for gn in $@;do is_group_in_config $gn || continue for pn in `get_all_process_by_group $gn`;do is_process_in_config $pn && format_print $pn $gn done done else for pn in $@;do gn=`get_group_by_process_name $pn` is_process_in_config $pn && format_print $pn $gn done fi else for pn in `get_all_process`;do gn=`get_group_by_process_name $pn` is_process_in_config $pn && format_print $pn $gn done fi
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。