2021年1月

当那个讨厌的命令就在你的指间,但是就是想不起来,一个方便的速查表就可以拯救你。这份速查表清单涵盖了从编程语言到协作工具的各种内容。

 title=

有时候,你需要一个简短的提示。你知道自己想做什么,但就是想不起具体怎么做。这时候速查表就派上用场了。在这篇文章中,我给大家提供了 MariaDB 和 MySQL 的速查表。这个速查表对于偶尔使用数据库的人来说是非常有用的。接下来,我列出了两个树莓派速查表。第一张可以让你入门这台单板计算机。一旦你有了一定的基础知识,就可以把它变成一个家庭实验室,可以开始使用 Kubernetes 进行容器管理。一定要同时看看下一张速查表,因为它涵盖了 kubectl 工具。接下来,有一个很棒的 Emacs 的速查表,以及还有一个 C 编程语言的速查表。最后,这个列表以两个非常实用的速查表结束:协作工具和开源替代品。

下面是这份清单:

MariaDB 和 MySQL 速查表

MariaDB 是一个企业级数据库。学习 MariaDB 是使用它来管理 Web 应用程序或编程语言库的重要一步。这个 MariaDB 和 MySQL 速查表涵盖了连接到服务器、分析数据和其他关键活动的有用命令。本速查表上的命令对交互式提示符和 SQL 脚本有效,但很多内容推断可以用于编程库。

树莓派:如何入门

自 2012 年以来,树莓派一直是学习编程技能、构建硬件项目、进行家庭自动化和创建应用程序的必备工具。它实惠的价格使它对任何技能水平的开源爱好者都有吸引力。这本可下载的指南将为你提供挑选树莓派、保持更新、使用它进行 Linux 游戏、为社区做贡献等方面的提示,让你获得成功。

在你的树莓派家庭实验室上运行 Kubernetes

由于树莓派单板计算机的经济性和多功能性,建立一个家庭实验室变得越来越容易。你可以用树莓派做成千上万的事情,包括实验 Kubernetes。在这本电子书中,作者 Chris Collins 演示了如何开始在树莓派上运行 Kubernetes。本指南的每个部分都可以单独学习,也可以作为一个整体项目来学习。无论你的日常工作是什么,阅读这些教程并按照自己的节奏进行尝试,一定会提升你的云技术实力。

kubectl 速查表

kubectl 是维护 Kubernetes 集群的强大命令行工具。这个 2 页的速查表涵盖了常用的命令,让你超越一般的集群管理。它分为三个不同的部分,包括基本命令、故障排除命令和高级命令。掌握这九个关键的 kubectl 命令,可以帮助你排除故障和管理 Kubernetes 集群。

Emacs 速查表

要记住每一个 Emacs 的快捷键几乎是不可能的。通过这个速查表,你可以熟悉最常见的组合,从而提高工作效率。当你有这个指南在身边时,你可以不用担心忘记 Emacs 键盘快捷键。通过学习这个速查表中演示的基本键盘快捷键,成为 Emacs 高手。

C 语言编程速查表

C 是一种直接的编译编程语言。许多其他编程语言从 C 语言中借用了概念,如果你想学习 Lua、C++、Java 或 Go 等编程语言,C 语言是一个很好的起点。Jim Hall 的这份双面速查表包含了所有的基础知识,因此你可以立即获得 C 语法的所有要领。通过下载这个速查表来学习 C 语言,并将语法要领随身携带。

5 个开源协作工具

Kevin Sonney 的生产力指南通过五个开源工具教程让协作变得轻而易举。下载的速查表所涉及的工具包括开源邮件客户端、Google Docs 的替代方案等。让团队沟通不畅成为过去,迎接团队生产力的提升。

开放源码软件替代方案速查表

在我们广阔的开源世界里,有很多通用的专有软件工具的替代品。然而,有时要找到合适的开源替代品以满足你的特定需求是令人生畏的。这就是为什么我们整理了这一页的速查表,涵盖了主要的软件工具类别,包括团队聊天、文件共享、文字处理等。我们并没有止步于办公工具。我们还包括游戏、社交媒体和个人理财的顶级开源应用。通过这个速查表,可以快速找到常见的专有软件工具的替代品。

总结

这个列表涵盖了很多主题。在我们的下载页面上可以查看更多的速查表和指南。请在下面的评论中告诉我们你最喜欢的是哪一个。不要忘了为你最喜欢的开源工具写和提交速查表。


via: https://opensource.com/article/21/1/cheat-sheets

作者:Jim Hall 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

想学习 Git?看看这个最重要的术语和命令的快速总结。

 title=

如今,对于任何希望跟踪他们的变化的人来说,版本控制是一个重要的工具。它对程序员、系统管理员和 网站可靠性工程师 site reliability engineers (SRE)都特别有用。确保可以从错误中恢复到已知的良好状态是一个巨大的胜利,比以前给复制的文件添加 .old 后缀的策略更友好。

