欢迎光临散文网 会员登陆 & 注册

[MIT]计算机科学课堂中学不到的知识 The Missing Semester

2022-12-08 15:01 作者:渚_花  | 我要投稿

前注:

此笔记内容来自BV1x7411H7wa


本视频几乎所有操作都是在linux系统上运行,如果想体验一下的话,可能需要安装linux系统,或安装linux虚拟机

屏幕显示内容、脚本内容、代码内容使用

```

此处为脚本内容

```

加以标注


大多数平台都提供了Shell, 例如在Windows上有 PowerShell。但是也可以找到别的shell可用,例如bash 。MacOS 通常也有bash的旧版本。

注:PowerShell在资源管理器(打开文件夹)页面,长按Shift,在空白位置右键,即可打开PowerShell


本视频以 Linux 的 Terminal 为例。

注: 终端(terminal)的作用是提供一个命令的输入输出环境,在linux下可使用ctrl+alt+T; shell 是一个命令行解释器,是linux系统的一个外壳,负责外界与linux内核的交互。shell接受用户或者其他应用程序的命令,然后将命令转化为内核能理解的语言并传给内核,内核执行命令完成后,将结果返回给用户或者应用程序。当我们在terminal输入命令后,shell会负责解释命令。

—— https://blog.csdn.net/weixin_38214171/article/details/90050340

Terminal的外观大致像这样


只有在顶部有一行,这就是所谓的shell prompt(shell 提示/shell指令),其中包括用户名,当前使用的机器名字,以及(下文将会提到的)path(路径)

```

[jon@xpanse missing-semester]$ 

```


你可以自定义配置shell prompt。如果你配置了一些设置之后,shell prompt可能看起来像这样(视频并没有介绍怎么配置,只是略微说了一下)

&6:32 


shell可以执行命令。例如 输入命令 date ,屏幕会打印日期和时间

```

[jon@xpanse missing-semester]$ date

Mon 13 Jan 2020 02:12:55 PM EST

[jon@xpanse missing-semester]$ 

```


shell 也可以执行带有参数(argument)的程序,增加参数可以修改程序的行为。

指令echo 可以打印你列出的参数, 参数只需要空格分隔即可

注: argument 在这里不是“论点”“论据”,视频字幕有误

```

[jon@xpanse missing-semester]$ echo hello

hello

[jon@xpanse missing-semester]$ echo "Hello world"

```

如果参数中带有空格,可以将参数用(英文标点)单引号或双引号括起来,这样即使中间具有空格,也会作为一个参数传输。或者用反斜杠(转义符)将空格转义(escape)。下面两个指令执行结果相同。

```

[jon@xpanse missing-semester]$ echo "Hello world"

[jon@xpanse missing-semester]$ echo hello\ World

```

注:按照弹幕说法以及本人实际实验,PowerShell不能用反斜杠转义空格。

此视频的大多数操作都是针对于linux系统的,有些不能在PowerShell上使用

你可能想知道shell怎么知道这些程序是应该怎样执行的。是这样的,你的电脑中有很多的内置程序(built-in program / builtin program),存储于文件系统中。shell有一套叫做invariant (恒定的,不变的)environment variable(环境变量)的东西用来检索这些内置程序的位置。环境变量可用于(BASH)编程语言。


事实上,Bourne Again SHell(简称BASH)真的是一种编程语言。你打出的shell prompt(shell提示/shell指令)并不是仅仅可以运行带参数的程序,你也可以使用while循环(while loop)或for循环(for loop)以及条件语句(conditionals),也可以使用变量(variable)。下一个讲座将会有很多关于shell脚本的内容。

注: Bourne Again Shell是作为GUN项目开发的,诞生于1987年。许多Linux发行版很快就采用了它。—— https://www.aoetc.com/117a48.html


环境变量储存着,你的主目录、你的用户名等信息存储的位置。

