转自 :csdn
视频:B站

1.0 Shell 简介

Shell是一个用C语言编写的程序,通过Shell用户可以访问操作系统内核服务,类似于DOS下的command和后来的cmd.exe。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量、参数、函数、流程控制等等。它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。

1.1 两类程序设计语言

shell脚本是一种脚本语言,也就是解释性语言,程序设计语言可以分为两类:编译型语言和解释型语言

语言 区别
编译型语言 需要预先将我们写好的源代码转换成目标代码,这个过程被称作“编译”。运行程序时,直接读取目标代码。由于编译后的目标代码非常接近计算机底层,因此执行效率很高,这是编译型语言的优点
解释型语言 也叫做脚本语言。执行这类程序时,解释器需要读取我们编写的源代码,并将其转换成目标代码,再由计算机运行。因为每次执行程序都多了编译的过程,因此效率有所下降

1.2 shell脚本(需要解释器解释)

  1. 系统命令的堆积
  2. 特定的语法+系统的文件=文件

    1.3 shell脚本作用

    1. 基于标准化之上的 --->工具化<br />作用:简化操作步骤,提高工作效率,减少认为干预,减少系统故障

    1. 自动化的完成基础配置

    (系统初始化操作,系统更新,内核调整,网络,时区,SSH优化)

    2. 自动化安装程序,自动化调整配置文件

         安装nginx,redis
    

    3. 自动化部署业务

       部署php.java,秒级回退
    

    4. 定期备份恢复程序

        (mysql全备+增量+binlog + crond + shell脚本)
    

    5. 自动化信息的采集(zabbix + shell)

                (硬件 ,系统, 服务, 网络, 等等) 
    

    6.自动化日志收集 (Elk)

    收集->存储->展示->分析
    日志分析(取值->排序->去重->统计->分析)

    7.自动化扩容/伸缩(zabbix + shell)

    监控服务器,如果发现cpu持续80% + 触发动作(脚本)
    脚本: 调用api开通云主机->初始化环境->加入集群->对外提供
    当前cpu使用率20%->判断有多少web节点->判断是否超过预设->缩减到对应的预设状态->变更负载的配置

1.4 shell技能

变量

自定义变量
系统环境变量
预定义变量
位置参数变量
内置变量 continue , break exit

条件判断

if ,else

循环语句

for,while

流程控制

  case

函数

 function      function   test { xxxxxx  if e======0}

数组

array

正则表达式

案例.项目

新建helloworld.sh

[root@centos6-1 ~]# touch helloworld.sh
1
编辑helloworld.sh文件,添入一下内容

vim helloworld.sh
#!/bin/bash
echo "helloworld"

! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell,这里指定bash
echo 是Shell的一个内部指令,用于在屏幕上打印出指定的字符串
赋予当前用户helloworld.sh的执行权限(刚创建的文件没有执行权限)

chmod u+x helloworld.sh

1.5 shell脚本的特性

‘bash shell ‘ 特性
….

1.命令补全和文件路径补全, 如果写错了无法补全

2.命令历史记忆功能 history

3.别名功能alias,

4.常用快捷键

5.前后台作业控制

6.输入输出重定向 >(输入) >> 1>

命令 说明
command>file 将输出重定向到file
command<file 将输入重定向到file
command>>file 将输出以追加的方式重定向到file
n > file 将文件描述符为n的文件重定向
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

输出重定向

  1. 实例 command1>file1

    上面这个命令执行command1然后将输出的内容存入file1。
    注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。

    who > users
    [root@11111]# cat user 
    root     pts/0        2021-06-06 23:18 (112.83.50.183)
    

    输出重定向会覆盖文件内容,请看下面的例子: ```bash [root@111111]# echo “菜鸟教程:www.runoob.com” > user [root@111111]# cat user 菜鸟教程:www.runoob.com

如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾

[root@111111 ]# echo “菜鸟教程:www.runoob.com” >> user [root@i11111 ]# cat user 菜鸟教程:www.runoob.com 菜鸟教程:www.runoob.com

<a name="2HuZK"></a>
#### 输入重定向
和输出重定向一样,Unix命令也可以从文件获取输入,语法为:
```bash
command1 < file1

这样,本来需要从键盘获取输入命令会转移到文件读取内容
注意:输出重定向是大于号(>),输入重定向是小于(<).
实例

wc -l users     #查看文件行数
        2 users