但学习 Git 这件事往往被告诉大家“投身开源”的好心同行们过度简化了。在你还不明白之前,就有人要你给一个从 上游 upstream 变基 rebase 的 拉取请求 pull request (PR)或 合并请求 merge request (MR),然后他们才能从你的 远程版本库 remote 合并 —— 而且一定会删除 合并提交 merge commits 。无论你想给开源项目做出什么好的贡献,当你看到这些你不认识的单词时,都会觉得难以融入。

 title=

  • 下载 我们的 Git 速查表。

如果你有一两个月的时间和足够的好奇心,Git SCM 是你需要学习所有术语的权威来源。但如果你正在寻找来自实践的总结,请继续阅读。

提交就是提醒

对我来说,Git 最难理解的部分是 Git 最简单的概念:一个 提交 commit 就是一个内容的集合,包括一个关于描述的信息,以及之前的提交。没有固有的代码发布策略,甚至没有内置的明确建议。这个内容甚至不一定是代码 —— 可以是任何你想添加到版本库的东西。 提交消息 commit message 会对这些内容进行注释。

我喜欢把提交信息看作是给未来的自己的礼物:它可能会提到你编辑的文件,但更重要的是它提醒你修改这些文件的意图。添加更多关于你为什么编辑这些内容的信息,可以帮助任何使用你的版本库的人,即使那个人是你。

origin/master 在哪里?

要知道自己在 Git 项目中的位置,首先把它想成一棵树。所有 Git 项目都有一个根目录,类似于文件系统的根目录。所有的提交都是这个根目录下的分支。这样一来,分支只是一个提交的指针。按照惯例,master 是根目录下默认的分支名称。(LCTT 译注:世界变得快,原文发表于 2019 年,而现在有些地方开始用 main 替代这个名字。)

由于 Git 是一个分布式的版本控制系统,同一个代码库分布在多个地方,所以人们经常用 版本库 repository 这个词来表示同一个项目的所有副本。(LCTT 译注:“repository” 英文原意是仓库、存储库,在计算机环境中,常用于版本控制、软件分发等方面,有时候会统一译作“仓库”、“存储库”。但我们认为,应该根据不同语境采用更有指向性的译法。在 Git 等版本控制语境中,采用“版本库”;在软件分发方面,采用“软件库”;其它泛指或不确定的语境中,可采用“仓库”、“存储库”译法。)有 本地版本库 local repository ,这是你编辑代码的地方(稍后会有更多的介绍),还有 远程版本库 remote repository ,这是你完成后想把代码发送到的地方。远程版本库可以在任何地方,甚至在你的本地版本库所在的同一台计算机上,但它们通常托管在 GitLab 或 GitHub 等版本库服务上。

我在哪里?

虽然不是官方的卖点,但迷路也是 Git 仓库的“乐趣”之一。你可以通过这套可靠的命令来找到自己的方向:

  • git branch —— 找到你所在的分支。
  • git log —— 查看你正在进行的提交。
  • git status —— 查看自上次提交以来你所做的编辑。
  • git remote —— 查看你正在跟踪的远程仓库。

用这些命令来定位自己的方向,当你被卡住的时候,会让你有一种方向感。

我是否已将我的提交暂存或缓存起来?

你电脑上的代码俗称为你的 工作空间 workspace 。但不是很明显的是,当你在 Git 仓库中时,你还有两个(是的,两个!)其他位置: 索引 index 和 暂存 stash 。当你写了一些内容,然后添加时,你是把它添加到索引中,也就是准备提交的缓存内容。有的时候,你的索引中的文件还没有准备好提交,但你想查看另一个分支。这时,暂存就派上用场了。你可以使用 git stash 将索引了但尚未提交的文件存储到暂存区中。当你准备好取回文件时,运行 git stash pop 将更改带回索引中。

下面是一些你需要使用暂存区和缓存区的命令:

  • git diff ...origin/master —— 显示最近的本地提交和远程的 origin 版本库的 master 分支之间的差异。
  • git diff --cached —— 显示最近的本地提交与添加到本地索引的内容之间的任何差异。
  • git stash —— 将索引的(已添加但未提交的)文件放在暂存区堆栈中。
  • git stash list —— 显示暂存区堆栈中的变化。
  • git stash pop —— 将最近的变化从暂存库中删除。

无头骑士

Git 里面有各种比喻。当我想到 HEAD 是哪里的时候,我就会想到火车线路。如果你最终处于 脱离的 HEAD detached HEAD 模式,就意味着你已经脱离了这个隐喻的轨道。

HEAD 是指向当前签出分支中最近一次提交的指针。默认的“签出checkout”是指当你创建一个 Git 仓库并进入到 master 分支的时候。每次创建或修改到另一个分支时,你都会切换到该分支行。如果你在当前分支的某处进行 git checkout <commit>,HEAD 就会移动到该提交。如果没有提交历史记录将你的当前提交连接到已签出的提交,那么你将处于脱离的 HEAD 状态。如果你找不到 HEAD 的位置,你可以随时用 git reset --hard origin/master 来删除修改,回到已知状态。警告:这将删除你上次推送到 master 后的任何改动。

你是上游还是下游?

你的项目的本地副本被认为是你的本地版本库,它可能有也可能没有远程版本库 —— 远程版本库的副本是用于协作或保存的。也可能还有一个 上游 upstream 版本库,在那里,项目的第三个副本由不同的贡献者托管和维护。

