2021-01-10 shell基础

文章目录

shell基础

一 编程与编程语言

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

​ 编程的目的:

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

​ 什么是编程语言?

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

​ 什么是编程?

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

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

​ 什么是程序

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

​ 什么是进程

程序运行的过程就是进程,或者说是操作系统干活的过程,即操作系统拿着硬件去运行程序的过程

​ 编程的步骤?

1、先把自己想让计算机做事的步骤想清楚
2、再用一种计算机可以听懂的语言把做事的步骤翻译下来

​ 所以我有话对大家说

shell是语言,而学习语言的套路都是一样的,以英语学习为例,你需要学单词,然后学语法,最后写作文。
    英语的单词---------->shell中的关键字
    英语的语法---------->shell的语法
    英语的作文---------->用shell语言写的程序

    此时你心里应该有数了,学shell其实很简单,全都是在记忆一些固定的套路而已,那为何有的人会觉得shell难呢?来看一个普遍的问题,问题中包含答案。。。。。。


    经常有学生问:老师,我上课都能听得懂,为啥我就是不会写程序。
    我:你这不废话么!
    你学完了英语的单词、语法、还有写作文的方式,你能立刻写出一篇优美的作文吗?当然不能,那么问题出在哪里呢?
    你想想,你现在用汉语跟我沟通,脑子里会不会分神去琢磨某个汉字的意思,汉语的语法应该怎样?你当然不会,你脑子里想到什么,就会很自然地将它表达出来,因为你已经足够熟练,汉语的文字、单词、语法等已经深深地植入了你的意识里。学英语,学shell都是一样的道理,你以为你会了,你可能确实会了,但你远没有达到烂熟于心的地步,因此你在写程序的时候需要考虑的是关键字的用法、语法结构,而我则只需要考虑我脑子里的逻辑如何安排,逻辑走通了程序自然就表达出来了,我完全不会考虑关键字或语法什么的,它就像是我的器官一样,我不会在想吃饭的时候考虑应该用锭眼吃还是用嘴吃,这就是你跟我的差别。
    那有何好的解决方法呢?答:没有。不下狠心翻来覆去练习,知识是无法根植于你的潜意识的,你也永远无法自己写程序,就跟当年郭靖学降龙十八掌一样,洪七公要他打200下,他能打1000下,屌丝到不能再屌丝的你,没有这点意志力,就别妄想咸鱼翻身了。。。。。。
    附一句:我不知道成功有没有捷径,但我确定学shell没有,没有上万行代码的洗礼,你不可能真的学会shell,这就是我想对你说的。

二 编程语言分类

​ 编程的语言的发展经历了

# 机器语言:站在计算机(奴隶)的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件;
#         优点:执行效率最高
#         缺点:1、二进制指令难以记忆,开发时极容易出错
#              2、开发程序的复杂度高:即便是完成一个简单的功能,需要用到的二进制指令的条数都会非常多

# 汇编语言:站在计算机(奴隶)的角度,简写的英文标识符取代二进制指令去编写程序,本质仍然是直接操作硬件;
#         优点:解决了机器语言的二进制指令难以记忆的问题,执行效率还是高
#         缺点:开发程序的复杂度依然很高:因为汇编语言就是用英文标签对应原来的二进制指令,好记归好记,开发
#              的复杂度却没有降低

ps:因为上述两类语言都是在直接与计算机硬件打交道,离计算机硬件比较近,所以又统称为低级语言

# 高级语言:站在人(奴隶主)的角度,说人话,即用人类的字符去编写程序,屏蔽了硬件操作
#         优点:开发复杂度地,即开发效率高
#         缺点:速度肯定是不如低级语言,一直到今天,对速度要求极高的场景还会用到低级语言,比如操作系统的
#              调度程序

​ 高级语言更贴近人类语言,因而造成了:它必须被翻译成计算机能读懂二进制后,才能被执行,按照翻译方式分为

# 1. 编译型(需要编译器,相当于用谷歌翻译):如C,执行速度快,调试麻烦

# 2. 解释型(需要解释器,相当于同声传译):如python,执行速度慢,调试方便

​ 机器语言、汇编语言、高级语言示例:https://www.cnblogs.com/linhaifeng/articles/7133167.html#_label2

三 计算机完整体系结构图

