Shell概述
Linux自带的Shell解释器有:
bash和sh的关系:其实sh指向的就是bash
Shell脚本入门
①脚本的格式
脚本以#!/bin/bash开头(指定解析器)
②第一个shell脚本
创建一个文件:touch helloworld
编辑文件:vim helloworld
输入内容:
#!/bin/bash
echo "helloworld"
执行脚本:
通过bash解析器运行:bash ./helloworld通过sh解析器运行:sh ./helloworld修改文件权限,文件自行运行:chmod 777 helloworld
③多命令运行脚本
在/home/atguigu/目录下创建一个banzhang.txt,在banzhang.txt文件中增加“I love cls”。
创建一个文件:touch batch.sh
编辑文件并输入内容:
vim batch.sh
cd /home/atguigu/
touch banzhang.txt
echo "l love cls" >> banzhang.txt
Shell变量使用
①系统变量
常用系统变量有:
set可以查看所有的环境变量值,不过太多了,可以进行过滤
②自定义变量
定义变量:变量=值撤销变量:unset 变量声明静态变量:readonly 变量 (静态变量不能unset)环境变量命名规则:
字母、数字、下划线,不能以数字开头,环境变量建议大写!等号两边没有空格! 案例:
1. 定义变量A
A
=5
echo $A
2. 重新赋值变量A
A
=8
echo $A
3. 撤销变量A
unset A
echo $A
4. 声明静态变量B
readonly B
=2
echo $B
5. 在bash中,变量都是字符串类型,无法直接进行数值计算
C
=1+2
echo $C
>> 1+2
6. 变量的值中如果有空格,需要适用双引号或单引号括起来
D
="l love cls"
echo $A
>> l love cls
7. 把变量提升为全局变量:export 变量名
③特殊环境变量
特殊变量$n:表示输入参数的值,10以上的为 需要适用{10}
$0:表示脚本文件名
(1)输出该脚本文件名称、输入参数1和输入参数2 的值
[atguigu@hadoop101 datas
]$
touch parameter.sh
[atguigu@hadoop101 datas
]$ vim parameter.sh
echo "$0 $1 $2"
[atguigu@hadoop101 datas
]$
chmod 777 parameter.sh
[atguigu@hadoop101 datas
]$ ./parameter.sh cls xz
./parameter.sh cls xz
特殊变量$#:表示输入参数的个数
[atguigu@hadoop101 datas
]$ vim parameter.sh
echo "$0 $1 $2"
echo $
[atguigu@hadoop101 datas
]$
chmod 777 parameter.sh
[atguigu@hadoop101 datas
]$ ./parameter.sh cls xz
parameter.sh cls xz
2
特殊变量$*:命令行中所有的参数,不过是以整体的形式输出
特殊变量$@:命令行中所有的参数,是逐个输出参数
[atguigu@hadoop101 datas
]$ vim parameter.sh
echo "$0 $1 $2"
echo $
echo $*
echo $@
[atguigu@hadoop101 datas
]$
bash parameter.sh 1 2 3
parameter.sh 1 2
3
1 2 3
1 2 3
特殊变量$?:表示上一条语句是否正确执行,正确为0,错误为非0值
[atguigu@hadoop101 datas
]$ ./helloworld.sh
hello world
[atguigu@hadoop101 datas
]$
echo $?
0
运算符
①基本语法:
(1)“
(
(
运
算
式
)
)
”
或
“
((运算式))”或“
((运算式))”或“[运算式]”
(2)expr + , - , *, /, % 加,减,乘,除,取余
②案例实操:
(1
)计算3+2
echo $($3+$2)
echo $
[3+2
]
expr 2 + 3
(2
)计算(2+3)*4
echo $($($2+$3)*
$4)
echo $
[(2+3
)*4
]
expr `expr 2 + 3` \* 4
条件判断
①基本语法
[ condition ](注意condition前后要有空格)
注意:条件非空即为true,[ atguigu ]返回true,[]返回 false
②常用判断条件
整数比较:
小于:-lt等于:-eq大于:-gt
小于等于:-le不等于:-ne大于等于:-ge 文件权限判断
有读的权限:-r有写的权限:-w有执行的权限:-x
文件类型判断
文件存在且为常规文件:-f文件存在-:e文件存在且为目录:-d
③案例实操
(1)23是否大于等于22
[atguigu@hadoop101 datas
]$
[ 23 -ge 22
]
[atguigu@hadoop101 datas
]$
echo $?
0
(2)helloworld.sh是否具有写权限
[atguigu@hadoop101 datas
]$
[ -w helloworld.sh
]
[atguigu@hadoop101 datas
]$
echo $?
0
(3)/home/atguigu/cls.txt目录中的文件是否存在
[atguigu@hadoop101 datas
]$
[ -e /home/atguigu/cls.txt
]
[atguigu@hadoop101 datas
]$
echo $?
1
(4)多条件判断(
&& 表示前一条命令执行成功时,才执行后一条命令,
|| 表示上一条命令执行失败后,才执行下一条命令)
[atguigu@hadoop101 ~
]$
[ condition
] && echo OK
|| echo notok
OK
[atguigu@hadoop101 datas
]$
[ condition
] && [ ] || echo notok
notok
流程控制★
①if 判断
1)输入一个数字,如果是1,则输出banzhang zhen shuai,如果是2,则输出cls zhen mei,如果是其它,什么也不输出。
[atguigu@hadoop101 datas
]$
touch if.sh
[atguigu@hadoop101 datas
]$ vim if.sh
if [ $1 -eq
"1" ]
then
echo "banzhang zhen shuai"
elif [ $1 -eq
"2" ]
then
echo "cls zhen mei"
fi
[atguigu@hadoop101 datas
]$
chmod 777 if.sh
[atguigu@hadoop101 datas
]$ ./if.sh 1
banzhang zhen shuai
②case 语句
(1)输入一个数字,如果是1,则输出banzhang,如果是2,则输出cls,如果是其它,输出renyao。
[atguigu@hadoop101 datas
]$
touch case.sh
[atguigu@hadoop101 datas
]$ vim case.sh
!/bin/bash
case $1 in
"1")
echo "banzhang"
;;
"2")
echo "cls"
;;
*
)
echo "renyao"
;;
esac
[atguigu@hadoop101 datas
]$
chmod 777 case.sh
[atguigu@hadoop101 datas
]$ ./case.sh 1
1
③for循环
(1)从1加到100
[atguigu@hadoop101 datas
]$
touch for1.sh
[atguigu@hadoop101 datas
]$ vim for1.sh
s
=0
for((i=0;i<=100;i++))
do
s
=$
[$s+
$i]
done
echo $s
[atguigu@hadoop101 datas
]$
chmod 777 for1.sh
[atguigu@hadoop101 datas
]$ ./for1.sh
“5050”
(1)打印所有输入参数
[atguigu@hadoop101 datas
]$
touch for2.sh
[atguigu@hadoop101 datas
]$ vim for2.sh
for i
in $*
do
echo "ban zhang love $i "
done
[atguigu@hadoop101 datas
]$
chmod 777 for2.sh
[atguigu@hadoop101 datas
]$
bash for2.sh cls xz bd
ban zhang love cls
ban zhang love xz
ban zhang love bd
④while循环
(1)从1加到100
[atguigu@hadoop101 datas
]$
touch while.sh
[atguigu@hadoop101 datas
]$ vim while.sh
s
=0
i
=1
while [ $i -le 100
]
do
s
=$
[$s+
$i]
i
=$
[$i+1
]
done
echo $s
[atguigu@hadoop101 datas
]$
chmod 777 while.sh
[atguigu@hadoop101 datas
]$ ./while.sh
5050
read读取控制台输入
基本语法
read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名
案例实操
(1)提示7秒内,读取控制台输入的名称
read -t -7 -p
"Enter your name in 7 seconds" NAME
echo NAME
函数
①系统函数
basename
1)截取该/home/atguigu/banzhang.txt路径的文件名称
[atguigu@hadoop101 datas
]$
basename /home/atguigu/banzhang.txt
banzhang.txt
[atguigu@hadoop101 datas
]$
basename /home/atguigu/banzhang.txt .txt
banzhang
dirname
(1)获取banzhang.txt文件的路径
[atguigu@hadoop101 ~
]$
dirname /home/atguigu/banzhang.txt
/home/atguigu
②自定义函数
3.案例实操
(1)计算两个输入参数的和
[atguigu@hadoop101 datas
]$
touch fun.sh
[atguigu@hadoop101 datas
]$ vim fun.sh
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;
[atguigu@hadoop101 datas
]$
chmod 777 fun.sh
[atguigu@hadoop101 datas
]$ ./fun.sh
Please input the number1: 2
Please input the number2: 5
7
Shell工具★
①cut
cut就是剪的操作。
语法:以“:”截切file.txt文件,并取第2列的值。
cut -d
":" -f 2 file.txt
案例实操:
(0)数据准备
[atguigu@hadoop101 datas
]$
touch cut.txt
[atguigu@hadoop101 datas
]$ vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
(1)切割cut.txt第一列
cut -d
" " -f 1 cut.txt
(2)切割cut.txt的第二、三列
cut -d
" " -f 2,3 cut.txt
(3)切割cut.txt文件中的guan
cat cut.txt
|grep "guan" | cut -d
" " -f 1
(4)切割ifconfig 后打印的IP地址
ifconfig eth0
| grep "inet addr" | cut -d: -f 2
| cut -d
" " -f 1
②sed
sed是一种流编辑器。
sed -e “a新增;d删除;s替换”
(0)数据准备
[atguigu@hadoop102 datas
]$
touch sed.txt
[atguigu@hadoop102 datas
]$ vim sed.txt
dong shen
guan zhen
wo wo
lai lai
le le
(1)将“mei nv”这个单词插入到sed.txt第二行下,打印。
sed '2a mei nv' sed.txt
(2)删除sed.txt文件所有包含wo的行
sed '/wo/d' sed.txt
(3)将sed.txt文件中wo替换为ni
sed 's/wo/ni/g' sed.txt
(4)删除第二行
sed '2d' sed.txt
(5)将sed.txt文件中的第二行删除并将wo替换成ni
sed -e
'2d' -e
's/wo/ni/g' sed.txt
③awk
awk是一个强大的文本分析工具。(一定不要忘了最后要加文件名!!!)
-F 指定输入文件拆分符-v 赋值一个用户定义变量
案例实操
(0)数据准备
[atguigu@hadoop102 datas
]$
sudo cp /etc/passwd ./
(1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
awk -F:
'/^root/{print $7}' passwd
(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
awk -F:
'/^root/{print $1","$7}' passwd
(3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加
"dahaige,/bin/zuishuai"。
awk -F:
'BEGIN{print "user, shell"}{print $1","$7} END{print "dahaige, /bin/zuishuai"}' passwd
(4)将passwd文件中的用户id增加数值1并输出
awk -v i
=1 -F:
'{print $3+i}' passwd
awk的内置变量
变量说明
FILENAME文件名NR已读的记录数NF浏览记录的域的个数(切割后,列的个数)
案例实操
(1)统计passwd文件名,每行的行号,每行的列数
awk -F:
'{print "filename:" FILENAME ", linenumber:" NR ", columns:" NF}' passwd
(2)切割IP
ifconfig eth0
| grep "inet addr" | awk -F:
'{print $2}' | awk -F
" " '{print $1}'
(3)查询sed.txt中空行所在的行号
awk '/^$/{print NR}' sed.txt
④sort
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。
选项说明
-n依照数值的大小排序-r以相反的顺序来排序-t设置排序时所用的分隔字符-k指定需要排序的列
案例实操
(0)数据准备
[atguigu@hadoop102 datas
]$
touch sort.sh
[atguigu@hadoop102 datas
]$ vim sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
(1)按照“:”分割后的第三列倒序排序。
sort -t
: -nrk 3 sort.sh
企业面试真题
问题1:使用Linux命令查询file1中空行所在的行号
答案:
[atguigu@hadoop102 datas
]$
awk '/^$/{print NR}' sed.txt
5
问题2:有文件chengji.txt内容如下:
张三 40
李四 50
王五 60
使用Linux命令计算第二列的和并输出
[atguigu@hadoop102 datas
]$
cat chengji.txt
| awk -F
" " '{sum+=$2} END{print sum}'
150
问题3:Shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?
if [ -f file.txt
]; then
echo "文件存在!"
else
echo "文件不存在!"
fi
问题4:用shell写一个脚本,对文本中无序的一列数字排序
cat test.txt
9
8
7
6
5
4
3
2
10
1
sort -n test.txt
| awk -v sum
=0
'{sum+=$1}END {print "SUM=" sum}'
问题5:请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen”的文件名称
[atguigu@hadoop102 datas
]$
grep -r
"shen" /home
| cut -d
":" -f 1
/home/atguigu/datas/sed.txt
/home/atguigu/datas/cut.txt