例如,假设我想为 Kubernetes 做贡献。我会首先将 kubernetes/kubernetes 项目 复刻 fork 到我的账户下 mbbroberg/kubernetes。然后我会将我的项目克隆到我的本地工作区。在这种情况下,我的本地克隆是我的本地仓库,mbbroberg/kubernetes 是我的远程仓库,kubernetes/kubernetes 是上游。

合并的隐喻

当你深入 Git 分支时,根系统的视觉效果就会和火车轨道的形象合二为一。分支通常被用作开发一个新功能的方式,最终你想把它 合并 merge 到主分支中。当这样做时,Git 会按顺序保留共同的提交历史,然后将你的分支的新提交追加到历史中。这个过程有一大堆的细节:是否 变基 rebase ,是否添加一个 合并提交 merge commit ,Brent Laster 在《如何在 Git 中重置、恢复和返回之前的状态》中会有更详细的探讨。

我想现在就去 Git

要掌握 Git 命令的世界,有大量的术语和需要探索的地方。我希望这篇关于日常使用术语的第一人称探索能帮助你适应这一切。如果你觉得自己被卡住了或者遇到了挫折,欢迎在 Twitter @mbbroberg 上联系我。

回顾

  • 提交 Commit —— 将当前索引的内容保存在一个新的提交中,并附上用户描述更改的日志信息。
  • 分支 Branch —— 指向一个提交的指针。
  • master —— 第一个分支的默认名称。
  • HEAD —— 指向当前分支上最近一次提交的指针。
  • 合并 Merge —— 合并两个或多个提交的历史。
  • 工作空间 Workspace —— Git 仓库本地副本的通俗名称。
  • 工作树 Working tree —— 工作区中的当前分支;任何时候你都可以在 git status 的输出中看到这个。
  • 缓存 Cache —— 用于临时存储未提交的变更的空间。
  • 索引 Index —— 变更提交前存储其变化的缓存。
  • 跟踪和未跟踪的文件 —— 没有被索引缓存的文件或尚未加入其中的文件。
  • 暂存 Stash —— 另一个缓存,作为一个堆栈,在这里可以存储更改而不需要提交它们。
  • origin —— 远程版本库的默认名称。
  • 本地仓库 Local repository —— 也就是你在工作站上保存 Git 仓库副本的地方。
  • 远程存储库 Remote repository —— Git 存储库的第二副本,你可以在这里推送变更以便协作或备份。
  • 上游存储库 Upstream repository —— 你跟踪的远程存储库的通俗说法。
  • 拉取请求 Pull request —— 这是 GitHub 的专用术语,用于让其他人知道你推送到仓库分支的变化。
  • 合并请求 Merge request —— 这是 GitLab 的专用术语,用于让其他人知道你推送到仓库分支的变化。
  • origin/master —— 远程版本库及其主要分支的默认名称。

后记:双关语是 Git 最好的部分之一,愿你喜欢。


via: https://opensource.com/article/19/2/git-terminology

作者:Matthew Broberg 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Joe's Own Editor (JOE)是一款简单易学和使用的通用文本编辑器。

我很喜欢那些能让你轻松学会如何使用的文本编辑器。GNU nano 是我最喜欢的例子:你启动 nano,你会在整个会话的窗口底部看到一个最常用的命令列表。Joe's Own Editor(简称 joe)是另一个很好的例子。

joe 编辑器使用了一个基于终端的界面,提供了简单的文本编辑功能和一个易于访问的帮助屏幕。它用 C 语言编写,体积小,只对 libc 有硬性依赖(ncurses 是可选的),并且采用 GPL 许可证。

安装

在 Linux 上,你也许能在你的发行版软件仓库中找到 JOE。虽然它有点小众,并不是所有的发行版都打包了它。如果是这样的话,你可以从 SourceForge 下载源码,然后自己编译。这是个简单的过程:

$ ./configure
$ make
$ sudo make install

使用 JOE

据其作者介绍,JOE 的灵感来自于一个叫 WordStar 的应用和 GNU Emacs。它的大部分基本编辑键都与 WordStar 的快捷键相同,编辑器本身也在努力向 WordStar 靠拢。JOE 也有 GNU Emacs 的一些键绑定和功能。这种两种灵感来源的混合有时会让人迷惑,但话又说回来,在任何情况下,让自己离开 Emacs(或你通常选择的文本编辑器)都会让人迷惑。重要的是,JOE 提供了帮助,而且很容易访问。

在 JOE 界面右上角,有一个持续的提示,你可以按 Ctrl+K,紧接着按 H 来查看帮助界面。这是一个切换键,所以一旦你激活它,帮助屏幕就会一直显示在你的编辑器窗口顶部,直到用同样的组合键(JOE 中的键盘符号为 ^KH)解除。

键盘快捷键

尽管 JOE 的作者在模拟 WordStar 用户体验方面非常自豪,但我不得不承认,这对我来说是失落的。我从来没有听说过 WordStar,直到我在 JOE 的文档中读到了它,在我看来,它的键盘快捷键方案完全是任意的。有的用 Ctrl+K 作为转义序列的前缀,有的用 Esc 作为前缀,还有的完全不需要转义序列。我无法确定其中的逻辑。编辑操作和应用选项一样,都有可能需要或不需要转义序列,而且字母关联对我来说是没有什么意义(例如,Ctrl+K D 代表另存为)。