```

[jon@xpanse missing-semester]$ echo $PATH

/usr/local/sbin:usr/local/bin:/usr/bin:/bin:/opt/inter/vtune_

后面内容省略

[jon@xpanse missing-semester]$ 

```

用美元符号(dollar)+PATH,这样可以打印(show)机器上所有路径。

PATH变量是一个存储着路径的列表,以冒号分隔,shell会从这些路径中寻找程序。每当你输入一个程序名字时,shell会从这些路径中搜索,找到符合名字的程序并运行。

可以用which命令找到指令的位置。

```

[jon@xpanse missing-semester]$ which echo

/usr/bin/echo

[jon@xpanse missing-semester]$

```

路径(path)是表示文件在计算机上的位置的方式。在Linux和MacOS上,这些路径以正斜杠(slash)分隔,而Windows路径上通常以反斜杠(back slash)分隔。在路径最开始的正斜杠表示是文件系统的顶部。echo在文件系统顶部下的usr目录(directory)下的bin目录下。Windows的路径上通常有多个根目录(root),例如C:\\和D:\\,每一个驱动器(Drive)是一个根目录。Windows具有不同的路径层次结构(file system path hierarchies)。而Linux的驱动器全部安装在一个名字空间下。


绝对路径(absolute paths)(与概念”相对路径“相对应)是完全确定一个文件位置的路径。例如上面的echo的路径就是一个绝对路径。还有一个东西叫做“相对路径”(relative paths),相对路径与你当前所在的位置相关。

指令 pwd (present working directory)可以打印当前的工作目录。

指令cd可以更改当前目录

```

[jon@xpanse missing-semester]$ pwd

/home/jon/dev/pdos/classs/missing-semester

[jon@xpanse missing-semester]$ cd /home

[jon@xpanse home]$ pwd

/home

[jon@xpanse home]$ 

```

有一些特殊地址,一个点(.)和两个点(..)。一个点表示当前目录,两个点表示父目录。

./home 表示当前目录下名为home的子目录

```

[jon@xpanse home]$ cd ..

[jon@xpanse /]$ pwd

/

[jon@xpanse]$ cd ./home

[jon@xpanse home]$ 

[jon@xpanse home]$ cd ./home

bash: cd: ./home: No such file or dierctory

[jon@xpanse home]$ cd jon/dev/pdos/classes/missing-semester/

[jon@xpanse missing-semester]$ ../../../../../bin/echo world

world

[jon@xpanse missing-semester]$ 

```

指令ls可以打印出当前路径下的所有文件

```

[jon@xpanse missing-semester]$ ls

404.html  data-wrangling.md  lectures.html  

后面内容省略

[jon@xpanse missing-semester]$ cd ..

[jon@xpanse classes]$ ls

6.824 6.828 6.858 6.HT grade missing-semester web-submit

[jon@xpanse classes]$ 

```

ls 后面可以带有参数,例如下面的示例,以当前文件夹的父文件夹 .. 为参数

```

[jon@xpanse missing-semester]$ ls ..

6.824 6.828 6.858 6.HT grade missing-semester web-submit

[jon@xpanse missing-semester]$ 

```

还有一些字符,例如波浪线字符(tilde character, ~)可以带你回到home目录。例如这里,~指的是 /home/jon

可以传给指令cd 参数dash(减号,横杠,-)可以返回到上一次的目录中

注: cd - PowerShell不可用

```

[jon@xpanse /]$ cd ~/dev/pdos/classes/missing-semester

[jon@xpanse missing-semester]$ cd -

/

[jon@xpanse /]$ cd -

/home/jon/dev/pdos/classes/missing-semester

[jon@xpanse missing-semester]$ 

```

大多数程序都可以以 --help 作为参数,以打印帮助内容

```

[jon@xpanse missing-semester]$ ls --help

Usage: ls [OPTION]... [FILE]...

中间内容省略

-l     use a long listing format

中间内容省略

[jon@xpanse missing-semester]$ 

```