​ 了解玩编程语言后,我们得知我们使用编程语言的目的在于与计算机对话,准确地说是命令计算机帮我们做事情,但编程语言又分类很多种,不同种类有不同的特点和难度,这对于学习者有不同的要求,比如对机器语言,要求学习者必须具备非常深厚的计算机硬件知识才可以使用它编写程序,一般等级比较低的人是没办法学会机器语言的!但我们大家伙虽然比较low,但我们也都想用一下计算机硬件,家里摆着一台机器能够帮我们做事情,就跟家里养了一个奴隶一样,谁不想呢?

​ 所以,为了方便不同的人群都能够操作计算机硬件,有了一层一层封装的概念,如下图所示

2021-01-10 shell基础

四 shell介绍

1、shell有两层意思:

# 1、一层指的是shell这门语言,是一种特定的语法风格,规范等

# 2、另外一层指的是专门用于解释执行shell这门语言语法的应用程序,即shell解释器,我们常用的是bash

2021-01-10 shell基础

linux系统上自带多种shell解释器,无需安装

[root@localhost ~]# chsh -l  #linux系统自带多种shell解释器
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

通常用户登录成功后执行的shell程序为:/bin/bash

[root@localhost ~]# head -1 /etc/passwd   #用户登录成功后执行的shell程序
root:x:0:0:root:/root:/bin/bash

shell本身就是一门解释型、弱类型、动态语言,与python相对应,Python属于解释型、强类型、动态语言,我们平时登录成功一个用户后进入的就是bash解释器的交互式环境,我们敲的命令其实都属于shell这门语言的语法

2021-01-10 shell基础

2、为何要用shell

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

  • 自动备份
  • 自动部署
  • 监控脚本

3、Shell VS python

shell语言

Shell 脚本的优势在于处理偏操作系统底层的业务,例如,Linux 内部的很多应用(有的是应用的一部分)都是使用 Shell 脚本开发的,因为有 1000 多个 Linux 系统命令为它作支撑,特别是 Linux 正则表达式以及三剑客 grep、awk、sed 等命令。

对于一些常见的系统脚本,使用 Shell 开发会更简单、更快速,例如,让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,日志分析脚本等,虽然 Python 也能做到这些,但是考虑到掌握难度、开发效率、开发习惯等因素,它们可能就不如 Shell 脚本流行以及有优势了。对于一些常见的业务应用,使用 Shell 更符合 Linux 运维简单、易用、高效的三大原则。

python语言

Python 是近几年非常流行的语言,它不但可以用于脚本程序开发,也可以实现 Web 程序开发(知乎、豆瓣、YouTube、Instagram 都是用 Python 开发),甚至还可以实现软件的开发(大名鼎鼎的 OpenStack、SaltStack 都是 Python 语言开发)、游戏开发、大数据开发、移动端开发。

现在越来越多的公司要求运维人员会 Python 自动化开发,Python 也成了运维人员必备的技能,每一个运维人员在熟悉了 Shell 之后,都应该再学习 Python 语言。

Python 语言的优势在于开发复杂的运维软件、Web 页面的管理工具和 Web 业务的开发(例如 CMDB 自动化运维平台、跳板机、批量管理软件 SaltStack、云计算OpenStack 软件)等。

五 第一个shell程序

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

我们可以在两个地方编写shell程序

# 1、交互式环境
调试方便,无法永久保存代码
ps:
交互式环境,请看附录《shell解释器交互式环境》,或者点击链接https://www.cnblogs.com/linhaifeng/articles/13976243.html


# 2、写到文件中
我们采用解释型语言编写的代码文件通常都会被称之为脚本程序(使用nodpad++演示):可以永久保存代码

2、编写shell脚本程序

其实我们在交互式环境里敲的命令直接放到一个文本文件里,一个简单的shell程序就完成了

强调:shell解释器执行程序是解释执行,即打开文件读内容,因此文件的后缀名没有硬性限制,但通常定义为.sh结尾

[root@web03 ~]# mkdir -p /a/b
[root@web03 ~]# vim /a/b/hello.sh
[root@web03 ~]# vim /a/b/hello.sh
#!/bin/bash   #第一行表示我们选择使用的shell解释器是bash,也可以用#!/usr/bin/env bash

