第一节:shell
lecture1:the shell(参考链接)
1、shell是什么
如今的计算机有着多种多样的交互接口让我们可以进行指令的的输入。为了充分利用计算机的能力,我们使用文字接口:Shell,
其核心功能为:它允许你执行程序,输入并获取某种半结构化的输出。
2、使用shell
当您打开终端时,您会看到一个提示符,它看起来一般是这个样子的:
missing:~$
这是 shell 最主要的文本接口。它告诉你,你的主机名是 missing
并且您当前的工作目录(”current working directory”)或者说您所在的位置是 ~
(表示 “home”)。 $
符号表示您现在的身份不是 root 用户(root用户用#表示)。在这个提示符中,您可以输入 命令 ,命令最终会被 shell 解析。最简单的命令是执行一个程序:
missing:~$ date
Fri 10 Jan 2020 11:49:31 AM EST
missing:~$
这里,我们执行了 date
这个程序,它打印了当前的日期和时间。然后,shell 等待我们输入其他命令。我们可以在执行命令的同时向程序传递 参数 :
missing:~$ echo hello
hello
上例中,我们让 shell 执行 echo
,同时指定参数 hello
。echo
程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数。如果您希望传递的参数中包含空格(例如一个名为 My Photos 的文件夹),您要么用使用单引号,双引号将其包裹起来,要么使用转义符号 \
进行处理(My\ Photos
)。
但是,shell 是如何知道去哪里寻找 date
或 echo
的呢?其实,shell 是一个编程环境,所以它具备变量、条件、循环和函数。当你在 shell 中执行命令时,您实际上是在执行一段 shell 可以解释执行的简短代码。如果你要求 shell 执行某个指令,但是该指令并不是 shell 所了解的编程关键字,那么它会去咨询 环境变量 $PATH
,它会列出当 shell 接到某条指令时,进行程序搜索的路径:
missing:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
missing:~$ which echo
/bin/echo
missing:~$ /bin/echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
当我们执行 echo
命令时,shell 了解到需要执行 echo
这个程序,随后它便会在 $PATH
中搜索由 :
所分割的一系列目录,基于名字搜索该程序。当找到该程序时便执行。确定某个程序名代表的是哪个具体的程序,可以使用 which
程序。我们也可以绕过 $PATH
,通过直接指定需要执行的程序的路径来执行该程序
3、在shell中导航
shell 中的路径是一组被分割的目录,在 Linux 和 macOS 上使用 /
分割,而在Windows上是 \
。路径 /
代表的是系统的根目录,所有的文件夹都包括在这个路径之下,在Windows上每个盘都有一个根目录(例如: C:\
)。在Linux系统,如果某个路径以 /
开头,那么它是一个 绝对路径,其他的都是 相对路径 。相对路径是指相对于当前工作目录的路径,当前工作目录可以使用 pwd
命令来获取。此外,切换目录需要使用 cd
命令。在路径中,.
表示的是当前目录,而 ..
表示上级目录:
missing:~$ pwd
/home/missing
missing:~$ cd /home
missing:/home$ pwd
/home
missing:/home$ cd ..
missing:/$ pwd
/
missing:/$ cd ./home
missing:/home$ pwd
/home
missing:/home$ cd missing
missing:~$ pwd
/home/missing
missing:~$ ../../bin/echo hello
hello
注意,shell 会实时显示当前的路径信息。一般来说,当我们运行一个程序时,如果我们没有指定路径,则该程序会在当前目录下执行。
为了查看指定目录下包含哪些文件,我们使用 ls
命令:
missing:~$ ls
missing:~$ cd ..
missing:/home$ ls
missing
missing:/home$ cd ..
missing:/$ ls
bin
boot
dev
etc
home
...
除非我们利用第一个参数指定目录,否则 ls
会打印当前目录下的文件。大多数的命令接受标记和选项(带有值的标记),它们以 -
开头,并可以改变程序的行为。通常,在执行程序时使用 -h
或 --help
标记可以打印帮助信息,以便了解有哪些可用的标记或选项。例如,ls --help
的输出如下:
-l use a long listing format
missing:~$ ls -l /home
drwxr-xr-x 1 missing users 4096 Jun 15 2019 missing
这个参数可以更加详细地列出目录下文件或文件夹的信息。首先,本行第一个字符 d
表示 missing
是一个目录。然后接下来的九个字符,每三个字符构成一组。 (rwx
). 它们分别代表了文件所有者(missing
),用户组(users
) 以及其他所有人具有的权限。其中 -
表示该用户不具备相应的权限。从上面的信息来看,只有文件所有者可以修改(w
),missing
文件夹 (例如,添加或删除文件夹中的文件)。为了进入某个文件夹,用户需要具备该文件夹以及其父文件夹的“搜索”权限(以“可执行”:x
)权限表示。为了列出它的包含的内容,用户必须对该文件夹具备读权限(r
)。对于文件来说,权限的意义也是类似的。注意,/bin
目录下的程序在最后一组,即表示所有人的用户组中,均包含 x
权限,也就是说任何人都可以执行这些程序。
在这个阶段,还有几个趁手的命令是您需要掌握的,例如 mv
(用于重命名或移动文件,move)、 cp
(拷贝文件,copy)以及 mkdir
(新建文件夹,make directory)。
如果您想要知道关于程序参数、输入输出的信息,亦或是想要了解它们的工作方式,请试试 man
这个程序。它会接受一个程序名作为参数,然后将它的文档(用户手册)展现给您。注意,使用 q
可以退出该程序。
missing:~$ man ls
4、在程序间创建连接
在 shell 中,程序有两个主要的“流”:它们的输入流和输出流。 当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。 通常,一个程序的输入输出流都是您的终端。也就是,您的键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流!
最简单的重定向是 < file
和 > file
。这两个命令可以将程序的输入输出流分别重定向到文件:
missing:~$ echo hello > hello.txt
missing:~$ cat hello.txt
hello
missing:~$ cat < hello.txt
hello
missing:~$ cat < hello.txt > hello2.txt
missing:~$ cat hello2.txt
hello
您还可以使用 >>
来向一个文件追加内容。使用管道( pipes ),我们能够更好的利用文件重定向。 |
操作符允许我们将一个程序的输出和另外一个程序的输入连接起来:
missing:~$ ls -l / | tail -n1
drwxr-xr-x 1 root root 4096 Jun 20 2019 var
missing:~$ curl --head --silent google.com | grep --ignore-case content-length | cut --delimiter=' ' -f2
219
我们会在数据清理一章中更加详细的探讨如何更好的利用管道。
5、一个功能全面又强大的工具
对于大多数的类 Unix 系统,有一类用户是非常特殊的,那就是:根用户(root user)。 您应该已经注意到了,在上面的输出结果中,根用户几乎不受任何限制,他可以创建、读取、更新和删除系统中的任何文件。 通常在我们并不会以根用户的身份直接登录系统,因为这样可能会因为某些错误的操作而破坏系统。 取而代之的是我们会在需要的时候使用 sudo
命令。顾名思义,它的作用是让您可以以 su(super user 或 root 的简写)的身份执行一些操作。 当您遇到拒绝访问(permission denied)的错误时,通常是因为此时您必须是根用户才能操作。然而,请再次确认您是真的要执行此操作。
有一件事情是您必须作为根用户才能做的,那就是向 sysfs
文件写入内容。系统被挂载在 /sys
下,sysfs
文件则暴露了一些内核(kernel)参数。 因此,您不需要借助任何专用的工具,就可以轻松地在运行期间配置系统内核。注意 Windows 和 macOS 没有这个文件
例如,您笔记本电脑的屏幕亮度写在 brightness
文件中,它位于
/sys/class/backlight
通过将数值写入该文件,我们可以改变屏幕的亮度。现在,蹦到您脑袋里的第一个想法可能是:
$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*' //以root权限在/sys/class/backlight目录及其直接子目录中(maxdepth)搜索名称包含brightness的所有文件,包括符号链接指向的文件(-l)。
/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen
$ sudo echo 3 > brightness
An error occurred while redirecting file 'brightness'
open: Permission denied
出乎意料的是,我们还是得到了一个错误信息。毕竟,我们已经使用了 sudo
命令!关于 shell,有件事我们必须要知道。|
、>
、和 <
是通过 shell 执行的,而不是被各个程序单独执行。 echo
等程序并不知道 |
的存在,它们只知道从自己的输入输出流中进行读写。 回到上面更改屏幕亮度命令执行的报错,为了能让 sudo echo
命令输出的亮度值写入 brightness 文件, shell (权限为当前用户) 会先尝试打开 brightness 文件,但此时操作 shell 的不是根(root)用户,所以系统拒绝了这个打开操作,提示无权限。
明白这一点后,我们可以这样操作:
$ echo 3 | sudo tee brightness
此时打开 /sys
文件的是 tee
这个程序,并且该程序以 root
权限在运行,因此操作可以进行。 这样您就可以在 /sys
中愉快地玩耍了,例如修改系统中各种LED的状态(路径可能会有所不同):
$ echo 1 | sudo tee /sys/class/leds/input6::scrolllock/brightness
6、命令概述:
date: 显示时间
echo:打印,声明
$PATH:环境变量
..:上级目录
.:当前目录
pwd:获取当前工作目录(present work directory)
ls:查看当前目录下的文件(list,-l参数以列表形式提供信息,-h提供帮助文档)
mv(用于重命名或移动文件,move)、
cp(拷贝文件,copy)以及
mkdir`(新建文件夹,make directory)。
man:后加程序名,显示该程序的帮助文档(manual)
<:重定向输出流;>:重定向输入流;>>:重定向并追加内容
|:将左边的输出作为右边的输入
tee:多输出,(T型管道),输出到多个位置
touch:在当前目录新建空文件
cat:查看一个文件的内容(catch)
tail -n:
格式:tail [options] [file]
常用参数:-n, --lines=[+]NUM:输出文件的最后NUM行。如果NUM前面有+,则从文件的第NUM行开始输出到文件末尾。
grep:根据特定的模式(通常是正则表达式)搜索一个或多个文件中的文本.
格式:grep [options] pattern [file...]
在文件
example.txt
中搜索字符串 “hello”:grep "hello" example.txt
chmod:在Linux和Unix系统中更改文件或目录的权限。
数字表示法:
`4` - 读权限(read)
`2` - 写权限(write)
`1` - 执行权限(execute)
`0` - 无权限
示例:
给文件所有者读和写权限,给组和其他用户只读权限:
chmod 644 filename
文字表示法:
u
- 文件所有者(user)g
- 组(group)o
- 其他用户(others)a
- 所有人(all)
操作符:
+
- 添加权限-
- 移除权限=
- 设置权限
示例:
给文件所有者添加执行权限:
chmod u+x filename
作业相关情况
作业的第十题做不了,原因在于linux虚拟机的内核是模拟出来的,内核并不存在。其他的借助gpt都可完成