(该系列文章大部分内容来源于MIT课程笔记,加入了个人的理解、原笔记中没有的细节和其他的需要理解的内容,公开课地址:https://www.bilibili.com/video/BV14E411J7n2?p=1)
上一讲:安全和密码学
下一讲:Q&A(Q&A由于博主没有太多其他的见解,所以直接引用MIT课程讲义)
通常这个功能由在计算机上运行的软件实现。当某一个按键被按下,软件截获键盘发出的按键事件(keypress event)并使用另外一个事件取代。比如:
你也可以将键位映射为任意常用的指令。软件监听到特定的按键组合后会运行设定的脚本。甚至更复杂的修改也可以通过软件实现:
下面是一些修改键位映射的软件:
大部分计算机都有一系列在后台保持运行,不需要用户手动运行或者交互的进程。这些进程就是守护进程(deamon)。以守护进程运行的程序名一般以 d 结尾,比如 SSH 服务端 sshd,用来监听传入的 SSH 连接请求并对用户进行鉴权。
Linux 中的 systemd
(the system daemon)是最常用的配置和运行守护进程的方法。运行 systemctl status 命令可以看到正在运行的所有守护进程。这里面有很多可能你没有见过,但是掌管了系统的核心部分的进程:管理网络、DNS解析、显示系统的图形界面等等。用户使用 systemctl
命令和systemd
交互来enable(启用)、disable(禁用)、start(启动)、stop(停止)、restart(重启)、或者status(检查)配置好的守护进程及系统服务。
systemd 提供了一个很方便的界面用于配置和启用新的守护进程或系统服务。下面的配置文件使用了守护进程来运行一个简单的 Python 程序。文件的内容非常直接所以我们不对它详细阐述。systemd 配置文件的详细指南可参见 freedesktop.org。
# /etc/systemd/system/myapp.service
[Unit]
# 配置文件描述
Description=My Custom App
# 在网络服务启动后启动该进程
After=network.target
[Service]
# 运行该进程的用户
User=foo
# 运行该进程的用户组
Group=foo
# 运行该进程的根目录
WorkingDirectory=/home/foo/projects/mydaemon
# 开始该进程的命令
ExecStart=/usr/bin/local/python3.7 app.py
# 在出现错误时重启该进程
Restart=on-failure
[Install]
# 相当于Windows的开机启动。即使GUI没有启动,该进程也会加载并运行
WantedBy=multi-user.target
# 如果该进程仅需要在GUI活动时运行,这里应写作:
# WantedBy=graphical.target
# graphical.target在multi-user.target的基础上运行和GUI相关的服务
如果你只是想定期运行一些程序,可以直接使用 cron。它是一个系统内置的,用来执行定期任务的守护进程。
现在的软件系统一般由很多模块化的组件构建而成。你使用的操作系统可以通过一系列共同的方式使用不同的文件系统上的相似功能。比如当你使用 touch
命令创建文件的时候,touch
使用系统调用(system call)向内核发出请求。内核再根据文件系统,调用特有的方法来创建文件。这里的问题是,UNIX 文件系统在传统上是以内核模块的形式实现,导致只有内核可以进行文件系统相关的调用。
FUSE(用户空间文件系统)允许运行在用户空间上的程序实现文件系统调用,并将这些调用与内核接口联系起来。在实践中,这意味着用户可以在文件系统调用中实现任意功能。
FUSE 可以用于实现如:一个将所有文件系统操作都使用 SSH 转发到远程主机,由远程主机处理后返回结果到本地计算机的虚拟文件系统。这个文件系统里的文件虽然存储在远程主机,对于本地计算机上的软件而言和存储在本地别无二致。sshfs就是一个实现了这种功能的 FUSE 文件系统。
一些有趣的 FUSE 文件系统包括:
任何没有备份的数据都可能在一个瞬间永远消失。复制数据很简单,但是可靠地备份数据很难。有效备份方案的几个核心特性是:版本控制,删除重复数据,以及安全性。
3-2-1规则是备份数据的一个通用规则:
备份不限制于备份在本地计算机上的文件。云端应用的重大发展使得我们很多的数据只存储在云端。当我们无法登录这些应用,在云端存储的网络邮件,社交网络上的照片,流媒体音乐播放列表,以及在线文档等等都会随之丢失,用户应该有这些数据的离线备份。
首先,复制存储在同一个磁盘上的数据不是备份,因为这个磁盘是一个单点故障(single point of failure)。这个磁盘一旦出现问题,所有的数据都可能丢失。推荐的做法是将数据备份到不同的地点存储。
同步方案也不是备份。即使方便如 Dropbox 或者 Google Drive,当数据在本地被抹除或者损坏,同步方案可能会把这些“更改”同步到云端。同理,像 RAID 这样的磁盘镜像方案也不是备份。它不能防止文件被意外删除、损坏、或者被勒索软件加密。
对备份的数据实施版本控制保证了用户可以从任何记录过的历史版本中恢复数据。
在备份中检测并删除重复数据,使其仅备份增量变化可以减少存储开销。为了减少重复数据并保持安全性, Tarsnap和Borgbase是两种商用途径,他们提供给用户两种密匙,一种是只允许追加,一种是替换(删除原有内容再添加),后者(可以删除的密匙)存储在用户本地,避免恶意软件的侵入而导致你的数据丢失。
在安全性方面,作为用户,你应该考虑别人需要有什么信息或者工具才可以访问或者完全删除你的数据及备份。由于第三方备份不是总是可以信任,你可以将你的数据加密之后再备份到第三方,目前很多第三方支持用户加密,除非得到你的密匙,否则服务器无法读取你的数据。最后一点,不要盲目信任备份方案,用户应该经常检查备份是否可以用来恢复数据。
关于如何使用计算机有效率地完成 本地 任务,我们这堂课已经介绍了很多方法。这些方法在互联网上其实也适用。大多数线上服务提供的 API(应用程序接口)让你可以通过编程方式来访问这些服务的数据。比如,美国国家气象局就提供了一个可以从 shell 中获取天气预报的 API。
这些 API 大多具有类似的格式。它们的结构化 URL 通常使用 api.service.com
作为根路径,用户可以访问不同的子路径来访问需要调用的操作,以及添加查询参数使 API 返回符合查询参数条件的结果。
以美国天气数据为例,为了获得某个地点的天气数据,你可以发送一个 GET 请求(比如使用curl
)到https://api.weather.gov/points/42.3604,-71.094。返回中会包括一系列用于获取特定信息(比如小时预报、气象观察站信息等)的 URL。通常这些返回都是JSON
格式,你可以使用jq等工具来选取需要的部分。
有些需要认证的 API 通常要求用户在请求中加入某种私密令牌(secret token)来完成认证。请阅读你想访问的 API 所提供的文档来确定它请求的认证方式,但是其实大多数 API 都会使用 OAuth。OAuth 通过向用户提供一系列仅可用于该 API 特定功能的私密令牌进行校验。因为使用了有效 OAuth 令牌的请求在 API 看来就是用户本人发出的请求,所以请一定保管好这些私密令牌。否则其他人就可以冒用你的身份进行任何你可以在这个 API 上进行的操作。
IFTTT 这个网站可以将很多 API 整合在一起,让某 API 发生的特定事件触发在其他 API 上执行的任务。IFTTT 的全称If This Then That 足以说明它的用法,比如在检测到用户的新推文后,自动发布在其他平台。
命令行工具的用法千差万别,阅读 man 页面可以帮助你理解每种工具的用法。即便如此,下面我们将介绍一下命令行工具一些常见的共同功能。
lilhoe at LilHoedeMacBook-Pro in ~
$ python3 -V
Python 3.8.1
- 使用 rm 删除一个叫 -r 的文件;
- 在通过一个程序运行另一个程序的时候(ssh machine foo),向内层的程序(foo)传递一个标志参数。
这时候你可以使用特殊参数 – 让某个程序 停止处理 – 后面出现的标志参数以及选项(以 - 开头的内容):- rm - - -r 会让 rm 将 -r 当作文件名;
- ssh machine --for-ssh – foo --for-foo 的 – 会让 ssh 知道 --for-foo 不是 ssh 的标志参数。
大部分人适应了 Windows、macOS、以及 Ubuntu 默认的“拖拽”式窗口管理器。这种堆叠式(floating/stacking)管理器只是窗口管理器中的一种。特别在 Linux 中,有很多种其他的管理器。
平铺式(tiling)管理器就是一个常见的替代。顾名思义,平铺式管理器会把不同的窗口像贴瓷砖一样平铺在一起而不和其他窗口重叠。这和 tmux 管理终端窗口的方式类似。平铺式管理器按照写好的布局显示打开的窗口。如果只打开一个窗口,它会填满整个屏幕。新开一个窗口的时候,原来的窗口会缩小到比如三分之二或者三分之一的大小来腾出空间。打开更多的窗口会让已有的窗口进一步调整。平铺式管理器可以让你在完全不使用鼠标的情况下使用键盘切换、缩放、以及移动窗口。
V*N(csdn检测为敏感词汇…) 现在非常火,但我们不清楚这是不是因为一些好的理由。你应该了解 V*N 能提供的功能和它的限制。使用了 V*N 的你对于互联网而言,最好的情况下也就是换了一个网络供应商(ISP)。所有你发出的流量看上去来源于 V*N 供应商的网络而不是你的“真实”地址,而你实际接入的网络只能看到加密的流量。
虽然这听上去非常诱人,但是你应该知道使用 V*N 只是把原本对网络供应商的信任放在了 V*N 供应商那里——网络供应商 能看到的,V*N 供应商 也都能看到。如果相比网络供应商你更信任 V*N 供应商,那当然很好。反之,则连接V*N的价值不明确。机场的不加密公共热点确实不可以信任,但是在家庭网络环境里,这个差异就没有那么明显。
你也应该了解现在大部分包含用户敏感信息的流量已经被 HTTPS 或者 TLS 加密。这种情况下你所处的网络环境是否“安全”不太重要:供应商只能看到你和哪些服务器在交谈,却不能看到你们交谈的内容。
这一切的大前提都是“最好的情况”。曾经发生过 V*N 提供商错误使用弱加密或者直接禁用加密的先例。另外,有些恶意的或者带有投机心态的供应商会记录和你有关的所有流量,并很可能会将这些信息卖给第三方。找错一家 V*N 经常比一开始就不用 V*N 更危险。
如果你也想自己配置一个 V*N,可以了解一下 WireGuard 以及 Algo。
在不使用 Word 或者 LaTeX 等复杂工具的情况下,你可以考虑使用 Markdown 这个轻量化的标记语言(markup language)。你可能已经见过 Markdown 或者它的一个变种。很多环境都支持并使用 Markdown 的一些子功能。
Markdown 致力于将人们编写纯文本时的一些习惯标准化。比如:
就像这样
Markdown 不仅容易上手,而且应用非常广泛。实际上本课程的课堂笔记和其他资料都是使用 Markdown 编写的。点击这个链接可以看到本页面的原始 Markdown 内容。
Hammerspoon 是面向 macOS 的一个桌面自动化框架。它允许用户编写和操作系统功能挂钩的 Lua 脚本,从而与键盘、鼠标、窗口、文件系统等交互。
下面是 Hammerspoon 的一些示例应用:
从用户的角度,Hammerspoon 可以运行任意 Lua 代码,绑定菜单栏按钮、按键、或者事件。Hammerspoon 提供了一个全面的用于和系统交互的库,因此它能没有限制地实现任何功能。你可以从头编写自己的 Hammerspoon 配置,也可以结合别人公布的配置来满足自己的需求。
在你的计算机启动时,BIOS 或者 UEFI 会在加载操作系统之前对硬件系统进行初始化,这被称为引导(booting)。你可以通过按下计算机提示的键位组合来配置引导,比如 Press F9 to configure BIOS. Press F12 to enter boot menu
。在 BIOS 菜单中你可以对硬件相关的设置进行更改,也可以在引导菜单中选择从硬盘以外的其他设备加载操作系统——比如 Live USB。
Live USB 是包含了完整操作系统的闪存盘。Live USB 的用途非常广泛,包括:
Live USB 通过在闪存盘上 写入 操作系统的镜像制作,而写入不是单纯的往闪存盘上复制 .iso 文件。你可以使用 UNetbootin 、Rufus 等 Live USB 写入工具制作。
虚拟机(Virtual Machine)以及如容器化(containerization)等工具可以帮助你模拟一个包括操作系统的完整计算机系统。虚拟机可以用于创建独立的测试或者开发环境,以及用作安全测试的沙盒。
Vagrant 是一个构建和配置虚拟开发环境的工具。它支持用户在配置文件中写入比如操作系统、系统服务、需要安装的软件包等描述,然后使用 vagrant up
命令在各种环境(VirtualBox,KVM,Hyper-V等)中启动一个虚拟机。Docker 是一个使用容器化概念的类似工具。
租用云端虚拟机可以享受以下资源的即时访问:
受欢迎的 VPS 服务商有 Amazon AWS,Google Cloud,以及 DigitalOcean。
交互式记事本可以帮助开发者进行与运行结果交互等探索性的编程。现在最受欢迎的交互式记事本环境大概是 Jupyter。它的名字来源于所支持的三种核心语言:Julia、Python、R。Wolfram Mathematica 是另外一个常用于科学计算的优秀环境。
GitHub 是最受欢迎的开源软件开发平台之一。我们课程中提到的很多工具,从 vim 添加链接描述到 Hammerspoon,都托管在 Github 上。向你每天使用的开源工具作出贡献其实很简单,下面是两种贡献者们经常使用的方法:
创建一个议题(issue)。 议题可以用来反映软件运行的问题或者请求新的功能。创建议题并不需要创建者阅读或者编写代码,所以它是一个轻量化的贡献方式。高质量的问题报告对于开发者十分重要。在现有的议题发表评论也可以对项目的开发作出贡献。
使用拉取请求(pull request)提交代码更改。由于涉及到阅读和编写代码,提交拉取请求总的来说比创建议题更加深入。拉取请求是请求别人把你自己的代码拉取(且合并)到他们的仓库里。很多开源项目仅允许认证的管理者管理项目代码,所以一般需要复刻(fork)这些项目的上游仓库(upstream repository),在你的 Github 账号下创建一个内容完全相同但是由你控制的复刻仓库。这样你就可以在这个复刻仓库自由创建新的分支并推送修复问题或者实现新功能的代码。完成修改以后再回到开源项目的 Github 页面创建一个拉取请求。
提交请求后,项目管理者会和你交流拉取请求里的代码并给出反馈。如果没有问题,你的代码会和上游仓库中的代码合并。很多大的开源项目会提供贡献指南,容易上手的议题,甚至专门的指导项目来帮助参与者熟悉这些项目。
参考:
https://missing-semester-cn.github.io/2020/potpourri/