Loading...

参考链接


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
2
(base) chenyubin@chenyubindeMacBook-Pro ~ % date
2024年 2月26日 星期一 21时25分04秒 `CST`

这里,我们执行了 date 这个程序,不出意料地,它打印出了当前的日期和时间


echo

1
2
(base) chenyubin@chenyubindeMacBook-Pro ~ % echo hellop
hellop

echo 程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数.


PATH

shell 是如何知道去哪里寻找 dateecho 的呢?其实,类似于 PythonRubyshell 是一个编程环境,所以它具备变量、条件、循环和函数(下一课进行讲解)。当你在 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 中的路径是一组被分割的目录,在 LinuxmacOS 上使用 / 分割,而在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
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
(base) chenyubin@chenyubindeMacBook-Pro ~ % ls -l
total 3226936
drwx------@ 5 chenyubin staff 160 7 17 2023 Applications
drwxr-xr-x@ 4 chenyubin staff 128 9 22 01:24 CLionProjects
drwx------@ 16 chenyubin staff 512 2 26 21:36 Desktop
drwx------@ 4 chenyubin staff 128 2 3 01:14 Documents
drwx------+ 47 chenyubin staff 1504 2 17 20:33 Downloads
drwx------@ 98 chenyubin staff 3136 11 18 19:49 Library
drwx------ 4 chenyubin staff 128 7 10 2023 Movies
drwx------+ 5 chenyubin staff 160 7 11 2023 Music
lrwxr-xr-x 1 chenyubin staff 53 7 12 2023 OneDrive - kvz8wq -> /Users/chenyubin/Library/CloudStorage/OneDrive-kvz8wq
drwx------+ 4 chenyubin staff 128 7 10 2023 Pictures
drwxr-xr-x+ 5 chenyubin staff 160 9 22 13:46 Public
drwxr-xr-x@ 17 chenyubin staff 544 1 6 21:01 PycharmProjects
drwxr-xr-x 5 chenyubin staff 160 1 9 20:14 Virtual Machines.localized
drwxr-xr-x 25 chenyubin staff 800 7 12 2023 anaconda3
-rw-------@ 1 chenyubin staff 2655 7 13 2023 chenyubin
-rw-r--r--@ 1 chenyubin staff 571 7 13 2023 chenyubin.pub
drwxr-xr-x@ 4 chenyubin staff 128 10 8 03:21 dumps
drwx------ 4 chenyubin staff 128 7 14 2023 iCloud云盘(归档)
-rw-------@ 1 chenyubin staff 1651750569 7 23 2023 java_error_in_pycharm.hprof
drwxr-xr-x@ 4 chenyubin staff 128 12 4 18:40 nltk_data
drwxr-xr-x 53 root staff 1696 7 30 2023 node_modules
-rw-r--r-- 1 root staff 19405 7 30 2023 package-lock.json
-rw-r--r-- 1 root staff 94 7 30 2023 package.json
drwxr-xr-x@ 4 chenyubin staff 128 12 16 23:09 scikit_learn_data
-rw-r--r--@ 1 chenyubin staff 590 7 23 2023 未命名.ipynb
-rw-r--r--@ 1 chenyubin staff 389418 8 17 2023 未命名1.ipynb
-rw-r--r--@ 1 chenyubin staff 6118 11 24 20:38 未命名2.ipynb

这个参数可以更加详细地列出目录下文件或文件夹的信息。首先,本行第一个字符 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
2
3
4
5
6
(base) chenyubin@chenyubindeMacBook-Pro desktop % echo hello > hello.txt
(base) chenyubin@chenyubindeMacBook-Pro desktop % cat hello.txt
hello
(base) chenyubin@chenyubindeMacBook-Pro desktop % cat < hello.txt > hello2.txt
(base) chenyubin@chenyubindeMacBook-Pro desktop % cat hello2.txt
hello


|

使用管道(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

顾名思义,它的作用是让您可以以 susuper userroot 的简写)的身份执行一些操作。 当您遇到拒绝访问(permission denied)的错误时,通常是因为此时您必须是根用户才能操作。然而,请再次确认您是真的要执行此操作。


课后练习

