mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
Merge branch 'master' of https://github.com/LCTT/TranslateProject into translating
This commit is contained in:
commit
fb1d77b323
@ -1,18 +1,20 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10535-1.html)
|
||||
[#]: subject: (Getting started with Sandstorm, an open source web app platform)
|
||||
[#]: via: (https://opensource.com/article/19/1/productivity-tool-sandstorm)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
|
||||
|
||||
开始使用 Sandstorm,一个开源 Web 应用平台
|
||||
开始使用 Sandstorm 吧,一个开源 Web 应用平台
|
||||
======
|
||||
了解 Sandstorm,这是我们在开源工具系列中的第三篇,它将在 2019 年提高你的工作效率。
|
||||
|
||||
> 了解 Sandstorm,这是我们在开源工具系列中的第三篇,它将在 2019 年提高你的工作效率。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/sand_dunes_desert_hills_landscape_nature.jpg?itok=wUByylBb)
|
||||
|
||||
每年年初似乎都有疯狂的冲动,想方设法提高工作效率。新年的决议,开始一年的权利,当然,“与旧的,与新的”的态度都有助于实现这一目标。通常的一轮建议严重偏向封闭源和专有软件。它不一定是这样。
|
||||
每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。
|
||||
|
||||
这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第三个工具来帮助你在 2019 年更有效率。
|
||||
|
||||
@ -22,7 +24,7 @@
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/sandstorm_1.png)
|
||||
|
||||
[Sandstorm][1]是打包的开源应用集合,它们都可从一个 Web 界面访问,也可在中央控制台进行管理。你可以自己托管或使用 [Sandstorm Oasis][2] 服务。它按用户收费。
|
||||
[Sandstorm][1] 是打包的开源应用集合,它们都可从一个 Web 界面访问,也可在中央控制台进行管理。你可以自己托管或使用 [Sandstorm Oasis][2] 服务。它按用户收费。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/sandstorm_2.png)
|
||||
|
||||
@ -46,7 +48,7 @@ via: https://opensource.com/article/19/1/productivity-tool-sandstorm
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,138 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10534-1.html)
|
||||
[#]: subject: (Top 5 Linux Distributions for Development in 2019)
|
||||
[#]: via: (https://www.linux.com/blog/2019/1/top-5-linux-distributions-development-2019)
|
||||
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||
|
||||
5 个用于开发工作的 Linux 发行版
|
||||
======
|
||||
|
||||
> 这五个发行版用于开发工作将不会让你失望。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev-main.jpg?itok=DEe9pYtb)
|
||||
|
||||
Linux 上最受欢迎的任务之一肯定是开发。理由很充分:业务依赖于 Linux。没有 Linux,技术根本无法满足当今不断发展的世界的需求。因此,开发人员不断努力改善他们的工作环境。而进行此类改善的一种方法就是拥有合适的平台。值得庆幸的是,这就是 Linux,所以你总是有很多选择。
|
||||
|
||||
但有时候,太多的选择本身就是一个问题。哪种发行版适合你的开发需求?当然,这取决于你正在开发的工作,但某些发行版更适合作为你的工作任务的基础。我将重点介绍我认为 2019 年最适合开发人员的五个发行版。
|
||||
|
||||
### Ubuntu
|
||||
|
||||
无需赘言。虽然 Linux Mint 的忠实用户无疑是一个非常忠诚的群体(这是有充分的理由的,他们选择的发行版很棒),但 Ubuntu Linux 在这里更被认可。为什么?因为有像 [AWS][1] 这样的云服务商存在,Ubuntu 成了部署最多的服务器操作系统之一。这意味着在 Ubuntu 桌面发行版上进行开发可以更轻松地转换为 Ubuntu Server。而且因为 Ubuntu 使得开发、使用和部署容器非常容易,所以你想要使用这个平台是完全合理的。而 Ubuntu 与其包含的 Snap 软件包相结合,使得这个 Canonical(Ubuntu 发行版背后的公司)的操作系统如虎添翼。
|
||||
|
||||
但这不仅是你可以用 Ubuntu 做什么,而是你可以轻松做到。几乎对于所有的任务,Ubuntu 都是一个非常易用的发行版。而且因为 Ubuntu 如此受欢迎,所以你可以从 Ubuntu “软件” 应用的图形界面里轻松安装你想要使用的每个工具和 IDE(图 1)。
|
||||
|
||||
![Ubuntu][3]
|
||||
|
||||
*图 1:可以在 Ubuntu “软件”工具里面找到开发者工具。*
|
||||
|
||||
如果你正在寻求易用、易于迁移,以及大量的工具,那么将 Ubuntu 作为开发平台就不会有错。
|
||||
|
||||
### openSUSE
|
||||
|
||||
我将 openSUSE 添加到此列表中有一个非常具体的原因。它不仅是一个出色的桌面发行版,它还是市场上最好的滚动发行版之一。因此,如果你希望用最新的软件开发、发布最新的软件,[openSUSE Tumbleweed][5] 应该是你的首选之一。如果你想使用最喜欢的 IDE 的最新版本,如果你总是希望确保使用最新的库和工具包进行开发,那么 Tumbleweed 就是你的平台。
|
||||
|
||||
但 openSUSE 不仅提供滚动发布版本。如果你更愿意使用标准发行版,那么 [openSUSE Leap][6] 就是你想要的。
|
||||
|
||||
当然,它不仅有标准版或滚动版,openSUSE 平台还有一个名为 [Kubic][7] 的 Kubernetes 特定版本,该版本基于 openSUSE MicroOS 上的 Kubernetes。但即使你没有为 Kubernetes 进行开发,你也会发现许多软件和工具可供使用。
|
||||
|
||||
openSUSE 还提供了选择桌面环境的能力,或者你也可以选择通用桌面或服务器(图 2)。
|
||||
|
||||
![openSUSE][9]
|
||||
|
||||
*图 2: 正在安装 openSUSE Tumbleweed。*
|
||||
|
||||
### Fedora
|
||||
|
||||
使用 Fedora 作为开发平台才有意义。为什么?这个发行版本身似乎是面向开发人员的。通过定期的六个月发布周期,开发人员可以确保他们不会一直使用过时的软件。当你需要最新的工具和库时,这很重要。如果你正在开发企业级业务,Fedora 是一个理想的平台,因为它是红帽企业 Linux(RHEL)的上游。这意味着向 RHEL 的过渡应该是无痛的。这一点很重要,特别是如果你希望将你的项目带到一个更大的市场(一个比以桌面为中心的目标更深的领域)。
|
||||
|
||||
Fedora 还提供了你将体验到的最佳 GNOME 体验之一(图 3)。换言之,这是非常稳定和快速的桌面。
|
||||
|
||||
![GNOME][11]
|
||||
|
||||
*图 3:Fedora 上的 GNOME 桌面。*
|
||||
|
||||
但是如果 GNOME 不是你的菜,你还可以选择安装一个 [Fedora 花样版][12](包括 KDE、XFCE、LXQT、Mate-Compiz、Cinnamon、LXDE 和 SOAS 等桌面环境)。
|
||||
|
||||
### Pop!_OS
|
||||
|
||||
如果这个列表中我没有包括 [System76][13] 平台专门为他们的硬件定制的操作系统(虽然它也在其他硬件上运行良好),那我算是失职了。为什么我要包含这样的发行版,尤其是它还并未远离其所基于的 Ubuntu 平台?主要是因为如果你计划从 System76 购买台式机或笔记本电脑,那它就是你想要的发行版。但是你为什么要这样做呢(特别是考虑到 Linux 几乎适用于所有现成的硬件)?因为 System76 销售的出色硬件。随着他们的 Thelio 桌面的发布,这是你可以使用的市场上最强大的台式计算机之一。如果你正在努力开发大型应用程序(特别是那些非常依赖于非常大的数据库或需要大量处理能力进行编译的应用程序),为什么不用最好的计算机呢?而且由于 Pop!_OS 完全适用于 System76 硬件,因此这是一个明智的选择。
|
||||
|
||||
由于 Pop!_OS 基于 Ubuntu,因此你可以轻松获得其所基于的 Ubuntu 可用的所有工具(图 4)。
|
||||
|
||||
![Pop!_OS][15]
|
||||
|
||||
*图 4:运行在 Pop!_OS 上的 Anjunta IDE*
|
||||
|
||||
Pop!_OS 也会默认加密驱动器,因此你可以放心你的工作可以避免窥探(如果你的硬件落入坏人之手)。
|
||||
|
||||
### Manjaro
|
||||
|
||||
对于那些喜欢在 Arch Linux 上开发,但不想经历安装和使用 Arch Linux 的所有环节的人来说,那选择就是 Manjaro。Manjaro 可以轻松地启动和运行一个基于 Arch Linux 的发行版(就像安装和使用 Ubuntu 一样简单)。
|
||||
|
||||
但是 Manjaro 对开发人员友好的原因(除了享受 Arch 式好处)是你可以下载好多种不同口味的桌面。从[Manjaro 下载页面][16] 中,你可以获得以下口味:
|
||||
|
||||
* GNOME
|
||||
* XFCE
|
||||
* KDE
|
||||
* OpenBox
|
||||
* Cinnamon
|
||||
* I3
|
||||
* Awesome
|
||||
* Budgie
|
||||
* Mate
|
||||
* Xfce 开发者预览版
|
||||
* KDE 开发者预览版
|
||||
* GNOME 开发者预览版
|
||||
* Architect
|
||||
* Deepin
|
||||
|
||||
值得注意的是它的开发者版本(面向测试人员和开发人员),Architect 版本(适用于想要从头开始构建 Manjaro 的用户)和 Awesome 版本(图 5,适用于开发人员处理日常工作的版本)。使用 Manjaro 的一个警告是,与任何滚动版本一样,你今天开发的代码可能明天无法运行。因此,你需要具备一定程度的敏捷性。当然,如果你没有为 Manjaro(或 Arch)做开发,并且你正在进行工作更多是通用的(或 Web)开发,那么只有当你使用的工具被更新了且不再适合你时,才会影响你。然而,这种情况发生的可能性很小。和大多数 Linux 发行版一样,你会发现 Manjaro 有大量的开发工具。
|
||||
|
||||
![Manjaro][18]
|
||||
|
||||
*图 5:Manjaro Awesome 版对于开发者来说很棒。*
|
||||
|
||||
Manjaro 还支持 AUR(Arch User Repository —— Arch 用户的社区驱动软件库),其中包括最先进的软件和库,以及 [Unity Editor][19] 或 yEd 等专有应用程序。但是,有个关于 AUR 的警告:AUR 包含的软件中被怀疑发现了恶意软件。因此,如果你选择使用 AUR,请谨慎操作,风险自负。
|
||||
|
||||
### 其实任何 Linux 都可以
|
||||
|
||||
说实话,如果你是开发人员,几乎任何 Linux 发行版都可以工作。如果从命令行执行大部分开发,则尤其如此。但是如果你喜欢在可靠的桌面上运行一个好的图形界面程序,试试这些发行版中的一个,它们不会令人失望。
|
||||
|
||||
通过 Linux 基金会和 edX 的免费[“Linux 简介”][20]课程了解有关 Linux 的更多信息。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/2019/1/top-5-linux-distributions-development-2019
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/jlwallen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://aws.amazon.com/
|
||||
[2]: https://www.linux.com/files/images/dev1jpg
|
||||
[3]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_1.jpg?itok=7QJQWBKi (Ubuntu)
|
||||
[4]: https://www.linux.com/licenses/category/used-permission
|
||||
[5]: https://en.opensuse.org/Portal:Tumbleweed
|
||||
[6]: https://en.opensuse.org/Portal:Leap
|
||||
[7]: https://software.opensuse.org/distributions/tumbleweed
|
||||
[8]: /files/images/dev2jpg
|
||||
[9]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_2.jpg?itok=1GJmpr1t (openSUSE)
|
||||
[10]: /files/images/dev3jpg
|
||||
[11]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_3.jpg?itok=_6Ki4EOo (GNOME)
|
||||
[12]: https://spins.fedoraproject.org/
|
||||
[13]: https://system76.com/
|
||||
[14]: /files/images/dev4jpg
|
||||
[15]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_4.jpg?itok=nNG2Ax24 (Pop!_OS)
|
||||
[16]: https://manjaro.org/download/
|
||||
[17]: /files/images/dev5jpg
|
||||
[18]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_5.jpg?itok=RGfF2UEi (Manjaro)
|
||||
[19]: https://unity3d.com/unity/editor
|
||||
[20]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10536-1.html)
|
||||
[#]: subject: (3 simple and useful GNOME Shell extensions)
|
||||
[#]: via: (https://fedoramagazine.org/3-simple-and-useful-gnome-shell-extensions/)
|
||||
[#]: author: (Ryan Lerch https://fedoramagazine.org/introducing-flatpak/)
|
||||
@ -11,37 +11,37 @@
|
||||
======
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2019/01/3simple-816x345.png)
|
||||
|
||||
Fedora Workstation 的默认桌面 GNOME Shell,因其最小化,整洁的用户界面而闻名并深受许多用户的喜爱。它还以可使用扩展添加到 stock 界面的能力而闻名。在本文中,我们将介绍 GNOME Shell 的 3 个简单且有用的扩展。这三个扩展为你的桌面提供了简单的,你可能每天都会做的行为。
|
||||
Fedora 工作站的默认桌面 GNOME Shell,因其极简、整洁的用户界面而闻名,并深受许多用户的喜爱。它还以可使用扩展添加到 stock 界面的能力而闻名。在本文中,我们将介绍 GNOME Shell 的 3 个简单且有用的扩展。这三个扩展为你的桌面提供了更多的行为,可以完成你可能每天都会做的简单任务。
|
||||
|
||||
### 安装扩展程序
|
||||
|
||||
安装 GNOME Shell 扩展的最快捷最简单的方法是使用软件应用。有关详细信息,请查看 Magazine 中的上一篇文章:
|
||||
安装 GNOME Shell 扩展的最快捷、最简单的方法是使用“软件”应用。有关详细信息,请查看 Magazine [以前的文章](https://fedoramagazine.org/install-extensions-via-software-application/):
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2018/11/installing-extensions-768x325.jpg)
|
||||
|
||||
### Removable Drive Menu
|
||||
### 可移动驱动器菜单
|
||||
|
||||
![][1]
|
||||
|
||||
Fedora 29 中的 Removable Drive Menu 扩展
|
||||
*Fedora 29 中的 Removable Drive Menu 扩展*
|
||||
|
||||
首先是 [Removable Drive Menu][2] 扩展。如果你的计算机中有可移动驱动器,那么它是一个可在系统托盘中添加一个 widget 的简单工具。它可以使你轻松打开可移动驱动器中的文件,或者快速方便地弹出驱动器以安全移除设备。
|
||||
首先是 [Removable Drive Menu][2] 扩展。如果你的计算机中有可移动驱动器,它是一个可在系统托盘中添加一个 widget 的简单工具。它可以使你轻松打开可移动驱动器中的文件,或者快速方便地弹出驱动器以安全移除设备。
|
||||
|
||||
![][3]
|
||||
|
||||
软件应用中的 Removable Drive Menu
|
||||
*软件应用中的 Removable Drive Menu*
|
||||
|
||||
### Extensions 扩展
|
||||
### 扩展之扩展
|
||||
|
||||
![][4]
|
||||
|
||||
如果你一直在安装和尝试新扩展,那么 [Extensions][5] 扩展非常有用。它提供了所有已安装扩展的列表,允许你启用或禁用它们。此外,如果扩展有设置,那么可以快速打开每个扩展的设置对话框。
|
||||
如果你一直在安装和尝试新扩展,那么 [Extensions][5] 扩展非常有用。它提供了所有已安装扩展的列表,允许你启用或禁用它们。此外,如果该扩展有设置,那么可以快速打开每个扩展的设置对话框。
|
||||
|
||||
![][6]
|
||||
|
||||
软件中的 Extensions 扩展
|
||||
*软件中的 Extensions 扩展*
|
||||
|
||||
### Frippery Move Clock
|
||||
### 无用的时钟移动
|
||||
|
||||
![][7]
|
||||
|
||||
@ -56,7 +56,8 @@ via: https://fedoramagazine.org/3-simple-and-useful-gnome-shell-extensions/
|
||||
作者:[Ryan Lerch][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/introducing-flatpak/
|
136
published/20190205 DNS and Root Certificates.md
Normal file
136
published/20190205 DNS and Root Certificates.md
Normal file
@ -0,0 +1,136 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10533-1.html)
|
||||
[#]: subject: (DNS and Root Certificates)
|
||||
[#]: via: (https://lushka.al/dns-and-certificates/)
|
||||
[#]: author: (Anxhelo Lushka https://lushka.al/)
|
||||
|
||||
DNS 和根证书
|
||||
======
|
||||
|
||||
> 关于 DNS 和根证书你需要了解的内容。
|
||||
|
||||
由于最近发生的一些事件,我们(Privacy Today 组织)感到有必要写一篇关于此事的短文。它适用于所有读者,因此它将保持简单 —— 技术细节可能会在稍后的文章发布。
|
||||
|
||||
### 什么是 DNS,为什么它与你有关?
|
||||
|
||||
DNS 的意思是<ruby>域名系统<rt>Domain Name System</rt></ruby>,你每天都会接触到它。每当你的 Web 浏览器或任何其他应用程序连接到互联网时,它就很可能会使用域名。简单来说,域名就是你键入的地址:例如 [duckduckgo.com][1]。你的计算机需要知道它所导向的地方,会向 DNS 解析器寻求帮助。而它将返回类似 [176.34.155.23][2] 这样的 IP —— 这就是连接时所需要知道的公开网络地址。 此过程称为 DNS 查找。
|
||||
|
||||
这对你的隐私、安全以及你的自由都有一定的影响:
|
||||
|
||||
#### 隐私
|
||||
|
||||
由于你要求解析器获取域名的 IP,因此它会确切地知道你正在访问哪些站点,并且由于“物联网”(通常缩写为 IoT),甚至它还知道你在家中使用的是哪个设备。
|
||||
|
||||
#### 安全
|
||||
|
||||
你可以相信解析器返回的 IP 是正确的。有一些检查措施可以确保如此,在正常情况下这一般不是问题。但这些可能措施会被破坏,这就是写作本文的原因。如果返回的 IP 不正确,你可能会被欺骗引向了恶意的第三方 —— 甚至你都不会注意到任何差异。在这种情况下,你的隐私会受到更大的危害,因为不仅会被跟踪你访问了什么网站,甚至你访问的内容也会被跟踪。第三方可以准确地看到你正在查看的内容,收集你输入的个人信息(例如密码)等等。你的整个身份可以轻松接管。
|
||||
|
||||
#### 自由
|
||||
|
||||
审查通常是通过 DNS 实施的。这不是最有效的方法,但它非常普遍。即使在西方国家,它也经常被公司和政府使用。他们使用与潜在攻击者相同的方法;当你查询 IP 地址时,他们不会返回正确的 IP。他们可以表现得就好像某个域名不存在,或完全将访问指向别处。
|
||||
|
||||
### DNS 查询的方式
|
||||
|
||||
#### 由你的 ISP 提供的第三方 DNS 解析器
|
||||
|
||||
大多数人都在使用由其互联网接入提供商(ISP)提供的第三方解析器。当你连接调制解调器时(LCTT 译注:或宽带路由器),这些 DNS 解析器就会被自动取出,而你可能从来没注意过它。
|
||||
|
||||
#### 你自己选择的第三方 DNS 解析器
|
||||
|
||||
如果你已经知道 DNS 意味着什么,那么你可能会决定使用你选择的另一个 DNS 解析器。这可能会改善这种情况,因为它使你的 ISP 更难以跟踪你,并且你可以避免某些形式的审查。尽管追踪和审查仍然是可能的,但这种方法并没有被广泛使用。
|
||||
|
||||
#### 你自己(本地)的 DNS 解析器
|
||||
|
||||
你可以自己动手,避免使用别人的 DNS 解析器的一些危险。如果你对此感兴趣,请告诉我们。
|
||||
|
||||
### 根证书
|
||||
|
||||
#### 什么是根证书?
|
||||
|
||||
每当你访问以 https 开头的网站时,你都会使用它发送的证书与之通信。它使你的浏览器能够加密通信并确保没有人可以窥探。这就是为什么每个人都被告知在登录网站时要注意 https(而不是 http)。证书本身仅用于验证是否为某个域所生成。以及:
|
||||
|
||||
这就是根证书的来源。可以其视为一个更高的级别,用来确保其下的级别是正确的。它验证发送给你的证书是否已由证书颁发机构授权。此权限确保创建证书的人实际上是真正的运营者。
|
||||
|
||||
这也被称为信任链。默认情况下,你的操作系统包含一组这些根证书,以确保该信任链的存在。
|
||||
|
||||
#### 滥用
|
||||
|
||||
我们现在知道:
|
||||
|
||||
* DNS 解析器在你发送域名时向你发送 IP 地址
|
||||
* 证书允许加密你的通信,并验证它们是否为你访问的域生成
|
||||
* 根证书验证该证书是否合法,并且是由真实站点运营者创建的
|
||||
|
||||
**怎么会被滥用呢?**
|
||||
|
||||
* 如前所述,恶意 DNS 解析器可能会向你发送错误的 IP 以进行审查。它们还可以将你导向完全不同的网站。
|
||||
* 这个网站可以向你发送假的证书。
|
||||
* 恶意的根证书可以“验证”此假证书。
|
||||
|
||||
对你来说,这个网站看起来绝对没问题;它在网址中有 https,如果你点击它,它会说已经通过验证。就像你了解到的一样,对吗?**不对!**
|
||||
|
||||
它现在可以接收你要发送给原站点的所有通信。这会绕过想要避免被滥用而创建的检查。你不会收到错误消息,你的浏览器也不会发觉。
|
||||
|
||||
**而你所有的数据都会受到损害!**
|
||||
|
||||
### 结论
|
||||
|
||||
#### 风险
|
||||
|
||||
* 使用恶意 DNS 解析器总是会损害你的隐私,但只要你注意 https,你的安全性就不会受到损害。
|
||||
* 使用恶意 DNS 解析程序和恶意根证书,你的隐私和安全性将完全受到损害。
|
||||
|
||||
#### 可以采取的动作
|
||||
|
||||
**不要安装第三方根证书!**只有非常少的例外情况才需要这样做,并且它们都不适用于一般最终用户。
|
||||
|
||||
**不要被那些“广告拦截”、“军事级安全”或类似的东西营销噱头所吸引**。有一些方法可以自行使用 DNS 解析器来增强你的隐私,但安装第三方根证书永远不会有意义。你正在将自己置身于陷阱之中。
|
||||
|
||||
### 实际看看
|
||||
|
||||
**警告**
|
||||
|
||||
有位友好的系统管理员提供了一个现场演示,你可以实时看到自己。这是真事。
|
||||
|
||||
**千万不要输入私人数据!之后务必删除证书和该 DNS!**
|
||||
|
||||
如果你不知道如何操作,那就不要安装它。虽然我们相信我们的朋友,但你不要随便安装随机和未知的第三方根证书。
|
||||
|
||||
#### 实际演示
|
||||
|
||||
链接在这里:<http://https-interception.info.tm/>
|
||||
|
||||
* 设置所提供的 DNS 解析器
|
||||
* 安装所提供的根证书
|
||||
* 访问 <https://paypal.com> 并输入随机登录数据
|
||||
* 你的数据将显示在该网站上
|
||||
|
||||
### 延伸信息
|
||||
|
||||
如果你对更多技术细节感兴趣,请告诉我们。如果有足够多感兴趣的人,我们可能会写一篇文章,但是目前最重要的部分是分享基础知识,这样你就可以做出明智的决定,而不会因为营销和欺诈而陷入陷阱。请随时提出对你很关注的其他主题。
|
||||
|
||||
这篇文章来自 [Privacy Today 频道][3]。[Privacy Today][4] 是一个关于隐私、开源、自由哲学等所有事物的组织!
|
||||
|
||||
所有内容均根据 CC BY-NC-SA 4.0 获得许可。([署名 - 非商业性使用 - 共享 4.0 国际][5])。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://lushka.al/dns-and-certificates/
|
||||
|
||||
作者:[Anxhelo Lushka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://lushka.al/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://duckduckgo.com
|
||||
[2]: http://176.34.155.23
|
||||
[3]: https://t.me/privacytoday
|
||||
[4]: https://t.me/joinchat/Awg5A0UW-tzOLX7zMoTDog
|
||||
[5]: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
@ -1,911 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Guevaraya)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 11 Input02)
|
||||
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html)
|
||||
[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk)
|
||||
|
||||
Computer Laboratory – Raspberry Pi: Lesson 11 Input02
|
||||
======
|
||||
|
||||
The Input02 lesson builds on Input01, by building a simple command line interface where the user can type commands and the computer interprets and displays them. It is assumed you have the code for the [Lesson 11: Input01][1] operating system as a basis.
|
||||
|
||||
### 1 Terminal 1
|
||||
|
||||
```
|
||||
In the early days of computing, there would usually be one large computer in a building, and many 'terminals' which sent commands to it. The computer would take it in turns to execute different incoming commands.
|
||||
```
|
||||
|
||||
Almost every operating system starts life out as a text terminal. This is typically a black screen with white writing, where you type commands for the computer to execute on the keyboard, and it explains how you've mistyped them, or very occasionally, does what you want. This approach has two main advantages: it provides a simple, robust control mechanism for the computer using only a keyboard and monitor, and it is done by almost every operating system, so is widely understood by system administrators.
|
||||
|
||||
Let's analyse what we want to do precisely:
|
||||
|
||||
1. Computer turns on, displays some sort of welcome message
|
||||
2. Computer indicates its ready for input
|
||||
3. User types a command, with parameters, on the keyboard
|
||||
4. User presses return or enter to commit the command
|
||||
5. Computer interprets command and performs actions if command is acceptable
|
||||
6. Computer displays messages to indicate if command was successful, and also what happened
|
||||
7. Loop back to 2
|
||||
|
||||
|
||||
|
||||
One defining feature of such terminals is that they are unified for both input and output. The same screen is used to enter inputs as is used to print outputs. This means it is useful to build an abstraction of a character based display. In a character based display, the smallest unit is a character, not a pixel. The screen is divided into a fixed number of characters which have varying colours. We can build this on top of our existing screen code, by storing the characters and their colours, and then using the DrawCharacter method to push them to the screen. Once we have a character based display, drawing text becomes a matter of drawing a line of characters.
|
||||
|
||||
In a new file called terminal.s copy the following code:
|
||||
```
|
||||
.section .data
|
||||
.align 4
|
||||
terminalStart:
|
||||
.int terminalBuffer
|
||||
terminalStop:
|
||||
.int terminalBuffer
|
||||
terminalView:
|
||||
.int terminalBuffer
|
||||
terminalColour:
|
||||
.byte 0xf
|
||||
.align 8
|
||||
terminalBuffer:
|
||||
.rept 128*128
|
||||
.byte 0x7f
|
||||
.byte 0x0
|
||||
.endr
|
||||
terminalScreen:
|
||||
.rept 1024/8 core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LICENSE published README.md scripts sources translated 768/16
|
||||
.byte 0x7f
|
||||
.byte 0x0
|
||||
.endr
|
||||
```
|
||||
This sets up the data we need for the text terminal. We have two main storages: terminalBuffer and terminalScreen. terminalBuffer is storage for all of the text we have displayed. It stores up to 128 lines of text (each containing 128 characters). Each character consists of an ASCII character code and a colour, all of which are initially set to 0x7f (ASCII delete) and 0 (black on a black background). terminalScreen stores the characters that are currently displayed on the screen. It is 128 by 48 characters, similarly initialised. You may think that we only need this terminalScreen, not the terminalBuffer, but storing the buffer has 2 main advantages:
|
||||
|
||||
1. We can easily see which characters are different, so we only have to draw those.
|
||||
2. We can 'scroll' back through the terminal's history because it is stored (to a limit).
|
||||
|
||||
|
||||
|
||||
You should always try to design systems that do the minimum amount of work, as they run much faster for things which don't often change.
|
||||
|
||||
The differing trick is really common on low power Operating Systems. Drawing the screen is a slow operation, and so we only want to draw thing that we absolutely have to. In this system, we can freely alter the terminalBuffer, and then call a method which copies the bits that change to the screen. This means we don't have to draw each character as we go along, which may save time in the long run on very long sections of text that span many lines.
|
||||
|
||||
The other values in the .data section are as follows:
|
||||
|
||||
* terminalStart
|
||||
The first character which has been written in terminalBuffer.
|
||||
* terminalStop
|
||||
The last character which has been written in terminalBuffer.
|
||||
* terminalView
|
||||
The first character on the screen at present. We can use this to scroll the screen.
|
||||
* temrinalColour
|
||||
The colour to draw new characters with.
|
||||
|
||||
|
||||
|
||||
```
|
||||
Circular buffers are an example of an **data structure**. These are just ideas we have for organising data, that we sometimes implement in software.
|
||||
```
|
||||
|
||||
![Diagram showing hellow world being inserted into a circular buffer of size 5.][2]
|
||||
The reason why terminalStart needs to be stored is because termainlBuffer should be a circular buffer. This means that when the buffer is completely full, the end 'wraps' round to the start, and so the character after the very last one is the first one. Thus, we need to advance terminalStart so we know that we've done this. When wokring with the buffer this can easily be implemented by checking if the index goes beyond the end of the buffer, and setting it back to the beginning if it does. Circular buffers are a common and clever way of storing a lot of data, where only the most recent data is important. It allows us to keep writing indefinitely, while always being sure there is a certain amount of recent data available. They're often used in signal processing or compression algorithms. In this case, it allows us to store a 128 line history of the terminal, without any penalties for writing over 128 lines. If we didn't have this, we would have to copy 127 lines back a line very time we went beyond the 128th line, wasting valuable time.
|
||||
|
||||
I've mentioned the terminalColour here a few times. You can implement this however you, wish, however there is something of a standard on text terminals to have only 16 colours for foreground, and 16 colours for background (meaning there are 162 = 256 combinations). The colours on a CGA terminal are defined as follows:
|
||||
|
||||
Table 1.1 - CGA Colour Codes
|
||||
| Number | Colour (R, G, B) |
|
||||
| ------ | ------------------------|
|
||||
| 0 | Black (0, 0, 0) |
|
||||
| 1 | Blue (0, 0, ⅔) |
|
||||
| 2 | Green (0, ⅔, 0) |
|
||||
| 3 | Cyan (0, ⅔, ⅔) |
|
||||
| 4 | Red (⅔, 0, 0) |
|
||||
| 5 | Magenta (⅔, 0, ⅔) |
|
||||
| 6 | Brown (⅔, ⅓, 0) |
|
||||
| 7 | Light Grey (⅔, ⅔, ⅔) |
|
||||
| 8 | Grey (⅓, ⅓, ⅓) |
|
||||
| 9 | Light Blue (⅓, ⅓, 1) |
|
||||
| 10 | Light Green (⅓, 1, ⅓) |
|
||||
| 11 | Light Cyan (⅓, 1, 1) |
|
||||
| 12 | Light Red (1, ⅓, ⅓) |
|
||||
| 13 | Light Magenta (1, ⅓, 1) |
|
||||
| 14 | Yellow (1, 1, ⅓) |
|
||||
| 15 | White (1, 1, 1) |
|
||||
|
||||
```
|
||||
Brown was used as the alternative (dark yellow) was unappealing and not useful.
|
||||
```
|
||||
|
||||
We store the colour of each character by storing the fore colour in the low nibble of the colour byte, and the background colour in the high nibble. Apart from brown, all of these colours follow a pattern such that in binary, the top bit represents adding ⅓ to each component, and the other bits represent adding ⅔ to individual components. This makes it easy to convert to RGB colour values.
|
||||
|
||||
We need a method, TerminalColour, to read these 4 bit colour codes, and then call SetForeColour with the 16 bit equivalent. Try to implement this on your own. If you get stuck, or have not completed the Screen series, my implementation is given below:
|
||||
|
||||
```
|
||||
.section .text
|
||||
TerminalColour:
|
||||
teq r0,#6
|
||||
ldreq r0,=0x02B5
|
||||
beq SetForeColour
|
||||
|
||||
tst r0,#0b1000
|
||||
ldrne r1,=0x52AA
|
||||
moveq r1,#0
|
||||
tst r0,#0b0100
|
||||
addne r1,#0x15
|
||||
tst r0,#0b0010
|
||||
addne r1,#0x540
|
||||
tst r0,#0b0001
|
||||
addne r1,#0xA800
|
||||
mov r0,r1
|
||||
b SetForeColour
|
||||
```
|
||||
### 2 Showing the Text
|
||||
|
||||
The first method we really need for our terminal is TerminalDisplay, one that copies the current data from terminalBuffer to terminalScreen and the actual screen. As mentioned, this method should do a minimal amount of work, because we need to be able to call it often. It should compare the text in terminalBuffer with that in terminalDisplay, and copy it across if they're different. Remember, terminalBuffer is a circular buffer running, in this case, from terminalView to terminalStop or 128*48 characters, whichever comes sooner. If we hit terminalStop, we'll assume all characters after that point are 7f16 (ASCII delete), and have colour 0 (black on a black background).
|
||||
|
||||
Let's look at what we have to do:
|
||||
|
||||
1. Load in terminalView, terminalStop and the address of terminalDisplay.
|
||||
2. For each row:
|
||||
1. For each column:
|
||||
1. If view is not equal to stop, load the current character and colour from view
|
||||
2. Otherwise load the character as 0x7f and the colour as 0
|
||||
3. Load the current character from terminalDisplay
|
||||
4. If the character and colour are equal, go to 10
|
||||
5. Store the character and colour to terminalDisplay
|
||||
6. Call TerminalColour with the background colour in r0
|
||||
7. Call DrawCharacter with r0 = 0x7f (ASCII delete, a block), r1 = x, r2 = y
|
||||
8. Call TerminalColour with the foreground colour in r0
|
||||
9. Call DrawCharacter with r0 = character, r1 = x, r2 = y
|
||||
10. Increment the position in terminalDisplay by 2
|
||||
11. If view and stop are not equal, increment the view position by 2
|
||||
12. If the view position is at the end of textBuffer, set it to the start
|
||||
13. Increment the x co-ordinate by 8
|
||||
2. Increment the y co-ordinate by 16
|
||||
|
||||
|
||||
|
||||
Try to implement this yourself. If you get stuck, my solution is given below:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl TerminalDisplay
|
||||
TerminalDisplay:
|
||||
push {r4,r5,r6,r7,r8,r9,r10,r11,lr}
|
||||
x .req r4
|
||||
y .req r5
|
||||
char .req r6
|
||||
col .req r7
|
||||
screen .req r8
|
||||
taddr .req r9
|
||||
view .req r10
|
||||
stop .req r11
|
||||
|
||||
ldr taddr,=terminalStart
|
||||
ldr view,[taddr,#terminalView - terminalStart]
|
||||
ldr stop,[taddr,#terminalStop - terminalStart]
|
||||
add taddr,#terminalBuffer - terminalStart
|
||||
add taddr,#128*128*2
|
||||
mov screen,taddr
|
||||
```
|
||||
|
||||
I go a little wild with variables here. I'm using taddr to store the location of the end of the textBuffer for ease.
|
||||
|
||||
2.
|
||||
```
|
||||
mov y,#0
|
||||
yLoop$:
|
||||
```
|
||||
Start off the y loop.
|
||||
|
||||
1.
|
||||
```
|
||||
mov x,#0
|
||||
xLoop$:
|
||||
```
|
||||
Start off the x loop.
|
||||
|
||||
1.
|
||||
```
|
||||
teq view,stop
|
||||
ldrneh char,[view]
|
||||
```
|
||||
I load both the character and the colour into char simultaneously for ease.
|
||||
|
||||
2.
|
||||
```
|
||||
moveq char,#0x7f
|
||||
```
|
||||
This line complements the one above by acting as though a black delete character was read.
|
||||
|
||||
3.
|
||||
```
|
||||
ldrh col,[screen]
|
||||
```
|
||||
For simplicity I load both the character and colour into col simultaneously.
|
||||
|
||||
4.
|
||||
```
|
||||
teq col,char
|
||||
beq xLoopContinue$
|
||||
```
|
||||
Now we can check if anything has changed with a teq.
|
||||
|
||||
5.
|
||||
```
|
||||
strh char,[screen]
|
||||
```
|
||||
We can also easily save the current value.
|
||||
|
||||
6.
|
||||
```
|
||||
lsr col,char,#8
|
||||
and char,#0x7f
|
||||
lsr r0,col,#4
|
||||
bl TerminalColour
|
||||
```
|
||||
I split up char into the colour in col and the character in char with a bitshift and an and, then use a bitshift to get the background colour to call TerminalColour.
|
||||
|
||||
7.
|
||||
```
|
||||
mov r0,#0x7f
|
||||
mov r1,x
|
||||
mov r2,y
|
||||
bl DrawCharacter
|
||||
```
|
||||
Write out a delete character which is a coloured block.
|
||||
|
||||
8.
|
||||
```
|
||||
and r0,col,#0xf
|
||||
bl TerminalColour
|
||||
```
|
||||
Use an and to get the low nibble of col then call TerminalColour.
|
||||
|
||||
9.
|
||||
```
|
||||
mov r0,char
|
||||
mov r1,x
|
||||
mov r2,y
|
||||
bl DrawCharacter
|
||||
```
|
||||
Write out the character we're supposed to write.
|
||||
|
||||
10.
|
||||
```
|
||||
xLoopContinue$:
|
||||
add screen,#2
|
||||
```
|
||||
Increment the screen pointer.
|
||||
|
||||
11.
|
||||
```
|
||||
teq view,stop
|
||||
addne view,#2
|
||||
```
|
||||
Increment the view pointer if necessary.
|
||||
|
||||
12.
|
||||
```
|
||||
teq view,taddr
|
||||
subeq view,#128*128*2
|
||||
```
|
||||
It's easy to check for view going past the end of the buffer because the end of the buffer's address is stored in taddr.
|
||||
|
||||
13.
|
||||
```
|
||||
add x,#8
|
||||
teq x,#1024
|
||||
bne xLoop$
|
||||
```
|
||||
We increment x and then loop back if there are more characters to go.
|
||||
|
||||
2.
|
||||
```
|
||||
add y,#16
|
||||
teq y,#768
|
||||
bne yLoop$
|
||||
```
|
||||
We increment y and then loop back if there are more characters to go.
|
||||
|
||||
```
|
||||
pop {r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
.unreq x
|
||||
.unreq y
|
||||
.unreq char
|
||||
.unreq col
|
||||
.unreq screen
|
||||
.unreq taddr
|
||||
.unreq view
|
||||
.unreq stop
|
||||
```
|
||||
Don't forget to clean up at the end!
|
||||
|
||||
|
||||
### 3 Printing Lines
|
||||
|
||||
Now we have our TerminalDisplay method, which will automatically display the contents of terminalBuffer to terminalScreen, so theoretically we can draw text. However, we don't actually have any drawing routines that work on a character based display. A quick method that will come in handy first of all is TerminalClear, which completely clears the terminal. This can actually very easily be achieved with no loops. Try to deduce why the following method suffices:
|
||||
|
||||
```
|
||||
.globl TerminalClear
|
||||
TerminalClear:
|
||||
ldr r0,=terminalStart
|
||||
add r1,r0,#terminalBuffer-terminalStart
|
||||
str r1,[r0]
|
||||
str r1,[r0,#terminalStop-terminalStart]
|
||||
str r1,[r0,#terminalView-terminalStart]
|
||||
mov pc,lr
|
||||
```
|
||||
|
||||
Now we need to make a basic method for character based displays; the Print function. This takes in a string address in r0, and a length in r1, and simply writes it to the current location at the screen. There are a few special characters to be wary of, as well as special behaviour to ensure that terminalView is kept up to date. Let's analyse what it has to do:
|
||||
|
||||
1. Check if string length is 0, if so return
|
||||
2. Load in terminalStop and terminalView
|
||||
3. Deduce the x-coordinate of terminalStop
|
||||
4. For each character:
|
||||
1. Check if the character is a new line
|
||||
2. If so, increment bufferStop to the end of the line storing a black on black delete character.
|
||||
3. Otherwise, copy the character in the current terminalColour
|
||||
4. Check if we're at the end of a line
|
||||
5. If so, check if the number of characters between terminalView and terminalStop is more than one screen
|
||||
6. If so, increment terminalView by one line
|
||||
7. Check if terminalView is at the end of the buffer, replace it with the start if so
|
||||
8. Check if terminalStop is at the end of the buffer, replace it with the start if so
|
||||
9. Check if terminalStop equals terminalStart, increment terminalStart by one line if so
|
||||
10. Check if terminalStart is at the end of the buffer, replace it with the start if so
|
||||
5. Store back terminalStop and terminalView.
|
||||
|
||||
|
||||
|
||||
See if you can implement this yourself. My solution is provided below:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl Print
|
||||
Print:
|
||||
teq r1,#0
|
||||
moveq pc,lr
|
||||
```
|
||||
This quick check at the beginning makes a call to Print with a string of length 0 almost instant.
|
||||
|
||||
2.
|
||||
```
|
||||
push {r4,r5,r6,r7,r8,r9,r10,r11,lr}
|
||||
bufferStart .req r4
|
||||
taddr .req r5
|
||||
x .req r6
|
||||
string .req r7
|
||||
length .req r8
|
||||
char .req r9
|
||||
bufferStop .req r10
|
||||
view .req r11
|
||||
|
||||
mov string,r0
|
||||
mov length,r1
|
||||
|
||||
ldr taddr,=terminalStart
|
||||
ldr bufferStop,[taddr,#terminalStop-terminalStart]
|
||||
ldr view,[taddr,#terminalView-terminalStart]
|
||||
ldr bufferStart,[taddr]
|
||||
add taddr,#terminalBuffer-terminalStart
|
||||
add taddr,#128*128*2
|
||||
```
|
||||
I do a lot of setup here. bufferStart contains terminalStart, bufferStop contains terminalStop, view contains terminalView, taddr is the address of the end of terminalBuffer.
|
||||
|
||||
3.
|
||||
```
|
||||
and x,bufferStop,#0xfe
|
||||
lsr x,#1
|
||||
```
|
||||
As per usual, a sneaky alignment trick makes everything easier. Because of the aligment of terminalBuffer, the x-coordinate of any character address is simply the last 8 bits divided by 2.
|
||||
|
||||
4.
|
||||
1.
|
||||
```
|
||||
charLoop$:
|
||||
ldrb char,[string]
|
||||
and char,#0x7f
|
||||
teq char,#'\n'
|
||||
bne charNormal$
|
||||
```
|
||||
We need to check for new lines.
|
||||
|
||||
2.
|
||||
```
|
||||
mov r0,#0x7f
|
||||
clearLine$:
|
||||
strh r0,[bufferStop]
|
||||
add bufferStop,#2
|
||||
add x,#1
|
||||
teq x,#128 blt clearLine$
|
||||
|
||||
b charLoopContinue$
|
||||
```
|
||||
Loop until the end of the line, writing out 0x7f; a delete character in black on a black background.
|
||||
|
||||
3.
|
||||
```
|
||||
charNormal$:
|
||||
strb char,[bufferStop]
|
||||
ldr r0,=terminalColour
|
||||
ldrb r0,[r0]
|
||||
strb r0,[bufferStop,#1]
|
||||
add bufferStop,#2
|
||||
add x,#1
|
||||
```
|
||||
Store the current character in the string and the terminalColour to the end of the terminalBuffer and then increment it and x.
|
||||
|
||||
4.
|
||||
```
|
||||
charLoopContinue$:
|
||||
cmp x,#128
|
||||
blt noScroll$
|
||||
```
|
||||
Check if x is at the end of a line; 128.
|
||||
|
||||
5.
|
||||
```
|
||||
mov x,#0
|
||||
subs r0,bufferStop,view
|
||||
addlt r0,#128*128*2
|
||||
cmp r0,#128*(768/16)*2
|
||||
```
|
||||
Set x back to 0 and check if we're currently showing more than one screen. Remember, we're using a circular buffer, so if the difference between bufferStop and view is negative, we're actually wrapping around the buffer.
|
||||
|
||||
6.
|
||||
```
|
||||
addge view,#128*2
|
||||
```
|
||||
Add one lines worth of bytes to the view address.
|
||||
|
||||
7.
|
||||
```
|
||||
teq view,taddr
|
||||
subeq view,taddr,#128*128*2
|
||||
```
|
||||
If the view address is at the end of the buffer we subtract the buffer length from it to move it back to the start. I set taddr to the address of the end of the buffer at the beginning.
|
||||
|
||||
8.
|
||||
```
|
||||
noScroll$:
|
||||
teq bufferStop,taddr
|
||||
subeq bufferStop,taddr,#128*128*2
|
||||
```
|
||||
If the stop address is at the end of the buffer we subtract the buffer length from it to move it back to the start. I set taddr to the address of the end of the buffer at the beginning.
|
||||
|
||||
9.
|
||||
```
|
||||
teq bufferStop,bufferStart
|
||||
addeq bufferStart,#128*2
|
||||
```
|
||||
Check if bufferStop equals bufferStart. If so, add one line to bufferStart.
|
||||
|
||||
10.
|
||||
```
|
||||
teq bufferStart,taddr
|
||||
subeq bufferStart,taddr,#128*128*2
|
||||
```
|
||||
If the start address is at the end of the buffer we subtract the buffer length from it to move it back to the start. I set taddr to the address of the end of the buffer at the beginning.
|
||||
|
||||
```
|
||||
subs length,#1
|
||||
add string,#1
|
||||
bgt charLoop$
|
||||
```
|
||||
Loop until the string is done.
|
||||
|
||||
5.
|
||||
```
|
||||
charLoopBreak$:
|
||||
sub taddr,#128*128*2
|
||||
sub taddr,#terminalBuffer-terminalStart
|
||||
str bufferStop,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
str bufferStart,[taddr]
|
||||
|
||||
pop {r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
.unreq bufferStart
|
||||
.unreq taddr
|
||||
.unreq x
|
||||
.unreq string
|
||||
.unreq length
|
||||
.unreq char
|
||||
.unreq bufferStop
|
||||
.unreq view
|
||||
```
|
||||
Store back the variables and return.
|
||||
|
||||
|
||||
This method allows us to print arbitrary text to the screen. Throughout, I've been using the colour variable, but no where have we actually set it. Normally, terminals use special combinations of characters to change the colour. For example ASCII Escape (1b16) followed by a number 0 to f in hexadecimal could set the foreground colour to that CGA colour number. You can try implementing this yourself; my version is in the further examples section on the download page.
|
||||
|
||||
### 4 Standard Input
|
||||
|
||||
```
|
||||
By convention, in many programming languages, every program has access to stdin and stdout, which are an input and and output stream linked to the terminal. This is still true on graphical programs, though many don't use it.
|
||||
```
|
||||
|
||||
Now we have an output terminal that in theory can print out text and display it. That is only half the story however, we want input. We want to implement a method, ReadLine, which stores the next line of text a user types to a location given in r0, up to a maximum length given in r1, and returns the length of the string read in r0. The tricky thing is, the user annoyingly wants to see what they're typing as they type it, they want to use backspace to delete mistakes and they want to use return to submit commands. They probably even want a flashing underscore character to indicate the computer would like input! These perfectly reasonable requests make this method a real challenge. One way to achieve all of this is to store the text they type in memory somewhere along with its length, and then after every character, move the terminalStop address back to where it started when ReadLine was called and calling Print. This means we only have to be able to manipulate a string in memory, and then make use of our Print function.
|
||||
|
||||
Lets have a look at what ReadLine will do:
|
||||
|
||||
1. If the maximum length is 0, return 0
|
||||
2. Retrieve the current values of terminalStop and terminalView
|
||||
3. If the maximum length is bigger than half the buffer size, set it to half the buffer size
|
||||
4. Subtract one from maximum length to ensure it can store our flashing underscore or a null terminator
|
||||
5. Write an underscore to the string
|
||||
6. Write the stored terminalView and terminalStop addresses back to the memory
|
||||
7. Call Print on the current string
|
||||
8. Call TerminalDisplay
|
||||
9. Call KeyboardUpdate
|
||||
10. Call KeyboardGetChar
|
||||
11. If it is a new line character go to 16
|
||||
12. If it is a backspace character, subtract 1 from the length of the string (if it is > 0)
|
||||
13. If it is an ordinary character, write it to the string (if the length < maximum length)
|
||||
14. If the string ends in an underscore, write a space, otherwise write an underscore
|
||||
15. Go to 6
|
||||
16. Write a new line character to the end of the string
|
||||
17. Call Print and TerminalDisplay
|
||||
18. Replace the new line with a null terminator
|
||||
19. Return the length of the string
|
||||
|
||||
|
||||
|
||||
Convince yourself that this will work, and then try to implement it yourself. My implementation is given below:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl ReadLine
|
||||
ReadLine:
|
||||
teq r1,#0
|
||||
moveq r0,#0
|
||||
moveq pc,lr
|
||||
```
|
||||
Quick special handling for the zero case, which is otherwise difficult.
|
||||
|
||||
2.
|
||||
```
|
||||
string .req r4
|
||||
maxLength .req r5
|
||||
input .req r6
|
||||
taddr .req r7
|
||||
length .req r8
|
||||
view .req r9
|
||||
|
||||
push {r4,r5,r6,r7,r8,r9,lr}
|
||||
|
||||
mov string,r0
|
||||
mov maxLength,r1
|
||||
ldr taddr,=terminalStart
|
||||
ldr input,[taddr,#terminalStop-terminalStart]
|
||||
ldr view,[taddr,#terminalView-terminalStart]
|
||||
mov length,#0
|
||||
```
|
||||
As per the general theme, I do a lot of initialisations early. input contains the value of terminalStop and view contains terminalView. Length starts at 0.
|
||||
|
||||
3.
|
||||
```
|
||||
cmp maxLength,#128*64
|
||||
movhi maxLength,#128*64
|
||||
```
|
||||
We have to check for unusually large reads, as we can't process them beyond the size of the terminalBuffer (I suppose we CAN, but it would be very buggy, as terminalStart could move past the stored terminalStop).
|
||||
|
||||
4.
|
||||
```
|
||||
sub maxLength,#1
|
||||
```
|
||||
Since the user wants a flashing cursor, and we ideally want to put a null terminator on this string, we need 1 spare character.
|
||||
|
||||
5.
|
||||
```
|
||||
mov r0,#'_'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
Write out the underscore to let the user know they can input.
|
||||
|
||||
6.
|
||||
```
|
||||
readLoop$:
|
||||
str input,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
```
|
||||
Save the stored terminalStop and terminalView. This is important to reset the terminal after each call to Print, which changes these variables. Strictly speaking it can change terminalStart too, but this is irreversible.
|
||||
|
||||
7.
|
||||
```
|
||||
mov r0,string
|
||||
mov r1,length
|
||||
add r1,#1
|
||||
bl Print
|
||||
```
|
||||
Write the current input. We add 1 to the length for the underscore.
|
||||
|
||||
8.
|
||||
```
|
||||
bl TerminalDisplay
|
||||
```
|
||||
Copy the new text to the screen.
|
||||
|
||||
9.
|
||||
```
|
||||
bl KeyboardUpdate
|
||||
```
|
||||
Fetch the latest keyboard input.
|
||||
|
||||
10.
|
||||
```
|
||||
bl KeyboardGetChar
|
||||
```
|
||||
Retrieve the key pressed.
|
||||
|
||||
11.
|
||||
```
|
||||
teq r0,#'\n'
|
||||
beq readLoopBreak$
|
||||
teq r0,#0
|
||||
beq cursor$
|
||||
teq r0,#'\b'
|
||||
bne standard$
|
||||
```
|
||||
|
||||
Break out of the loop if we have an enter key. Also skip these conditions if we have a null terminator and process a backspace if we have one.
|
||||
|
||||
12.
|
||||
```
|
||||
delete$:
|
||||
cmp length,#0
|
||||
subgt length,#1
|
||||
b cursor$
|
||||
```
|
||||
Remove one from the length to delete a character.
|
||||
|
||||
13.
|
||||
```
|
||||
standard$:
|
||||
cmp length,maxLength
|
||||
bge cursor$
|
||||
strb r0,[string,length]
|
||||
add length,#1
|
||||
```
|
||||
Write out an ordinary character where possible.
|
||||
|
||||
14.
|
||||
```
|
||||
cursor$:
|
||||
ldrb r0,[string,length]
|
||||
teq r0,#'_'
|
||||
moveq r0,#' '
|
||||
movne r0,#'_'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
Load in the last character, and change it to an underscore if it isn't one, and a space if it is.
|
||||
|
||||
15.
|
||||
```
|
||||
b readLoop$
|
||||
readLoopBreak$:
|
||||
```
|
||||
Loop until the user presses enter.
|
||||
|
||||
16.
|
||||
```
|
||||
mov r0,#'\n'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
Store a new line at the end of the string.
|
||||
|
||||
17.
|
||||
```
|
||||
str input,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
mov r0,string
|
||||
mov r1,length
|
||||
add r1,#1
|
||||
bl Print
|
||||
bl TerminalDisplay
|
||||
```
|
||||
Reset the terminalView and terminalStop and then Print and TerminalDisplay the final input.
|
||||
|
||||
18.
|
||||
```
|
||||
mov r0,#0
|
||||
strb r0,[string,length]
|
||||
```
|
||||
Write out the null terminator.
|
||||
|
||||
19.
|
||||
```
|
||||
mov r0,length
|
||||
pop {r4,r5,r6,r7,r8,r9,pc}
|
||||
.unreq string
|
||||
.unreq maxLength
|
||||
.unreq input
|
||||
.unreq taddr
|
||||
.unreq length
|
||||
.unreq view
|
||||
```
|
||||
Return the length.
|
||||
|
||||
|
||||
|
||||
|
||||
### 5 The Terminal: Rise of the Machine
|
||||
|
||||
So, now we can theoretically interact with the user on the terminal. The most obvious thing to do is to put this to the test! In 'main.s' delete everything after bl UsbInitialise and copy in the following code:
|
||||
|
||||
```
|
||||
reset$:
|
||||
mov sp,#0x8000
|
||||
bl TerminalClear
|
||||
|
||||
ldr r0,=welcome
|
||||
mov r1,#welcomeEnd-welcome
|
||||
bl Print
|
||||
|
||||
loop$:
|
||||
ldr r0,=prompt
|
||||
mov r1,#promptEnd-prompt
|
||||
bl Print
|
||||
|
||||
ldr r0,=command
|
||||
mov r1,#commandEnd-command
|
||||
bl ReadLine
|
||||
|
||||
teq r0,#0
|
||||
beq loopContinue$
|
||||
|
||||
mov r4,r0
|
||||
|
||||
ldr r5,=command
|
||||
ldr r6,=commandTable
|
||||
|
||||
ldr r7,[r6,#0]
|
||||
ldr r9,[r6,#4]
|
||||
commandLoop$:
|
||||
ldr r8,[r6,#8]
|
||||
sub r1,r8,r7
|
||||
|
||||
cmp r1,r4
|
||||
bgt commandLoopContinue$
|
||||
|
||||
mov r0,#0
|
||||
commandName$:
|
||||
ldrb r2,[r5,r0]
|
||||
ldrb r3,[r7,r0]
|
||||
teq r2,r3
|
||||
bne commandLoopContinue$
|
||||
add r0,#1
|
||||
teq r0,r1
|
||||
bne commandName$
|
||||
|
||||
ldrb r2,[r5,r0]
|
||||
teq r2,#0
|
||||
teqne r2,#' '
|
||||
bne commandLoopContinue$
|
||||
|
||||
mov r0,r5
|
||||
mov r1,r4
|
||||
mov lr,pc
|
||||
mov pc,r9
|
||||
b loopContinue$
|
||||
|
||||
commandLoopContinue$:
|
||||
add r6,#8
|
||||
mov r7,r8
|
||||
ldr r9,[r6,#4]
|
||||
teq r9,#0
|
||||
bne commandLoop$
|
||||
|
||||
ldr r0,=commandUnknown
|
||||
mov r1,#commandUnknownEnd-commandUnknown
|
||||
ldr r2,=formatBuffer
|
||||
ldr r3,=command
|
||||
bl FormatString
|
||||
|
||||
mov r1,r0
|
||||
ldr r0,=formatBuffer
|
||||
bl Print
|
||||
|
||||
loopContinue$:
|
||||
bl TerminalDisplay
|
||||
b loop$
|
||||
|
||||
echo:
|
||||
cmp r1,#5
|
||||
movle pc,lr
|
||||
|
||||
add r0,#5
|
||||
sub r1,#5
|
||||
b Print
|
||||
|
||||
ok:
|
||||
teq r1,#5
|
||||
beq okOn$
|
||||
teq r1,#6
|
||||
beq okOff$
|
||||
mov pc,lr
|
||||
|
||||
okOn$:
|
||||
ldrb r2,[r0,#3]
|
||||
teq r2,#'o'
|
||||
ldreqb r2,[r0,#4]
|
||||
teqeq r2,#'n'
|
||||
movne pc,lr
|
||||
mov r1,#0
|
||||
b okAct$
|
||||
|
||||
okOff$:
|
||||
ldrb r2,[r0,#3]
|
||||
teq r2,#'o'
|
||||
ldreqb r2,[r0,#4]
|
||||
teqeq r2,#'f'
|
||||
ldreqb r2,[r0,#5]
|
||||
teqeq r2,#'f'
|
||||
movne pc,lr
|
||||
mov r1,#1
|
||||
|
||||
okAct$:
|
||||
|
||||
mov r0,#16
|
||||
b SetGpio
|
||||
|
||||
.section .data
|
||||
.align 2
|
||||
welcome: .ascii "Welcome to Alex's OS - Everyone's favourite OS"
|
||||
welcomeEnd:
|
||||
.align 2
|
||||
prompt: .ascii "\n> "
|
||||
promptEnd:
|
||||
.align 2
|
||||
command:
|
||||
.rept 128
|
||||
.byte 0
|
||||
.endr
|
||||
commandEnd:
|
||||
.byte 0
|
||||
.align 2
|
||||
commandUnknown: .ascii "Command `%s' was not recognised.\n"
|
||||
commandUnknownEnd:
|
||||
.align 2
|
||||
formatBuffer:
|
||||
.rept 256
|
||||
.byte 0
|
||||
.endr
|
||||
formatEnd:
|
||||
|
||||
.align 2
|
||||
commandStringEcho: .ascii "echo"
|
||||
commandStringReset: .ascii "reset"
|
||||
commandStringOk: .ascii "ok"
|
||||
commandStringCls: .ascii "cls"
|
||||
commandStringEnd:
|
||||
|
||||
.align 2
|
||||
commandTable:
|
||||
.int commandStringEcho, echo
|
||||
.int commandStringReset, reset$
|
||||
.int commandStringOk, ok
|
||||
.int commandStringCls, TerminalClear
|
||||
.int commandStringEnd, 0
|
||||
```
|
||||
This code brings everything together into a simple command line operating system. The commands available are echo, reset, ok and cls. echo copies any text after it back to the terminal, reset resets the operating system if things go wrong, ok has two functions: ok on turns the OK LED on, and ok off turns the OK LED off, and cls clears the terminal using TerminalClear.
|
||||
|
||||
Have a go with this code on the Raspberry Pi. If it doesn't work, please see our troubleshooting page.
|
||||
|
||||
When it works, congratulations you've completed a basic terminal Operating System, and have completed the input series. Unfortunately, this is as far as these tutorials go at the moment, but I hope to make more in the future. Please send feedback to awc32@cam.ac.uk.
|
||||
|
||||
You're now in position to start building some simple terminal Operating Systems. My code above builds up a table of available commands in commandTable. Each entry in the table is an int for the address of the string, and an int for the address of the code to run. The last entry has to be commandStringEnd, 0. Try implementing some of your own commands, using our existing functions, or making new ones. The parameters for the functions to run are r0 is the address of the command the user typed, and r1 is the length. You can use this to pass inputs to your commands. Maybe you could make a calculator program, perhaps a drawing program or a chess program. Whatever ideas you've got, give them a go!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html
|
||||
|
||||
作者:[Alex Chadwick][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.cl.cam.ac.uk
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html
|
||||
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/circular_buffer.png
|
@ -1,54 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Go on an adventure in your Linux terminal)
|
||||
[#]: via: (https://opensource.com/article/18/12/linux-toy-adventure)
|
||||
[#]: author: (Jason Baker https://opensource.com/users/jason-baker)
|
||||
|
||||
Go on an adventure in your Linux terminal
|
||||
======
|
||||
|
||||
Our final day of the Linux command-line toys advent calendar ends with the beginning of a grand adventure.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/uploads/linux-toy-advent.png?itok=OImUJJI5)
|
||||
|
||||
Today is the final day of our 24-day-long Linux command-line toys advent calendar. Hopefully, you've been following along, but if not, start back at [the beginning][1] and work your way through. You'll find plenty of games, diversions, and oddities for your Linux terminal.
|
||||
|
||||
And while you may have seen some toys from our calendar before, we hope there’s at least one new thing for everyone.
|
||||
|
||||
Today's toy was suggested by Opensource.com moderator [Joshua Allen Holm][2]:
|
||||
|
||||
"If the last day of your advent calendar is not ESR's [Eric S. Raymond's] [open source release of Adventure][3], which retains use of the classic 'advent' command (Adventure in the BSD Games package uses 'adventure), I will be very, very, very disappointed. ;-)"
|
||||
|
||||
What a perfect way to end our series.
|
||||
|
||||
Colossal Cave Adventure (often just called Adventure), is a text-based game from the 1970s that gave rise to the entire adventure game genre. Despite its age, Adventure is still an easy way to lose hours as you explore a fantasy world, much like a Dungeons and Dragons dungeon master might lead you through an imaginary place.
|
||||
|
||||
Rather than take you through the history of Adventure here, I encourage you to go read Joshua's [history of the game][4] itself and why it was resurrected and re-ported a few years ago. Then, go [clone the source][5] and follow the [installation instructions][6] to launch the game with **advent** **** on your system. Or, as Joshua mentions, another version of the game can be obtained from the **bsd-games** package, which is probably available from your default repositories in your distribution of choice.
|
||||
|
||||
Do you have a favorite command-line toy that you we should have included? Our series concludes today, but we'd still love to feature some cool command-line toys in the new year. Let me know in the comments below, and I'll check it out. And let me know what you thought of today's amusement.
|
||||
|
||||
Be sure to check out yesterday's toy, [The Linux command line can fetch fun from afar][7], and I'll see you next year!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/12/linux-toy-adventure
|
||||
|
||||
作者:[Jason Baker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jason-baker
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/18/12/linux-toy-boxes
|
||||
[2]: https://opensource.com/users/holmja
|
||||
[3]: https://gitlab.com/esr/open-adventure (https://gitlab.com/esr/open-adventure)
|
||||
[4]: https://opensource.com/article/17/6/revisit-colossal-cave-adventure-open-adventure
|
||||
[5]: https://gitlab.com/esr/open-adventure
|
||||
[6]: https://gitlab.com/esr/open-adventure/blob/master/INSTALL.adoc
|
||||
[7]: https://opensource.com/article/18/12/linux-toy-remote
|
@ -1,186 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( WangYueScream)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Display Thumbnail Images In Terminal)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-display-thumbnail-images-in-terminal/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
How To Display Thumbnail Images In Terminal
|
||||
======
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-720x340.png)
|
||||
|
||||
A while ago, we discussed about [**Fim**][1], a lightweight, CLI image viewer application used to display various type of images, such as bmp, gif, jpeg, and png etc., from command line. Today, I stumbled upon a similar utility named **‘lsix’**. It is like ‘ls’ command in Unix-like systems, but for images only. The lsix is a simple CLI utility designed to display thumbnail images in Terminal using **Sixel** graphics. For those wondering, Sixel, short for six pixels, is a type of bitmap graphics format. It uses **ImageMagick** , so almost all file formats supported by imagemagick will work fine.
|
||||
|
||||
### Features
|
||||
|
||||
Concerning the features of lsix, we can list the following:
|
||||
|
||||
* Automatically detects if your Terminal supports Sixel graphics or not. If your Terminal doesn’t support Sixel, it will notify you to enable it.
|
||||
* Automatically detects the terminal background color. It uses terminal escape sequences to try to figure out the foreground and background colors of your Terminal application and will display the thumbnails clearly.
|
||||
* If there are more images in the directory, usually >21, lsix will display those images one row a a time, so you need not to wait for the entire montage to be created.
|
||||
* Works well over SSH, so you can manipulate images stored on your remote web server without much hassle.
|
||||
* It supports Non-bitmap graphics, such as.svg, .eps, .pdf, .xcf etc.
|
||||
* Written in BASH, so works on almost all Linux distros.
|
||||
|
||||
|
||||
|
||||
### Installing lsix
|
||||
|
||||
Since lsix uses ImageMagick, make sure you have installed it. It is available in the default repositories of most Linux distributions. For example, on Arch Linux and its variants like Antergos, Manjaro Linux, ImageMagick can be installed using command:
|
||||
|
||||
```
|
||||
$ sudo pacman -S imagemagick
|
||||
```
|
||||
|
||||
On Debian, Ubuntu, Linux Mint:
|
||||
|
||||
```
|
||||
$ sudo apt-get install imagemagick
|
||||
```
|
||||
|
||||
lsix doesn’t require any installation as it is just a BASH script. Just download it and move it to your $PATH. It’s that simple.
|
||||
|
||||
Download the latest lsix version from project’s github page. I am going to download the lsix archive file using command:
|
||||
|
||||
```
|
||||
$ wget https://github.com/hackerb9/lsix/archive/master.zip
|
||||
```
|
||||
|
||||
Extract the downloaded zip file:
|
||||
|
||||
```
|
||||
$ unzip master.zip
|
||||
```
|
||||
|
||||
This command will extract all contents into a folder named ‘lsix-master’. Copy the lsix binary from this directory to your $PATH, for example /usr/local/bin/.
|
||||
|
||||
```
|
||||
$ sudo cp lsix-master/lsix /usr/local/bin/
|
||||
```
|
||||
|
||||
Finally, make the lsbix binary executable:
|
||||
|
||||
```
|
||||
$ sudo chmod +x /usr/local/bin/lsix
|
||||
```
|
||||
|
||||
That’s it. Now is the time to display thumbnails in the terminal itself.
|
||||
|
||||
Before start using lsix, **make sure your Terminal supports Sixel graphics**.
|
||||
|
||||
The developer has developed lsix on an Xterm in **vt340 emulation mode**. However, the he claims that lsix should work on any Sixel compatible Terminal.
|
||||
|
||||
Xterm supports Sixel graphics, but it isn’t enabled by default.
|
||||
|
||||
You can launch Xterm with Sixel mode enabled using command (from another Terminal):
|
||||
|
||||
```
|
||||
$ xterm -ti vt340
|
||||
```
|
||||
|
||||
Alternatively, you can make vt340 the default terminal type for Xterm as described below.
|
||||
|
||||
Edit **.Xresources** file (If it not available, just create it):
|
||||
|
||||
```
|
||||
$ vi .Xresources
|
||||
```
|
||||
|
||||
Add the following line:
|
||||
|
||||
```
|
||||
xterm*decTerminalID : vt340
|
||||
```
|
||||
|
||||
Press **ESC** and type **:wq** to save and close the file.
|
||||
|
||||
Finally, run the following command to apply the changes:
|
||||
|
||||
```
|
||||
$ xrdb -merge .Xresources
|
||||
```
|
||||
|
||||
Now Xterm will start with Sixel mode enabled at every launch by default.
|
||||
|
||||
### Display Thumbnail Images In Terminal
|
||||
|
||||
Launch Xterm (Don’t forget to start it with vt340 mode). Here is how Xterm looks like in my system.
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/xterm-1.png)
|
||||
|
||||
Like I already stated, lsix is very simple utility. It doesn’t have any command line flags or configuration files. All you have to do is just pass the path of your file as an argument like below.
|
||||
|
||||
```
|
||||
$ lsix ostechnix/logo.png
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-4.png)
|
||||
|
||||
If you run it without path, it will display the thumbnail images in your current working directory. I have few files in a directory named **ostechnix**.
|
||||
|
||||
To display the thumbnails in this directory, just run:
|
||||
|
||||
```
|
||||
$ lsix
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-1.png)
|
||||
|
||||
See? The thumbnails of all files are displayed in the terminal itself.
|
||||
|
||||
If you use ‘ls’ command, you would just see the filenames only, not thumbnails.
|
||||
|
||||
![][3]
|
||||
|
||||
You can also display a specific image or group of images of a specific type using wildcards.
|
||||
|
||||
For example, to display a single image, just mention the full path of the image like below.
|
||||
|
||||
```
|
||||
$ lsix girl.jpg
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-2.png)
|
||||
|
||||
To display all images of a specific type, say PNG, use the wildcard character like below.
|
||||
|
||||
```
|
||||
$ lsix *.png
|
||||
```
|
||||
|
||||
![][4]
|
||||
|
||||
For JPEG type images, the command would be:
|
||||
|
||||
```
|
||||
$ lsix *jpg
|
||||
```
|
||||
|
||||
The thumbnail image quality is surprisingly good. I thought lsix would just display blurry thumbnails. I was wrong. The thumbnails are clearly visible just like on the graphical image viewers.
|
||||
|
||||
And, that’s all for now. As you can see, lsix is very similar to ‘ls’ command, but it only for displaying thumbnails. If you deal with a lot of images at work, lsix might be quite handy. Give it a try and let us know your thoughts on this utility in the comment section below. If you know any similar tools, please suggest them as well. I will check and update this guide.
|
||||
|
||||
More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-display-thumbnail-images-in-terminal/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/how-to-display-images-in-the-terminal/
|
||||
[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]: http://www.ostechnix.com/wp-content/uploads/2019/01/ls-command-1.png
|
||||
[4]: http://www.ostechnix.com/wp-content/uploads/2019/01/lsix-3.png
|
@ -1,161 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Top 5 Linux Distributions for Development in 2019)
|
||||
[#]: via: (https://www.linux.com/blog/2019/1/top-5-linux-distributions-development-2019)
|
||||
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||
|
||||
Top 5 Linux Distributions for Development in 2019
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev-main.jpg?itok=DEe9pYtb)
|
||||
|
||||
One of the most popular tasks undertaken on Linux is development. With good reason: Businesses rely on Linux. Without Linux, technology simply wouldn’t meet the demands of today’s ever-evolving world. Because of that, developers are constantly working to improve the environments with which they work. One way to manage such improvements is to have the right platform to start with. Thankfully, this is Linux, so you always have a plethora of choices.
|
||||
|
||||
But sometimes, too many choices can be a problem in and of itself. Which distribution is right for your development needs? That, of course, depends on what you’re developing, but certain distributions that just make sense to use as a foundation for your task. I’ll highlight five distributions I consider the best for developers in 2019.
|
||||
|
||||
### Ubuntu
|
||||
|
||||
Let’s not mince words here. Although the Linux Mint faithful are an incredibly loyal group (with good reason, their distro of choice is fantastic), Ubuntu Linux gets the nod here. Why? Because, thanks to the likes of [AWS][1], Ubuntu is one of the most deployed server operating systems. That means developing on a Ubuntu desktop distribution makes for a much easier translation to Ubuntu Server. And because Ubuntu makes it incredibly easy to develop for, work with, and deploy containers, it makes perfect sense that you’d want to work with this platform. Couple that with Ubuntu’s inclusion of Snap Packages, and Canonical's operating system gets yet another boost in popularity.
|
||||
|
||||
But it’s not just about what you can do with Ubuntu, it’s how easily you can do it. For nearly every task, Ubuntu is an incredibly easy distribution to use. And because Ubuntu is so popular, chances are every tool and IDE you want to work with can be easily installed from the Ubuntu Software GUI (Figure 1).
|
||||
|
||||
![Ubuntu][3]
|
||||
|
||||
Figure 1: Developer tools found in the Ubuntu Software tool.
|
||||
|
||||
[Used with permission][4]
|
||||
|
||||
If you’re looking for ease of use, simplicity of migration, and plenty of available tools, you cannot go wrong with Ubuntu as a development platform.
|
||||
|
||||
### openSUSE
|
||||
|
||||
There’s a very specific reason why I add openSUSE to this list. Not only is it an outstanding desktop distribution, it’s also one of the best rolling releases you’ll find on the market. So if you’re wanting to develop with and release for the most recent software available, [openSUSE Tumbleweed][5] should be one of your top choices. If you want to leverage the latest releases of your favorite IDEs, if you always want to make sure you’re developing with the most recent libraries and toolkits, Tumbleweed is your platform.
|
||||
|
||||
But openSUSE doesn’t just offer a rolling release distribution. If you’d rather make use of a standard release platform, [openSUSE Leap][6] is what you want.
|
||||
|
||||
Of course, it’s not just about standard or rolling releases. The openSUSE platform also has a Kubernetes-specific release, called [Kubic][7], which is based on Kubernetes atop openSUSE MicroOS. But even if you aren’t developing for Kubernetes, you’ll find plenty of software and tools to work with.
|
||||
|
||||
And openSUSE also offers the ability to select your desktop environment, or (should you chose) a generic desktop or server (Figure 2).
|
||||
|
||||
![openSUSE][9]
|
||||
|
||||
Figure 2: The openSUSE Tumbleweed installation in action.
|
||||
|
||||
[Used with permission][4]
|
||||
|
||||
### Fedora
|
||||
|
||||
Using Fedora as a development platform just makes sense. Why? The distribution itself seems geared toward developers. With a regular, six month release cycle, developers can be sure they won’t be working with out of date software for long. This can be important, when you need the most recent tools and libraries. And if you’re developing for enterprise-level businesses, Fedora makes for an ideal platform, as it is the upstream for Red Hat Enterprise Linux. What that means is the transition to RHEL should be painless. That’s important, especially if you hope to bring your project to a much larger market (one with deeper pockets than a desktop-centric target).
|
||||
|
||||
Fedora also offers one of the best GNOME experiences you’ll come across (Figure 3). This translates to a very stable and fast desktops.
|
||||
|
||||
![GNOME][11]
|
||||
|
||||
Figure 3: The GNOME desktop on Fedora.
|
||||
|
||||
[Used with permission][4]
|
||||
|
||||
But if GNOME isn’t your jam, you can opt to install one of the [Fedora spins][12] (which includes KDE, XFCE, LXQT, Mate-Compiz, Cinnamon, LXDE, and SOAS).
|
||||
|
||||
### Pop!_OS
|
||||
|
||||
I’d be remiss if I didn’t include [System76][13]’s platform, customized specifically for their hardware (although it does work fine on other hardware). Why would I include such a distribution, especially one that doesn’t really venture far away from the Ubuntu platform for which is is based? Primarily because this is the distribution you want if you plan on purchasing a desktop or laptop from System76. But why would you do that (especially given that Linux works on nearly all off-the-shelf hardware)? Because System76 sells outstanding hardware. With the release of their Thelio desktop, you have available one of the most powerful desktop computers on the market. If you’re developing seriously large applications (especially ones that lean heavily on very large databases or require a lot of processing power for compilation), why not go for the best? And since Pop!_OS is perfectly tuned for System76 hardware, this is a no-brainer.
|
||||
Since Pop!_OS is based on Ubuntu, you’ll have all the tools available to the base platform at your fingertips (Figure 4).
|
||||
|
||||
![Pop!_OS][15]
|
||||
|
||||
Figure 4: The Anjunta IDE running on Pop!_OS.
|
||||
|
||||
[Used with permission][4]
|
||||
|
||||
Pop!_OS also defaults to encrypted drives, so you can trust your work will be safe from prying eyes (should your hardware fall into the wrong hands).
|
||||
|
||||
### Manjaro
|
||||
|
||||
For anyone that likes the idea of developing on Arch Linux, but doesn’t want to have to jump through all the hoops of installing and working with Arch Linux, there’s Manjaro. Manjaro makes it easy to have an Arch Linux-based distribution up and running (as easily as installing and using, say, Ubuntu).
|
||||
|
||||
But what makes Manjaro developer-friendly (besides enjoying that Arch-y goodness at the base) is how many different flavors you’ll find available for download. From the [Manjaro download page][16], you can grab the following flavors:
|
||||
|
||||
* GNOME
|
||||
|
||||
* XFCE
|
||||
|
||||
* KDE
|
||||
|
||||
* OpenBox
|
||||
|
||||
* Cinnamon
|
||||
|
||||
* I3
|
||||
|
||||
* Awesome
|
||||
|
||||
* Budgie
|
||||
|
||||
* Mate
|
||||
|
||||
* Xfce Developer Preview
|
||||
|
||||
* KDE Developer Preview
|
||||
|
||||
* GNOME Developer Preview
|
||||
|
||||
* Architect
|
||||
|
||||
* Deepin
|
||||
|
||||
|
||||
|
||||
|
||||
Of note are the developer editions (which are geared toward testers and developers), the Architect edition (which is for users who want to build Manjaro from the ground up), and the Awesome edition (Figure 5 - which is for developers dealing with everyday tasks). The one caveat to using Manjaro is that, like any rolling release, the code you develop today may not work tomorrow. Because of this, you need to think with a certain level of agility. Of course, if you’re not developing for Manjaro (or Arch), and you’re doing more generic (or web) development, that will only affect you if the tools you use are updated and no longer work for you. Chances of that happening, however, are slim. And like with most Linux distributions, you’ll find a ton of developer tools available for Manjaro.
|
||||
|
||||
![Manjaro][18]
|
||||
|
||||
Figure 5: The Manjaro Awesome Edition is great for developers.
|
||||
|
||||
[Used with permission][4]
|
||||
|
||||
Manjaro also supports the Arch User Repository (a community-driven repository for Arch users), which includes cutting edge software and libraries, as well as proprietary applications like [Unity Editor][19] or yEd. A word of warning, however, about the Arch User Repository: It was discovered that the AUR contained software considered to be malicious. So, if you opt to work with that repository, do so carefully and at your own risk.
|
||||
|
||||
### Any Linux Will Do
|
||||
|
||||
Truth be told, if you’re a developer, just about any Linux distribution will work. This is especially true if you do most of your development from the command line. But if you prefer a good GUI running on top of a reliable desktop, give one of these distributions a try, they will not disappoint.
|
||||
|
||||
Learn more about Linux through the free ["Introduction to Linux" ][20]course from The Linux Foundation and edX.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/2019/1/top-5-linux-distributions-development-2019
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/jlwallen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://aws.amazon.com/
|
||||
[2]: https://www.linux.com/files/images/dev1jpg
|
||||
[3]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_1.jpg?itok=7QJQWBKi (Ubuntu)
|
||||
[4]: https://www.linux.com/licenses/category/used-permission
|
||||
[5]: https://en.opensuse.org/Portal:Tumbleweed
|
||||
[6]: https://en.opensuse.org/Portal:Leap
|
||||
[7]: https://software.opensuse.org/distributions/tumbleweed
|
||||
[8]: /files/images/dev2jpg
|
||||
[9]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_2.jpg?itok=1GJmpr1t (openSUSE)
|
||||
[10]: /files/images/dev3jpg
|
||||
[11]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_3.jpg?itok=_6Ki4EOo (GNOME)
|
||||
[12]: https://spins.fedoraproject.org/
|
||||
[13]: https://system76.com/
|
||||
[14]: /files/images/dev4jpg
|
||||
[15]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_4.jpg?itok=nNG2Ax24 (Pop!_OS)
|
||||
[16]: https://manjaro.org/download/
|
||||
[17]: /files/images/dev5jpg
|
||||
[18]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dev_5.jpg?itok=RGfF2UEi (Manjaro)
|
||||
[19]: https://unity3d.com/unity/editor
|
||||
[20]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -1,142 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (DNS and Root Certificates)
|
||||
[#]: via: (https://lushka.al/dns-and-certificates/)
|
||||
[#]: author: (Anxhelo Lushka https://lushka.al/)
|
||||
|
||||
DNS and Root Certificates
|
||||
======
|
||||
|
||||
Due to recent events we (as in we from the Privacy Today group) felt compelled to write an impromptu article on this matter. It’s intended for all audiences so it will be kept simple - technical details may be posted later.
|
||||
|
||||
### What Is DNS And Why Does It Concern You?
|
||||
|
||||
DNS stands for Domain Name System and you encounter it daily. Whenever your web browser or any other application connects to the internet, it will most likely do so using a domain. A domain is simply the address you type: i.e. [duckduckgo.com][1]. Your computer needs to know where this leads to and will ask a DNS resolver for help. It will return an IP like [176.34.155.23][2]; the public network address you need to know to connect. This process is called a DNS lookup.
|
||||
|
||||
There are certain implications for both your privacy and your security as well as your liberty:
|
||||
|
||||
#### Privacy
|
||||
|
||||
Since you ask the resolver for an IP for a domain name, it knows exactly which sites you’re visiting and, thanks to the “Internet Of Things”, often abbreviated as IoT, even which appliances you use at home.
|
||||
|
||||
#### Security
|
||||
|
||||
You’re trusting the resolver that the IP it returns is correct. There are certain checks to ensure it is so, under normal circumstances, that is not a common source of issues. These can be undermined though and that’s why this article is important. If the IP is not correct, you can be fooled into connecting to malicious 3rd parties - even without ever noticing any difference. In this case, your privacy is in much greater danger because, not only are the sites you visit tracked, but the contents as well. 3rd parties can see exactly what you’re looking at, collect personal information you enter (such as passwords), and a lot more. Your whole identity can be taken over with ease.
|
||||
|
||||
#### Liberty
|
||||
|
||||
Censorship is commonly enforced via DNS. It’s not the most effective way to do so but it is extremely widespread. Even in western countries, it’s routinely used by corporations and governments. They use the same methods as potential attackers; they will not return the correct IP when you ask. They could act as if the domain doesn’t exist or direct you elsewhere entirely.
|
||||
|
||||
### Ways DNS lookups can happen
|
||||
|
||||
#### 3rd Party DNS Resolvers Hosted By Your ISP
|
||||
|
||||
Most people are using 3rd party resolvers hosted by their Internet Service Provider. When you connect your modem, they will automatically be fetched and you might never bother with it at all.
|
||||
|
||||
#### 3rd Party DNS Resolver Of Your Choice
|
||||
|
||||
If you already knew what DNS means then you might have decided to use another DNS resolver of your choice. This might improve the situation since it makes it harder for your ISP to track you and you can avoid some forms of censorship. Both are still possible though, but the methods required are not as widely used.
|
||||
|
||||
#### Your Own (local) DNS Resolver
|
||||
|
||||
You can run your own and avoid some of the possible perils of using others’. If you’re interested in more information drop us a line.
|
||||
|
||||
### Root Certificates
|
||||
|
||||
#### What Is A Root Certificate?
|
||||
|
||||
Whenever you visit a website starting with https, you communicate with it using a certificate it sends. It enables your browser to encrypt the communication and ensures that nobody listening in can snoop. That’s why everybody has been told to look out for the https (rather than http) when logging into websites. The certificate itself only verifies that it has been generated for a certain domain. There’s more though:
|
||||
|
||||
That’s where the root certificate comes in. Think of it as the next higher level that makes sure the levels below are correct. It verifies that the certificate sent to you has been authorized by a certificate authority. This authority ensures that the person creating the certificate is actually the real operator.
|
||||
|
||||
This is also referred to as the chain of trust. Your operating system includes a set of these root certificates by default so that the chain of trust can be guaranteed.
|
||||
|
||||
#### Abuse
|
||||
|
||||
We now know that:
|
||||
|
||||
* DNS resolvers send you an IP address when you send a domain name
|
||||
* Certificates allow encrypting your communication and verify they have been generated for the domain you visit
|
||||
* Root certificates verify that the certificate is legitimate and has been created by the real site operator
|
||||
|
||||
|
||||
|
||||
**How can it be abused?**
|
||||
|
||||
* A malicious DNS resolver can send you a wrong IP for the purpose of censorship as said before. They can also send you to a completely different site.
|
||||
* This site can send you a fake certificate.
|
||||
* A malicious root certificate can “verify” this fake certificate.
|
||||
|
||||
|
||||
|
||||
This site will look absolutely fine to you; it has https in the URL and, if you click it, it will say verified. All just like you learned, right? **No!**
|
||||
|
||||
It now receives all the communication you intended to send to the original. This bypasses the checks created to avoid it. You won’t receive error messages, your browser won’t complain.
|
||||
|
||||
**All your data is compromised!**
|
||||
|
||||
### Conclusion
|
||||
|
||||
#### Risks
|
||||
|
||||
* Using a malicious DNS resolver can always compromise your privacy but your security will be unharmed as long as you look out for the https.
|
||||
* Using a malicious DNS resolver and a malicious root certificate, your privacy and security are fully compromised.
|
||||
|
||||
|
||||
|
||||
#### Actions To Take
|
||||
|
||||
**Do not ever install a 3rd party root certificate!** There are very few exceptions why you would want to do so and none of them are applicable to general end users.
|
||||
|
||||
**Do not fall for clever marketing that ensures “ad blocking”, “military grade security”, or something similar**. There are methods of using DNS resolvers on their own to enhance your privacy but installing a 3rd party root certificate never makes sense. You are opening yourself up to extreme abuse.
|
||||
|
||||
### Seeing It Live
|
||||
|
||||
**WARNING**
|
||||
|
||||
A friendly sysadmin provided a live demo so you can see for yourself in realtime. This is real.
|
||||
|
||||
**DO NOT ENTER PRIVATE DATA! REMOVE THE CERT AND DNS AFTERWARDS!**
|
||||
|
||||
If you do not know how to, don’t install it in the first place. While we trust our friend you still wouldn’t want to have the root certificate of a random and unknown 3rd party installed.
|
||||
|
||||
#### Live Demo
|
||||
|
||||
Here is the link: <http://https-interception.info.tm/>
|
||||
|
||||
* Set the provided DNS resolver
|
||||
* Install the provided root certificate
|
||||
* Visit <https://paypal.com> and enter random login data
|
||||
* Your data will show up on the website
|
||||
|
||||
|
||||
|
||||
### Further Information
|
||||
|
||||
If you are interested in more technical details, let us know. If there is enough interest, we might write an article but, for now, the important part is sharing the basics so you can make an informed decision and not fall for marketing and straight up fraud. Feel free to suggest other topics that are important to you.
|
||||
|
||||
This post is mirrored from [Privacy Today channel][3]. [Privacy Today][4] is a group about all things privacy, open source, libre philosophy and more!
|
||||
|
||||
All content is licensed under CC BY-NC-SA 4.0. ([Attribution-NonCommercial-ShareAlike 4.0 International][5]).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://lushka.al/dns-and-certificates/
|
||||
|
||||
作者:[Anxhelo Lushka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://lushka.al/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://duckduckgo.com
|
||||
[2]: http://176.34.155.23
|
||||
[3]: https://t.me/privacytoday
|
||||
[4]: https://t.me/joinchat/Awg5A0UW-tzOLX7zMoTDog
|
||||
[5]: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (LazyWolfLin)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -0,0 +1,911 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (guevaraya )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 11 Input02)
|
||||
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html)
|
||||
[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk)
|
||||
|
||||
计算机实验室 – 树莓派开发: 课程11 输入02
|
||||
======
|
||||
|
||||
课程输入02是以课程输入01基础讲解的,通过一个简单的命令行实现用户的命令输入和计算机的处理和显示。本文假设你已经具备 [课程11:输入01][1] 的操作系统代码基础。
|
||||
|
||||
### 1 终端
|
||||
|
||||
```
|
||||
早期的计算一般是在一栋楼里的一个巨型计算机系统,他有很多可以输命令的'终端'。计算机依次执行不同来源的命令。
|
||||
```
|
||||
|
||||
几乎所有的操作系统都是以字符终端显示启动的。经典的黑底白字,通过键盘输入计算机要执行的命令,然后会提示你拼写错误,或者恰好得到你想要的执行结果。这种方法有两个主要优点:键盘和显示器可以提供简易,健壮的计算机交互机制,几乎所有的计算机系统都采用这个机制,这个也广泛被系统管理员应用。
|
||||
|
||||
让我们分析下真正想要哪些信息:
|
||||
|
||||
1. 计算机打开后,显示欢迎信息
|
||||
2. 计算机启动后可以接受输入标志
|
||||
3. 用户从键盘输入带参数的命令
|
||||
4. 用户输入回车键或提交按钮
|
||||
5. 计算机解析命令后执行可用的命令
|
||||
6. 计算机显示命令的执行结果,过程信息
|
||||
7. 循环跳转到步骤2
|
||||
|
||||
|
||||
这样的终端被定义为标准的输入输出设备。用于输入的屏幕和输出打印的屏幕是同一个。也就是说终端是对字符显示的一个抽象。字符显示中,单个字符是最小的单元,而不是像素。屏幕被划分成固定数量不同颜色的字符。我们可以在现有的屏幕代码基础上,先存储字符和对应的颜色,然后再用方法 DrawCharacter 把其推送到屏幕上。一旦我们需要字符显示,就只需要在屏幕上画出一行字符串。
|
||||
|
||||
新建文件名为 terminal.s 如下:
|
||||
```
|
||||
.section .data
|
||||
.align 4
|
||||
terminalStart:
|
||||
.int terminalBuffer
|
||||
terminalStop:
|
||||
.int terminalBuffer
|
||||
terminalView:
|
||||
.int terminalBuffer
|
||||
terminalColour:
|
||||
.byte 0xf
|
||||
.align 8
|
||||
terminalBuffer:
|
||||
.rept 128*128
|
||||
.byte 0x7f
|
||||
.byte 0x0
|
||||
.endr
|
||||
terminalScreen:
|
||||
.rept 1024/8 core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LICENSE published README.md scripts sources translated 768/16
|
||||
.byte 0x7f
|
||||
.byte 0x0
|
||||
.endr
|
||||
```
|
||||
这是文件终端的配置数据文件。我们有两个主要的存储变量:terminalBuffer 和 terminalScreen。terminalBuffer保存所有显示过的字符。它保存128行字符文本(1行包含128个字符)。每个字符有一个 ASCII 字符和颜色单元组成,初始值为0x7f(ASCII的删除键)和 0(前景色和背景色为黑)。terminalScreen 保存当前屏幕显示的字符。它保存128x48的字符,与 terminalBuffer 初始化值一样。你可能会想我仅需要terminalScreen就够了,为什么还要terminalBuffer,其实有两个好处:
|
||||
|
||||
1. 我们可以很容易看到字符串的变化,只需画出有变化的字符。
|
||||
2. 我们可以回滚终端显示的历史字符,也就是缓冲的字符(有限制)
|
||||
|
||||
|
||||
你总是需要尝试去设计一个高效的系统,如果很少变化的条件这个系统会运行的更快。
|
||||
|
||||
独特的技巧在低功耗系统里很常见。画屏是很耗时的操作,因此我们仅在不得已的时候才去执行这个操作。在这个系统里,我们可以任意改变terminalBuffer,然后调用一个仅拷贝屏幕上字节变化的方法。也就是说我们不需要持续画出每个字符,这样可以节省一大段跨行文本的操作时间。
|
||||
|
||||
其他在 .data 段的值得含义如下:
|
||||
|
||||
* terminalStart
|
||||
写入到 terminalBuffer 的第一个字符
|
||||
* terminalStop
|
||||
写入到 terminalBuffer 的最后一个字符
|
||||
* terminalView
|
||||
表示当前屏幕的第一个字符,这样我们可以控制滚动屏幕
|
||||
* temrinalColour
|
||||
即将被描画的字符颜色
|
||||
|
||||
|
||||
```
|
||||
循环缓冲区是**数据结构**一个例子。这是一个组织数据的思路,有时我们通过软件实现这种思路。
|
||||
```
|
||||
|
||||
![显示 Hellow world 插入到大小为5的循环缓冲区的示意图。][2]
|
||||
terminalStart 需要保存起来的原因是 termainlBuffer 是一个循环缓冲区。意思是当缓冲区变满时,末尾地方会回滚覆盖开始位置,这样最后一个字符变成了第一个字符。因此我们需要将 terminalStart 往前推进,这样我们知道我们已经占满它了。如何实现缓冲区检测:如果索引越界到缓冲区的末尾,就将索引指向缓冲区的开始位置。循环缓冲区是一个比较常见的高明的存储大量数据的方法,往往这些数据的最近部分比较重要。它允许无限制的写入,只保证最近一些特定数据有效。这个常常用于信号处理和数据压缩算法。这样的情况,可以允许我们存储128行终端记录,超过128行也不会有问题。如果不是这样,当超过第128行时,我们需要把127行分别向前拷贝一次,这样很浪费时间。
|
||||
|
||||
之前已经提到过 terminalColour 几次了。你可以根据你的想法实现终端颜色,但这个文本终端有16个前景色和16个背景色(这里相当于有16²=256种组合)。[CGA][3]终端的颜色定义如下:
|
||||
|
||||
表格 1.1 - CGA 颜色编码
|
||||
|
||||
| 序号 | 颜色 (R, G, B) |
|
||||
| ------ | ------------------------|
|
||||
| 0 | 黑 (0, 0, 0) |
|
||||
| 1 | 蓝 (0, 0, ⅔) |
|
||||
| 2 | 绿 (0, ⅔, 0) |
|
||||
| 3 | 青色 (0, ⅔, ⅔) |
|
||||
| 4 | 红色 (⅔, 0, 0) |
|
||||
| 5 | 品红 (⅔, 0, ⅔) |
|
||||
| 6 | 棕色 (⅔, ⅓, 0) |
|
||||
| 7 | 浅灰色 (⅔, ⅔, ⅔) |
|
||||
| 8 | 灰色 (⅓, ⅓, ⅓) |
|
||||
| 9 | 淡蓝色 (⅓, ⅓, 1) |
|
||||
| 10 | 淡绿色 (⅓, 1, ⅓) |
|
||||
| 11 | 淡青色 (⅓, 1, 1) |
|
||||
| 12 | 淡红色 (1, ⅓, ⅓) |
|
||||
| 13 | 浅品红 (1, ⅓, 1) |
|
||||
| 14 | 黄色 (1, 1, ⅓) |
|
||||
| 15 | 白色 (1, 1, 1) |
|
||||
|
||||
```
|
||||
棕色作为替代色(黑黄色)既不吸引人也没有什么用处。
|
||||
```
|
||||
我们将前景色保存到颜色的低字节,背景色保存到颜色高字节。除过棕色,其他这些颜色遵循一种模式如二进制的高位比特代表增加 ⅓ 到每个组件,其他比特代表增加⅔到各自组件。这样很容易进行RGB颜色转换。
|
||||
|
||||
我们需要一个方法从TerminalColour读取颜色编码的四个比特,然后用16比特等效参数调用 SetForeColour。尝试实现你自己实现。如果你感觉麻烦或者还没有完成屏幕系列课程,我们的实现如下:
|
||||
|
||||
```
|
||||
.section .text
|
||||
TerminalColour:
|
||||
teq r0,#6
|
||||
ldreq r0,=0x02B5
|
||||
beq SetForeColour
|
||||
|
||||
tst r0,#0b1000
|
||||
ldrne r1,=0x52AA
|
||||
moveq r1,#0
|
||||
tst r0,#0b0100
|
||||
addne r1,#0x15
|
||||
tst r0,#0b0010
|
||||
addne r1,#0x540
|
||||
tst r0,#0b0001
|
||||
addne r1,#0xA800
|
||||
mov r0,r1
|
||||
b SetForeColour
|
||||
```
|
||||
### 2 文本显示
|
||||
|
||||
我们的终端第一个真正需要的方法是 TerminalDisplay,它用来把当前的数据从 terminalBuffe r拷贝到 terminalScreen 和实际的屏幕。如上所述,这个方法必须是最小开销的操作,因为我们需要频繁调用它。它主要比较 terminalBuffer 与 terminalDisplay的文本,然后只拷贝有差异的字节。请记住 terminalBuffer 是循环缓冲区运行的,这种情况,从 terminalView 到 terminalStop 或者 128*48 字符集,哪个来的最快。如果我们遇到 terminalStop,我们将会假定在这之后的所有字符是7f16 (ASCII delete),背景色为0(黑色前景色和背景色)。
|
||||
|
||||
让我们看看必须要做的事情:
|
||||
|
||||
1. 加载 terminalView ,terminalStop 和 terminalDisplay 的地址。
|
||||
2. 执行每一行:
|
||||
1. 执行每一列:
|
||||
1. 如果 terminalView 不等于 terminalStop,根据 terminalView 加载当前字符和颜色
|
||||
2. 否则加载 0x7f 和颜色 0
|
||||
3. 从 terminalDisplay 加载当前的字符
|
||||
4. 如果字符和颜色相同,直接跳转到10
|
||||
5. 存储字符和颜色到 terminalDisplay
|
||||
6. 用 r0 作为背景色参数调用 TerminalColour
|
||||
7. 用 r0 = 0x7f (ASCII 删除键, 一大块), r1 = x, r2 = y 调用 DrawCharacter
|
||||
8. 用 r0 作为前景色参数调用 TerminalColour
|
||||
9. 用 r0 = 字符, r1 = x, r2 = y 调用 DrawCharacter
|
||||
10. 对位置参数 terminalDisplay 累加2
|
||||
11. 如果 terminalView 不等于 terminalStop不能相等 terminalView 位置参数累加2
|
||||
12. 如果 terminalView 位置已经是文件缓冲器的末尾,将他设置为缓冲区的开始位置
|
||||
13. x 坐标增加8
|
||||
2. y 坐标增加16
|
||||
|
||||
|
||||
Try to implement this yourself. If you get stuck, my solution is given below:
|
||||
尝试去自己实现吧。如果你遇到问题,我们的方案下面给出来了:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl TerminalDisplay
|
||||
TerminalDisplay:
|
||||
push {r4,r5,r6,r7,r8,r9,r10,r11,lr}
|
||||
x .req r4
|
||||
y .req r5
|
||||
char .req r6
|
||||
col .req r7
|
||||
screen .req r8
|
||||
taddr .req r9
|
||||
view .req r10
|
||||
stop .req r11
|
||||
|
||||
ldr taddr,=terminalStart
|
||||
ldr view,[taddr,#terminalView - terminalStart]
|
||||
ldr stop,[taddr,#terminalStop - terminalStart]
|
||||
add taddr,#terminalBuffer - terminalStart
|
||||
add taddr,#128*128*2
|
||||
mov screen,taddr
|
||||
```
|
||||
|
||||
我这里的变量有点乱。为了方便起见,我用 taddr 存储 textBuffer 的末尾位置。
|
||||
|
||||
2.
|
||||
```
|
||||
mov y,#0
|
||||
yLoop$:
|
||||
```
|
||||
从yLoop开始运行。
|
||||
|
||||
1.
|
||||
```
|
||||
mov x,#0
|
||||
xLoop$:
|
||||
```
|
||||
从yLoop开始运行。
|
||||
|
||||
1.
|
||||
```
|
||||
teq view,stop
|
||||
ldrneh char,[view]
|
||||
```
|
||||
为了方便起见,我把字符和颜色同时加载到 char 变量了
|
||||
|
||||
2.
|
||||
```
|
||||
moveq char,#0x7f
|
||||
```
|
||||
这行是对上面一行的补充说明:读取黑色的Delete键
|
||||
|
||||
3.
|
||||
```
|
||||
ldrh col,[screen]
|
||||
```
|
||||
为了简便我把字符和颜色同时加载到 col 里。
|
||||
|
||||
4.
|
||||
```
|
||||
teq col,char
|
||||
beq xLoopContinue$
|
||||
```
|
||||
现在我用teq指令检查是否有数据变化
|
||||
|
||||
5.
|
||||
```
|
||||
strh char,[screen]
|
||||
```
|
||||
我可以容易的保存当前值
|
||||
|
||||
6.
|
||||
```
|
||||
lsr col,char,#8
|
||||
and char,#0x7f
|
||||
lsr r0,col,#4
|
||||
bl TerminalColour
|
||||
```
|
||||
我用 bitshift(比特偏移) 指令和 and 指令从 char 变量中分离出颜色到 col 变量和字符到 char变量,然后再用bitshift(比特偏移)指令后调用TerminalColour 获取背景色。
|
||||
|
||||
7.
|
||||
```
|
||||
mov r0,#0x7f
|
||||
mov r1,x
|
||||
mov r2,y
|
||||
bl DrawCharacter
|
||||
```
|
||||
写入一个彩色的删除字符块
|
||||
|
||||
8.
|
||||
```
|
||||
and r0,col,#0xf
|
||||
bl TerminalColour
|
||||
```
|
||||
用 and 指令获取 col 变量的最低字节,然后调用TerminalColour
|
||||
|
||||
9.
|
||||
```
|
||||
mov r0,char
|
||||
mov r1,x
|
||||
mov r2,y
|
||||
bl DrawCharacter
|
||||
```
|
||||
写入我们需要的字符
|
||||
|
||||
10.
|
||||
```
|
||||
xLoopContinue$:
|
||||
add screen,#2
|
||||
```
|
||||
自增屏幕指针
|
||||
|
||||
11.
|
||||
```
|
||||
teq view,stop
|
||||
addne view,#2
|
||||
```
|
||||
如果可能自增view指针
|
||||
|
||||
12.
|
||||
```
|
||||
teq view,taddr
|
||||
subeq view,#128*128*2
|
||||
```
|
||||
很容易检测 view指针是否越界到缓冲区的末尾,因为缓冲区的地址保存在 taddr 变量里
|
||||
|
||||
13.
|
||||
```
|
||||
add x,#8
|
||||
teq x,#1024
|
||||
bne xLoop$
|
||||
```
|
||||
如果还有字符需要显示,我们就需要自增 x 变量然后循环到 xLoop 执行
|
||||
|
||||
2.
|
||||
```
|
||||
add y,#16
|
||||
teq y,#768
|
||||
bne yLoop$
|
||||
```
|
||||
如果还有更多的字符显示我们就需要自增 y 变量,然后循环到 yLoop 执行
|
||||
|
||||
```
|
||||
pop {r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
.unreq x
|
||||
.unreq y
|
||||
.unreq char
|
||||
.unreq col
|
||||
.unreq screen
|
||||
.unreq taddr
|
||||
.unreq view
|
||||
.unreq stop
|
||||
```
|
||||
不要忘记最后清除变量
|
||||
|
||||
|
||||
### 3 行打印
|
||||
|
||||
现在我有了自己 TerminalDisplay方法,它可以自动显示 terminalBuffer 到 terminalScreen,因此理论上我们可以画出文本。但是实际上我们没有任何基于字符显示的实例。 首先快速容易上手的方法便是 TerminalClear, 它可以彻底清除终端。这个方法没有循环很容易实现。可以尝试分析下面的方法应该不难:
|
||||
|
||||
```
|
||||
.globl TerminalClear
|
||||
TerminalClear:
|
||||
ldr r0,=terminalStart
|
||||
add r1,r0,#terminalBuffer-terminalStart
|
||||
str r1,[r0]
|
||||
str r1,[r0,#terminalStop-terminalStart]
|
||||
str r1,[r0,#terminalView-terminalStart]
|
||||
mov pc,lr
|
||||
```
|
||||
|
||||
现在我们需要构造一个字符显示的基础方法:打印函数。它将保存在 r0 的字符串和 保存在 r1 字符串长度简易的写到屏幕上。有一些特定字符需要特别的注意,这些特定的操作是确保 terminalView 是最新的。我们来分析一下需要做啥:
|
||||
|
||||
1. 检查字符串的长度是否为0,如果是就直接返回
|
||||
2. 加载 terminalStop 和 terminalView
|
||||
3. 计算出 terminalStop 的 x 坐标
|
||||
4. 对每一个字符的操作:
|
||||
1. 检查字符是否为新起一行
|
||||
2. 如果是的话,自增 bufferStop 到行末,同时写入黑色删除键
|
||||
3. 否则拷贝当前 terminalColour 的字符
|
||||
4. 加成是在行末
|
||||
5. 如果是,检查从 terminalView 到 terminalStop 之间的字符数是否大于一屏
|
||||
6. 如果是,terminalView 自增一行
|
||||
7. 检查 terminalView 是否为缓冲区的末尾,如果是的话将其替换为缓冲区的起始位置
|
||||
8. 检查 terminalStop 是否为缓冲区的末尾,如果是的话将其替换为缓冲区的起始位置
|
||||
9. 检查 terminalStop 是否等于 terminalStart, 如果是的话 terminalStart 自增一行。
|
||||
10. 检查 terminalStart 是否为缓冲区的末尾,如果是的话将其替换为缓冲区的起始位置
|
||||
5. 存取 terminalStop 和 terminalView
|
||||
|
||||
|
||||
试一下自己去实现。我们的方案提供如下:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl Print
|
||||
Print:
|
||||
teq r1,#0
|
||||
moveq pc,lr
|
||||
```
|
||||
这个是打印函数开始快速检查字符串为0的代码
|
||||
|
||||
2.
|
||||
```
|
||||
push {r4,r5,r6,r7,r8,r9,r10,r11,lr}
|
||||
bufferStart .req r4
|
||||
taddr .req r5
|
||||
x .req r6
|
||||
string .req r7
|
||||
length .req r8
|
||||
char .req r9
|
||||
bufferStop .req r10
|
||||
view .req r11
|
||||
|
||||
mov string,r0
|
||||
mov length,r1
|
||||
|
||||
ldr taddr,=terminalStart
|
||||
ldr bufferStop,[taddr,#terminalStop-terminalStart]
|
||||
ldr view,[taddr,#terminalView-terminalStart]
|
||||
ldr bufferStart,[taddr]
|
||||
add taddr,#terminalBuffer-terminalStart
|
||||
add taddr,#128*128*2
|
||||
```
|
||||
|
||||
这里我做了很多配置。 bufferStart 代表 terminalStart, bufferStop代表terminalStop, view 代表 terminalView,taddr 代表 terminalBuffer 的末尾地址。
|
||||
|
||||
3.
|
||||
```
|
||||
and x,bufferStop,#0xfe
|
||||
lsr x,#1
|
||||
```
|
||||
和通常一样,巧妙的对齐技巧让许多事情更容易。由于需要对齐 terminalBuffer,每个字符的 x 坐标需要8位要除以2。
|
||||
|
||||
4.
|
||||
1.
|
||||
```
|
||||
charLoop$:
|
||||
ldrb char,[string]
|
||||
and char,#0x7f
|
||||
teq char,#'\n'
|
||||
bne charNormal$
|
||||
```
|
||||
我们需要检查新行
|
||||
|
||||
2.
|
||||
```
|
||||
mov r0,#0x7f
|
||||
clearLine$:
|
||||
strh r0,[bufferStop]
|
||||
add bufferStop,#2
|
||||
add x,#1
|
||||
teq x,#128 blt clearLine$
|
||||
|
||||
b charLoopContinue$
|
||||
```
|
||||
循环执行值到行末写入 0x7f;黑色删除键
|
||||
|
||||
3.
|
||||
```
|
||||
charNormal$:
|
||||
strb char,[bufferStop]
|
||||
ldr r0,=terminalColour
|
||||
ldrb r0,[r0]
|
||||
strb r0,[bufferStop,#1]
|
||||
add bufferStop,#2
|
||||
add x,#1
|
||||
```
|
||||
存储字符串的当前字符和 terminalBuffer 末尾的 terminalColour然后将它和 x 变量自增
|
||||
|
||||
4.
|
||||
```
|
||||
charLoopContinue$:
|
||||
cmp x,#128
|
||||
blt noScroll$
|
||||
```
|
||||
检查 x 是否为行末;128
|
||||
|
||||
5.
|
||||
```
|
||||
mov x,#0
|
||||
subs r0,bufferStop,view
|
||||
addlt r0,#128*128*2
|
||||
cmp r0,#128*(768/16)*2
|
||||
```
|
||||
这是 x 为 0 然后检查我们是否已经显示超过1屏。请记住,我们是用的循环缓冲区,因此如果 bufferStop 和 view 之前差是负值,我们实际使用是环绕缓冲区。
|
||||
|
||||
6.
|
||||
```
|
||||
addge view,#128*2
|
||||
```
|
||||
增加一行字节到 view 的地址
|
||||
|
||||
7.
|
||||
```
|
||||
teq view,taddr
|
||||
subeq view,taddr,#128*128*2
|
||||
```
|
||||
如果 view 地址是缓冲区的末尾,我们就从它上面减去缓冲区的长度,让其指向开始位置。我会在开始的时候设置 taddr 为缓冲区的末尾地址。
|
||||
|
||||
8.
|
||||
```
|
||||
noScroll$:
|
||||
teq bufferStop,taddr
|
||||
subeq bufferStop,taddr,#128*128*2
|
||||
```
|
||||
如果 stop 的地址在缓冲区末尾,我们就从它上面减去缓冲区的长度,让其指向开始位置。我会在开始的时候设置 taddr 为缓冲区的末尾地址。
|
||||
|
||||
9.
|
||||
```
|
||||
teq bufferStop,bufferStart
|
||||
addeq bufferStart,#128*2
|
||||
```
|
||||
检查 bufferStop 是否等于 bufferStart。 如果等于增加一行到 bufferStart。
|
||||
|
||||
10.
|
||||
```
|
||||
teq bufferStart,taddr
|
||||
subeq bufferStart,taddr,#128*128*2
|
||||
```
|
||||
如果 start 的地址在缓冲区的末尾,我们就从它上面减去缓冲区的长度,让其指向开始位置。我会在开始的时候设置 taddr 为缓冲区的末尾地址。
|
||||
|
||||
```
|
||||
subs length,#1
|
||||
add string,#1
|
||||
bgt charLoop$
|
||||
```
|
||||
循环执行知道字符串结束
|
||||
|
||||
5.
|
||||
```
|
||||
charLoopBreak$:
|
||||
sub taddr,#128*128*2
|
||||
sub taddr,#terminalBuffer-terminalStart
|
||||
str bufferStop,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
str bufferStart,[taddr]
|
||||
|
||||
pop {r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
.unreq bufferStart
|
||||
.unreq taddr
|
||||
.unreq x
|
||||
.unreq string
|
||||
.unreq length
|
||||
.unreq char
|
||||
.unreq bufferStop
|
||||
.unreq view
|
||||
```
|
||||
保存变量然后返回
|
||||
|
||||
|
||||
这个方法允许我们打印任意字符到屏幕。然而我们用了颜色变量,但实际上没有设置它。一般终端用特性的组合字符去行修改颜色。如ASCII转移(1b16)后面跟着一个0-f的16进制的书,就可以设置前景色为 CGA颜色。如果你自己想尝试实现;在下载页面有一个我的详细的例子。
|
||||
|
||||
|
||||
### 4 标志输入
|
||||
|
||||
```
|
||||
按照惯例,许多编程语言中,任意程序可以访问 stdin 和 stdin,他们可以连接到终端的输入和输出流。在图形程序其实也可以进行同样操作,但实际几乎不用。
|
||||
```
|
||||
|
||||
现在我们有一个可以打印和显示文本的输出终端。这仅仅是说了一半,我们需要输入。我们想实现一个方法:Readline,可以保存文件的一行文本,文本位置有 r0 给出,最大的长度由 r1 给出,返回 r0 里面的字符串长度。棘手的是用户输出字符的时候要回显功能,同时想要退格键的删除功能和命令回车执行功能。他们还想需要一个闪烁的下划线代表计算机需要输入。这些完全合理的要求让构造这个方法更具有挑战性。有一个方法完成这些需求就是存储用户输入的文本和文件大小到内存的某个地方。然后当调用 ReadLine 的时候,移动 terminalStop 的地址到它开始的地方然后调用 Print。也就是说我们只需要确保在内存维护一个字符串,然后构造一个我们自己的打印函数。
|
||||
|
||||
让我们看看 ReadLine做了哪些事情:
|
||||
|
||||
1. 如果字符串可保存的最大长度为0,直接返回
|
||||
2. 检索 terminalStop 和 terminalStop 的当前值
|
||||
3. 如果字符串的最大长度大约缓冲区的一半,就设置大小为缓冲区的一半
|
||||
4. 从最大长度里面减去1来确保输入的闪烁字符或结束符
|
||||
5. 向字符串写入一个下划线
|
||||
6. 写入一个 terminalView 和 terminalStop 的地址到内存
|
||||
7. 调用 Print 大约当前字符串
|
||||
8. 调用 TerminalDisplay
|
||||
9. 调用 KeyboardUpdate
|
||||
10. 调用 KeyboardGetChar
|
||||
11. 如果为一个新行直接跳转到16
|
||||
12. 如果是一个退格键,将字符串长度减一(如果其大约0)
|
||||
13. 如果是一个普通字符,将他写入字符串(字符串大小确保小于最大值)
|
||||
14. 如果字符串是以下划线结束,写入一个空格,否则写入下划线
|
||||
15. 跳转到6
|
||||
16. 字符串的末尾写入一个新行
|
||||
17. 调用 Print 和 TerminalDisplay
|
||||
18. 用结束符替换新行
|
||||
19. 返回字符串的长度
|
||||
|
||||
|
||||
|
||||
为了方便读者理解,然后然后自己去实现,我们的实现提供如下:
|
||||
|
||||
1.
|
||||
```
|
||||
.globl ReadLine
|
||||
ReadLine:
|
||||
teq r1,#0
|
||||
moveq r0,#0
|
||||
moveq pc,lr
|
||||
```
|
||||
快速处理长度为0的情况
|
||||
|
||||
2.
|
||||
```
|
||||
string .req r4
|
||||
maxLength .req r5
|
||||
input .req r6
|
||||
taddr .req r7
|
||||
length .req r8
|
||||
view .req r9
|
||||
|
||||
push {r4,r5,r6,r7,r8,r9,lr}
|
||||
|
||||
mov string,r0
|
||||
mov maxLength,r1
|
||||
ldr taddr,=terminalStart
|
||||
ldr input,[taddr,#terminalStop-terminalStart]
|
||||
ldr view,[taddr,#terminalView-terminalStart]
|
||||
mov length,#0
|
||||
```
|
||||
考虑到常见的场景,我们初期做了很多初始化动作。input 代表 terminalStop 的值,view 代表 terminalView。Length 默认为 0.
|
||||
|
||||
3.
|
||||
```
|
||||
cmp maxLength,#128*64
|
||||
movhi maxLength,#128*64
|
||||
```
|
||||
我们必须检查异常大的读操作,我们不能处理超过 terminalBuffer 大小的输入(理论上可行,但是terminalStart 移动越过存储的terminalStop,会有很多问题)。
|
||||
|
||||
4.
|
||||
```
|
||||
sub maxLength,#1
|
||||
```
|
||||
由于用户需要一个闪烁的光标,我们需要一个备用字符在理想状况在这个字符串后面放一个结束符。
|
||||
|
||||
5.
|
||||
```
|
||||
mov r0,#'_'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
写入一个下划线让用户知道我们可以输入了。
|
||||
|
||||
6.
|
||||
```
|
||||
readLoop$:
|
||||
str input,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
```
|
||||
保存 terminalStop 和 terminalView。这个对重置一个终端很重要,它会修改这些变量。严格讲也可以修改 terminalStart,但是不可逆。
|
||||
|
||||
7.
|
||||
```
|
||||
mov r0,string
|
||||
mov r1,length
|
||||
add r1,#1
|
||||
bl Print
|
||||
```
|
||||
写入当前的输入。由于下划线因此字符串长度加1
|
||||
8.
|
||||
```
|
||||
bl TerminalDisplay
|
||||
```
|
||||
拷贝下一个文本到屏幕
|
||||
|
||||
9.
|
||||
```
|
||||
bl KeyboardUpdate
|
||||
```
|
||||
获取最近一次键盘输入
|
||||
|
||||
10.
|
||||
```
|
||||
bl KeyboardGetChar
|
||||
```
|
||||
检索键盘输入键值
|
||||
|
||||
11.
|
||||
```
|
||||
teq r0,#'\n'
|
||||
beq readLoopBreak$
|
||||
teq r0,#0
|
||||
beq cursor$
|
||||
teq r0,#'\b'
|
||||
bne standard$
|
||||
```
|
||||
|
||||
如果我们有一个回车键,循环中断。如果有结束符和一个退格键也会同样跳出选好。
|
||||
|
||||
12.
|
||||
```
|
||||
delete$:
|
||||
cmp length,#0
|
||||
subgt length,#1
|
||||
b cursor$
|
||||
```
|
||||
从 length 里面删除一个字符
|
||||
|
||||
13.
|
||||
```
|
||||
standard$:
|
||||
cmp length,maxLength
|
||||
bge cursor$
|
||||
strb r0,[string,length]
|
||||
add length,#1
|
||||
```
|
||||
写回一个普通字符
|
||||
|
||||
14.
|
||||
```
|
||||
cursor$:
|
||||
ldrb r0,[string,length]
|
||||
teq r0,#'_'
|
||||
moveq r0,#' '
|
||||
movne r0,#'_'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
加载最近的一个字符,如果不是下换线则修改为下换线,如果是空格则修改为下划线
|
||||
|
||||
15.
|
||||
```
|
||||
b readLoop$
|
||||
readLoopBreak$:
|
||||
```
|
||||
循环执行值到用户输入按下
|
||||
|
||||
16.
|
||||
```
|
||||
mov r0,#'\n'
|
||||
strb r0,[string,length]
|
||||
```
|
||||
在字符串的结尾处存入一新行
|
||||
|
||||
17.
|
||||
```
|
||||
str input,[taddr,#terminalStop-terminalStart]
|
||||
str view,[taddr,#terminalView-terminalStart]
|
||||
mov r0,string
|
||||
mov r1,length
|
||||
add r1,#1
|
||||
bl Print
|
||||
bl TerminalDisplay
|
||||
```
|
||||
重置 terminalView 和 terminalStop 然后调用 Print 和 TerminalDisplay 输入回显
|
||||
|
||||
|
||||
18.
|
||||
```
|
||||
mov r0,#0
|
||||
strb r0,[string,length]
|
||||
```
|
||||
写入一个结束符
|
||||
|
||||
19.
|
||||
```
|
||||
mov r0,length
|
||||
pop {r4,r5,r6,r7,r8,r9,pc}
|
||||
.unreq string
|
||||
.unreq maxLength
|
||||
.unreq input
|
||||
.unreq taddr
|
||||
.unreq length
|
||||
.unreq view
|
||||
```
|
||||
返回长度
|
||||
|
||||
|
||||
|
||||
|
||||
### 5 终端: 机器进化
|
||||
|
||||
现在我们理论用终端和用户可以交互了。最显而易见的事情就是拿去测试了!在 'main.s' 里UsbInitialise后面的删除代码如下
|
||||
|
||||
```
|
||||
reset$:
|
||||
mov sp,#0x8000
|
||||
bl TerminalClear
|
||||
|
||||
ldr r0,=welcome
|
||||
mov r1,#welcomeEnd-welcome
|
||||
bl Print
|
||||
|
||||
loop$:
|
||||
ldr r0,=prompt
|
||||
mov r1,#promptEnd-prompt
|
||||
bl Print
|
||||
|
||||
ldr r0,=command
|
||||
mov r1,#commandEnd-command
|
||||
bl ReadLine
|
||||
|
||||
teq r0,#0
|
||||
beq loopContinue$
|
||||
|
||||
mov r4,r0
|
||||
|
||||
ldr r5,=command
|
||||
ldr r6,=commandTable
|
||||
|
||||
ldr r7,[r6,#0]
|
||||
ldr r9,[r6,#4]
|
||||
commandLoop$:
|
||||
ldr r8,[r6,#8]
|
||||
sub r1,r8,r7
|
||||
|
||||
cmp r1,r4
|
||||
bgt commandLoopContinue$
|
||||
|
||||
mov r0,#0
|
||||
commandName$:
|
||||
ldrb r2,[r5,r0]
|
||||
ldrb r3,[r7,r0]
|
||||
teq r2,r3
|
||||
bne commandLoopContinue$
|
||||
add r0,#1
|
||||
teq r0,r1
|
||||
bne commandName$
|
||||
|
||||
ldrb r2,[r5,r0]
|
||||
teq r2,#0
|
||||
teqne r2,#' '
|
||||
bne commandLoopContinue$
|
||||
|
||||
mov r0,r5
|
||||
mov r1,r4
|
||||
mov lr,pc
|
||||
mov pc,r9
|
||||
b loopContinue$
|
||||
|
||||
commandLoopContinue$:
|
||||
add r6,#8
|
||||
mov r7,r8
|
||||
ldr r9,[r6,#4]
|
||||
teq r9,#0
|
||||
bne commandLoop$
|
||||
|
||||
ldr r0,=commandUnknown
|
||||
mov r1,#commandUnknownEnd-commandUnknown
|
||||
ldr r2,=formatBuffer
|
||||
ldr r3,=command
|
||||
bl FormatString
|
||||
|
||||
mov r1,r0
|
||||
ldr r0,=formatBuffer
|
||||
bl Print
|
||||
|
||||
loopContinue$:
|
||||
bl TerminalDisplay
|
||||
b loop$
|
||||
|
||||
echo:
|
||||
cmp r1,#5
|
||||
movle pc,lr
|
||||
|
||||
add r0,#5
|
||||
sub r1,#5
|
||||
b Print
|
||||
|
||||
ok:
|
||||
teq r1,#5
|
||||
beq okOn$
|
||||
teq r1,#6
|
||||
beq okOff$
|
||||
mov pc,lr
|
||||
|
||||
okOn$:
|
||||
ldrb r2,[r0,#3]
|
||||
teq r2,#'o'
|
||||
ldreqb r2,[r0,#4]
|
||||
teqeq r2,#'n'
|
||||
movne pc,lr
|
||||
mov r1,#0
|
||||
b okAct$
|
||||
|
||||
okOff$:
|
||||
ldrb r2,[r0,#3]
|
||||
teq r2,#'o'
|
||||
ldreqb r2,[r0,#4]
|
||||
teqeq r2,#'f'
|
||||
ldreqb r2,[r0,#5]
|
||||
teqeq r2,#'f'
|
||||
movne pc,lr
|
||||
mov r1,#1
|
||||
|
||||
okAct$:
|
||||
|
||||
mov r0,#16
|
||||
b SetGpio
|
||||
|
||||
.section .data
|
||||
.align 2
|
||||
welcome: .ascii "Welcome to Alex's OS - Everyone's favourite OS"
|
||||
welcomeEnd:
|
||||
.align 2
|
||||
prompt: .ascii "\n> "
|
||||
promptEnd:
|
||||
.align 2
|
||||
command:
|
||||
.rept 128
|
||||
.byte 0
|
||||
.endr
|
||||
commandEnd:
|
||||
.byte 0
|
||||
.align 2
|
||||
commandUnknown: .ascii "Command `%s' was not recognised.\n"
|
||||
commandUnknownEnd:
|
||||
.align 2
|
||||
formatBuffer:
|
||||
.rept 256
|
||||
.byte 0
|
||||
.endr
|
||||
formatEnd:
|
||||
|
||||
.align 2
|
||||
commandStringEcho: .ascii "echo"
|
||||
commandStringReset: .ascii "reset"
|
||||
commandStringOk: .ascii "ok"
|
||||
commandStringCls: .ascii "cls"
|
||||
commandStringEnd:
|
||||
|
||||
.align 2
|
||||
commandTable:
|
||||
.int commandStringEcho, echo
|
||||
.int commandStringReset, reset$
|
||||
.int commandStringOk, ok
|
||||
.int commandStringCls, TerminalClear
|
||||
.int commandStringEnd, 0
|
||||
```
|
||||
这块代码集成了一个简易的命令行操作系统。支持命令:echo,reset,ok 和 cls。echo 拷贝任意文本到终端,reset命令会在系统出现问题的是复位操作系统,ok 有两个功能:设置 OK 灯亮灭,最后 cls 调用 TerminalClear 清空终端。
|
||||
|
||||
试试树莓派的代码吧。如果遇到问题,请参照问题集锦页面吧。
|
||||
|
||||
如果运行正常,祝贺你完成了一个操作系统基本终端和输入系列的课程。很遗憾这个教程先讲到这里,但是我希望将来能制作更多教程。有问题请反馈至awc32@cam.ac.uk。
|
||||
|
||||
你已经在建立了一个简易的终端操作系统。我们的代码在 commandTable 构造了一个可用的命令表格。每个表格的入口是一个整型数字,用来表示字符串的地址,和一个整型数字表格代码的执行入口。 最后一个入口是 为 0 的commandStringEnd。尝试实现你自己的命令,可以参照已有的函数,建立一个新的。函数的参数 r0 是用户输入的命令地址,r1是其长度。你可以用这个传递你输入值到你的命令。也许你有一个计算器程序,或许是一个绘图程序或国际象棋。不管你的什么电子,让它跑起来!
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input02.html
|
||||
|
||||
作者:[Alex Chadwick][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/guevaraya)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.cl.cam.ac.uk
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html
|
||||
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/circular_buffer.png
|
||||
[3]: https://en.wikipedia.org/wiki/Color_Graphics_Adapter
|
@ -0,0 +1,55 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Go on an adventure in your Linux terminal)
|
||||
[#]: via: (https://opensource.com/article/18/12/linux-toy-adventure)
|
||||
[#]: author: (Jason Baker https://opensource.com/users/jason-baker)
|
||||
|
||||
在 Linux 终端上进行冒险
|
||||
======
|
||||
|
||||
我们的 Linux 命令行玩具日历的最后一天以开始一场盛大冒险结束。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/uploads/linux-toy-advent.png?itok=OImUJJI5)
|
||||
|
||||
今天是我们为期 24 天的 Linux 命令行玩具日历的最后一天。希望你一直有在看,但如果没有,请从[头][1]开始,继续努力。你会发现 Linux 终端有很多游戏、消遣和奇怪之处。
|
||||
|
||||
虽然你之前可能已经看过我们日历中的一些玩具,但我们希望对每个人而言至少有一件新东西。
|
||||
|
||||
今天的玩具是由 Opensource.com 管理员 [Joshua Allen Holm][2] 提出的:
|
||||
|
||||
“如果你的日历的最后一天不是 ESR(Eric S. Raymond)的[开源 Adventure][3],它保留了使用经典的 “advent” 命令(BSD 游戏包中的 Adventure 包名是 “adventure”) ,我会非常非常非常失望 ;-)“
|
||||
|
||||
这是结束我们这个系列的完美方式。
|
||||
|
||||
Colossal Cave Adventure(通常简称 Adventure),是一款来自 20 世纪 70 年代的基于文本的游戏,它带领产生了冒险游戏类型。尽管它很古老,但是当探索幻想世界时,Adventure 仍然是一种轻松消耗时间的方式,就像龙与地下城那样,地下城主可能会引导你穿过一个想象的地方。
|
||||
|
||||
与其带你了解 Adventure 的历史,我鼓励你去阅读 Joshua 的[游戏的历史][4]这篇文章,为什么它几年前会复活,并且被重新移植。接着,[克隆源码][5]并按照[安装说明][6]在你的系统上使用 **advent** 启动游戏。或者,像 Joshua 提到的那样,可以从 **bsd-games** 包中获取另一个版本的游戏,该软件包可能存在于你的发行版中的默认仓库。
|
||||
|
||||
|
||||
你有喜欢的命令行玩具认为我们应该介绍么?今天我们的系列结束了,但我们仍然乐于在新的一年中介绍一些很酷的命令行玩具。请在下面的评论中告诉我,我会查看一下。让我知道你对今天玩具的看法。
|
||||
|
||||
一定要看看昨天的玩具,[能从远程获得乐趣的 Linux 命令][7],明年再见!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/12/linux-toy-adventure
|
||||
|
||||
作者:[Jason Baker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jason-baker
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/18/12/linux-toy-boxes
|
||||
[2]: https://opensource.com/users/holmja
|
||||
[3]: https://gitlab.com/esr/open-adventure (https://gitlab.com/esr/open-adventure)
|
||||
[4]: https://opensource.com/article/17/6/revisit-colossal-cave-adventure-open-adventure
|
||||
[5]: https://gitlab.com/esr/open-adventure
|
||||
[6]: https://gitlab.com/esr/open-adventure/blob/master/INSTALL.adoc
|
||||
[7]: https://opensource.com/article/18/12/linux-toy-remote
|
@ -0,0 +1,185 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Display Thumbnail Images In Terminal)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-display-thumbnail-images-in-terminal/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
如何在终端显示图像缩略图
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-720x340.png)
|
||||
|
||||
不久前,我们讨论了 [Fim][1],这是一个轻量级的命令行图像查看器应用程序,用于从命令行显示各种类型的图像,如 bmp、gif、jpeg 和 png 等。今天,我偶然发现了一个名为 `lsix` 的类似工具。它类似于类 Unix 系统中的 `ls` 命令,但仅适用于图像。`lsix` 是一个简单的命令行实用程序,旨在使用 Sixel 图形在终端中显示缩略图。对于那些想知道的人来说,Sixel 是六像素的缩写,是一种位图图形格式。它使用 ImageMagick,因此几乎所有 imagemagick 支持的文件格式都可以正常工作。
|
||||
|
||||
### 功能
|
||||
|
||||
关于 `lsix` 的功能,我们可以列出如下:
|
||||
|
||||
* 自动检测你的终端是否支持 Sixel 图形。如果你的终端不支持 Sixel,它会通知你启用它。
|
||||
* 自动检测终端背景颜色。它使用终端转义序列来试图找出终端应用程序的前景色和背景色,并清楚地显示缩略图。
|
||||
* 如果目录中有更多图像,通常大于 21 个,`lsix` 将一次显示这些图像,因此你无需等待创建整个蒙太奇图像。
|
||||
* 可以通过 SSH 工作,因此你可以轻松操作存储在远程 Web 服务器上的图像。
|
||||
* 它支持非位图图形,例如 .svg、.eps、.pdf、.xcf 等。
|
||||
* 用 Bash 编写,适用于几乎所有 Linux 发行版。
|
||||
|
||||
### 安装 lsix
|
||||
|
||||
由于 `lsix` 使用 ImageMagick,请确保已安装它。它在大多数 Linux 发行版的默认软件库中都可用。 例如,在 Arch Linux 及其变体如 Antergos、Manjaro Linux 上,可以使用以下命令安装ImageMagick:
|
||||
|
||||
```
|
||||
$ sudo pacman -S imagemagick
|
||||
```
|
||||
|
||||
在 Debian、Ubuntu、Linux Mint:
|
||||
|
||||
```
|
||||
$ sudo apt-get install imagemagick
|
||||
```
|
||||
|
||||
`lsix` 并不需要安装,因为它只是一个 Bash 脚本。只需要下载它并移动到你的 `$PATH` 中。就这么简单。
|
||||
|
||||
从该项目的 GitHub 主页下载最新的 `lsix` 版本。我使用如下命令下载 `lsix` 归档包:
|
||||
|
||||
```
|
||||
$ wget https://github.com/hackerb9/lsix/archive/master.zip
|
||||
```
|
||||
|
||||
提取下载的 zip 文件:
|
||||
|
||||
```
|
||||
$ unzip master.zip
|
||||
```
|
||||
|
||||
此命令将所有内容提取到名为 `lsix-master` 的文件夹中。将 `lsix` 二进制文件从此目录复制到 `$ PATH` ,例如 `/usr/local/bin/`。
|
||||
|
||||
```
|
||||
$ sudo cp lsix-master/lsix /usr/local/bin/
|
||||
```
|
||||
|
||||
最后,使 `lsbix` 二进制文件可执行:
|
||||
|
||||
```
|
||||
$ sudo chmod +x /usr/local/bin/lsix
|
||||
```
|
||||
|
||||
如此,现在是在终端本身显示缩略图的时候了。
|
||||
|
||||
在开始使用 `lsix` 之前,请确保你的终端支持 Sixel 图形。
|
||||
|
||||
开发人员在 vt340 仿真模式下的 Xterm 上开发了 `lsix`。 然而,他声称 `lsix` 应该适用于任何Sixel 兼容终端。
|
||||
|
||||
Xterm 支持 Sixel 图形,但默认情况下不启用。
|
||||
|
||||
你可以从另外一个终端使用命令启动有个启用了 Sixel 模式的 Xterm:
|
||||
|
||||
```
|
||||
$ xterm -ti vt340
|
||||
```
|
||||
|
||||
或者,你可以使 vt340 成为 Xterm 的默认终端类型,如下所述。
|
||||
|
||||
编辑 `.Xresources` 文件(如果它不可用,只需创建它):
|
||||
|
||||
```
|
||||
$ vi .Xresources
|
||||
```
|
||||
|
||||
添加如下行:
|
||||
|
||||
```
|
||||
xterm*decTerminalID : vt340
|
||||
```
|
||||
|
||||
按下 `ESC` 并键入 `:wq` 以保存并关闭该文件。
|
||||
|
||||
最后,运行如下命令来应用改变:
|
||||
|
||||
```
|
||||
$ xrdb -merge .Xresources
|
||||
```
|
||||
|
||||
现在,每次启动 Xterm 就会默认启用 Sixel 模式。
|
||||
|
||||
### 在终端中显示缩略图
|
||||
|
||||
启动 Xterm(不要忘记以 vt340 模式启动它)。以下是 Xterm 在我的系统中的样子。
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/xterm-1.png)
|
||||
|
||||
就像我已经说过的那样,`lsix` 非常简单实用。它没有任何命令行选项或配置文件。你所要做的就是将文件的路径作为参数传递,如下所示。
|
||||
Like I already stated, lsix is very simple utility. It doesn’t have any command
|
||||
|
||||
```
|
||||
$ lsix ostechnix/logo.png
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-4.png)
|
||||
|
||||
如果在没有路径的情况下运行它,它将显示在当前工作目录中的缩略图图像。我在名为 `ostechnix` 的目录中有几个文件。
|
||||
|
||||
要显示此目录中的缩略图,只需运行:
|
||||
|
||||
```
|
||||
$ lsix
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-1.png)
|
||||
|
||||
看到了吗?所有文件的缩略图都显示在终端里。
|
||||
|
||||
如果使用 `ls` 命令,则只能看到文件名,而不是缩略图。
|
||||
|
||||
![][3]
|
||||
|
||||
你还可以使用通配符显示特定类型的指定图像或一组图像。
|
||||
|
||||
例如,要显示单个图像,只需提及图像的完整路径,如下所示。
|
||||
|
||||
```
|
||||
$ lsix girl.jpg
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/01/lsix-2.png)
|
||||
|
||||
要显示特定类型的所有图像,例如 PNG,请使用如下所示的通配符。
|
||||
|
||||
```
|
||||
$ lsix *.png
|
||||
```
|
||||
|
||||
![][4]
|
||||
|
||||
对于 JEPG 类型,命令如下:
|
||||
|
||||
```
|
||||
$ lsix *jpg
|
||||
```
|
||||
|
||||
缩略图的显示质量非常好。我以为 `lsix` 会显示模糊的缩略图。但我错了,缩略图清晰可见,就像在图形图像查看器上一样。
|
||||
|
||||
而且,这一切都是唾手可得。如你所见,`lsix` 与 `ls` 命令非常相似,但它仅用于显示缩略图。如果你在工作中处理很多图像,`lsix` 可能会非常方便。试一试,请在下面的评论部分告诉我们你对此实用程序的看法。如果你知道任何类似的工具,也请提出建议。我将检查并更新本指南。
|
||||
|
||||
更多好东西即将到来。敬请关注!
|
||||
|
||||
干杯!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-display-thumbnail-images-in-terminal/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/how-to-display-images-in-the-terminal/
|
||||
[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]: http://www.ostechnix.com/wp-content/uploads/2019/01/ls-command-1.png
|
||||
[4]: http://www.ostechnix.com/wp-content/uploads/2019/01/lsix-3.png
|
Loading…
Reference in New Issue
Block a user