Shell脚本编程
- 一. SHELL入门
-
- 1.1 变量
-
-
- 1.1.1 变量名规范
- 1.1.2 位置变量
- 1.1.3 环境变量
-
- 1.2 管道
- 1.3 退出状态码
-
-
- 1.3.1 退出状态码描述
- 1.3.2 更改退出状态码exit命令
-
- 二. 判断与控制
-
- 2.1 if-then 语句
- 2.2 if-then-else 语句
- 2.3 嵌套if语句
- 2.4 条件测试-数值比较
- 2.5 条件测试-字符串比较
- 2.6 条件测试-文件比较
- 2.7 符合条件的测试
- 2.8 if-then中使用双括号
- 2.9 if-then使用双方括号
- 2.10 case命令
- 三. 循环与控制
-
- 3.1 for循环
- 3.2 while循环
- 3.3 until命令
- 3.4 break命令
- 3.5 continue命令
- 3.6 处理循环输出
- 四. 高级变量用法
-
- 4.1 变量替换和测试
- 4.2 字符串处理
- 4.3 命令替换
- 4.4 有类型变量
- 4.5 bash数学运算
-
-
- 4.5.1 bash数学运算之expr
- 4.5.2 bash数学运算之bc
-
- 五. 函数的高级用法
-
- 5.1 定义和使用函数
- 5.2 将参数传递给函数
- 5.3 函数返回值
- 5.4 局部变量和全局变量
- 5.5 函数库
- 六. 文件查找
-
- 6.1 find命令
- 6.2 find、locate、whereis和which总结和应用场景分析
- 七. 三剑客之一的文件处理grep
-
- 7.1 grep命令
-
-
- 7.1.1 语法格式
- 7.1.2 grep参数
- 7.1.3 grep和egrep
-
- 7.2 三剑客之一的文件处理sed
-
-
- 7.2.1 sed工作模式
- 7.2.2 sed选项
- 7.2.3 sed中的pattern详解
- 7.2.4 sed详细说明编辑命令
- 7.2.5 反向引用
- 7.2.6 利用sed查找文件内容
- 7.2.7 利用sed删除文件内容
- 7.2.8 利用sed修改文件内容
- 7.2.9 利用sed添加文件内容
-
- 7.3 三剑客之一的文本处理awk
-
-
- 7.3.1 awk工作模式
- 7.3.2 awk内置变量
- 7.3.3 awk格式输出printf
- 7.3.4 awk模式匹配的两种用法
- 7.3.5 awk表达式用法
- 7.3.6 awk动作中的条件和循环句子
- 7.3.7 awk中间的字符串函数
- 7.3.8 awk的常用选项
- 7.3.9 awk使用中数组
- 7.3.10 实例
-
- 八. Shell实战脚本操作数据库
-
- 8.1 导入测试数据
-
-
- 8.1.1 载入数据
- 8.1.2 赋予用户数据库权限
-
- 8.2 Shell脚本与MySQL数据库交互
-
-
- 8.2.1 mysql详细说明命令参数:
- 8.2.2 实例
-
- 8.3 利用Shell脚本导入文本数据MySQL中
- 8.4 备份MySQL并通过数据FTP将其传输到远端主机
-
-
- 8.4.1 mysqldump常用参数详解:
- 8.4.2 FTP常用指令
- 8.4.3 需求
-
- 九. 大型脚本工具开发实战
-
- 9.1 需求描述:
- 9.2 功能函数代码
- 9.3 程序主流程设计和代码实现
一. SHELL入门
1.1 变量
1.1.1 变量名规范
- 变量是由任何字母、数字和下划线组成的字符串,不能从数字开始。
- 区分字母大小写
- 变量、等号、值中间不能出现任何空格
注:$ var1 $ var2不能实现相加,$ var1,$ var默认情况下,2作为字符串处理
1.1.2 位置变量
在执行命令或脚本时,我们可以使用位置参数变量来表示这些参数。
位置参数变量 | 描述 |
---|---|
$n | n 为数字,$ 0 代表Shell本身的文件名,$ 1?$ 9 代表第 1 ~ 9 个参数,10 大括号应包含上述参数, 如 $ {10} |
$* | |
$@ | 命令行中所有参数,但每个参数区别对待 |
$# | 命令行中所有参数的个数 |
$ @和$ *都表示命令行所有参数,但是$ *将命令行的所有参数看成一个整体,而$ @则区分各个参数
1.1.3 环境变量
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或多个应用程序将使用到的信息。Linux是一个多用户的操作系统,每个用户登录系统时都会有一个专用的运行环境,通常情况下每个用户的默认的环境都是相同的。这个默认环境就是一组环境变量的定义。每个用户都可以通过修改环境变量的方式对自己的运行环境进行配置。
-
对所有用户生效的环境变量 /etc/profile
-
对特定用户生效的环境变量 ~ /.bashrc或者~/.bash_profile
-
临时有效的环境变量 export
环境变量 | 含义 |
---|---|
PATH | 命令搜索的路径 |
HOME | 用户家目录的路径 |
LOGNAME | 用户登录名 |
PWD | 当前所在路径 |
HISTFILE | 历史命令的保存文件 |
HISTSIZE | 历史命令保存的最大行数 |
HOSTNAME | 主机名 |
SHELL | 用户当前使用的SHELL |
PS1 | 一级命令提示符 |
TMOUT | 用户和系统交互过程的超时值 |
IFS | 系统输入分隔符 |
OFS | 系统输出分隔符 |
1.2 管道
将一个命令的输出作为另一个命令的输入
- 列出所有安装过的软件包
rpm -qa
rpm命令是RPM软件包的管理工具
- 列出与python相关的软件包
rpm -qa | grep python
Linux grep 命令用于查找文件里符合条件的字符串。
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :打印匹配次数
-f 两个文件相同行 如,grep -f file1 file2
-h 不显示匹配行所在文件名
-i :忽略大小写的不同,所以大小写视为相同
-l 只显示匹配到的文件名
-n :顺便输出行号
-o 只显示匹配的字符
-v :只显示不匹配的行。
--color=auto :可以将找到的关键词部分加上颜色的显示喔!
- 显示与python相关的软件包的行数
rpm -qa | grep python | wc -l
Linux wc命令用于计算字数
-c或--bytes或--chars 只显示Bytes数。
-l或--lines 只显示行数。
-w或--words 只显示字数。
--help 在线帮助。
--version 显示版本信息。
1.3 退出状态码
1.3.1 退出状态码描述
所有的shell命令都使用退出状态吗来告知shell它已执行完毕
退出状态码是一个0~255的整数值
Linux提供了一个$?来捕获退出状态码的值,所以,可以通过echo语句测试命令是否运行成功。
一般来讲,退出状态 0 表示正常执行,没有遭遇任何问题。其他非零的状态码均表示失败。
状态码 | 描述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shell 命令 |
126 | 找到了该命令但无法执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与linux信号x相关的严重错误 |
130 | 通过ctrl+C终止的命令 |
255 | 正常范围之外的退出状态码 |
1.3.2 改变退出状态码的exit命令
退出状态码是以上一条指令的返回结果为准 使用exit命令改变退出状态码
exit $exit_code
exit 48 或者 exit 125 或者exit 0
二. 判断与控制
2.1 if-then 语句
语法:
if command | condition
then
commands
fi
实例
#!/bin/bash
if pwd
then
echo "It works"
fi
2.2 if-then-else 语句
if command | condition
then
commands
else
commands
fi
#!/bin/bash
if pwd
then
echo "It works"
fi
2.3 嵌套if语句
if command | condition
then
commands
elif command | condition
then
commands
else
commands
fi
2.4 条件测试-数值比较
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
2.5 条件测试-字符串比较
字符串比较 | 含义 |
---|---|
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
2.6 条件测试-文件比较
文件比较 | 含义 |
---|---|
-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
2.7 符合条件测试
语法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
2.8 if-then中使用双括号
if ((expression))
then
commands
fi
注:
-
双括号结构中,变量名引用可以加$,也可以不加
-
运算符前后可以有空格,也可以没有
-
可以用于if,for,while等循环控制结构中
-
多个运算符使用逗号分隔
运算符 | 含义 |
---|---|
value++ | 后增 |
value– | 后减 |
++value | 先增 |
–value | 先减 |
! | 逻辑求反 |
== | 相等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
&& | 逻辑与 |
#!/bin/bash
a=10
((a+=10))
echo $a
2.9 if-then中使用双方括号
if [ $n1 -gt $n2 ] && [ $n2 -lt $n3 ]
then
commands
fi
改为双方括号语法
if [ [$n1 -gt $n2 && $n2 -lt $n3 ]]
then
commands
fi
注:
双括号结构中,变量名引用必须加$
[[后面必须要空格,]]前面必须有空格
2.10 case命令
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
三. 循环与控制
3.1 for循环
循环遍历一系列特定值,然后在结构体中针对每个特定值做处理
for var in list
do
commands
done
#!/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
#!/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
#!/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
#!/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"
3.2 while循环
while command
do
commands
done
实例:
#!/bin/bash
num=10
while [ $num -lt 20 ]
do
echo "number is $num"
((num++))
done
3.3 until命令
until command
do
commands
done
#!/bin/bash
num=10
until [ $num -eq 0 ]
do
echo "number is $num"
((num--))
done
3.4 break命令
实例:
#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
if ((i==5))
then
break
else
echo "number is $i"
fi
done
#!/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
3.5 continue命令
实例:
#!/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
3.6 处理循环的输出
#!/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"
四. 变量的高级用法
4.1 变量替换和测试
语法 | 含义 |
---|---|
${变量名#匹配规则} | 从变量开头进行规则匹配,将符合最短的数据删除 |
${变量名##匹配规则} | 从变量开头进行规则匹配,将符合最长的数据删除 |
${变量名%匹配规则} | 从变量尾部进行规则匹配,将符合最短的数据删除 |
${变量名%%匹配规则} | 从变量尾部进行规则匹配,将符合最长的数据删除 |
${变量名/旧字符串/新字符串} | 变量内容符合旧字符串规则,则第一个旧字符串会被新字符串取代 |
${变量名//旧字符串/新字符串} | 变量内容符合旧字符串规则,则全部的旧字符串会被新字符串取代 |
4.2 字符串处理
方法一:
${#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字符串变量,并给出用户以下选项:
- 打印string长度
- 删除字符串中所有的Hadoop
- 替换第一个Hadoop为Mapreduce
- 替换全部Hadoop为Mapreduce
用户输入数字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
4.3 命令替换
方法一
`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
标签: 系列17p连接器