例如,帮助中有这样一条 -l  use a long listing format,我们可以实际试验一下。

```

[jon@xpanse missing-semester]$ ls -l

部分内容省略

-rw-r--r-- 1 jon jon  102 Dec 5 14:05 404.html

drwxr-xr-x 1 jon jon  24 Jan 13 12:41 _data

-rw-r--r-- 1 jon jon 18647 Dec 5 14:06 static

-rw-r--r-- 1 jon jon 5671 Dec 28 06:50 virtual-machines.md

-rw-r--r-- 1 jon jon 10073 Dec 5 14:06 web.md

```

我们来看一下这些是什么意思。条目(entries)开头的d表示这是一个目录(directory),所以这里的 \_data 是一个目录,而这里的 404.html 不是一个目录。


```

drwxr-xr-x 1 jon jon  24 Jan 13 12:42 _data

```

第一个字符  d: 是否是文件夹,

二—五字符 rwx: 该文件对于文件所有者的权限

六—八字符 -xr: 该文件对于拥有此文件的组(group)所具有的的权限

九—11字符 r-x: 该文件对于其余所有人的权限


第一个 jon : 文件所有者

第二个 jon : 拥有此文件的组


对于文件:

r : 可以读此文件

w: 可以写此文件

x : 可以执行此文件

\- : 无相应权限


例如, ls -l /bin 中的所有文件都具有 x 权限,因为这个目录下 echo 等指令应该给所有用户开放使用。


对于文件夹:

r : 可以查看有哪些文件在此文目录中

w: 可以重命名、创建或者删除此目录中的文件

x : 如果该目录,及其所有父目录都具有 x 权限,该目录下的文件才可以执行


如果仅具有一个文件的 w 权限,但是没有其所在目录的 w 权限,你只可以清空(empty, v.)它,但不能删除它,因为这会修改目录本身。


部分目录的第一个字母 l 几乎与本次讲座没什么关系,如果好奇的话,请自己查询资料或讲座结束后单独来办公室询问。

注:第一个字符代表文件类型,d是文件夹,l是链接文件,-是普通文件 —— https://blog.csdn.net/chiwen8728/article/details/100649290


mv可以用来移动或重命名文件。例如下面的示例,将 dotfiles.md重命名为foo.md,然后又修改了回去。

```

[jon@xpanse missing-semester]$ ls


[jon@xpanse missing-semester]$ mv dotfiles.md foo.md

[jon@xpanse missing-semester]$ mv foo.md dotfiles.md

```

还有cp指令,可以复制文件

```

[jon@xpanse missing-semester]$ cp dotfiles.md ../food.md

[jon@xpanse missing-semester]$ ls ..

6.824 6.828 6.858 6.HT food.md grade missing-semester web-submit

[jon@xpanse missing-semester]$ 

```

rm指令可以移除文件

```

[jon@xpanse missing-semester]$ rm ../food.md

[jon@xpanse missing-semester]$ 

```

在linux上,rm指令默认是不能递归(recursion)的,所以不能通过传入目录作为rm 的参数来删除目录。可以传入-r 标记(flag)即可递归删除,即删除一个目录下所有内容。


rmdir指令可以用来删除目录。如果该目录为空,则会成功删除该目录;

下面是本人在虚拟机上的示例

```

j****@j****-virtual-machine:~$ rm Lab2

rmdir: failed to remove 'Lab2': Directory not empty

j****@j****-virtual-machine:~$

```

mkdir 指令可以用于创建新目录。例如,下面的指令会创建两个目录,分别名为 My 和 Photos。

```

[jon@xpanse missing-semester]$ mkdir My Photos

```

man 指令(manual)接受另一个指令作为参数,然后向你展示该指令的参数。

```

[jon@xpanse missing-semester]$ man ls

```

man ls 和 ls --help 相似,只是 man 更容易阅读,同时还具有示例。

#清屏 

