The Missing Semester - 第一讲 学习笔记

第一讲 课程概览与 shell

课程视频地址:

https://www.bilibili.com/video/BV1Eo4y1d7KZ/?vd_source=87f9cb5d00dc916a8f510966777362a2

本机学习使用平台:虚拟机ubuntu18.04.6

动机

作为计算机科学家,我们都知道计算机最擅长帮助我们完成重复性的工作。 但是我们却常常忘记这一点也适用于我们使用计算机的方式,而不仅仅是利用计算机程序去帮我们求解问题。 在从事与计算机相关的工作时,我们有很多触手可及的工具可以帮助我们更高效的解决问题。 但是我们中的大多数人实际上只利用了这些工具中的很少一部分,我们常常只是死记硬背一些如咒语般的命令, 或是当我们卡住的时候,盲目地从网上复制粘贴一些命令。

本课程意在帮你解决这一问题。

我们希望教会您如何挖掘现有工具的潜力,并向您介绍一些新的工具。也许我们还可以促使您想要去探索(甚至是去开发)更多的工具。 我们认为这是大多数计算机科学相关课程中缺少的重要一环。

主题 1: The Shell

这节课讲的是一些比较基础的东西。后面的课程都会用到。

关键点是:how to use ur shell & terminal.

shell 是什么?

如今的计算机有着多种多样的交互接口让我们可以进行指令的的输入,从炫酷的图像用户界面(GUI),语音输入甚至是 AR/VR 都已经无处不在。 这些交互接口可以覆盖 80% 的使用场景,但是它们也从根本上限制了您的操作方式——你不能点击一个不存在的按钮或者是用语音输入一个还没有被录入的指令。 为了充分利用计算机的能力,我们不得不回到最根本的方式,使用文字接口:Shell。

shell是你和电脑交互的最主要方式之一,属于非可视化界面。

可视化界面是比较受限制的,这节课介绍的命令行工具和基于文本的工具可以打破这些限制,使不同的基于文本实现的各种各样的功能,以各种各样的方式耦合起来。shell即是你使用这些工具的”工作地点“。

几乎所有您能够接触到的平台都支持某种形式的 shell,有些甚至还提供了多种 shell 供您选择。虽然它们之间有些细节上的差异,但是其核心功能都是一样的:它允许你执行程序,输入并获取某种半结构化的输出。

本节课我们会使用 Bourne Again SHell, 简称 “bash” 。 这是被最广泛使用的一种 shell,它的语法和其他的 shell 都是类似的。打开shell 提示符(您输入指令的地方),您首先需要打开 终端 。您的设备通常都已经内置了终端,或者您也可以安装一个,非常简单。

目前最普遍的shell:BASH

注意事项 -- 注意参数输入

当您打开终端时,您会看到一个提示符,它看起来一般是这个样子的:

grapefruitcat@grapefruitcat:~$

这是 shell 最主要的文本接口。它告诉你,你的主机名是 missing 并且您当前的工作目录(”current working directory”)或者说您当前所在的位置是 ~ (表示 “home”)。 $ 符号表示您现在的身份不是 root 用户(稍后会介绍)。在这个提示符中,您可以输入 命令 ,命令最终会被 shell 解析。最简单的命令是执行一个程序:

grapefruitcat@grapefruitcat:~$ date
2023年 01月 12日 星期四 18:05:24 CST
grapefruitcat@grapefruitcat:~$

这里,我们执行了 date 这个程序,不出意料地,它打印出了当前的日期和时间。然后,shell 等待我们输入其他命令。我们可以在执行命令的同时向程序传递 参数

grapefruitcat@grapefruitcat:~$ echo hello
hello
grapefruitcat@grapefruitcat:~$ echo "Hello world"
Hello world
grapefruitcat@grapefruitcat:~$ echo 'hello world'
hello world
grapefruitcat@grapefruitcat:~$ echo hello\ world
hello world

上例中,我们让 shell 执行 echo ,同时指定参数 helloecho 程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数。如果您希望传递的参数中包含空格(例如一个名为 My Photos 的文件夹),您要么用使用单引号,双引号将其包裹起来,要么使用转义符号 \ 进行处理(My\ Photos)。

环境变量

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等,在开发环境或者部署环境中都需要使用到。

系统内嵌了许多围绕终端工作的程序,而 shell 通过环境变量去搜索程序。

shell 是如何知道去哪里寻找 dateecho 的呢?其实,类似于 Python 或 Ruby,shell 是一个编程环境,所以它具备变量、条件、循环和函数(下一课进行讲解)。当你在 shell 中执行命令时,您实际上是在执行一段 shell 可以解释执行的简短代码。