#第一个shell程序  #第二行以#开始,表示本行是注释,注释是对代码的解释说明,注释的内容不会执行,对关键代码加注释是一种好的习惯。
echo "hello world"  #第三行中的echo是Linux中的输出命令,该行的意思很明显的就是输出 hello world

精通各种语言的hello world!看一看还是高级语言的简洁

#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!");

}

3、 运行shell脚本程序

编写好shell脚本之后,运行它有几种方式

  • 方式一:绝对路径,此时采用的是文件头指定的解释器来解释执行文件内代码

    # 权限:
    # 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 ~~]$ 
    
  • 方式二:相对路径,需要加./作为前缀,此时采用的仍是文件头指定的解释器来解释执行文件内代码

    # 权限:
    # 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、对沿途文件夹有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!
    
    
  • 方式四:上述三种方式都是在子shell进程中执行程序,而方式四则是在当前shell进程中执行

    # 权限:
    # 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环境中的变量
    #不同的窗口代表在不同的作用域   不同的作用域之间变量是不共享的
    [root@egon ~~]# su - egon
    [egon@localhost ~]$ x=111
    [egon@localhost ~]$ cat /a/b/hello.sh 
    #!/bin/bash
    
    echo "hello world!"  
    echo $x  # 我们在这里访问一下全局变量x
    
    [egon@localhost ~]$ source /a/b/hello.sh  # 在当前shell环境执行,可以访问到x
    hello world!
    111         # 取到了x的值
    [egon@localhost ~]$ bash /a/b/hello.sh  # 在子shell环境执行,不能访问到x 
    hello world!
                # 此处打印空
    

4、 调试shell程序

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

[root@web03 ~]# sh -x /a/b/hello.sh  #显示程序中运行的代码
+ echo 'hello world'
hello world
[root@web03 ~]# sh -vx /a/b/hello.sh   #显示程序中运行的代码及注释信息
#!/bin/bash
#第一个shell程序
echo "hello world"
+ echo 'hello world'
hello world

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

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

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

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


[root@web03 ~]# cat login.sh 
#!/usr/bin/env bash
read -p "请输入您的名字: " name
read -p "请输入您的密码: " pwd

if [[ "$name" == "egon" && "$pwd" == "123" ]];then
    echo "登录成功"
else
    echo "账号或密码错误"
fi
[root@web03 ~]# . login.sh 
请输入您的名字: egon
请输入您的密码: 123
登录成功

4、注释是代码之母

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

  • 1、注释掉暂时不想运行的代码

  • 2、为关键代码添加注解说明,增强程序的可读性和可维护性

    1. 可以加在被注释代码的正上方单独一行,或者被注释代码的正后方,例如
    # 注释。。。
    echo "hello"  # 注释。。。
    
    2. 不用全部加注释,只需要在自己觉得重要或不好理解的部分加注释即可
    
    3. 注释可以用中文或英文,但不要用拼音
    

六 shell编写规范与建议

一 脚本编写规范

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

  • 2、shell脚本的结尾以.sh

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

  • 4、脚本开头注意加时间、作者、联系邮箱、脚本作用等信息

    # Author egon 2020-8-30  version 1  des:xxxxx
    
  • 5、关键代码应该用#号加上注释

二 代码编写好习惯

  • 1、成对的符号尽量一次性写出来,防止遗漏

    例如大括号{},中括号[],小括号(),单引号’’,双引号””,反引号``等
    
  • 2、括号的保留空格习惯

    中括号[ ]两端需要留有空格,不然会报错。书写时即可留出空格然后书写内容。
    如果不知道大括号{},中括号[],小括号(),到底哪种括号需要两端留空格,可以在书写这些括号的时候两端都保留空格来进行书写,这样可以有效避免因空格导致的各种错误。
    
  • 3、流程控制语句一次性书写完再添加内容

    例1:if语句格式一次书写完成
    
    if 条件内容
    then
      条件成立后执行的代码
    fi
     
    
    例2:for循环格式一次书写完成
    
    for条件内容
       do
         条件成立后执行的代码
       done
    提示:while、until、case等语句也是一样
    
  • 4、代码缩进提高可读性

ok,简单了解完shell程序的编写、执行、调试之后,就让我们开始学习这门编程语言的语法吧!!!

上一篇:-linux-进程管理


下一篇:html中的alt和title用法区别