Linux-总结(一):Shell编程

一、Shell概述

Shell:是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。
shell: 一个可以解释shell规定的语法命令的解释器!解释器负责将应用程序发送的指令,进行检查,合法后交给内核解释执行!返回结果!
shell命令: shell解释器要求的指定语法编写的命令!
shell脚本: 多条shell命令,可以编写在一个文件中,文件中的指令,可以按照顺序执行!将这个文件称为shell脚本!

在这里插入图片描述
Linux系统的核心是内核。内核控制着计算机系统上的所有硬件和软件,在必要时为应用程序分配硬件, 并根据需要执行程序中的代码。
内核主要负责以下四种功能:

  1. 系统内存管理
  2. 软件程序管理
  3. 硬件设备管理
  4. 文件系统管理

简单来说Shell是一种特殊的交互式工具,核心是命令提示符,允许输入文本命令,解释命令,并在内核中执行命令。为了防止程序发送一些恶意指令导致损坏内核,在内核和应用程序接口之间,设置一个中间层,称为shell。

1. linux中一切皆文件

service network restart”命令的含义:运行service文件,参数为:network、restart。

[root@localhost ~]$ which service
/usr/sbin/service

2. linux中常用目录

目录作用备注
/bin是Binary的缩写, 这个目录存放着最经常使用的命令 :cd、echo、pwd等存放的是普通用户用的命令
/boot这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件,自己的安装别放这里。
/dev类似于windows的设备管理器,把所有的硬件用文件的形式存储。
/etc所有的系统管理所需要的配置文件和子目录。
/home存放普通用户的主目录,在Linux中每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。
/lib系统开机所需要最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。
/medialinux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。
/mnt系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将外部的存储挂载在/mnt/上,然后进入该目录就可以查看里的内容了。
/opt这是给主机额外安装软件所摆放的目录。比如你安装一个mysql数据库则就可以放到这个目录下。默认是空的。
/proc这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
/root该目录为系统管理员,也称作超级权限者的用户主目录。
/sbins就是Super User的意思,这里存放的是系统管理员使用的系统管理程序(root用户(管理员)使用的常用命令),
对整个机器的管理命令!比如:service network start
[root@localhost ~]$ which service /usr/sbin/service
/srvservice缩写,该目录存放一些服务启动之后需要提取的数据。
/sys这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。
/tmp这个目录是用来存放一些临时文件的。
/usr这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。
/var这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
/lost+found这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。
/selinuxSELinux是一种安全子系统,它能控制程序只能访问特定文件。

3. linux的环境变量

[root@localhost ~]$ hahawhx
bash: hahawhx: command not found...

表明当前命令“hahawhx”不在当前用户的环境变量!
查看环境变量: echo $PATH

[root@localhost ~]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
Linux中多个环境变量之间用冒号间隔(Windows中是用分号)。

由于bin目录的路径以及sbin目录的路径都在Linux的环境变量里,所以在使用bin目录或sbin目录下的命令(命令即文件)时,就不用在命令的前面加上bin目录或sbin目录的绝对路径了

二、Shell解释器

1. Shell解析器种类

Linux提供的Shell解析器有以下几种(linux是开源的,不同的人写了不同风格的解释器):

  • /bin/sh
  • /bin/bash
  • /sbin/nologin
  • /bin/dash
  • /bin/tcsh
  • /bin/csh