shell 本身可以看作一门程序设计语言(既是应用程序,又是一种脚本语言),你输入的提示符不仅可以带参,也可以写出条件、循环和函数。

如果你要求 shell 执行某个指令,但是该指令并不是 shell 所了解的编程关键字,那么它会去咨询 环境变量 $PATH,它会列出当 shell 接到某条指令时,进行程序搜索的路径:

grapefruitcat@grapefruitcat:~$  echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
grapefruitcat@grapefruitcat:~$ which echo
/bin/echo
grapefruitcat@grapefruitcat:~$ /bin/echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

path环境变量,也是我们接触最为常见的环境变量,path环境变量的作用就是告诉系统,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到哪些目录下去寻找。而我们通常情况下配置的path变量,就是这个目录的完整路径。

当我们执行 echo 命令时,shell 了解到需要执行 echo 这个程序,随后它便会在 $PATH 中搜索由 : 所分割的一系列目录,基于名字搜索该程序。当找到该程序时便执行(假定该文件是 可执行程序,后续课程将详细讲解)。确定某个程序名代表的是哪个具体的程序,可以使用 which 程序。我们也可以绕过 $PATH,通过直接指定需要执行的程序的路径来执行该程序。

关于环境变量具体可参考博文:

https://www.cnblogs.com/gemuxiaoshe/p/10640245.html

路径

shell 中的路径是一组被分割的目录,在 Linux 和 macOS 上使用 / 分割,而在Windows上是 \。路径 / 代表的是系统的根目录,所有的文件夹都包括在这个路径之下,在Windows上每个盘都有一个根目录(例如: C:\)。

学习时使用的是 Linux, 这与 windows 的文件系统不同。(但 WSL 的文件系统好像大同小异?)

如果某个路径以 / 开头,那么它是一个 绝对路径,其他的都是 相对路径 。相对路径是指相对于当前工作目录的路径。

各种基本操作命令

当前工作目录可以使用 pwd 命令来获取。

切换目录需要使用 cd 命令。在路径中,. 表示的是当前目录,而 .. 表示上级目录。 ~表示的是用户目录,-表示的是最近一次到达的目录,/表示的是根目录。

grapefruitcat@grapefruitcat:~$ pwd
/home/grapefruitcat
grapefruitcat@grapefruitcat:~$ cd /home
grapefruitcat@grapefruitcat:/home$ pwd
/home
grapefruitcat@grapefruitcat:/home$ cd ..
grapefruitcat@grapefruitcat:/$ pwd
/
grapefruitcat@grapefruitcat:/$ cd ..
grapefruitcat@grapefruitcat:/$ pwd
/
grapefruitcat@grapefruitcat:/$ cd .
grapefruitcat@grapefruitcat:/$ cd ./
grapefruitcat@grapefruitcat:/$ cd ./home
grapefruitcat@grapefruitcat:/home$ cd ./home
bash: cd: ./home: 没有那个文件或目录
grapefruitcat@grapefruitcat:/home$ cd /grapefruitcat
bash: cd: /grapefruitcat: 没有那个文件或目录
grapefruitcat@grapefruitcat:/home$ cd ./grapefruitcat
grapefruitcat@grapefruitcat:~$ pwd
/home/grapefruitcat

注意,shell 会实时显示当前的路径信息。您可以通过配置 shell 提示符来显示各种有用的信息,参考博客:

https://www.cnblogs.com/Dreamer-qiao/p/7617344.html

https://zhuanlan.zhihu.com/p/348416919

一般来说,当我们运行一个程序时,如果我们没有指定路径,则该程序会在当前目录下执行。例如,我们常常会搜索文件,并在需要时创建文件。

为了查看指定目录下包含哪些文件,我们使用 ls 命令:

grapefruitcat@grapefruitcat:~$ ls
binalab buflab linklab phase3_patch.c 公共的 模板 视频 图片 文档 下载 音乐 桌面
grapefruitcat@grapefruitcat:~$ ls ..
grapefruitcat
grapefruitcat@grapefruitcat:~$ cd /
grapefruitcat@grapefruitcat:/$ ls
bin cdrom etc initrd.img lib lib64 lost+found mnt proc run snap swapfile tmp var vmlinuz.old boot dev home initrd.img.old lib32 libx32 media opt root sbin srv sys usr vmlinuz 桌面

