第一章 shell基础

一、学习shell编程的目的

1.将运维工作自动化
2.为了解其他更高级编程语言打基础

二、编程与编程语言

1.shell是一门编程语言,作为学习shell的开始,需要事先搞明白:编程的目的是什么?什么是编程语言?什么是编程?

1)编程的目的

#计算机的发明,是为了用机器取代/解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而达到让计算机能够像人脑/电脑一样自动执行的效果。

人---------------汉语---------------人		
人---------------编程语言-----------计算机			
银行行长-----------------------------柜台人员
	接收客户输入的账号
	接收客户输入的密码
	判断 输入的账号 等于 正确的账号 并且 输入的密码 等于 正确的密码:	
		告诉用户登录成功
	否则
		告诉用户登录失败

2)什么是编程语言

#上面提及的能够被计算机所识别的表达方式即为编程语言,语言是沟通的介质,而编程语言是程序员与计算机沟通的介质。在编程的世界里,计算机更像是人的奴隶,人类编程的目的就是命令奴隶去工作。

3)什么是编程

#编程即程序员根据需求把自己的思想流程按照某种编程语言的语法风格编写下来,产出的结果就是包含一堆字符的文件。

#强调: 程序在未运行前跟普通文件无异,只有程序在运行时,文件内所写的字符才有特定的语法意义。

4)什么是程序

#编程的结果就是程序,更准确的说,程序就是一系列代码文件

5)什么是进程?

#一个程序的运行过程,或者说是操作系统干活的过程,即操作系统拿着计算机硬件去运行应用程序的过程。

6)编程的步骤

#编程就是人把自己想让计算机做事的步骤给翻译下来,可以总结为两个步骤
	1)先把自己想让计算机做事的步骤想清楚
	2)用一种计算机能听懂的语言把做事的步骤翻译下来,然后存入文件

三、编程语言分类

1)机器语言

1.定义:用二进制指令去编程程序,直接控制计算机硬件
2.优点:执行效率高
3.缺点:
	1)哪怕是实现一个简单的功能,需要用到的二进制指令的条数都会非常多(#编程的复杂高,即开发效率)
	2)难以记忆,极容易出错

2)汇编语言

1.定义:用英文标签取代二进制指令去编写程序,直接控制计算机硬件
2.优点:执行效率也很高,解决机器语言难记的问题
3.缺点:
	1)编程的复杂程度依然很高,开发效率很低。
ps: 因为上述两类语言都是在直接与计算机硬件打交道,离计算机硬件比较近,所以有统称为低级语言。

3)高级语言

1.定义:用人类能理解的表达方式去编写程序,计算机无法理解,需要经过翻译计算机才能理解。
2.优点:开发复杂度低,即开发效率高
3.缺点:速度肯定是不如低级语言,一直到今天,对速度要求极高的场景还会用到低级语言,比如操作系统的调度程序。

4)翻译方式

1.翻译类型:
	1)编译型(c、go):
	编译型语言写出的代码-------------》编译器-------------》机器指令
	2)解释型(shell、python)
	解释型语言写出的代码-------------》解释器-------------》机器指令 

5)语言效率

1.执行效率:
机器语言》汇编语言》高级语言(编译型》解释型)

2.开发效率:
机器语言《汇编语言《高级语言

四、计算机完整体系结构图

五、shell介绍

1)shell的含义

1.shell有两层意思
#1.一层指的是shell这门语言,是一种特定的语法风格,规范等。
#2.另外一层指的是专门用于解释执行shell这门语言语法的应用程序,即shell解释器,我们常用的是bash
	
Shell 是一类应用程序的统称,该类应用程序负责连接用户和 Linux 内核,让用户能够更加高效、安
全、低成本地使用 Linux 内核来控制计算机硬件。
具体来说,linux系统上自带多种shell程序
通常用户登录成功后执行的shell程序为:/bin/bash
[root@localhost ~]# chsh -l
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@localhost ~]# head -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
其实,shell程序例如bash的本质就是一个解释器,shell本身就是一门解释型、弱类型、动态语言,与
python相对应,Python属于解释型、强类型、动态语言,我们平时登录成功一个用户后进入的就是
bash解释器的交互式环境,我们敲的命令其实都属于shell这门语言的语法

2)为何要用shell

那还用说吗,一些日常的运维工作自动化、配合计划任务威力无穷,彻底解放双手,你说它不香吗?例
如
#自动备份
#自动部署
#监控脚本

3)Shell VS python

1.shell语言
Shell 脚本的优势在于处理偏操作系统底层的业务,例如,Linux 内部的很多应用(有的是应用的一部分)都是使用 Shell 脚本开发的,因为有 1000 多个 Linux 系统命令为它作支撑,特别是 Linux 正则表达式以及三剑客 grep、awk、sed 等命令。
对于一些常见的系统脚本,使用 Shell 开发会更简单、更快速,例如,让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,日志分析脚本等,虽然 Python 也能做到这些,但是考虑到掌握难度、开发效
率、开发习惯等因素,它们可能就不如 Shell 脚本流行以及有优势了。对于一些常见的业务应用,使用
Shell 更符合 Linux 运维简单、易用、高效的三大原则。