#可以将输入重定向到users文件
wc -l users
       2
# 上面两个例子的结果不同,第一个例子,会输出文件名,第二个不会,因为它从标准输入内容

command1 < file > outfile
#同时代替输入和输出,执行command1从文件infile读取内容,然后将写入到outfile中

重定向深入讲解

一般情况下,每个Uinx/linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin): stdin的文件描述符为0,Unix程序默认从stdin读取数据
  • 标准输出文件(stdout): stdout的文件描述符为1,Unix程序默认向stdout输出数据
  • 标准错误文件(stderr): stderr的文件描述为2,Unix程序会向stderr流中写入错误信息

默认情况下, command>file将stdout重定向到file,command<file将stdin重定向到file

#如果希望 stderr 重定向到 file,可以这样写:

$ command 2>file
#如果希望 stderr 追加到 file 文件末尾,可以这样写:

$ command 2>>file
# 2 表示标准错误文件(stderr)。

#如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1

或者

$ command >> file 2>&1
#如果希望对 stdin 和 stdout 都重定向,可以这样写:

$ command < file1 >file2

Here Document

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:

command << delimiter
    document
delimiter

实例:

[root@1111 ~]# wc -l << EOF
> 欢迎来到
> 菜鸟教程
> www.runoob.com
> EOF
3   #输出结果为3行

我们也可以将 Here Document 用在脚本中,例如:

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
cat << EOF
欢迎来到
菜鸟教程
www.runoob.com
EOF
#执行以上脚本,输出结果:
欢迎来到
菜鸟教程
www.runoob.com

/dev/null文件

希望执行的命令,不显示输出结果,那么可以重定向到/dev/null:

command > /dev/null

dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出”的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。 这里的 2> 之间不可以有空格,2> 是一体的时候才表示错误输出。

7.管道 tee

语法

tee [-ai][--help][--version][文件...]

参数:

  • -a 或 -append 附加到既有文件的后面,而非覆盖它.
  • -i或—ignore-interrupts  忽略中断信号。
  • —help  在线帮助。
  • —version  显示版本信息

输出的信息也同时能写入文件:

[root@1111 ~]# ping qq.com|tee output.txt
PING qq.com (203.205.254.157) 56(84) bytes of data.
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=1 ttl=46 time=300 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=2 ttl=46 time=298 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=3 ttl=46 time=310 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=4 ttl=46 time=302 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=5 ttl=46 time=309 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=6 ttl=46 time=300 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=7 ttl=46 time=299 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=8 ttl=46 time=298 ms
^C[root@1111 ~]# cat output.txt 
PING qq.com (203.205.254.157) 56(84) bytes of data.
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=1 ttl=46 time=300 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=2 ttl=46 time=298 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=3 ttl=46 time=310 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=4 ttl=46 time=302 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=5 ttl=46 time=309 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=6 ttl=46 time=300 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=7 ttl=46 time=299 ms
64 bytes from 203.205.254.157 (203.205.254.157): icmp_seq=8 ttl=46 time=298 ms

8 命令排序

  • ; 没有逻辑关系 ,无论分号前面是否执行成功都执行后者命令
  • && 前面执行成功,则执行后面 cat /etc/hosts &>/dev/null && mkdir /test3
  • || 前面不成功,则执行后者

    9.shell 通配符

    • 匹配多个字符多个字符
  • ? 匹配任意一个字符
  • 在子shell中执行(cd /noot; ls) (umask 077; touch file1000)
  • 集合 touch file{1..9}

    \转义符\

    10.echo输出颜色,printf 格式化输出文本

    echo -e “\033[30m 黑色字 \033[0m”
    echo -e “\033[31m 红色字 \033[0m”
    echo -e “\033[32m 绿色字 \033[0m”
    echo -e “\033[33m 黄色字 \033[0m”
    echo -e “\033[34m 蓝色字 \033[0m”
    echo -e “\033[35m 紫色字 \033[0m”
    echo -e “\033[36m 天蓝字 \033[0m”
    echo -e “\033[37m 白色字 \033[0m”

    2.1 自定义变量

  1. 定义变量 变量名=变量值, 不允许数字命名,不能使用横线命名
  2. 应用变量 $变量名 或 ${变量名}
  3. 查看变量 echo $变量名 set显示所有变量,包括自定义变量和环境变量
  4. 取消变量 unset 变量名 作用范围:仅在当前shell中有效

2.2 系统环境变量