除非我们利用第一个参数指定目录,否则 ls 会打印当前目录下的文件。大多数的命令接受标记和选项(带有值的标记),它们以 - 开头,并可以改变程序的行为。通常,在执行程序时使用 -h--help 标记可以打印帮助信息,以便了解有哪些可用的标记或选项。例如,ls --help 的输出如下:

grapefruitcat@grapefruitcat:~$ ls --help
...
-l 使用较长格式列出信息
...
grapefruitcat@grapefruitcat:~$ ls -l /home
总用量 4
drwxr-xr-x 23 grapefruitcat grapefruitcat 4096 1月 12 21:52 grapefruitcat
grapefruitcat@grapefruitcat:/$ cd ./home/grapefruitcat
grapefruitcat@grapefruitcat:~$ ls -l
总用量 48
drwxrwxr-x 2 grapefruitcat grapefruitcat 4096 10月 20 21:14 binalab
drwxrwxrwx 2 grapefruitcat grapefruitcat 4096 11月 4 11:49 buflab
drwxrwxrwx 2 grapefruitcat grapefruitcat 4096 11月 23 23:09 linklab
-rw-rw-r-- 1 grapefruitcat grapefruitcat 292 11月 21 21:44 phase3_patch.c
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 公共的
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 模板
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 视频
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 图片
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 文档
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 10月 19 14:37 下载
drwxr-xr-x 2 grapefruitcat grapefruitcat 4096 3月 16 2022 音乐
drwxr-xr-x 7 grapefruitcat grapefruitcat 4096 10月 19 14:35 桌面

这个参数可以更加详细地列出目录下文件或文件夹的信息。

drwxr-xr-x 是什么意思呢?

首先,第一个字符 d 表示 grapefruitcat 是一个目录。然后接下来的九个字符,每三个字符构成一组, 共三组,分别代表着 文件所有者(grapefruitcat),用户组(users) 以及其他所有人具有的权限。

而在一组字符中,出现的有rwx-四种字符。

- 表示该用户不具备相应的权限。

r表示该用户具有读取文件的权限。这个权限与 ls 命令挂钩:为了列出路径所包含的内容,用户必须对路径下所有的文件夹具备读取权限。

w表示该用户具有写文件的权限。从上面的信息来看,只有文件所有者可以修改grapefruitcat 文件夹 (例如,添加或删除文件夹中的文件)。如果一个用户有目标文件的w权限,但没有文件所在目录下的w权限,则用户只能修改文件内的内容,但不可对整个文件进行删除等操作。

x表示该用户具有执行文件的权限。为了进入某个文件夹,用户需要具备该文件夹以及其父文件夹的“搜索”权限。

对于文件来说,权限的意义也是类似的。注意,/bin 目录下的程序在最后一组,即表示所有人的用户组中,均包含 x 权限,也就是说任何人都可以执行这些程序。

在这个阶段,还有几个趁手的命令是您需要掌握的,例如 mv(用于重命名或移动文件)、 cp(拷贝文件)rm(删除文件和目录)以及 mkdir(新建文件夹),rmdir(删除整个文件夹,只能在目标文件夹为空文件夹时使用)。如下:

使用mv命令在文件系统中移动(或重命名)文件和目录。
若要使用此命令,请将其名称与源文件和目标文件一起键入:
mv source_file destination_folder/
mv command_list.txt commands/
要使用绝对路径,请使用:(./是您当前所在的目录。)
mv /home/wbolt/BestMoviesOfAllTime ./
使用mv重命名文件,同时将其保留在同一目录中:
mv old.txt new.txt
要使用cp命令,只需将其与源文件和目标文件一起键入即可:
cp file.txt new_file.txt
使用递归标志 -r 复制整个目录:
cp -r dir_to_copy/ new_copy_dir/
使用rm命令删除文件和目录。但在使用时要小心,因为用这种方法恢复删除的文件非常困难。
删除常规文件:
rm file_to_copy.txt
删除空目录,可以使用递归(-r)标志:
rm -r dir_to_remove/
另一方面,要删除包含内容的目录,需要使用force(-f)和recursive标志:
rm -rf dir_with_content_to_remove/
要在shell中创建文件夹,可以使用mkdir命令。只需指定新文件夹的名称,确保它不存在,然后就可以开始了。
创建一个目录:
mkdir newdir/
创建子目录,使用parent(-p)标志:
mkdir -p olddir/dir1/

如果您想要知道关于程序参数、输入输出的信息,亦或是想要了解它们的工作方式,请试试 man 这个程序。它会接受一个程序名作为参数,然后将它的文档(用户手册)展现给您。注意,使用 q 可以退出该程序。