2.python语言
Python 是近几年非常流行的语言,它不但可以用于脚本程序开发,也可以实现 Web 程序开发(知乎、豆
瓣、YouTube、Instagram 都是用 Python 开发),甚至还可以实现软件的开发(大名鼎鼎的
OpenStack、SaltStack 都是 Python 语言开发)、游戏开发、大数据开发、移动端开发。
现在越来越多的公司要求运维人员会 Python 自动化开发,Python 也成了运维人员必备的技能,每一个运
维人员在熟悉了 Shell 之后,都应该再学习 Python 语言。
Python 语言的优势在于开发复杂的运维软件、Web 页面的管理工具和 Web 业务的开发(例如 CMDB 自动
化运维平台、跳板机、批量管理软件 SaltStack、云计算OpenStack 软件)等。

六、第一个shell程序

1)编写shell程序的两种环境

#1.交互式环境
调试方便,无法永久保存代码

#2.写到文件中
我们采用解释型语言编写的代码文件通常会被称之为脚本程序,可以永久保存代码。

2)编写shell脚本程序

其实我们在交互式环境里敲的命令直接放到一个文本文件里,一个简单的shell程序就完成了
#强调: shell解释器执行程序是解释执行,即打开文件读内容,因此文件的后缀名没有硬性限制,但通常定义为.sh结尾。

[root@localhost shell]# vim hello.sh
[root@localhost shell]# cat hello.sh
#!/bin/bash
#第一个shell小程序
echo "hello world!" 

1、第一行表示我们选择使用的shell解释器是bash,也可以用 :#!/usr/bin/env bash
	1)shell的第一行比较特殊,一般都会以#!开始来指定使用的shell解释的类型。
	2)在linux中,除了bash shell以外,还有很多版本的shell, 例如zsh、dash等等...
	3)不过bash shell还是我们使用最多的。
2、第二行以#符号开始,表示本行是注释,注释是对代码的解释说明,注释的内容不会执行,对
关键代码加注释是一种好的编程习惯
3、第三行中的echo是linux中的输出命令,该行的意思很明显的就是输出hello world!

3)各种语言的hello word!

#C++
#include <iostream>
int main(void)
{
std::cout<<"Hello world";
}

#C
#include <stdio.h>
int main(void)
{
printf("\nhello world!");
return 0;
}

#JAVA
public class HelloWorld{
// 程序的入口
public static void main(String args[]){
// 向控制台输出信息
System.out.println("Hello World!");
}
}

#PHP
<?php
echo "hello world!";
?>

#Ruby
日本人开发的,砸日本车的时候,顺手就把你拖出去打死了,祭天
puts "Hello world."

#GO
package main
import "fmt"
func main(){
 fmt.Printf("Hello World!\n God Bless You!");
}

4)运行shell脚本程序

shell程序通常会被称为脚本程序,因为shell属于解释型语言,而我们采用解释型语言编写的代码文件
通常都会被称之为脚本程序,运行它有几种方式:

#方式一 以绝对路径的方式去执行shell脚本,此时采用的是文件头指定的解释器来解释执行文件内代码
1.权限:
	1)对沿途文件夹有x权限
	2)对目标文件有r和x权限
	
[root@egon ~~]# ll -d /a
d--------x. 3 root root 15 11? 15 11:05 /a
[root@egon ~~]# ll -d /a/b
d--------x. 2 root root 18 11? 15 11:06 /a/b
[root@egon ~~]# ll /a/b/hello.sh
-rw-r--r-x. 1 root root 10 11? 15 11:06 /a/b/hello.sh
[root@egon ~~]# su - egon
[egon@egon ~~]$ /a/b/hello.sh
hello world!
[egon@egon ~~]$

#方式二 以相对路径的方式去执行shell脚本,需要加./作为前缀,此时采用的仍然是文件头指定的解释器来解释执行文件内代码
1.权限
	1)对沿途文件夹有x权限
	2)对目标文件有r和x权限
	
[root@egon ~~]# ll -d /a
d--------x. 3 root root 15 11? 15 11:05 /a
[root@egon ~~]# ll -d /a/b
d--------x. 2 root root 18 11? 15 11:06 /a/b
[root@egon ~~]# ll /a/b/hello.sh
-rw-r--r-x. 1 root root 10 11? 15 11:06 /a/b/hello.sh
[root@egon ~~]# su - egon
[egon@egon ~~]$ /a/b/hello.sh # 绝对路径的方式
hello world!
[egon@egon ~~]$ cd /a
[egon@egon /a/a]$ ./b/hello.sh # 相对路径的方式,加./作为前缀
hello world!
[egon@egon /a/a]$

#方式三 解释器+文件路径(绝对路径或相对路径都可以),此时采用的是我们指定的解释器来解释执行文件内代码。
1.权限
	1)对沿途文件夹有x权限
	2)对目标文件有r权限即可

	因为我们执行的是解释器,当前用户对解释器有执行权限就可以了,这个权限默认就有,而解释器需要读文件内容来执行,所以需要对目标文件有r权限。