幸运的是,JOE 可以让你在键盘快捷键上作弊。安装后,JOE 会悄悄为 joe 可执行文件创建一些符号链接。包括:

  • jmacs JOE 使用 Emacs 键绑定
  • jpico JOE 使用 Pico (或 GNU nano) 键绑定
  • rjoe JOE 的编辑只限于启动时传递给 JOE 的文件
  • jstar JOE 使用 WordStar 键绑定

 title=

持久保留的帮助菜单仍然存在,所以如果你不清楚有哪些功能可以使用,可以通过屏幕右上方的帮助提示来参考。当然,在 Pico/nano 模式下,主要命令总是可见的。

尝试 JOE

JOE 并不是一个你永远不会离开的文本编辑器,它不会成为你的 IDE、电子邮件客户端、网络浏览器和文件管理器。事实上,它甚至可能不是你所有任务的主要文本编辑器。它专注于做好一件事,那就是成为一般的文本编辑。

JOE 拥有你所需要的所有基本功能,比如能够快速浏览你的文本、能够选择文本、复制和粘贴等等。试试 JOE 吧,使用你喜欢的符号链接。


via: https://opensource.com/article/20/12/joe

作者:Seth Kenlon 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Sed 缺少通常的文本框,而是按照用户的命令直接写入到文件上。

sed 命令是为 AT&T 最初的 Unix 操作系统第 7 版创建的,此后,可能每一个 Unix 和 Linux 操作系统都包含了它。sed 应用程序是一个 流编辑器,与文本编辑器不同的是,它不会打开一个视觉缓冲区,将文件的数据加载到其中进行处理。相反,它根据在终端输入的命令或脚本中的一系列命令,逐行对文件进行操作。

安装

如果你使用的是 Linux、BSD 或 macOS,那么你已经安装了 GNU 或 BSD 版的 sed。这是两个不同的原始 sed 命令的重新实现,虽然它们很相似,但也有一些小的区别。GNU sed 通常被认为是功能最丰富的 sed,而且它在这些平台上都可以广泛使用。

如果你找不到 GNU sed(在非 Linux 系统上通常被称为 gsed),那么你可以从 GNU 网站上下载它的源代码。安装 GNU sed 的好处是,可以使用它的额外功能,但它也可以被限制为只符合 sed 的 POSIX 规范,如果你需要移植性的话。

在 Windows 上,你可以用 Chocolatey 来安装 GNU sed。

Sed 如何工作

sed 应用程序一次只处理一行。因为它没有视觉显示,所以它在内存中创建了一个模式空间:一个包含输入流的当前行的空间(去掉任何尾部的换行符)。一旦填充了模式空间,你对 sed 的指令就会被执行。有时你的指令是有条件的,有时是无条件的,所以这些指令的结果取决于你如何使用 sed。

当命令结束时,sed 会将模式空间的内容打印到输出流中。默认的输出流是标准输出,但可以将其重定向到一个文件,甚至使用 --in-place=.bak 选项重定向到同一个文件中。

然后再从下一个输入行开始循环。

sed命令的语法是:

$ sed --options [optional SCRIPT] [INPUT FILE or STREAM]

找到你要编辑的内容

在可视化编辑器中,你通常不需要考虑太多,就能在文本文件中找到你想要修改的内容。你的眼睛(或屏幕阅读器)会扫描文本,找到你想改变的单词或你想插入或删除文本的地方,然后你就可以开始输入了。而 sed 没有交互模式,所以你需要告诉它必须满足什么条件才能运行特定的命令。

在这些例子中,假设一个名为 example.txt 的文件包含了这样的文字:

hello
world
This is line three.
Here is the final line.

行号

指定行号告诉 sed 只对文件中的那一行进行操作。

例如,下面这条命令选择文件的第 1 行并打印出来。因为 sed 在处理后的默认操作也是打印一行到标准输出,这样做的效果就是重复第一行:

$ sed '1p' example.txt
hello
hello
world
This is line three.
Here is the final line.

你也可以步进式指定行号。例如,1~2 表示每两行选择一行(“从第一行开始每两行选择一行”)。指令 1~3 表示从第一行开始,每三行选择一行:

$ sed '1p' example.txt
hello
hello
world
This is line three.
Here is the final line.
Here is the final line.

行定位

你可以通过使用 $ 作为选择器,只对文件的最后一行进行操作:

$ sed '$p' example.txt
hello
world
This is line three.
Here is the final line.
Here is the final line.

在 GNU sed 中,你可以选择多行(例如,sed '1,$p' 打印第一行和最后一行)。

反转

任何数字或位置的选择,你都可以用感叹号(!)字符反转。下面这将选择除第一行以外的所有行:

$ sed '1!p' example.txt
hello
world
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.

模式匹配

你可以把模式匹配想象成文字处理器或浏览器中的查找操作。你提供一个词(一个 模式),然后选择了结果。模式匹配的语法是 /pattern/:

$ sed '/hello/p' example.txt
hello
hello
world
This is line three.
Here is the final line.
$ sed '/line/p' example.txt
hello
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.

用 Sed 编辑

一旦你找到了你要编辑的内容,你就可以执行你想要的任何操作。你可以用 sed 中的命令来执行编辑。sed 中的命令不是 sed 命令本身。如果这样说有帮助的话,可以把它们看作是“动作”或“动词”或“指令”。

sed 中的命令是单个字母,例如前面例子中使用的打印命令的 p。它们一开始可能很难记忆,但和所有事情一样,你会随着练习而了解它们。

p 代表打印

p 指令打印当前模式空间中的任何内容。

d 用于删除

d 指令删除模式空间:

$ sed '$d' example.txt
hello
world
This is line three.
$ sed '1d' example.txt
world
This is line three.
Here is the final line.

s 用于搜索和替换

s 命令搜索一个模式并将其替换为其他东西。这可能是 sed 最流行和最随意的用法,而且它通常是用户学习的第一个(有时也是唯一的)sed 命令。几乎可以肯定它是文本编辑中最有用的命令:

$ sed 's/world/opensource.com/' example.txt
hello
opensource.com
This is line three.
Here is the final line.

在你的替换文本中,也可以使用一些特殊的功能。例如,\L 将替换文本转换为小写,\l 则只转换下一个字符。还有其他一些功能,列在 sed 文档中(你可以用 info sed 命令查看)。

替换子句中的特殊字符 & 指的是匹配到的模式:

$ sed 's/is/\U&/' example.txt
hello
world
ThIS is line three.
Here IS the final line.

你也可以通过特殊的标志来影响 s 如何处理它找到的内容。g(应该是指 全局)标志告诉 s 对行上找到的所有匹配项进行替换,而不仅仅是第一个匹配项:

$ sed 's/is/\U&/g' example.txt
hello
world
ThIS IS line three.
Here IS the final line.

其他重要的标志还包括用一个数字来表示要影响第几个出现的匹配模式:

$ sed 's/is/\U&/2' example.txt
hello
world
This IS line three.
Here is the final line.

w 标志,后面跟着一个文件名,\_只有\_在有变化的情况下,才会将匹配的行写入文件:

$ sed 's/is/\U&/w sed.log' example.txt
hello
world
ThIS is line three.
Here IS the final line.
$ cat sed.log
ThIS is line three.
Here IS the final line.

标志可以组合:

$ sed 's/is/\U&/2w sed.log' example.txt
hello
world
This IS line three.
Here is the final line.
$ cat sed.log
This IS line three.

脚本

有很多很棒的网站都有 sed “单行脚本”,它们给你提供了面向任务的 sed 命令来解决常见的问题。然而,自己学习 sed 可以让你写出自己的单行脚本,而且这些单行脚本可以根据你的具体需求来定制。

sed 的脚本可以在终端中写成一行,也可以保存到文件中,然后用 sed 本身执行。我倾向于把小脚本写成一个命令,因为我发现自己在现实生活中很少重复使用 sed 命令。当我写一个 sed 脚本时,通常都是针对一个文件的。例如,在写完这篇文章的初稿后,我用 sed 来规范 “sed” 的大小写,而这是我可能永远也不会再做的任务。

你可以向 sed 发出一系列不同的命令,用分号(;)分开。

$ sed '3t ; s/line/\U&/' example.txt
hello
world
This is LINE three.
This is the final line.

带括号的范围改变

你也可以用大括号({})限制哪些结果受到影响。当你将 sed 命令用大括号括起来时,它们只适用于特定的选择。例如,“line” 字出现在样本文本的两行中。你可以通过声明所需的匹配条件($ 表示最后一行),并将你希望执行的 s 命令放在紧随其后的括号中,强制 sed 只影响最后一行:

$ sed '$ {s/line/\U&/}' example.txt
hello
world
This is line three.
This is the final LINE.

学习 Sed

你可以用 sed 做的事情比本文所解释的多得多。我甚至还没有涉及到分支(b)、测试(t)、保留空格(H)和许多其他功能。就像 ed 一样,sed 可能不是你要用来创建文档的文本编辑器,甚至不是你需要做的每一个脚本任务中使用的文本编辑器,但它是你作为 POSIX 用户的一个强大的选择。学习 sed 命令的结构以及如何编写简短的脚本可以快速修改大量的文本。阅读 GNU sed 的info 页面,或者 BSD sed 的手册页,看看 sed 能为你做什么。


via: https://opensource.com/article/20/12/sed

作者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果你的程序需要一段时间才能显示结果,可通过显示它的进度来避免让用户感到沮丧。

阿拉米语,希伯来语和阿拉伯语中的闪米特语根 q-d-m 通常与前进或进度有关。阿拉伯语 taqaddum (تقدّم)的意思是“进度”。进度是很重要的。正如每部感觉良好的电影都会告诉你,旅程和目的地同样重要。

大多数程序都有一个明确的目标,一个期望的最终状态。有时,计算这个最终状态可能需要很长的时间。虽然计算机没有感情不在乎,但人却在乎。人类并不乐意坐在原地等待,而看不到任何明显的进展迹象。疑问不断蔓延。程序崩溃了吗?磁盘性能是否抖动?操作系统是否把所有的计算资源都分配给了其他任务?