grapefruitcat@grapefruitcat:~$ man ls

重定向数据流stream

在 shell 中,程序有两个主要的“流”:它们的输入流和输出流。 当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。 通常,一个程序的输入输出流都是您的终端。也就是,您的键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流!

最简单的重定向是 < file> file。即分别为input输入流和output输出流。这两个命令可以将程序的输入输出流分别重定向到文件:

grapefruitcat@grapefruitcat:~$ echo hellohello > hello.txt
grapefruitcat@grapefruitcat:~$ cat hello.txt
hellohello
grapefruitcat@grapefruitcat:~$ cat < hello.txt
hellohello
grapefruitcat@grapefruitcat:~$ cat < hello.txt > hello2.txt
grapefruitcat@grapefruitcat:~$ cat hello2.txt
hellohello
grapefruitcat@grapefruitcat:~$ ls
111.html binalab buflab hello2.txt hello.txt linklab newdir olddir phase3_patch.c 公共的 模板 视频 图片 文档 下载 音乐 桌面

您还可以使用 >> 来向一个文件追加内容。注意>的功能为覆盖重写,而>>为追加。

grapefruitcat@grapefruitcat:~$ echo byebye > hello.txt
grapefruitcat@grapefruitcat:~$ cat hello.txt
byebye
grapefruitcat@grapefruitcat:~$ echo byebye >> hello2.txt
grapefruitcat@grapefruitcat:~$ cat hello2.txt
hellohello
byebye

要实现追加不换行,则需要加上参数-n

grapefruitcat@grapefruitcat:/tmp/missing$ echo -n "hello," > newfile
grapefruitcat@grapefruitcat:/tmp/missing$ echo "world" >> newfile
grapefruitcat@grapefruitcat:/tmp/missing$ cat newfile
hello,world

使用管道符( pipes )---- |,我们能够更好的利用文件重定向。 | 操作符允许我们将一个程序的输出和另外一个程序的输入连接起来:

grapefruitcat@grapefruitcat:~$ ls -l /
总用量 2097264
drwxr-xr-x 2 root root 4096 10月 20 10:57 bin
drwxr-xr-x 3 root root 4096 10月 21 15:29 boot
drwxrwxr-x 2 root root 4096 3月 16 2022 cdrom
drwxr-xr-x 16 root root 4380 1月 11 11:22 dev
drwxr-xr-x 124 root root 12288 11月 21 15:58 etc
drwxr-xr-x 3 root root 4096 3月 16 2022 home
lrwxrwxrwx 1 root root 33 10月 20 10:58 initrd.img -> boot/initrd.img-5.4.0-128-generic
lrwxrwxrwx 1 root root 33 10月 20 10:58 initrd.img.old -> boot/initrd.img-5.4.0-105-generic
drwxr-xr-x 22 root root 4096 10月 20 10:56 lib
drwxr-xr-x 2 root root 4096 11月 21 15:58 lib32
drwxr-xr-x 2 root root 4096 10月 19 14:49 lib64
drwxr-xr-x 2 root root 4096 11月 21 15:58 libx32
drwx------ 2 root root 16384 3月 16 2022 lost+found
drwxr-xr-x 3 root root 4096 3月 16 2022 media
drwxr-xr-x 3 root root 4096 3月 16 2022 mnt
drwxr-xr-x 2 root root 4096 9月 16 2021 opt
dr-xr-xr-x 421 root root 0 1月 11 11:22 proc
drwx------ 5 root root 4096 3月 16 2022 root
drwxr-xr-x 29 root root 880 1月 13 21:14 run
drwxr-xr-x 2 root root 12288 10月 20 10:56 sbin
drwxr-xr-x 16 root root 4096 10月 19 09:34 snap
drwxr-xr-x 2 root root 4096 9月 16 2021 srv
-rw------- 1 root root 2147483648 3月 16 2022 swapfile
dr-xr-xr-x 13 root root 0 1月 11 11:22 sys
drwxrwxrwt 18 root root 4096 1月 13 21:28 tmp
drwxr-xr-x 13 root root 4096 11月 21 15:58 usr
drwxr-xr-x 14 root root 4096 9月 16 2021 var
lrwxrwxrwx 1 root root 30 10月 20 10:58 vmlinuz -> boot/vmlinuz-5.4.0-128-generic
lrwxrwxrwx 1 root root 30 10月 20 10:58 vmlinuz.old -> boot/vmlinuz-5.4.0-105-generic
lrwxrwxrwx 1 root root 10 3月 18 2022 桌面 -> /mnt/hgfs/
grapefruitcat@grapefruitcat:~$ ls -l / | tail -n1
lrwxrwxrwx 1 root root 10 3月 18 2022 桌面 -> /mnt/hgfs/