[root@egon ~~]# chmod -R o=x /a
[root@egon ~~]# chmod o=r /a/b/hello.sh
[root@egon ~~]# su - egon
[egon@egon ~~]$ cd /a
[egon@egon /a/a]$ bash b/hello.sh
hello world!
[egon@egon /a/a]$

#方式四 上述三种方式都是在shell子进程中执行程序,而方式四则是在当前shell进程中执行。
1.权限:
	1)对沿途文件夹有x权限
	2)对目标文件有r权限即可
	
	上述三种方式都是在当前shell环境下开启了一个新的shell解释器环境/子shell来执行程序,脚本程
序在子shell中运行完毕后,子shell环境随即关闭,然后返回到父级shell即当前shell环境中,如果
就想在当前shell环境中执行,需要这么做

[egon@localhost shell]$ cd /home/egon/shell/
[egon@localhost shell]$ ll hello.sh # 当前用户egon对改文件没有执行权限
-rw-r--r--. 1 root root 60 8? 14 18:33 hello.sh

# 下面两种方式都一样
[root@egon ~~]# chmod -R o=x /a
[root@egon ~~]# chmod o=r /a/b/hello.sh
[root@egon ~~]# su - egon
[egon@egon ~~]$ . /a/b/hello.sh # . 后跟空格,然后再跟绝对路径
hello world!
[egon@egon ~~]$ cd /a/b/
[egon@egon /a/b/a/b]$ . hello.sh # . 后跟空格,然后再跟相对路径
hello world!
[egon@egon /a/b/a/b]$ source hello.sh # 跟上述方式一样
hello world!

在当前shell中执行脚本与在子shell中执行脚本的区别在于作用域,后续我们会详细介绍
# 一个shell环境就是一个单独的全局作用域,不同的shell环境,无法访问彼此shell环境中的变量
[egon@localhost ~]$ x=111
[egon@localhost ~]$ cat /home/egon/shell/hello.sh
#!/bin/bash
echo "hello world!" 
echo $x  # 我们在这里访问一下全局变量x
[egon@localhost ~]$ source /home/egon/shell/hello.sh  # 在当前shell环境执行,可
以访问到x
hello world!
111     # 取到了x的值
[egon@localhost ~]$ bash /home/egon/shell/hello.sh  # 在子shell环境执行,不能访问到x
hello world!
      # 此处打印空

5)调试shell程序

1.调试方式1:以调试的方式运行

[root@egon test]# sh -vx login.sh  # 不加-v选项,只会显示程序中运行的代码,不会显示注释信息

2.调试方式2:只调试语法是否有问题,比如if判断少了fi结尾

[root@egon test]# sh -n login.sh

3.调试方式3:仅调试脚本的一部分,用set -x与set +x包含,运行过程中只打印它们包含的代码段的运行情况

[root@jh test]# cat login.sh
#!/usr/bin/env bash
set -x
read -p "请输入您的名字: " name
read -p "请输入您的密码: " pwd
set +x
if [[ "$name" == "jh" && "$pwd" == "123" ]];then
echo "登录成功"
else
echo "账号或密码错误"
fi
[root@jh test]# . login.sh

6)注释是代码之母

以#号开头的内容不会执行,注释的作用有二

1.注释掉暂时不想运行的代码
2.为关键代码添加注解说明,增强程序的可读性和可维护性
	1)可以加在被注释代码的正上方单独一行,或者被注释代码的正后方,例如 # 注释。。。
	2)不用全部加注释,只需要在自己觉重要或不好理解的部分加注释即可
	3)注释可以用中文或者英文,但不要用拼音

七、shell编写规范与建议

1)脚本编写规范

1、脚本存放目录需要统一

2、shell脚本的结尾以.sh

3、脚本开头要有解释器
如 #!/bin/bash 或者 #!/usr/bin/env bash

4、脚本开头注意加时间、作者、联系邮箱、脚本作用等信息
如 # Author egon 2020-8-30 version 1 des:xxxxx

5、关键代码应该用#号加上注释

2)代码编写好习惯

1、成对的符号尽量一次性写出来,防止遗漏
例如大括号{},中括号[],小括号(),单引号’’,双引号””,反引号``等

2、括号的保留空格习惯
中括号[ ]两端需要留有空格,不然会报错。书写时即可留出空格然后书写内容。如果不知道大括号{},中括号[],小括号(),到底哪种括号需要两端留空格,可以在书写这些括号的时候两端都保留空格来进行书写,这样可以有效避免因空格导致的各种错误。

3、流程控制语句一次性书写完再添加内容
例1:if语句格式一次书写完成
if 条件内容
then
 条件成立后执行的代码
fi
例2:for循环格式一次书写完成
for条件内容
 do
  条件成立后执行的代码
   done
提示:while、until、case等语句也是一样

4、代码缩进提高可读性
posted @ 2020-11-16 20:38  年少纵马且长歌  阅读(152)  评论(0编辑  收藏  举报