[root@localhost ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

不同的shell解析器,功能不同,比如csh,符合c语言风格的shell解析器。Centos默认使用的是“/bin/bash”和“/bin/sh”作为shell解析器。“/bin/sh”是“/bin/bash”的软连接,两者等价。

2. 查看当前解释器

通过“echo $SHELL”命令查看当前解释器

[root@localhost ~]$ echo $SHELL
/bin/bash

在终端中输入:cat /etc/shells等价于:/bin/bash -c 'cat /etc/shells’

默认/bin/bash必须接收一个脚本作为输入!如果是一条命令,需要加-c (command)
[root@localhost ~]$ /bin/bash -c 'cat /etc/shells'
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

3. Shell脚本的编写要求

  1. 声明解释器: #!/bin/bash
  2. 正文: 必须是shell解释器能解释的命令
[root@localhost /]$ cd home
[root@localhost home]$ ls
whx
[root@localhost home]$ cd whx
[root@localhost whx]$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos
[root@localhost whx]$ mkdir myshells
[root@localhost whx]$ ll
total 0
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Desktop
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Documents
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Downloads
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Music
drwxr-xr-x. 2 root root 6 Oct 28 22:13 myshells
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Pictures
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Public
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Templates
drwxr-xr-x. 2 whx  whx  6 Aug 13 05:01 Videos
[root@localhost whx]$ cd myshells
[root@localhost myshells]$ ll
total 0
[root@localhost myshells]$ vim first.sh
[root@localhost myshells]$ ll
total 4
-rw-r--r--. 1 root root 51 Oct 28 22:15 first.sh
[root@localhost myshells]$ bash first.sh
这是shell脚本文件first.sh
[root@localhost myshells]$ sh first.sh
这是shell脚本文件first.sh

first.sh文件内容为:

#!/bin/bash
echo 'first.sh脚本文件执行完毕'

second.sh文件内容为:

#!/bin/bash
b='这是second.sh'
sleep 10s
echo $b
echo 'second.sh脚本文件执行完毕'

third.sh文件内容为:

#!/bin/bash
echo $b
echo 'third.sh脚本文件执行完毕'

虽然linux系统的文件不需要用后缀,但是一般用后缀.sh表明该文件是一个shell脚本文件,方便识别。

4. Shell脚本的执行方式

  1. bash 脚本sh 脚本
[root@localhost myshells]$ bash first.sh
这是shell脚本文件first.sh
[root@localhost myshells]$
特点: 
	①新开一个bash执行脚本;
	②一旦脚本执行完毕,bash自动关闭!

使用pstree查看进程

        ├─sshd─┬─sshd───bash───bash───sleep
        │      └─sshd───bash───pstree
  1. ./脚本

    特点:
    ①前提是当前用户对脚本有执行权限,使用当前默认的解释器执行脚本;
    ②新开一个bash执行脚本;
    ③一旦脚本执行完毕,bash自动关闭!
    添加权限:chmod u+x first.sh
    删除权限:chmod u-x first.sh

[root@localhost myshells]$ ll
total 4
-rw-r--r--. 1 root root 51 Oct 28 22:15 first.sh
[root@localhost myshells]$ ./first.sh
-bash: ./first.sh: Permission denied
[root@localhost myshells]$ chmod u+x first.sh
[root@localhost myshells]$ ll
total 4
-rwxr--r--. 1 root root 51 Oct 28 22:15 first.sh
[root@localhost myshells]$ ./first.sh
这是shell脚本文件first.sh
[root@localhost myshells]$ 

使用pstree查看进程

        ├─sshd─┬─sshd───bash───second.sh───sleep
        │      └─sshd───bash───pstree
  1. . 脚本
[root@localhost myshells]$ . first.sh
这是shell脚本文件first.sh
[root@localhost myshells]$ 
特点: 
	①使用当前默认的解释器执行脚本,并不要求当前用户对脚本有执行权限;
	②使用当前默认的解释器执行脚本

使用pstree查看进程

├─sshd─┬─sshd───bash───sleep
│      └─sshd───bash───pstree
  1. source 脚本
[root@localhost myshells]$ source first.sh
这是shell脚本文件first.sh
[root@localhost myshells]$ 
特点: 
	①使用当前默认的解释器执行脚本,并不要求当前用户对脚本有执行权限;	
	②使用当前默认的解释器执行脚本

使用pstree查看进程

├─sshd─┬─sshd───bash───sleep
│      └─sshd───bash───pstree

三、Shell变量

3.1 系统变量

$HOME、$PWD、$SHELL、$USER等
查看系统变量的值

[root@localhost ~]$ echo $HOME
/root
[root@localhost ~]$ 

3.2 自定义变量

3.2.1 基本语法
  1. 定义变量:变量=值
  2. 撤销变量:unset 变量
  3. 声明静态变量:readonly变量,注意:不能unset
3.2.2 自定义变量规则
  1. 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
  2. 等号两侧不能有空格
  3. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
  4. 变量的值如果有空格,需要使用双引号或单引号括起来。
  5. 使用双引号,可以识别空格之外的其他变量,使用单引号则会只会忽略空格!
  6. 使用反引号,可以将语句运行的结果作为值赋值给变量!
3.2.3 自定义变量例子
  1. 定义变量A
[root@localhost ~]$ A=5
[root@localhost ~]$ echo $A
5
  1. 给变量A重新赋值
[root@localhost ~]$ A=8
[root@localhost ~]$ echo $A
8
  1. 撤销变量A
[root@localhost ~]$ unset A
[root@localhost ~]$ echo $A
[root@localhost ~]$
  1. 声明静态的变量B=2,不能unset
[root@localhost ~]$ readonly B=2
[root@localhost ~]$ echo $B
2
[root@localhost ~]$ B=9
-bash: B: readonly variable
  1. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
[atguigu@hadoop102 ~]$ C=1+2
[atguigu@hadoop102 ~]$ echo $C
1+2
  1. 变量的值如果有空格,需要使用双引号或单引号括起来,无需注意数据的类型
[atguigu@hadoop102 ~]$ D=I love banzhang
-bash: world: command not found
[atguigu@hadoop102 ~]$ D="I love banzhang"
[atguigu@hadoop102 ~]$ echo $A
I love banzhang
  1. 使用双引号可以识别变量
[root@0725pc shells]$ echo $A
hello
[root@0725pc shells]$ B="hello $A"
[root@0725pc shells]$ echo $B
hello hello
[root@0725pc shells]$ C='hello $A'
[root@0725pc shells]$ echo $C
hello $A
  1. 使用反引号,将命令运行的结果赋值给参数,即A=ll 等同于 A=$(ll)
[root@0725pc shells]$ D=`ll`
[root@0725pc shells]$ echo $D
总用量 4 -rwxr--r--. 1 root root 23 10月 8 21:36 test1.sh
[root@0725pc shells]$ E=$(ll)
[root@0725pc shells]$ echo $E
总用量 4 -rwxr--r--. 1 root root 23 10月 8 21:36 test1.sh
  1. 可把变量提升为全局环境变量,可供其他Shell程序使用
    export 变量名
[root@localhost ~]$ vim helloworld.sh 

在helloworld.sh文件中增加echo $B
#!/bin/bash

echo "helloworld"
echo $B

[root@localhost ~]$ ./helloworld.sh 
Helloworld
发现并没有打印输出变量B的值。
[root@localhost ~]$ export B
[root@localhost ~]$ ./helloworld.sh 
helloworld
每次修改 /etc/profile时,我们会执行source /etc/profile,source的作用就是执行文件中所有的export命令!

3.3 特殊变量

3.3.1 $n
  1. 基本语法
    $n(功能描述:n为数字,$0代表该脚本名称,$1- 9 代 表 第 一 到 第 九 个 参 数 , 十 以 上 的 参 数 , 十 以 上 的 参 数 需 要 用 大 括 号 包 含 , 如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9{10})
  2. 案例实操:输出该脚本文件名称、输入参数1和输入参数2 的值
[atguigu@hadoop101 datas]$ touch parameter.sh 
[atguigu@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"

[atguigu@hadoop101 datas]$ chmod 777 parameter.sh

[atguigu@hadoop101 datas]$ ./parameter.sh cls  xz
./parameter.sh  cls   xz
3.3.2 $#
  1. 基本语法
    $# (功能描述:获取所有输入参数个数,常用于循环)。
  2. 案例实操:获取输入参数的个数
[atguigu@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#

[atguigu@hadoop101 datas]$ chmod 777 parameter.sh

[atguigu@hadoop101 datas]$ ./parameter.sh cls  xz
parameter.sh cls xz 
2
3.3.3 ∗ 、 *、 @
  1. 基本语法
    ∗ ( 功 能 描 述 : 这 个 变 量 代 表 命 令 行 中 所 有 的 参 数 , * (功能描述:这个变量代表命令行中所有的参数, *把所有的参数看成一个整体)
    @ ( 功 能 描 述 : 这 个 变 量 也 代 表 命 令 行 中 所 有 的 参 数 , 不 过 @ (功能描述:这个变量也代表命令行中所有的参数,不过 @@把每个参数区分对待)
  2. 案例实操:打印输入的所有参数
[atguigu@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
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
3.3.4 $?
  1. 基本语法
    $? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
  2. 案例实操:判断helloworld.sh脚本是否正确执行
[atguigu@hadoop101 datas]$ ./helloworld.sh 
hello world
[atguigu@hadoop101 datas]$ echo $?
0

四、Shell运算符

4.1 基本语法

  1. “$((运算式))” 或 “$[运算式]”
  2. expr + , - , *, /, % 加,减,乘,除,取余
    注意:
    expr运算符间要有空格;
    *号需要转义为*,否则会被视为通配符;
    运算指的都是整数的运算,浮点运算需要借助其他的命令!

4.2 运算符案例

  1. 计算3+2的值
[atguigu@hadoop101 datas]$ expr 2 + 3
5
  1. 计算3-2的值
[atguigu@hadoop101 datas]$ expr 3 - 2 
1
  1. 计算(2+3)×4的值
    (a)expr一步完成计算
[atguigu@hadoop101 datas]$ expr `expr 2 + 3` \* 4
20
(b)采用$[运算式]方式
[atguigu@hadoop101 datas]$ S=$[(2+3)*4]
[atguigu@hadoop101 datas]$ echo $S

五、Shell条件判断

5.1 基本语法

[ condition ](注意condition前后要有空格)

注意:条件非空即为true,[ atguigu ]返回true,[] 返回false。

5.2 常用判断条件

  1. 两个整数之间比较
符号作用
=字符串比较(等号两侧要加空格)
-lt小于(less than)
-le小于等于(less equal)
-eq等于(equal)
-gt大于(greater than)
-ge大于等于(greater equal)
-ne不等于(Not equal)
  1. 按照文件权限进行判断
符号作用
-r有读的权限(read)
-w有写的权限(write)
-x有执行的权限(execute)
  1. 按照文件类型进行判断
符号作用
-f文件存在并且是一个常规的文件(file)
-e文件存在(existence)
-d文件存在并是一个目录(directory)
-s文件存在且不为空
-L文件存在且是一个链接(link)

5.3 常用判断条件案例实操

  1. 23是否大于等于22
[atguigu@hadoop101 datas]$ [ 23 -ge 22 ]
[atguigu@hadoop101 datas]$ echo $?
0
  1. helloworld.sh是否具有写权限
[atguigu@hadoop101 datas]$ [ -w helloworld.sh ]
[atguigu@hadoop101 datas]$ echo $?
0
  1. /home/atguigu/cls.txt目录中的文件是否存在
[atguigu@hadoop101 datas]$ [ -e /home/atguigu/cls.txt ]
[atguigu@hadoop101 datas]$ echo $?
1
  1. 多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
[atguigu@hadoop101 ~]$ [ condition ] && echo OK || echo notok
OK
[atguigu@hadoop101 datas]$ [ condition ] && [ ] || echo notok
notok

六、Shell流程控制

6.1 if 判断

  1. 基本语法
if [ 条件判断式 ] 
then 
	程序 
elif 条件判断式
	then 程序..
else 程序..
fi
if [ 条件判断式 ] ; then 
程序.. 
elif [条件判断式] ; then 
程序..
else 程序
fi
	注意事项:
	(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
	(2)if后要有空格
  1. 案例实操:如果输入的数字是1,2,3则输出你输入的数字是xx,否则输出,你输入的数字不是1,2,3
[root@0725pc shells]$ cat test3.sh 
#! /bin/bash
if [ $1 -eq 1 ]
then
    echo "你输入的是1啊!"
elif [ $1 -eq 2 ]
then
	 echo "你输入的是2啊!"
elif [ $1 -eq 3 ]
then
         echo "你输入的是3啊!"
else  echo "你输入的不是1,2,3啊!"
fi

[root@0725pc shells]$ bash test3.sh 3
你输入的是3啊!
[root@0725pc shells]$ bash test3.sh 2
你输入的是2啊!
[root@0725pc shells]$ bash test3.sh 1
你输入的是1啊!
[root@0725pc shells]$ bash test3.sh 4
你输入的不是1,2,3啊!

6.2 case 语句

  1. 基本语法
case $变量名 in 
 "值1") 
   如果变量的值等于值1,则执行程序1 
   ;; 
 "值2") 
   如果变量的值等于值2,则执行程序2 
   ;; 
 …省略其他分支… 
 *) 
   如果变量的值都不是以上的值,则执行此程序 
   ;; 
esac
注意事项:
1)	case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
2)	双分号“;;”表示命令序列结束,相当于java中的break。
3)	最后的“*)”表示默认模式,相当于java中的default。
  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

