shell 英文含义是“壳”,这是相对于内核来说的,shell 也确实就像是内核的壳,通常来说,所有对内核的访问都要经由 shell 。同时,shell 还是一门功能强大的编程语言。shell 是 Linux 学习中必然要经过的一环。实际上,Linux 系统在启动完成,登录成功后运行的第一个程序就是一个 shell ,Linux 的许多功能都可以从 shell 中轻松实现。

一、什么是 shell

  UNIX / Linux 系统在逻辑上可以分为两部分:内核实用工具。shell 其实就是一个实用工具,准确的说,shell 是一个作为用户与 Linux 系统间接口的程序,它允许用户向操作系统输入需要执行的命令

1.1 命令解释器 shell

  shell 是一个命令解释器,可以将用户输入的命令翻译成内核可以识别的代码,然后由内核去控制硬件;而内核则可以通过 shell 将硬件信息翻译成用户可识别的代码,展现给用户。可以用下图大致表达一下 shell 与内核以及其他实用工具之间的关系:

  

   Linux 提供了多种版本的 shell 供用户选择使用,它们大多数都是从最初的 Bourne shell(sh) 演变而来。在 Linux 中,最常用的 shell 是 bash(Bourne-Again Shell), /bin/bash 也是多数 Linux 系统的默认 shell。bash 是开源的,基于 GNU,且符合 POSIX 标准,因此可以被移植到几乎所有的类 UNIX 系统上,本文所使用的 shell 也是 bash。在大多数的 Linux 发行版中,默认的 shell 程序 /bin/sh 实际上是对程序 /bin/bash 的一个连接。

  除此之外,还有许多其他的 shell 可以使用。 常用的 shell 有以下几种:

shell 名称 描述
sh (Bourne shell)     源于UNIX早期版本的最初的 shell
csh、tcsh、zsh                         C shell 及其变体
ksh/pdksh korn shell 和它的公共域兄弟 pdksh(public domain korn shell),是许多商业版本 UNIX 的默认 shell
bash(Bourne-Again shell)                                    l来自 GUN 项目,是 Linux 的主要 shell,它是开源的,且具有很高的移植型,与 kron shell 有许多相似之处

  可以使用下面的命令来查看系统的默认 shell:

[tongye@localhost ~]$ echo $SHELL
/bin/bash
[tongye@localhost ~]$ bash --version
GNU bash, version 4.2.()-release (x86_64-redhat-linux-gnu)
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[tongye@localhost ~]$

  如上,笔者的系统中的默认 shell 是 bash,使用 bash --version 命令查看 bash 的版本,可以看到 GNU 证书。

  在 Linux 系统中安装多个 shell 是完全可行的,用户可以挑选一种自己喜欢的 shell 来使用,使用下面命令可以查看系统中有多少可以使用的 shell:

[tongye@localhost ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin 

  可以看到,系统中可用的 shell 有 sh 和 bash。同时,我们还发现有一个特殊的家伙混了进来:sbin/nologin。这其实也是一个 shell,使用这个 shell 的用户不允许登录当前系统,即使有密码也不行。不过,虽然无法登入系统,但是用户还是可以使用其他的系统资源的,许多系统账户都是使用的这个  shell,如 ftp、mail 等,它们只需要使用系统资源,而不需要登入系统,设置成使用 sbin/nologin 可以使系统更安全。

  想要切换到另一个 shell 也很简单,直接运行这个 shell 就行,比如,笔者的系统上默认 shell 是 bash,如果我想要切换到 sh 的话,直接在命令行输入:/bin/sh 即可切换到 sh,再输入 exit 即可退出 sh 回到 bash:

[tongye@localhost ~]$ /bin/sh
sh-4.2$
sh-4.2$ exit
exit
[tongye@localhost ~]$

  如果用户想使用 csh 或者 ksh 而系统中没有这个 shell 的话,也可以使用 yum 在线安装获得它们:

[tongye@localhost ~]$ sudo yum install csh
[tongye@localhost ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

  安装完成后再使用 cat /etc/shells 查看,可以发现 csh 已经可以使用了。

1.2 编程语言 shell

  shell 还是一种功能强大的解释型编程语言,使用 shell 来执行 shell 程序,这些程序通常被称为脚本,它们是在运行时解释执行的。这使得调试工作比较容易进行,因为你可以逐行的执行指令,而且节省了重新编译的时间。然而,这也使得 shell 不适合用来完成时间紧迫型和处理器忙碌型的任务。shell 非常适合于编写一些执行相对简单的任务的小工具,它们更强调的是易于配置、易于维护和可移植性,而不是很看重执行的效率。

二、解释型语言与编译型语言

2.1  解释型语言

  解释型语言的源代码不是直接翻译成机器语言的,而是先翻译成中间代码,再由解释器对中间代码进行解释运行(解释器一般是用编译型语言编写的程序)。解释型语言编写的程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次,因此效率较低,依赖于解释器。但是,也正是由于解释的特性,使得这种语言编写的程序可移植性很好,只要有相应的解释环境,就可以在不同的操作系统上运行。常见的解释型语言有 Shell、Python、Ruby等。

2.2 编译型语言

  编译型语言在执行之前需要先进行编译,将程序直接编译成机器语言,然后直接运行即可,不需要再进行翻译。这种程序执行效率高,依赖于编译器,跨平台性要弱一点。常见的 C、C++等都是编译型语言。

三、为什么要使用 shell 脚本

1)简单性

  shell 脚本可以很简单的对文件、目录层次的内容进行操作,使用 shell 脚本将使得许多事情变得十分简洁;

2)可移植性

  shell 脚本的可移植性非常好,因为它是遵循 POSIX 标准的,基本上无需修改就可以在不同的系统上执行;