pipe命令前后互不影响,它可以看作一个抽象的接口,只把输入输出连接起来。

我们会在数据清理一章中更加详细的探讨如何更好的利用管道符。

sudo 根用户权限

对于大多数的类 Unix 系统,有一类用户是非常特殊的,那就是:根用户(root user)。 您应该已经注意到了,在上面的输出结果中,根用户几乎不受任何限制,他可以创建、读取、更新和删除系统中的任何文件。 通常在我们并不会以根用户的身份直接登录系统,因为这样可能会因为某些错误的操作而破坏系统。 取而代之的是我们会在需要的时候使用 sudo 命令。顾名思义,它的作用是让您可以以 su(super user 或 root 的简写)的身份执行一些操作。 当您遇到拒绝访问(permission denied)的错误时,通常是因为此时您必须是根用户才能操作。然而,请再次确认您是真的要执行此操作。

有一件事情是您必须作为根用户才能做的,那就是向 sysfs 文件写入内容。系统被挂载在 /sys 下,sysfs 文件则暴露了一些内核(kernel)参数。 因此,您不需要借助任何专用的工具,就可以轻松地在运行期间配置系统内核。注意 Windows 和 macOS 没有这个文件

例如,您笔记本电脑的屏幕亮度写在 brightness 文件中,它位于(虚拟机没有这个文件)

/sys/class/backlight

通过将数值写入该文件,我们可以改变屏幕的亮度。现在,蹦到您脑袋里的第一个想法可能是:

$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen
$ sudo echo 3 > brightness
An error occurred while redirecting file 'brightness'
open: Permission denied

出乎意料的是,我们还是得到了一个错误信息。毕竟,我们已经使用了 sudo 命令!关于 shell,有件事我们必须要知道。|>、和 < 是通过 shell 执行的,而不是被各个程序单独执行(如前文所说的pipe的前后执行互不影响)。 echo 等程序并不知道 | 的存在,它们只知道从自己的输入输出流中进行读写。 对于上面这种情况, shell (权限为您的当前用户) 在设置 sudo echo 前尝试打开 brightness 文件并写入,但是系统拒绝了 shell 的操作因为此时 shell 不是根用户。

明白这一点后,我们可以这样操作:

$ echo 3 | sudo tee brightness

Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。

tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。

因为打开 /sys 文件的是 tee 这个程序,并且该程序以 root 权限在运行,因此操作可以进行。 这样您就可以在 /sys 中愉快地玩耍了,例如修改系统中各种LED的状态(路径可能会有所不同):

$ echo 1 | sudo tee /sys/class/leds/input6::scrolllock/brightness

当然,您也可以直接使用命令进入root,这时提示符从$变成了#,所有操作变成在root权限下进行,即每一整行命令都是在root下运行的。但这很危险!

grapefruitcat@grapefruitcat:~$ sudo su
[sudo] grapefruitcat 的密码:
root@grapefruitcat:/home/grapefruitcat#
root@grapefruitcat:/home/grapefruitcat# exit
exit
grapefruitcat@grapefruitcat:~$

此外,我们可以用root权限操作来干一些很有趣的事情。比如通过写一个程序,让它在邮件到达的时候向键盘上的led灯亮度配置文件输入1,就可以得到一个检查邮件到来的通知灯效。

其它

linux 下打开文件可以用命令 xdg-open。它会自动选择适合的打开方式来打开文件,在macOS上叫open

在windows吗...who know?

grapefruitcat@grapefruitcat:~$ xdg-open 111.html
grapefruitcat@grapefruitcat:~$ [GFX1-]: glxtest: VA-API test failed: missing or old libva-drm library.