6.3 for 循环

6.3.1 基本语法1
for (( 初始值;循环控制条件;变量变化 )) 
do 
    程序 
done

for (( 初始值;循环控制条件;变量变化 )); do 程序; done

案例实操:从1加到100

[atguigu@hadoop101 datas]$ touch for1.sh
[atguigu@hadoop101 datas]$ vim for1.sh

#!/bin/bash

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”

[root@0725pc shells]$ tail -n 4 test1.sh 
SUM2=0
for((i=0;i<=10;i++));do SUM2=$(($SUM2+$i)); done
echo "从1加到100的值是:$SUM2"
[root@0725pc shells]$ ./test1.sh 
从1加到100的值是:55
6.3.2 基本语法2
for 变量 in 值1 值2 值3… 
 do 
    程序 
 done

for 变量 in 1 2 3; do 程序; done

for 变量 in {1..3}; do 程序; done

案例实操:打印所有输入参数

[atguigu@hadoop101 datas]$ touch for2.sh
[atguigu@hadoop101 datas]$ vim for2.sh

#!/bin/bash
#打印数字

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

多种写法

[root@0725pc shells]$ cat test2.sh 
#! /bin/bash
for i in 1 2 3
do 
	echo $i
done
echo "--------------------"
for i in 1 2 3 ;do echo $i;done
echo "--------------------"
for i in {1..3};do echo $i;done
[root@0725pc shells]$ ./test2.sh 
1
2
3
--------------------
1
2
3
--------------------
1
2
3

