[MIT公开课(计算机教育中缺失的⼀课)]1.Overview+Shell
下⼀讲:
⽬录
The Shell
1.Shell是什么?
如今的计算机有着多种多样的交互接⼝让我们可以进⾏指令的的输⼊,从炫酷的图像⽤户界⾯(GUI),语⾳输⼊甚⾄是AR/VR都已经⽆处不在。 这些交互接⼝可以覆盖80%的使⽤场景,但是它们也从根本上限制了您的操作⽅式——你不能点击⼀个不存在的按钮或者是⽤语⾳输⼊⼀个还没有被录⼊的指令。 为了充分利⽤计算机的能⼒,我们不得不回到最根本的⽅式,使⽤⽂字接⼝:Shell。虽然各种平台⽀持不同的Shell,但是其核⼼功能都是⼀样的:它允许你执⾏程序,输⼊并获取某种半结构化的输出。
这⾥我们使⽤Bourne Again SHell, 简称 “bash” (现在流⾏的zsh是兼容bash的,MIT⽼师⽤的是bash,博主演⽰的是在Mac下使⽤zsh)
在mac终端切换bash和zsh:
切换到bash:chsh -s /bin/bash或直接输⼊bash
切换到zsh:chsh -s /bin/zsh或直接输⼊zsh
重启终端后有效(后⾯两个⽅法不需要重启)。
2.使⽤shell
当您打开终端时,您会看到⼀个提⽰符,它看起来⼀般是这个样⼦的:
missing:~$
这是shell最主要的⽂本接⼝。它告诉你,你的主机名是 missing 并且您当前的⼯作⽬录或者说您当前所在的位置是~ (表⽰ “home”)。$符号表⽰您现在的⾝份不是root⽤户(稍后会介绍)。在这个提⽰符中,您可以输⼊ 命令 ,命令最终会被shell解析。最简单的命令是执⾏⼀个程序:
missing:~$ date
Fri 10 Jan 2020 11:49:31 AM EST
missing:~$ cal# 输出当⽉⽇历
九⽉ 2020
⽇⼀⼆三四五六
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
missing:~$ df# 查看磁盘剩余空间的数量
missing:~$ free# 查看空闲内存的数量
echo
我们可以在执⾏命令的同时向程序传递 参数 :
missing:~$ echo hello
hello
missing:~$
上例中,我们让shell执⾏ echo ,同时指定参数hello,echo 程序将该参数打印出来。
echo还可以将shell当做计算器使⽤,在算术表达式中空格并不重要,并且表达式可以嵌套:
echo$((expression))
举例:
➜ Downloads echo Five divided by two equals $((5/2))
Five divided by two equals 2
参数展开
shell是如何知道去哪⾥寻 date 或 echo 的呢?其实,类似于Python or Ruby,shell是⼀个编程环境,所以它具备变量、条件、循环和函数。当你在shell中执⾏命令时,您实际上是在执⾏⼀段shell可以解释执⾏的简短代码。如果你要求shell执⾏某个指令,但是该指令并不是shell所了解的编程关键字,那么它会去咨询环境变量 $PATH,它会列出当shell接到某条指令时,进⾏程序搜索的路径;叫做 “USER”的变量包含你的⽤户名。
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
➜ Downloads echo$USER
lilhoe
当我们执⾏ echo 命令时,shell了解到需要执⾏ echo 这个程序,随后它便会在$PATH中搜索由:所分割的⼀系列⽬录,基于名字搜索该程序。当到该程序时便执⾏(假定该⽂件是 可执⾏程序,后续课程将详细讲解)。确定某个程序名代表的是哪个具体的程序,可以使⽤which 程序。我们也可以绕过 $PATH,通过直接指定需要执⾏的程序的路径来执⾏该程序。
要查看有效的变量列表,可以试试这个:
printenv|less
引⽤
➜ Downloads echo this is a test
this is a test
➜ Downloads echo The total is $100.00
The total is .00
shell基于空格分割命令并进⾏解析,在第⼀个例⼦中,shell 利⽤单词分割删除掉 echo 命令的参数列
表中多余的空格。在第⼆个 例⼦中,参数展开把 $1 的值替换为⼀个空字符串,因为 1 是没有定义的变量。shell 提供了⼀ 种叫做引⽤的机制,来有选择地禁⽌不需要的展开。
双引号: 如果你把⽂本放在双引号中,shell 使⽤的特殊字 符,都失去它们的特殊含义,被当作普通字符来看待。有⼏个例
外:$,\(反斜杠),和 ‘(上单引号)。这意味着单词分割(内嵌的空格也不会被当作界定符,它们成为参数的⼀部分)、路径名展开、波浪线展开和花括号展开都将失效,然⽽参数展开、 算术展开和命令替换仍然执⾏。使⽤双引号,我们可以处理包含空格的⽂件名(当然也可以不⽤双引号⽽⽤\转义空格)。
单引号:禁⽌所有的展开。
# ⽆引⽤,双引号和单引号的⽐较
[me@linuxbox ~]$ echo text ~/*.txt {a,b}$(echo foo)$((2+2))$USER text
/home/ a b foo 4 me
[me@linuxbox ~]$ echo"text ~/*.txt {a,b} $(echo foo)$((2+2))$USER" text
~/*.txt {a,b} foo 4 me
[me@linuxbox ~]$ echo'text ~/*.txt {a,b} $(echo foo)$((2+2))$USER' text
~/*.txt {a,b}$(echo foo)$((2+2))$USER
确定⽂件类型
Linux关于⽂件名的重要规则:
1. 以 “.” 字符开头的⽂件名是隐藏⽂件,ls命令不能列出它们,⽤ls -a 命令就可以了。当你创建帐号后,⼏个配置帐号的隐藏⽂件被
放置在你的home⽬录下。稍后,我们会仔细研究⼀些隐藏⽂件,来定制你的系统环境。另外, ⼀些应⽤程序也会把它们的配置⽂件以隐藏⽂件的形式放在你的家⽬录下⾯。
2. Linux 没有“⽂件扩展名”的概念,不像其它⼀些系统。可以⽤你喜欢的任何 名字来给⽂件起名。⽂件内容或⽤途由其它⽅法来决
定。虽然类 Unix 的操作 系统,不⽤⽂件扩展名来决定⽂件的内容或⽤途,但是有些应⽤程序会。
shell代码3. 虽然 Linux ⽀持长⽂件名,⽂件名可能包含空格,标点符号,但标点符号仅限 使⽤“.”,“-”,下划线。最重要的是,不要在⽂件
名中使⽤空格。如果你想表 ⽰词与词间的空格,⽤下划线字符来代替。
基于上述第三点,我们需要确定⽂件类型,使⽤下⾯file语句,打印出⽂件内容的简单描述:
file filename
# 举例:
~/Downloads
<: LaTeX 2e document text, ASCII text
3.在shell中导航
shell中的路径是⼀组被分割的⽬录,在 Linux 和 macOS 上使⽤ / 分割,⽽在Windows上是\。路径 /代表的是系统的根⽬录,所有的⽂件夹都包括在这个路径之下(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
通过cd -命令可以回到上次的⽬录环境下,cd ~默认回到根⽬录:
lilhoe@LilHoedeMacBook-Pro ~ % cd /Users/lilhoe/Downloads
lilhoe@LilHoedeMacBook-Pro Downloads % pwd
/Users/lilhoe/Downloads
lilhoe@LilHoedeMacBook-Pro Downloads % cd ~
lilhoe@LilHoedeMacBook-Pro ~ % pwd
/Users/lilhoe
lilhoe@LilHoedeMacBook-Pro ~ % cd -
~/Downloads
lilhoe@LilHoedeMacBook-Pro Downloads % pwd
/Users/lilhoe/Downloads
lilhoe@LilHoedeMacBook-Pro Downloads %
为了查看指定⽬录下包含哪些⽂件,我们使⽤ls 命令:
missing:~$ ls
missing:~$ cd..
missing:/home$ ls
missing
missing:/home$ cd..
missing:/$ ls
bin
boot
dev
etc
home
...
除⾮我们利⽤第⼀个参数指定⽬录,否则ls会打印当前⽬录下的⽂件。⼤多数的命令接受标记和选项(带有值的标记),它们以- 开头,并可以改变程序的⾏为。通常,在执⾏程序时使⽤-h 或 -help标记可以打印帮助信息,以便了解有哪些可⽤的标记或选项。例如,ls -help 的输出如下(zsh):
lilhoe@LilHoedeMacBook-Pro ~ %ls-help
total 0
drwx------@ 3 lilhoe staff 96B 2 15 2020 Applications/
drwx------@ 25 lilhoe staff 800B 8 17 18:27 Desktop/
0: group:everyone deny delete
drwx------@ 42 lilhoe staff 1.3K 8 26 14:23 Documents/
0: group:everyone deny delete
drwx------@ 36 lilhoe staff 1.1K 8 26 18:50 Downloads/
0: group:everyone deny delete
drwx------@ 80 lilhoe staff 2.5K 7 6 11:58 Library/
0: group:everyone deny delete
drwx------+ 6 lilhoe staff 192B 7 3 15:57 Movies/
0: group:everyone deny delete
drwx------+ 8 lilhoe staff 256B 5 17 15:53 Music/
0: group:everyone deny delete
drwx------+ 7 lilhoe staff 224B 2 25 2020 Pictures/
0: group:everyone deny delete
drwxr-xr-x+ 4 lilhoe staff 128B 1 1 1970 Public/
0: group:everyone deny delete
drwxr-xr-x 9 lilhoe staff 288B 7 21 19:02 wekafiles/
lilhoe@LilHoedeMacBook-Pro ~ %
这个参数可以打印出更加详细地列出⽬录下⽂件或⽂件夹的信息。⾸先,本⾏第⼀个字符d 表⽰ missing 是⼀个⽬录。然后接下来的九个字符,每三个字符构成⼀组。 (rwx).们分别代表了⽂件所有者(missing),⽤户组 (users) 以及其他所有⼈具有的权限。其中 -表⽰该⽤户不具备相应的权限。从上⾯的信息来看,只有⽂件所有者可以修改(w) , missing ⽂件夹 (例如,添加或删除⽂件夹中的⽂件)。
为了进⼊某个⽂件夹,⽤户需要具备该⽂件夹以及其⽗⽂件夹的“搜索”权限(以“可执⾏”:x)权限表⽰。为了列出它的包含的内容,⽤户必须对该⽂件夹具备读权限(r)。对于⽂件来说,权限的意义也是类似的。注意,/bin⽬录下的程序在最后⼀组,即表⽰所有⼈的⽤户组中,均包含x权限,也就是说任何⼈都可以执⾏这些程序。
还有的命令是需要掌握的,例如 mv (⽤于重命名或移动⽂件)、 cp(拷贝⽂件)、rm(删除⽂件)以及 mkdir(新建⽂件夹)。mv和cp都接收两个参数,第⼀个为旧路径(或⽂件名),第⼆个为新路径(或⽂件名)。rm和mkdir接收⼀个参数,在Linux下,删除默认是⾮递归的,所以不能⽤rm指令删除⼀个⽂件夹,可以传递⼀个-r来递归删除(详情查看man rm⼿册)。另⼀种删除⽂件夹的安全命令:rmdir,只有当⽂件夹为空时才允许删除。
lilhoe@LilHoedeMacBook-Pro Downloads % mv课表.numbers kebiao.numbers
lilhoe@LilHoedeMacBook-Pro Downloads % cp kebiao.numbers /Users/lilhoe/Desktop/Kebiao.numbers
lilhoe@LilHoedeMacBook-Pro Downloads % mkdir lilhoe
lilhoe@LilHoedeMacBook-Pro Downloads % rm kebiao.numbers
lilhoe@LilHoedeMacBook-Pro Downloads % mkdir hisd
lilhoe@LilHoedeMacBook-Pro Downloads % rmdir hisd
lilhoe@LilHoedeMacBook-Pro Downloads %
如果您想要知道关于程序参数、输⼊输出的信息,亦或是想要了解它们的⼯作⽅式,请试试 man 这个程序。它会接受⼀个程序名作为参数,然后将它的⽂档(⽤户⼿册)展现给您。注意,使⽤q 可以退出该程序(mac的terminal使⽤:q只是退出修改模式,需要键⼊:wq才会保存退出)。
man ls
4.重定向
在shell中,程序有两个主要的“流”:它们的输⼊流和输出流。 通常,⼀个程序的输⼊输出流都是您的终端。也就是,键盘作为输⼊,显⽰器作为输出。 但是,我们也可以重定向这些流!
标准输出重定向
最简单的重定向是< file 和> file。这两个命令可以将程序的输⼊输出流分别重定向到⽂件:
missing:~$ echo hello >
missing:~$
hello
missing:~$ cat<
hello
missing:~$ cat< >
missing:~$
hello
<;表⽰重定向该该⽂件的内容作为输⼊,>表⽰将该程序的输出重定向为该⽂件的内容,cat打印⽂件内容,cat < > 可以代替cp命令来复制⽂件。
还可以使⽤ >> 来向⼀个⽂件追加内容,⽽>是覆盖输出:
missing:~$ cat< >>
missing:~$
hello
hello
由于>是覆盖输出,我们则可以使⽤>⽂件名来清空⽂件或者创建⼀个新的空⽂件。
标准错误重定向
⼀个程序可以在⼏个编号的⽂件流中的任⼀个上产⽣输出。虽然我们已经将这些⽂件流的 前三个称作标准输⼊、输出和错误,shell 内部分别将其称为⽂件描述符 0、1 和 2。因为标准错误和⽂件描述符 2 ⼀样,我们⽤这种 表⽰法来重定向标准错误:
➜ demo2 git:(master)✗ls -l /bin/sgd 2& # 这⾥将ls命令操作在⼀个不存在的⽂件夹上
➜ demo2 git:(master)✗
ls: /bin/sgd: No such file or directory
< (END)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论