文章目录
1、Shell脚本入门
注意事项:
-
以#!/bin/bash开头,以指定解析器;
-
执行方式;
执行方式 bash/sh 进入子shell执行完后退出 source/. 在当前shell执行 在子 shell 中设置的变量,父 shell 是不可见的。
在一个shell脚本中访问另一个shell脚本的方式
1.sh
#!/bin/bash
A=5
2.sh
#!/bin/bash
echo $A
-
在不开启子shell的情况下执行1.sh,
source 1.sh
这种方式可以将A放置在当前shell中
-
将A设为全局变量(环境变量)
export A
-
无论通过什么方式执行2.sh,均可访问到A
bash 2.sh
1.1 系统变量
$HOME
$PWD
$SHELL
$PATH
1.2 自定义变量
注意事项:
- 由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写;
- 等号两侧不能有空格;
- 变量的值如果有空格,需要使用双引号或单引号括起来。
- 声明静态变量:readonly 变量,不能 unset取消变量。
1.3 特殊变量
$n #第几个参数
$# #输入参数个数
#这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$*
#这个变量代表命令行中所有的参数,$@把所有的参数区分对待
$@
#最后一次执行的命令的返回状态
$?
#!/bin/bash
#不加双引号时输出结果一样
echo '--------------$*-------------'
for i in $*
do
echo "$i"
done
echo '--------------$@----------------'
for j in $@
do
echo "$j"
done
[root@hadoop100 zyn]# bash test2.sh 111 222 333 444
--------------$*-------------
111
222
333
444
--------------$@----------------
111
222
333
444
#!/bin/bash
#加双引号时输出结果不样
echo '--------------$*-------------'
for i in "$*"
do
echo "$i"
done
echo '--------------$@----------------'
for j in "$@"
do
echo "$j"
done
[root@hadoop100 zyn]# vim test2.sh
[root@hadoop100 zyn]# bash test2.sh 111 222 333 444
--------------$*-------------
111 222 333 444
--------------$@----------------
111
222
333
444
1.4 条件判断
- test condition
- [condition]
数值比较
符号 | 解释 |
---|---|
-eq | 等于 |
-ne | 不等于 |
-lt | 小于 |
-le | 小于等于 |
-gt | 大于 |
-ge | 大于等于 |
文件权限
符号 | 解释 |
---|---|
-r | 有读权限 |
-w | 有写权限 |
-x | 有执行权限 |
文件
符号 | 解释 |
---|---|
-e | 文件存在 |
-f | 是否为文件 |
-d | 是否为目录 |
多条件判断:
[atguigu@hadoop101 ~]$ [ atguigu ] && echo OK || echo notOK
OK
[atguigu@hadoop101 shells]$ [ ] && echo OK || echo notOK
notOK
2、流程控制
2.1 if判断
#单分支
if [ condition ];then
程序
fi
或
if [ condition ]
then
程序
fi
#多分支
if [ condition ]
then
程序
elif [ condition ]
then
程序
else
程序
fi
例子:
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "11111"
elif [ $1 -eq 2 ]
then
echo "222222"
fi
2.2 case语句
格式:
case $变量名 in
"值1")
程序1
;;
"值2")
程序2
;;
...
*)
默认程序
;;
esac
例子:
#!/bin/bash
case $1 in
"1")
echo "1111111"
;;
"2")
echo "2222222"
;;
*)
echo "******"
;;
esac
2.3 for循环
格式:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
或者
for 变量 in 值1 值2 值3
do
程序
done
例子:
#!/bin/bash
sum=0
for (( i=0;i<=100;i++))
do
sum=$[$sum+$i]
done
echo $sum
#!/bin/bash
for i in $*
do
echo $i
done
2.4 while循环
格式:
while [ 条件判断式 ]
do
程序
done
案例:
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo $sum
3、read读取控制台
参数 | 功能 |
---|---|
-p | 提示语 |
-t | 指定等待时间 |
read -t 7 -p "在7s内输入你的名字:" NN
echo $NN
4、函数
4.1 内置函数
#取路径里的文件名称
basename 路径
basename /home/atguigu/banzhang.txt
basename /home/atguigu/banzhang.txt .txt
#取出文件的绝对路径
dirname 绝对路径
basename /home/atguigu/banzhang.txt
4.2 自定义函数
格式:
[ function ] funname[()]
{
Action;
[return int;]
}
注意事项:
- 必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行。
- 函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值 n(0-255)。
案例:
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo "$s"
}
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;
5、Shell工具
5.1 cut
参数 | 含义 |
---|---|
-f | 指定列 |
-d | 指定分隔符,默认"\t" |
-c | 按字符切割,指定列 |
案例:
[atguigu@hadoop101 shells]$ vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
#切割 cut.txt 第一列
[atguigu@hadoop101 shells]$ cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
#切割 cut.txt 第二、三列
[atguigu@hadoop101 shells]$ cut -d " " -f 2,3 cut.txt
#切ip
[atguigu@hadoop101 shells]$ ifconfig ens33 | grep netmask | cut -d "i" -f 2 | cut -d " " -f 2
5.2 awk
参数 | 功能 |
---|---|
-F | 指定分割符 |
-v | 赋值一个用户变量 |
案例:
#搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 7 列
awk -F : '/^root/{print $7}' passwd
#搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 1 列和第 7 列,中间以“,”号分割。
awk -F : '/^root/{print $1","$7}' passwd
#只显示/etc/passwd 的第一列和第七列,以逗号分割,且在所有行前面添加列名 user,shell 在最后一行添加"dahaige,/bin/zuishuai"。
awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd
#将 passwd 文件中的用户 id 增加数值 1 并输出
awk -v i=1 -F : '{print $3+i}' passwd
awk的内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 行号 |
NF | 切割后,列的个数 |
案例:
#统计passwd文件名,每行的行号,每行的列数
awk -F : '{print "filename:" FILENAME",linenum:" NR ",col:"NF}' passwd
#查询 ifconfig 命令输出结果中的空行所在的行号
ifconfig | awk '/^$/{print NR}'
#切割 IP
ifconfig ens33 | grep netmask | awk -F "inet" '{print $2}' | awk -F " " '{print $1}'
5.3 sort
参数 | 说明 |
---|---|
-n | 数值大小排序 |
-r | 相反顺序排序 |
-t | 分隔符 |
-k | 指定需要排序的列 |
案例:
[atguigu@hadoop101 shells]$ vim sort.txt
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
#按照“:”分割后的第三列倒序排序。
sort -t : -nrk 3 sort.txt
5.4 wc
参数 | 功能 |
---|---|
-l | 统计文件行数 |
-w | 统计文件的单词数 |
-m | 统计文件的字符数 |
-c | 统计文件字节数 |
案例:
#统计/etc/profile 文件的行数、单词数、字节数!
wc -l /etc/profile
wc -w /etc/profile
wc -m /etc/profile
6、正则表达式
#^:以指定字符开头
cat /etc/passwd | grep ^a
#$:匹配指定字符结尾
cat /etc/passwd | grep t$
#.:匹配一个任意的字符
cat /etc/passwd | grep r..t
#*:匹配上一个字符 0 次或多次
cat /etc/passwd | grep ro*t
#[]:表示匹配某个范围内的一个字符
cat /etc/passwd | grep r[a,b,c]*t
[6,8]------匹配 6 或者 8
[0-9]------匹配一个 0-9 的数字
[0-9]*------匹配任意长度的数字字符串
[a-z]------匹配一个 a-z 之间的字符
[a-z]* ------匹配任意长度的字母字符串
[a-c, e-f]-匹配 a-c 或者 e-f 之间的任意字符