day32~33 shell编程以及Linux高级命令

课程大纲

 

课程内容

学习效果

掌握目标

Linux基础

Shell编程

掌握

Linux高级命令

掌握

六、shell编程

(一)概述

Shell 是一个用 C 语言编写的程序,能解释我们给它的命令并执行,是用户使用 Linux 的桥梁。所以Shell 既是一个命令解释器,又是一种程序设计语言。

Shell 脚本(shell script),是一种为 shell 编写,让shell解析并执行的脚本程序。

"shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身,我们进行shell编程就是将之前学过的好多命令放到一个文件里面,然后交给shell解释并执行,从而完成一个小功能。

day32~33 shell编程以及Linux高级命令_第1张图片

 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

(二)shell的编写和执行

脚本格式

脚本以  #!/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、定义变量

(1)基本语法:

  1. 定义变量:变量=值
  2. 撤销变量:unset 变量
  3. 声明静态变量:readonly变量,注意:不能unset

(2)变量定义规则

  1. 变量名称可以由字母、数字和下划线组成,但是不能以数字开头
  2. 等号两侧不能有空格。
  3. 变量名称一般习惯为大写。

(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 变量名  

2、将命令的返回值赋给变量

    (1)A=`ls -la` 反引号,运行里面的命令,并把结果返回给变量A

day32~33 shell编程以及Linux高级命令_第2张图片

     (2)A=$(ls -la) 等价于反引号

3、设置环境变量

(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

4、位置参数变量

(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

5、预定义变量

(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程序中的操作默认都是字符串操作,要想进行数学运算,可以采用以下几种方式。

  1. $((运算式))”或“$[运算式]
  2. expr
  3. let表达式

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 ]。

3、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

运算符

说明

举例

-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

4、布尔运算符

运算符

说明

举例

非运算,表达式为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

5、逻辑运算符

逻辑运算符主要用于判断要不要继续进行下一步,包括三个符号,分别是;&&||

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

6、字符串运算符

定义:

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

7、文件测试运算符定义:

定义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

(五)条件判断方式

1、[]

格式: [ condition ]

示例:

1)23是否大于等于22

[ 23 -ge 22 ]

2)student.txt是否具有写权限

[ -w student.txt ]

3)/root/install.log目录中的文件是否存在

[ -e /root/install.log ]

2、test

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 
两个数相等!

(六)流程控制语句

1、if判断

第一种: 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 语句

2、case语句

类似于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

3、for循环

基本语法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

基本语法:

    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

(八)函数

1、系统函数

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

注意:该命令只是处理的字符串,不管文件是否存在

2、自定义函数

基本语法:

[ 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

1、基本语法:

语法

功能描述

paste + [选项] + 参数

将多个文件按照列进行合并

选项:

-d 指定多个列之间的间隔字符(默认制表符)

-s 串列进行而非平行处理

2、案例:

(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

1、基本语法:

语法

功能描述

命令|xargs + [选项] + 参数

是给命令传递参数的一个过滤器,也是组合多个命令的一个工具

选项:

-n 按照分割符(默认空格)显示n列

-d 分隔符,默认分隔符是回车

2、案例:

(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

1、基本语法:

语法

功能描述

cut + [选项] + 参数

在文件中按行剪切指定的字节、字符和字段并将它们进行输出

选项:

-c 按照字符选取内容 char

-d 自定义分隔符 delimiter,默认\t,空格用-d

-f 分割以后显示第几段内容, 使用 , 分割

2、案例:

(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

1、基本语法:

语法

功能描述

sort + [选项] + 参数

可对文件内容进行排序,并将结果进行输出

选项:

-c 检查文件是否已经按照顺序排序

-u 排序时去除重复行

-r 反序进行排序

-n 依照数值的大小排序

-t 指定间隔字符

-k 指定间隔字符后,用来指定列数

-o 指定输出位置

   2、案例:

(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

1、基本语法:

语法

功能描述

wc + [选项] + 文件

计算文件的字节数、字数或是列数

选项:

-l 计算文件的行数

-w:计算文件单词的个数

-c 计算文件的字节数

   2、案例:

(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

基本语法:

语法

功能描述

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

1、基本语法:

语法

功能描述

tee + [选项] + 文件

把数据重定向写入文件并进行输出显示

选项:

-a append追加写到文件中,默认覆盖写

命令|tee + [选项] + 文件

将命令结果写入文件,选项使用同上

   2、案例:

(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

1、基本语法:

语法

功能描述

命令|tr + [选项] + 参数

将文件中的字符进行替换、删除

选项:

-d 删除指定字符

-s 将连续字符缩减为单个字符

-c 反选指定的字符进行替换(包括空格、换行符等)

2、案例:

[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

1、基本语法:

语法

功能描述

split + [选项] + 文件

将一个文件按指定规则切割成多个文件

选项:

-数字 :指定每多少行切成一个小文件

-b 数字 :指定每多少字节切成一个小文件

2、案例:

[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

awk = cut + sed

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

1、基本用法

awk  [选项参数] 'pattern1{action1}pattern2{action2}...' filename

注意:必须单引号

pattern表示 AWK 在数据中查找的内容,就是匹配模式

action在找到匹配内容时所执行的一系列动作命令

选项参数说明

选项参数

功能

-F

指定输入文件分隔符,默认分隔符为空格

-v

赋值一个用户定义变量

2、案例:

(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

(十二)expect

是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。

1、安装

先检查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

2、使用

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代表第一个参数

3、案例:

需求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

你可能感兴趣的:(#,linux)