课后练习

  1. 本课程需要使用类Unix shell,例如 Bash 或 ZSH。如果您在 Linux 或者 MacOS 上面完成本课程的练习,则不需要做任何特殊的操作。如果您使用的是 Windows,则您不应该使用 cmd 或是 Powershell;您可以使用Windows Subsystem for Linux或者是 Linux 虚拟机。使用echo $SHELL命令可以查看您的 shell 是否满足要求。如果打印结果为/bin/bash/usr/bin/zsh则是可以的。

    grapefruitcat@grapefruitcat:~$ echo $SHELL
    /bin/bash
  2. /tmp 下新建一个名为 missing 的文件夹。

    grapefruitcat@grapefruitcat:/tmp$ mkdir missing
    grapefruitcat@grapefruitcat:/tmp$ ls -l
    总用量 48
    -rw------- 1 grapefruitcat grapefruitcat 0 1月 11 11:22 config-err-XVDsNU
    drwxrwxr-x 2 grapefruitcat grapefruitcat 4096 1月 18 11:20 missing
    drwx------ 2 grapefruitcat grapefruitcat 4096 1月 11 11:22 ssh-2PxNWqBWFqHz
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-bolt.service-Em4F02
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-colord.service-0GxLKZ
    drwx------ 3 root root 4096 1月 13 21:14 systemd-private-4bb41aa2370647849194529f3df1c865-fwupd.service-AUmCyt
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-ModemManager.service-1mesOZ
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-rtkit-daemon.service-DoUu5j
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-systemd-resolved.service-jpIo7N
    drwx------ 3 root root 4096 1月 11 11:22 systemd-private-4bb41aa2370647849194529f3df1c865-systemd-timesyncd.service-F8gFLo
    drwxrwxrwt 2 root root 4096 1月 12 21:52 VMwareDnD
    drwx------ 2 root root 4096 1月 11 11:22 vmware-root
    drwx------ 2 root root 4096 1月 11 11:22 vmware-root_978-2957649101
  3. man 查看程序 touch 的使用手册。

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

    touch 命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。

    "A FILE argument that does not exist is created empty, unless -c or -h is supplied."

    touch加上命令参数 -c ,在目的档案不存在时,不会建立新的档案。

    -c, --no-create do not create any files

    grapefruitcat@grapefruitcat:/tmp$ cd missing
    grapefruitcat@grapefruitcat:/tmp/missing$ touch -c semester
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l
    总用量 0
    grapefruitcat@grapefruitcat:/tmp/missing$ touch semester
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l
    总用量 0
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:31 semester

    注意创建的semester文件是一个空白文件,属于acsii类型的文本文档。利用touch命令可以创建一个文件,利用mkdir命令可以创建一个文件夹。

    专门创建文件的命令:尽量短且要通用的话可以试试空命令:,有 :>newfile

    在 bash 和 sh 下直接>new.txt,但是 zsh 好像不适用。此方法也可以用以清空文件内容。

    grapefruitcat@grapefruitcat:/tmp/missing$ > newfile
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l
    总用量 0
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:39 newfile
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:31 semester
    grapefruitcat@grapefruitcat:/tmp/missing$ :> newfile2
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l
    总用量 0
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:39 newfile
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:39 newfile2
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 0 1月 18 11:31 semester
  5. 将以下内容一行一行地写入semester文件:

     #!/bin/sh
    curl --head --silent https://baidu.com

    第一行可能有点棘手, # 在Bash中表示注释,而 ! 即使被双引号(")包裹也具有特殊的含义。 单引号(')则不一样,此处利用这一点解决输入问题。更多信息请参考 Bash quoting 手册

    grapefruitcat@grapefruitcat:/tmp/missing$ echo "#!/bin/sh"
    bash: !/bin/sh: event not found
    grapefruitcat@grapefruitcat:/tmp/missing$ echo "#'!'/bin/sh"
    bash: !'/bin/sh: event not found
    grapefruitcat@grapefruitcat:/tmp/missing$ echo '#!/bin/sh'
    #!/bin/sh
    # 利用流操作清空文件
    grapefruitcat@grapefruitcat:/tmp/missing$ > semester
    grapefruitcat@grapefruitcat:/tmp/missing$ cat semester
    # 写入内容
    grapefruitcat@grapefruitcat:/tmp/missing$ echo '#!/bin/sh' > semester
    grapefruitcat@grapefruitcat:/tmp/missing$ echo "curl --head --silent https://baidu.com" >> semester
    # 打印内容
    grapefruitcat@grapefruitcat:/tmp/missing$ cat semester
    #!/bin/sh
    curl --head --silent https://baidu.com
  6. 尝试执行这个文件。例如,将该脚本的路径(./semester)输入到您的shell中并回车。如果程序无法执行,请使用 ls 命令来获取信息并理解其不能执行的原因。

    # 显然,不能执行的第一个原因是用户权限不够。(此时我还没意识到真正问题)
    grapefruitcat@grapefruitcat:/tmp/missing$ ./semester
    bash: ./semester: 权限不够
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l
    总用量 4
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 61 1月 18 11:59 semester

    sudo 获取用户权限来执行文件,发现找不到命令:

    grapefruitcat@grapefruitcat:/tmp/missing$ sudo ./semester
    [sudo] grapefruitcat 的密码:
    sudo: ./semester:找不到命令

    可能是本地的 ubuntu 缺乏curl工具?把它补上:

    # 使用sudo apt install curl进行安装。
    grapefruitcat@grapefruitcat:/tmp/missing$ curl Command 'curl' not found, but can be installed with: sudo snap install curl # version 7.86.0, or
    sudo apt install curl See 'snap info curl' for additional versions.

    补完发现还是不行,排除 curl 命令的问题, 怎么会是呢?

    grapefruitcat@grapefruitcat:/tmp/missing$ curl --head --silent https://baidu.com
    HTTP/1.1 302 Moved Temporarily
    Server: bfe/1.0.8.18
    Date: Wed, 18 Jan 2023 04:14:53 GMT
    Content-Type: text/html
    Content-Length: 161
    Connection: keep-alive
    Location: http://www.baidu.com/ grapefruitcat@grapefruitcat:/tmp/missing$ sudo ./semester
    sudo: ./semester:找不到命令

    查阅发现是没有 x 权限。

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

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

    # 使用 chmod 命令改变权限, 添加用户执行权限
    grapefruitcat@grapefruitcat:/tmp/missing$ chmod -c u+x semester
    mode of 'semester' changed from 0664 (rw-rw-r--) to 0764 (rwxrw-r--)
    grapefruitcat@grapefruitcat:/tmp/missing$ ./semester
    HTTP/1.1 302 Moved Temporarily
    Server: bfe/1.0.8.18
    Date: Wed, 18 Jan 2023 04:39:24 GMT
    Content-Type: text/html
    Content-Length: 161
    Connection: keep-alive
    Location: http://www.baidu.com/
    # 不要使用 sh semester 来执行该程序。因为 sh 可以直接执行哈哈:
    grapefruitcat@grapefruitcat:/tmp/missing$ ls -l semester
    -rw-rw-r-- 1 grapefruitcat grapefruitcat 49 1月 18 12:11 semester
    grapefruitcat@grapefruitcat:/tmp/missing$ sh semester
    HTTP/1.1 302 Moved Temporarily
    Server: bfe/1.0.8.18
    Date: Wed, 18 Jan 2023 04:23:51 GMT
    Content-Type: text/html
    Content-Length: 161
    Connection: keep-alive
    Location: http://www.baidu.com/
  9. 使用 |> ,将 semester 文件输出的最后更改日期信息,写入主目录下的 last-modified.txt 的文件中

    # 用 stat 命令获取文件信息
    grapefruitcat@grapefruitcat:/tmp/missing$ stat ./semester | grep 最近访问 > ~/last-modified.txt
    grapefruitcat@grapefruitcat:/tmp/missing$ cd ~
    grapefruitcat@grapefruitcat:~$ ls
    111.html binalab buflab hello2.txt hello.txt last-modified.txt linklab newdir olddir phase3_patch.c 公共的 模板 视频 图片 文档 下载 音乐 桌面
    # 查看文件内容
    grapefruitcat@grapefruitcat:~$ cat last-modified.txt
    最近访问:2023-01-18 12:39:24.154799101 +0800
  10. 写一段命令来从 /sys 中获取笔记本的电量信息,或者台式机 CPU 的温度。注意:macOS 并没有 sysfs,所以 Mac 用户可以跳过这一题。