比较 ∗ 和 *和 @区别

  1. ∗ 和 *和 @都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 2 … 2 … 2n的形式输出所有参数。
[atguigu@hadoop101 datas]$ touch for.sh
[atguigu@hadoop101 datas]$ vim for.sh

#!/bin/bash 

for i in $*
do
      echo "ban zhang love $i "
done

for j in $@
do      
        echo "ban zhang love $j"
done

[atguigu@hadoop101 datas]$ bash for.sh cls xz bd
ban zhang love cls 
ban zhang love xz 
ban zhang love bd 
ban zhang love cls
ban zhang love xz
ban zhang love bd
  1. 当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 2 … 2 … 2n”的形式输出所有参数;“$@”会将各个参数分开,以“$1” “ 2 ” … ” 2”…” 2n”的形式输出所有参数。
[atguigu@hadoop101 datas]$ vim for.sh

#!/bin/bash 

for i in "$*" 
#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次 
        do 
                echo "ban zhang love $i"
        done 

for j in "$@" 
#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次 
        do 
                echo "ban zhang love $j" 
done

[atguigu@hadoop101 datas]$ chmod 777 for.sh
[atguigu@hadoop101 datas]$ bash for.sh cls xz bd
ban zhang love cls xz bd
ban zhang love cls
ban zhang love xz
ban zhang love bd

