参考链接
- 🔗:The Missing Semester of Your CS Education 中文版
- 🔗:The Missing Semester of Your CS Education
- 🔗:课程中文字幕视频
- 🔗:Terminal VS Shell
- 🔗:MIT: Missing Semester of CS Education - Lecture 1
- 🔗:chmod指令
- 🔗:Missing-Semester of CS Education 第一次作业
What is the shell?
The shell is a program that takes commands from the keyboard and gives them to the operating system to perform.
When launching the terminal, we see a prompt, that is the main textual interface to the shell.
为了更清楚地展示高亮要求,我会在下面的文本中将英文名词和符号用高亮
表示:
Using the shell
1 | missing:~$ |
这是 shell
最主要的文本接口。它告诉你,你的主机名是 missing
并且您当前的工作目录(”current working directory
”)或者说您当前所在的位置是 ~
(表示 “home
”)
date
1 | (base) chenyubin@chenyubindeMacBook-Pro ~ % date |
这里,我们执行了 date
这个程序,不出意料地,它打印出了当前的日期和时间
echo
1 | (base) chenyubin@chenyubindeMacBook-Pro ~ % echo hellop |
echo
程序将该参数打印出来。 shell
基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数.
PATH
shell
是如何知道去哪里寻找 date
或 echo
的呢?其实,类似于 Python
或 Ruby
,shell
是一个编程环境,所以它具备变量、条件、循环和函数(下一课进行讲解)。当你在 shell
中执行命令时,您实际上是在执行一段 shell
可以解释执行的简短代码。如果你要求 shell
执行某个指令,但是该指令并不是 shell
所了解的编程关键字,那么它会去咨询 环境变量 $PATH
,它会列出当 shell
接到某条指令时,进行程序搜索的路径1
2(base) chenyubin@chenyubindeMacBook-Pro ~ % echo $PATH
/Users/chenyubin/anaconda3/bin:/Users/chenyubin/anaconda3/condabin:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/usr/local/mysql/bin
当我们执行 echo
命令时,shell
了解到需要执行 echo
这个程序,随后它便会在 $PATH
中搜索由 :
所分割的一系列目录,基于名字搜索该程序。当找到该程序时便执行
which
确定某个程序名代表的是哪个具体的程序,可以使用 which
程序,MacOS
中为where
1
2
3(base) chenyubin@chenyubindeMacBook-Pro ~ % where echo
echo: shell built-in command
/bin/echo
Shell中导航
shell
中的路径是一组被分割的目录,在 Linux
和 macOS
上使用 /
分割,而在Windows
上是 \
。路径 /
代表的是系统的根目录,所有的文件夹都包括在这个路径之下,在Windows
上每个盘都有一个根目录(例如: C:\
)。
Linux
文件系统下,如果某个路径以 /
开头,那么它是一个 绝对路径
,其他的都是 相对路径
。相对路径是指相对于当前工作目录的路径
在路径中,.
表示的是当前目录,而 ..
表示上级目录
。
pwd
你可以使用 pwd
(print working directory)来查看当前的工作目录1
2(base) chenyubin@chenyubindeMacBook-Pro ~ % pwd
/Users/chenyubin
ls
要列出一个目录中的文件,可以使用 ls
程序。如果不带任何参数,ls
会列出当前目录中的文件。1
2
3
4
5(base) chenyubin@chenyubindeMacBook-Pro ~ % ls
Applications Library Public
Desktop Movies chromedriver
Documents Music docker-compose.yml
Downloads Pictures postman
除非我们利用第一个参数指定目录,否则 ls 会打印当前目录下的文件。大多数的命令接受标记和选项(带有值的标记),它们以 - 开头,并可以改变程序的行为。
1 | (base) chenyubin@chenyubindeMacBook-Pro ~ % ls -l |
这个参数可以更加详细地列出目录下文件或文件夹的信息。首先,本行第一个字符 d 表示 当前 是一个目录。
然后接下来的九个字符,每三个字符构成一组。 (rwx). 它们分别代表了文件所有者(当前目录),用户组(users) 以及其他所有人具有的权限。其中 - 表示该用户不具备相应的权限。为了进入某个文件夹,用户需要具备该文件夹以及其父文件夹的“搜索”权限(以“可执行”:x)权限表示。为了列出它的包含的内容,用户必须对该文件夹具备读权限(r)。对于文件来说,权限的意义也是类似的。
cd
要改变当前工作目录,使用 cd
(change directory)命令1
2(base) chenyubin@chenyubindeMacBook-Pro ~ % cd Desktop
(base) chenyubin@chenyubindeMacBook-Pro Desktop %
为了更清楚地展示高亮要求,我会在下面的文本中将英文名词和符号用高亮
表示:
man
如果您想要知道关于程序参数、输入输出的信息,亦或是想要了解它们的工作方式,请试试 man
这个程序。它会接受一个程序名作为参数,然后将它的文档(用户手册)展现给您。注意,使用 q
可以退出该程序
1 | (base) chenyubin@chenyubindeMacBook-Pro ~ % man ls |
程序间的连接
在 shell
中,程序有两个主要的“流”:它们的输入流和输出流。 当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。 通常,一个程序的输入输出流都是您的终端。也就是,您的键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流!
< file
和 > file
最简单的重定向是 < file
和 > file
。这两个命令可以将程序的输入输出流分别重定向到文件:
1 | (base) chenyubin@chenyubindeMacBook-Pro desktop % echo hello > hello.txt |
|
使用管道(pipes
),我们能够更好的利用文件重定向。 |
操作符允许我们将一个程序的输出和另外一个程序的输入连接起来:1
2(base) chenyubin@chenyubindeMacBook-Pro desktop % ls -l / | tail -n1
lrwxr-xr-x@ 1 root wheel 11 9 16 15:48 var -> private/var
sudo
顾名思义,它的作用是让您可以以 su
(super user
或 root
的简写)的身份执行一些操作。 当您遇到拒绝访问(permission denied
)的错误时,通常是因为此时您必须是根用户才能操作。然而,请再次确认您是真的要执行此操作。
课后练习
在 /tmp
下新建一个名为 missing
的文件夹
1 | (base) chenyubin@chenyubindeMacBook-Pro desktop % cd /tmp |
用 man
查看程序 touch
的使用手册。
1 | (base) chenyubin@chenyubindeMacBook-Pro /tmp % man touch |
touch和mkdir区别:
- touch新建文件
- mkdir新建目录/文件夹(directory)
用 touch
在 missing
文件夹中新建一个叫 semester
的文件。
1 | (base) chenyubin@chenyubindeMacBook-Pro /tmp % cd missing |
将以下内容一行一行地写入 semester
文件:
1 | `#!/bin/sh` |
1 | (base) chenyubin@chenyubindeMacBook-Pro missing % echo \#'!'/bin/sh > semester |
尝试执行这个文件。例如,将该脚本的路径(./semester
)输入到您的shell
中并回车。如果程序无法执行,请使用 ls
命令来获取信息并理解其不能执行的原因。
1 | (base) chenyubin@chenyubindeMacBook-Pro missing % ./semester |
无法执行,原因是文件所有者无执行权限(权限为rw-,只可读写)
查看 chmod
的手册(例如,使用 man chmod
命令)
使用 chmod
命令改变权限,使 ./semester
能够成功执行,不要使用 sh semester
来执行该程序。您的 shell
是如何知晓这个文件需要使用 sh
来解析呢?更多信息请参考:shebang
1 | (base) chenyubin@chenyubindeMacBook-Pro missing % ls -l |
使用 |
和 >
,将 semester
文件输出的最后更改日期信息,写入主目录下的 last-modified.txt
的文件中
1 | ./semester | grep -i "last-modified" > /home/last-modified.txt |