Ctrl+L 可以清除终端。


也许你可能需要将多个程序链接在一起,或者与文件操作等需求,而shell给出的流(stream)这个概念可以解决这个问题。每个程序都有两个流,分别为输入流(input stream)和输出流(output stream)。


通常输入流来自于键盘,通过终端输入进程序。而当程序尝试打印一些东西时,会打印到输出流中。


shell 提供了可以重定向输入流和输出流的方式:使用尖括号标志(angle bracket ,<>)。

```

[jon@xpanse missing-semester]$ echo hello > hello.txt

[jon@xpanse missing-semester]$ 

```

然后shell就会创建一个文件叫 hello.txt ,里面的内容是 

```

hello

```

指令 cat 打印文件的内容

弹幕: cat 是  concatenate 的缩写

```

[jon@xpanse missing-semester]$ cat hello.txt

hello

[jon@xpanse missing-semester]$ 

```

cat 也可以复制(duplicate)它的输入到输出

```

[jon@xpanse missing-semester]$ cat < hello.txt

hello

[jon@xpanse missing-semester]$ 

```

cat也可以用来复制文件

```

[jon@xpanse missing-semester]$ cat < hello.txt > hello2.txt

[jon@xpanse missing-semester]$ cat hello2.txt

hello

[jon@xpanse missing-semester]$ 

```

程序cat并不知道输入和输出是否被重定向


>>也可以用来输出,但是是在文件后面追加,而不是覆盖文件

```

[jon@xpanse missing-semester]$ cat < hello.txt > hello2.txt

[jon@xpanse missing-semester]$ cat hello2.txt

hello

[jon@xpanse missing-semester]$ cat < hello.txt >> hello2.txt

[jon@xpanse missing-semester]$ cat hello2.txt

hello

hello

[jon@xpanse missing-semester]$ 

```

管道符号(pipe character, vertical bar, |)的含义是,将左面程序的输出,作为右面程序的输出,

指令 tail 打印输入的最后1行

注:

通常tail 打印最后10行。tail -n1 打印最后一行

-n\[+\]NUM

n后面可以跟参数决定输出的行数,或是通过跟加号跟参数,输出指定的行数之后的所有行。

```

[jon@xpanse missing-semester]$ ls -l / | tail -n1

drwxr-xr-x  1 root root  116 Jan 13 10:57 var

[jon@xpanse missing-semester]$ 

```

在这里ls不知道tail, tail也不知道 ls,它们是不同的程序,也没有通过互相兼容来共同运行,仅仅是对输入进行处理,并输出。

管道符号将wires(直译为电线)连接到一起。在这里,ls的输出(output)连接到tail的输入(input),tail的输出输出到terminal

我们也可以将tail的输出重定向(reware)到文件当中

```

[jon@xpanse missing-semester]$ ls -l / | tail -n1 > ls.txt

[jon@xpanse missing-semester]$ 

```


注:使用↑方向键可以调出刚刚执行过的指令

[jon@xpanse missing-semester]$ curl --head --silent | grep -i content-length

content-lentgh: 219

[jon@xpanse missing-semester]$ curl --head --silent | grep -i content-length | cut --delimiter=' ' -f2

219

[jon@xpanse missing-semester]$ 

```

管道符号不仅仅可以作用于文本,也可以作用于图像之类的东西


Linux的root user相当于Windows上的管理员用户,其用户ID为0 

root用户可以对文件系统做任何事,即使文件不具有读写权限

大多数时候,不会使用root权限,因为root权限很危险。

sudo 指令可以允许你用root权限执行指令。sudo意思是do as su,而su指的是super user 

弹幕:

sudo是substitute do ,不是super user do

<-两种说法都有

switch user do


如果你切换到 cd /sys 这是一个全新的世界

```

[jon@xpanse missing-semester]$ cd /sys

[jon@xpanse sys]$ ls

block bus class dev devices firmware fs hypervisor kernel module power