6.4 while 循环

6.4.1 基本语法
while [ 条件判断式 ] 
  do 
    程序
  donewhile((表达式))
do
	程序
done
6.4.2 案例实操
  1. 从1加到100
[atguigu@hadoop101 datas]$ touch while.sh
[atguigu@hadoop101 datas]$ vim while.sh

#!/bin/bash
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
  1. 从0开始,累加加11次
[root@0725pc shells]$ bash test3.sh 
11
[root@0725pc shells]$ cat test3.sh 
#! /bin/bash

NUM=0
while((NUM<=10));do let NUM++; done
echo $NUM

七、read读取控制台输入

6.1 基本语法

read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名

6.2 案例实操

提示7秒内,读取控制台输入的名称

[atguigu@hadoop101 datas]$ touch read.sh
[atguigu@hadoop101 datas]$ vim read.sh

#!/bin/bash

read -t 7 -p "Enter your name in 7 seconds " NAME
echo $NAME

[atguigu@hadoop101 datas]$ ./read.sh 
Enter your name in 7 seconds xiaoze
xiaoze

八、函数

8.1 系统函数

8.1.1 basename
  1. 基本语法

    basename [string / pathname] [suffix]
    选项:suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

  2. 功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。

  3. 案例实操:截取该/home/atguigu/banzhang.txt路径的文件名称