就像正义一样,进度必须被看到,而不仅仅是完成。Python 库 tqdm 有助于使进度变得明确。

tqdm 模块可在控制台下工作,但它也专门支持了我最喜欢的环境之一 Jupyter。要在 Jupyter 中使用 tqdm,你需要导入 notebook 子模块并安装 ipywidgets。notebook 子模块与 tqdm 接口兼容。

这意味着你可以做一些导入时操作来导入正确的模块,同时保持 tqdm 的用法不变。诀窍是检查 __main__ 模块是否具有全局变量 get_ipython。虽然这只是一个启发式的方法,但却是一个相当准确的方法:

import sys
if hasattr(sys.modules["__main__"], "get_ipython"):
    from tqdm import notebook as tqdm
else:
    import tqdm

最简单的情况是,某件事情需要运行一定的迭代次数(事先已知),而每一次迭代的时间都差不多。例如,有一个计算任何数字的平方根的算法,通过从 1 作为猜测值开始,然后计算出一个改进后的猜测值:

def improve_guess(rt, n):
    return (rt + n/rt) / 2

一点点的改进可以让你更加接近该平方根。例如,你可以计算 2 的平方根:

guess = 1
target = 2
for i in tqdm.trange(10):
    guess = improve_guess(guess, target)

 title=

精确了到小数点后 10 位!

round(2 - guess*guess, 10)
0.0

一个稍微复杂一点的例子是,当元素的数量是已知的,而处理每个元素需要类似的时间。例如,你可以计算一些数字的乘积。为此,你需要一些随机数:

import random
numbers = [random.uniform(0, 2.8) for i in range(100)]
numbers[:5]
[2.6575636572230916,
0.1286674965830302,
1.0634250104041332,
1.1760969844376505,
0.45192978568125486]

现在有了这些数字,可以将它们相乘了。使用 tqdm 最简单的方法是包装一个 Python 迭代函数。数值是一样的,但是 tqdm 会显示一个进度条:

result = 1
for num in tqdm.tqdm(numbers):
    result *= num
result
2.4081854901728303

 title=

然而,并不是所有的事情都可以预测。最不容易预测的事情之一就是网络速度。当你下载一个大文件时,衡量进度的唯一方法就是检查已经下载了多少:

url = "https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz"
import httpx
with httpx.stream("GET", url) as response:
    total = int(response.headers["Content-Length"])
    with tqdm.tqdm(total=total) as progress:
        for chunk in response.iter_bytes():
            progress.update(len(chunk))

 title=

有时,“嵌套”进度条是有意义的。例如,如果你要下载一个目录,你就需要一个进度条来跟踪文件,并为每个文件设置一个进度条。

下面是一个例子(但没有实际下载一个目录):

files = [f"vid-{i}.mp4" for i in range(4)]
for fname in tqdm.tqdm(files, desc="files"):
    total = random.randrange(10**9, 2 * 10**9)
    with tqdm.tqdm(total=total, desc=fname) as progress:
        current = 0
        while current &lt; total:
            chunk_size = min(random.randrange(10**3, 10**5), total - current)
            current += chunk_size
            if random.uniform(0, 1) &lt; 0.01:
                time.sleep(0.1)
            progress.update(chunk_size)

 title=

所以,如果你的程序需要一段时间才能显示最终结果,为避免让你的用户感到沮丧。请显示它的进度!


via: https://opensource.com/article/20/12/tqdm-python

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Loki 扩展了 Prometheus 用于度量监测和日志聚合的模型。

Loki 是一个 Apache 2.0 许可的开源日志聚合框架,由 Grafana 实验室设计,并在不断发展的社区的巨大支持之下建立。它也是我每天为之努力的项目。在这篇文章中,我将不只是谈论 Loki 如何工作,而是提供一个实际操作的介绍,以解决实际问题。

问题:一个持久的集中式 Shell 历史记录

我喜欢我的 shell 历史,一直是 CTRL+R 的狂热用户。大约一年前,我的终端生活发生了翻天覆地的变化,我的同行 Dieter Plaetinck 向我介绍了命令行模糊查找器 fzf。

突然间,在命令中搜索就从这样:

 title=

变成了这样:

 title=

虽然 fzf 极大地提高了我的生活质量,但围绕着我的 shell 历史记录,还是缺少了一些片段:

  • 终端突然关闭、电脑崩溃、死机、整盘加密密钥被遗忘等情况下会丢失 shell 历史记录。
  • 想从我的所有电脑上访问我的 shell 历史记录。

我认为我的 shell 历史记录是文件:它是一个重要的故事,我不想失去。将 Loki 与我的 shell 历史结合起来,有助于解决这些问题和更多问题。

关于 Loki

