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
使用 shell 的注意事项 -- 注意参数输入
当您打开终端时,您会看到一个提示符,它看起来一般是这个样子的:
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
,同时指定参数 hello
。echo
程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数。如果您希望传递的参数中包含空格(例如一个名为 My Photos 的文件夹),您要么用使用单引号,双引号将其包裹起来,要么使用转义符号 \
进行处理(My\ Photos
)。
环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等,在开发环境或者部署环境中都需要使用到。
系统内嵌了许多围绕终端工作的程序,而 shell 通过环境变量去搜索程序。
shell 是如何知道去哪里寻找 date
或 echo
的呢?其实,类似于 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
,通过直接指定需要执行的程序的路径来执行该程序。
关于环境变量具体可参考博文:
在shell中导航 -- 路径
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 提示符来显示各种有用的信息,参考博客:
一般来说,当我们运行一个程序时,如果我们没有指定路径,则该程序会在当前目录下执行。例如,我们常常会搜索文件,并在需要时创建文件。
为了查看指定目录下包含哪些文件,我们使用 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.
课后习题
课后练习
-
本课程需要使用类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
-
在
/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
-
用
man
查看程序touch
的使用手册。 -
用
touch
在missing
文件夹中新建一个叫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
-
将以下内容一行一行地写入
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
-
尝试执行这个文件。例如,将该脚本的路径(
./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
权限。 -
查看
chmod
的手册(例如,使用man chmod
命令) -
使用
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/
-
使用
|
和>
,将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
-
写一段命令来从
/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
标签:11,shell,4096,Missing,--,grapefruitcat,笔记,Semester,root
From: https://www.cnblogs.com/grapefruit-cat/p/17059665.html