[atguigu@hadoop101 datas]$ basename /home/atguigu/banzhang.txt 
banzhang.txt
[atguigu@hadoop101 datas]$ basename /home/atguigu/banzhang.txt .txt
banzhang
8.1.2 dirname
  1. 基本语法

    dirname 文件绝对路径

  2. 功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

  3. 案例实操:获取banzhang.txt文件的路径

[atguigu@hadoop101 ~]$ dirname /home/atguigu/banzhang.txt 
/home/atguigu

8.2 自定义函数

  1. 基本语法
function  funname[()]
{
	Action;
	[return int;]
}
funname
  1. 经验技巧

    • 必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
    • 函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
  2. 案例实操:计算两个输入参数的和

[atguigu@hadoop101 datas]$ touch fun.sh
[atguigu@hadoop101 datas]$ vim fun.sh

#!/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;

[atguigu@hadoop101 datas]$ chmod 777 fun.sh
[atguigu@hadoop101 datas]$ ./fun.sh 
Please input the number1: 2
Please input the number2: 5
7

九、Shell工具

9.1 wc

wc命令:用来计算数字。利用wc指令我们可以计算文件的Byte数、字数或是列数,若不指定文件名称,或是所给予的文件名为“-”,则wc指令会从标准输入设备读取数据。

9.1.1 基本用法

cut [选项参数] filename
说明:默认分隔符是制表符

9.1.2 选项参数说明
选项参数功能
-ff为fileds,列号,提取第几列
-dd为Descriptor分隔符,按照指定分隔符分割列
9.1.3 案例实操
  1. 以:为间隔,切割PATH环境变量的第一列