/tmp 下新建一个名为 missing 的文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(base) chenyubin@chenyubindeMacBook-Pro desktop % cd /tmp
(base) chenyubin@chenyubindeMacBook-Pro /tmp % mkdir missing
(base) chenyubin@chenyubindeMacBook-Pro /tmp % tree -L 1
.
├── SangforSSL.lock
├── SangforSSLJava.lock
├── Sublime Text.4cff18d2bab96a93366319a9e0fa060d.5350f1748b9ec3b47b154263c0cfdaa7.sock
├── com.adobe.acrobat.rna.0.1f5.DC
├── com.adobe.acrobat.rna.131c.1f5
├── com.apple.launchd.viWeL6VPPz
├── com.sangfor.ca.sha
├── com.sangfor.ca.verification
├── com.sangfor.lockcert
├── com.sangfor.lockecagent
├── ko.2f4b4ffd.325bc6c2.0
├── ko.d87db22f.668d0007.1
├── missing
├── mysql.sock
├── mysqlx.sock
├── resolv.bak.conf
├── sangfor.ec.rundata
└── stop_easyconnect.sh

3 directories, 16 files

man 查看程序 touch 的使用手册。

1
(base) chenyubin@chenyubindeMacBook-Pro /tmp % man touch

touch和mkdir区别:

  • touch新建文件
  • mkdir新建目录/文件夹(directory)


touchmissing 文件夹中新建一个叫 semester 的文件。

1
2
3
4
5
6
7
(base) chenyubin@chenyubindeMacBook-Pro /tmp % cd missing
(base) chenyubin@chenyubindeMacBook-Pro missing % touch semester
(base) chenyubin@chenyubindeMacBook-Pro missing % tree -L 1
.
└── semester

1 directory, 1 file

将以下内容一行一行地写入 semester 文件:

1
2
`#!/bin/sh`  
`curl --head --silent https://missing.csail.mit.edu`
1
2
3
4
5
6
7
8
9
10
11
12
(base) chenyubin@chenyubindeMacBook-Pro missing % echo \#'!'/bin/sh > semester
(base) chenyubin@chenyubindeMacBook-Pro missing % cat semester
#!/bin/sh
(base) chenyubin@chenyubindeMacBook-Pro missing % echo cur; --head --silent http://github.com/siyuanluo >> semester
cur
zsh: command not found: --head
(base) chenyubin@chenyubindeMacBook-Pro missing % cat semester
#!/bin/sh
(base) chenyubin@chenyubindeMacBook-Pro missing % echo curl --head --silent http://github.com/siyuanluo >> semester
(base) chenyubin@chenyubindeMacBook-Pro missing % cat semester
#!/bin/sh
curl --head --silent http://github.com/siyuanluo


尝试执行这个文件。例如,将该脚本的路径(./semester)输入到您的shell中并回车。如果程序无法执行,请使用 ls 命令来获取信息并理解其不能执行的原因。

1
2
3
4
5
(base) chenyubin@chenyubindeMacBook-Pro missing % ./semester
zsh: permission denied: ./semester
(base) chenyubin@chenyubindeMacBook-Pro missing % ls -l
total 8
-rw-r--r--@ 1 chenyubin wheel 59 2 26 22:13 semester

无法执行,原因是文件所有者无执行权限(权限为rw-,只可读写)


查看 chmod 的手册(例如,使用 man chmod 命令)

使用 chmod 命令改变权限,使 ./semester 能够成功执行,不要使用 sh semester 来执行该程序。您的 shell 是如何知晓这个文件需要使用 sh 来解析呢?更多信息请参考:shebang

1
2
3
4
5
6
7
8
(base) chenyubin@chenyubindeMacBook-Pro missing % ls -l
total 8
-rw-r--r--@ 1 chenyubin wheel 59 2 26 22:13 semester
(base) chenyubin@chenyubindeMacBook-Pro missing % man chmod
(base) chenyubin@chenyubindeMacBook-Pro missing % chmod 777 semester
(base) chenyubin@chenyubindeMacBook-Pro missing % ls -l
total 8
-rwxrwxrwx@ 1 chenyubin wheel 59 2 26 22:13 semester

使用 |> ,将 semester 文件输出的最后更改日期信息,写入主目录下的 last-modified.txt 的文件中

1
./semester | grep -i "last-modified" > /home/last-modified.txt