[jon@xpanse sys]$ 

```

这里的文件实际上并不是文件,而是内核(kernel)参数,即计算机的核心。这里可以查看内核参数,看上去就像文件系统一样

```

[jon@xpanse sys]$ cd class/

[jon@xpanse class]$ ls

backlight dmi input nvme-subsystem remoteproc typec

下面内容省略

[jon@xpanse sys]$ cd backlight/

[jon@xpanse backlight]$ ls

intel_backlight

[jon@xpanse backlight]$ cd intel_backlight/

[jon@xpanse inter_backlight]$ ls

actual_brightness brightness max_brightness scale type

bl_power device power subsystem uevent

[jon@xpanse inter_backlight]$ cat brightness

1060

[jon@xpanse inter_backlight]$ cat max_brightness

1060

[jon@xpanse inter_backlight]$ echo 500 > brightness

bash: brightness: Permission denied

[jon@xpanse inter_backlight]$ 

```

例如,这个backlight可以直接调节笔记本电脑上的背光。

你可能想到用指令 sudo 来修改,但是不可行

```

[jon@xpanse inter_backlight]$ sudo echo 500 > brightness

bash: brightness: Permission denied

[jon@xpanse inter_backlight]$ 

```

原因是,在这里,程序 sudo 执行的是 echo 500,将输出发送到名为 brightness的文件,然而打开brightness的并不是 sudo 程序。所以此时出现了权限下降错误(permission down error)。

```

[jon@xpanse inter_backlight]$ echo 1 > /sys/net/ipv4_forward

```

这个指令可以用来设置防火墙。如果前面是英镑符号的话,这个指令可以运行。dollar符号表示你没有以root用户身份运行。

注:我也不知道为啥他管\#符号叫英镑符号

sudo su指令可以切换为超级用户(super user)模式。切换为超级用户模式之后,用户名从原来的jon切换为了root,同时美元符号变成了英镑符号。

```

[jon@xpanse inter_backlight]$ sudo su 

[sudo] password for jon:

[root@xpanse inter_backlight]# echo 500 > brightness

[root@xpanse inter_backlight]# exit

[jon@xpanse inter_backlight]$ 

```

据讲师所说,屏幕亮度变暗了,但是从视频中看不到。


```

[jon@xpanse inter_backlight]$ echo 1060 | sudo tee brightness

1060

[jon@xpanse inter_backlight]$ 

```

tee命令获取输入并写入到指定的文件中,可用来存储日志文件。

可以用find指令

```

[jon@xpanse inter_backlight]$ cd ..

[jon@xpanse backlight]$ cd leds/

[jon@xpanse leds]$ ls

input4::capslock phy0-led tpacpi::kbd_backlight tpacpi::thinklight

下面内容省略

[jon@xpanse leds]$ cd input4\:\scrolllock

```

也许大多数人不知道什么是scrolllock,也许你在键盘上看到这样一个scrolllock的按键,但是大家不知道这个键是干什么的。这个键已经成了死键了。

```

[jon@xpanse input4::scrolllock]$ cat brightness

0

[jon@xpanse input4::scrolllock]$ echo 1 | sudo tee brightness

1

[jon@xpanse input4::scrolllock]$ 

```

如果你想设置为,每当收到 email 的时候,scrolllock LED 闪烁的话,可以弄一个程序用来检查是否收集到 email ,然后将输出使用管道字符输出到 sudo tee brightness 中

```

[jon@xpanse missing-semester]$ xdg-open lectures.html

```

xdg-open,这个指令只在linux和macOS上起作用,在windows上叫做open 。这个指令会使用合适的方式打开指定的文件。


---


下节预告:如何完成自动化之类的任务、如何编写运行一堆程序的脚本,如何实现条件语句和循环语句


---


おわり




[MIT]计算机科学课堂中学不到的知识 The Missing Semester的评论 (共 条)

分享到微博请遵守国家法律