linux12shell编程 --> shell基础02

Posted FikL-09-19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux12shell编程 --> shell基础02相关的知识,希望对你有一定的参考价值。

shell基础

四、shell介绍

1、shell有两层意思:

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WPzY8Vto-1622443168468)(C:\\Users\\17155\\AppData\\Roaming\\Typora\\typora-user-images\\1622348148148.png)]

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

[root@localhost ~]# chsh -l 或 cat /etc/shells
/bin/sh
/bin/
/usr/bin/sh
/usr/bin/
/bin/tcsh
/bin/csh

1.通常用户登录成功后执行的shell程序为:/bin/
[root@localhost ~]# head -1 /etc/passwd
root:x:0:0:root:/root:/bin/
                        
2.shell语言
shell本身就是一门解释型、弱类型、动态语言,与python相对应,Python属于解释型、强类型、动态语言,我们平时登录成功一个用户后进入的就是解释器的交互式环境,我们敲的命令其实都属于shell这门语言的语法


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QUULPjJO-1622443168469)(C:\\Users\\17155\\AppData\\Roaming\\Typora\\typora-user-images\\1622348084366.png)]

3、为何要用shell?

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

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

4、Shell VS python

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

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

2、python语言
1.简介
Python 是近几年非常流行的语言,它不但可以用于脚本程序开发,也可以实现 Web 程序开发(知乎、豆瓣、YouTube、Instagram 都是用 Python 开发),甚至还可以实现软件的开发(大名鼎鼎的 OpenStack、SaltStack 都是 Python 语言开发)、游戏开发、大数据开发、移动端开发;现在越来越多的公司要求运维人员会 Python 自动化开发,Python 也成了运维人员必备的技能,每一个运维人员在熟悉了 Shell 之后,都应该再学习 Python 语言。

2.优势
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程序的三个步骤
1、先运行解析器
2、解析器会将zhuji.sh的内容从硬盘读入内存,这是没有语法意义
3、解析器会将解释执行刚刚读入内存的内容,开始识别语法

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

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

[root@mm ~~]# mkdir -p /a/b
[root@mm ~~]# vim /a/b/hello.sh
[root@mm ~~]# cat /a/b/hello.sh
#!/bin/

#第一个shell小程序
echo "hello world!"  

3、shell解释器解释

**1、第一行表示我们选择使用的shell解释器是,也可以用 :#!/usr/bin/env **

shell的第一行比较特殊,一般都会以#!开始来指定使用的shell解释的类型。
在linux中,除了 shell以外,还有很多版本的shell, 例如zsh、dash等等...
不过 shell还是我们使用最多的。

2、第二行以#符号开始,表示本行是注释,注释是对代码的解释说明,注释的内容不会执行,对关键代码加注释是一种好的编程习惯

3、第三行中的echo是linux中的输出命令,该行的意思很明显的就是输出hello world!

4、精通各种语言的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!");

}

5、运行shell脚本程序

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

1、方式一:绝对路径
此时采用的是文件头指定的解释器来解释执行文件内代码
# 权限:
# 1、当前用户对沿途文件夹有x权限
# 2、当前用户对目标文件有r和x权限

用法: 绝对路径即可

# 例
[root@mm ~~]# ll -d /a
d--------x. 3 root root 15 11月 15 11:05 /a
[root@mm ~~]# ll -d /a/b
d--------x. 2 root root 18 11月 15 11:06 /a/b
[root@mm ~~]# ll /a/b/hello.sh
-rw-r--r-x. 1 root root 10 11月 15 11:06 /a/b/hello.sh
[root@mm ~~]# su - mm
[mm@mm ~~]$ /a/b/hello.sh
hello world!
[mm@mm ~~]$ 

方式二:相对路径
需要加./作为前缀,此时采用的仍是文件头指定的解释器来解释执行文件内代码
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r和x权限

用法: 必须加上./为前缀
# 例
[root@mm ~~]# ll -d /a
d--------x. 3 root root 15 11月 15 11:05 /a
[root@mm ~~]# ll -d /a/b
d--------x. 2 root root 18 11月 15 11:06 /a/b
[root@mm ~~]# ll /a/b/hello.sh
-rw-r--r-x. 1 root root 10 11月 15 11:06 /a/b/hello.sh
[root@mm ~~]# su - mm
[mm@mm ~~]$ /a/b/hello.sh  # 绝对路径的方式
hello world!
[mm@mm ~~]$ cd /a
[mm@mm /a/a]$ ./b/hello.sh  # 相对路径的方式,加./作为前缀
hello world!
[mm@mm /a/a]$ 
3、方式三:解释器+文件路径
绝对路径或相对路径都可以,此时采用的是我们自己指定的解释器来解释执行文件内代码
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r权限即可
用法:  文件路径 (绝对路径、相对路径)
因为我们执行的是解释器,当前用户对解释有执行权限就可以了,这个权限默认就有,而解释器需要读文件内容来执行,所以需要对目标文件有r权限

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