# 如果使用虚拟机,则无法获取电量信息和cpu温度
# 官方答案:查询电量
cat /sys/class/power_supply/BAT1/capacity
# cpu的配置信息应该在以下路径
grapefruitcat@grapefruitcat:/sys$ cd ./devices/cpu/power
grapefruitcat@grapefruitcat:/sys/devices/cpu/power$ ls -l
总用量 0
-rw-r--r-- 1 root root 4096 1月 18 13:47 async
-rw-r--r-- 1 root root 4096 1月 18 13:47 autosuspend_delay_ms
-rw-r--r-- 1 root root 4096 1月 18 13:47 control
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_active_kids
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_active_time
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_enabled
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_status
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_suspended_time
-r--r--r-- 1 root root 4096 1月 18 13:47 runtime_usage

The Missing Semester - 第一讲 学习笔记的更多相关文章

  1. 深挖计算机基础:MySQL实战45讲学习笔记

    参考极客时间专栏<MySQL实战45讲>学习笔记 一.基础篇(8讲) MySQL实战45讲学习笔记:第一讲 MySQL实战45讲学习笔记:第二讲 MySQL实战45讲学习笔记:第三讲 My ...

  2. MySQL实战45讲学习笔记:第三十九讲

    一.本节概况 MySQL实战45讲学习笔记:自增主键为什么不是连续的?(第39讲) 在第 4 篇文章中,我们提到过自增主键,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧 ...

  3. [未完成]WebService学习第一天学习笔记

    [未完成]WebService学习第一天学习笔记[未完成]WebService学习第一天学习笔记

  4. PJ可能会用到的动态规划选讲-学习笔记

    PJ可能会用到的动态规划选讲-学习笔记 by Pleiades_Antares 难度和速度全部都是按照普及组来定的咯 数位状压啥就先不讲了 这里主要提到的都是比较简单的DP 一道思维数学巧题(补昨天) ...

  5. 20165326 java第一周学习笔记

    第一周学习笔记 一.理论视频学习 1.Java的特点:简单.面向对象.平台无关 2.Java的开发步骤&简单的应用程序: 文本编辑器写入代码 命名类名.java,文件类型所有文件,编码ANSI ...

  6. 《Linux内核分析》第一周学习笔记

    <Linux内核分析>第一周学习笔记 计算机是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...

  7. linux内核分析第一周学习笔记

    linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  8. Spring实战第一章学习笔记

    Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...

  9. MySQL实战45讲学习笔记:事务隔离级别(第三讲)

    一.隔离性与隔离级别 1.事务的特性 原子性 一致性 隔离性 持久性 2.不同事务隔离级别的区别 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到.读已提交:别人改数据的事务已经提交,我在我 ...

  10. linux就该这么学 第一天学习笔记

    题外话 在每天的网上冲浪中,一次无意间的点击,发现了linux就该这么学的网站,然后就看了一晚上,当时还是学生的我特别想要参加培训,可是碍于眼前的经济状况,只得将这个想法深深的藏在了心里,并加了一下网 ...

