[MIT]計(jì)算機(jī)科學(xué)課堂中學(xué)不到的知識(shí) The Missing Semester

前注:
此筆記內(nèi)容來(lái)自BV1x7411H7wa
本視頻幾乎所有操作都是在linux系統(tǒng)上運(yùn)行,如果想體驗(yàn)一下的話,可能需要安裝linux系統(tǒng),或安裝linux虛擬機(jī)
屏幕顯示內(nèi)容、腳本內(nèi)容、代碼內(nèi)容使用
```
此處為腳本內(nèi)容
```
加以標(biāo)注
大多數(shù)平臺(tái)都提供了Shell, 例如在Windows上有 PowerShell。但是也可以找到別的shell可用,例如bash 。MacOS 通常也有bash的舊版本。
注:PowerShell在資源管理器(打開(kāi)文件夾)頁(yè)面,長(zhǎng)按Shift,在空白位置右鍵,即可打開(kāi)PowerShell
本視頻以 Linux 的 Terminal 為例。
注: 終端(terminal)的作用是提供一個(gè)命令的輸入輸出環(huán)境,在linux下可使用ctrl+alt+T; shell 是一個(gè)命令行解釋器,是linux系統(tǒng)的一個(gè)外殼,負(fù)責(zé)外界與linux內(nèi)核的交互。shell接受用戶或者其他應(yīng)用程序的命令,然后將命令轉(zhuǎn)化為內(nèi)核能理解的語(yǔ)言并傳給內(nèi)核,內(nèi)核執(zhí)行命令完成后,將結(jié)果返回給用戶或者應(yīng)用程序。當(dāng)我們?cè)趖erminal輸入命令后,shell會(huì)負(fù)責(zé)解釋命令。
—— https://blog.csdn.net/weixin_38214171/article/details/90050340
Terminal的外觀大致像這樣
只有在頂部有一行,這就是所謂的shell prompt(shell 提示/shell指令),其中包括用戶名,當(dāng)前使用的機(jī)器名字,以及(下文將會(huì)提到的)path(路徑)
```
[jon@xpanse missing-semester]$?
```
你可以自定義配置shell prompt。如果你配置了一些設(shè)置之后,shell prompt可能看起來(lái)像這樣(視頻并沒(méi)有介紹怎么配置,只是略微說(shuō)了一下)
&6:32?
shell可以執(zhí)行命令。例如 輸入命令 date ,屏幕會(huì)打印日期和時(shí)間
```
[jon@xpanse missing-semester]$ date
Mon 13 Jan 2020 02:12:55 PM EST
[jon@xpanse missing-semester]$?
```
shell 也可以執(zhí)行帶有參數(shù)(argument)的程序,增加參數(shù)可以修改程序的行為。
指令echo 可以打印你列出的參數(shù), 參數(shù)只需要空格分隔即可
注: argument 在這里不是“論點(diǎn)”“論據(jù)”,視頻字幕有誤
```
[jon@xpanse missing-semester]$ echo hello
hello
[jon@xpanse missing-semester]$ echo "Hello world"
```
如果參數(shù)中帶有空格,可以將參數(shù)用(英文標(biāo)點(diǎn))單引號(hào)或雙引號(hào)括起來(lái),這樣即使中間具有空格,也會(huì)作為一個(gè)參數(shù)傳輸?;蛘哂梅葱备埽ㄞD(zhuǎn)義符)將空格轉(zhuǎn)義(escape)。下面兩個(gè)指令執(zhí)行結(jié)果相同。
```
[jon@xpanse missing-semester]$ echo "Hello world"
[jon@xpanse missing-semester]$ echo hello\ World
```
注:按照彈幕說(shuō)法以及本人實(shí)際實(shí)驗(yàn),PowerShell不能用反斜杠轉(zhuǎn)義空格。
此視頻的大多數(shù)操作都是針對(duì)于linux系統(tǒng)的,有些不能在PowerShell上使用
你可能想知道shell怎么知道這些程序是應(yīng)該怎樣執(zhí)行的。是這樣的,你的電腦中有很多的內(nèi)置程序(built-in program / builtin program),存儲(chǔ)于文件系統(tǒng)中。shell有一套叫做invariant (恒定的,不變的)environment variable(環(huán)境變量)的東西用來(lái)檢索這些內(nèi)置程序的位置。環(huán)境變量可用于(BASH)編程語(yǔ)言。
事實(shí)上,Bourne Again SHell(簡(jiǎn)稱BASH)真的是一種編程語(yǔ)言。你打出的shell prompt(shell提示/shell指令)并不是僅僅可以運(yùn)行帶參數(shù)的程序,你也可以使用while循環(huán)(while loop)或for循環(huán)(for loop)以及條件語(yǔ)句(conditionals),也可以使用變量(variable)。下一個(gè)講座將會(huì)有很多關(guān)于shell腳本的內(nèi)容。
注: Bourne Again Shell是作為GUN項(xiàng)目開(kāi)發(fā)的,誕生于1987年。許多Linux發(fā)行版很快就采用了它?!?https://www.aoetc.com/117a48.html
環(huán)境變量?jī)?chǔ)存著,你的主目錄、你的用戶名等信息存儲(chǔ)的位置。
```
[jon@xpanse missing-semester]$ echo $PATH
/usr/local/sbin:usr/local/bin:/usr/bin:/bin:/opt/inter/vtune_
后面內(nèi)容省略
[jon@xpanse missing-semester]$?
```
用美元符號(hào)(dollar)+PATH,這樣可以打印(show)機(jī)器上所有路徑。
PATH變量是一個(gè)存儲(chǔ)著路徑的列表,以冒號(hào)分隔,shell會(huì)從這些路徑中尋找程序。每當(dāng)你輸入一個(gè)程序名字時(shí),shell會(huì)從這些路徑中搜索,找到符合名字的程序并運(yùn)行。
可以用which命令找到指令的位置。
```
[jon@xpanse missing-semester]$ which echo
/usr/bin/echo
[jon@xpanse missing-semester]$
```
路徑(path)是表示文件在計(jì)算機(jī)上的位置的方式。在Linux和MacOS上,這些路徑以正斜杠(slash)分隔,而Windows路徑上通常以反斜杠(back slash)分隔。在路徑最開(kāi)始的正斜杠表示是文件系統(tǒng)的頂部。echo在文件系統(tǒng)頂部下的usr目錄(directory)下的bin目錄下。Windows的路徑上通常有多個(gè)根目錄(root),例如C:\\和D:\\,每一個(gè)驅(qū)動(dòng)器(Drive)是一個(gè)根目錄。Windows具有不同的路徑層次結(jié)構(gòu)(file system path hierarchies)。而Linux的驅(qū)動(dòng)器全部安裝在一個(gè)名字空間下。
絕對(duì)路徑(absolute paths)(與概念”相對(duì)路徑“相對(duì)應(yīng))是完全確定一個(gè)文件位置的路徑。例如上面的echo的路徑就是一個(gè)絕對(duì)路徑。還有一個(gè)東西叫做“相對(duì)路徑”(relative paths),相對(duì)路徑與你當(dāng)前所在的位置相關(guān)。
指令 pwd (present working directory)可以打印當(dāng)前的工作目錄。
指令cd可以更改當(dāng)前目錄
```
[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]$?
```
有一些特殊地址,一個(gè)點(diǎn)(.)和兩個(gè)點(diǎn)(..)。一個(gè)點(diǎn)表示當(dāng)前目錄,兩個(gè)點(diǎn)表示父目錄。
./home 表示當(dāng)前目錄下名為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可以打印出當(dāng)前路徑下的所有文件
```
[jon@xpanse missing-semester]$ ls
404.html??data-wrangling.md??lectures.html??
后面內(nèi)容省略
[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 后面可以帶有參數(shù),例如下面的示例,以當(dāng)前文件夾的父文件夾 .. 為參數(shù)
```
[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?參數(shù)dash(減號(hào),橫杠,-)可以返回到上一次的目錄中
注: 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]$?
```
大多數(shù)程序都可以以 --help 作為參數(shù),以打印幫助內(nèi)容
```
[jon@xpanse missing-semester]$ ls --help
Usage: ls [OPTION]... [FILE]...
中間內(nèi)容省略
-l?????use a long listing format
中間內(nèi)容省略
[jon@xpanse missing-semester]$?
```
例如,幫助中有這樣一條 -l??use a long listing format,我們可以實(shí)際試驗(yàn)一下。
```
[jon@xpanse missing-semester]$ ls -l
部分內(nèi)容省略
-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
```
我們來(lái)看一下這些是什么意思。條目(entries)開(kāi)頭的d表示這是一個(gè)目錄(directory),所以這里的 \_data 是一個(gè)目錄,而這里的 404.html 不是一個(gè)目錄。
```
drwxr-xr-x 1 jon jon??24 Jan 13 12:42 _data
```
第一個(gè)字符??d: 是否是文件夾,
二—五字符 rwx: 該文件對(duì)于文件所有者的權(quán)限
六—八字符?-xr: 該文件對(duì)于擁有此文件的組(group)所具有的的權(quán)限
九—11字符?r-x: 該文件對(duì)于其余所有人的權(quán)限
第一個(gè) jon : 文件所有者
第二個(gè) jon : 擁有此文件的組
對(duì)于文件:
r : 可以讀此文件
w: 可以寫(xiě)此文件
x : 可以執(zhí)行此文件
\- : 無(wú)相應(yīng)權(quán)限
例如, ls -l /bin 中的所有文件都具有 x 權(quán)限,因?yàn)檫@個(gè)目錄下 echo 等指令應(yīng)該給所有用戶開(kāi)放使用。
對(duì)于文件夾:
r : 可以查看有哪些文件在此文目錄中
w: 可以重命名、創(chuàng)建或者刪除此目錄中的文件
x : 如果該目錄,及其所有父目錄都具有 x 權(quán)限,該目錄下的文件才可以執(zhí)行
如果僅具有一個(gè)文件的 w 權(quán)限,但是沒(méi)有其所在目錄的 w 權(quán)限,你只可以清空(empty, v.)它,但不能刪除它,因?yàn)檫@會(huì)修改目錄本身。
部分目錄的第一個(gè)字母 l 幾乎與本次講座沒(méi)什么關(guān)系,如果好奇的話,請(qǐng)自己查詢資料或講座結(jié)束后單獨(dú)來(lái)辦公室詢問(wèn)。
注:第一個(gè)字符代表文件類型,d是文件夾,l是鏈接文件,-是普通文件 —— https://blog.csdn.net/chiwen8728/article/details/100649290
mv可以用來(lái)移動(dòng)或重命名文件。例如下面的示例,將 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指令,可以復(fù)制文件
```
[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指令默認(rèn)是不能遞歸(recursion)的,所以不能通過(guò)傳入目錄作為rm 的參數(shù)來(lái)刪除目錄??梢詡魅?r 標(biāo)記(flag)即可遞歸刪除,即刪除一個(gè)目錄下所有內(nèi)容。
rmdir指令可以用來(lái)刪除目錄。如果該目錄為空,則會(huì)成功刪除該目錄;
下面是本人在虛擬機(jī)上的示例
```
j****@j****-virtual-machine:~$ rm Lab2
rmdir: failed to remove 'Lab2': Directory not empty
j****@j****-virtual-machine:~$
```
mkdir 指令可以用于創(chuàng)建新目錄。例如,下面的指令會(huì)創(chuàng)建兩個(gè)目錄,分別名為 My 和 Photos。
```
[jon@xpanse missing-semester]$ mkdir My Photos
```
man 指令(manual)接受另一個(gè)指令作為參數(shù),然后向你展示該指令的參數(shù)。
```
[jon@xpanse missing-semester]$ man ls
```
man ls 和 ls --help 相似,只是 man 更容易閱讀,同時(shí)還具有示例。
#清屏?
Ctrl+L 可以清除終端。
也許你可能需要將多個(gè)程序鏈接在一起,或者與文件操作等需求,而shell給出的流(stream)這個(gè)概念可以解決這個(gè)問(wèn)題。每個(gè)程序都有兩個(gè)流,分別為輸入流(input stream)和輸出流(output stream)。
通常輸入流來(lái)自于鍵盤,通過(guò)終端輸入進(jìn)程序。而當(dāng)程序嘗試打印一些東西時(shí),會(huì)打印到輸出流中。
shell 提供了可以重定向輸入流和輸出流的方式:使用尖括號(hào)標(biāo)志(angle bracket ,<>)。
```
[jon@xpanse missing-semester]$ echo hello > hello.txt
[jon@xpanse missing-semester]$?
```
然后shell就會(huì)創(chuàng)建一個(gè)文件叫 hello.txt ,里面的內(nèi)容是?
```
hello
```
指令 cat 打印文件的內(nèi)容
彈幕: cat 是??concatenate 的縮寫(xiě)
```
[jon@xpanse missing-semester]$ cat hello.txt
hello
[jon@xpanse missing-semester]$?
```
cat 也可以復(fù)制(duplicate)它的輸入到輸出
```
[jon@xpanse missing-semester]$ cat < hello.txt
hello
[jon@xpanse missing-semester]$?
```
cat也可以用來(lái)復(fù)制文件
```
[jon@xpanse missing-semester]$ cat < hello.txt > hello2.txt
[jon@xpanse missing-semester]$ cat hello2.txt
hello
[jon@xpanse missing-semester]$?
```
程序cat并不知道輸入和輸出是否被重定向
>>也可以用來(lái)輸出,但是是在文件后面追加,而不是覆蓋文件
```
[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]$?
```
管道符號(hào)(pipe character, vertical bar, |)的含義是,將左面程序的輸出,作為右面程序的輸出,
指令 tail 打印輸入的最后1行
注:
通常tail 打印最后10行。tail -n1 打印最后一行
-n\[+\]NUM
n后面可以跟參數(shù)決定輸出的行數(shù),或是通過(guò)跟加號(hào)跟參數(shù),輸出指定的行數(shù)之后的所有行。
```
[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,它們是不同的程序,也沒(méi)有通過(guò)互相兼容來(lái)共同運(yùn)行,僅僅是對(duì)輸入進(jìn)行處理,并輸出。
管道符號(hào)將wires(直譯為電線)連接到一起。在這里,ls的輸出(output)連接到tail的輸入(input),tail的輸出輸出到terminal
我們也可以將tail的輸出重定向(reware)到文件當(dāng)中
```
[jon@xpanse missing-semester]$ ls -l / | tail -n1 > ls.txt
[jon@xpanse missing-semester]$?
```
注:使用↑方向鍵可以調(diào)出剛剛執(zhí)行過(guò)的指令
[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]$?
```
管道符號(hào)不僅僅可以作用于文本,也可以作用于圖像之類的東西
Linux的root user相當(dāng)于Windows上的管理員用戶,其用戶ID為0?
root用戶可以對(duì)文件系統(tǒng)做任何事,即使文件不具有讀寫(xiě)權(quán)限
大多數(shù)時(shí)候,不會(huì)使用root權(quán)限,因?yàn)閞oot權(quán)限很危險(xiǎn)。
sudo 指令可以允許你用root權(quán)限執(zhí)行指令。sudo意思是do as su,而su指的是super user?
彈幕:
sudo是substitute do ,不是super user do
<-兩種說(shuō)法都有
switch user do
如果你切換到 cd /sys 這是一個(gè)全新的世界
```
[jon@xpanse missing-semester]$ cd /sys
[jon@xpanse sys]$ ls
block bus class dev devices firmware fs hypervisor kernel module power
[jon@xpanse sys]$?
```
這里的文件實(shí)際上并不是文件,而是內(nèi)核(kernel)參數(shù),即計(jì)算機(jī)的核心。這里可以查看內(nèi)核參數(shù),看上去就像文件系統(tǒng)一樣
```
[jon@xpanse sys]$ cd class/
[jon@xpanse class]$ ls
backlight dmi input nvme-subsystem remoteproc typec
下面內(nèi)容省略
[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]$?
```
例如,這個(gè)backlight可以直接調(diào)節(jié)筆記本電腦上的背光。
你可能想到用指令 sudo 來(lái)修改,但是不可行
```
[jon@xpanse inter_backlight]$ sudo echo 500 > brightness
bash: brightness: Permission denied
[jon@xpanse inter_backlight]$?
```
原因是,在這里,程序 sudo 執(zhí)行的是 echo 500,將輸出發(fā)送到名為 brightness的文件,然而打開(kāi)brightness的并不是 sudo 程序。所以此時(shí)出現(xiàn)了權(quán)限下降錯(cuò)誤(permission down error)。
```
[jon@xpanse inter_backlight]$ echo 1 > /sys/net/ipv4_forward
```
這個(gè)指令可以用來(lái)設(shè)置防火墻。如果前面是英鎊符號(hào)的話,這個(gè)指令可以運(yùn)行。dollar符號(hào)表示你沒(méi)有以root用戶身份運(yùn)行。
注:我也不知道為啥他管\#符號(hào)叫英鎊符號(hào)
sudo su指令可以切換為超級(jí)用戶(super user)模式。切換為超級(jí)用戶模式之后,用戶名從原來(lái)的jon切換為了root,同時(shí)美元符號(hào)變成了英鎊符號(hào)。
```
[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]$?
```
據(jù)講師所說(shuō),屏幕亮度變暗了,但是從視頻中看不到。
```
[jon@xpanse inter_backlight]$ echo 1060 | sudo tee brightness
1060
[jon@xpanse inter_backlight]$?
```
tee命令獲取輸入并寫(xiě)入到指定的文件中,可用來(lái)存儲(chǔ)日志文件。
可以用find指令
```
[jon@xpanse inter_backlight]$ cd ..
[jon@xpanse backlight]$ cd leds/
[jon@xpanse leds]$ ls
input4::capslock?phy0-led?tpacpi::kbd_backlight?tpacpi::thinklight
下面內(nèi)容省略
[jon@xpanse leds]$ cd input4\:\scrolllock
```
也許大多數(shù)人不知道什么是scrolllock,也許你在鍵盤上看到這樣一個(gè)scrolllock的按鍵,但是大家不知道這個(gè)鍵是干什么的。這個(gè)鍵已經(jīng)成了死鍵了。
```
[jon@xpanse input4::scrolllock]$ cat brightness
0
[jon@xpanse input4::scrolllock]$ echo 1 | sudo tee brightness
1
[jon@xpanse input4::scrolllock]$?
```
如果你想設(shè)置為,每當(dāng)收到 email 的時(shí)候,scrolllock LED 閃爍的話,可以弄一個(gè)程序用來(lái)檢查是否收集到 email ,然后將輸出使用管道字符輸出到 sudo tee brightness 中
```
[jon@xpanse missing-semester]$ xdg-open lectures.html
```
xdg-open,這個(gè)指令只在linux和macOS上起作用,在windows上叫做open 。這個(gè)指令會(huì)使用合適的方式打開(kāi)指定的文件。
---
下節(jié)預(yù)告:如何完成自動(dòng)化之類的任務(wù)、如何編寫(xiě)運(yùn)行一堆程序的腳本,如何實(shí)現(xiàn)條件語(yǔ)句和循環(huán)語(yǔ)句
---
おわり