Loki 采用了开源 Prometheus 项目用于度量的直观的标签模型,并将其扩展到日志聚合的世界。这使得开发人员和运维人员能够使用相同的标签集在他们的度量和日志之间无缝切换。即使你没有使用 Prometheus,也有很多理由说明 Loki 可能很适合你的日志存储需求:

  • 低开销: Loki 不做全文日志索引;它只创建你放在日志上的标签的索引。保持小的索引大大降低了 Loki 的运维要求。我在 树莓派 上运行我的 loki-shell 项目,该项目使用 Loki 来存储 shell 历史记录,只使用了 50MB 多一点的内存。
  • *成本低:**日志内容被压缩并存储在对象存储中,如 Amazon S3、Google 云存储、Azure Blob,甚至可以直接存储在文件系统中。我们的目标是使用价格低廉且持久的存储。
  • 灵活性: Loki 以单个二进制文件的形式提供,可以直接下载并运行,也可以作为 Docker 镜像在任何容器环境中运行。在 Kubernetes 中可以用一个 Helm 海图 快速上手。如果你对日志工具的要求很高,可以看看运行在 Grafana 实验室的 生产环境。它使用开源的 Jsonnet 和 Tanka 部署了同样的 Loki 镜像作为离散的构件,以实现大规模的水平扩展、高可用性、复制、读写路径的分别扩展、高度可并行的查询等。

总而言之,Loki 的方法是保留一个关于你的日志元数据的小索引(标签),并将未索引的、压缩的日志内容存储在廉价的对象存储中,以使操作更容易和更便宜。该应用程序被构建为单进程运行,并很容易演变成一个高可用的分布式系统。你可以通过并行化和查询的分片,在较大的日志工作负载上获得较高的查询性能 —— 有点像为你的日志设计的 MapReduce。

此外,这个功能是任何人都可以免费使用的。与其 Grafana 开放观测性平台一样,Grafana 实验室致力于将 Loki 打造成一个任何人都可以使用的全功能、全开放的日志聚合软件。

开始吧

我在树莓派上运行 Loki,并将我的 shell 历史记录异地存储在 S3 bucket 中。

当我按下 CTRL+R,Loki 的 LogCLI 命令行界面会发起几个批处理请求,传输至 fzf。下面是一个例子,上半部分显示的是树莓派上的 Loki 服务器日志。

 title=

准备试试?下面的指南将帮助你设置和运行 Loki,与你的 shell 历史记录集成。为了让本教程保持简洁,此设置将 Loki 本地运行在你的计算机上,并在文件系统上存储所有文件。

在 loki-shell 的 GitHub 版本库,你可以找到所有这一切,以及如何设置一个更复杂的安装的信息。

请注意,本教程不会改变任何围绕你的历史记录的现有行为,所以 你现有的 shell 历史记录命令和历史记录设置不会被触动。相反,这将用 Bash 中的 $PROMPT_COMMAND 和 Zsh 中的 precmd 复制命令历史记录到 Loki。在 CTRL+R 方面,它重载了 fzf 用来访问 CTRL+R 命令的函数。因此试一试是安全的,如果你觉得不喜欢它,只需按照 GitHub 版本库中的 卸载步骤 来删除所有痕迹。你的 shell 历史记录不会被触及。

第一步:安装 fzf

安装 fzf 有几种方法,但我更喜欢 Git 方法:

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

对所有的问题提示说 yes。

如果你已经安装了 fzf,确保你已经启用了键绑定(即,确保当你输入 CTRL+R 时,fzf 会弹出)。如果有必要的话,你可以重新运行 fzf 安装过程来启用键绑定。

第二步:安装 loki-shell

和 fzf 一样,loki-shell 也有一个 Git 版本库和安装脚本:

git clone --depth 1 https://github.com/slim-bean/loki-shell.git ~/.loki-shell
~/.loki-shell/install

首先,该脚本创建了 ~/.loki-shell 目录,所有的文件都将保存在该目录下(包括 Loki 数据),接下来,它将下载 Promtail、LogCLI 和 Loki 的二进制文件。

然后它会问:

Do you want to install Loki? ([y]/n)

如果你已经为 Loki-shell 运行了一个集中化的 Loki,你可以回答 n;然而,对于本教程,回答 y 或按回车键。

在本地运行 Loki 有两种方式:作为一个 Docker 镜像或作为一个单一的二进制文件(支持添加为 systemd 服务)。如果可以,我建议使用 Docker,因为我认为它稍微简化了操作,但这两者都可以工作。

使用 Docker 运行

将 Loki 作为 Docker 镜像运行:

[y] to run Loki in Docker, [n] to run Loki as a binary ([y]/n) y
Error: No such object: loki-shell
Error response from daemon: No such container: loki-shell
Error: No such container: loki-shell
54843ff3392f198f5cac51a6a5071036f67842bbc23452de8c3efa392c0c2e1e

如果这是你第一次运行这个安装程序,你可以忽略错误信息。这个脚本将停止和替换运行的 Loki 容器,如果版本不匹配,你可以重新运行此脚本升级 Loki。

就是这样!Loki 现在作为一个 Docker 容器运行了。

Loki 的数据将存储在 ~/.loki-shell/data 中。

由于带着 -restart=unless-stopped 标志运行该镜像,所以它会在系统重启时重启该服务,但如果你运行 docker stop loki-shell 则会保持停止。

(如果你使用的是 Docker,你可以跳到 “Shell 集成”一节。)

以二进制文件运行