随机推荐

  1. A-深度学习面试题

    目录 目录 一,滤波器与卷积核 二,卷积层和池化输出大小计算 2.1,CNN 中术语解释 2.2,卷积输出大小计算(简化型) 2.3,理解边界效应与填充 padding 参考资料 三,深度学习框架的张 ...

  2. windows error LNK2019

    温馨提示,请使用ctrl+F进行快速查找 ws2_32.lib error LNK2001: 无法解析的外部符号 __imp_htons error LNK2001: 无法解析的外部符号 __imp_ ...

  3. Hexo+next主题美化

    前言 需要在Hexo下配置next主题 Hexo配置next主题教程:https://www.cnblogs.com/xuande/p/16641543.html 更改配置以后使用素质三连:hexo ...

  4. pycharm 小技巧

    ctrl键 + B 查看定义源代码 alt键 + enter键 查看帮助 ctrl键 + shift键 + -号 所有代码隐藏 ctrl键 + shift键 + +号 所有代码展示 ctrl键 + D ...

  5. Appium工具

    1.安装 (1)jdk安装以及环境配置 a.jdk下载地址:https://www.oracle.com/cn/java/technologies/downloads/ 新建系统环境变量: b.编辑P ...

  6. C++进阶(智能指针)

    智能指针原理 C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理.程序员自己管理堆内存可以提高了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11中引入了智能指针的 ...

  7. React中实现keepalive组件缓存效果

    背景:由于react官方并没有提供缓存组件相关的api(类似vue中的keepalive),在某些场景,会使得页面交互性变的很差,比如在有搜索条件的表格页面,点击某一条数据跳转到详情页面,再返回表格页 ...

  8. 在不使用cv2等库的情况下利用numpy实现双线性插值缩放图像

    起因 我看到了一个别人的作业,他们老师让不使用cv2等图像处理库缩放图像 算法介绍 如果你仔细看过一些库里缩放图像的方法参数会发现有很多可选项,其中一般默认是使用双线性插值.具体步骤: 计算目标图坐标 ...

  9. 手把手教你写Dockerfile以及测试

    Dockerfile是什么? dockerfile就是用来构建docker镜像的构建文件,命令参数脚本. 如何使用Dockerfile? 1.编写一个Dockerfile文件 2.docker bui ...

  10. 详解 Gulp4 和 Gulp3 的区别

    最近在开发几个网站,为了优化一下前端代码,就复习一下gulpjs,之前工作gulp用的版本比较老,但是今天看了新的版本,新的语法出了一下,但是为了时间,我决定使用之前gulp3的旧版本,后面发现自己环 ...