LV02-02-shell-01-基础知识

本文主要是shell——基础知识相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
SecureCRT Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日
开发板 正点原子 i.MX6ULL Linux阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
STM32开发板 正点原子战舰V3(STM32F103ZET6)
点击查看本文参考资料
参考方向 参考原文
------
点击查看相关文件下载
--- ---

一、什么是 shell ?

shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

二、什么是 shell 脚本?

shell 脚本语言是解释型语言,本质是 shell 命令的有序集合, 一般 shell 脚本文件的后缀名称是 .sh 。

【注意】shell脚本文件就是一个文本文件,只是后缀名建议使用 .sh 结尾,之后其实也会遇到很多根本就没有后缀的shell脚本文件。

三、 Hello World!

1
2
#!/bin/bash
echo "Hello World!"

这段代码是一个最简单的 shell 脚本程序,就像 C 语言学习时的第一个 hello world 程序一样。

  • 第一行: #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 shell 。这里就是设置当前shell脚本文件采用 bash 解析器运行脚本代码
  • 第二行:echo 命令用于向命令行窗口输出文本,这个后边会再学习。

四、shell脚本解释器

这部分是后边补充的,会涉及根文件系统的概念,这其实就是我们后边做linux内核移植的时候会做的事情。

1.相关命令

1.1查看支持的shell解释器

我们可以在linux中执行以下命令看一下(注意这个命令查看的是一个文件,我们要是在自己移植的根文件系统的话,可能没有这个文件,就看不到啦):

1
sudo cat /etc/shells

然后会看到如下输出信息:

1
2
3
4
5
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash

可以看到我当前使用的ubuntu中支持这几种shell脚本解释器。

1.2当前使用的是哪个?

那当前系统使用的是哪一个解释器呢?我们可以使用以下命令查看:

1
echo $SHELL

这个是可以在移植的根文件系统上使用的,因为它打印的是当前shell的环境变量的值。

2.什么是解释器?

这个嘛,其实就是指shell本身,前边说什么是shell的时候就解释过了其实,我自己的理解就是,shell解释器就是运行shell脚本的那个工具,它担任着类似翻译官的角色,也是一个桥梁,用户通过这个桥梁访问操作系统内核的服务。

3.常见解释器

上边我们已经知道怎么查看当前系统支持的shell解释器了,接下来做一个简单的了解吧,这里就简单介绍下bash和sh,关于dash和其他的就暂时不做介绍了。

3.1 bash

bash(Bourne-Again Shell) ,Unix shell的一种,在1987年由布莱恩·福克斯为了GNU计划而编写。1989年发布第一个正式版本,原先是计划用在GNU操作系统上,但能运行于大多数类Unix系统的操作系统之上,包括Linux与Mac OS X v10.4起至macOS Mojave都将它作为默认shell,而自macOS Catalina,默认Shell以zsh取代。

3.2 sh

sh是啥呢?我们看一下这个文件:

1
ls -alh /bin/sh

然后会看到以下输出结果:

1
lrwxrwxrwx 1 root root 4 8月  18 08:50 /bin/sh -> dash

发现它是一个超链接,GNU/Linux 操作系统中的 /bin/sh 本是 bash 的符号链接,但鉴于 bash 过于复杂,有人把 bash 从 NetBSD 移植到 Linux 并更名为 dash (Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Dash Shell 比 Bash Shell 小的多,符合POSIX标准。

其实我们是可以修改sh,让其指向bash的,我们可以在终端执行:

1
sudo dpkg-reconfigure dash

然后就会弹出一个菜单界面

1
2
3
4
5
6
7
8
9
10
11
12
┌─────────────────────────────┤ 正在设定 dash ├─────────────────────────────┐
│ │
│ The system shell is the default command interpreter for shell scripts. │
│ │
│ Using dash as the system shell will improve the system's overall │
│ performance. It does not alter the shell presented to interactive users. │
│ │
│ Use dash as the default system shell (/bin/sh)? │
│ │
│ <是> <否> │
│ │
└───────────────────────────────────────────────────────────────────────────┘

我们选择否就可以让sh指向bash啦,然后会出现以下提示信息:

1
2
3
4
正在删除 dash 导致 /bin/sh 转移到 /bin/sh.distrib
正在添加 bash 导致 /bin/sh 转移到 /bin/sh.distrib
正在删除 dash 导致 /usr/share/man/man1/sh.1.gz 转移到 /usr/share/man/man1/sh.distrib.1.gz
正在添加 bash 导致 /usr/share/man/man1/sh.1.gz 转移到 /usr/share/man/man1/sh.distrib.1.gz

然后我们重新看一下这个超链接,就会发现它指向了bash了已经。

【注意】需要注意的是dash和bash有一些语法是不太一样的,所以我们写脚本的时候使用sh作为解释器的时候,有时候可能会出现问题,这个时候我们要知道是bash和dash语法有区别就可以了。

五、如何运行 Shell 脚本?

1.使用 ./ 的方式

这种方式就是必须要进入脚本所在的目录中,才能执行脚本文件。

(1)进入 shell 脚本所在目录

1
cd <file_path>

(2)赋予 shell 文件执行权限

1
chmod permissions file_name.sh

permissions 为要赋予文件的权限(常用777或者740,保证文件具有可执行权限即可)。

(3)执行 shell 脚本文件

1
./file_name.sh

2. sh或bash + 脚本相对或绝对路径

这种方式我们并不需要这个脚本有 +x(也就是可执行权限)。这种方式以我们以这个脚本为例:

1
2
#!/bin/sh
echo "hello world"

我们把它放在 /home/hk/6temp 目录下,然后到家目录下执行以下命令:

1
2
3
4
5
6
# 使用bash
bash 6temp/test.sh
bash /home/hk/6temp/test.sh
# 使用sh
sh 6temp/test.sh
sh /home/hk/6temp/test.sh

会发现都是可以正常执行的。

3.相对路径或绝对路径执行

其实还有一种使用相对路径或者绝对路径的方式执行脚本,可以不适用bash和sh作为执行命令的前缀,这样在一些我们并不清楚使用的解释器是什么的情况下就比较方便。但是这种方式要求脚本文件具有可执行权限(+x)。我们这次到 test.sh 的上一级目录进行测试:

1
2
3
4
5
6
7
8
9
# 赋予可执行权限
chmod +x 6temp/test.sh

# 相对路径执行
6temp/test.sh

# 绝对路径执行
/home/hk/6temp/test.sh

会发现这两种方式都是可以正常执行脚本文件的。

【注意】其实上边的 ./ 的方式就属于相对路径执行脚本的方式,只是是在脚本文件所在目录中执行的,但是这里需要注意,若是在脚本所在目录使用相对路径执行脚本的话,一定要加上 ./ ,否则是找不到这脚本的,当然,也可以将其添加到环境变量中去,这样就可以不需要 ./ 了。