在 Linux 系统上运行二进制文件的方法有很多。这个脚本可以安装一个 systemd 服务。如果你没有 systemd,你也可以使用二进制安装:

[y] to run Loki in Docker, [n] to run Loki as a binary ([y]/n) n

Run Loki with systemd? ([y]/n) n

This is as far as this script can take you
You will need to setup an auto-start for Loki
It can be run with this command: /home/username/.loki-shell/bin/loki -config.file=/home/username/.loki-shell/config/loki-binary-config.yaml

脚本会输出你需要用来运行 Loki 的命令,你可以自己设置一个 init 脚本或其他方法来自动启动它。

如果你想的话,你可以直接运行该命令,从你当前的 shell 运行 Loki。

如果你有 systemd,你可以选择让脚本安装 systemd 服务或显示出你自己运行它的命令:

Run Loki with systemd? ([y]/n) y

Installing the systemd service requires root permissions.
[y] to run these commands with sudo [n] to print out the commands and you can run them yourself. ([y]/n) n
sudo cp /home/ed/.loki-shell/config/loki-shell.service /etc/systemd/system/loki-shell.service
sudo systemctl daemon-reload
sudo systemctl enable loki-shell
sudo systemctl start loki-shell
Copy these commands and run them when the script finishes. (press enter to continue)
Shell 集成

无论你如何安装 Loki,你现在应该看到一个提示:

Enter the URL for your Loki server or press enter for default (http://localhost:4100)

如果你已经设置了一个中心化的 Loki,你应在这里输入其 URL。然而,这个演示只是使用了默认的 URL,所以你可以按回车键。

它会输出很多文本来解释添加到你的 ~.bashrc 或 ~.zshrc(或两者)的所有条目。

好了!

Finished. Restart your shell or reload config file.
   source ~/.bashrc  # bash
   source ~/.zshrc   # zsh

第三步:试试吧!

开始使用你的 shell,并使用 CTRL+R 查看你的命令。

打开多个终端窗口,在一个窗口中输入命令,在另一个窗口中输入 CTRL+R,你会看到你的命令立即可用。

另外,请注意,当你在终端之间切换并输入命令时,使用 CTRL+R 可以立即使用它们,但向上箭头的操作在终端之间不受影响。(如果你安装了 Oh My Zsh,情况可能就不一样了,因为它会自动将所有命令追加到历史记录中。)

多次按下 CTRL+R 可以在按时间排序和按相关性排序之间切换。

请注意,此配置将只显示当前主机的查询历史记录,即使你正在从多个主机向 Loki 发送 shell 数据。我认为默认情况下这是最合理的。如果你想改变这种行为,有很多地方可以调整;请参见 loki-shell 版本库了解更多。

它还安装了一个名为 hist 的别名。

alias hist="$HOME/.loki-shell/bin/logcli --addr=$LOKI_URL"

LogCLI 可以用来直接在 Loki 上查询和搜索你的历史,也允许你搜索其他主机。查看 LogCLI 的入门指南,了解更多关于查询的信息。

Loki 的日志查询语言(LogQL)提供了度量查询,可以让你做一些有趣的事情,例如,我可以看到在过去 30 天里我发出了多少次 kc 命令(我对 kubectl 的别名)。

 title=

额外增强

安装 Grafana,摆弄一下你的 shell 历史记录。

docker run -d -p 3000:3000 --name=grafana grafana/grafana

打开 Web 浏览器,访问 http://localhost:3000,使用默认的 admin/admin 用户名和密码登录。

在左边,导航到“ 配置 Configuration -> 数据源 Datasources ”,点击“ 添加数据源 Add Datasource ”按钮,然后选择 “Loki”。

对于 URL,你应该可以使用 http://localhost:4100(然而,在我的 WSL2 机器上,我必须使用计算机的实际 IP 地址)。

单击“ 保存并测试 Save and Test ”。你应该看到连接了数据源并找到了标签。

点击左边的“ 管理器 Explore ”图标,确保选择 Loki 数据源,并尝试这个查询:

{job="shell"}

如果发送 shell 命令的主机较多,可以使用“ 主机 Host ”标签将结果限制在某个主机上:

{job="shell", hostname="myhost"}.

你也可以用过滤表达式寻找特定的命令:

{job="shell"} |= "docker"

或者你可以从日志中探索度量的世界,看看你使用 shell 的频率:

rate({job="shell"}[1m])

 title=

想从一个事件中重建一个时间线?你可以通过特定的命令进行过滤,查看它的运行时间:

 title=

要想知道你还能做什么,并了解更多关于 Loki 查询语言的信息,请查看 LogQL 指南。

总结

更多的想法、故障排除和更新,请关注该 GitHub 版本库。这仍然是一项正在进行中的工作,所以请在那里报告发现的任何问题。

要了解更多关于 Loki 的信息,请查看文档、博客文章和该 GitHub 版本库,或者在 Grafana Cloud 中试用。


特别感谢我的同事 Jack Baldry 为这个想法播下的种子。我有 Loki 的知识来实现这个想法,但如果不是他的建议,我想我永远也不会做到这一点。


via: https://opensource.com/article/20/10/shell-history-loki-fzf

作者:Ed Welch 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出