4、方式四:当前shell进程中执行
用source命令执行或者在路径前加空格作为前缀
上述三种方式都是在子shell进程中执行程序,而方式四则是在当前shell进程中执行
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r权限即可
用法:source 文件路径 (绝对路径,相对路径)
. 文件路径 (绝对路径,相对路径)
上述三种方式都是在当前shell环境下开启了一个新的shell解释器环境/子shell来执行程序,脚本程序在子shell中运行完毕后,子shell环境随即关闭,然后返回到父级shell即当前shell环境中,如果就想在当前shell环境中执行,需要这么做
# 例如
[mm@localhost shell]$ cd /home/mm/shell/
[mm@localhost shell]$ ll hello.sh # 当前用户mm对该文件没有执行权限
-rw-r--r--. 1 root root 60 8月  14 18:33 hello.sh
    
# 下面两种方式都一样
[root@mm ~~]# chmod -R o=x /a
[root@mm ~~]# chmod o=r /a/b/hello.sh
[root@mm ~~]# su - mm
[mm@mm ~~]$ . /a/b/hello.sh  # . 后跟空格,然后再跟绝对路径
hello world!
[mm@mm ~~]$ cd /a/b/
[mm@mm /a/b/a/b]$ . hello.sh # . 后跟空格,然后再跟相对路径
hello world!
[mm@mm /a/b/a/b]$ source hello.sh  # 跟上述方式一样
hello world!

5、当前shell与子shell的区别
在当前shell解释器进程中执行脚本与在子shell进程中执行脚本的区别在于作用域,后续我们会详细介绍
# 一个shell环境就是一个单独的全局作用域,不同的shell环境,无法访问彼此shell环境中的变量
[root@mm ~~]# su - mm
[mm@localhost ~]$ x=111
[mm@localhost ~]$ cat /a/b/hello.sh 
#!/bin/

echo "hello world!"  
echo $x  # 我们在这里访问一下全局变量x

[mm@localhost ~]$ source /a/b/hello.sh  # 在当前shell环境执行,可以访问到x
hello world!
111         # 取到了x的值
[mm@localhost ~]$  /a/b/hello.sh  # 在子shell环境执行,不能访问到x 
hello world!
            # 此处打印空


6、调试shell程序

调试方式1
[root@mm test]# sh -vx mm.sh  # 不加-v选项,只会显示程序中运行的代码,不会显示注释信息
[root@mm test]# sh -x mm.sh  # 显示程序中运行的代码,不会显示注释信息

调试方式2
只调试语法是否有问题,比如if判断少了fi结尾
[root@mm test]# sh -n mm.sh

调试方式3
mm.sh仅调试脚本的一部分,用set -x与set +x包含,运行过程中会只打印它们包含的代码段的运行情况
[root@mm test]# cat mm.sh
#!/usr/bin/env 
set -x
read -p "请输入您的名字: " name
read -p "请输入您的密码: " pwd
set +x
if [[ "$name" == "mm" && "$pwd" == "123" ]];then
    echo "登录成功"
else
    echo "账号或密码错误"
fi
[root@mm test]# . mm.sh


7、注释是代码之母

注释的两个作用

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

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

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

六 、shell编写规范与建议

1、脚本编写规范

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

2、shell脚本的结尾以.sh # 加不加后缀.sh 无所谓,但是加上.sh 代表解析器执行的程序

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

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

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

# Author mm 2020-8-30  version 1  des:xxxxx

2、代码编写好习惯

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

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

3、流程控制语句一次性书写完再添加内容
例1:if语句格式一次书写完成

if 条件内容
then
  条件成立后执行的代码
fi
 

例2:for循环格式一次书写完成

for条件内容
   do
     条件成立后执行的代码
   done
提示:while、until、case等语句也是一样

4、代码缩进提高可读性
ok,简单了解完shell程序的编写、执行、调试之后,就让我们开始学习这门编程语言的语法吧!!!

以上是关于linux12shell编程 --> shell基础02的主要内容,如果未能解决你的问题,请参考以下文章

linux12shell编程 --> shell基础02

2017-12-5Linux基础知识(15)shell编程

linux12shell编程 -->shell变量

ubuntu12.04中用emacs进行shell编程怎么配置呢?

Linux之Shell编程(12)--Shell输入/输出重定向实例演示

Linux之Shell编程(12)--Shell输入/输出重定向实例演示