3)易于开发

  shell 脚本易于开发,你可以在一个较短时间内完成一个功能强大又好用的脚本。

四、如何编写一个 shell 脚本

4.1 先从最简单的 shell 脚本说起

  假如我想要使用 shell 脚本在终端打印一串字符:Hello world! 可以这样编写 shell 脚本:

#!/bin/bash

# 这是一个 shell 脚本,脚本将打印 Hello world! 这个字符串
echo Hello world!
exit

  将文件保存为 hello.sh 后退出,这就是一个简单的 shell 脚本了。虽然 Linux 中并不依靠后缀名来识别文件,但是最好还是加上一个 .sh 的后缀,以方便用户识别这是一个 shell 脚本。

  在 shell 脚本中,# 符号表示这一行接下来的语句是注释。注意,第一行中的 #!/bin/bash 是一个特殊形式的注释, #! 告诉系统同一行上紧跟在它后面的那个参数是用来执行本文件的程序。在这里,这一句的作用是告诉系统这个文件是一个 shell 脚本,默认 shell 是 /bin/bash。shell 脚本都是以这个语句作为开始的。

  由于脚本程序本质上被看作是 shell 的标准输入,所以它可以包含任何能够通过你的 PATH 环境变量引用到的 Linux 命令。因此,在该脚本中,直接使用 echo 命令来打印一串字符。由于能够直接在脚本中使用 Linux 命令,因此许多操作将会变得简单易行,这也是为什么 shell 脚本易于开发。

  exit 命令的作用是确保脚本程序能够返回一个有意义的退出码,因为 shell 脚本能够对任何可以从命令行上调用的命令的退出码进行测试,其中也包括你自己编写的脚本程序。使用 exit 命令给脚本程序一个明确的退出码,就可以在执行完脚本后通过一些手段来检测脚本程序是否执行成功(比如说,可以在刚执行完一个脚本后,执行 echo $? ,如果输出结果为你设置的那个退出码,则说明脚本成功执行了)。

4.2 执行一个 shell 脚本

  在上一节,我们编写了一个简单的 shell 脚本,现在来尝试运行这个脚本。运行一个脚本很简单,只需要在该脚本所在目录下从命令行输入:

./shell脚本名

  这样就能执行脚本了。使用 ./ 是为了把 shell 脚本所在相对路径告诉 shell,以便 shell 根据路径找到脚本。当然,使用绝对路径也是可以的。

  但是,按照上述方法在命令行输入指令后,发现脚本并没有被执行。这是因为刚新建好的脚本还不具有可执行权限:

[tongye@localhost ~/Shell_Program]$ ls -l | grep hello.sh
-rw-rw-r-- tongye tongye Sep : hello.sh

  使用 ls -l 命令查看脚本文件的属性,可以发现该脚本是没用可执行权限的,我们可以使用 chmod 指令来给文件赋予可执行权限:

[tongye@localhost ~/Shell_Program]$ chmod +x hello.sh
[tongye@localhost ~/Shell_Program]$ ls -l | grep hello.sh
-rwxrwxr-x tongye tongye Sep : hello.sh

  再次查看,发现文件有了可执行权限,然后再执行脚本文件,即可得到想要的结果:

[tongye@localhost ~/Shell_Program]$ ./hello.sh
Hello world!

参考书籍:

Linux程序设计 第四版

shell 脚本学习指南

shell基础 -- 入门篇的更多相关文章

  1. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

  2. 【Linux开发】Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer ...

  3. SQLAlchemy 教程 —— 基础入门篇

    SQLAlchemy 教程 -- 基础入门篇 一.课程简介 1.1 实验内容 本课程带领大家使用 SQLAlchemy 连接 MySQL 数据库,创建一个博客应用所需要的数据表,并介绍了使用 SQLA ...

  4. Shell基础入门

    目录 Shell基础入门 1.什么是Shell? 2.Shell脚本的结构 3.Shell的变量 3.1.自定义环境变量 3.2.普通变量 3.3.位置参数变量 3.4.状态变量 4.条件测试和比较 ...

  5. FPGA基础入门篇(四) 边沿检测电路

    FPGA基础入门篇(四)--边沿检测电路 一.边沿检测 边沿检测,就是检测输入信号,或者FPGA内部逻辑信号的跳变,即上升沿或者下降沿的检测.在检测到所需要的边沿后产生一个高电平的脉冲.这在FPGA电 ...

  6. JS基础入门篇(三十五)—面向对象(二)

    如果没有面向对象这种抽象概念的小伙伴,建议先看一下我写的JS基础入门篇(三十四)-面向对象(一)

  7. 云小课|DGC数据开发之基础入门篇

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:欢迎来到DGC数据 ...

  8. .NET ORM 的 “SOD蜜”--零基础入门篇

    PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...

  9. Elasticsearch 7.x 之文档、索引和 REST API 【基础入门篇】

    前几天写过一篇<Elasticsearch 7.x 最详细安装及配置>,今天继续最新版基础入门内容.这一篇简单总结了 Elasticsearch 7.x 之文档.索引和 REST API. ...

随机推荐

  1. DPDK安装依赖项合集 环境合集

    前言 在dpdk编译过程中,由于一些依赖项的限制,dpdk在纯净的系统上安装需要花一些功夫.本文总结了编译dpdk所需的依赖项,并归纳了安装合集,在安装过程上可以省下大量的搜索时间. 使用系统 ubu ...

  2. Bluetooth® Low Energy Beacons

    Bluetooth® Low Energy Beacons ABSTRACT (abstract ) 1.This application report presents the concept of ...

  3. 使用interface与类型诊断机制判断一个类型是否实现了某个方法

    Golang中的interface通常用来定义接口,在接口里提供一些方法,其他类型可以实现(implement)这些方法,通过将接口指针指向不同的类型实例实现多态(polymorphism),这是in ...

  4. (Les17 移动数据)expdp/impdp

    oracle 11.2.0 expdp/impdp 数据泵参数   expdp参数=========================================================== ...

  5. 【OC底层】OC对象本质,如 isa, super-class

    Objective-C的本质 1.我们编写的Objective-C,底层现实都是C/C++,代码生成步骤如下:   2.在OC中的所有面向对象的实现,都是基于C/C++的数据结构实现的 3.将Obje ...

  6. 关于iOS Block当中为什么要用weakSelf和strongSelf的思考

    场景:当你在某个界面请求网络数据的时候,用户不愿意等待点击了返回按钮,此时在Block当中用如下的方式使用weakSelf的话,有可能会奔溃(因为在并发编程的情况下,虽然在if判断的时候weaksel ...

  7. JS中判断字符串中出现次数最多的字符及出现的次数

    <script type="text/javascript"> var str = 'qwertyuilo.,mnbvcsarrrrrrrrtyuiop;l,mhgfd ...

  8. mysql 基本的操作数据库命令

    注意:命令操作都是分号结尾 1 .连接mysql: mysql -u  用户名   -p 密码 2.展示所有数据库: show  databases; 3.进入数据库: use   数据库名字; 4. ...

  9. u-boot-1.1.6第1阶段分析之start.S、lowlevel_init.S文件

    学习目标: 对start.S中每一行代码,都有基本了解 通过对start.S文件分析,对ARM920T架构的CPU的启动过程,有更清楚理解 U-boot属于两个阶段的Bootloader,第一阶段的文 ...

  10. python小项目之微信远程控制

    前两天接触了一个有趣的python模块--itchat,这个模块可以非常方便的操作微信,今天就来使用这个模块来实现微信远程控制. 环境准备 itchat模块不是python标准模块(内置模块),是一个 ...