[root@0725pc ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/jdk1.8.0_121/bin:/root/bin
[root@0725pc ~]$ echo $PATH | cut -d ':' -f 1
/usr/lib64/qt-3.3/bin
  1. 以:为间隔,切割PATH环境变量的第二、三列
[root@0725pc ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/jdk1.8.0_121/bin:/root/bin
[root@0725pc ~]$ echo $PATH | cut -d ':' -f 2,3
/usr/local/sbin:/usr/local/bin
  1. 选取系统PATH变量值,第2个“:”开始后的所有路径:
[atguigu@hadoop101 datas]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin

[atguigu@hadoop102 datas]$ echo $PATH | cut -d: -f 3-
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin
  1. 以:为间隔,切割PATH环境变量的第一到三列,和第五列
[root@0725pc ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/jdk1.8.0_121/bin:/root/bin
[root@0725pc ~]$ echo $PATH | cut -d ':' -f 1-3,5
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/bin
  1. 切割ifconfig 后打印的IP地址
[atguigu@hadoop101 datas]$ ifconfig eth0 | grep "inet addr" | cut -d: -f 2 | cut -d" " -f1
192.168.1.102

9.2 sed

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

9.2.1 基本用法

sed [选项参数] ‘command’ filename

9.2.2 选项参数说明
选项参数功能
-e直接在指令列模式上进行sed的动作编辑
9.2.3 命令功能描述
命令功能描述
a新增,a的后面可以接字串,在下一行出现
d删除
s查找并替换
9.2.4 案例实操
  1. 数据准备
[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第二行下,打印。
[atguigu@hadoop102 datas]$ sed '2a mei nv' sed.txt 
dong shen
guan zhen
mei nv
wo  wo
lai  lai

le  le
[atguigu@hadoop102 datas]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le
注意:文件并没有改变
  1. 删除sed.txt文件所有包含wo的行
[atguigu@hadoop102 datas]$ sed '/wo/d' sed.txt
dong shen
guan zhen
lai  lai

le  le
  1. 删除sed.txt文件第二行
[root@0725pc ~]$ cat sed.txt
dong shen
guan zhen
wo  wo
lai  lai

le  le

[root@0725pc ~]$ sed '2d' sed.txt 
dong shen
wo  wo
lai  lai

le  le
  1. 删除sed.txt文件最后一行
[root@0725pc ~]$ sed '$d' sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le
  1. 删除sed.txt文件第二行至最后一行
[root@0725pc ~]$ sed '2,$d' sed.txt 
dong shen
  1. 将sed.txt文件中wo替换为ni
[atguigu@hadoop102 datas]$ sed 's/wo/ni/g' sed.txt 
dong shen
guan zhen
ni  ni
lai  lai

le  le
注意:‘g’表示global,全部替换,不加g只会替换第一个匹配到的字符。
  1. 将sed.txt文件中的第二行删除并将wo替换为ni,
[atguigu@hadoop102 datas]$ sed -e '2d' -e 's/wo/ni/g' sed.txt 
dong shen
ni  ni
lai  lai

le  le

9.3 awk

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

9.3.1 基本用法

awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令

9.3.2 选项参数说明
选项参数功能
-F指定输入文件折分隔符
-v赋值一个用户定义变量
9.3.3 案例实操
  1. 数据准备
[atguigu@hadoop102 datas]$ sudo cp /etc/passwd ./
  1. 搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
[atguigu@hadoop102 datas]$ awk -F: '/^root/{print $7}' passwd 
/bin/bash
  1. 搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
[atguigu@hadoop102 datas]$ awk -F: '/^root/{print $1","$7}' passwd 
root,/bin/bash

注意:只有匹配了patter的行才会执行action

  1. 只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"dahaige,/bin/zuishuai"。
[atguigu@hadoop102 datas]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd
user, shell
root,/bin/bash
bin,/sbin/nologin
。。。
atguigu,/bin/bash
dahaige,/bin/zuishuai

注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。

  1. 将passwd文件中的用户id增加数值1并输出
[atguigu@hadoop102 datas]$ awk -v i=1 -F: '{print $3+i}' passwd
1
2
3
4
9.3.4 awk的内置变量
变量说明
FILENAME文件名
NR已读的记录数(行号)
NF浏览记录的域的个数(切割后列的个数)

案例实操

  1. 统计passwd文件名,每行的行号,每行的列数
[atguigu@hadoop102 datas]$ awk -F: '{print "filename:"  FILENAME ", linenumber:" NR  ",columns:" NF}' passwd 
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
  1. 切割IP
[atguigu@hadoop102 datas]$ ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}' 
192.168.1.102
  1. 查询sed.txt中空行所在的行号
[atguigu@hadoop102 datas]$ awk '/^$/{print NR}' sed.txt 
5

9.4 sort

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。默认情况以第一个字符串的字典顺序来排序!

  1. 基本语法
    sort(选项)(参数)
选项说明
-n依照数值的大小排序
-r以相反的顺序来排序
-t设置排序时所用的分隔字符,默认使用TAB
-k指定需要排序的列
-uu为unique的缩写,即如果出现相同的数据,只出现一行
参数:指定待排序的文件列表
  1. 案例实操:按照“:”分割后的第三列倒序排序。
[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
[atguigu@hadoop102 datas]$ sort -t : -nrk 3  sort.sh 
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页