课程大纲
|
课程内容 |
学习效果 |
掌握目标 |
Linux基础 |
Shell编程 |
掌握 |
|
Linux高级命令 |
掌握 |
Shell 是一个用 C 语言编写的程序,能解释我们给它的命令并执行,是用户使用 Linux 的桥梁。所以Shell 既是一个命令解释器,又是一种程序设计语言。
Shell 脚本(shell script),是一种为 shell 编写,让shell解析并执行的脚本程序。
"shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身,我们进行shell编程就是将之前学过的好多命令放到一个文件里面,然后交给shell解释并执行,从而完成一个小功能。
Shell作为一个功能相当强大的编程语言,易编写、易调试、灵活性强,可以做到随时编写,随时调试,随时执行。而java的话,必须编译后,才能执行。Shell类似于js,python,是解释执行的脚本语言,在Shell中也可以调用Linux系统命令。
Shell作为一种命令行解释器,有好多中,比如bourne shell (sh) ,bourne aginst shell( bash),c shell ,k shell,centos7默认的解释器,可以通过以下方式查看。
[root@bd-offcn-01 ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
脚本格式
脚本以 #!/bin/bash 开头,指定用bash来解释我们编写的shell脚本。
脚本必须有可执行权限
案例:
第一个Shell脚本
a)需求:创建一个Shell脚本,输出helloworld
b)实操:
[root@bd-offcn-01 ~]# touch helloworld.sh
[root@bd-offcn-01 ~]# vi helloworld.sh
[root@bd-offcn-01 ~]# vim helloworld.sh
在helloworld.sh中输入如下内容
#!/bin/bash
echo "helloworld"
脚本的常用执行方式
第一种:输入脚本的绝对路径或相对路径,第一行必须加上#!/bin/bash
a) 首先要赋予helloworld.sh 脚本的+x权限
[root@bd-offcn-01 ~]# chmod 777 helloworld.sh
b) 执行脚本
通过绝对路径执行
[root@bd-offcn-01 ~]# /root/helloworld.sh
通过相对路径执行
[root@bd-offcn-01 ~]# ./helloworld.sh
helloworld
第二种:bash或sh+脚本(不用赋予脚本+x权限)第一行可以不加上#!/bin/bash,但是一般都加上
[root@bd-offcn-01 ~]# sh /root/helloworld.sh
helloworld
[root@bd-offcn-01 ~]# sh helloworld.sh
helloworld
Linux Shell中的变量分为,系统变量和用户自定义变量。
系统变量:$HOME、$PWD、$SHELL、$USER等等
显示当前shell中所有变量:set
(1)基本语法:
(2)变量定义规则
(3)案例
a)定义变量A
[root@bd-offcn-01 ~]# A=8
[root@bd-offcn-01 ~]# echo $A
8
等号两边不能有空格
[root@bd-offcn-01 ~]# B =8
bash: B: 未找到命令..
b)撤销变量A
unset A
[root@bd-offcn-01 ~]# unset A
[root@bd-offcn-01 ~]# echo $A
[root@bd-offcn-01 ~]#
c) 声明静态的变量B=2,不能unset
readonly B=2
[root@bd-offcn-01 ~]# readonly B=2
[root@bd-offcn-01 ~]# unset B
-bash: unset: B: 无法反设定: 只读 variable
d) 可把变量提升为全局环境变量,可供其他shell程序使用
export 变量名
(1)A=`ls -la` 反引号,运行里面的命令,并把结果返回给变量A
(2)A=$(ls -la) 等价于反引号
(1)基本语法:
a)export 变量名=变量值 (功能描述:设置环境变量的值)
b)source 配置文件 (功能描述:让修改后的配置信息立即生效)
c)echo $变量名 (功能描述:查询环境变量的值)
(2)案例:
a)在/etc/profile文件中定义JAVA_HOME环境变量
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin
b)查看环境变量JAVA_HOME的值
[root@hadoop003 datas]$ echo $JAVA_HOME
/opt/module/jdk1.8.0_144
(1)基本语法
$n (功能描述:n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}。)
$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
$# (功能描述:这个变量代表命令行中所有参数的个数)
(2)案例
打印输入的的参数1,参数2,所有参数,参数个数
[root@bd-offcn-01 ~]# mkdir myshell
[root@bd-offcn-01 ~]# cd myshell/
[root@bd-offcn-01 myshell]#
[root@bd-offcn-01 myshell]# vim para.sh
向脚本中添加如下内容:
#!/bin/bash
echo "$0 $1 $2"
echo "$*"
echo "$@"
echo "$#"
运行展示:
[root@bd-offcn-01 myshell]# sh para.sh 1 2 3
para.sh 1 2
1 2 3
1 2 3
3
(3)$*与$@的区别
编写一个脚本,
[root@bd-offcn-01 myshell]# vim diff.sh
向其中添加如下内容:
#!/bin/bash
for i in "$*"
#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo "The parameters is: $i"
done
x=1
for y in "$@"
#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
do
echo "The parameter$x is: $y"
x=$(( $x +1 ))
done
运行展示:
[root@bd-offcn-01 myshell]# sh diff.sh 1 2 3
The parameters is: 1 2 3
The parameter1 is: 1
The parameter2 is: 2
The parameter3 is: 3
(1)基本语法:
$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
$$ (功能描述:当前进程的进程号(PID))
$! (功能描述:后台运行的最后一个进程的进程号(PID))
(2)案例
编写一个脚本,
[root@bd-offcn-01 myshell]# vim pre.sh
向其中添加如下内容:
#!/bin/bash
echo "$$"
/root/helloworld.sh &
echo "$!"
echo "$?"
运行展示:
[root@bd-offcn-01 myshell]# sh pre.sh
10729
10730
0
[root@bd-offcn-01 myshell]# helloworld
[root@bd-offcn-01 myshell]# helloworld
1、运算规则
shell程序中的操作默认都是字符串操作,要想进行数学运算,可以采用以下几种方式。
2、算数运算符
运算符 |
说明 |
举例 |
+ |
加法 |
expr 10 + 20 结果为30 |
- |
减法 |
expr 10 - 20 结果为-10 |
* |
乘法 |
expr 10 \* 20 结果为200 |
/ |
除法 |
expr 20 / 10 结果为2 |
% |
取余 |
expr 4 % 3 结果为1 |
= |
赋值 |
a=2,将2赋值给a变量 |
== |
相等。用于比较两个数字,相同则返回 true |
[ 10 == 20 ]返回false |
!= |
不相等。用于比较两个数字,不相同则返回true |
[ 10 != 20 ]返回true |
示例:
编写一个脚本,验证这些运算符
[root@bd-offcn-01 myshell]# vi suanshu.sh
添加如下内容:
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi
运行展示:
[root@bd-offcn-01 myshell]# sh suanshu.sh
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a is not equal to b
注意:
乘号前边必须加反斜杠\才能实现乘法运算;
if...then...fi 是条件语句,后续将会讲解。
条件表达式要放在方括号之间,并且表达式两边要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 |
说明 |
举例 |
-eq |
等于则为真 |
[ 10 -eq 20 ] 返回false |
-ne |
不等于则为真 |
[ 10 -ne 20 ] 返回true |
-gt |
大于则为真 |
[ 10 -gt 20 ] 返回false |
-lt |
小于则为真 |
[ 10 -lt 20 ] 返回true |
-ge |
大于等于则为真 |
[ 10 -ge 20 ] 返回false |
-le |
小于等于则为真 |
[ 10 -le 20 ] 返回true |
示例:
编写一个脚本,验证这些运算符
[root@bd-offcn-01 myshell]# vim guanxi.sh
向脚本添加以下内容:
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a is equal to b"
else
echo "$a -eq $b: a is not equal to b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a is not equal to b"
else
echo "$a -ne $b : a is equal to b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a is greater than b"
else
echo "$a -gt $b: a is not greater than b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a is less than b"
else
echo "$a -lt $b: a is not less than b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a is greater or equal to b"
else
echo "$a -ge $b: a is not greater or equal to b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a is less or equal to b"
else
echo "$a -le $b: a is not less or equal to b"
fi
运行展示:
[root@bd-offcn-01 myshell]# sh guanxi.sh
10 -eq 20: a is not equal to b
10 -ne 20: a is not equal to b
10 -gt 20: a is not greater than b
10 -lt 20: a is less than b
10 -ge 20: a is not greater or equal to b
10 -le 20: a is less or equal to b
运算符 |
说明 |
举例 |
! |
非运算,表达式为true则返回false,否则返回true |
[ !false ] 返回true |
-a |
与运算,两个表达式都为true才返回true |
[ 10 -lt 100 -a 20 -gt 15 ] 返回true |
-o |
或运算,有一个表达式为true则返回true |
[10 -lt 100 -o 20 -gt 100 ] 返回true |
示例:
编写一个脚本,验证这些运算符
#!/bin/bash
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a is not equal to b"
else
echo "$a != $b: a is equal to b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a -lt 100 -a $b -gt 15 : returns true"
else
echo "$a -lt 100 -a $b -gt 15 : returns false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a -lt 100 -o $b -gt 100 : returns true"
else
echo "$a -lt 100 -o $b -gt 100 : returns false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a -lt 5 -o $b -gt 100 : returns true"
else
echo "$a -lt 5 -o $b -gt 100 : returns false"
fi
逻辑运算符主要用于判断要不要继续进行下一步,包括三个符号,分别是;,&&,||。
1、无条件继续执行符号,即分号;
在某些时候,我们希望一次执行多个命令,也就是说,执行完一条命令后,无条件的执行下一条命令。我们可以在指令与指令中间利用分号 ; 来隔开,这样一来,分号前的指令执行完后, 就会立刻接着执行后面的指令了。
示例:
编写脚本,先输出一句话,然后在输出一句话
[root@bd-offcn-01 myshell]# vim luoji1.sh
添加如下:
#!/bin/bash
echo "hello,";echo "world"
运行展示:
[root@bd-offcn-01 myshell]# sh luoji1.sh
hello,
world
2、正确则继续执行符号,即&&
有时候我们希望上一条命令执行正确才执行下一条命令。我们可以在指令与指令中间利用&&来隔开。
示例:
想要在某个目录底下建立一个文件,如果该目录存在的话, 那我才建立这个文件,如果不存在,就不创建。
编写脚本
[root@bd-offcn-01 myshell]# vim luoji2.sh
添加如下:
#!/bin/bash
ls /tmppp && touch /tmp/testingagin2
运行展示:
[root@bd-offcn-01 myshell]# sh luoji2.sh
3、错误则继续执行符号,即||
有时候我们希望上一条命令执行错误才执行下一条命令。我们可以在指令与指令中间利用 || 来隔开。
示例:
当某个文件不存在时,就去建立那个文件, 否则就略过。我们可以这样实现。
编写脚本
[root@bd-offcn-01 myshell]# vim luoji3.sh
添加如下:
#!/bin/bash
ls /tmp/testingagin3 || touch /tmp/testingagin3
运行展示:
[root@bd-offcn-01 myshell]# sh luoji3.sh
定义:
a="abc"
b="efg"
运算符 |
说明 |
举例 |
= |
检测两个字符串是否相等,相等返回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。 |
示例:
编写脚本
[root@bd-offcn-01 myshell]# vim str.sh
添加如下:
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a is equal to b"
else
echo "$a = $b: a is not equal to b"
fi
if [ $a != $b ]
then
echo "$a != $b : a is not equal to b"
else
echo "$a != $b: a is equal to b"
fi
if [ -z $a ]
then
echo "-z $a : string length is zero"
else
echo "-z $a : string length is not zero"
fi
if [ -n $a ]
then
echo "-n $a : string length is not zero"
else
echo "-n $a : string length is zero"
fi
if [ $a ]
then
echo "$a : string is not empty"
else
echo "$a : string is empty"
fi
定义file="/root/helloworld.sh",它是个大小为100字节的文件,具有 rwx 权限。
运算符 |
说明 |
举例 |
-d |
检测文件是否是目录,如果是,则返回true |
[ -d $file ]返回返回 false |
-f |
检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回true |
[ -f $file ]返回返回 true |
-r |
检测文件是否可读,如果是,则返回 true |
[ -r $file ] 返回返回 true |
-w |
检测文件是否可写,如果是,则返回true |
[ -w $file ] 返回返回 true |
-x |
检测文件是否可执行,如果是,则返回true |
[ -x $file ] 返回返回 true |
-s |
检测文件是否为空(文件大小是否大于0),不为空返回 true |
[ -s $file ] 返回返回 true |
-e |
检测文件(包括目录)是否存在,如果是,则返回true |
[ -e $file ] 返回返回 true |
示例:
编写脚本
[root@bd-offcn-01 myshell]# vim file.sh
添加如下:
#!/bin/bash
file="/root/helloworld.sh"
if [ -r $file ]
then
echo "File has read access"
else
echo "File does not have read access"
fi
if [ -w $file ]
then
echo "File has write permission"
else
echo "File does not have write permission"
fi
if [ -x $file ]
then
echo "File has execute permission"
else
echo "File does not have execute permission"
fi
if [ -f $file ]
then
echo "File is an ordinary file"
else
echo "This is sepcial file"
fi
if [ -d $file ]
then
echo "File is a directory"
else
echo "This is not a directory"
fi
if [ -s $file ]
then
echo "File size is not zero"
else
echo "File size is zero"
fi
if [ -e $file ]
then
echo "File exists"
else
echo "File does not exist"
fi
运行展示:
[root@bd-offcn-01 myshell]# sh file.sh
File has read access
File has write permission
File has execute permission
File is an ordinary file
This is not a directory
File size is not zero
File exists
格式: [ condition ]
示例:
1)23是否大于等于22
[ 23 -ge 22 ]
2)student.txt是否具有写权限
[ -w student.txt ]
3)/root/install.log目录中的文件是否存在
[ -e /root/install.log ]
test是shell环境中测试条件表达式的实用工具。
数值测试
编写脚本:
[root@bd-offcn-01 myshell]# vim test1.sh
添加如下内容:
#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
运行展示:
[root@bd-offcn-01 myshell]# sh test1.sh
两个数相等!
第一种: if ... fi 语句
语法:
if [ expression ]
then
Statement(s) to be executed if expression is true
fi
示例:
编写脚本:
[root@bd-offcn-01 myshell]# vim if1.sh
添加如下内容:
#!/bin/bash
a=10
b=10
if [ $a == $b ]
then
echo "a is equal to b"
fi
运行展示:
[root@bd-offcn-01 myshell]# sh if1.sh
a is equal to b
第二种: if ... else ... fi 语句
第三种: if ... elif ... fi 语句
类似于java中的switch case,语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
基本语法:
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
示例:
#!/bin/bash
case $1 in
"1")
echo "1"
;;
"2")
echo "2"
;;
*)
echo "other"
;;
esac
基本语法1:
for 变量 in 值1 值2 值3…
do
程序
done
基本语法2:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
示例:
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo "$s"
4、while循环
基本语法:
while [ 条件判断式 ]
do
程序
done
示例:
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
运行展示:
[root@bd-offcn-01 myshell]# sh while.sh
5050
5、until循环
until循环执行一系列命令直至条件为true时停止。until循环与while循环在处理方式上刚好相反。一般while循环优于until循环,但在某些时候,也只是极少数情况下,until循环更加有用。
语法:
until command
do
Statement(s) to be executed until command is true
done
command一般为条件表达式,如果返回值为false,则继续执行循环体内的语句,否则跳出循环。
示例:
使用 until 命令输出 0 - 4 的数字。
[root@bd-offcn-01 myshell]# vim until.sh
添加如下内容:
#!/bin/bash
a=0
until [ ! $a -lt 5 ]
do
echo $a
a=`expr $a + 1`
done
基本语法:
read(选项)(参数)
选项:
-p:指定读取值时的提示符
-t:指定读取值时等待的时间(秒)
参数
变量:指定读取值的变量名
示例:
读取控制台输入并打印
[root@bd-offcn-01 myshell]# vim read.sh
添加如下内容:
#!/bin/bash
read -t 7 -p "please input your name in 7 s" NAME
echo $NAME
运行展示:
[root@bd-offcn-01 myshell]# sh read.sh
please input your name in 7 stomcat
[root@bd-offcn-01 myshell]# tomcat
basename用于获取基本名称
格式:
basename [pathname] [suffix]
basename [string] [suffix] (功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
选项:
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
示例:
[root@bd-offcn-01 myshell]# basename /opt/test.txt
test.txt
[root@bd-offcn-01 myshell]# basename /opt/test.txt .txt
test
注意:该命令只是处理的字符串,不管文件是否存在
dirname基本语法
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
示例:
[root@bd-offcn-01 myshell]# dirname /opt/test.txt
/opt
注意:该命令只是处理的字符串,不管文件是否存在
基本语法:
[ function ] funname[()]
{
Action;
[return int;]
}
Funname
示例1:采用return返回结果
编写脚本,进行求和
[root@bd-offcn-01 myshell]# vim func1.sh
添加如下内容:
#!/bin/bash
function sum()
{
s=0
s=$[ $1 + $2 ]
return $s
}
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;
echo $?
结果说明:在定义函数时,函数return后的值只能是整形数值,采用$?来接收,其范围是[0,255],因此我们看到当输出的内容在此范围时,是没问题的,否则错误。一般该返回值是用来表示函数执行成功与否的,0表示成功,其他值表示失败。因而用函数返回值来返回函数执行结果是不合适的。
另外,如果返回值是个字符串,也会报错。
编写一个脚本,返回字符串测试:
[root@bd-offcn-01 myshell]# vim func11.sh
添加如下内容:
#!/bin/bash
function sum()
{
return "hello,world"
}
sum
echo $?
语法 |
功能描述 |
paste + [选项] + 参数 |
将多个文件按照列进行合并 选项: -d :指定多个列之间的间隔字符(默认制表符) -s :串列进行而非平行处理 |
(1)准备数据
[root@bd-offcn-01 test]# vim test1.txt
this is line 1
this is line 2
this is line 3
[root@bd-offcn-01 test]# vim test2.txt
this is line 1
my line 2
i love you
wa da xi wa
(2)需求1:分列按行合并test1.txt test2.txt
[root@bd-offcn-01 test]# paste test1.txt test2.txt | cat -A
this is line 1^Ithis is line 1$
this is line 2^Imy line 2$
this is line 3^Ii love you$
^Iwa da xi wa$
(3)需求2:指定分隔符,分列按行合并test1.txt test2.txt
[root@bd-offcn-01 test]# paste -d"|" test1.txt test2.txt| cat -A
this is line 1|this is line 1$
this is line 2|my line 2$
this is line 3|i love you$
|wa da xi wa$
(4)需求3: 列转行合并test1.txt test2.txt
[root@bd-offcn-01 test]# paste -s test1.txt test2.txt
this is line 1 this is line 2 this is line 3
this is line 1 my line 2 i love you wa da xi wa
语法 |
功能描述 |
命令|xargs + [选项] + 参数 |
是给命令传递参数的一个过滤器,也是组合多个命令的一个工具 选项: -n :按照分割符(默认空格)显示n列 -d :分隔符,默认分隔符是回车 |
(1)基本使用
[root@bd-offcn-01 test]# cat test1.txt
this is line 1
this is line 2
this is line 3
[root@bd-offcn-01 test]# cat test1.txt |xargs
this is line 1 this is line 2 this is line 3
[root@bd-offcn-01 test]# cat test1.txt | xargs -n2
this is
line 1
this is
line 2
this is
line 3
[root@bd-offcn-01 test]# echo "file1 file2 file3"|xargs -n2
file1 file2
file3
(2)需求1:按照test1.txt文件内容创建/删除文件
[root@bd-offcn-03 test]# cat test1.txt | xargs -n3 touch
[root@bd-offcn-03 test]# ll
total 8
-rw-r--r-- 1 root root 0 May 7 09:26 1
-rw-r--r-- 1 root root 0 May 7 09:26 2
-rw-r--r-- 1 root root 0 May 7 09:26 3
-rw-r--r-- 1 root root 0 May 7 09:26 is
-rw-r--r-- 1 root root 0 May 7 09:26 line
-rw-r--r-- 1 root root 45 Apr 28 20:38 test1.txt
-rw-r--r-- 1 root root 48 Apr 28 20:39 test2.txt
-rw-r--r-- 1 root root 0 May 7 09:26 this
(3)需求2:按照指定名称同时创建/删除多个目录
[root@bd-offcn-03 test]# echo "file1 file2 file3"|xargs mkdir
[root@bd-offcn-03 test]# ll
total 8
drwxr-xr-x 2 root root 6 May 7 09:29 file1
drwxr-xr-x 2 root root 6 May 7 09:29 file2
drwxr-xr-x 2 root root 6 May 7 09:29 file3
-rw-r--r-- 1 root root 45 Apr 28 20:38 test1.txt
-rw-r--r-- 1 root root 48 Apr 28 20:39 test2.txt
语法 |
功能描述 |
cut + [选项] + 参数 |
在文件中按行剪切指定的字节、字符和字段并将它们进行输出 选项: -c :按照字符选取内容 char -d :自定义分隔符 delimiter,默认\t,空格用-d” ”。 -f :分割以后显示第几段内容, 使用 , 分割 |
(1)需求1:截取出test1.txt文件中前2行的第2个字符
# 分析:截取出test1.txt文件中前2行
head -2 test1.txt
# 分析:截取出test1.txt文件中前2行第2个字符
head -2 test1.txt |cut -c 2
(2)需求2:截取出test1.txt文件中最后1行的is
tail -1 test1.txt|cut -d " " -f 2
语法 |
功能描述 |
sort + [选项] + 参数 |
可对文件内容进行排序,并将结果进行输出 选项: -c :检查文件是否已经按照顺序排序 -u :排序时去除重复行 -r :反序进行排序 -n :依照数值的大小排序 -t :指定间隔字符 -k :指定间隔字符后,用来指定列数 -o :指定输出位置 |
(1)准备数据
[root@bd-offcn-01 test]# vim test3.txt
11,zhangsan,16,male
21,lisi,9,male
1,wangwu,21,female
2,zhaoliu,20,female
3,luqi,18,male
3,luqi,18,male
2)需求1:查看文件是否有序
[root@bd-offcn-01 test]# sort -c test3.txt
sort:test3.txt:3:无序: 1,wangwu,21,female
(3)需求2:将文件自然排序
[root@bd-offcn-01 test]# sort test3.txt
11,zhangsan,16,male
1,wangwu,21,female
21,lisi,9,male
2,zhaoliu,20,female
3,luqi,18,male
3,luqi,18,male
(4)需求3:将文件自然排序并去重
[root@bd-offcn-01 test]# sort -u test3.txt
11,zhangsan,16,male
1,wangwu,21,female
21,lisi,9,male
2,zhaoliu,20,female
3,luqi,18,male
(5)需求4:将文件反序进行排序
[root@bd-offcn-01 test]# sort -r test3.txt
3,luqi,18,male
3,luqi,18,male
2,zhaoliu,20,female
21,lisi,9,male
1,wangwu,21,female
11,zhangsan,16,male
(6)需求5:将文件按照数字大小进行排序
[root@bd-offcn-01 test]# sort -n test3.txt
1,wangwu,21,female
2,zhaoliu,20,female
3,luqi,18,male
3,luqi,18,male
11,zhangsan,16,male
21,lisi,9,male
(7)需求6:将文件按照”,”进行分割,并按照年龄大小进行排序,并将结果保存
[root@bd-offcn-01 test]# sort -n -t, -k 3 test3.txt -o test4.txt
[root@bd-offcn-01 test]# cat test4.txt
21,lisi,9,male
11,zhangsan,16,male
3,luqi,18,male
3,luqi,18,male
2,zhaoliu,20,female
1,wangwu,21,female
语法 |
功能描述 |
wc + [选项] + 文件 |
计算文件的字节数、字数或是列数 选项: -l :计算文件的行数 -w:计算文件单词的个数 -c :计算文件的字节数 |
(1)基本使用:
[root@bd-offcn-01 test]# wc -c test3.txt
104 test3.txt
[root@bd-offcn-01 test]# wc -l test3.txt
6 test3.txt
[root@bd-offcn-01 test]# cat test3.txt |wc -c
104
[root@bd-offcn-01 test]# cat test3.txt |wc -l
6
(2)需求1:查看/etc目录下字内容的个数
[root@bd-offcn-01 test]# ll /etc/ | wc
200 1823 11585
[root@bd-offcn-01 test]# ls /etc/ | wc -w
199
基本语法:
语法 |
功能描述 |
uniq + [选项] + 文件 |
检查或忽略文件中重复出现的行列 选项: -c :显示各行重复出现的次数 -d :仅显示重复出现的行列 -u :仅显示出现一次的行列 |
案例:
(1)显示该行重复出现的次数
[root@bd-offcn-01 test]# uniq -c test4.txt
1 21,lisi,9,male
1 11,zhangsan,16,male
2 3,luqi,18,male
1 2,zhaoliu,20,female
1 1,wangwu,21,female
(2)仅显示重复出现的行列
[root@bd-offcn-01 test]# uniq -d test4.txt
3,luqi,18,male
(3)仅显示出现一次的行列
[root@bd-offcn-01 test]# uniq -u test4.txt
21,lisi,9,male
11,zhangsan,16,male
2,zhaoliu,20,female
1,wangwu,21,female
(4)将test3.txt文件按照年龄倒序并统计重复的行数
[root@bd-offcn-01 test]# sort -t, -k3nr test3.txt | uniq -c
1 1,wangwu,21,female
1 2,zhaoliu,20,female
2 3,luqi,18,male
1 11,zhangsan,16,male
1 21,lisi,9,male
语法 |
功能描述 |
tee + [选项] + 文件 |
把数据重定向写入文件并进行输出显示 选项: -a :append,追加写到文件中,默认覆盖写 |
命令|tee + [选项] + 文件 |
将命令结果写入文件,选项使用同上 |
(1)基本使用
[root@bd-offcn-01 test]# touch test5.txt
[root@bd-offcn-01 test]# tee test5.txt
hello #手动输入
hello #写入成功并打印
^C #Ctrl + c退出进程
[root@bd-offcn-01 test]# cat test5.txt
hello
[root@bd-offcn-01 test]# tee -a test5.txt
world
world
^C
[root@bd-offcn-01 test]# cat test5.txt
hello
world
(2)需求1:将test4.txt文件快速复制到其他多个文件
[root@bd-offcn-01 test]# cat test4.txt | tee a.txt b.txt c.txt
[root@bd-offcn-01 test]# ll
total 28
-rw-r--r-- 1 root root 104 May 7 14:16 a.txt
-rw-r--r-- 1 root root 104 May 7 14:16 b.txt
-rw-r--r-- 1 root root 104 May 7 14:16 c.txt
-rw-r--r-- 1 root root 45 Apr 28 20:38 test1.txt
-rw-r--r-- 1 root root 48 Apr 28 20:39 test2.txt
-rw-r--r-- 1 root root 104 May 7 13:09 test3.txt
-rw-r--r-- 1 root root 104 May 7 13:19 test4.txt
语法 |
功能描述 |
命令|tr + [选项] + 参数 |
将文件中的字符进行替换、删除 选项: -d :删除指定字符 -s :将连续字符缩减为单个字符 -c :反选指定的字符进行替换(包括空格、换行符等) |
[root@bd-offcn-01 test]# vim test5.txt
hello world 1
hello world 2
hello world 3
[root@bd-offcn-01 test]# cat test5.txt|tr 'hl' 'ab'
#h替换为a,l替换为b,而不是hl替换为ab
aebbo worbd 1
aebbo worbd 2
aebbo worbd 3
删除指定字符 l
[root@bd-offcn-01 test]# cat test5.txt|tr -d 'l'
heo word 1
heo word 2
heo word 3
将连续字符l去重
[root@bd-offcn-01 test]# cat test5.txt|tr -s 'l'
helo world 1
helo world 2
helo world 3
#将除l之外的所有字符进行替换为a,包括空格、回车等
[root@bd-offcn-01 test]# cat test5.txt|tr -c 'l' 'a'
aallaaaaalaaaaaallaaaaalaaaaaallaaaaalaaaa
语法 |
功能描述 |
split + [选项] + 文件 |
将一个文件按指定规则切割成多个文件 选项: -数字 :指定每多少行切成一个小文件 -b 数字 :指定每多少字节切成一个小文件 |
[root@bd-offcn-01 ~]# mkdir d1 && cd d1
[root@bd-offcn-01 d1]# vi test6.txt
hello world 1
hello world 2
hello world 3
[root@bd-offcn-01 d1]# split -2 test6.txt
[root@bd-offcn-01 d1]# ll
-rw-r--r-- 1 root root 43 May 7 14:21 test6.txt
-rw-r--r-- 1 root root 28 May 7 14:27 xaa
-rw-r--r-- 1 root root 15 May 7 14:27 xab
[root@bd-offcn-01 d1]# cat xaa
hello world 1
hello world 2
[root@bd-offcn-01 d1]# cat xab
hello world 3
[root@bd-offcn-01 d1]# rm -rf xa*
[root@bd-offcn-01 d1]# split -b 10 test5.txt
[root@bd-offcn-01 d2]# wc -c xaa
10 xaa
[root@bd-offcn-01 d2]# wc -c xab
10 xab
[root@bd-offcn-01 d2]# wc -c xad
10 xad
[root@bd-offcn-01 d2]# wc -c xae
2 xae
awk = cut + sed
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
awk [选项参数] 'pattern1{action1}pattern2{action2}...' filename
注意:必须单引号
pattern: 表示 AWK 在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列动作命令
选项参数说明
选项参数 |
功能 |
-F |
指定输入文件分隔符,默认分隔符为空格 |
-v |
赋值一个用户定义变量 |
(1)需求1:搜索/etc/passwd以root关键字开头的所有行,并输出该行的第7列
[root@bd-offcn-01 ~]# awk -F: '/^root/{print $7}' /etc/passwd
/bin/bash
说明:只有匹配了patter的行才会执行action
(2)需求2:只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user和shell,在最后一行添加"offcn,/bin/bash"。
[root@bd-offcn-01 ~]# awk -F: 'BEGIN{print"user,shell"} {print $1","$7} END{print "offcn,/bin/bash"}' /etc/passwd
说明:
BEGIN 大写在所有数据读取行之前执行;END大写 在所有数据执行之后执行。
(3)需求3:将/etc/passwd文件中的用户id增加指定数值并输出
[root@bd-offcn-01 ~]# awk -F: -va=1 '{print $3+a}' /etc/passwd
awk的内置变量
变量 |
说明 |
FILENAME |
文件名 |
NR |
已读的记录数 |
NF |
浏览记录的域(field)的个数 |
(4)需求4:统计/etc/passwd:文件名,每行的行号,每行的列数
[root@bd-offcn-01 ~]# awk -F: '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF}' /etc/passwd
(5)需求5:切割IP
[root@bd-offcn-01 ~]# ifconfig ens33 | grep "inet" | grep -v "inet6" | awk '{pri
是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。
先检查centos7中是否已经安装。
[root@bd-offcn-01 myshell]# which expect
/usr/bin/which: no expect in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
以上说明,未安装,执行以下命令,进行安装
[root@bd-offcn-01 myshell]# yum install -y expect
1.定义脚本执行的shell
#!/usr/bin/expect
这里定义expect可执行文件的路径,功能类似于bin/bash
2.设置超时间
set timeout 30
单位是秒,如果设置为-1将永不超时
3.传递交互指令:spawn
spawn是进入expect后的用于传递交互的命令,不可以单独使用在shell中
4.判断返回的交互指令
expect用于判断返回的交互提示中是否包含某些字符串,没有则立即返回,有则等待继续交互
5.执行提交的交互命令
send可以将要发送的指令输入进行发送,命令的结尾处必须交上/r,用于异常核查
6.保持交互状态
interact可以将交互后的状态控制权限交给控制台,不加则自动退出
7.继续执行接下来的交互操作
exp_continue继续执行接下来的交互操作
8.获取传入脚本参数
[ lindex $argv n ] 可以接受从脚本传来的参数,0代表第一个参数
需求1:使用expect实现免密登录
编写一个脚本
[root@bd-offcn-01 myshell]# vim expect_ssh.sh
添加如下内容:
#!/usr/bin/expect
spawn ssh root@bd-offcn-02
expect {
"yes/no" { send "yes\r";exp_continue }
"password" {send "hadoop\r"};
}
interact
给脚本加可执行权限
[root@bd-offcn-01 myshell]# chmod u+x expect_ssh.sh
运行展示:
[root@bd-offcn-01 myshell]# ./expect_ssh.sh
spawn ssh root@bd-offcn-02
root@bd-offcn-02's password:
Last login: Wed Feb 3 14:36:54 2021 from bd-offcn-01
[root@bd-offcn-02 ~]#
优化:
#!/usr/bin/expect
set ip 192.168.1.112
set pwd hadoop
set timeout 30
spawn ssh root@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "hadoop\r" }
}
interact
#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set pwd [ lindex $argv 1 ]
set timeout 30
spawn ssh root@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$pwd\r" }
}
interact
需求2:采用shell脚本实现expect,在远程主机创建目录
编写脚本:
[root@bd-offcn-01 myshell]# vim expect_dirs.sh
添加如下内容:
#!/bin/bash
>ip.txt
passwd='hadoop'
for i in {111..112}
do
{
ip=192.168.1.$i
ping -c1 -w1 $ip &>/dev/null
if [ $? -eq 0 ]
then
echo $ip >> ip.txt
/usr/bin/expect <<-EOF
spawn ssh $1@$ip mkdir ~/apps ~/datas ~/logs ~/software
expect {
"yes/no" { send "yes\r"; exp_continue }
"password" { send "$passwd\r" }
}
expect eof
EOF
fi
}&
done
加可执行权限
chmod u+x expect_dirs.sh
执行
sh expect_dirs.sh root
拓展需求:发送公钥
#!/bin/bash
>ip.txt
passwd='hadoop'
for i in {111..112}
do
{
ip=192.168.1.$i
ping -c1 -w1 $ip &>/dev/null
if [ $? -eq 0 ]
then
echo $ip >> ip.txt
#ssh $ip rm -rf /root/.ssh/* exit
/usr/bin/expect <<-EOF
spawn ssh-copy-id $ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password" { send "$passwd\r" }
}
expect eof
EOF
fi
}&
done