mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-28 01:01:09 +08:00
commit
2e34a8f6f6
@ -1,22 +1,22 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13271-1.html)
|
||||
[#]: subject: (4 open source chat applications you should use right now)
|
||||
[#]: via: (https://opensource.com/article/20/4/open-source-chat)
|
||||
[#]: author: (Sudeshna Sur https://opensource.com/users/sudeshna-sur)
|
||||
|
||||
现如今你应当使用的四款开源聊天应用软件
|
||||
值得现在就去尝试的四款开源聊天应用软件
|
||||
======
|
||||
|
||||
现在,远程协作已作为一项必不可少的能力,让开源实时聊天成为你工具箱中必不可少的一部分吧。
|
||||
![Chat bubbles][1]
|
||||
> 现在,远程协作已作为一项必不可少的能力,让开源实时聊天成为你工具箱中必不可少的一部分吧。
|
||||
|
||||

|
||||
|
||||
清晨起床后,我们通常要做的第一件事是检查手机,看看是否有同事和朋友发来的重要信息。无论这是否是一个好习惯,但这种行为早已成为我们日常生活的一部分。
|
||||
|
||||
> 人是理性动物。他总能想出任何自己愿意相信的理由。
|
||||
> 人是理性动物。他可以为任何他想相信的事情想出一个理由。
|
||||
> – 阿纳托尔·法朗士
|
||||
|
||||
无论理由是否合理,我们每天都在使用的一系列的通讯工具,例如电子邮件、电话、网络会议工具或社交网络。甚至在 COVID-19 之前,居家办公就已经使这些通信工具成为我们生活中的重要部分。随着疫情出现,居家办公成为新常态,我们交流方式的方方面面正面临着前所未有的改变,这让这些工具变得不可或缺。
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
作为全球团队的一部分进行远程工作时,我们必须要有一个相互协作的环境。聊天应用软件在帮助我们保持相互联系中起着至关重要的作用。与电子邮件相比,聊天应用软件可提供与全球各地的同事快速、实时的通信。
|
||||
|
||||
考虑选择一款聊天应用软件需要考虑很多因素。为了帮助你选择最适合你的应用软件,在本文中,我将探讨四款开源聊天应用软件和一个开源视频通信工具(用于当你需要与同事“面对面”时),然后概述在高效的通讯应用软件中,你应当考虑的一些功能。
|
||||
选择一款聊天应用软件需要考虑很多因素。为了帮助你选择最适合你的应用软件,在本文中,我将探讨四款开源聊天应用软件,和一个当你需要与同事“面对面”时的开源视频通信工具,然后概述在高效的通讯应用软件中,你应当考虑的一些功能。
|
||||
|
||||
### 四款开源聊天软件
|
||||
|
||||
@ -33,64 +33,53 @@
|
||||
|
||||
![Rocket.Chat][2]
|
||||
|
||||
|
||||
[Rocket.Chat][3] 是一个综合性的通讯平台,其将频道分为公开房间(任何人都可以加入)和私有房间(仅受邀请)。你还可以直接将消息发送给已登录的人员。其能共享文档、链接、照片、视频和<ruby>动态图<rt>GIF</rt></ruby>,以及进行视频通话,并可以在平台中发送语音信息。
|
||||
|
||||
|
||||
|
||||
Rocket.Chat 是免费开源的软件,但是其独特之处在于其可自托管的聊天系统。你可以将其下载到你的服务器上,无论它是本地服务器或是在公有云上的虚拟专用服务器。
|
||||
|
||||
|
||||
Rocket.Chat 是自由开源软件,但是其独特之处在于其可自托管的聊天系统。你可以将其下载到你的服务器上,无论它是本地服务器或是在公有云上的虚拟专用服务器。
|
||||
|
||||
Rocket.Chat 是完全免费,其 [源码][4] 可在 Github 获得。许多开源项目都使用 Rocket.Chat 作为他们官方交流平台。该软件在持续不断的发展且不断更新和改进新功能。
|
||||
|
||||
|
||||
我最喜欢 Rocket.Chat 的地方是其能够根据用户需求来进行自定义操作,并且它使用机器学习来自动化处理,在用户通讯间实时翻译信息。你也可以下载适用于你移动设备的 Rocket.Chat,以便能随时随地使用。
|
||||
我最喜欢 Rocket.Chat 的地方是其能够根据用户需求来进行自定义操作,并且它使用机器学习在用户通讯间进行自动的、实时消息翻译。你也可以下载适用于你移动设备的 Rocket.Chat,以便能随时随地使用。
|
||||
|
||||
#### IRC
|
||||
|
||||
![IRC on WeeChat 0.3.5][5]
|
||||
|
||||
[Internet Relay Chat (IRC)][6] 是一款实时、基于文本格式的通信软件。尽管其是最古老的电子通讯形式之一,但在许多知名的软件项目中仍受欢迎。
|
||||
IRC(<ruby>[互联网中继聊天][6]<rt>Internet Relay Chat</rt></ruby>)是一款实时、基于文本格式的通信软件。尽管其是最古老的电子通讯形式之一,但在许多知名的软件项目中仍受欢迎。
|
||||
|
||||
IRC 频道是单独的聊天室。它可以让你在一个开放的频道中与多人进行聊天或与某人私下一对一聊天。如果频道名称以 `#` 开头,则可以假定它是官方的聊天室,而以 `##` 开头的聊天室通常是非官方的聊天室。
|
||||
|
||||
IRC 频道是单独的聊天室。它可以让你在一个开放的频道中与多人进行聊天或与某人私下一对一聊天。如果频道名称以 # 开头,则可以假定它是官方的聊天室,然而以 ## 开头的聊天室通常是非官方的聊天室。
|
||||
[上手 IRC][7] 很容易。你的 IRC 昵称可以让人们找到你,因此它必须是唯一的。但是,你可以完全自主地选择 IRC 客户端。如果你需要比标准 IRC 客户端更多功能的应用程序,则可以使用 [Riot.im][8] 连接到 IRC。
|
||||
|
||||
[使用 IRC][7] 是很容易上手。你的 IRC 昵称可以让人们找到你,因此它必须是唯一的。但是,你可以完全自主地选择 IRC 客户端。如果你需要比标准 IRC 客户端更多功能的应用程序,则可以使用 [Riot.im][8] 连接到 IRC。
|
||||
|
||||
考虑到它悠久的历史,你为什么还要继续使用 IRC?出于一个原因是,其仍是我们所依赖的许多免费和开源项目的家园。如果你想参于开源软件开发和社区,可以选择用 IRC。
|
||||
考虑到它悠久的历史,你为什么还要继续使用 IRC?出于一个原因是,其仍是我们所依赖的许多自由及开源项目的家园。如果你想参于开源软件开发和社区,可以选择用 IRC。
|
||||
|
||||
#### Zulip
|
||||
|
||||
![Zulip][9]
|
||||
|
||||
[Zulip][10] 是十分流行的群聊应用程序,它遵循基于话题线索的模式。在 Zulip 中,你可以订阅<ruby>流<rt>stream</rt></ruby>,就像在 IRC 频道或 Rocket.Chat 中一样。但是,每个 Zulip 流都会拥有一个唯一的<ruby>话题<rt>topic</rt></ruby>,该话题可帮助你以后查找对话,因此其更有条理。
|
||||
|
||||
[Zulip][10] 是遵循基于话题时间线模式且十分流行的群聊应用程序。在 Zulip 中,你可以订阅<ruby>流<rt>stream</rt></ruby>,就像在 IRC 频道或 Rocket.Chat 中一样。但是,每个 Zulip 流都会拥有一个唯一的<ruby>话题<rt>topic</rt></ruby>,该话题可帮助你以后查找对话,因此其更有条理。
|
||||
与其他平台一样,它支持表情符号、内嵌图片、视频和推特预览。它还支持 LaTeX 来分享数学公式或方程式、支持 Markdown 和语法高亮来分享代码。
|
||||
|
||||
Zulip 是跨平台的,并提供 API 用于编写你自己的程序。我特别喜欢 Zulip 的一点是它与 GitHub 的集成整合功能:如果我正在处理某个<ruby>议题<rt>issue</rt></ruby>,则可以使用 Zulip 的标记回链某个<ruby>拉取请求<rt>pull request</rt></ruby> ID。
|
||||
|
||||
与其他平台一样,它支持表情符号、图片、视频和推特预览。它还支持 LaTeX 共享数学公式或等式、Markdown 语法和共享代码的语法高亮。
|
||||
|
||||
|
||||
Zulip 是跨平台、并提供 API 用于编写你自己的程序。我特别喜欢 Zulip 的一点是它与 GitHub 的集成整合功能:如果我正在处理某个<ruby>问题<rt>issue</rt></ruby>,则可以使用 Zulip 的标记链接<ruby>拉回<rt>pull</rt></ruby>某个请求 ID。
|
||||
|
||||
Zulip是开源(你可以在 GitHub 上访问其[源码][11])并且免费使用,但是其已经为本地支持、[LDAP][12] 的集成整合和存储扩展提供了付费服务。
|
||||
Zulip 是开源的(你可以在 GitHub 上访问其 [源码][11])并且免费使用,但它有提供预置支持、[LDAP][12] 集成和更多存储类型的付费产品。
|
||||
|
||||
#### Let's Chat
|
||||
|
||||
![Let's Chat][13]
|
||||
|
||||
[Let's Chat][14] 是面向小型团队的自托管的聊天解决方案。它使用 Node.js 和 MongoDB 编写运行,只需鼠标点击几下即可将其部署到本地服务器或云服务器。它是免费且开源,可以在 GitHub 上查看其 [源码][15]。
|
||||
[Let's Chat][14] 是一个面向小型团队的自托管的聊天解决方案。它使用 Node.js 和 MongoDB 编写运行,只需鼠标点击几下即可将其部署到本地服务器或云服务器。它是自由开源软件,可以在 GitHub 上查看其 [源码][15]。
|
||||
|
||||
Let's Chat 与其他开源聊天工具的不同之处在于其企业功能:它支持 LDAP 和 [Kerberos][16] 身份验证。它还具有新用户想要的所有功能:你可以在历史记录中搜索过往消息,并使用 @username 之类的标签来标记人员。
|
||||
|
||||
我喜欢 Let's Chat 的地方是它拥有私人、受密码保护的聊天室、发送图片、GIPHY 支持和代码拷贝。它不断更新,并不断增加新功能。
|
||||
我喜欢 Let's Chat 的地方是它拥有私人的受密码保护的聊天室、发送图片、支持 GIPHY 和代码粘贴。它不断更新,不断增加新功能。
|
||||
|
||||
### 附加:开源视频聊天软件 Jitsi
|
||||
|
||||
![Jitsi][17]
|
||||
|
||||
有时,文字聊天还不够,你还可能需要与某人面谈。在这种情况下,如果不能选择面对面开会交流,那么视频聊天是最好的选择。[Jitsi][18] 是一个完全开源的,多平台且兼容 WebRTC 的视频会议工具。
|
||||
|
||||
有时,文字聊天还不够,你还可能需要与某人面谈。在这种情况下,如果不能选择面对面开会交流,那么视频聊天是最好的选择。[Jitsi][18] 是一个完全开源的、支持多平台且兼容 WebRTC 的视频会议工具。
|
||||
|
||||
Jitsi 从 Jitsi Desktop 开始,已经发展成为许多 [项目][19],包括 Jitsi Meet、Jitsi Videobridge、jibri 和 libjitsi,并且每个项目都在 GitHub 上开放了 [源码][20]。
|
||||
|
||||
@ -106,10 +95,10 @@ Jitsi 是安全且可扩展的,并支持诸如<ruby>联播<rt>simulcast</rt></
|
||||
* 最好寻找一种功能强大且能让人们以各种方式使用它的工具。
|
||||
* 如果与你所使用的工具有进行集成整合的话,可以重点考虑。一些工具与 GitHub 或 GitLab 以及某些应用程序具有良好的无缝衔接,这将是一个非常有用的功能。
|
||||
* 有能托管到云主机的工具将十分方便。
|
||||
* 应考虑到聊天服务的安全性。对于许多组织和个人而言,能在个人服务器上进行托管服务是不可或缺的。
|
||||
* 应考虑到聊天服务的安全性。在私人服务器上托管服务的能力对许多组织和个人来说是必要的。
|
||||
* 最好选择那些具有丰富的隐私设置,并拥有私人聊天室和公共聊天室的通讯工具。
|
||||
|
||||
由于人们比以往任何时候都更加依赖在线服务,因此拥有备用的通讯平台是明智之举。例如,如果一个项目正在使用 Rocket.Chat,则必要之时,它还应具有跳转到 IRC 的能力。由于这些软件在不断更新,你可能会发现自己已经连接到多个频道,因此集成整合其他应用将变得非常有价值。
|
||||
由于人们比以往任何时候都更加依赖在线服务,因此拥有备用的通讯平台是明智之举。例如,如果一个项目正在使用 Rocket.Chat,则必要之时,它还应具有跳转到 IRC 的能力。由于这些软件在不断更新,你可能会发现自己已经连接到多个渠道,因此集成整合其他应用将变得非常有价值。
|
||||
|
||||
在各种可用的开源聊天服务中,你喜欢和使用哪些?这些工具又是如何帮助你进行远程办公?请在评论中分享你的想法。
|
||||
|
||||
@ -120,7 +109,7 @@ via: https://opensource.com/article/20/4/open-source-chat
|
||||
作者:[Sudeshna Sur][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wyxplus](https://github.com/wyxplus)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
68
published/20210222 5 benefits of choosing Linux.md
Normal file
68
published/20210222 5 benefits of choosing Linux.md
Normal file
@ -0,0 +1,68 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (max27149)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13284-1.html)
|
||||
[#]: subject: (5 benefits of choosing Linux)
|
||||
[#]: via: (https://opensource.com/article/21/2/linux-choice)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
选择 Linux 的五大好处
|
||||
======
|
||||
|
||||
> Linux 的一大优点是多样化选择,选择激发了用户之间自由分享想法和解决方案。Linux 将如何激发你为这个社区做出贡献呢?
|
||||
|
||||

|
||||
|
||||
到了 2021 年,人们比以往任何时候都更有理由喜欢 Linux。在本系列中,我将分享 21 个使用 Linux 的理由。本文讨论选择 Linux 带来的好处。
|
||||
|
||||
_选择_ 是 Linux 中被误解最深的特性之一。这种误解从可被选择的 Linux 发行版数量就开始了。Distrowatch.org 报告了数百种可用的和活跃的 Linux 发行版。当然,在这些发行版当中,许多都是业余爱好项目或者针对某些晦涩需求的特别版。因为是开源的,所以实际上,任何人都可以“重新设计”或“重新混搭”现有的 Linux 发行版,赋予一个新名称,提供一个新的默认墙纸,然后称其为自己的作品。尽管这些修改似乎微不足道,但我认为这显示了 Linux 的一些特别之处。
|
||||
|
||||
### 灵感
|
||||
|
||||
Linux 似乎一直在启迪着人们,从了解它的那一刻起,到创造出自己的版本。
|
||||
|
||||
有数十家公司花费数百万美元来从他们自己的产品中获取灵感。商业技术广告试着强硬地说服你,只要你购买某种产品,你就会与所关心的人建立更多的联系,更具创造力、更加充满活力。这些广告用 4k 视频拍摄,焦点柔和,并在欢快振奋的音乐节奏下播放,试图说服人们不仅购买而且还要支持和宣传该公司的产品。
|
||||
|
||||
当然,Linux 基本没有营销预算,因为 Linux 是个形形色色的大集合,*没有固定实体*。然而,当人们发现它的存在时候,他们似乎就被启发着去构建属于自己的版本。
|
||||
|
||||
灵感的数量很难量化,但是它显然很有价值,要不然那些公司不会花钱来尝试创造灵感。
|
||||
|
||||
### 革新
|
||||
|
||||
灵感,无论给它标价有多难,它都因它的生产创造而有价值。许多 Linux 用户受启发来为各种奇怪问题定制解决方案。我们解决的大多数问题,对于其他大部分人而言,似乎微不足道:也许你使用 [Seeed 微控制器][2] 来监控番茄植株土壤的水分含量;或者你使用脚本来搜索 Python 软件包的索引,因为你总是会忘记每天导入的库的名称;或者设置了自动清理下载文件夹,因为将文件图标拖进回收站这个活儿干太多了。不管你在使用 Linux 的过程中,为自己解决过什么问题,都是这个平台包含的特性之一,你被这个正在运行中的开放的技术所启发,使其更好地服务于你自己。
|
||||
|
||||
### 开放策略
|
||||
|
||||
诚然,不论是灵感,还是创新,都不能算 Linux 独有的属性。其他平台也确实让我们激发灵感,我们也以或大或小的方式进行创新。运算能力已在很大程度上拉平了操作系统的竞争领域,你在一个操作系统上可以完成的任何事,在另一个操作系统上或许都能找到对应的方法来完成。
|
||||
|
||||
但是,许多用户发现,Linux 操作系统保留了坚定的开放策略,当你尝试可能无人想到过的尝试时,Linux 不会阻挡你。这种情况不会也不可能发生在专有的操作系统上,因为无法进入系统层级的某些区域,因为它们本身就是被设计为不开放源码的。有各种独断的封锁。当你完全按照操作系统的期望进行操作时,你不会碰到那些看不见的墙,但是当你心里想着要做一些只对你有意义的事情的时候,你的系统环境可能变得无从适应。
|
||||
|
||||
### 小小的选择,大大的意义
|
||||
|
||||
并非所有创新都是大的或重要的,但总的来说,它们带来的变化并不小。如今,数百万用户的那些疯狂想法在 Linux 的各个部分中愈发显现。它们存在于 KDE 或 GNOME 桌面的工作方式中,存在于 [31 种不同的文本编辑器][3] 中 —— 每一种都有人喜爱,存在于不计其数的浏览器插件和多媒体应用程序中,存在于文件系统和扩展属性中,以及数以百万行计的 Linux 内核代码中。而且,如果上述功能中的哪怕仅其中一项,能让你每天额外节省下一小时时间,陪家人、朋友或用在自己的业余爱好上,那么按照定义,套用一句老话就是,“改变生活”。
|
||||
|
||||
### 在社区中交流
|
||||
|
||||
开源的重要组成部分之一是共享工作。共享代码是开源软件中显而易见的、普遍流行的事务,但我认为,分享,可不仅仅是在 Gitlab 做一次提交那么简单。当人们彼此分享着自己的奇思妙想,除了获得有用的代码贡献作为回报外,再无其他动机,我们都认为这是一种馈赠。这与你花钱从某公司购买软件时的感觉非常不同,甚至与得到某公司对外分享他们自己生产的开源代码时的感觉也有很大不同。开源的实质是,由全人类创造,服务于全人类。当知识和灵感可以被自由地分享时,人与人之间就建立了连接,这是市场营销活动无法复制的东西,我认为我们都认同这一点。
|
||||
|
||||
### 选择
|
||||
|
||||
Linux 并不是唯一拥有很多选择的平台。无论使用哪种操作系统,你都可以找到针对同一问题的多种解决方案,尤其是在深入研究开源软件的时候。但是,Linux 明显的选择水准指示了推动 Linux 前进的因素:诚邀协作。在 Linux 上,有些创造会很快消失,有些会在你家用电脑中保留数年 —— 即便只是执行一些不起眼的自动化任务,然而有一些则非常成功,以至于被其他系统平台借鉴并变得司空见惯。没关系,无论你在 Linux 上创作出什么,都请毫不犹豫地把它加入千奇百怪的选择之中,你永远都不知道它可能会激发到谁的灵感。
|
||||
|
||||
---
|
||||
|
||||
via: https://opensource.com/article/21/2/linux-choice
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[max27149](https://github.com/max27149)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/yearbook-haff-rx-linux-file-lead_0.png?itok=-i0NNfDC (Hand putting a Linux file folder into a drawer)
|
||||
[2]: https://opensource.com/article/19/12/seeeduino-nano-review
|
||||
[3]: https://opensource.com/article/21/1/text-editor-roundup
|
160
published/20210225 How to use the Linux anacron command.md
Normal file
160
published/20210225 How to use the Linux anacron command.md
Normal file
@ -0,0 +1,160 @@
|
||||
[#]: subject: (How to use the Linux anacron command)
|
||||
[#]: via: (https://opensource.com/article/21/2/linux-automation)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13270-1.html)
|
||||
|
||||
如何使用 Linux anacron 命令
|
||||
======
|
||||
|
||||
> 与其手动执行重复性的任务,不如让 Linux 为你做。
|
||||
|
||||

|
||||
|
||||
在 2021 年,人们有更多的理由喜欢 Linux。在这个系列中,我将分享使用 Linux 的 21 个不同理由。自动化是使用 Linux 的最佳理由之一。
|
||||
|
||||
我最喜欢 Linux 的一个原因是它愿意为我做工作。我不想执行重复性的任务,这些任务会占用我的时间,或者容易出错,或者我可能会忘记,我安排 Linux 为我做这些工作。
|
||||
|
||||
### 为自动化做准备
|
||||
|
||||
“自动化”这个词既让人望而生畏,又让人心动。我发现用模块化的方式来处理它是有帮助的。
|
||||
|
||||
#### 1、你想实现什么?
|
||||
|
||||
首先,要知道你想产生什么结果。你是要给图片加水印吗?从杂乱的目录中删除文件?执行重要数据的备份?为自己明确定义任务,这样你就知道自己的目标是什么。如果有什么任务是你发现自己每天都在做的,甚至一天一次以上,那么它可能是自动化的候选者。
|
||||
|
||||
#### 2、学习你需要的应用
|
||||
|
||||
将大的任务分解成小的组件,并学习如何手动但以可重复和可预测的方式产生每个结果。在 Linux 上可以做的很多事情都可以用脚本来完成,但重要的是要认识到你当前的局限性。学习如何自动调整几张图片的大小,以便可以方便地通过电子邮件发送,与使用机器学习为你的每周通讯生成精心制作的艺术品之间有天壤之别。有的事你可以在一个下午学会,而另一件事可能要花上几年时间。然而,我们都必须从某个地方开始,所以只要从小做起,并时刻注意改进的方法。
|
||||
|
||||
#### 3、自动化
|
||||
|
||||
在 Linux 上使用一个自动化工具来定期实现它。这就是本文介绍的步骤!
|
||||
|
||||
要想自动化一些东西,你需要一个脚本来自动化一个任务。在测试时,最好保持简单,所以本文自动化的任务是在 `/tmp` 目录下创建一个名为 `hello` 的文件。
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
touch /tmp/hello
|
||||
```
|
||||
|
||||
将这个简单的脚本复制并粘贴到一个文本文件中,并将其命名为 `example`。
|
||||
|
||||
### Cron
|
||||
|
||||
每个安装好的 Linux 系统都会有的内置自动化解决方案就是 cron 系统。Linux 用户往往把 cron 笼统地称为你用来安排任务的方法(通常称为 “cron 作业”),但有多个应用程序可以提供 cron 的功能。最通用的是 [cronie][2];它的优点是,它不会像历史上为系统管理员设计的 cron 应用程序那样,假设你的计算机总是开着。
|
||||
|
||||
验证你的 Linux 发行版提供的是哪个 cron 系统。如果不是 cronie,你可以从发行版的软件仓库中安装 cronie。如果你的发行版没有 cronie 的软件包,你可以使用旧的 anacron 软件包来代替。`anacron` 命令是包含在 cronie 中的,所以不管你是如何获得它的,你都要确保在你的系统上有 `anacron` 命令,然后再继续。anacron 可能需要管理员 root 权限,这取决于你的设置。
|
||||
|
||||
```
|
||||
$ which anacron
|
||||
/usr/sbin/anacron
|
||||
```
|
||||
|
||||
anacron 的工作是确保你的自动化作业定期执行。为了做到这一点,anacron 会检查找出最后一次运行作业的时间,然后检查你告诉它运行作业的频率。
|
||||
|
||||
假设你将 anacron 设置为每五天运行一次脚本。每次你打开电脑或从睡眠中唤醒电脑时,anacron都会扫描其日志以确定是否需要运行作业。如果一个作业在五天或更久之前运行,那么 anacron 就会运行该作业。
|
||||
|
||||
### Cron 作业
|
||||
|
||||
许多 Linux 系统都捆绑了一些维护工作,让 cron 来执行。我喜欢把我的工作与系统工作分开,所以我在我的主目录中创建了一个目录。具体来说,有一个叫做 `~/.local` 的隐藏文件夹(“local” 的意思是它是为你的用户账户定制的,而不是为你的“全局”计算机系统定制的),所以我创建了子目录 `etc/cron.daily` 来作为 cron 在我的系统上的家目录。你还必须创建一个 spool 目录来跟踪上次运行作业的时间。
|
||||
|
||||
```
|
||||
$ mkdir -p ~/.local/etc/cron.daily ~/.var/spool/anacron
|
||||
```
|
||||
|
||||
你可以把任何你想定期运行的脚本放到 `~/.local/etc/cron.daily` 目录中。现在把 `example` 脚本复制到目录中,然后 [用 chmod 命令使其可执行][3]。
|
||||
|
||||
```
|
||||
$ cp example ~/.local/etc/cron.daily
|
||||
# chmod +x ~/.local/etc/cron.daily/example
|
||||
```
|
||||
|
||||
接下来,设置 anacron 来运行位于 `~/.local/etc/cron.daily` 目录下的任何脚本。
|
||||
|
||||
### anacron
|
||||
|
||||
默认情况下,cron 系统的大部分内容都被认为是系统管理员的领域,因为它通常用于重要的底层任务,如轮换日志文件和更新证书。本文演示的配置是为普通用户设置个人自动化任务而设计的。
|
||||
|
||||
要配置 anacron 来运行你的 cron 作业,请在 `/.local/etc/anacrontab` 创建一个配置文件:
|
||||
|
||||
```
|
||||
SHELL=/bin/sh
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
1 0 cron.mine run-parts /home/tux/.local/etc/cron.daily/
|
||||
```
|
||||
|
||||
这个文件告诉 anacron 每到新的一天(也就是每日),延迟 0 分钟后,就运行(`run-parts`)所有在 `~/.local/etc/cron.daily` 中找到的可执行脚本。有时,会使用几分钟的延迟,这样你的计算机就不会在你登录后就被所有可能的任务冲击。不过这个设置适合测试。
|
||||
|
||||
`cron.mine` 值是进程的一个任意名称。我称它为 `cron.mine`,但你也可以称它为 `cron.personal` 或 `penguin` 或任何你想要的名字。
|
||||
|
||||
验证你的 `anacrontab` 文件的语法:
|
||||
|
||||
```
|
||||
$ anacron -T -t ~/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
沉默意味着成功。
|
||||
|
||||
### 在 .profile 中添加 anacron
|
||||
|
||||
最后,你必须确保 anacron 以你的本地配置运行。因为你是以普通用户而不是 root 用户的身份运行 anacron,所以你必须将它引导到你的本地配置:告诉 anacron 要做什么的 `anacrontab` 文件,以及帮助 anacron 跟踪每一个作业最后一次执行是多少天的 spool 目录:
|
||||
|
||||
```
|
||||
anacron -fn -t /home/tux/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
`-fn` 选项告诉 anacron *忽略* 时间戳,这意味着你强迫它无论如何都要运行你的 cron 作业。这完全是为了测试的目的。
|
||||
|
||||
### 测试你的 cron 作业
|
||||
|
||||
现在一切都设置好了,你可以测试作业了。从技术上讲,你可以在不重启的情况下进行测试,但重启是最有意义的,因为这就是设计用来处理中断和不规则的登录会话的。花点时间重启电脑、登录,然后寻找测试文件:
|
||||
|
||||
```
|
||||
$ ls /tmp/hello
|
||||
/tmp/hello
|
||||
```
|
||||
|
||||
假设文件存在,那么你的示例脚本已经成功执行。现在你可以从 `~/.profile` 中删除测试选项,留下这个作为你的最终配置。
|
||||
|
||||
```
|
||||
anacron -t /home/tux/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
### 使用 anacron
|
||||
|
||||
你已经配置好了你的个人自动化基础设施,所以你可以把任何你想让你的计算机替你管理的脚本放到 `~/.local/etc/cron.daily` 目录下,它就会按计划运行。
|
||||
|
||||
这取决于你希望作业运行的频率。示例脚本是每天执行一次。很明显,这取决于你的计算机在任何一天是否开机和醒着。如果你在周五使用电脑,但把它设置在周末,脚本就不会在周六和周日运行。然而,在周一,脚本会执行,因为 anacron 会知道至少有一天已经过去了。你可以在 `~/.local/etc` 中添加每周、每两周、甚至每月的目录,以安排各种各样的间隔。
|
||||
|
||||
要添加一个新的时间间隔:
|
||||
|
||||
1. 在 `~/.local/etc` 中添加一个目录(例如 `cron.weekly`)。
|
||||
2. 在 `~/.local/etc/anacrontab` 中添加一行,以便在新目录下运行脚本。对于每周一次的间隔,其配置如下。`7 0 cron.mine run-parts /home/tux/.local/etc/cron.weekly/`(`0` 的值可以选择一些分钟数,以适当地延迟脚本的启动)。
|
||||
3. 把你的脚本放在 `cron.weekly` 目录下。
|
||||
|
||||
欢迎来到自动化的生活方式。它不会让人感觉到,但你将会变得更有效率。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/2/linux-automation
|
||||
|
||||
作者:[Seth Kenlon][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://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
|
||||
[2]: https://github.com/cronie-crond/cronie
|
||||
[3]: https://opensource.com/article/19/8/linux-chmod-command
|
73
published/20210303 5 signs you might be a Rust programmer.md
Normal file
73
published/20210303 5 signs you might be a Rust programmer.md
Normal file
@ -0,0 +1,73 @@
|
||||
[#]: subject: (5 signs you might be a Rust programmer)
|
||||
[#]: via: (https://opensource.com/article/21/3/rust-programmer)
|
||||
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13280-1.html)
|
||||
|
||||
你可能是 Rust 程序员的五个迹象
|
||||
======
|
||||
|
||||
> 在我学习 Rust 的过程中,我注意到了 Rust 一族的一些常见行为。
|
||||
|
||||

|
||||
|
||||
我是最近才 [皈依 Rust][2] 的,我大约在是 2020 年 4 月底开始学习的。但是,像许多皈依者一样,我还是一个热情的布道者。说实话,我也不是一个很好的 Rust 人,因为我的编码风格不是很好,我写的也不是特别符合 Rust 习惯。我猜想这一方面是因为我在写大量代码之前还没有没有真正学完 Rust(其中一些代码又困扰了我),另一方面是因为我并不是那么优秀的程序员。
|
||||
|
||||
但我喜欢 Rust,你也应该喜欢吧。它很友好,比 C 或 C++ 更友好;它为低级系统任务做好了准备,这比 Python 做的更好;而且结构良好,这要超过 Perl;而且,最重要的是,从设计层面开始,它就是完全开源的,这要比 Java 那些语言好得多。
|
||||
|
||||
尽管我缺乏专业知识,但我注意到了一些我认为是许多 Rust 爱好者和程序员的共同点。如果你对以下五个迹象点头(其中第一个迹象是由最近的一些令人兴奋的新闻引发的),那么你也可能是一个 Rust 程序员。
|
||||
|
||||
### 1、“基金会”一词会使你兴奋
|
||||
|
||||
对于 Rust 程序员来说,“基金会”一词将不再与<ruby>艾萨克·阿西莫夫<rt>Isaac Asimov</rt></ruby>关联在一起,而是与新成立的 [Rust 基金会][3] 关联。微软、华为、谷歌、AWS 和Mozilla 为该基金会提供了董事(大概也提供了大部分初始资金),该基金会将负责该语言的各个方面,“预示着 Rust 成为企业生产级技术的到来”,[根据临时执行董事][4] Ashley Williams 说。(顺便说一句,很高兴看到一位女士领导这样一项重大的行业计划。)
|
||||
|
||||
该基金会似乎致力于维护 Rust 的理念,并确保每个人都有参与的机会。在许多方面,Rust 都是开源项目的典型示例。并不是说它是完美的(无论是语言还是社区),而是因为似乎有足够的爱好者致力于维护高参与度、低门槛的社区方式,我认为这是许多开源项目的核心。我强烈欢迎此举,我认为这只会帮助促进 Rust 在未来数年和数月内的采用和成熟。
|
||||
|
||||
### 2、你会因为新闻源中提到 Rust 游戏而感到沮丧
|
||||
|
||||
还有一款和电脑有关的东西,也叫做“Rust”,它是一款“只限多玩家生存类的电子游戏”。它比 Rust 这个语言更新一些(2013 年宣布,2018 年发布),但我曾经在搜索 Rust 相关的内容时,犯了一个错误,用这个名字搜索了游戏。互联网络就是这样的,这意味着我的新闻源现在被这个另类的 Rust 野兽感染了,我现在会从它的影迷和公关人员那里随机得到一些更新消息。这是个低调的烦恼,但我很确定在 Rust(语言)社区中并不是就我一个人这样。我强烈建议,如果你确实想了解更多关于这个计算世界的后起之秀的信息,你可以使用一个提高隐私(我拒绝说 "保护隐私")的 [开源浏览器][5] 来进行研究。
|
||||
|
||||
### 3、“不安全”这个词会让你感到恐惧。
|
||||
|
||||
Rust(语言,再次强调)在帮助你做**正确的事情**™方面做得非常好,当然,在内存安全方面,这是 C 和 C++ 内部的主要关注点(不是因为不可能做到,而是因为真的很难持续正确)。Dave Herman 在 2016 年写了一篇文章《[Safety is Rust's fireflower][6]》,讲述了为什么安全是 Rust 语言的一个积极属性。安全性(内存、类型安全)可能并不赏心悦目,但随着你写的 Rust 越多,你就会习惯并感激它,尤其是当你参与任何系统编程时,这也是 Rust 经常擅长的地方。
|
||||
|
||||
现在,Rust 并不能阻止你做**错误的事情**™,但它确实通过让你使用 `unsafe` 关键字,让你在希望超出安全边界的时候做出一个明智的决定。这不仅对你有好处,因为它(希望)会让你非常、非常仔细地思考你在任何使用它的代码块中放入了什么;它对任何阅读你的代码的人也有好处,这是一个触发词,它能让任何不太清醒的 Rust 人至少可以稍微打起精神,在椅子上坐直,然后想:“嗯,这里发生了什么?我需要特别注意。”如果幸运的话,读你代码的人也许能想到重写它的方法,使它利用到 Rust 的安全特性,或者至少减少提交和发布的不安全代码的数量。
|
||||
|
||||
### 4、你想知道为什么没有 `?;`、`{:?}` 、`::<>` 这样的表情符号
|
||||
|
||||
人们喜欢(或讨厌)涡轮鱼(`::<>`),但在 Rust 代码中你经常还会看到其他的语义结构。特别是 `{:?}` (用于字符串格式化)和 `?;`(`?` 是向调用栈传播错误的一种方式,`;` 则是行/块的结束符,所以你经常会看到它们在一起)。它们在 Rust 代码中很常见,你只需边走边学,边走边解析,而且它们也很有用,我有时会想,为什么它们没有被纳入到正常对话中,至少可以作为表情符号。可能还有其他的。你有什么建议?
|
||||
|
||||
### 5、Clippy 是你的朋友(而不是一个动画回形针)
|
||||
|
||||
微软的动画回形针 Clippy 可能是 Office 用户很快就觉得讨厌的“功能”,并成为许多 [模因][7] 的起点。另一方面,`cargo clippy` 是那些 [很棒的 Cargo 命令][8] 之一,应该成为每个 Rust 程序员工具箱的一部分。Clippy 是一个语言<ruby>整洁器<rt>Linter</rt></ruby>,它可以帮助改进你的代码,使它更干净、更整洁、更易读、更惯用,让你与同事或其他人分享 Rust 代码时,不会感到尴尬。Cargo 可以说是让 “Clippy” 这个名字恢复了声誉,虽然我不会选择给我的孩子起这个名字,但现在每当我在网络上遇到这个词的时候,我不会再有一种不安的感觉。
|
||||
|
||||
* * *
|
||||
|
||||
这篇文章最初发表在 [Alice, Eve, and Bob] [9]上,经作者许可转载。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/rust-programmer
|
||||
|
||||
作者:[Mike Bursell][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://opensource.com/users/mikecamel
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_OSDC_IntroOS_520x292_FINAL.png?itok=woiZamgj (name tag that says hello my name is open source)
|
||||
[2]: https://opensource.com/article/20/6/why-rust
|
||||
[3]: https://foundation.rust-lang.org/
|
||||
[4]: https://foundation.rust-lang.org/posts/2021-02-08-hello-world/
|
||||
[5]: https://opensource.com/article/19/7/open-source-browsers
|
||||
[6]: https://www.thefeedbackloop.xyz/safety-is-rusts-fireflower/
|
||||
[7]: https://knowyourmeme.com/memes/clippy
|
||||
[8]: https://opensource.com/article/20/11/commands-rusts-cargo
|
||||
[9]: https://aliceevebob.com/2021/02/09/5-signs-that-you-may-be-a-rust-programmer/
|
@ -0,0 +1,94 @@
|
||||
[#]: subject: (Plausible: Privacy-Focused Google Analytics Alternative)
|
||||
[#]: via: (https://itsfoss.com/plausible/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13283-1.html)
|
||||
|
||||
Plausible:注重隐私的 Google Analytics 替代方案
|
||||
======
|
||||
|
||||

|
||||
|
||||
[Plausible][1]是一款简单的、对隐私友好的分析工具。它可以帮助你分析独立访客数量、页面浏览量、跳出率和访问时间。
|
||||
|
||||
如果你有一个网站,你可能会理解这些术语。作为一个网站所有者,它可以帮助你了解你的网站是否随着时间的推移获得更多的访问者,流量来自哪里,如果你对这些事情有一定的了解,你可以努力改进你的网站,以获得更多的访问量。
|
||||
|
||||
说到网站分析,统治这个领域的一个服务就是谷歌的免费工具 Google Analytics。就像 Google 是事实上的搜索引擎一样,Google Analytics 是事实上的分析工具。但你不必再忍受它,尤其是当你无法信任大科技公司使用你和你的网站访问者的数据的时候。
|
||||
|
||||
Plausible 让你摆脱 Google Analytics 的束缚,我将在本文中讨论这个开源项目。
|
||||
|
||||
请注意,如果你从来没有管理过网站或对分析感兴趣,文章中的一些技术术语可能对你来说是陌生的。
|
||||
|
||||
### Plausible 是隐私友好的网站分析工具
|
||||
|
||||
Plausible 使用的分析脚本是非常轻量级的,大小不到 1KB。
|
||||
|
||||
其重点在于保护隐私,因此你可以在不影响访客隐私的情况下获得有价值且可操作的统计数据。Plausible 是为数不多的不需要 cookie 横幅或 GDP 同意的分析工具之一,因为它在隐私方面已经符合 [GDPR 标准][2]。这是超级酷的。
|
||||
|
||||
在功能上,它没有 Google Analytics 那样的粒度和细节。Plausible 靠的是简单。它显示的是你过去 30 天的流量统计图。你也可以切换到实时视图。
|
||||
|
||||
![][3]
|
||||
|
||||
你还可以看到你的流量来自哪里,以及你网站上的哪些页面访问量最大。来源也可以显示 UTM 活动。
|
||||
|
||||
![][4]
|
||||
|
||||
你还可以选择启用 GeoIP 来了解网站访问者的地理位置。你还可以检查有多少访问者使用桌面或移动设备访问你的网站。还有一个操作系统的选项,正如你所看到的,[Linux Handbook][5] 有 48% 的访问者来自 Windows 设备。很奇怪,对吧?
|
||||
|
||||
![][6]
|
||||
|
||||
显然,提供的数据与 Google Analytics 的数据相差甚远,但这是有意为之。Plausible 意图是为你提供简单的模式。
|
||||
|
||||
### 使用 Plausible:选择付费托管或在你的服务器上自行托管
|
||||
|
||||
使用 Plausible 有两种方式:注册他们的官方托管服务。你必须为这项服务付费,这最终会帮助 Plausible 项目的发展。它们有 30 天的试用期,甚至不需要你这边提供任何支付信息。
|
||||
|
||||
定价从每月 1 万页浏览量 6 美元开始。价格会随着页面浏览量的增加而增加。你可以在 Plausible 网站上计算价格。
|
||||
|
||||
- [Plausible 价格][7]
|
||||
|
||||
你可以试用 30 天,看看你是否愿意向 Plausible 开发者支付服务费用,并拥有你的数据。
|
||||
|
||||
如果你觉得定价不合理,你可以利用 Plausible 是开源的优势,自己部署。如果你有兴趣,请阅读我们的 [使用 Docker 自助托管 Plausible 实例的深度指南][8]。
|
||||
|
||||
我们自行托管 Plausible。我们的 Plausible 实例添加了我们的三个网站。
|
||||
|
||||
![Plausble dashboard for It’s FOSS websites][9]
|
||||
|
||||
如果你维护一个开源项目的网站,并且想使用 Plausible,你可以通过我们的 [High on Cloud 项目][10] 联系我们。通过 High on Cloud,我们帮助小企业在其服务器上托管和使用开源软件。
|
||||
|
||||
### 总结
|
||||
|
||||
如果你不是超级痴迷于数据,只是想快速了解网站的表现,Plausible 是一个不错的选择。我喜欢它,因为它是轻量级的,而且遵守隐私。这也是我在 Linux Handbook,我们 [教授 Linux 服务器相关的门户网站][11] 上使用它的主要原因。
|
||||
|
||||
总的来说,我对 Plausible 相当满意,并向其他网站所有者推荐它。
|
||||
|
||||
你也经营或管理一个网站吗?你是用什么工具来做分析,还是根本不关心这个?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/plausible/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://plausible.io/
|
||||
[2]: https://gdpr.eu/compliance/
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-graph-lhb.png?resize=800%2C395&ssl=1
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-stats-lhb-2.png?resize=800%2C333&ssl=1
|
||||
[5]: https://linuxhandbook.com/
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-geo-ip-stats.png?resize=800%2C331&ssl=1
|
||||
[7]: https://plausible.io/#pricing
|
||||
[8]: https://linuxhandbook.com/plausible-deployment-guide/
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-analytics-for-itsfoss.png?resize=800%2C231&ssl=1
|
||||
[10]: https://highoncloud.com/
|
||||
[11]: https://linuxhandbook.com/about/#ethical-web-portal
|
@ -3,14 +3,16 @@
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13268-1.html)
|
||||
|
||||
用 Lua 操作文件中的数据
|
||||
======
|
||||
了解 Lua 如何处理数据的读写。
|
||||
![Person standing in front of a giant computer screen with numbers, data][1]
|
||||
|
||||
> 了解 Lua 如何处理数据的读写。
|
||||
|
||||

|
||||
|
||||
有些数据是临时的,存储在 RAM 中,只有在应用运行时才有意义。但有些数据是要持久的,存储在硬盘上供以后使用。当你编程时,无论是简单的脚本还是复杂的工具套件,通常都需要读取和写入文件。有时文件可能包含配置选项,而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言都会以不同的方式处理这项任务,本文将演示如何使用 Lua 处理文件数据。
|
||||
|
||||
@ -22,8 +24,7 @@
|
||||
|
||||
### 用 Lua 读取文件
|
||||
|
||||
Lua 使用 `io` 库进行数据输入和输出。下面的例子创建了一个名为 `ingest` 的函数来从文件中读取数据,然后用 `:read` 函数进行解析。在 Lua 中打开一个文件时,有几种模式可以启用。因为我只需要从这个文件中读取数据,所以我使用 `r`(代表”读“)模式:
|
||||
|
||||
Lua 使用 `io` 库进行数据输入和输出。下面的例子创建了一个名为 `ingest` 的函数来从文件中读取数据,然后用 `:read` 函数进行解析。在 Lua 中打开一个文件时,有几种模式可以启用。因为我只需要从这个文件中读取数据,所以我使用 `r`(代表“读”)模式:
|
||||
|
||||
```
|
||||
function ingest(file)
|
||||
@ -37,7 +38,7 @@ myfile=ingest("example.txt")
|
||||
print(myfile)
|
||||
```
|
||||
|
||||
在这段代码中,注意到变量 `myfile` 是为了触发 `ingest` 函数而创建的,因此,它接收该函数返回的任何内容。`ingest` 函数返回文件的行数(从一个称为 `lines` 的变量中)。当最后一步打印 `myfile` 变量的内容时,文件的行数就会出现在终端中。
|
||||
在这段代码中,注意到变量 `myfile` 是为了触发 `ingest` 函数而创建的,因此,它接收该函数返回的任何内容。`ingest` 函数返回文件的行数(从一个称为 `lines` 的变量中0。当最后一步打印 `myfile` 变量的内容时,文件的行数就会出现在终端中。
|
||||
|
||||
如果文件 `example.txt` 中包含了配置选项,那么我会写一些额外的代码来解析这些数据,可能会使用另一个 Lua 库,这取决于配置是以 INI 文件还是 YAML 文件或其他格式存储。如果数据是 SVG 图形,我会写额外的代码来解析 XML,可能会使用 Lua 的 SVG 库。换句话说,你的代码读取的数据一旦加载到内存中,就可以进行操作,但是它们都需要加载 `io` 库。
|
||||
|
||||
@ -45,7 +46,6 @@ print(myfile)
|
||||
|
||||
无论你是要存储用户用你的应用创建的数据,还是仅仅是关于用户在应用中做了什么的元数据(例如,游戏保存或最近播放的歌曲),都有很多很好的理由来存储数据供以后使用。在 Lua 中,这是通过 `io` 库实现的,打开一个文件,将数据写入其中,然后关闭文件:
|
||||
|
||||
|
||||
```
|
||||
function exgest(file)
|
||||
local f = io.open(file, "a")
|
||||
@ -63,13 +63,11 @@ exgest("example.txt")
|
||||
|
||||
在 Lua 中打开文件时,有一些保护措施和参数来定义如何处理文件。默认值是 `r`,允许你只读数据:
|
||||
|
||||
* **r** 只读
|
||||
* **w** 如果文件不存在,覆盖或创建一个新文件。
|
||||
* **r+** 读取和覆盖。
|
||||
* **a** 追加数据到文件中,或在文件不存在的情况下创建一个新文件。
|
||||
* **a+** 读取数据,将数据追加到文件中,或文件不存在的话,创建一个新文件。
|
||||
|
||||
|
||||
* `r` 只读
|
||||
* `w` 如果文件不存在,覆盖或创建一个新文件。
|
||||
* `r+` 读取和覆盖。
|
||||
* `a` 追加数据到文件中,或在文件不存在的情况下创建一个新文件。
|
||||
* `a+` 读取数据,将数据追加到文件中,或文件不存在的话,创建一个新文件。
|
||||
|
||||
还有一些其他的(例如,`b` 代表二进制格式),但这些是最常见的。关于完整的文档,请参考 [Lua.org/manual][5] 上的优秀 Lua 文档。
|
||||
|
||||
@ -84,7 +82,7 @@ via: https://opensource.com/article/21/3/lua-files
|
||||
作者:[Seth Kenlon][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,157 @@
|
||||
[#]: subject: (Why I love using the IPython shell and Jupyter notebooks)
|
||||
[#]: via: (https://opensource.com/article/21/3/ipython-shell-jupyter-notebooks)
|
||||
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13277-1.html)
|
||||
|
||||
为什么我喜欢使用 IPython shell 和 Jupyter 笔记本
|
||||
======
|
||||
|
||||
> Jupyter 笔记本将 IPython shell 提升到一个新的高度。
|
||||
|
||||

|
||||
|
||||
Jupyter 项目最初是以 IPython 和 IPython 笔记本的形式出现的。它最初是一个专门针对 Python 的交互式 shell 和笔记本环境,后来扩展为不分语言的环境,支持 Julia、Python 和 R 以及其他任何语言。
|
||||
|
||||
![Jupyter][2]
|
||||
|
||||
IPython 是一个 Python shell,类似于你在命令行输入 `python` 或者 `python3` 时看到的,但它更聪明、更有用。如果你曾经在 Python shell 中输入过多行命令,并且想重复它,你就会理解每次都要一行一行地滚动浏览历史记录的挫败感。有了 IPython,你可以一次滚动浏览整个块,同时还可以逐行浏览和编辑这些块的部分内容。
|
||||
|
||||
![iPython][4]
|
||||
|
||||
它具有自动补全,并提供上下文感知的建议:
|
||||
|
||||
![iPython offers suggestions][5]
|
||||
|
||||
它默认会整理输出:
|
||||
|
||||
![iPython pretty prints][6]
|
||||
|
||||
它甚至允许你运行 shell 命令:
|
||||
|
||||
![IPython shell commands][7]
|
||||
|
||||
它还提供了一些有用的功能,比如将 `?` 添加到对象中,作为运行 `help()` 的快捷方式,而不会破坏你的流程:
|
||||
|
||||
![IPython help][8]
|
||||
|
||||
如果你使用的是虚拟环境(参见我关于 [virtualenvwrapper][9] 的帖子),可以在环境中用 `pip` 安装:
|
||||
|
||||
```
|
||||
pip install ipython
|
||||
```
|
||||
|
||||
要在全系统范围内安装,你可以在 Debian、Ubuntu 或树莓派上使用 `apt`:
|
||||
|
||||
```
|
||||
sudo apt install ipython3
|
||||
```
|
||||
|
||||
或使用 `pip`:
|
||||
|
||||
```
|
||||
sudo pip3 install ipython
|
||||
```
|
||||
|
||||
### Jupyter 笔记本
|
||||
|
||||
Jupyter 笔记本将 IPython shell 提升到了一个新的高度。首先,它们是基于浏览器的,而不是基于终端的。要开始使用,请安装 `jupyter`。
|
||||
|
||||
如果你使用的是虚拟环境,请在环境中使用 `pip` 进行安装:
|
||||
|
||||
```
|
||||
pip install jupyter
|
||||
```
|
||||
|
||||
要在全系统范围内安装,你可以在 Debian、Ubuntu 或树莓派上使用 `apt`:
|
||||
|
||||
```
|
||||
sudo apt install jupyter-notebook
|
||||
```
|
||||
|
||||
或使用 `pip`:
|
||||
|
||||
```
|
||||
sudo pip3 install jupyter
|
||||
```
|
||||
|
||||
启动笔记本:
|
||||
|
||||
```
|
||||
jupyter notebook
|
||||
```
|
||||
|
||||
这将在你的浏览器中打开:
|
||||
|
||||
![Jupyter Notebook][10]
|
||||
|
||||
你可以使用 “New” 下拉菜单创建一个新的 Python 3 笔记本:
|
||||
|
||||
![Python 3 in Jupyter Notebook][11]
|
||||
|
||||
现在你可以在 `In[ ]` 字段中编写和执行命令。使用 `Enter` 在代码块中换行,使用 `Shift+Enter` 来执行:
|
||||
|
||||
![Executing commands in Jupyter][12]
|
||||
|
||||
你可以编辑和重新运行代码块,你可以重新排序、删除,复制/粘贴,等等。你可以以任何顺序运行代码块,但是要注意的是,任何创建的变量的作用域都将根据执行的时间而不是它们在笔记本中出现的顺序。你可以在 “Kernel” 菜单中重启并清除输出或重启并运行所有的代码块。
|
||||
|
||||
使用 `print` 函数每次都会输出。但是如果你有一条没有分配的语句,或者最后一条语句没有分配,那么它总是会输出:
|
||||
|
||||
![Jupyter output][13]
|
||||
|
||||
你甚至可以把 `In` 和 `Out` 作为可索引对象:
|
||||
|
||||
![Jupyter output][14]
|
||||
|
||||
所有的 IPython 功能都可以使用,而且通常也会表现得更漂亮一些:
|
||||
|
||||
![Jupyter supports IPython features][15]
|
||||
|
||||
你甚至可以使用 [Matplotlib][16] 进行内联绘图:
|
||||
|
||||
![Graphing in Jupyter Notebook][17]
|
||||
|
||||
最后,你可以保存你的笔记本,并将其包含在 Git 仓库中,如果你将其推送到 GitHub,它们将作为已完成的笔记本被渲染:输出、图形和所有一切(如 [本例][18]):
|
||||
|
||||
![Saving Notebook to GitHub][19]
|
||||
|
||||
* * *
|
||||
|
||||
本文原载于 Ben Nuttall 的 [Tooling Tuesday 博客][20],经许可后重用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/ipython-shell-jupyter-notebooks
|
||||
|
||||
作者:[Ben Nuttall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/bennuttall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_space_graphic_cosmic.png?itok=wu493YbB (Computer laptop in space)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/jupyterpreview.png (Jupyter)
|
||||
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/ipython-loop.png (iPython)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/ipython-suggest.png (iPython offers suggestions)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/ipython-pprint.png (iPython pretty prints)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/ipython-ls.png (IPython shell commands)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/ipython-help.png (IPython help)
|
||||
[9]: https://opensource.com/article/21/2/python-virtualenvwrapper
|
||||
[10]: https://opensource.com/sites/default/files/uploads/jupyter-notebook-1.png (Jupyter Notebook)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/jupyter-python-notebook.png (Python 3 in Jupyter Notebook)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/jupyter-loop.png (Executing commands in Jupyter)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/jupyter-cells.png (Jupyter output)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/jupyter-cells-2.png (Jupyter output)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/jupyter-help.png (Jupyter supports IPython features)
|
||||
[16]: https://matplotlib.org/
|
||||
[17]: https://opensource.com/sites/default/files/uploads/jupyter-graph.png (Graphing in Jupyter Notebook)
|
||||
[18]: https://github.com/piwheels/stats/blob/master/2020.ipynb
|
||||
[19]: https://opensource.com/sites/default/files/uploads/savenotebooks.png (Saving Notebook to GitHub)
|
||||
[20]: https://tooling.bennuttall.com/the-ipython-shell-and-jupyter-notebooks/
|
@ -0,0 +1,169 @@
|
||||
[#]: subject: (Use this open source tool to monitor variables in Python)
|
||||
[#]: via: (https://opensource.com/article/21/4/monitor-debug-python)
|
||||
[#]: author: (Tian Gao https://opensource.com/users/gaogaotiantian)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13279-1.html)
|
||||
|
||||
使用这个开源工具来监控 Python 中的变量
|
||||
======
|
||||
|
||||
> Watchpoints 是一个简单但功能强大的工具,可以帮助你在调试 Python 时监控变量。
|
||||
|
||||

|
||||
|
||||
在调试代码时,你经常面临着要弄清楚一个变量何时发生变化。如果没有任何高级工具,那么可以选择使用打印语句在期望它们更改时输出变量。然而,这是一种非常低效的方法,因为变量可能在很多地方发生变化,并且不断地将其打印到终端上会产生很大的干扰,而将它们打印到日志文件中则变得很麻烦。
|
||||
|
||||
这是一个常见的问题,但现在有一个简单而强大的工具可以帮助你监控变量:[watchpoints][2]。
|
||||
|
||||
[“监视点”的概念在 C 和 C++ 调试器中很常见][3],用于监控内存,但在 Python 中缺乏相应的工具。`watchpoints` 填补了这个空白。
|
||||
|
||||
### 安装
|
||||
|
||||
要使用它,你必须先用 `pip` 安装它:
|
||||
|
||||
```
|
||||
$ python3 -m pip install watchpoints
|
||||
```
|
||||
|
||||
### 在Python中使用 watchpoints
|
||||
|
||||
对于任何一个你想监控的变量,使用 `watch` 函数对其进行监控。
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
a = 0
|
||||
watch(a)
|
||||
a = 1
|
||||
```
|
||||
|
||||
当变量发生变化时,它的值就会被打印到**标准输出**:
|
||||
|
||||
```
|
||||
====== Watchpoints Triggered ======
|
||||
|
||||
Call Stack (most recent call last):
|
||||
<module> (my_script.py:5):
|
||||
> a = 1
|
||||
a:
|
||||
0
|
||||
->
|
||||
1
|
||||
```
|
||||
|
||||
信息包括:
|
||||
|
||||
* 变量被改变的行。
|
||||
* 调用栈。
|
||||
* 变量的先前值/当前值。
|
||||
|
||||
它不仅适用于变量本身,也适用于对象的变化:
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
a = []
|
||||
watch(a)
|
||||
a = {} # 触发
|
||||
a["a"] = 2 # 触发
|
||||
```
|
||||
|
||||
当变量 `a` 被重新分配时,回调会被触发,同时当分配给 `a` 的对象发生变化时也会被触发。
|
||||
|
||||
更有趣的是,监控不受作用域的限制。你可以在任何地方观察变量/对象,而且无论程序在执行什么函数,回调都会被触发。
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
def func(var):
|
||||
var["a"] = 1
|
||||
|
||||
a = {}
|
||||
watch(a)
|
||||
func(a)
|
||||
```
|
||||
|
||||
例如,这段代码打印出:
|
||||
|
||||
```
|
||||
====== Watchpoints Triggered ======
|
||||
|
||||
Call Stack (most recent call last):
|
||||
|
||||
<module> (my_script.py:8):
|
||||
> func(a)
|
||||
func (my_script.py:4):
|
||||
> var["a"] = 1
|
||||
a:
|
||||
{}
|
||||
->
|
||||
{'a': 1}
|
||||
```
|
||||
|
||||
`watch` 函数不仅可以监视一个变量,它也可以监视一个字典或列表的属性和元素。
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
class MyObj:
|
||||
def __init__(self):
|
||||
self.a = 0
|
||||
|
||||
obj = MyObj()
|
||||
d = {"a": 0}
|
||||
watch(obj.a, d["a"]) # 是的,你可以这样做
|
||||
obj.a = 1 # 触发
|
||||
d["a"] = 1 # 触发
|
||||
```
|
||||
|
||||
这可以帮助你缩小到一些你感兴趣的特定对象。
|
||||
|
||||
如果你对输出格式不满意,你可以自定义它。只需定义你自己的回调函数:
|
||||
|
||||
```
|
||||
watch(a, callback=my_callback)
|
||||
|
||||
# 或者全局设置
|
||||
|
||||
watch.config(callback=my_callback)
|
||||
```
|
||||
|
||||
当触发时,你甚至可以使用 `pdb`:
|
||||
|
||||
```
|
||||
watch.config(pdb=True)
|
||||
```
|
||||
|
||||
这与 `breakpoint()` 的行为类似,会给你带来类似调试器的体验。
|
||||
|
||||
如果你不想在每个文件中都导入这个函数,你可以通过 `install` 函数使其成为全局:
|
||||
|
||||
```
|
||||
watch.install() # 或 watch.install("func_name") ,然后以 func_name() 方式使用
|
||||
```
|
||||
|
||||
我个人认为,`watchpoints` 最酷的地方就是使用直观。你对一些数据感兴趣吗?只要“观察”它,你就会知道你的变量何时发生变化。
|
||||
|
||||
### 尝试 watchpoints
|
||||
|
||||
我在 [GitHub][2] 上开发维护了 `watchpoints`,并在 Apache 2.0 许可下发布了它。安装并使用它,当然也欢迎大家做出贡献。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/monitor-debug-python
|
||||
|
||||
作者:[Tian Gao][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/gaogaotiantian
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/look-binoculars-sight-see-review.png?itok=NOw2cm39 (Looking back with binoculars)
|
||||
[2]: https://github.com/gaogaotiantian/watchpoints
|
||||
[3]: https://opensource.com/article/21/3/debug-code-gdb
|
134
published/20210401 Find what changed in a Git commit.md
Normal file
134
published/20210401 Find what changed in a Git commit.md
Normal file
@ -0,0 +1,134 @@
|
||||
[#]: subject: (Find what changed in a Git commit)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-whatchanged)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (DCOLIVERSUN)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13286-1.html)
|
||||
|
||||
查看 Git 提交中发生了什么变化
|
||||
======
|
||||
|
||||
> Git 提供了几种方式可以帮你快速查看提交中哪些文件被改变。
|
||||
|
||||

|
||||
|
||||
如果你每天使用 Git,应该会提交不少改动。如果你每天和其他人在一个项目中使用 Git,假设 _每个人_ 每天的提交都是安全的,你会意识到 Git 日志会变得多么混乱,似乎永恒地滚动着变化,却没有任何迹象表明修改了什么。
|
||||
|
||||
那么,你该怎样查看指定提交中文件发生哪些变化?这比你想的容易。
|
||||
|
||||
### 查看提交中文件发生的变化
|
||||
|
||||
要想知道指定提交中哪些文件发生变化,可以使用 `git log --raw` 命令。这是发现一个提交影响了哪些文件的最快速、最方便的方法。`git log` 命令一般都没有被充分利用,主要是因为它有太多的格式化选项,许多用户在面对很多选择以及在一些情况下不明所以的文档时,会望而却步。
|
||||
|
||||
然而,Git 的日志机制非常灵活,`--raw` 选项提供了当前分支中的提交日志,以及更改的文件列表。
|
||||
|
||||
以下是标准的 `git log` 输出:
|
||||
|
||||
```
|
||||
$ git log
|
||||
commit fbbbe083aed75b24f2c77b1825ecab10def0953c (HEAD -> dev, origin/dev)
|
||||
Author: tux <tux@example.com>
|
||||
Date: Sun Nov 5 21:40:37 2020 +1300
|
||||
|
||||
exit immediately from failed download
|
||||
|
||||
commit 094f9948cd995acfc331a6965032ea0d38e01f03 (origin/master, master)
|
||||
Author: Tux <tux@example.com>
|
||||
Date: Fri Aug 5 02:05:19 2020 +1200
|
||||
|
||||
export makeopts from etc/example.conf
|
||||
|
||||
commit 76b7b46dc53ec13316abb49cc7b37914215acd47
|
||||
Author: Tux <tux@example.com>
|
||||
Date: Sun Jul 31 21:45:24 2020 +1200
|
||||
|
||||
fix typo in help message
|
||||
```
|
||||
|
||||
即使作者在提交消息中指定了哪些文件发生变化,日志也相当简洁。
|
||||
|
||||
以下是 `git log --raw` 输出:
|
||||
|
||||
```
|
||||
$ git log --raw
|
||||
commit fbbbe083aed75b24f2c77b1825ecab10def0953c (HEAD -> dev, origin/dev)
|
||||
Author: tux <tux@example.com>
|
||||
Date: Sun Nov 5 21:40:37 2020 +1300
|
||||
|
||||
exit immediately from failed download
|
||||
|
||||
:100755 100755 cbcf1f3 4cac92f M src/example.lua
|
||||
|
||||
commit 094f9948cd995acfc331a6965032ea0d38e01f03 (origin/master, master)
|
||||
Author: Tux <tux@example.com>
|
||||
Date: Fri Aug 5 02:05:19 2020 +1200
|
||||
|
||||
export makeopts from etc/example.conf
|
||||
|
||||
:100755 100755 4c815c0 cbcf1f3 M src/example.lua
|
||||
:100755 100755 71653e1 8f5d5a6 M src/example.spec
|
||||
:100644 100644 9d21a6f e33caba R100 etc/example.conf etc/example.conf-default
|
||||
|
||||
commit 76b7b46dc53ec13316abb49cc7b37914215acd47
|
||||
Author: Tux <tux@example.com>
|
||||
Date: Sun Jul 31 21:45:24 2020 +1200
|
||||
|
||||
fix typo in help message
|
||||
|
||||
:100755 100755 e253aaf 4c815c0 M src/example.lua
|
||||
```
|
||||
|
||||
这会准确告诉你哪个文件被添加到提交中,哪些文件发生改变(`A` 是添加,`M` 是修改,`R` 是重命名,`D` 是删除)。
|
||||
|
||||
### Git whatchanged
|
||||
|
||||
`git whatchanged` 命令是一个遗留命令,它的前身是日志功能。文档说用户不应该用该命令替代 `git log --raw`,并且暗示它实质上已经被废弃了。不过,我还是觉得它是一个很有用的捷径,可以得到同样的输出结果(尽管合并提交的内容不包括在内),如果它被删除的话,我打算为它创建一个别名。如果你只想查看已更改的文件,不想在日志中看到合并提交,可以尝试 `git whatchanged` 作为简单的助记符。
|
||||
|
||||
### 查看变化
|
||||
|
||||
你不仅可以看到哪些文件发生更改,还可以使用 `git log` 显示文件中发生了哪些变化。你的 Git 日志可以生成一个内联差异,用 `--patch` 选项可以逐行显示每个文件的所有更改:
|
||||
|
||||
```
|
||||
commit 62a2daf8411eccbec0af69e4736a0fcf0a469ab1 (HEAD -> master)
|
||||
Author: Tux <Tux@example.com>
|
||||
Date: Wed Mar 10 06:46:58 2021 +1300
|
||||
|
||||
commit
|
||||
|
||||
diff --git a/hello.txt b/hello.txt
|
||||
index 65a56c3..36a0a7d 100644
|
||||
--- a/hello.txt
|
||||
+++ b/hello.txt
|
||||
@@ -1,2 +1,2 @@
|
||||
Hello
|
||||
-world
|
||||
+opensource.com
|
||||
```
|
||||
|
||||
在这个例子中,“world” 这行字从 `hello.txt` 中删掉,“opensource.com” 这行字则添加进去。
|
||||
|
||||
如果你需要在其他地方手动进行相同的修改,这些<ruby>补丁<rt>patch</rt></ruby>可以与常见的 Unix 命令一起使用,例如 [diff 与 patch][4]。补丁也是一个好方法,可以总结指定提交中引入新信息的重要部分内容。当你在冲刺阶段引入一个 bug 时,你会发现这里的内容就是非常有价值的概述。为了更快地找到错误的原因,你可以忽略文件中没有更改的部分,只检查新代码。
|
||||
|
||||
### 用简单命令得到复杂的结果
|
||||
|
||||
你不必理解引用、分支和提交哈希,就可以查看提交中更改了哪些文件。你的 Git 日志旨在向你报告 Git 的活动,如果你想以特定方式格式化它或者提取特定的信息,通常需要费力地浏览许多文档来组合出正确的命令。幸运的是,关于 Git 历史记录最常用的请求之一只需要一两个选项:`--raw` 与 `--patch`。如果你不记得 `--raw`,就想想“Git,什么改变了?”,然后输入 `git whatchanged`。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-whatchanged
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[DCOLIVERSUN](https://github.com/DCOLIVERSUN)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82 (Code going into a computer.)
|
||||
[2]: mailto:tux@example.com
|
||||
[3]: mailto:Tux@example.com
|
||||
[4]: https://opensource.com/article/18/8/diffs-patches
|
@ -0,0 +1,104 @@
|
||||
[#]: subject: (Wrong Time Displayed in Windows-Linux Dual Boot Setup? Here’s How to Fix it)
|
||||
[#]: via: (https://itsfoss.com/wrong-time-dual-boot/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13276-1.html)
|
||||
|
||||
如何解决 Windows-Linux 双启动设置中显示时间错误的问题
|
||||
======
|
||||
|
||||

|
||||
|
||||
如果你 [双启动 Windows 和 Ubuntu][1] 或任何其他 Linux 发行版,你可能会注意到两个操作系统之间的时间差异。
|
||||
|
||||
当你 [使用 Linux][2] 时,它会显示正确的时间。但当你进入 Windows 时,它显示的时间是错误的。有时,情况正好相反,Linux 显示的是错误的时间,而 Windows 的时间是正确的。
|
||||
|
||||
特别奇怪的是,因为你已连接到互联网,并且已将日期和时间设置为自动使用。
|
||||
|
||||
别担心!你并不是唯一一个遇到这种问题的人。你可以在 Linux 终端上使用以下命令来解决这个问题:
|
||||
|
||||
```
|
||||
timedatectl set-local-rtc 1
|
||||
```
|
||||
|
||||
同样,不要担心。我会解释为什么你在双启动设置中会遇到时间差。我会向你展示上面的命令是如何修复 Windows 双启动后的时间错误问题的。
|
||||
|
||||
### 为什么 Windows 和 Linux 在双启动时显示不同的时间?
|
||||
|
||||
一台电脑有两个主要时钟:系统时钟和硬件时钟。
|
||||
|
||||
硬件时钟也叫 RTC([实时时钟][3])或 CMOS/BIOS 时钟。这个时钟在操作系统之外,在电脑的主板上。即使在你的系统关机后,它也会继续运行。
|
||||
|
||||
系统时钟是你在操作系统内看到的。
|
||||
|
||||
当计算机开机时,硬件时钟被读取并用于设置系统时钟。之后,系统时钟被用于跟踪时间。如果你的操作系统对系统时钟做了任何改变,比如改变时区等,它就会尝试将这些信息同步到硬件时钟上。
|
||||
|
||||
默认情况下,Linux 认为硬件时钟中存储的时间是 UTC,而不是本地时间。另一方面,Windows 认为硬件时钟上存储的时间是本地时间。这就是问题的开始。
|
||||
|
||||
让我用例子来解释一下。
|
||||
|
||||
你看我在加尔各答 UTC+5:30 时区。安装后,当我把 [Ubuntu 中的时区][4] 设置为加尔各答时区时,Ubuntu 会把这个时间信息同步到硬件时钟上,但会有 5:30 的偏移,因为对于 Linux 来说它必须是 UTC。
|
||||
|
||||
假设加尔各答时区的当前时间是 15:00,这意味着 UTC 时间是 09:30。
|
||||
|
||||
现在当我关闭系统并启动到 Windows 时,硬件时钟有 UTC 时间(本例中为 09:30)。但是 Windows 认为硬件时钟已经存储了本地时间。因此,它改变了系统时钟(应该显示为 15:00),而使用 UTC 时间(09:30)作为本地时间。因此,Windows 显示时间为 09:30,这比实际时间(我们的例子中为 15:00)早了 5:30。
|
||||
|
||||
![][5]
|
||||
|
||||
同样,如果我在 Windows 中通过自动时区和时间按钮来设置正确的时间,你知道会发生什么吗?现在它将在系统上显示正确的时间(15:00),并将此信息(注意图片中的“同步你的时钟”选项)同步到硬件时钟。
|
||||
|
||||
如果你启动到 Linux,它会从硬件时钟读取时间,而硬件时钟是当地时间(15:00),但由于 Linux 认为它是 UTC 时间,所以它在系统时钟上增加了 5:30 的偏移。现在 Linux 显示的时间是 20:30,比实际时间超出晚了 5:30。
|
||||
|
||||
现在你了解了双启动中时差问题的根本原因,是时候看看如何解决这个问题了。
|
||||
|
||||
### 修复 Windows 在 Linux 双启动设置中显示错误时间的问题
|
||||
|
||||
有两种方法可以处理这个问题:
|
||||
|
||||
* 让 Windows 将硬件时钟作为 UTC 时间
|
||||
* 让 Linux 将硬件时钟作为本地时间
|
||||
|
||||
在 Linux 中进行修改是比较容易的,因此我推荐使用第二种方法。
|
||||
|
||||
现在 Ubuntu 和大多数其他 Linux 发行版都使用 systemd,因此你可以使用 `timedatectl` 命令来更改设置。
|
||||
|
||||
你要做的是告诉你的 Linux 系统将硬件时钟(RTC)作为本地时间。你可以通过 `set-local-rtc` (为 RTC 设置本地时间)选项来实现:
|
||||
|
||||
```
|
||||
timedatectl set-local-rtc 1
|
||||
```
|
||||
|
||||
如下图所示,RTC 现在使用本地时间。
|
||||
|
||||
![][6]
|
||||
|
||||
现在如果你启动 Windows,它把硬件时钟当作本地时间,而这个时间实际上是正确的。当你在 Linux 中启动时,你的 Linux 系统知道硬件时钟使用的是本地时间,而不是 UTC。因此,它不会尝试添加这个时间的偏移。
|
||||
|
||||
这就解决了 Linux 和 Windows 双启动时的时差问题。
|
||||
|
||||
你会看到一个关于 RTC 不使用本地时间的警告。对于桌面设置,它不应该引起任何问题。至少,我想不出有什么问题。
|
||||
|
||||
希望我把事情给你讲清楚了。如果你还有问题,请在下面留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/wrong-time-dual-boot/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/
|
||||
[2]: https://itsfoss.com/why-use-linux/
|
||||
[3]: https://www.computerhope.com/jargon/r/rtc.htm
|
||||
[4]: https://itsfoss.com/change-timezone-ubuntu/
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/set-time-windows.jpg?resize=800%2C491&ssl=1
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/set-local-time-for-rtc-ubuntu.png?resize=800%2C490&ssl=1
|
136
published/20210403 What problems do people solve with strace.md
Normal file
136
published/20210403 What problems do people solve with strace.md
Normal file
@ -0,0 +1,136 @@
|
||||
[#]: subject: (What problems do people solve with strace?)
|
||||
[#]: via: (https://jvns.ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13267-1.html)
|
||||
|
||||
strace 可以解决什么问题?
|
||||
======
|
||||
|
||||

|
||||
|
||||
昨天我 [在 Twitter 上询问大家用 strace 解决了什么问题?][1],和往常一样,大家真的是给出了自己的答案! 我收到了大约 200 个答案,然后花了很多时间手动将它们归为 9 类。
|
||||
|
||||
这些解决的问题都是关于寻找程序依赖的文件、找出程序卡住或慢的原因、或者找出程序失败的原因。这些总体上与我自己使用 `strace` 的内容相吻合,但也有一些我没有想到的东西!
|
||||
|
||||
我不打算在这篇文章里解释什么是 `strace`,但我有一本 [关于它的免费杂志][2] 和 [一个讲座][3] 以及 [很多博文][4]。
|
||||
|
||||
### 问题 1:配置文件在哪里?
|
||||
|
||||
最受欢迎的问题是“这个程序有一个配置文件,但我不知道它在哪里”。这可能也是我最常使用 `strace` 解决的问题,因为这是个很简单的问题。
|
||||
|
||||
这很好,因为一个程序有一百万种方法来记录它的配置文件在哪里(在手册页、网站上、`--help`等),但只有一种方法可以让它真正打开它(用系统调用!)。
|
||||
|
||||
### 问题 2:这个程序还依赖什么文件?
|
||||
|
||||
你也可以使用 `strace` 来查找程序依赖的其他类型的文件,比如:
|
||||
|
||||
* 动态链接库(“为什么我的程序加载了这个错误版本的 `.so` 文件?"),比如 [我在 2014 年调试的这个 ruby 问题][5]
|
||||
* 它在哪里寻找它的 Ruby gem(Ruby 出现了几次这种情况!)
|
||||
* SSL 根证书
|
||||
* 游戏的存档文件
|
||||
* 一个闭源程序的数据文件
|
||||
* [哪些 node_modules 文件没有被使用][6]
|
||||
|
||||
### 问题 3:为什么这个程序会挂掉?
|
||||
|
||||
你有一个程序,它只是坐在那里什么都不做,这是怎么回事?这个问题特别容易回答,因为很多时候你只需要运行 `strace -p PID`,看看当前运行的是什么系统调用。你甚至不需要看几百行的输出。
|
||||
|
||||
答案通常是“正在等待某种 I/O”。“为什么会卡住”的一些可能的答案(虽然还有很多!):
|
||||
|
||||
* 它一直在轮询 `select()`
|
||||
* 正在 `wait()` 等待一个子进程完成
|
||||
* 它在向某个没有响应的东西发出网络请求
|
||||
* 正在进行 `write()`,但由于缓冲区已满而被阻止。
|
||||
* 它在 stdin 上做 `read()`,等待输入。
|
||||
|
||||
有人还举了一个很好的例子,用 `strace` 调试一个卡住的 `df` 命令:“用 `strace df -h` 你可以找到卡住的挂载,然后卸载它”。
|
||||
|
||||
### 问题 4:这个程序卡住了吗?
|
||||
|
||||
这是上一个问题的变种:有时一个程序运行的时间比你预期的要长,你只是想知道它是否卡住了,或者它是否还在继续进行。
|
||||
|
||||
只要程序在运行过程中进行系统调用,用 `strace` 就可以超简单地回答这个问题:只需 `strace` 它,看看它是否在进行新的系统调用!
|
||||
|
||||
### 问题 5:为什么这个程序很慢?
|
||||
|
||||
你可以使用 `strace` 作为一种粗略的剖析工具:`strace -t` 会显示每次系统调用的时间戳,这样你就可以寻找大的漏洞,找到罪魁祸首。
|
||||
|
||||
以下是 Twitter 上 9 个人使用 `strace` 调试“为什么这个程序很慢?”的小故事。
|
||||
|
||||
* 早在 2000 年,我帮助支持的一个基于 Java 的网站在适度的负载下奄奄一息:页面加载缓慢,甚至完全加载不出来。我们对 J2EE 应用服务器进行了测试,发现它每次只读取一个类文件。开发人员没有使用 BufferedReader,这是典型的 Java 错误。
|
||||
* 优化应用程序的启动时间……运行 `strace` 可以让人大开眼界,因为有大量不必要的文件系统交互在进行(例如,在同一个配置文件上反复打开/读取/关闭;在一个缓慢的 NFS 挂载上加载大量的字体文件,等等)。
|
||||
* 问自己为什么在 PHP 中从会话文件中读取(通常是小于 100 字节)非常慢。结果发现一些 `flock` 系统调用花了大约 60 秒。
|
||||
* 一个程序表现得异常缓慢。使用 `strace` 找出它在每次请求时,通过从 `/dev/random` 读取数据并耗尽熵来重新初始化其内部伪随机数发生器。
|
||||
* 我记得最近一件事是连接到一个任务处理程序,看到它有多少网络调用(这是意想不到的)。
|
||||
* `strace` 显示它打开/读取同一个配置文件数千次。
|
||||
* 服务器随机使用 100% 的 CPU 时间,实际流量很低。原来是碰到打开文件数限制,接受一个套接字时,得到 EMFILE 错误而没有报告,然后一直重试。
|
||||
* 一个工作流运行超慢,但是没有日志,结果它做一个 POST 请求花了 30 秒而超时,然后重试了 5 次……结果后台服务不堪重负,但是也没有可视性。
|
||||
* 使用 `strace` 注意到 `gethostbyname()` 需要很长时间才能返回(你不能直接看到 `gethostbyname`,但你可以看到 `strace` 中的 DNS 数据包)
|
||||
|
||||
### 问题 6:隐藏的权限错误
|
||||
|
||||
有时候程序因为一个神秘的原因而失败,但问题只是有一些它没有权限打开的文件。在理想的世界里,程序会报告这些错误(“Error opening file /dev/whatever: permission denied”),当然这个世界并不完美,所以 `strace` 真的可以帮助解决这个问题!
|
||||
|
||||
这其实是我最近使用 `strace` 做的事情。我使用了一台 AxiDraw 绘图仪,当我试图启动它时,它打印出了一个难以理解的错误信息。我 `strace` 它,结果发现我的用户没有权限打开 USB 设备。
|
||||
|
||||
### 问题 7:正在使用什么命令行参数?
|
||||
|
||||
有时候,一个脚本正在运行另一个程序,你想知道它传递的是什么命令行标志!
|
||||
|
||||
几个来自 Twitter 的例子。
|
||||
|
||||
* 找出实际上是用来编译代码的编译器标志
|
||||
* 由于命令行太长,命令失败了
|
||||
|
||||
### 问题 8:为什么这个网络连接失败?
|
||||
|
||||
基本上,这里的目标是找到网络连接的域名 / IP 地址。你可以通过 DNS 请求来查找域名,或者通过 `connect` 系统调用来查找 IP。
|
||||
|
||||
一般来说,当 `tcpdump` 因为某些原因不能使用或者只是因为比较熟悉 `strace` 时,就经常会使用 `strace` 调试网络问题。
|
||||
|
||||
### 问题 9:为什么这个程序以一种方式运行时成功,以另一种方式运行时失败?
|
||||
|
||||
例如:
|
||||
|
||||
* 同样的二进制程序在一台机器上可以运行,在另一台机器上却失败了
|
||||
* 可以运行,但被 systemd 单元文件生成时失败
|
||||
* 可以运行,但以 `su - user /some/script` 的方式运行时失败
|
||||
* 可以运行,作为 cron 作业运行时失败
|
||||
|
||||
能够比较两种情况下的 `strace` 输出是非常有用的。虽然我在调试“以我的用户身份工作,而在同一台计算机上以不同方式运行时却失败了”时,第一步是“看看我的环境变量”。
|
||||
|
||||
### 我在做什么:慢慢地建立一些挑战
|
||||
|
||||
我之所以会想到这个问题,是因为我一直在慢慢地进行一些挑战,以帮助人们练习使用 `strace` 和其他命令行工具。我的想法是,给你一个问题,一个终端,你可以自由地以任何方式解决它。
|
||||
|
||||
所以我的目标是用它来建立一些你可以用 `strace` 解决的练习题,这些练习题反映了人们在现实生活中实际使用它解决的问题。
|
||||
|
||||
### 就是这样!
|
||||
|
||||
可能还有更多的问题可以用 `strace` 解决,我在这里还没有讲到,我很乐意听到我错过了什么!
|
||||
|
||||
我真的很喜欢看到很多相同的用法一次又一次地出现:至少有 20 个不同的人回答说他们使用 `strace` 来查找配置文件。而且和以往一样,我觉得这样一个简单的工具(“跟踪系统调用!”)可以用来解决这么多不同类型的问题,真的很令人高兴。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/
|
||||
|
||||
作者:[Julia Evans][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://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://twitter.com/b0rk/status/1378014888405168132
|
||||
[2]: https://wizardzines.com/zines/strace
|
||||
[3]: https://www.youtube.com/watch?v=4pEHfGKB-OE
|
||||
[4]: https://jvns.ca/categories/strace
|
||||
[5]: https://jvns.ca/blog/2014/03/10/debugging-shared-library-problems-with-strace/
|
||||
[6]: https://indexandmain.com/post/shrink-node-modules-with-refining
|
@ -0,0 +1,146 @@
|
||||
[#]: subject: "Converting Multiple Markdown Files into HTML or Other Formats in Linux"
|
||||
[#]: via: "https://itsfoss.com/convert-markdown-files/"
|
||||
[#]: author: "Bill Dyer https://itsfoss.com/author/bill/"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13274-1.html"
|
||||
|
||||
在 Linux 中把多个 Markdown 文件转换成 HTML 或其他格式
|
||||
======
|
||||
|
||||

|
||||
|
||||
很多时候我与 Markdown 打交道的方式是,先写完一个文件,然后把它转换成 HTML 或其他格式。也有些时候,需要创建一些新的文件。当我要写多个 Markdown 文件时,通常要把他们全部写完之后才转换它们。
|
||||
|
||||
我用 `pandoc` 来转换文件,它可以一次性地转换所有 Markdown 文件。
|
||||
|
||||
Markdown 格式的文件可以转换成 .html 文件,有时候我需要把它转换成其他格式,如 epub,这个时候 [pandoc][1] 就派上了用场。我更喜欢用命令行,因此本文我会首先介绍它,然而你还可以使用 [VSCodium][2] 在非命令行下完成转换。后面我也会介绍它。
|
||||
|
||||
### 使用 pandoc 把多个 Markdown 文件转换成其他格式(命令行方式)
|
||||
|
||||
你可以在 Ubuntu 及其他 Debian 系发行版本终端输入下面的命令来快速开始:
|
||||
|
||||
```
|
||||
sudo apt-get install pandoc
|
||||
```
|
||||
|
||||
本例中,在名为 `md_test` 目录下我有四个 Markdown 文件需要转换。
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ ls -l *.md
|
||||
-rw-r--r-- 1 bdyer bdyer 3374 Apr 7 2020 file01.md
|
||||
-rw-r--r-- 1 bdyer bdyer 782 Apr 2 05:23 file02.md
|
||||
-rw-r--r-- 1 bdyer bdyer 9257 Apr 2 05:21 file03.md
|
||||
-rw-r--r-- 1 bdyer bdyer 9442 Apr 2 05:21 file04.md
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
现在还没有 HTML 文件。现在我要对这些文件使用 `pandoc`。我会运行一行命令来实现:
|
||||
|
||||
* 调用 `pandoc`
|
||||
* 读取 .md 文件并导出为 .html
|
||||
|
||||
下面是我要运行的命令:
|
||||
|
||||
```
|
||||
for i in *.md ; do echo "$i" && pandoc -s $i -o $i.html ; done
|
||||
```
|
||||
|
||||
如果你不太理解上面的命令中的 `;`,可以参考 [在 Linux 中一次执行多个命令][3]。
|
||||
|
||||
我执行命令后,运行结果如下:
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ for i in *.md ; do echo "$i" && pandoc -s $i -o $i.html ; done
|
||||
file01.md
|
||||
file02.md
|
||||
file03.md
|
||||
file04.md
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
让我再使用一次 `ls` 命令来看看是否已经生成了 HTML 文件:
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ ls -l *.html
|
||||
-rw-r--r-- 1 bdyer bdyer 4291 Apr 2 06:08 file01.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 1781 Apr 2 06:08 file02.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 10272 Apr 2 06:08 file03.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 10502 Apr 2 06:08 file04.md.html
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
转换很成功,现在你已经有了四个 HTML 文件,它们可以用在 Web 服务器上。
|
||||
|
||||
pandoc 功能相当多,你可以通过指定输出文件的扩展名来把 Markdown 文件转换成其他支持的格式。不难理解它为什么会被认为是[最好的写作开源工具][4]。
|
||||
|
||||
### 使用 VSCodium 把 Markdown 文件转换成 HTML(GUI 方式)
|
||||
|
||||
就像我们前面说的那样,我通常使用命令行,但是对于批量转换,我不会使用命令行,你也不必。VSCode 或 [VSCodium][7] 可以完成批量操作。你只需要安装一个 Markdown-All-in-One 扩展,就可以在一次运行中转换多个 Markdown 文件。
|
||||
|
||||
有两种方式安装这个扩展:
|
||||
|
||||
* VSCodium 的终端
|
||||
* VSCodium 的插件管理器
|
||||
|
||||
通过 VSCodium 的终端安装该扩展:
|
||||
|
||||
1. 点击菜单栏的 `终端`。会打开终端面板
|
||||
2. 输入,或[复制下面的命令并粘贴到终端][8]:
|
||||
|
||||
```
|
||||
codium --install-extension yzhang.markdown-all-in-one
|
||||
```
|
||||
|
||||
**注意**:如果你使用的 VSCode 而不是 VSCodium,那么请把上面命令中的 `codium` 替换为 `code`
|
||||
|
||||
![][9]
|
||||
|
||||
第二种安装方式是通过 VSCodium 的插件/扩展管理器:
|
||||
|
||||
1. 点击 VSCodium 窗口左侧的块区域。会出现一个扩展列表,列表最上面有一个搜索框。
|
||||
2. 在搜索框中输入 “Markdown All in One”。在列表最上面会出现该扩展。点击 “安装” 按钮来安装它。如果你已经安装过,在安装按钮的位置会出现一个齿轮图标。
|
||||
|
||||
![][10]
|
||||
|
||||
安装完成后,你可以打开含有需要转换的 Markdown 文件的文件夹。
|
||||
|
||||
点击 VSCodium 窗口左侧的纸张图标。你可以选择文件夹。打开文件夹后,你需要打开至少一个文件。你也可以打开多个文件,但是最少打开一个。
|
||||
|
||||
当打开文件后,按下 `CTRL+SHIFT+P` 唤起命令面板。然后,在出现的搜索框中输入 `Markdown`。当你输入时,会出现一列 Markdown 相关的命令。其中有一个是 `Markdown All in One: Print documents to HTML` 命令。点击它:
|
||||
|
||||
![][11]
|
||||
|
||||
你需要选择一个文件夹来存放这些文件。它会自动创建一个 `out` 目录,转换后的 HTML 文件会存放在 `out` 目录下。从下面的图中可以看到,Markdown 文档被转换成了 HTML 文件。在这里,你可以打开、查看、编辑这些 HTML 文件。
|
||||
|
||||
![][12]
|
||||
|
||||
在等待转换 Markdown 文件时,你可以更多地集中精力在写作上。当你准备好时,你就可以把它们转换成 HTML —— 你可以通过两种方式转换它们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/convert-markdown-files/
|
||||
|
||||
作者:[Bill Dyer][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/bill/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://pandoc.org/
|
||||
[2]: https://vscodium.com/
|
||||
[3]: https://itsfoss.com/run-multiple-commands-linux/
|
||||
[4]: https://itsfoss.com/open-source-tools-writers/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2016/10/Best-Markdown-Editors-for-Linux.jpg?fit=800%2C450&ssl=1
|
||||
[6]: https://itsfoss.com/best-markdown-editors-linux/
|
||||
[7]: https://itsfoss.com/vscodium/
|
||||
[8]: https://itsfoss.com/copy-paste-linux-terminal/
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_terminal.jpg?resize=800%2C564&ssl=1
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_extension_select.jpg?resize=800%2C564&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_markdown_function_options.jpg?resize=800%2C564&ssl=1
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_html_filelist_shown.jpg?resize=800%2C564&ssl=1
|
80
published/20210406 Teach anyone how to code with Hedy.md
Normal file
80
published/20210406 Teach anyone how to code with Hedy.md
Normal file
@ -0,0 +1,80 @@
|
||||
[#]: subject: (Teach anyone how to code with Hedy)
|
||||
[#]: via: (https://opensource.com/article/21/4/hedy-teach-code)
|
||||
[#]: author: (Joshua Allen Holm https://opensource.com/users/holmja)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13290-1.html)
|
||||
|
||||
用 Hedy 教人编程
|
||||
======
|
||||
|
||||
> Hedy 是一种专门为教人编程而设计的新型编程语言。
|
||||
|
||||

|
||||
|
||||
学习编程既要学习编程逻辑,又要学习特定编程语言的语法。我在大学上第一堂编程课的时候,教的语言是 C++。第一个代码例子是基本的 “Hello World” 程序,就像下面的例子。
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello World!";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
老师直到几节课后才会解释大部分的代码。我们的期望是,我们只需输入代码,并最终了解为什么需要这些东西以及它们如何工作。
|
||||
|
||||
C++(以及其他类似的语言)的复杂语法是为什么 Python 经常被建议作为一种更容易的编程教学语言。下面是 Python 中的同一个例子:
|
||||
|
||||
```
|
||||
print("Hello World!")
|
||||
```
|
||||
|
||||
虽然 Python 中的 “Hello World” 基础例子要简单得多,但它仍然有复杂而精确的语法规则。`print` 函数需要在字符串周围加括号和引号。这对于没有编程经验的人来说,还是会感到困惑。Python 比 C++ 少了 “我以后再解释” 的语法问题,但还是有一些。
|
||||
|
||||
[Hedy][2] 是一种专门为编码教学而设计的新语言,它通过在语言中将复杂性分成多个关卡来解决语法复杂性的问题。Hedy 没有马上提供语言的全部功能,而是采取循序渐进的方式,随着学生在 Hedy 的学习的通关,慢慢变得更加复杂。随着关卡的进展,该语言获得了新的功能,最终变得更像 Python。目前有七个关卡,但更多的关卡正在计划中。
|
||||
|
||||
在第 1 关,Hedy 程序除了打印(`print`)一条语句(不需要引号或括号),提出(`ask`)一个问题,并回传(`echo`)一个答案外,不能做任何事情。第 1 关没有变量,没有循环,结构极精简。回传的工作原理几乎和变量一样,但只针对用户的最后一个输入。这可以让学生对基本概念感到舒适,而不必一下子学习所有的东西。
|
||||
|
||||
这是一个第 1 关的 Hedy “Hello World” 程序:
|
||||
|
||||
```
|
||||
print Hello World
|
||||
```
|
||||
|
||||
第 2 关引入了变量,但由于 `print` 函数没有使用引号,可能会出现一些有趣的结果。如果用来存储一个人的名字的变量是 `name`,那么就不可能打印输出 `Your name is [name]`,因为 `name` 的第一次使用(本意是字符串)和第二次使用(是变量)都被解释为变量。如果将 `name` 设置为(`is`) `John Doe`,那么 `print Your name is name.` 的输出就会是 `Your John Doe is John Doe`。虽然这听起来很奇怪,但这是一个引入变量概念的好方法,这恰好是第 3 关中增加的一个功能。
|
||||
|
||||
第 3 关要求在字符串周围加引号,这使得变量的功能就像在 Python 中一样。现在可以输出与变量相结合的字符串,做出复杂的语句,而不用担心变量名和字符串中的单词之间的冲突。这个级别取消了 “回传”(`echo`)函数,这看起来确实是一个可能会让一些学习者感到沮丧的东西。他们应该使用变量,这是更好的代码,但如果一个 `ask`/`echo` 代码块变成无效语法,可能会让人感到困惑。
|
||||
|
||||
第 4 关增加了基本的 `if`/`else` 功能。学生可以从简单的问/答代码转向复杂的交互。例如,一个问“你最喜欢的颜色是什么?”的提示可以根据用户输入的内容接受不同的回复。如果他们输入绿色,回答可以是“绿色!这也是我最喜欢的颜色。”如果他们输入其他的东西,回复可以是不同的。`if`/`else` 块是一个基本的编程概念,Hedy 引入了这个概念,而不必担心复杂的语法或过于精确的格式。
|
||||
|
||||
第 5 关有一个 `repeat` 函数,在现有的功能上增加了一个基本的循环。这个循环只能多次重复同一个命令,所以它没有 Python 中的循环那么强大,但它让学生习惯了重复命令的一般概念。这是多介绍了一个编程概念,而不会用无谓的复杂来拖累。学生们可以先掌握概念的基础知识,然后再继续学习同一事物的更强大、更复杂的版本。
|
||||
|
||||
在第 6 关,Hedy 现在可以进行基本的数学计算。加法、减法、乘法和除法都支持,但更高级的数学功能不支持。不能使用指数、模数或其他任何 Python 和其他语言能处理的东西。目前,Hedy 还没有更高关卡的产品增加更复杂的数学功能。
|
||||
|
||||
第 7 关引入了 Python 风格的缩进,这意味着 `repeat` 可以处理多行代码。学生在这之前都是逐行处理代码,但现在他们可以处理代码块。这个 Hedy 关卡与非教学型编程语言能做的事情相比还是有很大的差距,但它可以教会学生很多东西。
|
||||
|
||||
开始学习 Hedy 最简单的方法是访问 Hedy 网站上的 [课程][3],目前有荷兰语、英语、法语、德语、葡萄牙语和西班牙语。这样一来,任何有网页浏览器的人都可以进入学习过程。也可以从 [GitHub][4] 下载 Hedy,并从命令行运行解释器,或者运行 Hedy 网站的本地副本及其交互式课程。基于网页的版本更容易使用,但网页版本和命令行版本都支持运行针对不同复杂程度的 Hedy 程序。
|
||||
|
||||
Hedy 永远不会与 Python、C++ 或其他语言竞争,成为现实世界项目编码的首选语言,但它是编码教学的绝佳方式。作为学习过程的一部分,学生编写的程序是真实的,甚至可能是复杂的。Hedy 可以促进学生的学习和创造力,而不会让学生在学习过程中过早地被过多的信息所迷惑。就像数学课一样,在进入微积分之前很久要从学习计数、相加等开始(这个过程需要数年时间),编程也不必一开始就对编程语言的语法问题“我稍后再解释”、精确地遵循这些语法问题,才能产生哪怕是最基本的语言程序。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/hedy-teach-code
|
||||
|
||||
作者:[Joshua Allen Holm][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://opensource.com/users/holmja
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/5538035618_4e19c9787c_o.png?itok=naiD1z1S (Teacher or learner?)
|
||||
[2]: https://www.hedycode.com/
|
||||
[3]: https://www.hedycode.com/hedy?lang=en
|
||||
[4]: https://github.com/felienne/hedy
|
@ -0,0 +1,107 @@
|
||||
[#]: subject: (Show CPU Details Beautifully in Linux Terminal With CPUFetch)
|
||||
[#]: via: (https://itsfoss.com/cpufetch/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13289-1.html)
|
||||
|
||||
使用 CPUFetch 在 Linux 终端中漂亮地显示 CPU 细节
|
||||
======
|
||||
|
||||

|
||||
|
||||
Linux 上有 [检查 CPU 信息的方法][1]。最常见的可能是 `lscpu` 命令,它可以提供大量的系统上所有 CPU 核心的信息。
|
||||
|
||||
![lscpu command output][2]
|
||||
|
||||
你可以在那里找到 CPU 信息,而无需安装任何额外的包。当然这是可行的。然而,我最近偶然发现了一个新的工具,它以一种漂亮的方式显示 Linux 中的 CPU 细节。
|
||||
|
||||
处理器制造商的 ASCII 艺术使它看起来很酷。
|
||||
|
||||
![][3]
|
||||
|
||||
这看起来很美,不是吗?这类似于 [Neoftech 或者 Screenfetch,在 Linux 中用漂亮的 ASCII 艺术来展示系统信息][4]。与这些工具类似,如果你要展示你的桌面截图,可以使用 CPUFetch。
|
||||
|
||||
该工具可以输出处理器制造商的 ASCII 艺术,它的名称、微架构、频率、核心、线程、峰值性能、缓存大小、[高级向量扩展][5] 等等。
|
||||
|
||||
除了它提供的一些主题外,你还可以使用自定义颜色。当你在整理桌面,并希望对 Linux 环境中的所有元素进行颜色匹配时,这给了你更多的自由度。
|
||||
|
||||
### 在 Linux 上安装 CPUFetch
|
||||
|
||||
不幸的是,CPUFetch 是一个相当新的软件,而且它并不包含在你的发行版的软件库中,甚至没有提供现成的 DEB/RPM 二进制文件、PPA、Snap 或 Flatpak 包。
|
||||
|
||||
Arch Linux 用户可以在 [AUR][7] 中 [找到][6] 它,但对于其他人来说,唯一的出路是 [从源代码构建][8]。
|
||||
|
||||
不要担心。安装以及删除并不是那么复杂。让我来告诉你步骤。
|
||||
|
||||
我使用的是 Ubuntu,你会 [需要先在 Ubuntu 上安装 Git][9]。一些发行版会预装 Git,如果没有,请使用你的发行版的包管理器来安装。
|
||||
|
||||
现在,把 Git 仓库克隆到你想要的地方。家目录也可以。
|
||||
|
||||
```
|
||||
git clone https://github.com/Dr-Noob/cpufetch
|
||||
```
|
||||
|
||||
切换到你刚才克隆的目录:
|
||||
|
||||
```
|
||||
cd cpufetch
|
||||
```
|
||||
|
||||
你会在这里看到一个 Makefile 文件。用它来编译代码。
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
![CPUFetch Installation][10]
|
||||
|
||||
现在你会看到一个新的可执行文件,名为 `cpufetch`。你运行这个可执行文件来显示终端的 CPU 信息。
|
||||
|
||||
```
|
||||
./cpufetch
|
||||
```
|
||||
|
||||
这是我系统的显示。AMD 的徽标用 ASCII 码看起来更酷,你不觉得吗?
|
||||
|
||||
![][11]
|
||||
|
||||
如何删除 CPUFetch?这很简单。当你编译代码时,它只产生了一个文件,而且也和其他代码在同一个目录下。
|
||||
|
||||
所以,要想从系统中删除 CPUFetch,只需删除它的整个文件夹即可。你知道 [在 Linux 终端中删除一个目录][12] 的方法吧?从 `cpufetch` 目录中出来,然后使用 `rm` 命令。
|
||||
|
||||
```
|
||||
rm -rf cpufetch
|
||||
```
|
||||
|
||||
这很简单,值得庆幸的是,因为从源代码中删除安装的软件有时真的很棘手。
|
||||
|
||||
说回 CPUFetch。我想这是一个实用工具,适合那些喜欢在各种 Linux 群里炫耀自己桌面截图的人。既然发行版有了 Neofetch,CPU 有了 CPUFetch,不知道能不能也来个 Nvidia ASCII 艺术的 GPUfetch?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/cpufetch/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linuxhandbook.com/check-cpu-info-linux/
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/lscpu-command-output.png?resize=800%2C415&ssl=1
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/cpufetch-1.png?resize=800%2C307&ssl=1
|
||||
[4]: https://itsfoss.com/display-linux-logo-in-ascii/
|
||||
[5]: https://software.intel.com/content/www/us/en/develop/articles/introduction-to-intel-advanced-vector-extensions.html
|
||||
[6]: https://aur.archlinux.org/packages/cpufetch-git
|
||||
[7]: https://itsfoss.com/aur-arch-linux/
|
||||
[8]: https://itsfoss.com/install-software-from-source-code/
|
||||
[9]: https://itsfoss.com/install-git-ubuntu/
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/cpufetch-installation.png?resize=800%2C410&ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/cpufetch-for-itsfoss.png?resize=800%2C335&ssl=1
|
||||
[12]: https://linuxhandbook.com/remove-files-directories/
|
@ -0,0 +1,135 @@
|
||||
[#]: subject: (GNOME’s Very Own “GNOME OS” is Not a Linux Distro for Everyone [Review])
|
||||
[#]: via: (https://itsfoss.com/gnome-os/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13287-1.html)
|
||||
|
||||
GNOME OS:一个并不是适合所有人的 Linux 发行版
|
||||
======
|
||||
|
||||

|
||||
|
||||
每当 GNOME 的一个重要版本到来时,总是很想尽快试用它。但是,要想第一时间进行测试,主要还是得依靠 [Fedora Rawhide][1] 开发分支。
|
||||
|
||||
然而,开发分支并不总是让人放心的,所以,用来尝试最新的 GNOME 并不是最方便的解决方案。这里,我所说的测试,并不仅仅是指用户的测试,同时也能够用于开发者对设计变更进行测试。
|
||||
|
||||
所以,最近来了个大救星 GNOME OS,让测试的过程变得轻松起来。但是,它到底是什么,怎么安装呢?让我们一起来看看吧。
|
||||
|
||||
### 什么是 GNOME OS?
|
||||
|
||||
GNOME OS 并不是一个独立完整的 Linux 发行版。事实上,它根本不基于任何东西。它是一个不完整的参考系统,只是为了让 GNOME 桌面工作。它仅仅是一个可启动的虚拟机镜像,在 GNOME 进入任何发行版的仓库之前,为调试和测试功能而量身定做的。
|
||||
|
||||
在 GNOME 的博客中,有一篇提到了它:
|
||||
|
||||
> GNOME OS 旨在通过提供一个用于开发、设计和用户测试的工作系统,来更好地促进 GNOME 的开发。
|
||||
|
||||
如果你好奇的话,你可以看看 GNOME 星球上的一篇 [博客文章][2] 来了解关于 GNOME OS 的更多信息。
|
||||
|
||||
### 如果它不是一个成熟的 Linux 发行版,那么它是用来干什么的?
|
||||
|
||||
![][3]
|
||||
|
||||
值得注意的是,每一次新的提交都可以创建一个新的 GNOME OS 镜像,所以它应该会使测试过程变得高效,并帮助你在开发周期的早期测试并发现问题。
|
||||
|
||||
不要忘了,设计者不再需要自己构建软件来测试 GNOME Shell 或任何其他核心模块。这为他们节省了时间和整个 GNOME 开发周期。
|
||||
|
||||
当然,不仅限于开发者和技术测试人员,它还可以让记者们拿到最新的和最棒的东西,来报道 GNOME 下一个版本或它是如何成型的。
|
||||
|
||||
媒体和 GNOME 团队也得到了一个很好的机会,借助于 GNOME OS,他们可以准备视频、图片两种形式的视觉资料来宣传此次发布。
|
||||
|
||||
### 如何安装 GNOME OS?
|
||||
|
||||
要轻松安装 GNOME OS,你需要先安装 GNOME Boxes 应用程序。
|
||||
|
||||
#### 安装 GNOME Boxes
|
||||
|
||||
Boxes 是一款简单的虚拟化软件,它不提供任何高级选项,但可以让你轻松安装操作系统镜像来快速测试。它是专门针对桌面终端用户的,所以使用起来也很方便。
|
||||
|
||||
要在任何 Linux 发行版上安装它,你可以利用 [Flathub][5] 的 [Flatpak][4] 包。如果你不知道 Flatpak,你可能需要阅读我们的《[在 Linux 中安装和使用 Flatpak][6]》指南。
|
||||
|
||||
你也可以在任何基于 Ubuntu 的发行版上直接在终端上输入以下内容进行安装:
|
||||
|
||||
```
|
||||
sudo apt install gnome-boxes
|
||||
```
|
||||
|
||||
一旦你安装了 Boxes,从这里安装 GNOME OS 就相当容易了。
|
||||
|
||||
#### 安装 GNOME OS
|
||||
|
||||
安装好 Boxes 后,你需要启动程序。接下来,点击窗口左上角的 “+” 标志,然后点击 “操作系统下载”,如下图所示。
|
||||
|
||||
![][7]
|
||||
|
||||
这个选项可以让你直接下载镜像文件,然后就可以继续安装它。
|
||||
|
||||
你所需要做的就是搜索 “GNOME”,然后你应该会找到可用的每夜构建版。这可以确保你正在尝试最新和最优秀的 GNOME 开发版本。
|
||||
|
||||
另外,你也可以前往 [GNOME OS 每夜构建网站][8] 下载系统镜像,然后在 Boxes 应用中选择 “运行系统镜像文件” 选择该 ISO,如上图截图所示,继续安装。
|
||||
|
||||
![][9]
|
||||
|
||||
考虑到你没有单独下载镜像。当你点击后,应该会开始下载,并且会出现一个进度条。
|
||||
|
||||
![][10]
|
||||
|
||||
完成后,如果需要,它会要求你自定义配置,让你创建虚拟机,如下图所示。
|
||||
|
||||
![][11]
|
||||
|
||||
你可以根据你可用的系统资源来定制资源分配,但应该可以使用默认设置。
|
||||
|
||||
点击 “创建”,就会直接开始 GNOME OS 的安装。
|
||||
|
||||
![][12]
|
||||
|
||||
选择“使用现有的版本”,然后继续。接下来,你必须选择磁盘(保持原样),然后同意擦除你所有的文件和应用程序(它不会删除本地计算机上的任何东西)。
|
||||
|
||||
![][13]
|
||||
|
||||
现在,它将简单地重新格式化并安装它。然后就完成了。它会提示你重启,重启后,你会发现 GNOME OS 已经安装好了。
|
||||
|
||||
它会像其他 Linux 发行版一样简单地启动,并要求你设置一些东西,包括用户名和密码。然后,你就可以开始探索了。
|
||||
|
||||
如果你想知道它的样子,它基本上就是最新的 GNOME 桌面环境。在 GNOME 40 正式发布之前,我用 GNOME OS 做了一个 GNOME 40 的概述视频。
|
||||
|
||||
### 结束语
|
||||
|
||||
GNOME OS 绝对是对开发者、设计师和媒体有用的东西。它可以让你轻松地测试最新的 GNOME 开发版本,而无需投入大量的时间。
|
||||
|
||||
我可以很快地测试 [GNOME 40][14],就是因为这个。当然,你要记住,这并不是一个可以在物理设备上安装的完整功能的操作系统。他们有计划让它可以在物理机器上运行,但就目前而言,它只是为虚拟机量身定做的,尤其是使用 GNOME Boxes。
|
||||
|
||||
GNOME Boxes 并没有提供任何高级选项,所以设置和使用它变得相当容易。如果体验太慢的话,你可能要调整一下资源,但在我的情况下,总体来说是一个不错的体验。
|
||||
|
||||
你试过 GNOME OS 了吗?欢迎在下面的评论中告诉我你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/gnome-os/
|
||||
|
||||
作者:[Ankush Das][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://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoraproject.org/wiki/Releases/Rawhide
|
||||
[2]: https://blogs.gnome.org/alatiera/2020/10/07/what-is-gnome-os/
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/GNOME-OS-distro-review.png?resize=800%2C450&ssl=1
|
||||
[4]: https://itsfoss.com/what-is-flatpak/
|
||||
[5]: https://flathub.org/apps/details/org.gnome.Boxes
|
||||
[6]: https://itsfoss.com/flatpak-guide/
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-os-search.jpg?resize=800%2C729&ssl=1
|
||||
[8]: https://os.gnome.org/
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-os-boxes.jpg?resize=800%2C694&ssl=1
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-os-download.jpg?resize=798%2C360&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-boxes-vm-setup.png?resize=800%2C301&ssl=1
|
||||
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-nightly-install.jpg?resize=800%2C636&ssl=1
|
||||
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/gnome-os-installation.jpg?resize=800%2C619&ssl=1
|
||||
[14]: https://news.itsfoss.com/gnome-40-release/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (max27149)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
@ -85,7 +85,7 @@ via: https://opensource.com/article/21/2/advice-non-technical
|
||||
|
||||
作者:[Dawn Parzych][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[max27149](https://github.com/max27149)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,93 @@
|
||||
[#]: subject: (What motivates open source software contributors?)
|
||||
[#]: via: (https://opensource.com/article/21/4/motivates-open-source-contributors)
|
||||
[#]: author: (Igor Steinmacher https://opensource.com/users/igorsteinmacher)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
What motivates open source software contributors?
|
||||
======
|
||||
New study finds people's reasons for contributing have changed since the
|
||||
early 2000s.
|
||||
![Practicing empathy][1]
|
||||
|
||||
The reasons people contribute to free and open source (FOSS) projects has been a topic of much interest. However, the research on this topic dates back 10 or more years, and much has changed in the world since then. This article shares seven insights from a recent research study that revisited old motivation studies and asked open source contributors what motivates them today.
|
||||
|
||||
These insights can be used by open source community managers who want to grow a community, organizations that want to understand how community members behave, or anyone working with others in open source. Understanding what motivates today's contributors helps us make impactful decisions.
|
||||
|
||||
### A brief history of open source motivation research
|
||||
|
||||
We need to look into the origins of open source and the free software movement to understand why studying what motivates contributors is so fascinating. When the free software movement started, it was in defiance of corporations using copyright and license terms to restrict user and developer freedoms. The free software movement is a story of rebellion. It was difficult for many to understand how high-quality software emerged from a movement of people who "scratched their own itch" or "volunteered" their skills. At the core of the free software movement was a collaborative way for creating software that became interesting to companies as well. The emergence of open source was a philosophical shift to make this collaboration method available and acceptable to businesses.
|
||||
|
||||
The state of the art of research into motivation in open source is a [publication from 2012][2] that summarizes research studies from more than a decade prior. Gordon Haff reviewed this topic in [_Why do we contribute to open source software?_][3] and Ruth Suehle in _[Drive and motivation: Daniel Pink webcast recap][4]_.
|
||||
|
||||
Over the last 10 years, much has changed in open source. With corporations' increasing interest in open source and having paid employees working on open source projects, it was high time to revisit motivation in open source.
|
||||
|
||||
### Contributors' changing motivations
|
||||
|
||||
In our scientific study, _[The shifting sands of motivation: Revisiting what drives contributors in open source][5]_, we investigated why people join FOSS projects and why they continue contributing. One of our goals was to study how contributors' motivations have changed since the 2000s. A second goal was to take the research to the next level and investigate how people's motivations change as they continue contributing. The research is based on a questionnaire answered by almost 300 FOSS contributors in late 2020.
|
||||
|
||||
### Seven key findings
|
||||
|
||||
Some of the study's results include:
|
||||
|
||||
1. **Intrinsic motivations play a key role.** The large majority of people contribute to FOSS because of fun (91%), altruism (85%), and kinship (80%). Moreover, when analyzing differences in motivations to join and continue, the study found that ideology, own-use, or education-related programs can be an impetus to join FOSS, but individuals continue for intrinsic reasons (fun, altruism, reputation, and kinship).
|
||||
|
||||
2. **Reputation and career motivate more than payment**. Many contributors seek reputation (68%) and career (67%), while payment was referenced by less than 30% of the participants. Compared to earlier studies, reputation is now considered more important.
|
||||
|
||||
3. **Social aspects have gained considerable importance since the 2000s.** Enjoying helping others (89%) and kinship (80%) rose in the rankings compared to surveys from the early 2000s.
|
||||
|
||||
4. **Motivation changes as people gain tenure.** A clear outcome of the paper is that current contributors often have a different motivation from what led them to join. Of the 281 respondents, 155 (55%) did not report the same motivation for joining and continuing to contribute.
|
||||
|
||||
The figure below shows individuals' shifts in motivation from when they joined to what leads them to keep contributing. The size of the boxes on the left represents the number of contributors with that motivation to start contributing to FOSS, and on the right, the motivation to continue contributing. The width of the connections is proportional to the number of contributors who shifted from one motivation to the other.
|
||||
|
||||
![Motivations for contributing to FOSS][6]
|
||||
|
||||
(Source: [Gerosa, et al.][7])
|
||||
|
||||
5. **Scratching one's own itch is a doorway.** Own-use ("scratch own itch") has decreased in importance since the early days. The contributors who joined FOSS for own-use-related reasons often shifted to altruism, learning, fun, and reciprocity. You can see this in the figure above.
|
||||
|
||||
6. **Experience and age explain different motivations**. Experienced developers have higher rates of reporting altruism (5.6x), pay (5.2x), and ideology (4.6x) than novices, who report career (10x), learning (5.5x), and fun (2.5x) as greater motivations to contribute. Looking at individual shifts in motivation, there was a considerable increase (120%) in altruism for experienced respondents and a slight decrease (-16%) for novices. A few young respondents joined FOSS because of career, but many of them shifted towards altruism (100% increase).
|
||||
|
||||
7. **Coders and non-coders report different motivations.** The odds of a coder reporting fun is 4x higher than non-coders, who are more likely (2.5x) to report ideology as a motivator.
|
||||
|
||||
|
||||
|
||||
|
||||
### Motivating contributors based on their contributor journey
|
||||
|
||||
Knowing how new and long-time contributors differ in motivation helps us discover how to support them better.
|
||||
|
||||
For example, to attract and retain new contributors, who might become the future workforce, projects could invest in promoting career, fun, kinship, and learning, which are particularly relevant for young contributors.
|
||||
|
||||
Because over time altruism becomes more important to contributors, FOSS projects aiming to retain experienced contributors, who tend to be core members or maintainers, could invest in strategies and tools showing how their work benefits the community and society (altruism) and improve social interactions.
|
||||
|
||||
Also in response to the increased rank of altruism, hosting platforms could offer social features to pair those needing help with those willing to help, highlight when a contributor helps someone, and make it easier to show appreciation to others (similar to stars given to projects).
|
||||
|
||||
These are some of our ideas after reviewing the study's findings. We hope that sharing our insights helps others with different backgrounds and experiences come up with more ideas for using this data to motivate new and seasoned contributors. Please share your ideas in the comments below.
|
||||
|
||||
The research paper's authors are Marco A. Gerosa (Northern Arizona University), Igor Wiese (Universidade Tecnologica Federal do Paraná), Bianca Trinkenreich (Northern Arizona University), Georg Link (Bitergia), Gregorio Robles (Universidad Rey Juan Carlos), Christoph Treude (University of Adelaide), Igor Steinmacher (Universidade Tecnologica Federal do Paraná), and Anita Sarma (Oregon State University). The full [study report][7] is available, as well as the [anonymized data and artifacts][8] related to the research.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/motivates-open-source-contributors
|
||||
|
||||
作者:[Igor Steinmacher][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/igorsteinmacher
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/practicing-empathy.jpg?itok=-A7fj6NF (Practicing empathy)
|
||||
[2]: https://www.semanticscholar.org/paper/Carrots-and-Rainbows%3A-Motivation-and-Social-in-Open-Krogh-Haefliger/52ec46a827ba5d6aeb38aaeb24b0780189c16856?p2df
|
||||
[3]: https://opensource.com/article/19/11/why-contribute-open-source-software
|
||||
[4]: https://opensource.com/business/11/6/today-drive-webcast-daniel-pink
|
||||
[5]: https://arxiv.org/abs/2101.10291
|
||||
[6]: https://opensource.com/sites/default/files/pictures/sankey_motivations.png (Motivations for contributing to FOSS)
|
||||
[7]: https://arxiv.org/pdf/2101.10291.pdf
|
||||
[8]: https://zenodo.org/record/4453904#.YFtFRa9KhaR
|
@ -1,68 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (max27149)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 benefits of choosing Linux)
|
||||
[#]: via: (https://opensource.com/article/21/2/linux-choice)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
5 benefits of choosing Linux
|
||||
======
|
||||
One of the great things about Linux is choice, and choice inspires users
|
||||
to freely share ideas and solutions. How will Linux inspire you to
|
||||
contribute to this community?
|
||||
![Hand putting a Linux file folder into a drawer][1]
|
||||
|
||||
In 2021, there are more reasons why people love Linux than ever before. In this series, I'll share 21 different reasons to use Linux. This article discusses the benefit of choice Linux brings.
|
||||
|
||||
_Choice_ is one of the most misunderstood features of Linux. It starts with how many Linuxes there are to choose from. Distrowatch.org reports hundreds of available and active Linux distributions. Many of these distributions, of course, are hobby projects or extremely specific to some obscure requirement. Because it's open source, in fact, anyone can "re-spin" or "remix" an existing distribution of Linux, give it a new name, maybe a new default wallpaper, and call it their own. And while that may seem trivial, I see it as an indication of something very special.
|
||||
|
||||
### Inspiration
|
||||
|
||||
Linux, it seems, inspires people, from the very moment they learn about it, to make it their own.
|
||||
|
||||
There are dozens of companies spending millions of dollars to generate inspiration from their product. Commercials for technology overwhelmingly try to convince you that as long as you buy some product, you'll feel more connected to the people you care about, more creative, and more alive. Shot in 4k video with soft focus and played to the beat of cheerful and uplifting music, these advertisements are attempts to convince people to not only purchase but then also to support and advertise that company's product.
|
||||
|
||||
Of course, Linux has essentially no marketing budget because Linux is a diverse collection of individuals, a body _discorporate_. Yet when people discover it, they are seemingly inspired to build their own version of it.
|
||||
|
||||
It's difficult to quantify amounts of inspiration, but there's obvious value to it, or else companies wouldn't spend money in an attempt to create it.
|
||||
|
||||
### Innovation
|
||||
|
||||
Inspiration, however difficult it is to put a price tag on it, is valuable because of what it produces. Many Linux users have been inspired to create custom solutions to odd problems. Many of the problems we each solve seem trivial to most other people. Maybe you monitor moisture levels of your tomato plant's soil with a [Seeed micro-controller][2], or you have a script to search through an index of Python packages because you keep forgetting the names of libraries you import every day, or you've automated cleaning out your Downloads folder because dragging icons to the Trash is too much work. Whatever problem you've solved for yourself on Linux, it's a feature of the platform that you're inspired by the open technology you're running to make it work better for yourself.
|
||||
|
||||
### Staying out of the way
|
||||
|
||||
Of course, neither inspiration nor innovation are exclusive properties of Linux. Other platforms do authentically produce inspiration in us, and we do innovate in small and huge ways. Computing has largely leveled most playing fields, and anything you can do on one OS, you can likely find a way to do on another.
|
||||
|
||||
What many users find, however, is that the Linux operating system maintains a firm policy of staying out of your way when you have the idea of trying something that possibly nobody else has thought to try yet. This doesn't and cannot happen, by design, on a proprietary operating system because there's just no way to get into certain areas of the system because they don't happen to be open source. There are arbitrary blockades. You tend not to bump up against invisible walls when you're doing exactly what the OS expects you to do, but when you have it in mind to do something that makes sense only to you, your environment may fail to adapt.
|
||||
|
||||
### Small choices and why they matter
|
||||
|
||||
Not all innovations are big or important, but collectively they make a big difference. The crazy ideas that millions of users have had are evident today in every part of Linux. They're in the ways that the KDE and GNOME desktops work, they're in [31 different text editors][3] each of them loved by someone, and countless plugins for browsers and media applications, in file systems and extended attributes, and in the millions of lines of the Linux kernel. And if just one of these features gives you an extra hour each day to spend with your family or friends or hobby, then it's by definition, to use an over-used phrase, "life-changing."
|
||||
|
||||
### Connecting with a community
|
||||
|
||||
An important part of open source is the sharing of work. Sharing code is the obvious, prevalent transaction of open source software, but I think there's a lot more to the act of sharing than just making a commit to Gitlab. When people share their ideas with one another, with no ulterior motive aside from potentially getting useful code contributions in return, we all recognize it as a gift. It feels very different from when you purchase software from a company, and it's even different from when a company shares open source code they've produced. The reality of open source is that it's made by humans for humans. There's a connection created when knowledge and inspiration are given freely. It's not something that a marketing campaign can replicate, and I think that we recognize that.
|
||||
|
||||
### Choice
|
||||
|
||||
Linux isn't the only platform with a lot of choices. You can find several solutions to the same problem regardless of your OS, especially when you delve into open source software. However, the level of choice evident on Linux is indicative of what drives Linux forward: The invitation to collaborate. Some things created on Linux fade quickly away, others stay on your home computer for years doing whatever small mundane task you've automated, and others are so successful that they get borrowed by other platforms and become commonplace. It doesn't matter. Whatever you create on Linux, don't hesitate to add it to the cacophony of choice. You never know who it might inspire.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/2/linux-choice
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/yearbook-haff-rx-linux-file-lead_0.png?itok=-i0NNfDC (Hand putting a Linux file folder into a drawer)
|
||||
[2]: https://opensource.com/article/19/12/seeeduino-nano-review
|
||||
[3]: https://opensource.com/article/21/1/text-editor-roundup
|
@ -1,170 +0,0 @@
|
||||
[#]: subject: (How to use the Linux anacron command)
|
||||
[#]: via: (https://opensource.com/article/21/2/linux-automation)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
How to use the Linux anacron command
|
||||
======
|
||||
Instead of manually performing repetitive tasks, let Linux do them for
|
||||
you.
|
||||
![Command line prompt][1]
|
||||
|
||||
In 2021, there are more reasons why people love Linux than ever before. In this series, I'll share 21 different reasons to use Linux. Automation is one of the best reasons to use Linux.
|
||||
|
||||
One of my favorite things about Linux is its willingness to do work for me. Instead of performing repetitive tasks that eat up my time, or are prone to error, or that I'm likely to forget, I schedule Linux to do them for me.
|
||||
|
||||
### Preparing for automation
|
||||
|
||||
The term "automation" can be as intimidating as it is appealing. I find it helps to approach it modularly.
|
||||
|
||||
#### 1\. What do you want to make happen?
|
||||
|
||||
First, know what outcome you want to produce. Are you watermarking images? Removing files from a cluttered directory? Performing a backup of important data? Define the task clearly for yourself so that you know what to aim for. If there's any task you find yourself doing every day, much less more than once a day, then it could be a candidate for automation.
|
||||
|
||||
#### 2\. Learn the applications you need
|
||||
|
||||
Break down big tasks into small components and learn how to produce each result manually but in a repeatable and predictable way. Much of what can be done on Linux can be scripted, but it's important to recognize your current limitations. There's a world of difference between learning how to automate resizing several images so that they can be emailed conveniently vs. using machine learning to generate elaborate artwork for your weekly newsletter. One of these things you can learn in an afternoon and the other could take years. However, we all have to start somewhere, so just start small and always be on the lookout for ways to improve.
|
||||
|
||||
#### 3\. Automate it
|
||||
|
||||
Use an automation tool on Linux to make it happen on a regular basis. This is the step this article covers!
|
||||
|
||||
To automate something, you need a script that automates a task. When testing, it's best to keep things simple, so the task this article automates is the creation of a file called `hello` in the `/tmp` directory:
|
||||
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
touch /tmp/hello
|
||||
```
|
||||
|
||||
Copy and paste that simple script into a text file and name it `example`.
|
||||
|
||||
### Cron
|
||||
|
||||
The built-in automation solution that every Linux install comes with is the cron system. Linux users tend to refer to cron generically as the method you use to schedule a task (usually called a "cron job"), but there are multiple applications that provide cron's functionality. The most versatile is [cronie][2]; its advantage is that it does _not_ assume that your computer is always on, the way historical cron applications designed for system administrators do.
|
||||
|
||||
Verify which cron system your Linux distribution provides. If it's anything other than cronie, you can probably install cronie from your distro's software repository. If your distribution doesn't have a package for cronie, you can use the old `anacron` package instead. The `anacron` command is included with cronie, so regardless of how you acquire it, you want to ensure that you have the `anacron` command available on your system before continuing. Anacron may require administrative root privileges, depending on your setup.
|
||||
|
||||
|
||||
```
|
||||
$ which anacron
|
||||
/usr/sbin/anacron
|
||||
```
|
||||
|
||||
Anacron's job is to ensure that your automation jobs are executed on a regular basis. To do this, anacron checks to find out when the last time a job ran and then checks how often you have told it to run jobs.
|
||||
|
||||
Suppose you set anacron to run a script once every five days. Every time you turn your computer on or wake it from sleep, anacron scans its logs to determine whether it needs to run the job. If a job ran five or more days ago, then anacron runs the job.
|
||||
|
||||
### Cron jobs
|
||||
|
||||
Many Linux systems come bundled with a few maintenance jobs for cron to perform. I like to keep my jobs separate from the system jobs, so I create a directory in my home directory. Specifically, there's a hidden folder called `~/.local` ("local" in the sense that it's customized for your user account rather than for your "global" computer system), so I create the subdirectory `etc/cron.daily` to mirror cron's usual home on my system. You must also create a spool directory to keep track of the last time jobs were run.
|
||||
|
||||
|
||||
```
|
||||
`$ mkdir -p ~/.local/etc/cron.daily ~/.var/spool/anacron`
|
||||
```
|
||||
|
||||
You can place any script you want to run regularly into the `~/.local/etc/cron.daily` directory. Copy the `example` script into the directory now, and [mark it executable using the chmod command][3].
|
||||
|
||||
|
||||
```
|
||||
$ cp example ~/.local/etc/cron.daily
|
||||
# chmod +x ~/.local/etc/cron.daily/example
|
||||
```
|
||||
|
||||
Next, set up anacron to run whatever scripts are located in the `~/.local/etc/cron.daily` directory.
|
||||
|
||||
### Anacron
|
||||
|
||||
By default, much of the cron system is considered the systems administrator's domain because it's often used for important low-level tasks, like rotating log files and updating certificates. The configuration demonstrated in this article is designed for a regular user setting up personal automation tasks.
|
||||
|
||||
To configure anacron to run your cron jobs, create a configuration file at `/.local/etc/anacrontab`:
|
||||
|
||||
|
||||
```
|
||||
SHELL=/bin/sh
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
1 0 cron.mine run-parts /home/tux/.local/etc/cron.daily/
|
||||
```
|
||||
|
||||
This file tells anacron to run all executable scripts (`run-parts`) found in `~/.local/etc/cron.daily` every one day (that is, daily), with a zero-minute delay. Sometimes, a few minutes' delay is used so that your computer isn't hit with all the possible tasks right after you log in. These settings are suitable for testing, though.
|
||||
|
||||
The `cron.mine` value is an arbitrary name for the process. I call it `cron.mine` but you could call it `cron.personal` or `penguin` or anything you want.
|
||||
|
||||
Verify your `anacrontab` file's syntax:
|
||||
|
||||
|
||||
```
|
||||
$ anacron -T -t ~/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
Silence means success.
|
||||
|
||||
### Adding anacron to .profile
|
||||
|
||||
Finally, you must ensure that anacron runs with your local configuration. Because you're running anacron as a regular user and not as the root user, you must direct it to your local configurations —the `anacrontab` file telling anacron what to do, and the spool directory helping anacron keep track of how many days it's been since each job was last executed:
|
||||
|
||||
|
||||
```
|
||||
anacron -fn -t /home/tux/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
The `-fn` options tell anacron to _ignore_ timestamps, meaning that you're forcing it to run your cron job no matter what. This is exclusively for testing purposes.
|
||||
|
||||
### Testing your cron job
|
||||
|
||||
Now that everything's set up, you can test the job. You can technically test this without rebooting, but it makes the most sense to reboot because that's what this is designed to handle: interrupted and irregular login sessions. Take a moment to reboot your computer, log in, and then look for the test file:
|
||||
|
||||
|
||||
```
|
||||
$ ls /tmp/hello
|
||||
/tmp/hello
|
||||
```
|
||||
|
||||
Assuming the file exists, your example script has executed successfully. You can now remove the test options from `~/.profile`, leaving this as your final configuration:
|
||||
|
||||
|
||||
```
|
||||
anacron -t /home/tux/.local/etc/anacrontab \
|
||||
-S /home/tux/.var/spool/anacron
|
||||
```
|
||||
|
||||
### Using anacron
|
||||
|
||||
You have your personal automation infrastructure configured, so you can place any script you want your computer to manage for you into the `~/.local/etc/cron.daily` directory and it will run as scheduled.
|
||||
|
||||
It's up to you how often you want jobs to run. Your example script is executed once a day. Obviously, that depends on whether your computer is powered on and awake on any given day. If you use your computer on Friday but set it aside for the weekend, the script won't run on Saturday and Sunday. However, on Monday the script will execute because anacron will know that at least one day has passed. You can add weekly, fortnightly, or even monthly directories to `~/.local/etc` to schedule a wide variety of intervals.
|
||||
|
||||
To add a new interval:
|
||||
|
||||
1. Add a directory to `~/.local/etc` (for instance, `cron.weekly`).
|
||||
2. Add a line to `~/.local/etc/anacrontab` to run scripts in the new directory. For a weekly interval, the configuration would be: [code]`7 0 cron.mine run-parts /home/tux/.local/etc/cron.weekly/`[/code] (with the `0` value optionally being some number of minutes to politely delay the start of the script).
|
||||
3. Place your scripts in the `cron.weekly` directory.
|
||||
|
||||
|
||||
|
||||
Welcome to the automated lifestyle. It won't feel like it, but you're about to become a lot more productive.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/2/linux-automation
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
|
||||
[2]: https://github.com/cronie-crond/cronie
|
||||
[3]: https://opensource.com/article/19/8/linux-chmod-command
|
@ -1,71 +0,0 @@
|
||||
[#]: subject: (5 signs you might be a Rust programmer)
|
||||
[#]: via: (https://opensource.com/article/21/3/rust-programmer)
|
||||
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
5 signs you might be a Rust programmer
|
||||
======
|
||||
During my journey to learning Rust, I've noticed a few common behaviors
|
||||
of fellow Rustaceans.
|
||||
![name tag that says hello my name is open source][1]
|
||||
|
||||
I'm a fairly recent [convert to Rust][2], which I started to learn around the end of April 2020. But, like many converts, I'm an enthusiastic evangelist. I'm also not a very good Rustacean, truth be told, in that my coding style isn't great, and I don't write particularly idiomatic Rust. I suspect this is partly because I never really finished learning Rust before diving in and writing quite a lot of code (some of which is coming back to haunt me) and partly because I'm just not that good a programmer.
|
||||
|
||||
But I love Rust, and so should you. It's friendly—well, more friendly than C or C++; it's ready for low-level systems tasks—more so than Python, it's well-structured—more than Perl; and, best of all, it's completely open source from the design level up—much more than Java, for instance.
|
||||
|
||||
Despite my lack of expertise, I noticed a few things that I suspect are common to many Rust enthusiasts and programmers. If you say "yes" to the following five signs (the first of which was sparked by some exciting recent news), you, too, might be a Rust programmer.
|
||||
|
||||
### 1\. The word "foundation" excites you
|
||||
|
||||
For Rust programmers, the word "foundation" will no longer be associated first and foremost with Isaac Asimov but with the newly formed [Rust Foundation][3]. Microsoft, Huawei, Google, AWS, and Mozilla are providing the directors (and presumably most of the initial funding) for the Foundation, which will look after all aspects of the language, "heralding Rust's arrival as an enterprise production-ready technology," [according to interim executive director][4] Ashley Williams. (On a side note, it's great to see a woman heading up such a major industry initiative.)
|
||||
|
||||
The Foundation seems committed to safeguarding the philosophy of Rust and ensuring that everybody has the opportunity to get involved. Rust is, in many ways, a poster-child example of an open source project. Not that it's perfect (neither the language nor the community), but in that there seem to be sufficient enthusiasts who are dedicated to preserving the high-involvement, low-bar approach to community, which I think of as core to much of open source. I strongly welcome the move, which I think can only help promote Rust's adoption and maturity over the coming years and months.
|
||||
|
||||
### 2\. You get frustrated by newsfeed references to Rust (the game)
|
||||
|
||||
There's another computer-related thing out there that goes by the name "Rust," and it's a "multi-player only survival video game." It's newer than Rust the language (having been announced in 2013 and released in 2018), but I was once searching for Rust-related swag and made the mistake of searching for the game by that name. The interwebs being what they are, this meant that my news feed is now infected with this alternative Rust beast, and I now get random updates from their fandom and PR folks. This is low-key annoying, but I'm pretty sure I'm not alone in the Rust (language) community. I strongly suggest that if you _do_ want to find out more about this upstart in the computing world, you use a privacy-improving (I refuse to say "privacy-preserving") [open source browser][5] to do your research.
|
||||
|
||||
### 3\. The word "unsafe" makes you recoil in horror
|
||||
|
||||
Rust (the language, again) does a _really_ good job of helping you do the Right Thing™, certainly in terms of memory safety, which is a major concern within C and C++ (not because it's impossible but because it's really hard to get right consistently). Dave Herman wrote a post in 2016 on why safety is such a positive attribute of the Rust language: [_Safety is Rust's fireflower_][6]. Safety (memory, type safety) may not be glamourous, but it's something you become used to—and grateful for—as you write more Rust, particularly if you're involved in any systems programming, which is where Rust often excels.
|
||||
|
||||
Now, Rust doesn't _stop_ you from doing the Wrong Thing™, but it does make you make a conscious decision when you wish to go outside the bounds of safety by making you use the `unsafe` keyword. This is good not only for you, as it will (hopefully) make you think really, really carefully about what you're putting in any code block that uses it; it is also good for anyone reading your code. It's a trigger-word that makes any half-sane Rustacean shiver at least slightly, sit upright in their chair, and think, "hmm, what's going on here? I need to pay special attention." If you're lucky, the person reading your code may be able to think of ways of rewriting it such that it _does_ make use of Rust's safety features or at least reduces the amount of unsafe code that gets committed and released.
|
||||
|
||||
### 4\. You wonder why there's no emoji for `?;` or `{:?}` or `::<>`
|
||||
|
||||
Everybody loves (to hate) the turbofish (`::<>`) but there are other semantic constructs that you see regularly in Rust code. In particular, `{:?}` (for string formatting) and `?;` (`?` is a way of propagating errors up the calling stack, and `;` ends the line/block, so you often see them together). They're so common in Rust code that you just learn to parse them as you go, and they're also so useful that I sometimes wonder why they've not made it into normal conversation, at least as emojis. There are probably others, too. What would be your suggestions?
|
||||
|
||||
### 5\. Clippy is your friend (and not an animated paperclip)
|
||||
|
||||
Clippy, the Microsoft animated paperclip, was a "feature" that Office users learned very quickly to hate and has become the starting point for many [memes][7]. On the other hand, `cargo clippy` is one of those [amazing Cargo commands][8] that should become part of every Rust programmer's toolkit. Clippy is a language linter and helps improve your code to make it cleaner, tidier, more legible, more idiomatic, and generally less embarrassing when you share it with your colleagues or the rest of the world. Cargo has arguably rehabilitated the name "Clippy," and although it's not something I'd choose to name one of my kids, I don't feel a sense of unease whenever I come across the term on the web anymore.
|
||||
|
||||
* * *
|
||||
|
||||
_This article was originally published on [Alice, Eve, and Bob][9] and is reprinted with the author's permission._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/rust-programmer
|
||||
|
||||
作者:[Mike Bursell][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/mikecamel
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_OSDC_IntroOS_520x292_FINAL.png?itok=woiZamgj (name tag that says hello my name is open source)
|
||||
[2]: https://opensource.com/article/20/6/why-rust
|
||||
[3]: https://foundation.rust-lang.org/
|
||||
[4]: https://foundation.rust-lang.org/posts/2021-02-08-hello-world/
|
||||
[5]: https://opensource.com/article/19/7/open-source-browsers
|
||||
[6]: https://www.thefeedbackloop.xyz/safety-is-rusts-fireflower/
|
||||
[7]: https://knowyourmeme.com/memes/clippy
|
||||
[8]: https://opensource.com/article/20/11/commands-rusts-cargo
|
||||
[9]: https://aliceevebob.com/2021/02/09/5-signs-that-you-may-be-a-rust-programmer/
|
@ -1,92 +0,0 @@
|
||||
[#]: subject: (Plausible: Privacy-Focused Google Analytics Alternative)
|
||||
[#]: via: (https://itsfoss.com/plausible/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Plausible: Privacy-Focused Google Analytics Alternative
|
||||
======
|
||||
|
||||
[Plausible][1] is a simple, privacy-friendly analytics tool. It helps you analyze the number of unique visitors, pageviews, bounce rate and visit duration.
|
||||
|
||||
If you have a website you would probably understand those terms. As a website owner, it helps you know if your site is getting more visitors over the time, from where the traffic is coming and if you have some knowledge on these things, you can work on improving your website for more visits.
|
||||
|
||||
When it comes to website analytics, the one service that rules this domain is the Google’s free tool Google Analytics. Just like Google is the de-facto search engine, Google Analytics is the de-facto analytics tool. But you don’t have to live with it specially if you cannot trust Big tech with your and your site visitor’s data.
|
||||
|
||||
Plausible gives you the freedom from Google Analytics and I am going to discuss this open source project in this article.
|
||||
|
||||
Please mind that some technical terms in the article could be unknown to you if you have never managed a website or bothered about analytics.
|
||||
|
||||
### Plausible for privacy friendly website analytics
|
||||
|
||||
The script used by Plausible for analytics is extremely lightweight with less than 1 KB in size.
|
||||
|
||||
The focus is on preserving the privacy so you get valuable and actionable stats without compromising on the privacy of your visitors. Plausible is one of the rare few analytics tool that doesn’t require cookie banner or GDP consent because it is already [GDPR-compliant][2] on privacy front. That’s super cool.
|
||||
|
||||
In terms of features, it doesn’t have the same level of granularity and details of Google Analytics. Plausible banks on simplicity. It shows a graph of your traffic stats for past 30 days. You may also switch to real time view.
|
||||
|
||||
![][3]
|
||||
|
||||
You can also see where your traffic is coming from and which pages on your website gets the most visits. The sources can also show UTM campaigns.
|
||||
|
||||
![][4]
|
||||
|
||||
You also have the option to enable GeoIP to get some insights about the geographical location of your website visitors. You can also check how many visitors use desktop or mobile device to visit your website. There is also an option for operating system and as you can see, [Linux Handbook][5] gets 48% of its visitors from Windows devices. Pretty strange, right?
|
||||
|
||||
![][6]
|
||||
|
||||
Clearly, the data provided is nowhere close to what Google Analytics can do, but that’s intentional. Plausible intends to provide you simple matrix.
|
||||
|
||||
### Using Plausible: Opt for paid managed hosting or self-host it on your server
|
||||
|
||||
There are two ways you can start using Plausible. Sign up for their official managed hosting. You’ll have to pay for the service and this eventually helps the development of the Plausible project. They do have 30-days trial period and it doesn’t even require any payment information from your side.
|
||||
|
||||
The pricing starts at $6 per month for 10k monthly pageviews. Pricing increases with the number of pageviews. You can calculate the pricing on Plausible website.
|
||||
|
||||
[Plausible Pricing][7]
|
||||
|
||||
You can try it for 30 days and see if you would like to pay to Plausible developers for the service and own your data.
|
||||
|
||||
If you think the pricing is not affordable, you can take the advantage of the fact that Plausible is open source and deploy it yourself. If you are interested, read our [in-depth guide on self-hosting a Plausible instance with Docker][8].
|
||||
|
||||
At It’s FOSS, we self-host Plausible. Our Plausible instance has three of our websites added.
|
||||
|
||||
![Plausble dashboard for It’s FOSS websites][9]
|
||||
|
||||
If you maintain the website of an open source project and would like to use Plausible, you can contact us through our [High on Cloud project][10]. With High on Cloud, we help small businesses host and use open source software on their servers.
|
||||
|
||||
### Conclusion
|
||||
|
||||
If you are not super obsessed with data and just want a quick glance on how your website is performing, Plausible is a decent choice. I like it because it is lightweight and privacy compliant. That’s the main reason why I use it on Linux Handbook, our [ethical web portal for teaching Linux server related stuff][11].
|
||||
|
||||
Overall, I am pretty content with Plausible and recommend it to other website owners.
|
||||
|
||||
Do you run or manage a website as well? What tool do you use for the analytics or do you not care about that at all?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/plausible/
|
||||
|
||||
作者:[Abhishek Prakash][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://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://plausible.io/
|
||||
[2]: https://gdpr.eu/compliance/
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-graph-lhb.png?resize=800%2C395&ssl=1
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-stats-lhb-2.png?resize=800%2C333&ssl=1
|
||||
[5]: https://linuxhandbook.com/
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-geo-ip-stats.png?resize=800%2C331&ssl=1
|
||||
[7]: https://plausible.io/#pricing
|
||||
[8]: https://linuxhandbook.com/plausible-deployment-guide/
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/plausible-analytics-for-itsfoss.png?resize=800%2C231&ssl=1
|
||||
[10]: https://highoncloud.com/
|
||||
[11]: https://linuxhandbook.com/about/#ethical-web-portal
|
@ -1,190 +0,0 @@
|
||||
[#]: subject: (Why I love using the IPython shell and Jupyter notebooks)
|
||||
[#]: via: (https://opensource.com/article/21/3/ipython-shell-jupyter-notebooks)
|
||||
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Why I love using the IPython shell and Jupyter notebooks
|
||||
======
|
||||
Jupyter notebooks take the IPython shell to the next level.
|
||||
![Computer laptop in space][1]
|
||||
|
||||
The Jupyter project started out as IPython and the IPython Notebook. It was originally a Python-specific interactive shell and notebook environment, which later branched out to become language-agnostic, supporting Julia, Python, and R—and potentially anything else.
|
||||
|
||||
![Jupyter][2]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
IPython is a Python shell—similar to what you get when you type `python` or `python3` at the command line—but it's more clever and more helpful. If you've ever typed a multi-line command into the Python shell and wanted to repeat it, you'll understand the frustration of having to scroll through your history one line at a time. With IPython, you can scroll back through whole blocks at a time while still being able to navigate line-by-line and edit parts of those blocks.
|
||||
|
||||
![iPython][4]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
It has autocompletion and provides context-aware suggestions:
|
||||
|
||||
![iPython offers suggestions][5]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
It pretty-prints by default:
|
||||
|
||||
![iPython pretty prints][6]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
It even allows you to run shell commands:
|
||||
|
||||
![IPython shell commands][7]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
It also provides helpful features like adding `?` to an object as a shortcut for running `help()` without breaking your flow:
|
||||
|
||||
![IPython help][8]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
If you're using a virtual environment (see my post on [virtualenvwrapper][9], install it with pip in the environment):
|
||||
|
||||
|
||||
```
|
||||
`pip install ipython`
|
||||
```
|
||||
|
||||
To install it system-wide, you can use apt on Debian, Ubuntu, or Raspberry Pi:
|
||||
|
||||
|
||||
```
|
||||
`sudo apt install ipython3`
|
||||
```
|
||||
|
||||
or with pip:
|
||||
|
||||
|
||||
```
|
||||
`sudo pip3 install ipython`
|
||||
```
|
||||
|
||||
### Jupyter notebooks
|
||||
|
||||
Jupyter notebooks take the IPython shell to the next level. First of all, they're browser-based, not terminal-based. To get started, install `jupyter`.
|
||||
|
||||
If you're using a virtual environment, install it with pip in the environment:
|
||||
|
||||
|
||||
```
|
||||
`pip install jupyter`
|
||||
```
|
||||
|
||||
To install it system-wide, you can use apt on Debian, Ubuntu, or Raspberry Pi:
|
||||
|
||||
|
||||
```
|
||||
`sudo apt install jupyter-notebook`
|
||||
```
|
||||
|
||||
or with pip:
|
||||
|
||||
|
||||
```
|
||||
`sudo pip3 install jupyter`
|
||||
```
|
||||
|
||||
Launch the notebook with:
|
||||
|
||||
|
||||
```
|
||||
`jupyter notebook`
|
||||
```
|
||||
|
||||
This will open in your browser:
|
||||
|
||||
![Jupyter Notebook][10]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
You can create a new Python 3 notebook using the **New** dropdown:
|
||||
|
||||
![Python 3 in Jupyter Notebook][11]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
Now you can write and execute commands in the `In[ ]` fields. Use **Enter** for a newline within the block and **Shift+Enter** to execute:
|
||||
|
||||
![Executing commands in Jupyter][12]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
You can edit and rerun blocks. You can reorder them, delete them, copy/paste, and so on. You can run blocks in any order—but be aware that any variables created will be in scope according to the time of execution, rather than the order they appear within the notebook. You can restart and clear output or restart and run all blocks from within the **Kernel** menu.
|
||||
|
||||
Using the `print` function will output every time. But if you only have a single statement that's not assigned or your last statement is unassigned, it will be output anyway:
|
||||
|
||||
![Jupyter output][13]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
You can even refer to `In` and `Out` as indexable objects:
|
||||
|
||||
![Jupyter output][14]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
All the IPython features are available and are often presented a little nicer, too:
|
||||
|
||||
![Jupyter supports IPython features][15]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
You can even do inline plots using [Matplotlib][16]:
|
||||
|
||||
![Graphing in Jupyter Notebook][17]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
Finally, you can save your notebooks and include them in Git repositories, and if you push to GitHub, they will render as completed notebooks—outputs, graphs, and all (as in [this example][18]):
|
||||
|
||||
![Saving Notebook to GitHub][19]
|
||||
|
||||
(Ben Nuttall, [CC BY-SA 4.0][3])
|
||||
|
||||
* * *
|
||||
|
||||
_This article originally appeared on Ben Nuttall's [Tooling Tuesday blog][20] and is reused with permission._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/ipython-shell-jupyter-notebooks
|
||||
|
||||
作者:[Ben Nuttall][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/bennuttall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_space_graphic_cosmic.png?itok=wu493YbB (Computer laptop in space)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/jupyterpreview.png (Jupyter)
|
||||
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/ipython-loop.png (iPython)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/ipython-suggest.png (iPython offers suggestions)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/ipython-pprint.png (iPython pretty prints)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/ipython-ls.png (IPython shell commands)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/ipython-help.png (IPython help)
|
||||
[9]: https://opensource.com/article/21/2/python-virtualenvwrapper
|
||||
[10]: https://opensource.com/sites/default/files/uploads/jupyter-notebook-1.png (Jupyter Notebook)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/jupyter-python-notebook.png (Python 3 in Jupyter Notebook)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/jupyter-loop.png (Executing commands in Jupyter)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/jupyter-cells.png (Jupyter output)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/jupyter-cells-2.png (Jupyter output)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/jupyter-help.png (Jupyter supports IPython features)
|
||||
[16]: https://matplotlib.org/
|
||||
[17]: https://opensource.com/sites/default/files/uploads/jupyter-graph.png (Graphing in Jupyter Notebook)
|
||||
[18]: https://github.com/piwheels/stats/blob/master/2020.ipynb
|
||||
[19]: https://opensource.com/sites/default/files/uploads/savenotebooks.png (Saving Notebook to GitHub)
|
||||
[20]: https://tooling.bennuttall.com/the-ipython-shell-and-jupyter-notebooks/
|
@ -2,7 +2,7 @@
|
||||
[#]: via: (https://opensource.com/article/21/3/python-package-index-json-apis-requests)
|
||||
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,180 +0,0 @@
|
||||
[#]: subject: (Use this open source tool to monitor variables in Python)
|
||||
[#]: via: (https://opensource.com/article/21/4/monitor-debug-python)
|
||||
[#]: author: (Tian Gao https://opensource.com/users/gaogaotiantian)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Use this open source tool to monitor variables in Python
|
||||
======
|
||||
Watchpoints is a simple but powerful tool to help you with monitoring
|
||||
variables while debugging Python.
|
||||
![Looking back with binoculars][1]
|
||||
|
||||
When debugging code, you're often faced with figuring out when a variable changes. Without any advanced tools, you have the option of using print statements to announce the variables when you expect them to change. However, this is a very ineffective way because the variables could change in many places, and constantly printing them to a terminal is noisy, while printing them to a log file becomes unwieldy.
|
||||
|
||||
This is a common issue, but now there is a simple but powerful tool to help you with monitoring variables: [watchpoints][2].
|
||||
|
||||
The [watchpoint concept is common in C and C++ debuggers][3] to monitor memories, but there's a lack of equivalent tools in Python. `watchpoints` fills in the gap.
|
||||
|
||||
### Installing
|
||||
|
||||
To use it, you must first install it by using `pip`:
|
||||
|
||||
|
||||
```
|
||||
`$ python3 -m pip install watchpoints`
|
||||
```
|
||||
|
||||
### Using watchpoints in Python
|
||||
|
||||
For any variable you'd like to monitor, use the **watch** function on it.
|
||||
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
a = 0
|
||||
watch(a)
|
||||
a = 1
|
||||
```
|
||||
|
||||
As the variable changes, information about its value is printed to **stdout**:
|
||||
|
||||
|
||||
```
|
||||
====== Watchpoints Triggered ======
|
||||
|
||||
Call Stack (most recent call last):
|
||||
<module> (my_script.py:5):
|
||||
> a = 1
|
||||
a:
|
||||
0
|
||||
->
|
||||
1
|
||||
```
|
||||
|
||||
The information includes:
|
||||
|
||||
* The line where the variable was changed.
|
||||
* The call stack.
|
||||
* The previous/current value of the variable.
|
||||
|
||||
|
||||
|
||||
It not only works with the variable itself, but it also works with object changes:
|
||||
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
a = []
|
||||
watch(a)
|
||||
a = {} # Trigger
|
||||
a["a"] = 2 # Trigger
|
||||
```
|
||||
|
||||
The callback is triggered when the variable **a** is reassigned, but also when the object assigned to a is changed.
|
||||
|
||||
What makes it even more interesting is that the monitor is not limited by the scope. You can watch the variable/object anywhere you want, and the callback is triggered no matter what function the program is executing.
|
||||
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
def func(var):
|
||||
var["a"] = 1
|
||||
|
||||
a = {}
|
||||
watch(a)
|
||||
func(a)
|
||||
```
|
||||
|
||||
For example, this code prints:
|
||||
|
||||
|
||||
```
|
||||
====== Watchpoints Triggered ======
|
||||
|
||||
Call Stack (most recent call last):
|
||||
|
||||
<module> (my_script.py:8):
|
||||
> func(a)
|
||||
func (my_script.py:4):
|
||||
> var["a"] = 1
|
||||
a:
|
||||
{}
|
||||
->
|
||||
{'a': 1}
|
||||
```
|
||||
|
||||
The **watch** function can monitor more than a variable. It can also monitor the attributes and an element of a dictionary or list.
|
||||
|
||||
|
||||
```
|
||||
from watchpoints import watch
|
||||
|
||||
class MyObj:
|
||||
def __init__(self):
|
||||
self.a = 0
|
||||
|
||||
obj = MyObj()
|
||||
d = {"a": 0}
|
||||
watch(obj.a, d["a"]) # Yes you can do this
|
||||
obj.a = 1 # Trigger
|
||||
d["a"] = 1 # Trigger
|
||||
```
|
||||
|
||||
This could help you narrow down to some specific objects that you are interested in.
|
||||
|
||||
If you are not happy about the format of the output, you can customize it. Just define your own callback function:
|
||||
|
||||
|
||||
```
|
||||
watch(a, callback=my_callback)
|
||||
|
||||
# Or set it globally
|
||||
|
||||
watch.config(callback=my_callback)
|
||||
```
|
||||
|
||||
You can even bring up **pdb** when the trigger is hit:
|
||||
|
||||
|
||||
```
|
||||
`watch.config(pdb=True)`
|
||||
```
|
||||
|
||||
This behaves similarly to **breakpoint()**, giving you a debugger-like experience.
|
||||
|
||||
If you don’t want to import the function in every single file, you can make it global by using **install** function:
|
||||
|
||||
|
||||
```
|
||||
`watch.install() # or watch.install("func_name") and use it as func_name()`
|
||||
```
|
||||
|
||||
Personally, I think the coolest thing about watchpoints is its intuitive usage. Are you interested in some data? Just "watch" it, and you'll know when your variable changes.
|
||||
|
||||
### Try watchpoints
|
||||
|
||||
I developed and maintain `watchpoints` on [GitHub][2], and have released it under the licensed under Apache 2.0. Install it and use it, and of course contribution is always welcome.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/monitor-debug-python
|
||||
|
||||
作者:[Tian Gao][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/gaogaotiantian
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/look-binoculars-sight-see-review.png?itok=NOw2cm39 (Looking back with binoculars)
|
||||
[2]: https://github.com/gaogaotiantian/watchpoints
|
||||
[3]: https://opensource.com/article/21/3/debug-code-gdb
|
@ -1,136 +0,0 @@
|
||||
[#]: subject: (Find what changed in a Git commit)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-whatchanged)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (DCOLIVERSUN)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Find what changed in a Git commit
|
||||
======
|
||||
Git offers several ways you can quickly see which files changed in a
|
||||
commit.
|
||||
![Code going into a computer.][1]
|
||||
|
||||
If you use Git every day, you probably make a lot of commits. If you're using Git every day in a project with other people, it's safe to assume that _everyone_ is making lots of commits. Every day. And this means you're aware of how disorienting a Git log can become, with a seemingly eternal scroll of changes and no sign of what's been changed.
|
||||
|
||||
So how do you find out what file changed in a specific commit? It's easier than you think.
|
||||
|
||||
### Find what file changed in a commit
|
||||
|
||||
To find out which files changed in a given commit, use the `git log --raw` command. It's the fastest and simplest way to get insight into which files a commit affects. The `git log` command is underutilized in general, largely because it has so many formatting options, and many users get overwhelmed by too many choices and, in some cases, unclear documentation.
|
||||
|
||||
The log mechanism in Git is surprisingly flexible, though, and the `--raw` option provides a log of commits in your current branch, plus a list of each file that had changes made to it.
|
||||
|
||||
Here's the output of a standard `git log`:
|
||||
|
||||
|
||||
```
|
||||
$ git log
|
||||
commit fbbbe083aed75b24f2c77b1825ecab10def0953c (HEAD -> dev, origin/dev)
|
||||
Author: tux <[tux@example.com][2]>
|
||||
Date: Sun Nov 5 21:40:37 2020 +1300
|
||||
|
||||
exit immediately from failed download
|
||||
|
||||
commit 094f9948cd995acfc331a6965032ea0d38e01f03 (origin/master, master)
|
||||
Author: Tux <[tux@example.com][2]>
|
||||
Date: Fri Aug 5 02:05:19 2020 +1200
|
||||
|
||||
export makeopts from etc/example.conf
|
||||
|
||||
commit 76b7b46dc53ec13316abb49cc7b37914215acd47
|
||||
Author: Tux <[tux@example.com][2]>
|
||||
Date: Sun Jul 31 21:45:24 2020 +1200
|
||||
|
||||
fix typo in help message
|
||||
```
|
||||
|
||||
Even when the author helpfully specifies in the commit message which files changed, the log is fairly terse.
|
||||
|
||||
Here's the output of `git log --raw`:
|
||||
|
||||
|
||||
```
|
||||
$ git log --raw
|
||||
commit fbbbe083aed75b24f2c77b1825ecab10def0953c (HEAD -> dev, origin/dev)
|
||||
Author: tux <[tux@example.com][2]>
|
||||
Date: Sun Nov 5 21:40:37 2020 +1300
|
||||
|
||||
exit immediately from failed download
|
||||
|
||||
:100755 100755 cbcf1f3 4cac92f M src/example.lua
|
||||
|
||||
commit 094f9948cd995acfc331a6965032ea0d38e01f03 (origin/master, master)
|
||||
Author: Tux <[tux@example.com][2]>
|
||||
Date: Fri Aug 5 02:05:19 2020 +1200
|
||||
|
||||
export makeopts from etc/example.conf
|
||||
|
||||
:100755 100755 4c815c0 cbcf1f3 M src/example.lua
|
||||
:100755 100755 71653e1 8f5d5a6 M src/example.spec
|
||||
:100644 100644 9d21a6f e33caba R100 etc/example.conf etc/example.conf-default
|
||||
|
||||
commit 76b7b46dc53ec13316abb49cc7b37914215acd47
|
||||
Author: Tux <[tux@example.com][2]>
|
||||
Date: Sun Jul 31 21:45:24 2020 +1200
|
||||
|
||||
fix typo in help message
|
||||
|
||||
:100755 100755 e253aaf 4c815c0 M src/example.lua
|
||||
```
|
||||
|
||||
This tells you exactly which file was added to the commit and how the file was changed (`A` for added, `M` for modified, `R` for renamed, and `D` for deleted).
|
||||
|
||||
### Git whatchanged
|
||||
|
||||
The `git whatchanged` command is a legacy command that predates the log function. Its documentation says you're not meant to use it in favor of `git log --raw` and implies it's essentially deprecated. However, I still find it a useful shortcut to (mostly) the same output (although merge commits are excluded), and I anticipate creating an alias for it should it ever be removed. If you don't need to merge commits in your log (and you probably don't, if you're only looking to see files that changed), try `git whatchanged` as an easy mnemonic.
|
||||
|
||||
### View changes
|
||||
|
||||
Not only can you see which files changed, but you can also make `git log` display exactly what changed in the files. Your Git log can produce an inline diff, a line-by-line display of all changes for each file, with the `--patch` option:
|
||||
|
||||
|
||||
```
|
||||
commit 62a2daf8411eccbec0af69e4736a0fcf0a469ab1 (HEAD -> master)
|
||||
Author: Tux <[Tux@example.com][3]>
|
||||
Date: Wed Mar 10 06:46:58 2021 +1300
|
||||
|
||||
commit
|
||||
|
||||
diff --git a/hello.txt b/hello.txt
|
||||
index 65a56c3..36a0a7d 100644
|
||||
\--- a/hello.txt
|
||||
+++ b/hello.txt
|
||||
@@ -1,2 +1,2 @@
|
||||
Hello
|
||||
-world
|
||||
+opensource.com
|
||||
```
|
||||
|
||||
In this example, the one-word line "world" was removed from `hello.txt` and the new line "opensource.com" was added.
|
||||
|
||||
These patches can be used with common Unix utilities like [diff and patch][4], should you need to make the same changes manually elsewhere. The patches are also a good way to summarize the important parts of what new information a specific commit introduces. This is an invaluable overview when you've introduced a bug during a sprint. To find the cause of the error faster, you can ignore the parts of a file that didn't change and review just the new code.
|
||||
|
||||
### Simple commands for complex results
|
||||
|
||||
You don't have to understand refs and branches and commit hashes to view what files changed in a commit. Your Git log was designed to report Git activity to you, and if you want to format it in a specific way or extract specific information, it's often a matter of wading through many screens of documentation to put together the right command. Luckily, one of the most common requests about Git history is available with just one or two options: `--raw` and `--patch`. And if you can't remember `--raw`, just think, "Git, what changed?" and type `git whatchanged`.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-whatchanged
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82 (Code going into a computer.)
|
||||
[2]: mailto:tux@example.com
|
||||
[3]: mailto:Tux@example.com
|
||||
[4]: https://opensource.com/article/18/8/diffs-patches
|
@ -1,104 +0,0 @@
|
||||
[#]: subject: (Wrong Time Displayed in Windows-Linux Dual Boot Setup? Here’s How to Fix it)
|
||||
[#]: via: (https://itsfoss.com/wrong-time-dual-boot/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Wrong Time Displayed in Windows-Linux Dual Boot Setup? Here’s How to Fix it
|
||||
======
|
||||
|
||||
If you [dual boot Windows and Ubuntu][1] or any other Linux distribution, you might have noticed a time difference between the two operating systems.
|
||||
|
||||
When you [use Linux][2], it shows the correct time. But when you boot into Windows, it shows the wrong time. Sometimes, it is the opposite and Linux shows the wrong time and Windows has the correct time.
|
||||
|
||||
That’s strange specially because you are connected to the internet and your date and time is set to be used automatically.
|
||||
|
||||
Don’t worry! You are not the only one to face this issue. You can fix it by using the following command in the Linux terminal:
|
||||
|
||||
```
|
||||
timedatectl set-local-rtc 1
|
||||
```
|
||||
|
||||
Again, don’t worry. I’ll explain why you encounter a time difference in a dual boot setup. I’ll show you how the above command fixes the wrong time issue in Windows after dual boot.
|
||||
|
||||
### Why Windows and Linux show different time in dual boot?
|
||||
|
||||
A computer has two main clocks: a system clock and a hardware clock.
|
||||
|
||||
A hardware clock which is also called RTC ([real time clock][3]) or CMOS/BIOS clock. This clock is outside the operating system, on your computer’s motherboard. It keeps on running even after your system is powered off.
|
||||
|
||||
The system clock is what you see inside your operating system.
|
||||
|
||||
When your computer is powered on, the hardware clock is read and used to set the system clock. Afterwards, the system clock is used for tracking time. If your operating system makes any changes to system clock, like changing time zone etc, it tries to sync this information to the hardware clock.
|
||||
|
||||
By default, Linux assumes that the time stored in the hardware clock is in UTC, not the local time. On the other hand, Windows thinks that the time stored on the hardware clock is local time. That’s where the trouble starts.
|
||||
|
||||
Let me explain with examples.
|
||||
|
||||
You see I am in Kolkata time zone which is UTC+5:30. After installing when I set the [timezon][4][e][4] [in Ubuntu][4] to the Kolkata time zone, Ubuntu syncs this time information to the hardware clock but with an offset of 5:30 because it has to be in UTC for Linux.
|
||||
|
||||
Let’ say the current time in Kolkata timezone is 15:00 which means that the UTC time is 09:30.
|
||||
|
||||
Now when I turn off the system and boot into Windows, the hardware clock has the UTC time (09:30 in this example). But Windows thinks the hardware clock has stored the local time. And thus it changes the system clock (which should have shown 15:00) to use the UTC time (09:30) as the local time. And hence, Windows shows 09:30 as the time which is 5:30 hours behind the actual time (15:00 in our example).
|
||||
|
||||
![][5]
|
||||
|
||||
Again, if I set the correct time in Windows by toggling the automatic time zone and time buttons, you know what is going to happen? Now it will show the correct time on the system (15:00) and sync this information (notice the “Synchronize your clock” option in the image) to the hardware clock.
|
||||
|
||||
If you boot into Linux, it reads the time from the hardware clock which is in local time (15:00) but since Linux believes it to be the UTC time, it adds an offset of 5:30 to the system clock. Now Linux shows a time of 20:30 which is 5:30 hours ahead of the actual time.
|
||||
|
||||
Now that you understand the root cause of the time difference issues in dual boot, it’s time to see how to fix the issue.
|
||||
|
||||
### Fixing Windows Showing Wrong Time in a Dual Boot Setup With Linux
|
||||
|
||||
There are two ways you can go about handling this issue:
|
||||
|
||||
* Make Windows use UTC time for the hardware clock
|
||||
* Make Linux use local time for the hardware clock
|
||||
|
||||
|
||||
|
||||
It is easier to make the changes in Linux and hence I’ll recommend going with the second method.
|
||||
|
||||
Ubuntu and most other Linux distributions use systemd these days and hence you can use timedatectl command to change the settings.
|
||||
|
||||
What you are doing is to tell your Linux system to use the local time for the hardware clock (RTC). You do that with the `set-local-rtc` (set local time for RTC) option:
|
||||
|
||||
```
|
||||
timedatectl set-local-rtc 1
|
||||
```
|
||||
|
||||
As you can notice in the image below, the RTC now uses the local time.
|
||||
|
||||
![][6]
|
||||
|
||||
Now if you boot into Windows, it takes the hardware clock to be as local time which is actually correct this time. When you boot into Linux, your Linux system knows that the hardware clock is using local time, not UTC. And hence, it doesn’t try to add the off-set this time.
|
||||
|
||||
This fixes the time difference issue between Linux and Windows in dual boot.
|
||||
|
||||
You see a warning about not using local time for RTC. For desktop setups, it should not cause any issues. At least, I cannot think of one.
|
||||
|
||||
I hope I made things clear for you. If you still have questions, please leave a comment below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/wrong-time-dual-boot/
|
||||
|
||||
作者:[Abhishek Prakash][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://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/
|
||||
[2]: https://itsfoss.com/why-use-linux/
|
||||
[3]: https://www.computerhope.com/jargon/r/rtc.htm
|
||||
[4]: https://itsfoss.com/change-timezone-ubuntu/
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/set-time-windows.jpg?resize=800%2C491&ssl=1
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/set-local-time-for-rtc-ubuntu.png?resize=800%2C490&ssl=1
|
@ -1,240 +0,0 @@
|
||||
[#]: subject: (A practical guide to using the git stash command)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-stash)
|
||||
[#]: author: (Ramakrishna Pattnaik https://opensource.com/users/rkpattnaik780)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
A practical guide to using the git stash command
|
||||
======
|
||||
Learn how to use the git stash command and when you should use it.
|
||||
![woman on laptop sitting at the window][1]
|
||||
|
||||
Version control is an inseparable part of software developers' daily lives. It's hard to imagine any team developing software without using a version control tool. It's equally difficult to envision any developer who hasn't worked with (or at least heard of) Git. In the 2018 Stackoverflow Developer Survey, 87.2% of the 74,298 participants [use Git][2] for version control.
|
||||
|
||||
Linus Torvalds created git in 2005 for developing the Linux kernel. This article walks through the `git stash` command and explores some useful options for stashing changes. It assumes you have basic familiarity with [Git concepts][3] and a good understanding of the working tree, staging area, and associated commands.
|
||||
|
||||
### Why is git stash important?
|
||||
|
||||
The first thing to understand is why stashing changes in Git is important. Assume for a moment that Git doesn't have a command to stash changes. Suppose you are working on a repository with two branches, A and B. The A and B branches have diverged from each other for quite some time and have different heads. While working on some files in branch A, your team asks you to fix a bug in branch B. You quickly save your changes to A and try to check out branch B with `git checkout B`. Git immediately aborts the operation and throws the error, "Your local changes to the following files would be overwritten by checkout … Please commit your changes or stash them before you switch branches."
|
||||
|
||||
There are few ways to enable branch switching in this case:
|
||||
|
||||
* Create a commit at that point in branch A, commit and push your changes to fix the bug in B, then check out A again and run `git reset HEAD^` to get your changes back.
|
||||
* Manually keep the changes in files not tracked by Git.
|
||||
|
||||
|
||||
|
||||
The second method is a bad idea. The first method, although appearing conventional, is less flexible because the unfinished saved changes are treated as a checkpoint rather than a patch that's still a work in progress. This is exactly the kind of scenario git stash is designed for.
|
||||
|
||||
Git stash saves the uncommitted changes locally, allowing you to make changes, switch branches, and perform other Git operations. You can then reapply the stashed changes when you need them. A stash is locally scoped and is not pushed to the remote by `git push`.
|
||||
|
||||
### How to use git stash
|
||||
|
||||
Here's the sequence to follow when using git stash:
|
||||
|
||||
1. Save changes to branch A.
|
||||
2. Run `git stash`.
|
||||
3. Check out branch B.
|
||||
4. Fix the bug in branch B.
|
||||
5. Commit and (optionally) push to remote.
|
||||
6. Check out branch A
|
||||
7. Run `git stash pop` to get your stashed changes back.
|
||||
|
||||
|
||||
|
||||
Git stash stores the changes you made to the working directory locally (inside your project's .git directory; `/.git/refs/stash`, to be precise) and allows you to retrieve the changes when you need them. It's handy when you need to switch between contexts. It allows you to save changes that you might need at a later stage and is the fastest way to get your working directory clean while keeping changes intact.
|
||||
|
||||
### How to create a stash
|
||||
|
||||
The simplest command to stash your changes is `git stash`:
|
||||
|
||||
|
||||
```
|
||||
$ git stash
|
||||
Saved working directory and index state WIP on master; d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
By default, `git stash` stores (or "stashes") the uncommitted changes (staged and unstaged files) and overlooks untracked and ignored files. Usually, you don't need to stash untracked and ignored files, but sometimes they might interfere with other things you want to do in your codebase.
|
||||
|
||||
You can use additional options to let `git stash` take care of untracked and ignored files:
|
||||
|
||||
* `git stash -u` or `git stash --include-untracked` stash untracked files.
|
||||
* `git stash -a` or `git stash --all` stash untracked files and ignored files.
|
||||
|
||||
|
||||
|
||||
To stash specific files, you can use the command `git stash -p` or `git stash –patch`:
|
||||
|
||||
|
||||
```
|
||||
$ git stash --patch
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 32174593..8d81be6e 100644
|
||||
\--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -3,6 +3,7 @@
|
||||
# dependencies
|
||||
node_modules/
|
||||
/.pnp
|
||||
+f,fmfm
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
(1/1) Stash this hunk [y,n,q,a,d,e,?]?
|
||||
```
|
||||
|
||||
### Listing your stashes
|
||||
|
||||
You can view your stashes with the command `git stash list`. Stashes are saved in a last-in-first-out (LIFO) approach:
|
||||
|
||||
|
||||
```
|
||||
$ git stash list
|
||||
stash@{0}: WIP on master: d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
By default, stashes are marked as WIP on top of the branch and commit that you created the stash from. However, this limited amount of information isn't helpful when you have multiple stashes, as it becomes difficult to remember or individually check their contents. To add a description to the stash, you can use the command `git stash save <description>`:
|
||||
|
||||
|
||||
```
|
||||
$ git stash save "remove semi-colon from schema"
|
||||
Saved working directory and index state On master: remove semi-colon from schema
|
||||
|
||||
$ git stash list
|
||||
stash@{0}: On master: remove semi-colon from schema
|
||||
stash@{1}: WIP on master: d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
### Retrieving stashed changes
|
||||
|
||||
You can reapply stashed changes with the commands `git stash apply` and `git stash pop`. Both commands reapply the changes stashed in the latest stash (that is, `stash@{0}`). A `stash` reapplies the changes while `pop` removes the changes from the stash and reapplies them to the working copy. Popping is preferred if you don't need the stashed changes to be reapplied more than once.
|
||||
|
||||
You can choose which stash you want to pop or apply by passing the identifier as the last argument:
|
||||
|
||||
|
||||
```
|
||||
`$ git stash pop stash@{1}`
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
|
||||
```
|
||||
`$ git stash apply stash@{1}`
|
||||
```
|
||||
|
||||
### Cleaning up the stash
|
||||
|
||||
It is good practice to remove stashes that are no longer needed. You must do this manually with the following commands:
|
||||
|
||||
* `git stash clear` empties the stash list by removing all the stashes.
|
||||
* `git stash drop <stash_id>` deletes a particular stash from the stash list.
|
||||
|
||||
|
||||
|
||||
### Checking stash diffs
|
||||
|
||||
The command `git stash show <stash_id>` allows you to view the diff of a stash:
|
||||
|
||||
|
||||
```
|
||||
$ git stash show stash@{1}
|
||||
console/console-init/ui/.graphqlrc.yml | 4 +-
|
||||
console/console-init/ui/generated-frontend.ts | 742 +++++++++---------
|
||||
console/console-init/ui/package.json | 2 +-
|
||||
```
|
||||
|
||||
To get a more detailed diff, pass the `--patch` or `-p` flag:
|
||||
|
||||
|
||||
```
|
||||
$ git stash show stash@{0} --patch
|
||||
diff --git a/console/console-init/ui/package.json b/console/console-init/ui/package.json
|
||||
index 755912b97..5b5af1bd6 100644
|
||||
\--- a/console/console-init/ui/package.json
|
||||
+++ b/console/console-init/ui/package.json
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
\- "name": "my-usepatternfly",
|
||||
\+ "name": "my-usepatternfly-2",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"proxy": "<http://localhost:4000>"
|
||||
diff --git a/console/console-init/ui/src/AppNavHeader.tsx b/console/console-init/ui/src/AppNavHeader.tsx
|
||||
index a4764d2f3..da72b7e2b 100644
|
||||
\--- a/console/console-init/ui/src/AppNavHeader.tsx
|
||||
+++ b/console/console-init/ui/src/AppNavHeader.tsx
|
||||
@@ -9,8 +9,8 @@ import { css } from "@patternfly/react-styles";
|
||||
|
||||
interface IAppNavHeaderProps extends PageHeaderProps {
|
||||
\- toolbar?: React.ReactNode;
|
||||
\- avatar?: React.ReactNode;
|
||||
\+ toolbar?: React.ReactNode;
|
||||
\+ avatar?: React.ReactNode;
|
||||
}
|
||||
|
||||
export class AppNavHeader extends React.Component<IAppNavHeaderProps>{
|
||||
render()
|
||||
```
|
||||
|
||||
### Checking out to a new branch
|
||||
|
||||
You might come across a situation where the changes in a branch and your stash diverge, causing a conflict when you attempt to reapply the stash. A clean fix for this is to use the command `git stash branch <new_branch_name stash_id>`, which creates a new branch based on the commit the stash was created _from_ and pops the stashed changes to it:
|
||||
|
||||
|
||||
```
|
||||
$ git stash branch test_2 stash@{0}
|
||||
Switched to a new branch 'test_2'
|
||||
On branch test_2
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
modified: .graphqlrc.yml
|
||||
modified: generated-frontend.ts
|
||||
modified: package.json
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
Dropped stash@{0} (fe4bf8f79175b8fbd3df3c4558249834ecb75cd1)
|
||||
```
|
||||
|
||||
### Stashing without disturbing the stash reflog
|
||||
|
||||
In rare cases, you might need to create a stash while keeping the stash reference log (reflog) intact. These cases might arise when you need a script to stash as an implementation detail. This is achieved by the `git stash create` command; it creates a stash entry and returns its object name without pushing it to the stash reflog:
|
||||
|
||||
|
||||
```
|
||||
$ git stash create "sample stash"
|
||||
63a711cd3c7f8047662007490723e26ae9d4acf9
|
||||
```
|
||||
|
||||
Sometimes, you might decide to push the stash entry created via `git stash create` to the stash reflog:
|
||||
|
||||
|
||||
```
|
||||
$ git stash store -m "sample stash testing.." "63a711cd3c7f8047662007490723e26ae9d4acf9"
|
||||
$ git stash list
|
||||
stash @{0}: sample stash testing..
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
I hope you found this article useful and learned something new. If I missed any useful options for using stash, please let me know in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-stash
|
||||
|
||||
作者:[Ramakrishna Pattnaik][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/rkpattnaik780
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
|
||||
[2]: https://insights.stackoverflow.com/survey/2018#work-_-version-control
|
||||
[3]: https://opensource.com/downloads/cheat-sheet-git
|
@ -1,144 +0,0 @@
|
||||
[#]: subject: (What problems do people solve with strace?)
|
||||
[#]: via: (https://jvns.ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
What problems do people solve with strace?
|
||||
======
|
||||
|
||||
Yesterday I [asked on Twitter about what problems people are solving with strace][1] and as usual everyone really delivered! I got 200 answers and then spent a bunch of time manually categorizing them into 9 categories of problems.
|
||||
|
||||
All of the problems are about either finding files a program depends on, figuring out why a program is stuck or slow, or finding out why a program is failing. These generally matched up with what I use strace for myself, but there were some things I hadn’t thought of too!
|
||||
|
||||
I’m not going to explain what strace is in this post but I have a [free zine about it][2] and [a talk][3] and [lots of blog posts][4].
|
||||
|
||||
### problem 1: where’s the config file?
|
||||
|
||||
The #1 most popular problem was “this program has a configuration file and I don’t know where it is”. This is probably my most common use for strace too, because it’s such a simple question.
|
||||
|
||||
This is great because there are a million ways for a program to document where its config file is (in a man page, on its website, in `--help`, etc), but there’s only one way for it to actually open it (with a system call!)
|
||||
|
||||
### problem 2: what other files does this program depend on?
|
||||
|
||||
You can also use strace to find other types of files a program depends on, like:
|
||||
|
||||
* dynamically linked libraries (“why is my program loading the wrong version of this `.so` file?“) like [this ruby problem I debugged in 2014][5]
|
||||
* where it’s looking for its Ruby gems (Ruby specifically came up a few times!)
|
||||
* SSL root certificates
|
||||
* a game’s save files
|
||||
* a closed-source program’s data files
|
||||
* [which node_modules files aren’t being used][6]
|
||||
|
||||
|
||||
|
||||
### problem 3: why is this program hanging?
|
||||
|
||||
You have a program, it’s just sitting there doing nothing, what’s going on? This one is especially easy to answer because a lot of the time you just need to run `strace -p PID` and look at what system call is currently running. You don’t even have to look through hundreds of lines of output!
|
||||
|
||||
The answer is usually ‘waiting for some kind of I/O’. Some possible answers for “why is this stuck” (though there are a lot more!):
|
||||
|
||||
* it’s polling forever on a `select()`
|
||||
* it’s `wait()`ing for a subprocess to finish
|
||||
* it’s making a network request to something that isn’t responding
|
||||
* it’s doing `write()` but it’s blocked because the buffer is full
|
||||
* it’s doing a `read()` on stdin and it’s waiting for input
|
||||
|
||||
|
||||
|
||||
Someone also gave a nice example of using strace to debug a stuck `df`: ‘with strace df -h you can find the stuck mount and unmount it”.
|
||||
|
||||
### problem 4: is this program stuck?
|
||||
|
||||
A variation on the previous one: sometimes a program has been running for longer than you expected, and you just want to know if it’s stuck or of it’s still making progress.
|
||||
|
||||
As long as the program makes system calls while it’s running, this is super easy to answer with strace – just strace it and see if it’s making new system calls!
|
||||
|
||||
### problem 5: why is this program slow?
|
||||
|
||||
You can use strace as a sort of coarse profiling tool – `strace -t` will show the timestamp of each system call, so you can look for big gaps and find the culprit.
|
||||
|
||||
Here are 9 short stories from Twitter of people using strace to debug “why is this program slow?”.
|
||||
|
||||
* Back in 2000, a Java-based web site that I helped support was dying under modest load: pages loaded slowly, if at all. We straced the J2EE application server and found that it was reading class files one. byte. at. a. time. Devs weren’t using BufferedReader, classic Java mistake.
|
||||
* Optimizing app startup times… running strace can be an eye-opening experience, in terms of the amount of unnecessary file system interaction going on (e.g. open/read/close on the same config file over and over again; loading gobs of font files over a slow NFS mount, etc)
|
||||
* Asked myself why reading from session files in PHP (usually <100 bytes) was incredibly slow. Turned out some `flock`-syscalls took ~60s
|
||||
* A program was behaving abnormally slow. Used strace to figure out it was re-initializing its internal pseudo-random number generator on every request by reading from /dev/random and exhausting entropy
|
||||
* Last thing I remember was attaching to a job worker and seeing just how many network calls it was making (which was unexpected).
|
||||
* Why is this program so slow to start? strace shows it opening/reading the same config file thousands of times.
|
||||
* Server using 100% CPU time randomly with low actual traffic. Turns out it’s hitting the number of open files limit accepting a socket, and retrying forever after getting EMFILE and not reporting it.
|
||||
* A workflow was running super slow but no logs, ends up it was trying to do a post request that was taking 30s before timing out and then retrying 5 times… ends up the backend service was overwhelmed but also had no visibility
|
||||
* using strace to notice that gethostbyname() is taking a long time to return (you can’t see the `gethostbyname` directly but you can see the DNS packets in strace)
|
||||
|
||||
|
||||
|
||||
### problem 6: hidden permissions errors
|
||||
|
||||
Sometimes a program is failing for a mysterious reason, but the problem is just that there’s some file that it doesn’t have permission to open. In an ideal world programs would report those errors (“Error opening file /dev/whatever: permission denied”), but of course the world is not perfect, so strace can really help with this!
|
||||
|
||||
This is actually the most recent thing I used strace for: I was using an AxiDraw pen plotter and it printed out an inscrutable error message when I tried to start it. I `strace`d it and it turned out that my user just didn’t have permission to open the USB device.
|
||||
|
||||
### problem 7: what command line arguments are being used?
|
||||
|
||||
Sometimes a script is running another program, and you want to know what command line flags it’s passing!
|
||||
|
||||
A couple of examples from Twitter:
|
||||
|
||||
* find what compiler flags are actually being used to build some code
|
||||
* a command was failing due to having too long a command line
|
||||
|
||||
|
||||
|
||||
### problem 8: why is this network connection failing?
|
||||
|
||||
Basically the goal here is just to find which domain / IP address the network connection is being made to. You can look at the DNS request to find the domain or the `connect` system call to find the IP.
|
||||
|
||||
In general there are a lot of stories about using strace to debug network issues when `tcpdump` isn’t available for some reason or just because it’s what the person is more familiar with.
|
||||
|
||||
### problem 9: why does this program succeed when run one way and fail when run in another way?
|
||||
|
||||
For example:
|
||||
|
||||
* the same binary works on one machine, fails on another machine
|
||||
* works when you run it, fails when spawned by a systemd unit file
|
||||
* works when you run it, fails when you run it as “su - user /some/script”
|
||||
* works when you run it, fails when run as a cron job
|
||||
|
||||
|
||||
|
||||
Being able to compare the strace output in both cases is very helpful. Though my first step when debugging “this works as my user and fails when run in a different way on the same computer” would be “look at my environment variables”.
|
||||
|
||||
### what I’m doing with this: slowly building some challenges
|
||||
|
||||
The reason I’m thinking about this is that I’ve been slowly working on some challenges to help people practice using strace and other command line tools. The idea is that you’re given a problem to solve, a terminal, and you’re free to solve it in any way you want.
|
||||
|
||||
So my goal is to use this to build some practice problems that you can solve with strace that reflect the kinds of problems that people actually use it for in real life.
|
||||
|
||||
### that’s all!
|
||||
|
||||
There are probably more problems that can be solved with strace that I haven’t covered here – I’d love to hear what I’ve missed!
|
||||
|
||||
I really loved seeing how many of the same uses came up over and over and over again – at least 20 different people replied saying that they use strace to find config files. And as always I think it’s really delightful how such a simple tool (“trace system calls!”) can be used to solve so many different kinds of problems.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/
|
||||
|
||||
作者:[Julia Evans][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://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://twitter.com/b0rk/status/1378014888405168132
|
||||
[2]: https://wizardzines.com/zines/strace
|
||||
[3]: https://www.youtube.com/watch?v=4pEHfGKB-OE
|
||||
[4]: https://jvns.ca/categories/strace
|
||||
[5]: https://jvns.ca/blog/2014/03/10/debugging-shared-library-problems-with-strace/
|
||||
[6]: https://indexandmain.com/post/shrink-node-modules-with-refining
|
@ -1,160 +0,0 @@
|
||||
[#]: subject: (Converting Multiple Markdown Files into HTML or Other Formats in Linux)
|
||||
[#]: via: (https://itsfoss.com/convert-markdown-files/)
|
||||
[#]: author: (Bill Dyer https://itsfoss.com/author/bill/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Converting Multiple Markdown Files into HTML or Other Formats in Linux
|
||||
======
|
||||
|
||||
Many times, when I use Markdown, I work on one file and when I’m done with it, I convert it to HTML or some other format. Occasionally, I have to create a few files. When I do work with more than one Markdown file, I usually wait until I have finished them before I convert them.
|
||||
|
||||
I use pandoc to convert files, and it’s possible convert all the Markdown files in one shot.
|
||||
|
||||
Markdown can convert its files to .html, but if there’s a chance that I will have to convert to other formats like epub, [pandoc][1] is the tool to use. I prefer to use the command line, so I will cover that first, but you can also do this in [VSCodium][2] without the command line. I’ll cover that too.
|
||||
|
||||
### Converting multiple Markdown files to another format with Pandoc [command line method]
|
||||
|
||||
To get started quickly, Ubuntu, and other Debian distros can type the following commands in the terminal:
|
||||
|
||||
```
|
||||
sudo apt-get install pandoc
|
||||
```
|
||||
|
||||
In this example, I have four Markdown files in a directory called md_test.
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ ls -l *.md
|
||||
-rw-r--r-- 1 bdyer bdyer 3374 Apr 7 2020 file01.md
|
||||
-rw-r--r-- 1 bdyer bdyer 782 Apr 2 05:23 file02.md
|
||||
-rw-r--r-- 1 bdyer bdyer 9257 Apr 2 05:21 file03.md
|
||||
-rw-r--r-- 1 bdyer bdyer 9442 Apr 2 05:21 file04.md
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
There are no HTML files yet. Now I’ll use Pandoc to do its magic on the collection of files. To do this, I run a one-line command that:
|
||||
|
||||
* calls pandoc
|
||||
* reads the .md files and exports them as .html
|
||||
|
||||
|
||||
|
||||
This is the command:
|
||||
|
||||
```
|
||||
for i in *.md ; do echo "$i" && pandoc -s $i -o $i.html ; done
|
||||
```
|
||||
|
||||
If you are not aware already, `;` is used for [running multiple commands at once in Linux][3].
|
||||
|
||||
Here’s what the display looks like once I have executed the command:
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ for i in *.md ; do echo "$i" && pandoc -s $i -o $i.html ; done
|
||||
file01.md
|
||||
file02.md
|
||||
file03.md
|
||||
file04.md
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
Let me use the `ls` command once more to see if HTML files were created:
|
||||
|
||||
```
|
||||
[email protected]:~/Documents/md_test$ ls -l *.html
|
||||
-rw-r--r-- 1 bdyer bdyer 4291 Apr 2 06:08 file01.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 1781 Apr 2 06:08 file02.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 10272 Apr 2 06:08 file03.md.html
|
||||
-rw-r--r-- 1 bdyer bdyer 10502 Apr 2 06:08 file04.md.html
|
||||
[email protected]:~/Documents/md_test$
|
||||
```
|
||||
|
||||
The conversion was a success, and you have four HTML files ready to go on the Web server.
|
||||
|
||||
Pandoc is quite versatile and you can convert the markdown files to some other supported format by specifying the extension of the output files. You can understand why it is considered among the [best open source tools for writers][4].
|
||||
|
||||
**Recommended Read:**
|
||||
|
||||
![][5]
|
||||
|
||||
#### [11 Best Markdown Editors for Linux][6]
|
||||
|
||||
A list of best Markdown Editors for Linux distributions that not only look good but are also feature rich.
|
||||
|
||||
### Converting Markdown files to HTML using VSCodium [GUI method]
|
||||
|
||||
Like I’ve said earlier, I normally use the command line, but I don’t always use it for batch conversions, and you don’t have to either. VSCode or [VSCodium][7] can do the job. You just need to add one extension, called: _Markdown-All-in-One_ which will allow you to convert more than one Markdown file in one run.
|
||||
|
||||
There are two ways to install the extension:
|
||||
|
||||
* VSCodium’s terminal
|
||||
* VSCodium’s plug-in manager
|
||||
|
||||
|
||||
|
||||
To install the extension through VSCodium’s terminal:
|
||||
|
||||
1. Click on `Terminal` on the menu bar. The terminal panel will open
|
||||
2. Type, or [copy-and-paste, the following command in the terminal][8]:
|
||||
|
||||
|
||||
|
||||
```
|
||||
codium --install-extension yzhang.markdown-all-in-one
|
||||
```
|
||||
|
||||
**Note**: If you’re using VSCode instead of VSCodium, replace the word, `codium`, in the above command, with `code`
|
||||
|
||||
![][9]
|
||||
|
||||
The second way to install is through VSCodium’s plug-in, or extension, manager:
|
||||
|
||||
1. Click on the blocks on the left side of the VSCodium window. A list of extensions will appear. At the top of the list, there will be a search bar.
|
||||
2. In the search bar, type: `Markdown All in One`. The extension will be listed at the top of the list. Click on the `Install` button to install it. If it is already installed, a gear icon will appear in place of the install button.
|
||||
|
||||
|
||||
|
||||
![][10]
|
||||
|
||||
Once the extension is installed, you can open the folder that contains the Markdown files you want to convert.
|
||||
|
||||
Click on the paper icon located on the left side of the VSCodium window. You’ll be given the opportunity to choose your folder. Once a folder is open, you’ll need to open at least one file. You can open as many files as you want, but one is the minimum.
|
||||
|
||||
Once a file is open, bring up the Command Palette by pressing `CTRL+SHIFT+P`. Then, start typing `Markdown`in the search bar that will appear. As you do this, a list of Markdown related commands will appear. One of these will be `Markdown All in One: Print documents to HTML` command. Click on that one.
|
||||
|
||||
![][11]
|
||||
|
||||
You’ll be asked to choose a folder containing the files. This is so an output directory (called `out`) can be made and this is where the HTML files will go. The image below shows that the HTML was made after exporting the Markdown documents. From here, you can open, view, and edit the HTML as you wish.
|
||||
|
||||
![][12]
|
||||
|
||||
By waiting to convert your Markdown files, you can concentrate more on writing. Conversion to HTML can come when you’re ready – and you have two ways to get that done.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/convert-markdown-files/
|
||||
|
||||
作者:[Bill Dyer][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://itsfoss.com/author/bill/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://pandoc.org/
|
||||
[2]: https://vscodium.com/
|
||||
[3]: https://itsfoss.com/run-multiple-commands-linux/
|
||||
[4]: https://itsfoss.com/open-source-tools-writers/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2016/10/Best-Markdown-Editors-for-Linux.jpg?fit=800%2C450&ssl=1
|
||||
[6]: https://itsfoss.com/best-markdown-editors-linux/
|
||||
[7]: https://itsfoss.com/vscodium/
|
||||
[8]: https://itsfoss.com/copy-paste-linux-terminal/
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_terminal.jpg?resize=800%2C564&ssl=1
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_extension_select.jpg?resize=800%2C564&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_markdown_function_options.jpg?resize=800%2C564&ssl=1
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/vscodium_html_filelist_shown.jpg?resize=800%2C564&ssl=1
|
@ -0,0 +1,142 @@
|
||||
[#]: subject: (7 Git tips for managing your home directory)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-home)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
7 Git tips for managing your home directory
|
||||
======
|
||||
Here is how I set up Git to manage my home directory.
|
||||
![Houses in a row][1]
|
||||
|
||||
I have several computers. I've got a laptop at work, a workstation at home, a Raspberry Pi (or four), a [Pocket CHIP][2], a [Chromebook running various forms of Linux][3], and so on. I used to set up my user environment on each computer by more or less following the same steps, and I often told myself that I enjoyed that each one was slightly unique. For instance, I use [Bash aliases][4] more often at work than at home, and the helper scripts I use at home might not be useful at work.
|
||||
|
||||
Over the years, my expectations across devices began to merge, and I'd forget that a feature I'd built up on my home machine wasn't ported over to my work machine, and so on. I needed a way to standardize my customized toolkit. The answer, to my surprise, was Git.
|
||||
|
||||
Git is version-tracker software. It's famously used by the biggest and smallest open source projects and even by the largest proprietary software companies. But it was designed for source code—not a home directory filled with music and video files, games, photos, and so on. I'd heard of people managing their home directory with Git, but I assumed that it was a fringe experiment done by coders, not real-life users like me.
|
||||
|
||||
Managing my home directory with Git has been an evolving process. I've learned and adapted along the way. Here are the things you might want to keep in mind should you decide to manage your home directory with Git.
|
||||
|
||||
### 1\. Text and binary locations
|
||||
|
||||
![home directory][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
When managed by Git, your home directory becomes something of a no-man 's-land for everything but configuration files. That means when you open your home directory, you should see nothing but a list of predictable directories. There shouldn't be any stray photos or LibreOffice documents, and no "I'll put this here for just a minute" files.
|
||||
|
||||
The reason for this is simple: when you manage your home directory with Git, everything in your home directory that's _not_ being committed becomes noise. Every time you do a `git status`, you'll have to scroll past any file that Git isn't tracking, so it's vital that you keep those files in subdirectories (which you add to your `.gitignore` file).
|
||||
|
||||
Many Linux distributions provide a set of default directories:
|
||||
|
||||
* Documents
|
||||
* Downloads
|
||||
* Music
|
||||
* Photos
|
||||
* Templates
|
||||
* Videos
|
||||
|
||||
|
||||
|
||||
You can create more if you need them. For instance, I differentiate between the music I create (Music) and the music I purchase to listen to (Albums). Likewise, my Cinema directory contains movies by other people, while Videos contains video files I need for editing. In other words, my default directory structure has more granularity than the default set provided by most Linux distributions, but I think there's a benefit to that. Without a directory structure that works for you, you'll be more likely to just stash stuff in your home directory, for lack of a better place for it, so think ahead and plan out directories that work for you. You can always add more later, but it's best to start strong.
|
||||
|
||||
### 2\. Setting up your very best .gitignore
|
||||
|
||||
Once you've cleaned up your home directory, you can instantiate it as a Git repository as usual:
|
||||
|
||||
|
||||
```
|
||||
$ cd
|
||||
$ git init .
|
||||
```
|
||||
|
||||
Your Git repository contains nothing yet, so everything in your home directory is untracked. Your first job is to sift through the list of untracked files and determine what you want to remain untracked. To see untracked files:
|
||||
|
||||
|
||||
```
|
||||
$ git status
|
||||
.AndroidStudio3.2/
|
||||
.FBReader/
|
||||
.ICEauthority
|
||||
.Xauthority
|
||||
.Xdefaults
|
||||
.android/
|
||||
.arduino15/
|
||||
.ash_history
|
||||
[...]
|
||||
```
|
||||
|
||||
Depending on how long you've been using your home directory, this list may be long. The easy ones are the directories you decided on in the first step. By adding these to a hidden file called `.gitignore`, you tell Git to stop listing them as untracked files and never to track them:
|
||||
|
||||
|
||||
```
|
||||
`$ \ls -lg | grep ^d | awk '{print $8}' >> ~/.gitignore`
|
||||
```
|
||||
|
||||
With that done, go through the remaining untracked files shown by `git status` and determine whether any other files warrant exclusion. This process helped me discover several stale old configuration files and directories, which I ended up trashing altogether, but also some that were very specific to one computer. I was fairly strict here because many configuration files do better when they're auto-generated. For instance, I never commit my KDE configuration files because many contain information like recent documents and other elements that don't exist on another machine.
|
||||
|
||||
I track my personalized configuration files, scripts and utilities, profile and Bash configs, and cheat sheets and other snippets of text that I refer to frequently. If the software is mostly responsible for maintaining a file, I ignore it. And when in doubt about a file, I ignore it. You can always un-ignore it later (by removing it from your `.gitignore` file).
|
||||
|
||||
### 3\. Get to know your data
|
||||
|
||||
I'm on KDE, so I use the open source scanner [Filelight][7] to get an overview of my data. Filelight gives you a chart that lets you see the size of each directory. You can navigate through each directory to see what's taking up all the space and then backtrack to investigate elsewhere. It's a fascinating view of your system, and it lets you see your files in a completely new light.
|
||||
|
||||
![Filelight][8]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
Use Filelight or a similar utility to find unexpected caches of data you don't need to commit. For instance, the KDE file indexer (Baloo) generates quite a lot of data specific to its host that I definitely wouldn't want to transport to another computer.
|
||||
|
||||
### 4\. Don't ignore your .gitignore file
|
||||
|
||||
On some projects, I tell Git to ignore my `.gitignore` file because what I want to ignore is sometimes specific to my working directory, and I don't presume other developers on the same project need me to tell them what their `.gitignore` file ought to look like. Because my home directory is for my use only, I do _not_ ignore my home's `.gitignore` file. I commit it along with other important files, so it's inherited across all of my systems. And of course, all of my systems are identical from the home directory's viewpoint: they have the same set of default folders and many of the same hidden configuration files.
|
||||
|
||||
### 5\. Don't fear the binary
|
||||
|
||||
I put my system through weeks and weeks of rigorous testing, convinced that it was _never_ wise to commit binary files to Git. I tried GPG encrypted password files, I tried LibreOffice documents, JPEGs, PNGs, and more. I even had a script that unarchived LibreOffice files before adding them to Git, extracted the XML inside so I could commit just the XML, and then rebuilt the LibreOffice file so that I could work on it within LibreOffice. My theory was that committing XML would render a smaller Git repository than a ZIP file (which is all a LibreOffice document really is).
|
||||
|
||||
To my great surprise, I found that committing a few binary files every now and then did not substantially increase the size of my Git repository. I've worked with Git long enough to know that if I were to commit gigabytes of binary data, my repository would suffer, but the occasional binary file isn't an emergency to avoid at all costs.
|
||||
|
||||
Armed with this new confidence, I add font OTF and TTF files to my standard home repo, my `.face` file for GDM, and other incidental minor binary blobs. Don't overthink it, don't waste time trying to avoid it; just commit it.
|
||||
|
||||
### 6\. Use a private repo
|
||||
|
||||
Don't commit your home directory to a public Git repository, even if the host offers private accounts. If you're like me, you have SSH keys and GPG keychains and GPG-encrypted files that ought not end up on anybody's server but my own.
|
||||
|
||||
I [run a local Git server][9] on a Raspberry Pi (it's easier than you think), so I can update any computer any time I'm home. I'm a remote worker, so that's usually good enough, but I can also reach the computer when traveling over my [VPN][10].
|
||||
|
||||
### 7\. Remember to push
|
||||
|
||||
The thing about Git is that it only pushes changes to your server when you tell it to. If you're a longtime Git user, this process is probably natural to you. For new users who might be accustomed to the automatic synchronization in Nextcloud or Syncthing, this may take some getting used to.
|
||||
|
||||
### Git at home
|
||||
|
||||
Managing my common files with Git hasn't just made life more convenient across devices. Knowing that I have a full history for all my configurations and utility scripts encourages me to try out new ideas because it's always easy to roll back my changes if they turn out to be _bad_ ideas. Git has rescued me from an ill-advised umask setting in `.bashrc`, a poorly executed late-night addition to my package management script, and an it-seemed-like-a-cool-idea-at-the-time change of my [rxvt][11] color scheme—and probably a few other mistakes in my past. Try Git in your home because a home that commits together merges together.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-home
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/house_home_colors_live_building.jpg?itok=HLpsIfIL (Houses in a row)
|
||||
[2]: https://opensource.com/article/17/2/pocketchip-or-pi
|
||||
[3]: https://opensource.com/article/21/2/chromebook-linux
|
||||
[4]: https://opensource.com/article/17/5/introduction-alias-command-line-tool
|
||||
[5]: https://opensource.com/sites/default/files/uploads/home-git.jpg (home directory)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://utils.kde.org/projects/filelight
|
||||
[8]: https://opensource.com/sites/default/files/uploads/filelight.jpg (Filelight)
|
||||
[9]: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
|
||||
[10]: https://www.redhat.com/sysadmin/run-your-own-vpn-libreswan
|
||||
[11]: https://opensource.com/article/19/10/why-use-rxvt-terminal
|
@ -0,0 +1,156 @@
|
||||
[#]: subject: (How different programming languages do the same thing)
|
||||
[#]: via: (https://opensource.com/article/21/4/compare-programming-languages)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
How different programming languages do the same thing
|
||||
======
|
||||
Compare 13 different programming languages by writing a simple game.
|
||||
![Developing code.][1]
|
||||
|
||||
Whenever I start learning a new programming language, I focus on defining variables, writing a statement, and evaluating expressions. Once I have a general understanding of those concepts, I can usually figure out the rest on my own. Most programming languages have some similarities, so once you know one programming language, learning the next one is a matter of figuring out the unique details and recognizing the differences.
|
||||
|
||||
To help me practice a new programming language, I like to write a few test programs. One sample program I often write is a simple "guess the number" game, where the computer picks a number between one and 100 and asks me to guess it. The program loops until I guess correctly. This is a very simple program, as you can see using pseudocode like this:
|
||||
|
||||
1. The computer picks a random number between 1 and 100
|
||||
2. Loop until I guess the random number
|
||||
1. The computer reads my guess
|
||||
2. It tells me if my guess is too low or too high
|
||||
|
||||
|
||||
|
||||
Recently, Opensource.com ran an article series that wrote this program in different languages. This was an interesting opportunity to compare how to do the same thing in each language. I also found that most programming languages do things similarly, so learning the next programming language is mostly about learning its differences.
|
||||
|
||||
C is an early general-purpose programming language, created in 1972 at Bell Labs by Dennis Ritchie. C proved popular and quickly became a standard programming language on Unix systems. Because of its popularity, many other programming languages adopted a similar programming syntax. That's why learning C++, Rust, Java, Groovy, JavaScript, awk, or Lua is easier if you already know how to program in C.
|
||||
|
||||
For example, look at how these different programming languages implement the major steps in the "guess the number" game. I'll skip some of the surrounding code, such as assigning temporary variables, to focus on how the basics are similar or different.
|
||||
|
||||
### The computer picks a random number between one and 100
|
||||
|
||||
You can see a lot of similarities here. Most of the programming languages generate a random number with a function like `rand()` that you can put into a range on your own. Other languages use a special function where you can specify the range for the random value.
|
||||
|
||||
C | Using the Linux `getrandom` system call:
|
||||
`getrandom(&randval, sizeof(int), GRND_NONBLOCK); number = randval % maxval + 1;`
|
||||
|
||||
Using the standard C library:
|
||||
`number = rand() % 100 + 1;`
|
||||
---|---
|
||||
C++ | `int number = rand() % 100+1;`
|
||||
Rust | `let random = rng.gen_range(1..101);`
|
||||
Java | `private static final int NUMBER = r.nextInt(100) + 1;`
|
||||
Groovy | `int randomNumber = (new Random()).nextInt(100) + 1`
|
||||
JavaScript | `const randomNumber = Math.floor(Math.random() * 100) + 1`
|
||||
awk | `randomNumber = int(rand() * 100) + 1`
|
||||
Lua | `number = math.random(1,100)`
|
||||
|
||||
### Loop until I guess the random number
|
||||
|
||||
Loops are usually done with a flow-control block such as `while` or `do-while`. The JavaScript implementation doesn't use a loop and instead updates the HTML page "live" until the user guesses the correct number. Awk supports loops, but it doesn't make sense to loop to read input because awk is based around data pipelines, so it reads input from a file instead of directly from the user.
|
||||
|
||||
C | `do { … } while (guess != number); `
|
||||
---|---
|
||||
C++ | `do { … } while ( number != guess ); `
|
||||
Rust | `for line in std::io::stdin().lock().lines() { … break; } `
|
||||
Java | `while ( guess != NUMBER ) { … } `
|
||||
Groovy | `while ( … ) { … break; } `
|
||||
Lua | ` while ( player.guess ~= number ) do … end`
|
||||
|
||||
### The computer reads my guess
|
||||
|
||||
Different programming languages handle input differently. So there's some variation here. For example, JavaScript reads values directly from an HTML form, and awk reads data from its data pipeline.
|
||||
|
||||
C | `scanf("%d", &guess); `
|
||||
---|---
|
||||
C++ | `cin >> guess; `
|
||||
Rust | `let parsed = line.ok().as_deref().map(str::parse::<i64>); if let Some(Ok(guess)) = parsed { … } `
|
||||
Java | `guess = player.nextInt(); `
|
||||
Groovy | `response = reader.readLine() int guess = response as Integer `
|
||||
JavaScript | `let myGuess = guess.value `
|
||||
awk | `guess = int($0) `
|
||||
Lua | `player.answer = io.read() player.guess = tonumber(player.answer) `
|
||||
|
||||
### Tell me if my guess is too low or too high
|
||||
|
||||
Comparisons are fairly consistent across these C-like programming languages, usually through an `if` statement. There's some variation in how each programming language prints output, but the print statement remains recognizable across each sample.
|
||||
|
||||
C | ` if (guess < number) { puts("Too low"); } else if (guess > number) { puts("Too high"); } … puts("That's right!");`` `
|
||||
---|---
|
||||
C++ | ` if ( guess > number) { cout << "Too high.\n" << endl; } else if ( guess < number ) { cout << "Too low.\n" << endl; } else { cout << "That's right!\n" << endl; exit(0); }`` `
|
||||
Rust | ` _ if guess < random => println!("Too low"), _ if guess > random => println!("Too high"), _ => { println!("That's right"); break; } `
|
||||
Java | ` if ( guess > NUMBER ) { System.out.println("Too high"); } else if ( guess < NUMBER ) { System.out.println("Too low"); } else { System.out.println("That's right!"); System.exit(0); } `
|
||||
Groovy | ` if (guess < randomNumber) print 'too low, try again: ' else if (guess > randomNumber) print 'too high, try again: ' else { println "that's right" break } `
|
||||
JavaScript | ` if (myGuess === randomNumber) { feedback.textContent = "You got it right!" } else if (myGuess > randomNumber) { feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!" } else if (myGuess < randomNumber) { feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!" } `
|
||||
awk | ` if (guess < randomNumber) { printf "too low, try again:" } else if (guess > randomNumber) { printf "too high, try again:" } else { printf "that's right\n" exit } `
|
||||
Lua | ` if ( player.guess > number ) then print("Too high") elseif ( player.guess < number) then print("Too low") else print("That's right!") os.exit() end `
|
||||
|
||||
### What about non-C-based languages?
|
||||
|
||||
Programming languages that are not based on C can be quite different and require learning specific syntax to do each step. Racket derives from Lisp and Scheme, so it uses Lisp's prefix notation and lots of parentheses. Python uses whitespace rather than brackets to indicate blocks like loops. Elixir is a functional programming language with its own syntax. Bash is based on the Bourne shell from Unix systems, which itself borrows from Algol68—and supports additional shorthand notation such as `&&` as a variation of "and." Fortran was created when code was entered using punched cards, so it relies on an 80-column layout where some columns are significant.
|
||||
|
||||
As an example of how these other programming languages can differ, I'll compare just the "if" statement that sees if one value is less than or greater than another and prints an appropriate message to the user.
|
||||
|
||||
Racket | ` (cond [(> number guess) (displayln "Too low") (inquire-user number)] [(< number guess) (displayln "Too high") (inquire-user number)] [else (displayln "Correct!")])) `
|
||||
---|---
|
||||
Python | ` if guess < random: print("Too low") elif guess > random: print("Too high") else: print("That's right!") `
|
||||
Elixir | ` cond do guess < num -> IO.puts "Too low!" guess_loop(num) guess > num -> IO.puts "Too high!" guess_loop(num) true -> IO.puts "That's right!" end `
|
||||
Bash | ` [ "0$guess" -lt $number ] && echo "Too low" [ "0$guess" -gt $number ] && echo "Too high" `
|
||||
Fortran | ` IF (GUESS.LT.NUMBER) THEN PRINT *, 'TOO LOW' ELSE IF (GUESS.GT.NUMBER) THEN PRINT *, 'TOO HIGH' ENDIF `
|
||||
|
||||
### Read more
|
||||
|
||||
This "guess the number" game is a great introductory program when learning a new programming language because it exercises several common programming concepts in a pretty straightforward way. By implementing this simple game in different programming languages, you can demonstrate some core concepts and compare each language's details.
|
||||
|
||||
Learn how to write the "guess the number" game in C and C-like languages:
|
||||
|
||||
* [C][2], by Jim Hall
|
||||
* [C++][3], by Seth Kenlon
|
||||
* [Rust][4], by Moshe Zadka
|
||||
* [Java][5], by Seth Kenlon
|
||||
* [Groovy][6], by Chris Hermansen
|
||||
* [JavaScript][7], by Mandy Kendall
|
||||
* [awk][8], by Chris Hermansen
|
||||
* [Lua][9], by Seth Kenlon
|
||||
|
||||
|
||||
|
||||
And in non-C-based languages:
|
||||
|
||||
* [Racket][10], by Cristiano L. Fontana
|
||||
* [Python][11], by Moshe Zadka
|
||||
* [Elixir][12], by Moshe Zadka
|
||||
* [Bash][13], by Jim Hall
|
||||
* [Fortran][14], by Jim Hall
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/compare-programming-languages
|
||||
|
||||
作者:[Jim Hall][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/jim-hall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_development_programming.png?itok=M_QDcgz5 (Developing code.)
|
||||
[2]: https://opensource.com/article/21/1/learn-c
|
||||
[3]: https://opensource.com/article/20/12/learn-c-game
|
||||
[4]: https://opensource.com/article/20/12/learn-rust
|
||||
[5]: https://opensource.com/article/20/12/learn-java
|
||||
[6]: https://opensource.com/article/20/12/groovy
|
||||
[7]: https://opensource.com/article/21/1/learn-javascript
|
||||
[8]: https://opensource.com/article/21/1/learn-awk
|
||||
[9]: https://opensource.com/article/20/12/lua-guess-number-game
|
||||
[10]: https://opensource.com/article/21/1/racket-guess-number
|
||||
[11]: https://opensource.com/article/20/12/learn-python
|
||||
[12]: https://opensource.com/article/20/12/elixir
|
||||
[13]: https://opensource.com/article/20/12/learn-bash
|
||||
[14]: https://opensource.com/article/21/1/fortran
|
179
sources/tech/20210405 Scaling Microservices on Kubernetes.md
Normal file
179
sources/tech/20210405 Scaling Microservices on Kubernetes.md
Normal file
@ -0,0 +1,179 @@
|
||||
[#]: subject: (Scaling Microservices on Kubernetes)
|
||||
[#]: via: (https://www.linux.com/news/scaling-microservices-on-kubernetes/)
|
||||
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Scaling Microservices on Kubernetes
|
||||
======
|
||||
|
||||
_By Ashley Davis_
|
||||
|
||||
_*This article was originally published at [TheNewStack][1]_
|
||||
|
||||
Applications built on microservices can be scaled in multiple ways. We can scale them to support development by larger development teams and we can also scale them up for better performance. Our application can then have a higher capacity and can handle a larger workload.
|
||||
|
||||
Using microservices gives us granular control over the performance of our application. We can easily measure the performance of our microservices to find the ones that are performing poorly, are overworked, or are overloaded at times of peak demand. Figure 1 shows how we might use the [Kubernetes dashboard][2] to understand CPU and memory usage for our microservices.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/748d12fb-image9.png>
|
||||
|
||||
_Figure 1: Viewing CPU and memory usage for microservices in the Kubernetes dashboard_
|
||||
|
||||
If we were using a monolith, however, we would have limited control over performance. We could vertically scale the monolith, but that’s basically it.
|
||||
|
||||
Horizontally scaling a monolith is much more difficult; and we simply can’t independently scale any of the “parts” of a monolith. This isn’t ideal, because it might only be a small part of the monolith that causes the performance problem. Yet, we would have to vertically scale the entire monolith to fix it. Vertically scaling a large monolith can be an expensive proposition.
|
||||
|
||||
Instead, with microservices, we have numerous options for scaling. For instance, we can independently fine-tune the performance of small parts of our system to eliminate bottlenecks and achieve the right mix of performance outcomes.
|
||||
|
||||
There are also many advanced ways we could tackle performance issues, but in this post, we’ll overview a handful of relatively simple techniques for scaling our microservices using [Kubernetes][3]:
|
||||
|
||||
1. Vertically scaling the entire cluster
|
||||
2. Horizontally scaling the entire cluster
|
||||
3. Horizontally scaling individual microservices
|
||||
4. Elastically scaling the entire cluster
|
||||
5. Elastically scaling individual microservices
|
||||
|
||||
|
||||
|
||||
Scaling often requires risky configuration changes to our cluster. For this reason, you shouldn’t try to make any of these changes directly to a production cluster that your customers or staff are depending on.
|
||||
|
||||
Instead, I would suggest that you create a new cluster and use **blue-green deployment**, or a similar deployment strategy, to buffer your users from risky changes to your infrastructure.
|
||||
|
||||
### **Vertically Scaling the Cluster**
|
||||
|
||||
As we grow our application, we might come to a point where our cluster generally doesn’t have enough compute, memory or storage to run our application. As we add new microservices (or replicate existing microservices for redundancy), we will eventually max out the nodes in our cluster. (We can monitor this through our cloud vendor or the Kubernetes dashboard.)
|
||||
|
||||
At this point, we must increase the total amount of resources available to our cluster. When scaling microservices on a [Kubernetes cluster][4], we can just as easily make use of either vertical or horizontal scaling. Figure 2 shows what vertical scaling looks like for Kubernetes.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/00c4f89c-image8.png>
|
||||
|
||||
_Figure 2: Vertically scaling your cluster by increasing the size of the virtual machines (VMs)_
|
||||
|
||||
We scale up our cluster by increasing the size of the virtual machines (VMs) in the node pool. In this example, we increased the size of three small-sized VMs so that we now have three large-sized VMs. We haven’t changed the number of VMs; we’ve just increased their size — scaling our VMs vertically.
|
||||
|
||||
Listing 1 is an extract from Terraform code that provisions a cluster on Azure; we change the vm_size field from Standard_B2ms to Standard_B4ms. This upgrades the size of each VM in our Kubernetes node pool. Instead of two CPUs, we now have four (one for each VM). As part of this change, memory and hard-drive for the VM also increase. If you are deploying to AWS or GCP, you can use this technique to vertically scale, but those cloud platforms offer different options for varying VM sizes.
|
||||
|
||||
We still only have a single VM in our cluster, but we have increased our VM’s size. In this example, scaling our cluster is as simple as a code change. This is the power of infrastructure-as-code, the technique where we store our infrastructure configuration as code and make changes to our infrastructure by committing code changes that trigger our continuous delivery (CD) pipeline
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/32f268d3-image2.png>
|
||||
|
||||
_Listing 1: Vertically scaling the cluster with Terraform (an extract)_
|
||||
|
||||
### Horizontally Scaling the Cluster
|
||||
|
||||
In addition to vertically scaling our cluster, we can also scale it horizontally. Our VMs can remain the same size, but we simply add more VMs.
|
||||
|
||||
By adding more VMs to our cluster, we spread the load of our application across more computers. Figure 3 illustrates how we can take our cluster from three VMs up to six. The size of each VM remains the same, but we gain more computing power by having more VMs.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/81dea0ef-image1.png>
|
||||
|
||||
_Figure 3: Horizontally scaling your cluster by increasing the number of VMs_
|
||||
|
||||
Listing 2 shows an extract of Terraform code to add more VMs to our node pool. Back in listing 1, we had node_count set to 1, but here we have changed it to 6. Note that we reverted the vm_size field to the smaller size of Standard_B2ms. In this example, we increase the number of VMs, but not their size; although there is nothing stopping us from increasing both the number and the size of our VMs.
|
||||
|
||||
Generally, though, we might prefer horizontal scaling because it is less expensive than vertical scaling. That’s because using many smaller VMs is cheaper than using fewer but bigger and higher-priced VMs.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/31716e5c-image6.png>
|
||||
|
||||
_Listing 2: Horizontal scaling the cluster with Terraform (an extract)_
|
||||
|
||||
### Horizontally Scaling an Individual Microservice
|
||||
|
||||
Assuming our cluster is scaled to an adequate size to host all the microservices with good performance, what do we do when individual microservices become overloaded? (This can be monitored in the Kubernetes dashboard.)
|
||||
|
||||
Whenever a microservice becomes a performance bottleneck, we can horizontally scale it to distribute its load over multiple instances. This is shown in figure 4.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/39ee5bd0-image4.png>
|
||||
|
||||
_Figure 4: Horizontally scaling a microservice by replicating it_
|
||||
|
||||
We are effectively giving more compute, memory and storage to this particular microservice so that it can handle a bigger workload.
|
||||
|
||||
Again, we can use code to make this change. We can do this by setting the replicas field in the specification for our Kubernetes deployment or pod as shown in listing 3.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/5acaf6b1-image5.png>
|
||||
|
||||
_Listing 3: Horizontally scaling a microservice with Terraform (an extract)_
|
||||
|
||||
Not only can we scale individual microservices for performance, we can also horizontally scale our microservices for redundancy, creating a more fault-tolerant application. By having multiple instances, there are others available to pick up the load whenever any single instance fails. This allows the failed instance of a microservice to restart and begin working again.
|
||||
|
||||
### Elastic Scaling for the Cluster
|
||||
|
||||
Moving into more advanced territory, we can now think about elastic scaling. This is a technique where we automatically and dynamically scale our cluster to meet varying levels of demand.
|
||||
|
||||
Whenever a demand is low, [Kubernetes][5] can automatically deallocate resources that aren’t needed. During high-demand periods, new resources are allocated to meet the increased workload. This generates substantial cost savings because, at any given moment, we only pay for the resources necessary to handle our application’s workload at that time.
|
||||
|
||||
We can use elastic scaling at the cluster level to automatically grow our clusters that are nearing their resource limits. Yet again, when using Terraform, this is just a code change. Listing 4 shows how we can enable the Kubernetes autoscaler and set the minimum and maximum size of our node pool.
|
||||
|
||||
Elastic scaling for the cluster works by default, but there are also many ways we can customize it. Search for “auto_scaler_profile” in [the Terraform documentation][6] to learn more.
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/feb61037-image3.png>
|
||||
|
||||
_Listing 4: Enabling elastic scaling for the cluster with Terraform (an extract)_
|
||||
|
||||
### Elastic Scaling for an Individual Microservice
|
||||
|
||||
We can also enable elastic scaling at the level of an individual microservice.
|
||||
|
||||
Listing 5 is a sample of Terraform code that gives microservices a “burstable” capability. The number of replicas for the microservice is expanded and contracted dynamically to meet the varying workload for the microservice (bursts of activity).
|
||||
|
||||
The scaling works by default, but can be customized to use other metrics. See the [Terraform documentation][7] to learn more. To learn more about pod auto-scaling in Kubernetes, [see the Kubernetes docs][8].
|
||||
|
||||
<https://cdn.thenewstack.io/media/2021/03/d4bd53af-image7.png>
|
||||
|
||||
_Listing 5: Enabling elastic scaling for a microservice with Terraform_
|
||||
|
||||
### About the Book: Bootstrapping Microservices
|
||||
|
||||
You can learn about building applications with microservices with [Bootstrapping Microservices][9].
|
||||
|
||||
Bootstrapping Microservices is a practical and project-based guide to building applications with microservices. It will take you all the way from building one single microservice all the way up to running a microservices application in production on [Kubernetes][10], ending up with an automated continuous delivery pipeline and using _infrastructure-as-code_ to push updates into production.
|
||||
|
||||
### Other Kubernetes Resources
|
||||
|
||||
This post is an extract from _Bootstrapping Microservices_ and has been a short overview of the ways we can scale microservices when running them on Kubernetes.
|
||||
|
||||
We specify the configuration for our infrastructure using Terraform. Creating and updating our infrastructure through code in this way is known as **intrastructure-as-code**, as a technique that turns working with infrastructure into a coding task and paved the way for the DevOps revolution.
|
||||
|
||||
To learn more about [Kubernetes][11], please see [the Kubernetes documentation][12] and the free [Introduction to Kubernetes][13] training course.
|
||||
|
||||
To learn more about working with Kubernetes using Terraform, please see [the Terraform documentation][14].
|
||||
|
||||
**About the Author, Ashley Davis**
|
||||
|
||||
Ashley is a software craftsman, entrepreneur, and author with over 20 years of experience in software development, from coding to managing teams, then to founding companies. He is the CTO of Sortal, a product that automatically sorts digital assets through the magic of machine learning.
|
||||
|
||||
The post [Scaling Microservices on Kubernetes][15] appeared first on [Linux Foundation – Training][16].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/scaling-microservices-on-kubernetes/
|
||||
|
||||
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://thenewstack.io/scaling-microservices-on-kubernetes/
|
||||
[2]: https://coding-bootcamps.com/blog/kubernetes-evolution-from-virtual-servers-and-kubernetes-architecture.html
|
||||
[3]: https://learn.coding-bootcamps.com/p/complete-live-training-for-mastering-devops-and-all-of-its-tools
|
||||
[4]: https://blockchain.dcwebmakers.com/blog/advance-topics-for-deploying-and-managing-kubernetes-containers.html
|
||||
[5]: http://myhsts.org/tutorial-review-of-17-essential-topics-for-mastering-kubernetes.php
|
||||
[6]: https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html
|
||||
[7]: http://www.terraform.io/docs/providers/kubernetes/r/horizontal_pod_autoscaler.html
|
||||
[8]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
|
||||
[9]: https://www.manning.com/books/bootstrapping-microservices-with-docker-kubernetes-and-terraform
|
||||
[10]: https://coding-bootcamps.com/blog/build-containerized-applications-with-golang-on-kubernetes.html
|
||||
[11]: https://learn.coding-bootcamps.com/p/live-training-class-for-mastering-kubernetes-containers-and-cloud-native
|
||||
[12]: https://kubernetes.io/docs/home/
|
||||
[13]: https://training.linuxfoundation.org/training/introduction-to-kubernetes/
|
||||
[14]: https://registry.terraform.io/providers/hashicorp/kubernetes/latest
|
||||
[15]: https://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/
|
||||
[16]: https://training.linuxfoundation.org/
|
@ -0,0 +1,145 @@
|
||||
[#]: subject: (Use Apache Superset for open source business intelligence reporting)
|
||||
[#]: via: (https://opensource.com/article/21/4/business-intelligence-open-source)
|
||||
[#]: author: (Maxime Beauchemin https://opensource.com/users/mistercrunch)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Use Apache Superset for open source business intelligence reporting
|
||||
======
|
||||
Since its creation in 2015 at an Airbnb hackathon, Apache Superset has
|
||||
matured into a leading open source BI solution.
|
||||
![metrics and data shown on a computer screen][1]
|
||||
|
||||
They say software is eating the world, but it's equally clear that open source is taking over software.
|
||||
|
||||
Simply put, open source is a superior approach for building and distributing software because it provides important guarantees around how software can be discovered, tried, operated, collaborated on, and packaged. For those reasons, it is not surprising that it has taken over most of the modern data stack: Infrastructure, databases, orchestration, data processing, AI/ML, and beyond.
|
||||
|
||||
Looking back, the main reason why I originally created both [Apache Airflow][2] and [Apache Superset][3] while I was at Airbnb from 2014-17 is that the vendors in the data space were failing to:
|
||||
|
||||
* Keep up with the pace of innovation in the data ecosystem
|
||||
* Give power to users who wanted to satisfy their more advanced use cases
|
||||
|
||||
|
||||
|
||||
As is often the case with open source, the capacity to integrate and extend was always at the core of how we approached the architecture of those two projects.
|
||||
|
||||
### Headaches with Tableau
|
||||
|
||||
More specifically, for Superset, the main driver to start the project at the time was the fact that Tableau (which was, at the time, our main data visualization tool) couldn't connect natively to [Apache Druid][4] and [Trino][5]/[Presto][6]. These were our data engines of choice that provided the properties and guarantees that we needed to satisfy our data use cases.
|
||||
|
||||
With Tableau's "Live Mode" misbehaving in intricate ways at the time (I won't get into this!), we were steered towards using Tableau Extracts. Extracts crumbled under the data volumes we had at Airbnb, creating a whole lot of challenges around non-additive metrics (think distinct user counts) and forcing us to intricately pre-compute multiple "grouping sets," which broke down some of the Tableau paradigms and confused users. Secondarily, we had a limited number of licenses for Tableau and generally had an order of magnitude more employees that wanted/needed access to our internal than our contract allowed. That's without mentioning the fact that for a cloud-native company, Tableau's Windows-centric approach at the time didn't work well for the team.
|
||||
|
||||
Some of the above premises have since changed, but the power of open source and the core principles on which it's built have only grown. In this blog post, I will explain why the future of business intelligence is open source.
|
||||
|
||||
## Benefits of open source
|
||||
|
||||
If I could only use a single word to describe why the time is right for organizations to adopt open source BI, the word would be _freedom_. Flowing from the principle of freedom comes a few more concrete superpowers for an organization:
|
||||
|
||||
* The power to customize, extend and integrate
|
||||
* The power of the community
|
||||
* Avoid vendor lock-in
|
||||
|
||||
|
||||
|
||||
### Extend, customize, and integrate
|
||||
|
||||
Airbnb wanted to integrate in-house tools like Dataportal and Minerva with a dashboarding tool to enable data democratization within their organization. Because Superset is open source and Airbnb actively contributes to the project, they could supercharge Superset with in-house components with relative ease.
|
||||
|
||||
On the visualization side, organizations like Nielsen create new visualizations and deploy them in their Superset environments. They're going a step further by empowering their engineers to contribute to Superset's customizability and extensibility. The Superset platform is now flexible enough so that anyone can build their [own custom visualization plugins][7], a benefit that is unmatched in the marketplace.
|
||||
|
||||
Many report using the rich [REST API that ships with Superset][8] within the wider community, allowing them full programmatic control over all aspects of the platform. Given that pretty much everything that users can do in Superset can be done through the API, the sky is the limit for automating processes in and around Superset.
|
||||
|
||||
Around the topic of integration, members from the Superset community have added support for over 30 databases ([and growing!][9]) by submitting code and documentation contributions. Because the core contributors bet on the right open source components ([SQLAlchemy][10] and Python [DB-API 2.0][11]), the Superset community both gives and receives to/from the broader Python community.
|
||||
|
||||
### The power of the community
|
||||
|
||||
Open source communities are composed of a diverse group of people who come together over a similar set of needs. This group is empowered to contribute to the common good. Vendors, on the other hand, tend to focus on their most important customers. Open source is a fundamentally different model that's much more collaborative and frictionless. As a result of this fundamentally de-centralized model, communities are very resilient to changes that vendor-led products struggle with. As contributors and organizations come and go, the community lives on!
|
||||
|
||||
At the core of the community are the active contributors that typically operate as a dynamic meritocracy. Network effects attract attention and talent, and communities welcome and offer guidance to newcomers because their goals are aligned. With the rise of platforms like Gitlab and Github, software is pretty unique in that engineers and developers from around the world seem to be able to come together and work collaboratively with minimal overhead. Those dynamics are fairly well understood and accepted as a disruptive paradigm shift in how people collaborate to build modern software.
|
||||
|
||||
![Growth in Monthly Unique Contributors][12]
|
||||
|
||||
Growth in Monthly Unique Contributors
|
||||
|
||||
Beyond the software at the core of the project, dynamic communities contribute in all sorts of ways that provide even more value. Here are some examples:
|
||||
|
||||
* Rich and up-to-date documentation
|
||||
* Example use cases and testimonials, often in the form of blog posts
|
||||
* Bug reports and bug fixes, contributing to stability and quality
|
||||
* Ever-growing online knowledge bases and FAQs
|
||||
* How-to videos and conference talks
|
||||
* Real-time support networks of enthusiasts and experts in forums and on [chat platforms][13]
|
||||
* Dynamic mailing lists where core contributors propose and debate over complex issues
|
||||
* Feedback loops, ways to suggest features and influence roadmaps
|
||||
|
||||
|
||||
|
||||
### Avoid lock-in
|
||||
|
||||
Recently, [Atlassian acquired the proprietary BI platform Chart.io][14], started to downsize the Chart.io team, and announced their intention to shut down the platform. Their customers now have to scramble and find a new home for their analytics assets that they now have to rebuild.
|
||||
|
||||
![Chart.io Shutting Down][15]
|
||||
|
||||
Chart.io Shutting Down
|
||||
|
||||
This isn't a new phenomenon. Given how mature and dynamic the BI market is, consolidation has been accelerating over the past few years:
|
||||
|
||||
* Tableau was acquired by Salesforce
|
||||
* Looker was acquired by Google Cloud
|
||||
* Periscope was acquired by Sisense
|
||||
* Zoomdata was acquired by Logi Analytics
|
||||
|
||||
|
||||
|
||||
While consolidation is likely to continue, these concerns don't arise when your BI platform is open source. If you're self-hosting, you are essentially immune to vendor lock-in. If you choose to partner with a commercial open source software (COSS), you should have an array of options from alternative vendors to hiring expertise in the marketplace, all the way to taking ownership and operating the software on your own.
|
||||
|
||||
For example, if you were using Apache Airflow service to take care of your Airflow needs, and your cloud provider decided to shut down the service, you'd be left with a set of viable options:
|
||||
|
||||
* Select and migrate to another service provider in the space, such as Apache Airflow specialist [Astronomer][16].
|
||||
* Hire or consult Airflow talent that can help you take control. The community has fostered a large number of professionals who know and love Airflow and can help your organization.
|
||||
* Learn and act. That is, take control and tap into the community's amazing resources to run the software on your own (Docker, Helm, k8s operator, and so on.)
|
||||
|
||||
|
||||
|
||||
Even at [Preset][17], where we offer a cloud-hosted version of Superset, we don't fork the Superset code and instead run the same Superset that's available to everyone. In the Preset cloud, you can freely import and export data sources, charts, and dashboards. This is not unique to Preset. Many vendors understand that "no lock-in!" is integral to their value proposition and are incentivized to provide clear guarantees around this.
|
||||
|
||||
## Open source for your data
|
||||
|
||||
Open source is disruptive in the best of ways, providing freedom, and a set of guarantees that really matter when it comes to adopting software. These guarantees fully apply when it comes to business intelligence. In terms of business intelligence, Apache Superset has matured to a level where it's a compelling choice over any proprietary solution. Since its creation in 2015 at an Airbnb hackathon, the project has come a very long way indeed. Try it yourself to discover a combination of features and guarantees unique to open source BI. To learn more, visit and [join our growing community][18].
|
||||
|
||||
In this article, I review some of the top open source business intelligence (BI) and reporting...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/business-intelligence-open-source
|
||||
|
||||
作者:[Maxime Beauchemin][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/mistercrunch
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI- (metrics and data shown on a computer screen)
|
||||
[2]: https://airflow.apache.org/
|
||||
[3]: https://superset.apache.org/
|
||||
[4]: https://druid.apache.org/
|
||||
[5]: https://trino.io/
|
||||
[6]: https://prestodb.io/
|
||||
[7]: https://preset.io/blog/2020-07-02-hello-world/
|
||||
[8]: https://superset.apache.org/docs/rest-api/
|
||||
[9]: https://superset.apache.org/docs/databases/installing-database-drivers
|
||||
[10]: https://www.sqlalchemy.org/
|
||||
[11]: https://www.python.org/dev/peps/pep-0249/
|
||||
[12]: https://opensource.com/sites/default/files/uniquecontributors.png
|
||||
[13]: https://opensource.com/article/20/7/mattermost
|
||||
[14]: https://www.atlassian.com/blog/announcements/atlassian-acquires-chartio
|
||||
[15]: https://opensource.com/sites/default/files/chartio.jpg
|
||||
[16]: https://www.astronomer.io/
|
||||
[17]: https://preset.io/
|
||||
[18]: https://superset.apache.org/community/
|
225
sources/tech/20210407 Get started with batch files in FreeDOS.md
Normal file
225
sources/tech/20210407 Get started with batch files in FreeDOS.md
Normal file
@ -0,0 +1,225 @@
|
||||
[#]: subject: (Get started with batch files in FreeDOS)
|
||||
[#]: via: (https://opensource.com/article/21/3/batch-files-freedos)
|
||||
[#]: author: (Kevin O'Brien https://opensource.com/users/ahuka)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Get started with batch files in FreeDOS
|
||||
======
|
||||
Batch files are a great way to write your own simple programs and
|
||||
automate tasks that normally require lots of typing.
|
||||
![Computer screen with files or windows open][1]
|
||||
|
||||
On Linux, it's common to create _shell scripts_ to automate repetitive tasks. Similarly, on [FreeDOS][2], the open source implementation of old DOS operating systems, you can create a _batch file_ containing several FreeDOS commands. Then you can run your batch file to execute each command in order.
|
||||
|
||||
You create a batch file by using an ASCII text editor, such as the FreeDOS Edit application. Once you create a batch file, you save it with a file name and the extension `.bat`. The file name should be unique. If you use a FreeDOS command name as your own file name, the FreeDOS command probably will execute instead of your batch file.
|
||||
|
||||
Virtually all internal and external FreeDOS commands can be used in a batch file. When you create a batch file, you are essentially writing a program. FreeDOS batch files may not have the power of a structured programming language, but they can be very handy for quick but repetitive tasks.
|
||||
|
||||
### Commenting your code
|
||||
|
||||
The No. 1 good habit for any programmer to learn is to put comments in a program to explain what the code is doing. This is a very good thing to do, but you need to be careful not to fool the operating system into executing your comments. The way to avoid this is to place `REM` (short for "remark") at the beginning of a comment line.
|
||||
|
||||
FreeDOS ignores lines starting with `REM`. But anyone who looks at the source code (the text you've written in your batch file) can read your comments and understand what it's doing. This is also a way to temporarily disable a command without deleting it. Just open your batch file for editing, place `REM` at the beginning of the line you want to disable, and save it. When you want to re-enable that command, just open the file for editing and remove `REM`. This technique is sometimes referred to as "commenting out" a command.
|
||||
|
||||
### Get set up
|
||||
|
||||
Before you start writing your own batch files, I suggest creating a temporary directory in FreeDOS. This can be a safe space for you to play around with batch files without accidentally deleting, moving, or renaming important system files or directories. On FreeDOS, you [create a directory][3] with the `MD` command:
|
||||
|
||||
|
||||
```
|
||||
C:\>MD TEMP
|
||||
C:\>CD TEMP
|
||||
C:\TEMP>
|
||||
```
|
||||
|
||||
The `ECHO` FreeDOS command controls what is shown on the screen when you run a batch file. For instance, here is a simple one-line batch file:
|
||||
|
||||
|
||||
```
|
||||
`ECHO Hello world`
|
||||
```
|
||||
|
||||
If you create this file and run it, you will see the sentence displayed on the screen. The quickest way to do this is from the command line: Use the `COPY` command to take the input from your keyboard (`CON`) and place it into the file `TEST1.BAT`. Then press **Ctrl**+**Z** to stop the copy process, and press Return or Enter on your keyboard to return to a prompt.
|
||||
|
||||
Try creating this file as `TEST1.BAT` in your temporary directory, and then run it:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>COPY CON TEST1.BAT
|
||||
CON => TEST1.BAT
|
||||
ECHO Hello world
|
||||
^Z
|
||||
|
||||
C:\TEMP>TEST1
|
||||
Hello world
|
||||
```
|
||||
|
||||
This can be useful when you want to display a piece of text. For instance, you might see a message on your screen telling you to wait while a program finishes its task, or in a networked environment, you might see a login message.
|
||||
|
||||
What if you want to display a blank line? You might think that the `ECHO` command all by itself would do the trick, but the `ECHO` command alone asks FreeDOS to respond whether `ECHO` is on or off:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>ECHO
|
||||
ECHO is on
|
||||
```
|
||||
|
||||
The way to get a blank line is to use a `+` sign immediately after `ECHO`:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>ECHO+
|
||||
|
||||
C:\TEMP>
|
||||
```
|
||||
|
||||
### Batch file variables
|
||||
|
||||
A variable is a holding place for information you need your batch file to remember temporarily. This is a vital function of programming because you don't always know what data you want your batch file to use. Here's a simple example to demonstrate.
|
||||
|
||||
Create `TEST3.BAT`:
|
||||
|
||||
|
||||
```
|
||||
@MD BACKUPS
|
||||
COPY %1 BACKUPS\%1
|
||||
```
|
||||
|
||||
Variables are signified by the use of the percentage symbol followed by a number, so this batch file creates a `BACKUPS` subdirectory in your current directory and then copies a variable `%1` into a `BACKUPS` folder. What is this variable? That's up to you to decide when you run the batch file:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>TEST3 TEMP1.BAT
|
||||
TEST1.BAT => BACKUPS\TEST1.BAT
|
||||
```
|
||||
|
||||
Your batch file has copied `TEST1.BAT` into a subdirectory called `BACKUPS` because you identified that file as an argument when running your batch file. Your batch file substituted `TEST1.BAT` for `%1`.
|
||||
|
||||
Variables are positional. The variable `%1` is the first argument you provide to your command, while `%2` is the second, and so on. Suppose you create a batch file to list the contents of a directory:
|
||||
|
||||
|
||||
```
|
||||
`DIR %1`
|
||||
```
|
||||
|
||||
Try running it:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>TEST4.BAT C:\HOME
|
||||
ARTICLES
|
||||
BIN
|
||||
CHEATSHEETS
|
||||
GAMES
|
||||
DND
|
||||
```
|
||||
|
||||
That works as expected. But this fails:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP>TEST4.BAT C:\HOME C:\DOCS
|
||||
ARTICLES
|
||||
BIN
|
||||
CHEATSHEETS
|
||||
GAMES
|
||||
DND
|
||||
```
|
||||
|
||||
If you try that, you get the listing of the first argument (`C:\HOME`) but not of the second (`C:\DOCS`). This is because your batch file is only looking for one variable (`%1`), and besides, the `DIR` command can take only one directory.
|
||||
|
||||
Also, you don't really need to specify a batch file's extension when you run it—unless you are unlucky enough to pick a name for the batch file that matches one of the FreeDOS external commands or something similar. When FreeDOS executes commands, it goes in the following order:
|
||||
|
||||
1. Internal commands
|
||||
2. External commands with the *.COM extension
|
||||
3. External commands with the *.EXE extension
|
||||
4. Batch files
|
||||
|
||||
|
||||
|
||||
### Multiple arguments
|
||||
|
||||
OK, now rewrite the `TEST4.BAT` file to use a command that takes two arguments so that you can see how this works. First, create a simple text file called `FILE1.TXT` using the `EDIT` application. Put a sentence of some kind inside (e.g., "Hello world"), and save the file in your `TEMP` working directory.
|
||||
|
||||
Next, use `EDIT` to change your `TEST4.BAT` file:
|
||||
|
||||
|
||||
```
|
||||
COPY %1 %2
|
||||
DIR
|
||||
```
|
||||
|
||||
Save it, then execute the command:
|
||||
|
||||
|
||||
```
|
||||
`C:\TEMP\>TEST4 FILE1.TXT FILE2.TXT`
|
||||
```
|
||||
|
||||
Upon running your batch file, you see a directory listing of your `TEMP` directory. Among the files listed, you have `FILE1.TXT` and `FILE2.TXT`, which were created by your batch file.
|
||||
|
||||
### Nested batch files
|
||||
|
||||
Another feature of batch files is that they can be "nested," meaning that one batch file can be called and run inside another batch file. To see how this works, start with a simple pair of batch files.
|
||||
|
||||
The first file is called `NBATCH1.BAT`:
|
||||
|
||||
|
||||
```
|
||||
@ECHO OFF
|
||||
ECHO Hello
|
||||
CALL NBATCH2.BAT
|
||||
ECHO world
|
||||
```
|
||||
|
||||
The first line (`@ECHO OFF`) quietly tells the batch file to show only the output of the commands (not the commands themselves) when you run it. You probably noticed in previous examples that there was a lot of feedback about what the batch file was doing; in this case, you're permitting your batch file to display only the results.
|
||||
|
||||
The second batch file is called NBATCH2.BAT:
|
||||
|
||||
|
||||
```
|
||||
`echo from FreeDOS`
|
||||
```
|
||||
|
||||
Create both of these files using `EDIT`, and save them in your TEMP subdirectory. Run `NBATCH1.BAT` to see what happens:
|
||||
|
||||
|
||||
```
|
||||
C:\TEMP\>NBATCH1.BAT
|
||||
Hello
|
||||
from FreeDOS
|
||||
world
|
||||
```
|
||||
|
||||
Your second batch file was executed from within the first by the `CALL` command, which provided the string "from FreeDOS" in the middle of your "Hello world" message.
|
||||
|
||||
### FreeDOS scripting
|
||||
|
||||
Batch files are a great way to write your own simple programs and automate tasks that normally require lots of typing. The more you use FreeDOS, the more familiar you'll become with its commands, and once you know the commands, it's just a matter of listing them in a batch file to make your FreeDOS system make your life easier. Give it a try!
|
||||
|
||||
* * *
|
||||
|
||||
_Some of the information in this article was previously published in [DOS lesson 15: Introduction to batch files][4] and [DOS lesson 17: Batch file variables; nested batch files][5] (both CC BY-SA 4.0)._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/batch-files-freedos
|
||||
|
||||
作者:[Kevin O'Brien][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/ahuka
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_screen_windows_files.png?itok=kLTeQUbY (Computer screen with files or windows open)
|
||||
[2]: https://www.freedos.org/
|
||||
[3]: https://opensource.com/article/21/2/freedos-commands-you-need-know
|
||||
[4]: https://www.ahuka.com/dos-lessons-for-self-study-purposes/dos-lesson-15-introduction-to-batch-files/
|
||||
[5]: https://www.ahuka.com/dos-lessons-for-self-study-purposes/dos-lesson-17-batch-file-variables-nested-batch-files/
|
@ -0,0 +1,288 @@
|
||||
[#]: subject: (Using network bound disk encryption with Stratis)
|
||||
[#]: via: (https://fedoramagazine.org/network-bound-disk-encryption-with-stratis/)
|
||||
[#]: author: (briansmith https://fedoramagazine.org/author/briansmith/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Using network bound disk encryption with Stratis
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Photo by [iMattSmart][2] on [Unsplash][3]
|
||||
|
||||
In an environment with many encrypted disks, unlocking them all is a difficult task. Network bound disk encryption (NBDE) helps automate the process of unlocking Stratis volumes. This is a critical requirement in large environments. Stratis version 2.1 added support for encryption, which was introduced in the article “[Getting started with Stratis encryption][4].” Stratis version 2.3 recently introduced support for Network Bound Disk Encryption (NBDE) when using encrypted Stratis pools, which is the topic of this article.
|
||||
|
||||
The [Stratis website][5] describes Stratis as an “_easy to use local storage management for Linux_.” The short video [“Managing Storage With Stratis”][6] gives a quick demonstration of the basics. The video was recorded on a Red Hat Enterprise Linux 8 system, however, the concepts shown in the video also apply to Stratis in Fedora Linux.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
This article assumes you are familiar with Stratis, and also Stratis pool encryption. If you aren’t familiar with these topics, refer to this [article][4] and the [Stratis overview video][6] previously mentioned.
|
||||
|
||||
NBDE requires Stratis 2.3 or later. The examples in this article use a pre-release version of Fedora Linux 34. The Fedora Linux 34 final release will include Stratis 2.3.
|
||||
|
||||
### Overview of network bound disk encryption (NBDE)
|
||||
|
||||
One of the main challenges of encrypting storage is having a secure method to unlock the storage again after a system reboot. In large environments, typing in the encryption passphrase manually doesn’t scale well. NBDE addresses this and allows for encrypted storage to be unlocked in an automated manner.
|
||||
|
||||
At a high level, NBDE requires a Tang server in the environment. Client systems (using Clevis Pin) can automatically decrypt storage as long as they can establish a network connection to the Tang server. If there is no network connectivity to the Tang server, the storage would have to be decrypted manually.
|
||||
|
||||
The idea behind this is that the Tang server would only be available on an internal network, thus if the encrypted device is lost or stolen, it would no longer have access to the internal network to connect to the Tang server, therefore would not be automatically decrypted.
|
||||
|
||||
For more information on Tang and Clevis, see the man pages (man tang, man clevis) , the [Tang GitHub page][7], and the [Clevis GitHub page][8].
|
||||
|
||||
### Setting up the Tang server
|
||||
|
||||
This example uses another Fedora Linux system as the Tang server with a hostname of tang-server. Start by installing the tang package:
|
||||
|
||||
```
|
||||
dnf install tang
|
||||
```
|
||||
|
||||
Then enable and start the tangd.socket with systemctl:
|
||||
|
||||
```
|
||||
systemctl enable tangd.socket --now
|
||||
```
|
||||
|
||||
Tang uses TCP port 80, so you also need to open that in the firewall:
|
||||
|
||||
```
|
||||
firewall-cmd --add-port=80/tcp --permanent
|
||||
firewall-cmd --add-port=80/tcp
|
||||
```
|
||||
|
||||
Finally, run _tang-show-keys_ to display the output signing key thumbprint. You’ll need this later.
|
||||
|
||||
```
|
||||
# tang-show-keys
|
||||
l3fZGUCmnvKQF_OA6VZF9jf8z2s
|
||||
```
|
||||
|
||||
### Creating the encrypted Stratis Pool
|
||||
|
||||
The previous article on Stratis encryption goes over how to setup an encrypted Stratis pool in detail, so this article won’t cover that in depth.
|
||||
|
||||
The first step is capturing a key that will be used to decrypt the Stratis pool. Even when using NBDE, you need to set this, as it can be used to manually unlock the pool in the event that the NBDE server is unreachable. Capture the pool1 key with the following command:
|
||||
|
||||
```
|
||||
# stratis key set --capture-key pool1key
|
||||
Enter key data followed by the return key:
|
||||
```
|
||||
|
||||
Then I’ll create an encrypted Stratis pool (using the pool1key just created) named pool1 using the _/dev/vdb_ device:
|
||||
|
||||
```
|
||||
# stratis pool create --key-desc pool1key pool1 /dev/vdb
|
||||
```
|
||||
|
||||
Next, create a filesystem in this Stratis pool named filesystem1, create a mount point, mount the filesystem, and create a testfile in it:
|
||||
|
||||
```
|
||||
# stratis filesystem create pool1 filesystem1
|
||||
# mkdir /filesystem1
|
||||
# mount /dev/stratis/pool1/filesystem1 /filesystem1
|
||||
# cd /filesystem1
|
||||
# echo "this is a test file" > testfile
|
||||
```
|
||||
|
||||
### Binding the Stratis pool to the Tang server
|
||||
|
||||
At this point, we have the encrypted Stratis pool created, and also have a filesystem created in the pool. The next step is to bind your Stratis pool to the Tang server that you just setup. Do this with the _stratis pool bind nbde_ command.
|
||||
|
||||
When you make the Tang binding, you need to pass several parameters to the command:
|
||||
|
||||
* the pool name (in this example, pool1)
|
||||
* the key descriptor name (in this example, pool1key)
|
||||
* the Tang server name (in this example, <http://tang-server>)
|
||||
|
||||
|
||||
|
||||
Recall that on the Tang server, you previously ran _tang-show-keys_ which showed the Tang output signing key thumbprint is _l3fZGUCmnvKQF_OA6VZF9jf8z2s_. In addition to the previous parameters, you either need to pass this thumbprint with the parameter _–thumbprint l3fZGUCmnvKQF_OA6VZF9jf8z2s_, or skip the verification of the thumbprint with the _–trust-url_ parameter. ****
|
||||
|
||||
It is more secure to use the _–thumbprint_ parameter. For example:
|
||||
|
||||
```
|
||||
# stratis pool bind nbde pool1 pool1key http://tang-server --thumbprint l3fZGUCmnvKQF_OA6VZF9jf8z2s
|
||||
```
|
||||
|
||||
### Unlocking the Stratis Pool with NBDE
|
||||
|
||||
Next reboot the host, and validate that you can unlock the Stratis pool with NBDE, without requiring the use of the key passphrase. After rebooting the host, the pool is no longer available:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
```
|
||||
|
||||
To unlock the pool using NBDE, run the following command:
|
||||
|
||||
```
|
||||
# stratis pool unlock clevis
|
||||
```
|
||||
|
||||
Note that you did not need to use the key passphrase. This command could be automated to run during the system boot up.
|
||||
|
||||
At this point, the pool is now available:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
pool1 4.98 GiB / 583.65 MiB / 4.41 GiB ~Ca, Cr
|
||||
```
|
||||
|
||||
You can mount the filesystem and access the file that was previously created:
|
||||
|
||||
```
|
||||
# mount /dev/stratis/pool1/filesystem1 /filesystem1/
|
||||
# cat /filesystem1/testfile
|
||||
this is a test file
|
||||
```
|
||||
|
||||
### Rotating Tang server keys
|
||||
|
||||
Best practices recommend that you periodically rotate the Tang server keys and update the Stratis client servers to use the new Tang keys.
|
||||
|
||||
To generate new Tang keys, start by logging in to your Tang server and look at the current status of the /var/db/tang directory. Then, run the _tang-show-keys_ command:
|
||||
|
||||
```
|
||||
# ls -al /var/db/tang
|
||||
total 8
|
||||
drwx------. 1 tang tang 124 Mar 15 15:51 .
|
||||
drwxr-xr-x. 1 root root 16 Mar 15 15:48 ..
|
||||
-rw-r--r--. 1 tang tang 361 Mar 15 15:51 hbjJEDXy8G8wynMPqiq8F47nJwo.jwk
|
||||
-rw-r--r--. 1 tang tang 367 Mar 15 15:51 l3fZGUCmnvKQF_OA6VZF9jf8z2s.jwk
|
||||
# tang-show-keys
|
||||
l3fZGUCmnvKQF_OA6VZF9jf8z2s
|
||||
```
|
||||
|
||||
To generate new keys, run tangd-keygen and point it to the /var/db/tang directory:
|
||||
|
||||
```
|
||||
# /usr/libexec/tangd-keygen /var/db/tang
|
||||
```
|
||||
|
||||
If you look at the /var/db/tang directory again, you will see two new files:
|
||||
|
||||
```
|
||||
# ls -al /var/db/tang
|
||||
total 16
|
||||
drwx------. 1 tang tang 248 Mar 22 10:41 .
|
||||
drwxr-xr-x. 1 root root 16 Mar 15 15:48 ..
|
||||
-rw-r--r--. 1 tang tang 361 Mar 15 15:51 hbjJEDXy8G8wynMPqiq8F47nJwo.jwk
|
||||
-rw-r--r--. 1 root root 354 Mar 22 10:41 iyG5HcF01zaPjaGY6L_3WaslJ_E.jwk
|
||||
-rw-r--r--. 1 root root 349 Mar 22 10:41 jHxerkqARY1Ww_H_8YjQVZ5OHao.jwk
|
||||
-rw-r--r--. 1 tang tang 367 Mar 15 15:51 l3fZGUCmnvKQF_OA6VZF9jf8z2s.jwk
|
||||
```
|
||||
|
||||
And if you run _tang-show-keys_, it will show the keys being advertised by Tang:
|
||||
|
||||
```
|
||||
# tang-show-keys
|
||||
l3fZGUCmnvKQF_OA6VZF9jf8z2s
|
||||
iyG5HcF01zaPjaGY6L_3WaslJ_E
|
||||
```
|
||||
|
||||
You can prevent the old key (starting with l3fZ) from being advertised by renaming the two original files to be hidden files, starting with a period. With this method, the old key will no longer be advertised, however it will still be usable by any existing clients that haven’t been updated to use the new key. Once all clients have been updated to use the new key, these old key files can be deleted.
|
||||
|
||||
```
|
||||
# cd /var/db/tang
|
||||
# mv hbjJEDXy8G8wynMPqiq8F47nJwo.jwk .hbjJEDXy8G8wynMPqiq8F47nJwo.jwk
|
||||
# mv l3fZGUCmnvKQF_OA6VZF9jf8z2s.jwk .l3fZGUCmnvKQF_OA6VZF9jf8z2s.jwk
|
||||
```
|
||||
|
||||
At this point, if you run _tang-show-keys_ again, only the new key is being advertised by Tang:
|
||||
|
||||
```
|
||||
# tang-show-keys
|
||||
iyG5HcF01zaPjaGY6L_3WaslJ_E
|
||||
```
|
||||
|
||||
Next, switch over to your Stratis system and update it to use the new Tang key. Stratis supports doing this while the filesystem(s) are online.
|
||||
|
||||
First, unbind the pool:
|
||||
|
||||
```
|
||||
# stratis pool unbind pool1
|
||||
```
|
||||
|
||||
Next, set the key with the original passphrase used when the encrypted pool was created:
|
||||
|
||||
```
|
||||
# stratis key set --capture-key pool1key
|
||||
Enter key data followed by the return key:
|
||||
```
|
||||
|
||||
Finally, bind the pool to the Tang server with the updated key thumbprint:
|
||||
|
||||
```
|
||||
# stratis pool bind nbde pool1 pool1key http://tang-server --thumbprint iyG5HcF01zaPjaGY6L_3WaslJ_E
|
||||
```
|
||||
|
||||
The Stratis system is now configured to use the updated Tang key. Once any other client systems using the old Tang key have been updated, the two original key files that were renamed to hidden files in the /var/db/tang directory on the Tang server can be backed up and deleted.
|
||||
|
||||
### What if the Tang server is unavailable?
|
||||
|
||||
Next, shutdown the Tang server to simulate it being unavailable, then reboot the Stratis system.
|
||||
|
||||
Again, after the reboot, the Stratis pool is not available:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
```
|
||||
|
||||
If you try to unlock it with NBDE, this fails because the Tang server is unavailable:
|
||||
|
||||
```
|
||||
# stratis pool unlock clevis
|
||||
Execution failed:
|
||||
An iterative command generated one or more errors: The operation 'unlock' on a resource of type pool failed. The following errors occurred:
|
||||
Partial action "unlock" failed for pool with UUID 4d62f840f2bb4ec9ab53a44b49da3f48: Cryptsetup error: Failed with error: Error: Command failed: cmd: "clevis" "luks" "unlock" "-d" "/dev/vdb" "-n" "stratis-1-private-42142fedcb4c47cea2e2b873c08fcf63-crypt", exit reason: 1 stdout: stderr: /dev/vdb could not be opened.
|
||||
```
|
||||
|
||||
At this point, without the Tang server being reachable, the only option to unlock the pool is to use the original key passphrase:
|
||||
|
||||
```
|
||||
# stratis key set --capture-key pool1key
|
||||
Enter key data followed by the return key:
|
||||
```
|
||||
|
||||
You can then unlock the pool using the key:
|
||||
|
||||
```
|
||||
# stratis pool unlock keyring
|
||||
```
|
||||
|
||||
Next, verify the pool was successfully unlocked:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
pool1 4.98 GiB / 583.65 MiB / 4.41 GiB ~Ca, Cr
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/network-bound-disk-encryption-with-stratis/
|
||||
|
||||
作者:[briansmith][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://fedoramagazine.org/author/briansmith/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2021/03/stratis-nbde-816x345.jpg
|
||||
[2]: https://unsplash.com/@imattsmart?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/s/photos/lock?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/getting-started-with-stratis-encryption/
|
||||
[5]: https://stratis-storage.github.io/
|
||||
[6]: https://www.youtube.com/watch?v=CJu3kmY-f5o
|
||||
[7]: https://github.com/latchset/tang
|
||||
[8]: https://github.com/latchset/clevis
|
200
sources/tech/20210407 What is Git cherry-picking.md
Normal file
200
sources/tech/20210407 What is Git cherry-picking.md
Normal file
@ -0,0 +1,200 @@
|
||||
[#]: subject: (What is Git cherry-picking?)
|
||||
[#]: via: (https://opensource.com/article/21/4/cherry-picking-git)
|
||||
[#]: author: (Rajeev Bera https://opensource.com/users/acompiler)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
What is Git cherry-picking?
|
||||
======
|
||||
Learn the what, why, and how of the git cherry-pick command.
|
||||
![Measuring and baking a cherry pie recipe][1]
|
||||
|
||||
Whenever you're working with a group of programmers on a project, whether small or large, handling changes between multiple Git branches can become difficult. Sometimes, instead of combining an entire Git branch into a different one, you want to select and move a couple of specific commits. This procedure is known as "cherry-picking."
|
||||
|
||||
This article will cover the what, why, and how of cherry-picking.
|
||||
|
||||
So let's start.
|
||||
|
||||
### What is cherry-pick?
|
||||
|
||||
With the `cherry-pick` command, Git lets you incorporate selected individual commits from any branch into your current [Git HEAD][2] branch.
|
||||
|
||||
When performing a `git merge` or `git rebase`, all the commits from a branch are combined. The `cherry-pick` command allows you to select individual commits for integration.
|
||||
|
||||
### Benefits of cherry-pick
|
||||
|
||||
The following situation might make it easier to comprehend the way cherry-picking functions.
|
||||
|
||||
Imagine you are implementing new features for your upcoming weekly sprint. When your code is ready, you will push it into the remote branch, ready for testing.
|
||||
|
||||
However, the customer is not delighted with all of the modifications and requests that you present only certain ones. Because the client hasn't approved all changes for the next launch, `git rebase` wouldn't create the desired results. Why? Because `git rebase` or `git merge` will incorporate every adjustment from the last sprint.
|
||||
|
||||
Cherry-picking is the answer! Because it focuses only on the changes added in the commit, cherry-picking brings in only the approved changes without adding other commits.
|
||||
|
||||
There are several other reasons to use cherry-picking:
|
||||
|
||||
* It is essential for bug fixing because bugs are set in the development branch using their commits.
|
||||
* You can avoid unnecessary battles by using `git cherry-pick` instead of other options that apply changes in the specified commits, e.g., `git diff`.
|
||||
* It is a useful tool if a full branch unite is impossible because of incompatible versions in the various Git branches.
|
||||
|
||||
|
||||
|
||||
### Using the cherry-pick command
|
||||
|
||||
In the `cherry-pick` command's simplest form, you can just use the [SHA][3] identifier for the commit you want to integrate into your current HEAD branch.
|
||||
|
||||
To get the commit hash, you can use the `git log` command:
|
||||
|
||||
|
||||
```
|
||||
`$ git log --oneline`
|
||||
```
|
||||
|
||||
Once you know the commit hash, you can use the `cherry-pick` command.
|
||||
|
||||
The syntax is:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick <commit sha>`
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick 65be1e5`
|
||||
```
|
||||
|
||||
This will dedicate the specified change to your currently checked-out branch.
|
||||
|
||||
If you'd like to make further modifications, you can also instruct Git to add commit changes to your working copy.
|
||||
|
||||
The syntax is:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick <commit sha> --no-commit`
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick 65be1e5 --no-commit`
|
||||
```
|
||||
|
||||
If you would like to select more than one commit simultaneously, add their commit hashes separated by a space:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick hash1 hash3`
|
||||
```
|
||||
|
||||
When cherry-picking commits, you can't use the `git pull` command because it fetches _and_ automatically merges commits from one repository into another. The `cherry-pick` command is a tool you use to specifically not do that; instead, use `git fetch`, which fetches commits but does not apply them. There's no doubt that `git pull` is convenient, but it's imprecise.
|
||||
|
||||
### Try it yourself
|
||||
|
||||
To try the process, launch a terminal and generate a sample project:
|
||||
|
||||
|
||||
```
|
||||
$ mkdir fruit.git
|
||||
$ cd fruit.git
|
||||
$ git init .
|
||||
```
|
||||
|
||||
Create some data and commit it:
|
||||
|
||||
|
||||
```
|
||||
$ echo "Kiwifruit" > fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'First commit'
|
||||
```
|
||||
|
||||
Now, represent a remote developer by creating a fork of your project:
|
||||
|
||||
|
||||
```
|
||||
$ mkdir ~/fruit.fork
|
||||
$ cd !$
|
||||
$ echo "Strawberry" >> fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'Added a fruit"
|
||||
```
|
||||
|
||||
That's a valid commit. Now, create a bad commit to represent something you wouldn't want to merge into your project:
|
||||
|
||||
|
||||
```
|
||||
$ echo "Rhubarb" >> fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'Added a vegetable that tastes like a fruit"
|
||||
```
|
||||
|
||||
Return to your authoritative repo and fetch the commits from your imaginary developer:
|
||||
|
||||
|
||||
```
|
||||
$ cd ~/fruit.git
|
||||
$ git remote add dev ~/fruit.fork
|
||||
$ git fetch dev
|
||||
remote: Counting objects: 6, done.
|
||||
remote: Compressing objects: 100% (2/2), done.
|
||||
remote: Total 6 (delta 0), reused 0 (delta 0)
|
||||
Unpacking objects: 100% (6/6), done...
|
||||
|
||||
[/code] [code]
|
||||
|
||||
$ git log –oneline dev/master
|
||||
e858ab2 Added a vegetable that tastes like a fruit
|
||||
0664292 Added a fruit
|
||||
b56e0f8 First commit
|
||||
```
|
||||
|
||||
You've fetched the commits from your imaginary developer, but you haven't merged them into your repository yet. You want to accept the second commit but not the third, so use `cherry-pick`:
|
||||
|
||||
|
||||
```
|
||||
`$ git cherry-pick 0664292`
|
||||
```
|
||||
|
||||
The second commit is now in your repository:
|
||||
|
||||
|
||||
```
|
||||
$ cat fruit.txt
|
||||
Kiwifruit
|
||||
Strawberry
|
||||
```
|
||||
|
||||
Push your changes to your remote server, and you're done!
|
||||
|
||||
### Reasons to avoid cherry-picking
|
||||
|
||||
Cherry-picking is usually discouraged in the developer community. The primary reason is that it creates duplicate commits, but you also lose the ability to track your commit history.
|
||||
|
||||
If you're cherry-picking a lot of commits out of order, those commits will be recorded in your branch, and it might lead to undesirable results in your Git branch.
|
||||
|
||||
Cherry-picking is a powerful command that might cause problems if it's used without a proper understanding of what might occur. However, it may save your life (or at least your day job) when you mess up and make commits to the wrong branches.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/cherry-picking-git
|
||||
|
||||
作者:[Rajeev Bera][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/acompiler
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/pictures/cherry-picking-recipe-baking-cooking.jpg?itok=XVwse6hw (Measuring and baking a cherry pie recipe)
|
||||
[2]: https://acompiler.com/git-head/
|
||||
[3]: https://en.wikipedia.org/wiki/Secure_Hash_Algorithms
|
@ -0,0 +1,114 @@
|
||||
[#]: subject: (Why I love using bspwm for my Linux window manager)
|
||||
[#]: via: (https://opensource.com/article/21/4/bspwm-linux)
|
||||
[#]: author: (Stephen Adams https://opensource.com/users/stevehnh)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Why I love using bspwm for my Linux window manager
|
||||
======
|
||||
Install, configure, and start using the bspwm window manager on Fedora
|
||||
Linux.
|
||||
![Tall building with windows][1]
|
||||
|
||||
Some folks like to rearrange furniture. Other folks like to try new shoes or redecorate their bedroom on the regular. Me? I try out Linux desktops.
|
||||
|
||||
After drooling over some of the incredible desktop environments I've seen online, I got curious about one window manager in particular: [bspwm][2].
|
||||
|
||||
![bspwm desktop][3]
|
||||
|
||||
(Stephen Adams, [CC BY-SA 4.0][4])
|
||||
|
||||
I've been a fan of the [i3][5] window manager for quite a while, and I enjoy the way everything is laid out and the ease of getting started. But something about bspwm called to me. There are a few reasons I decided to try it out:
|
||||
|
||||
* It is _only_ a window manager.
|
||||
* It is managed by a few easy-to-configure scripts.
|
||||
* It supports gaps between windows by default.
|
||||
|
||||
|
||||
|
||||
The first reason—that it is simply a window manager—is probably the top thing to point out. Like i3, there are no graphical bells and whistles applied by default. You can certainly customize it to your heart's content, but _you_ will be putting in all the work to make it look like you want. That's part of its appeal to me.
|
||||
|
||||
Although it is available on many distributions, my examples use Fedora Linux.
|
||||
|
||||
### Install bspwm
|
||||
|
||||
Bspwm is packaged in most common distributions, so you can install it with your system's package manager. This command also installs [sxkhd][6], a daemon for the X Window System "that reacts to input events by executing commands," and [dmenu][7], a generic X Window menu:
|
||||
|
||||
|
||||
```
|
||||
`dnf install bspwm sxkhd dmenu`
|
||||
```
|
||||
|
||||
Since bspwm is _just_ a window manager, there aren't any built-in shortcuts or keyboard commands. This is where it stands in contrast to something like i3. sxkhd makes it easier to get going. So, go ahead and configure sxkhd before you fire up the window manager for the first time:
|
||||
|
||||
|
||||
```
|
||||
systemctl start sxkhd
|
||||
systemctl enable sxkhd
|
||||
```
|
||||
|
||||
This enables sxkhd at login, but you also need a configuration with some basic functionality ready to go:
|
||||
|
||||
|
||||
```
|
||||
`curl https://raw.githubusercontent.com/baskerville/bspwm/master/examples/sxhkdrc --output ~/.config/sxkhd/sxkhdrc`
|
||||
```
|
||||
|
||||
It's worth taking a look at this file before you get much further, as some commands that the scripts call may not exist on your system. A good example is the `super + Return` shortcut that calls `urxvt`. Change this to your preferred terminal, especially if you do not have urxvt installed:
|
||||
|
||||
|
||||
```
|
||||
#
|
||||
# wm independent hotkeys
|
||||
#
|
||||
|
||||
# terminal emulator
|
||||
super + Return
|
||||
urxvt
|
||||
|
||||
# program launcher
|
||||
super + @space
|
||||
dmenu_run
|
||||
```
|
||||
|
||||
If you are using GDM, LightDM, or another display manager, just choose bspwm before logging in.
|
||||
|
||||
### Configure bspwm
|
||||
|
||||
Once you are logged in, you'll see a whole lot of nothing on the screen. That's not a sense of emptiness you feel. It's possibility! You are now ready to start fiddling with all the parts of a desktop environment that you have taken for granted all these years. Building from scratch is not easy, but it's very rewarding once you get the hang of it.
|
||||
|
||||
The most difficult thing about any window manager is getting a handle on the shortcuts. You're going to be slow to start, but in a short time, you'll be flying around your system using your keyboard alone and looking like an ultimate hacker to your friends and family.
|
||||
|
||||
You can tailor the system as much as you want by editing `~/.config/bspwm/bspwmrc` to add apps at launch, set up your desktops and monitors, and set rules for how your windows should behave. There are a few examples set by default to get you going. Keyboard shortcuts are all managed by the **sxkhdrc** file.
|
||||
|
||||
There are plenty more open source projects to install to really get things looking nice—like [Feh][8] for desktop backgrounds, [Polybar][9] for that all-important status bar, [Rofi][10] to really help your app launcher pop, and [Compton][11] to give you the shadows and transparency to get things nice and shiny.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/bspwm-linux
|
||||
|
||||
作者:[Stephen Adams][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/stevehnh
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/windows_building_sky_scale.jpg?itok=mH6CAX29 (Tall building with windows)
|
||||
[2]: https://github.com/baskerville/bspwm
|
||||
[3]: https://opensource.com/sites/default/files/uploads/bspwm-desktop.png (bspwm desktop)
|
||||
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[5]: https://i3wm.org/
|
||||
[6]: https://github.com/baskerville/sxhkd
|
||||
[7]: https://linux.die.net/man/1/dmenu
|
||||
[8]: https://github.com/derf/feh
|
||||
[9]: https://github.com/polybar/polybar
|
||||
[10]: https://github.com/davatorium/rofi
|
||||
[11]: https://github.com/chjj/compton
|
@ -0,0 +1,67 @@
|
||||
[#]: subject: (5 commands to level-up your Git game)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-commands)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
5 commands to level-up your Git game
|
||||
======
|
||||
Get more use out of Git by adding these commands to your repertoire.
|
||||
![Business woman on laptop sitting in front of window][1]
|
||||
|
||||
If you use Git regularly, you might be aware that it has several reputations. It's probably the most popular version-control solution and is used by some of the [biggest software projects][2] around to [keep track of changes][3] to files. It provides a [robust interface][4] to review and incorporate experimental changes into existing documents. It's well-known for its flexibility, thanks to [Git hooks][5]. And partly because of its great power, it has earned its reputation for being complex.
|
||||
|
||||
You don't have to use all of Git's many features, but if you're looking to delve deeper into Git's subcommands, here are some that you might find useful.
|
||||
|
||||
### 1\. Finding out what changed
|
||||
|
||||
If you're familiar with Git's basics (`fetch`, `add`, `commit`, `push`, `log`, and so on) but you want to learn more, Git subcommands that query are a great, safe place to start. Querying your Git repository (your _work tree_) doesn't make any changes; it's only a reporting mechanism. You're not risking the integrity of your Git checkout; you're only asking Git about its status and history.
|
||||
|
||||
The [git whatchanged][6] command (almost a mnemonic itself) is an easy way to see what changed in a commit. A remarkably user-friendly command, it squashes the best features of `show` and `diff-tree` and `log` into one easy-to-remember command.
|
||||
|
||||
### 2\. Managing changes with git stash
|
||||
|
||||
The more you use Git, the more you use Git. That is, once you've become comfortable with the power of Git, the more often you use its powerful features. Sometimes, you may find yourself in the middle of working with a batch of files when you realize some other task is more urgent. With [git stash][7], you can gather up all the pieces of your work in progress and stash them away for safekeeping. With your workspace decluttered, you can turn your attention to some other task and then reapply stashed files to your work tree later to resume work.
|
||||
|
||||
### 3\. Making a linked copy with git worktree
|
||||
|
||||
When `git stash` isn't enough, Git also provides the powerful [git worktree][8] command. With it, you can create a new but _linked_ clone of your repository, forming a new branch and setting `HEAD` to whatever commit you want to base your new work on. In this linked clone, you can work on a task unrelated to what your primary clone is focused on. It's a good way to keep your work in progress safe from unintended changes. When you're finished with your new work tree, you can push your new branch to a remote, bundle the changes into an archive for later, or just fetch the changes from your other tree. Whatever you decide, your workspaces are kept separate, and the changes in one don't have to affect changes in the other until you are ready to merge.
|
||||
|
||||
### 4\. Selecting merges with git cherry-pick
|
||||
|
||||
It may seem counterintuitive, but the better at Git you get, the more merge conflicts you're likely to encounter. That's because merge conflicts aren't necessarily signs of errors but signs of activity. Getting comfortable with merge conflicts and how to resolve them is an important step in learning Git. The usual methods work well, but sometimes you need greater flexibility in how you merge, and for that, there's [git cherry-pick][9]. Cherry-picking merges allows you to be selective in what parts of commits you merge, so you never have to reject a merge request based on a trivial incongruity.
|
||||
|
||||
### 5\. Managing $HOME with Git
|
||||
|
||||
Managing your home directory with Git has never been easier, and thanks to Git's ability to be selective in what it manages, it's a realistic option for keeping your computers in sync. To work well, though, you must do it judiciously. To get started, read my tips on [managing $HOME with Git][10].
|
||||
|
||||
### Getting better at Git
|
||||
|
||||
Git is a powerful version-control system, and the more comfortable you become with it, the easier it becomes to use it for complex tasks. Try some new Git commands today, and share your favorites in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-commands
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||
[2]: https://opensource.com/article/19/10/how-gnome-uses-git
|
||||
[3]: https://opensource.com/article/18/2/how-clone-modify-add-delete-git-files
|
||||
[4]: https://opensource.com/article/18/5/git-branching
|
||||
[5]: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
|
||||
[6]: https://opensource.com/article/21/3/git-whatchanged
|
||||
[7]: https://opensource.com/article/21/3/git-stash
|
||||
[8]: https://opensource.com/article/21/3/git-worktree
|
||||
[9]: https://opensource.com/article/21/3/reasons-use-cherry-picking
|
||||
[10]: https://opensource.com/article/21/3/git-your-home
|
@ -0,0 +1,174 @@
|
||||
[#]: subject: (Protect external storage with this Linux encryption system)
|
||||
[#]: via: (https://opensource.com/article/21/3/encryption-luks)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Protect external storage with this Linux encryption system
|
||||
======
|
||||
Use Linux Unified Key Setup to encrypt your thumb drives, external hard
|
||||
drives, and other storage from prying eyes.
|
||||
![A keyboard with privacy written on it.][1]
|
||||
|
||||
Many people consider hard drives secure because they physically own them. It's difficult to read the data on a hard drive that you don't have, and many people think that protecting their computer with a passphrase makes the data on the drive unreadable.
|
||||
|
||||
This isn't always the case, partly because, in some cases, a passphrase serves only to unlock a user session. In other words, you can power on a computer, but because you don't have its passphrase, you can't get to the desktop, and so you have no way to open files to look at them.
|
||||
|
||||
The problem, as many a computer technician understands, is that hard drives can be extracted from computers, and some drives are already external by design (USB thumb drives, for instance), so they can be attached to any computer for full access to the data on them. You don't have to physically separate a drive from its computer host for this trick to work, either. Computers can be [booted from a portable boot drive][2], which separates a drive from its host operating system and turns it into, virtually, an external drive available for reading.
|
||||
|
||||
The answer is to place the data on a drive into a digital vault that can't be opened without information that only you have access to.
|
||||
|
||||
Linux Unified Key Setup ([LUKS][3]) is a disk-encryption system. It provides a generic key store (and associated metadata and recovery aids) in a dedicated area on a disk with the ability to use multiple passphrases (or key files) to unlock a stored key. It's designed to be flexible and can even store metadata externally so that it can be integrated with other tools. The result is full-drive encryption, so you can store all of your data confident that it's safe—even if your drive is separated, either physically or through software, from your computer.
|
||||
|
||||
### Encrypting during installation
|
||||
|
||||
The easiest way to implement full-drive encryption is to select the option during installation. Most modern Linux distributions offer this as an option, so it's usually a trivial process.
|
||||
|
||||
![Encrypt during installation][4]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][5])
|
||||
|
||||
This establishes everything you need: an encrypted drive requiring a passphrase before your system can boot. If the drive is extracted from your computer or accessed from another operating system running on your computer, the drive must be decrypted by LUKS before it can be mounted.
|
||||
|
||||
### Encrypting external drives
|
||||
|
||||
It's not common to separate an internal hard drive from its computer, but external drives are designed to travel. As technology gets smaller and smaller, it's easier to put a portable drive on your keychain and carry it around with you every day. The obvious danger, however, is that these are also pretty easy to misplace. I've found abandoned drives in the USB ports of hotel lobby computers, business center printers, classrooms, and even a laundromat. Most of these didn't include personal information, but it's an easy mistake to make.
|
||||
|
||||
You can mitigate against misplacing important data by encrypting your external drives.
|
||||
|
||||
LUKS and its frontend `cryptsetup` provide a way to do this on Linux. As Linux does during installation, you can encrypt the entire drive so that it requires a passphrase to mount it.
|
||||
|
||||
### How to encrypt an external drive with LUKS
|
||||
|
||||
First, you need an empty external drive (or a drive with contents you're willing to erase). This process overwrites all the data on a drive, so if you have data that you want to keep on the drive, _back it up first_.
|
||||
|
||||
#### 1\. Find your drive
|
||||
|
||||
I used a small USB thumb drive. To protect you from accidentally erasing data, the drive referenced in this article is located at the imaginary location `/dev/sdX`. Attach your drive and find its location:
|
||||
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
sda 8:0 0 111.8G 0 disk
|
||||
sda1 8:1 0 111.8G 0 part /
|
||||
sdb 8:112 1 57.6G 0 disk
|
||||
sdb1 8:113 1 57.6G 0 part /mydrive
|
||||
sdX 8:128 1 1.8G 0 disk
|
||||
sdX1 8:129 1 1.8G 0 part
|
||||
```
|
||||
|
||||
I know that my demo drive is located at `/dev/sdX` because I recognize its size (1.8GB), and it's also the last drive I attached (with `sda` being the first, `sdb` the second, `sdc` the third, and so on). The `/dev/sdX1` designator means the drive has 1 partition.
|
||||
|
||||
If you're unsure, remove your drive, look at the output of `lsblk`, and then attach your drive and look at `lsblk` again.
|
||||
|
||||
Make sure you identify the correct drive because encrypting it overwrites _everything on it_. My drive is not empty, but it contains copies of documents I have copies of elsewhere, so losing this data isn't significant to me.
|
||||
|
||||
#### 2\. Clear the drive
|
||||
|
||||
To proceed, destroy the drive's partition table by overwriting the drive's head with zeros:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dd if=/dev/zero of=/dev/sdX count=4096`
|
||||
```
|
||||
|
||||
This step isn't strictly necessary, but I like to start with a clean slate.
|
||||
|
||||
#### 3\. Format your drive for LUKS
|
||||
|
||||
The `cryptsetup` command is a frontend for managing LUKS volumes. The `luksFormat` subcommand creates a sort of LUKS vault that's password-protected and can house a secured filesystem.
|
||||
|
||||
When you create a LUKS partition, you're warned about overwriting data and then prompted to create a passphrase for your drive:
|
||||
|
||||
|
||||
```
|
||||
$ sudo cryptsetup luksFormat /dev/sdX
|
||||
WARNING!
|
||||
========
|
||||
This will overwrite data on /dev/sdX irrevocably.
|
||||
|
||||
Are you sure? (Type uppercase yes): YES
|
||||
Enter passphrase:
|
||||
Verify passphrase:
|
||||
```
|
||||
|
||||
#### 4\. Open the LUKS volume
|
||||
|
||||
Now you have a fully encrypted vault on your drive. Prying eyes, including your own right now, are kept out of this LUKS partition. So to use it, you must open it with your passphrase. Open the LUKS vault with `cryptsetup open` along with the device location (`/dev/sdX`, in my example) and an arbitrary name for your opened vault:
|
||||
|
||||
|
||||
```
|
||||
`$ cryptsetup open /dev/sdX vaultdrive`
|
||||
```
|
||||
|
||||
I use `vaultdrive` in this example, but you can name your vault anything you want, and you can give it a different name every time you open it.
|
||||
|
||||
LUKS volumes are opened in a special device location called `/dev/mapper`. You can list the files there to check that your vault was added:
|
||||
|
||||
|
||||
```
|
||||
$ ls /dev/mapper
|
||||
control vaultdrive
|
||||
```
|
||||
|
||||
You can close a LUKS volume at any time using the `close` subcommand:
|
||||
|
||||
|
||||
```
|
||||
`$ cryptsetup close vaultdrive`
|
||||
```
|
||||
|
||||
This removes the volume from `/dev/mapper`.
|
||||
|
||||
#### 5\. Create a filesystem
|
||||
|
||||
Now that you have your LUKS volume decrypted and open, you must create a filesystem there to store data in it. In my example, I use XFS, but you can use ext4 or JFS or any filesystem you want:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo mkfs.xfs -f -L myvault /dev/mapper/vaultdrive`
|
||||
```
|
||||
|
||||
### Mount and unmount a LUKS volume
|
||||
|
||||
You can mount a LUKS volume from a terminal with the `mount` command. Assume you have a directory called `/mnt/hd` and want to mount your LUKS volume there:
|
||||
|
||||
|
||||
```
|
||||
$ sudo cryptsetup open /dev/sdX vaultdrive
|
||||
$ sudo mount /dev/mapper/vaultdrive /mnt/hd
|
||||
```
|
||||
|
||||
LUKS also integrates into popular Linux desktops. For instance, when I attach an encrypted drive to my workstation running KDE or my laptop running GNOME, my file manager prompts me for a passphrase before it mounts the drive.
|
||||
|
||||
![LUKS requesting passcode to mount drive][6]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][5])
|
||||
|
||||
### Encryption is protection
|
||||
|
||||
Linux makes encryption easier than ever. It's so easy, in fact, that it's nearly unnoticeable. The next time you [format an external drive for Linux][7], consider using LUKS first. It integrates seamlessly with your Linux desktop and protects your important data from accidental exposure.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/encryption-luks
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/privacy_keyboard_security.jpg?itok=vZ9jFdK_ (A keyboard with privacy written on it.)
|
||||
[2]: https://opensource.com/article/19/6/linux-distros-to-try
|
||||
[3]: https://gitlab.com/cryptsetup/cryptsetup/blob/master/README.md
|
||||
[4]: https://opensource.com/sites/default/files/uploads/centos8-install-encrypt.jpg (Encrypt during installation)
|
||||
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/luks-mount-gui.png (LUKS requesting passcode to mount drive)
|
||||
[7]: https://opensource.com/article/18/11/partition-format-drive-linux
|
@ -0,0 +1,83 @@
|
||||
[#]: subject: (4 ways open source gives you a competitive edge)
|
||||
[#]: via: (https://opensource.com/article/21/4/open-source-competitive-advantage)
|
||||
[#]: author: (Jason Blais https://opensource.com/users/jasonblais)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
4 ways open source gives you a competitive edge
|
||||
======
|
||||
Using open source technology can help organizations drive better
|
||||
business outcomes.
|
||||
![Open ethernet cords.][1]
|
||||
|
||||
Building a tech stack is a major decision for every organization. While picking the right tools will set your team up for success, picking the wrong solutions or platforms can have devastating effects on productivity and profitability. To succeed in today's fast-paced world, organizations must make smart investments in digital solutions that enable them to move faster and increase operational agility.
|
||||
|
||||
This is precisely why more and more organizations of all sizes and across all industries are embracing open source solutions. According to a recent [McKinsey][2] report, open source adoption is the biggest differentiator for top-performing organizations.
|
||||
|
||||
Here are four reasons why adopting open source technology can help organizations drive competitive advantage and experience better business outcomes.
|
||||
|
||||
### 1\. Extensibility and flexibility
|
||||
|
||||
Suffice it to say the world of technology moves quickly. For example, Kubernetes didn't exist before 2014, but today, it's impressively ubiquitous. According to the CNCF's [2020 Cloud Native Survey][3], 91% of teams are using Kubernetes in some form.
|
||||
|
||||
One of the main reasons organizations are investing in open source is because it enables them to operate with agility and rapidly integrate new technologies into their stack. That's compared to the more traditional approach, where teams would take quarters or even years to vet, implement, and adopt software—making it impossible for them to pivot with any sense of urgency.
|
||||
|
||||
Since open source solutions offer complete access to source code, teams can easily connect the software to the other tools they use every day.
|
||||
|
||||
Simply put, open source enables development teams to build the perfect tool for what is at hand instead of being forced to change how they work to fit into how inflexible proprietary tools are designed.
|
||||
|
||||
### 2\. Security and high-trust collaboration
|
||||
|
||||
In the age of high-profile data breaches, organizations need highly secure tools that enable them to keep sensitive data secure.
|
||||
|
||||
When vulnerabilities exist in proprietary solutions, they're often undiscovered until it's too late. Unfortunately for the teams using these platforms, the lack of visibility into source code means they're essentially outsourcing security to the specific vendor and hoping for the best.
|
||||
|
||||
Another main driver of open source adoption is that open source tools enable organizations to take control over their own security. For example, open source projects—particularly those with large communities—tend to receive more responsible vulnerability disclosures because everyone using the product can thoroughly inspect the source code.
|
||||
|
||||
Since the source code is freely available, such disclosures often come with detailed proposed solutions for fixing bugs. This enables dev teams to remedy issues faster, continuously strengthening the software.
|
||||
|
||||
In the age of remote work, it's more important than ever for distributed teams to collaborate while knowing that sensitive data stays protected. Since open source solutions allow organizations to audit security while maintaining complete control over their data, they can facilitate the high-trust collaboration needed to thrive in remote environments.
|
||||
|
||||
### 3\. Freedom from vendor lock-in
|
||||
|
||||
According to a [recent study][4], 68% of CIOs are concerned about vendor lock-in. They should be. When you're locked into a piece of technology, you're forced to live with someone else's conclusions instead of making your own.
|
||||
|
||||
Proprietary solutions often make it [challenging to take data with you][5] when an organization switches vendors. On the other hand, open source tools offer the freedom and flexibility needed to avoid vendor lock-in and take data wherever an organization wants to go.
|
||||
|
||||
### 4\. Top talent and community
|
||||
|
||||
As more and more companies [embrace remote work][6], the war for talent is becoming even more competitive.
|
||||
|
||||
In the world of software development, landing top talent starts with giving engineers access to modern tools that enable them to reach their full potential at work. Since developers increasingly [prefer open source solutions][7] to proprietary counterparts, organizations should strongly consider open source alternatives to their commercial solutions to attract the best developers on the market.
|
||||
|
||||
In addition to making it easier to hire and retain top talent, open source platforms also enable companies to tap into a community of contributors for advice on how to walk through problems and get the most out of the platform. Plus, members of the community also [contribute to open source projects directly][8].
|
||||
|
||||
### Open source offers freedom
|
||||
|
||||
Open source software is increasingly popular among enterprise teams—[for good reason][9]. It gives teams the flexibility needed to build the perfect tool for the job while enabling them to maintain a highly secure environment. At the same time, an open source approach allows teams to maintain control of their future, rather than being locked into one vendor's roadmap. And it also gives companies access to talented engineers and members of the open source community.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/open-source-competitive-advantage
|
||||
|
||||
作者:[Jason Blais][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/jasonblais
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openwires_fromRHT_520_0612LL.png?itok=PqZi55Ab (Open ethernet cords.)
|
||||
[2]: https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/developer-velocity-how-software-excellence-fuels-business-performance#
|
||||
[3]: https://www.cncf.io/blog/2020/11/17/cloud-native-survey-2020-containers-in-production-jump-300-from-our-first-survey/
|
||||
[4]: https://solutionsreview.com/cloud-platforms/flexera-68-percent-of-cios-worry-about-vendor-lock-in-with-public-cloud/
|
||||
[5]: https://www.computerworld.com/article/3428679/mattermost-makes-case-for-open-source-as-team-messaging-market-booms.html
|
||||
[6]: https://mattermost.com/blog/tips-for-working-remotely/
|
||||
[7]: https://opensource.com/article/20/6/open-source-developers-survey
|
||||
[8]: https://mattermost.com/blog/100-most-popular-mattermost-features-invented-and-contributed-by-our-amazing-open-source-community/
|
||||
[9]: https://mattermost.com/open-source-advantage/
|
@ -0,0 +1,274 @@
|
||||
[#]: subject: (Stream event data with this open source tool)
|
||||
[#]: via: (https://opensource.com/article/21/4/event-streaming-rudderstack)
|
||||
[#]: author: (Amey Varangaonkar https://opensource.com/users/ameypv)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Stream event data with this open source tool
|
||||
======
|
||||
Route real-time events from web, mobile, and server-side app sources to
|
||||
help build your customer data lake on your data warehouse.
|
||||
![Net catching 1s and 0s or data in the clouds][1]
|
||||
|
||||
In my [previous article][2], I introduced [RudderStack][3], an open source, warehouse-first customer data pipeline. In this article, I demonstrate how easy Rudderstack makes it to set up and use event streams.
|
||||
|
||||
An event stream is a pipeline between a source you define and a destination of your choice. Rudderstack provides you with SDKs and plugins to help you ingest event data from your website, mobile apps, and server-side sources — including JavaScript, Gatsby, Android, iOS, Unity, ReactNative, Node.js, and many more. Similarly, Rudderstack's **Event Stream** module features over 80 destination and warehouse integrations, including Firebase, Google Analytics, Salesforce, Zendesk, Snowflake, BigQuery, RedShift, and more, making it easy to send event data to downstream tools that can use it as well as build a customer data lake on a data warehouse for analytical use cases.
|
||||
|
||||
This tutorial shows how to track and route events using RudderStack.
|
||||
|
||||
### How to set up an event stream
|
||||
|
||||
Before you get started, make sure you understand these terms used in this tutorial:
|
||||
|
||||
* **Source**: A source refers to a tool or a platform from which RudderStack ingests your event data. Your website, mobile app, or your back-end server are common examples of sources.
|
||||
* **Destination**: A destination refers to a tool that receives your event data from RudderStack. These destination tools can then use this data for your activation use cases. Tools like Google Analytics, Salesforce, and HubSpot are common examples of destinations.
|
||||
|
||||
|
||||
|
||||
The steps for setting up an event stream in RudderStack open source are:
|
||||
|
||||
1. Instrumenting an event stream source
|
||||
2. Configuring a warehouse destination
|
||||
3. Configuring a tool destination
|
||||
4. Sending events to verify the event stream
|
||||
|
||||
|
||||
|
||||
### Step 1: Instrument an event stream source
|
||||
|
||||
To set up an event stream source in RudderStack:
|
||||
|
||||
1. Log into your [RudderStack dashboard][4]. If you don't have a RudderStack account, please sign up. You can use the RudderStack open source control plane to [set up your event streams][5].
|
||||
|
||||
RudderStack's hosted control plane is an option to manage your event stream configurations. It is completely free, requires no setup, and has some more advanced features than the open source control plane.
|
||||
|
||||
2. Once you've logged into RudderStack, you should see the following dashboard:
|
||||
|
||||
![RudderStack dashboard][6]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
**Note:** Make sure to save the **Data Plane URL**. It is required in your RudderStack JavaScript SDK snippet to track events from your website.
|
||||
|
||||
3. To instrument the source, click **Add Source**. Optionally, you can also select the **Directory** option on the left navigation bar, and select **Event Streams** under **Sources**. This tutorial will set up a simple **JavaScript** source that allows you to track events from your website.
|
||||
|
||||
![RudderStack event streams dashboard][8]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
4. Assign a name to your source, and click **Next**.
|
||||
|
||||
![RudderStack Source Name][9]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
5. That's it! Your event source is now configured.
|
||||
|
||||
![RudderStack source write key][10]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
**Note:** Save the source **Write Key**. Your RudderStack JavaScript SDK snippet requires it to track events from your website.
|
||||
|
||||
|
||||
|
||||
|
||||
Now you need to install the RudderStack JavaScript SDK on your website. To do this, you need to place either the minified or non-minified version of the snippet with your **Data Plane URL** and source **Write Key** in your website's `<head>` section. Consult the docs for information on how to [install and use the RudderStack JavaScript SDK][11].
|
||||
|
||||
### Step 2: Configure a warehouse destination
|
||||
|
||||
**Important**: Before you configure your data warehouse as a destination in RudderStack, you need to set up a new project in your warehouse and create a RudderStack user role with the relevant permissions. The docs provide [detailed, step-by-step instructions][12] on how to do this for the warehouse of your choice.
|
||||
|
||||
This tutorial sets up a Google BigQuery warehouse destination. You don't have to configure a warehouse destination, but I recommend it. The docs provide [instructions on setting up][13] a Google BigQuery project and a service account with the required permissions.
|
||||
|
||||
Then configure BigQuery as a warehouse destination in RudderStack by following these steps:
|
||||
|
||||
1. On the left navigation bar, click on **Directory**, and then click on **Google BigQuery** from the list of destinations:
|
||||
|
||||
![RudderStack destination options][14]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
2. Assign a name to your destination, and click on **Next**.
|
||||
|
||||
|
||||
|
||||
|
||||
![RudderStack naming the destination][15]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
3. Choose which source you want to use to send the events to your destination. Select the source that you created in the previous section. Then, click on **Next**.
|
||||
|
||||
|
||||
|
||||
![RudderStack selecting data source][16]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
4. Specify the required connection credentials. For this destination, enter the **BigQuery Project ID** and the **staging bucket name**; information on [how to get this information][17] is in the docs.
|
||||
|
||||
|
||||
|
||||
![RudderStack connection credentials][18]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
5. Copy the contents of the private JSON file you created, as [the docs][19] explain.
|
||||
|
||||
|
||||
|
||||
That's it! You have configured your BigQuery warehouse as a destination in RudderStack. Once you start sending events from your source (a website in this case), RudderStack will automatically route them into your BigQuery and build your identity graph there as well.
|
||||
|
||||
### Step 3: Configure a tool destination
|
||||
|
||||
Once you've added a source, follow these steps to configure a destination in the RudderStack dashboard:
|
||||
|
||||
1. To add a new destination, click on the **Add Destination** button as shown:
|
||||
|
||||
![RudderStack adding the destination][20]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
**Note:** If you have configured a destination before, use the **Connect Destinations** option to connect it to any source.
|
||||
|
||||
2. RudderStack supports over 80 destinations to which you can send your event data. Choose your preferred destination platform from the list. This example configures **Google Analytics** as a destination.
|
||||
|
||||
|
||||
|
||||
|
||||
![RudderStack selecting destination platform][21]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
3. Add a name to your destination, and click **Next**.
|
||||
|
||||
|
||||
|
||||
![RudderStack naming the destination][22]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
4. Next, choose the preferred source. If you're following along with this tutorial, choose the source you configured above.
|
||||
|
||||
|
||||
|
||||
![RudderStack choosing source][23]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
5. In this step, you must add the relevant **Connection Settings**. Enter the **Tracking ID** for this destination (Google Analytics). You can also configure other optional settings per your requirements. Once you've added the required settings, click **Next**.
|
||||
|
||||
![RudderStack connection settings][24]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
**Note**: RudderStack also gives you the option of transforming the events before sending them to your destination. Read more about [user transformations][25] in RudderStack in the docs.
|
||||
|
||||
6. That's it! The destination is now configured. You should now see it connected to your source.
|
||||
|
||||
|
||||
|
||||
|
||||
![RudderStack connection configured][26]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
### Step 4: Send test events to verify the event stream
|
||||
|
||||
This tutorial set up a JavaScript source to track events from your website. Once you have placed the JavaScript code snippet in your website's `<head>` section, RudderStack will automatically track and collect user events from the website in real time.
|
||||
|
||||
However, to quickly test if your event stream is set up correctly, you can send some test events. To do so, follow these steps:
|
||||
|
||||
**Note**: Before you get started, you will need to clone the [rudder-server][27] repo and have a RudderStack server installed in your environment. Follow [this tutorial][28] to set up a RudderStack server.
|
||||
|
||||
1. Make sure you have set up a source and destination by following the steps in the previous sections and have your **Data Plane URL** and source **Write Key** available.
|
||||
|
||||
2. Start the RudderStack server.
|
||||
|
||||
3. The **rudder-server** repo includes a shell script that generates test events. Get the source **Write Key** from step 2, and run the following command:
|
||||
|
||||
|
||||
```
|
||||
`./scripts/generate-event <YOUR_WRITE_KEY> <YOUR_DATA_PLANE_URL>/v1/batch`
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
![RudderStack event testing code][29]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
4. To check if the test events are delivered, go to your Google Analytics dashboard, navigate to **Realtime** under Reports, and click **Events**.
|
||||
|
||||
**Note**: Make sure you check the events associated with the same Tracking ID you provided while instrumenting the destination.
|
||||
|
||||
|
||||
|
||||
|
||||
You should now be able to see the test event received in Google Analytics and BigQuery.
|
||||
|
||||
![RudderStack event test][30]
|
||||
|
||||
(Gavin Johnson, [CC BY-SA 4.0][7])
|
||||
|
||||
If you come across any issues while setting up or configuring RudderStack open source, join our [Slack][31] and start a conversation in our #open-source channel. We will be happy to help.
|
||||
|
||||
If you want to try RudderStack but don't want to host your own, sign up for our free, hosted offering, [RudderStack Cloud Free][32]. Explore our open source repos on [GitHub][33], subscribe to [our blog][34], and follow us on our socials: [Twitter][35], [LinkedIn][36], [dev.to][37], [Medium][38], and [YouTube][39].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/event-streaming-rudderstack
|
||||
|
||||
作者:[Amey Varangaonkar][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/ameypv
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_analytics_cloud.png?itok=eE4uIoaB (Net catching 1s and 0s or data in the clouds)
|
||||
[2]: https://opensource.com/article/21/3/rudderstack-customer-data-platform
|
||||
[3]: https://rudderstack.com/
|
||||
[4]: https://app.rudderstack.com/
|
||||
[5]: https://docs.rudderstack.com/how-to-guides/rudderstack-config-generator
|
||||
[6]: https://opensource.com/sites/default/files/uploads/rudderstack_dashboard.png (RudderStack dashboard)
|
||||
[7]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[8]: https://opensource.com/sites/default/files/uploads/rudderstack_eventstreamsdash.png (RudderStack event streams dashboard)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/rudderstack_namesource.png (RudderStack Source Name)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/rudderstack_writekey.png (RudderStack Source Name)
|
||||
[11]: https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk
|
||||
[12]: https://docs.rudderstack.com/data-warehouse-integrations
|
||||
[13]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery
|
||||
[14]: https://opensource.com/sites/default/files/uploads/rudderstack_destinations.png (RudderStack destination options)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/rudderstack_namedestination.png (RudderStack naming the destination)
|
||||
[16]: https://opensource.com/sites/default/files/uploads/rudderstack_adddestination.png (RudderStack selecting data source)
|
||||
[17]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery#setting-up-google-bigquery
|
||||
[18]: https://opensource.com/sites/default/files/uploads/rudderstack_connectioncredentials.png (RudderStack connection credentials)
|
||||
[19]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery#setting-up-the-service-account-for-rudderstack
|
||||
[20]: https://opensource.com/sites/default/files/uploads/rudderstack_addnewdestination.png (RudderStack adding the destination)
|
||||
[21]: https://opensource.com/sites/default/files/uploads/rudderstack_googleanalyticsdestination.png (RudderStack selecting destination platform)
|
||||
[22]: https://opensource.com/sites/default/files/uploads/rudderstack_namenewdestination.png (RudderStack naming the destination)
|
||||
[23]: https://opensource.com/sites/default/files/uploads/rudderstack_choosepreferredsource.png (RudderStack choosing source)
|
||||
[24]: https://opensource.com/sites/default/files/uploads/rudderstack_connectionsettings.png (RudderStack connection settings)
|
||||
[25]: https://docs.rudderstack.com/adding-a-new-user-transformation-in-rudderstack
|
||||
[26]: https://opensource.com/sites/default/files/uploads/rudderstack_destinationconfigured.png (RudderStack connection configured)
|
||||
[27]: https://github.com/rudderlabs/rudder-server
|
||||
[28]: https://docs.rudderstack.com/installing-and-setting-up-rudderstack/docker
|
||||
[29]: https://opensource.com/sites/default/files/uploads/rudderstack_testevents.jpg (RudderStack event testing code)
|
||||
[30]: https://opensource.com/sites/default/files/uploads/rudderstack_testeventoutput.png (RudderStack event test)
|
||||
[31]: https://resources.rudderstack.com/join-rudderstack-slack
|
||||
[32]: https://app.rudderlabs.com/signup?type=freetrial
|
||||
[33]: https://github.com/rudderlabs
|
||||
[34]: https://rudderstack.com/blog/
|
||||
[35]: https://twitter.com/RudderStack
|
||||
[36]: https://www.linkedin.com/company/rudderlabs/
|
||||
[37]: https://dev.to/rudderstack
|
||||
[38]: https://rudderstack.medium.com/
|
||||
[39]: https://www.youtube.com/channel/UCgV-B77bV_-LOmKYHw8jvBw
|
77
sources/tech/20210410 5 signs you-re a groff programmer.md
Normal file
77
sources/tech/20210410 5 signs you-re a groff programmer.md
Normal file
@ -0,0 +1,77 @@
|
||||
[#]: subject: (5 signs you're a groff programmer)
|
||||
[#]: via: (https://opensource.com/article/21/4/groff-programmer)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
5 signs you're a groff programmer
|
||||
======
|
||||
Learning groff, an old-school text processor, is like learning to ride a
|
||||
bicycle.
|
||||
![Typewriter in the grass][1]
|
||||
|
||||
I first discovered Unix systems in the early 1990s, when I was an undergraduate at university. I liked it so much that I replaced the MS-DOS system on my home computer with the Linux operating system.
|
||||
|
||||
One thing that Linux didn't have in the early to mid-1990s was a word processor. A standard office application on other desktop operating systems, a word processor lets you edit text easily. I often used a word processor on DOS to write my papers for class. I wouldn't find a Linux-native word processor until the late 1990s. Until then, word processing was one of the rare reasons I maintained dual-boot on my first computer, so I could occasionally boot back into DOS to write papers.
|
||||
|
||||
Then I discovered that Linux provided kind of a word processor. GNU troff, better known as [groff][2], is a modern implementation of a classic text processing system called troff, short for "typesetter roff," which is an improved version of the nroff system. And nroff was meant to be a new implementation of the original roff (which stood for "run off," as in to "run off" a document).
|
||||
|
||||
With text processing, you edit text in a plain text editor, and you add formatting through macros or other processing commands. You then process that text file through a text-processing system such as groff to generate formatted output suitable for a printer. Another well-known text processing system is LaTeX, but groff was simple enough for my needs.
|
||||
|
||||
With a little practice, I found I could write my class papers just as easily in groff as I could using a word processor on Linux. While I don't use groff to write documents today, I still remember the macros and commands to generate printed documents with it. And if you're the same and you learned how to write with groff all those years ago, you probably recognize these five signs that you're a groff writer.
|
||||
|
||||
### 1\. You have a favorite macro set
|
||||
|
||||
You format a document in groff by writing plain text interspersed with macros. A macro in groff is a short command that starts with a single period at the beginning of a line. For example: if you want to insert a few lines into your output, the `.sp 2` macro command adds two blank lines. groff supports other basic macros for all kinds of formatting.
|
||||
|
||||
To make formatting a document easier for the writer, groff also provides different _macro sets_, collections of macros that let you format documents your own way. The first macro set I learned was the `-me` macro set. Really, the macro set is called the `e` macro set, and you specify the `e` macro set when you process a file using the `-me` option.
|
||||
|
||||
groff includes other macro sets, too. For example, the `-man` macro set used to be the standard macro set to format the built-in _manual_ pages on Unix systems, and the `-ms` macro set is often used to format certain other technical documents. If you learned to write with groff, you probably have a favorite macro set.
|
||||
|
||||
### 2\. You want to focus on your content, not the formatting
|
||||
|
||||
One great feature of writing with groff is that you can focus on your _content_ and not worry too much about what it looks like. That is a handy feature for technical writers. groff is a great "distraction-free" environment for professional writers. At least, as long as you don't mind delivering your output in any of the formats that groff supports with the `-T` command-line option, including PDF, PostScript, HTML, and plain text. You can't generate a LibreOffice ODT file or Word DOC file directly from groff.
|
||||
|
||||
Once you get comfortable writing in groff, the macros start to _disappear_. The formatting macros become part of the background, and you focus purely on the text in front of you. I've done enough writing in groff that I don't even see the macros anymore. Maybe it's like writing programming code, and your mind just switches gears, so you think like a computer and see the code as a set of instructions. For me, writing in groff is like that; I just see my text, and my mind interprets the macros automatically into formatting.
|
||||
|
||||
### 3\. You like the old-school feel
|
||||
|
||||
Sure, it might be _easier_ to write your documents with a more typical word processor like LibreOffice Writer or even Google Docs or Microsoft Word. And for certain kinds of documents, a desktop word processor is the right fit. But if you want the "old-school" feel, it's hard to beat writing in groff.
|
||||
|
||||
I'll admit that I do most of my writing with LibreOffice Writer, which does an outstanding job. But when I get that itch to do it "old-school," I'll open an editor and write my document using groff.
|
||||
|
||||
### 4\. You like that you can use it anywhere
|
||||
|
||||
groff (and its cousins) are a standard package on almost any Unix system. And with groff, the macros don't change. For example, the `-me` macros should be the same from system to system. So once you've learned to use the macros on one system, you can use them on the next system.
|
||||
|
||||
And because groff documents are just plain text, you can use any editor you like to edit your documents for groff. I like to use GNU Emacs to edit my groff documents, but you can use GNOME Gedit, Vim, or your [favorite text editor][3]. Most editors include some kind of "mode" that will highlight the groff macros in a different color from the rest of your text to help you spot errors before processing the file.
|
||||
|
||||
### 5\. You wrote this article in -me
|
||||
|
||||
When I decided to write this article, I thought the best way would be to use groff directly. I wanted to demonstrate how flexible groff was in preparing documents. So even though you're reading this on a website, the article was originally written using groff.
|
||||
|
||||
I hope this has interested you in learning how to use groff to write documents. If you'd like to use more advanced functions in the `-me` macro set, refer to Eric Allman's _Writing papers with groff using -me_, which you should find on your system as **meintro.me** in groff's documentation. It's a great reference document that explains other ways to format papers using the `-me` macros.
|
||||
|
||||
I've also included a copy of the original draft of my article that uses the `-me` macros. Save the file to your system as **five-signs-groff.me**, and run it through groff to view it. The `-T` option sets the output type, such as `-Tps` to generate PostScript output or `-Thtml` to create an HTML file. For example:
|
||||
|
||||
groff -me -Thtml five-signs-groff.me > five-signs-groff.html
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/groff-programmer
|
||||
|
||||
作者:[Jim Hall][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/jim-hall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/doc-dish-lead.png?itok=h3fCkVmU (Typewriter in the grass)
|
||||
[2]: https://en.wikipedia.org/wiki/Groff_(software)
|
||||
[3]: https://opensource.com/article/21/2/open-source-text-editors
|
@ -0,0 +1,117 @@
|
||||
[#]: subject: (How to Install Steam on Fedora [Beginner’s Tip])
|
||||
[#]: via: (https://itsfoss.com/install-steam-fedora/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
How to Install Steam on Fedora [Beginner’s Tip]
|
||||
======
|
||||
|
||||
Steam is the best thing that could happen to Linux gamers. Thanks to Steam, you can play hundreds and thousands of games on Linux.
|
||||
|
||||
If you are not already aware of it, Steam is the most popular PC gaming platform. In 2013, it became available for Linux. [Steam’s latest Proton project][1] allows you to play games created for Windows platform on Linux. This enhanced Linux gaming library many folds.
|
||||
|
||||
![][2]
|
||||
|
||||
Steam provides a desktop client and you can use it to download or purchase games from the Steam store, install the game and play it.
|
||||
|
||||
We have discussed [installing Steam on Ubuntu][3] in the past. In this beginner’s tutorial, I am going to show you the steps for installing Steam on Fedora Linux.
|
||||
|
||||
### Installing Steam on Fedora
|
||||
|
||||
To get Steam on Fedora, you’ll have to use RMPFusion repository. [RPMFusion][4] is a series of third-party repos that contain software that Fedora chooses not to ship with their operating system. They offer both free (open source) and non-free (closed source) repos. Since Steam is in the non-free repo, you will only install that one.
|
||||
|
||||
I shall go over both the terminal and graphical installation methods.
|
||||
|
||||
#### Method 1: Install Steam via terminal
|
||||
|
||||
This is the easiest method because it requires the fewest steps. Just enter the following command to enable the free repo:
|
||||
|
||||
```
|
||||
sudo dnf install https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
```
|
||||
|
||||
You will be asked to enter your password. You will then be asked to verify that you want to install these repos. Once you approve it, the installation of the repo will be completed.
|
||||
|
||||
To install Steam, simply enter the following command:
|
||||
|
||||
```
|
||||
sudo dnf install steam
|
||||
```
|
||||
|
||||
![Install Steam via command line][5]
|
||||
|
||||
Enter your password and press “Y” to accept. Once installed, open Steam and play some games.
|
||||
|
||||
#### Method 2: Install Steam via GUI
|
||||
|
||||
You can [enable the third-party repository on Fedora][6] from the Software Center. Open the Software Center application and click on the hamburger menu:
|
||||
|
||||
![][7]
|
||||
|
||||
In the Software Repositories window, you will see a section at the top that says “Third Party Repositories”. Click the Install button. Enter your password when you are prompted and you are done.
|
||||
|
||||
![][8]
|
||||
|
||||
Once you have installed RPM Fusion repository for Steam, update your system’s software cache (if needed) and search for Steam in the software center.
|
||||
|
||||
![Steam in GNOME Software Center][9]
|
||||
|
||||
Once that installation is complete, open up the GNOME Software Center and search for Steam. Once you locate the Steam page, click install. Enter your password when asked and you’re done.
|
||||
|
||||
After installing Steam, start the application, enter your Steam account details or register for it and enjoy your games.
|
||||
|
||||
### Using Steam as Flatpak
|
||||
|
||||
Steam is also available as a Flatpak. Flatpak is installed by default on Fedora. Before we can install Steam using that method, we have to install the Flathub repo.
|
||||
|
||||
![Install Flathub][10]
|
||||
|
||||
First, open the [Flatpak site][11] in your browser. Now, click the blue button marked “Flathub repository file”. The browser will ask you if you want to open the file in GNOME Software Center. Click okay. Once GNOME Software Center open, click the install button. You will be prompted to enter your password.
|
||||
|
||||
If you get an error when you try to install the Flathub repo, run this command in the terminal:
|
||||
|
||||
```
|
||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
```
|
||||
|
||||
With the Flathub repo installed, all you need to do is search for Steam in the GNOME Software Center. Once you find it, install it, and you are ready to go.
|
||||
|
||||
![Fedora Repo Select][12]
|
||||
|
||||
The Flathub version of Steam has several add-ons you can install, as well. These include a DOS compatibility tool and a couple of tools for [Vulkan][13] and Proton.
|
||||
|
||||
![][14]
|
||||
|
||||
I think this should help you with Steam on Fedora. Enjoy your games :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-steam-fedora/
|
||||
|
||||
作者:[John Paul][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://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/steam-play-proton/
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2017/05/Steam-Store.jpg?resize=800%2C382&ssl=1
|
||||
[3]: https://itsfoss.com/install-steam-ubuntu-linux/
|
||||
[4]: https://rpmfusion.org/
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/install-steam-fedora.png?resize=800%2C588&ssl=1
|
||||
[6]: https://itsfoss.com/fedora-third-party-repos/
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/software-meni.png?resize=800%2C672&ssl=1
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/fedora-third-party-repo-gui.png?resize=746%2C800&ssl=1
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/gnome-store-steam.jpg?resize=800%2C434&ssl=1
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/flatpak-install-button.jpg?resize=800%2C434&ssl=1
|
||||
[11]: https://www.flatpak.org/setup/Fedora/
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/fedora-repo-select.jpg?resize=800%2C434&ssl=1
|
||||
[13]: https://developer.nvidia.com/vulkan
|
||||
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/steam-flatpak-addons.jpg?resize=800%2C434&ssl=1
|
@ -0,0 +1,49 @@
|
||||
[#]: subject: (Why Crate.io has returned to its pure open source roots)
|
||||
[#]: via: (https://opensource.com/article/21/4/crate-open-source)
|
||||
[#]: author: (Bernd Dorn https://opensource.com/users/bernd-dorn)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
Why Crate.io has returned to its pure open source roots
|
||||
======
|
||||
CrateDB's renewed commitment to open source aligns with both our best
|
||||
ideals and what's best for our business.
|
||||
![Open source stars.][1]
|
||||
|
||||
The headline benefits of open source are widely known and well-articulated. Open source technologies provide enterprise-level scalability, performance, security, and reliability. Trust is there, and it's deserved. But what's less celebrated, other than by die-hard open source adherents, are the inner workings of the everyday community contributions building those macro benefits at the atomic level. For those offering open source technologies, it is the community's constant user-driven testing and hardening that forges those technologies into robust and proven solutions. Those contributions don't show up on the balance sheet, but they can be absolutely formative to an enterprise's health and success.
|
||||
|
||||
In 2013, I co-founded [Crate.io][2] with open source ideals and my belief in the power of the community. As a startup intent on bringing the simplicity and strength of open source to the realm of advanced SQL databases that could handle the growing volume of Internet of Things (IoT) and Industrial IoT data, we rooted our CrateDB database in 100% open source component technologies. And we were sure to play our role as active contributors to those technologies and nurtured our own community of CrateDB developers.
|
||||
|
||||
In 2017, Crate began exploring an open core business model, and soon after, I took a few years away from the company. In 2019, Crate began to offer a CrateDB Free Edition with a strict three-node limit and stopped building and distributing packages for CrateDB Community Edition (the open source code could still be downloaded). This move focused the company more heavily on a paid open core enterprise edition that added some proprietary features. From a sales perspective, the idea was to spur community users to convert to paying customers. However, this strategy ended up being a fundamental misunderstanding of the user base. The result was a marked decline in user engagement and the strength of our valuable community while failing to convert much of anyone.
|
||||
|
||||
When I returned to Crate towards the end of 2020 as CTO, I made it my priority to bring back a commitment to pure open source. This sparked a rich conversation between competing viewpoints within our organization. The key to winning over my more revenue-minded colleagues was to explain that community users are completely different in nature from our enterprise customers and offer our business a different kind of support. Furthermore, forcing them away does nothing positive. Our open source community user base contributes crucial influence and experience that improves our technologies very effectively. Their support is invaluable and irreplaceable. Without them, CrateDB isn't nearly as compelling or as enterprise-ready a product.
|
||||
|
||||
Ultimately, it was our investors that weighed in and championed Crate's once and future commitment to pure open source. Our investors even helped us abandon considerations towards other licensing models such as the Business Source License by favoring the [Apache License 2.0][3] we now utilize, pressing for the fully open source permissions it offers.
|
||||
|
||||
Our recent [4.5 release][4] of CrateDB completes this full circle to our open source roots. I couldn't be prouder to say that our business is rededicated to building our community and openly welcomes all contributors as we work hand-in-hand to push CrateDB toward its full potential as a distributed SQL database for machine data.
|
||||
|
||||
I also need to mention the recent decision by [Elastic to discontinue its longstanding commitment to open source][5], as it offers a stark juxtaposition to ours. CrateDB has used open source Elasticsearch from the very beginning. But more than that, open source Elasticsearch was a formative inspiration to Crate's founders, especially me. Our drive to serve as contributing citizens in that community was born out of our work operating some of Europe's largest Elasticsearch deployments. That team and I later created Crate with Elasticsearch as our clearest example of why upholding open source ideals results in powerful technologies.
|
||||
|
||||
Our renewed commitment to open source elegantly aligns with both our best ideals and what's best for our business. The activity of a robust and inclusive open source community is the vital pulse of our product. It's our hope to provide an example of what dedication to pure open source can truly accomplish.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/crate-open-source
|
||||
|
||||
作者:[Bernd Dorn][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/bernd-dorn
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_opensourcestars.png?itok=hnrMETFh (Open source stars.)
|
||||
[2]: https://crate.io/
|
||||
[3]: https://www.apache.org/licenses/LICENSE-2.0
|
||||
[4]: https://crate.io/products/cratedb/
|
||||
[5]: https://www.elastic.co/blog/licensing-change
|
@ -0,0 +1,223 @@
|
||||
[#]: subject: (A practical guide to using the git stash command)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-stash)
|
||||
[#]: author: (Ramakrishna Pattnaik https://opensource.com/users/rkpattnaik780)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
git stash 命令实用指南
|
||||
======
|
||||
|
||||
> 学习如何使用 `git stash` 命令,以及何时应该使用它。
|
||||
|
||||
![女人在笔记本上坐在窗口][1]
|
||||
|
||||
版本控制是软件开发人员日常生活中不可分割的一部分。很难想象有哪个团队在开发软件时不使用版本控制工具。同样也很难想象有哪个开发者没有使用过(或没有听说过)Git。在 2018 年 Stackoverflow 开发者调查中,74298 名参与者中 87.2% 的人 [使用 Git][2] 进行版本控制。
|
||||
|
||||
Linus Torvalds 在 2005 年创建了 Git 用于开发 Linux 内核。本文将介绍 `git stash` 命令,并探讨一些有用的暂存修改的选项。本文假定你对 [Git 概念][3] 有基本的了解,并对工作树、暂存区和相关命令有良好的理解。
|
||||
|
||||
### 为什么 git stash 很重要?
|
||||
|
||||
首先要明白为什么在 Git 中暂存变更很重要。假设 Git 没有暂存变更的命令。当你正在一个有两个分支(A 和 B)的仓库上工作时,这两个分支已经分叉了一段时间,并且有不同的头。当你正在处理 A 分支的一些文件时,你的团队要求你修复 B 分支的一个错误。你迅速将你的修改保存到 A 分支,并尝试用 `git checkout B` 来签出 B 分支。Git 立即中止了这个操作,并抛出错误:“你对以下文件的本地修改会被该签出覆盖……请在切换分支之前提交你的修改或将它们暂存起来。”
|
||||
|
||||
在这种情况下,有几种方法可以启用分支切换:
|
||||
|
||||
* 在分支 A 中创建一个提交,提交并推送你的修改,以修复 B 中的错误,然后再次签出 A,并运行 `git reset HEAD^` 来恢复你的修改。
|
||||
* 手动保留不被 Git 跟踪的文件中的改动。
|
||||
|
||||
第二种方法是个馊主意。第一种方法虽然看起来很传统,但却不太灵活,因为保存未完成工作的修改会被当作一个检查点,而不是一个仍在进行中的补丁。这正是设计 `git stash` 的场景。
|
||||
|
||||
`git stash` 将未提交的改动保存在本地,让你可以进行修改、切换分支以及其他 Git 操作。然后,当你需要的时候,你可以重新应用这些存储的改动。暂存是本地范围的,不会被 `git push` 推送到远程。
|
||||
|
||||
### 如何使用git stash
|
||||
|
||||
下面是使用 `git stash` 时要遵循的顺序:
|
||||
|
||||
1. 将修改保存到分支 A。
|
||||
2. 运行 `git stash`。
|
||||
3. 签出分支 B。
|
||||
4. 修正 B 分支的错误。
|
||||
5. 提交并(可选)推送到远程。
|
||||
6. 查看分支 A
|
||||
7. 运行 `git stash pop` 来取回你的暂存的改动。
|
||||
|
||||
`git stash` 将你对工作目录的修改存储在本地(在你的项目的 `.git` 目录内,准确的说是 `/.git/refs/stash`),并允许你在需要时检索这些修改。当你需要在不同的上下文之间切换时,它很方便。它允许你保存以后可能需要的更改,是让你的工作目录干净同时保持更改完整的最快方法。
|
||||
|
||||
### 如何创建一个暂存
|
||||
|
||||
暂存你的变化的最简单的命令是 `git stash`:
|
||||
|
||||
```
|
||||
$ git stash
|
||||
Saved working directory and index state WIP on master; d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
默认情况下,`git stash` 存储(或“暂存”)未提交的更改(已暂存和未暂存的文件),并忽略未跟踪和忽略的文件。通常情况下,你不需要暂存未跟踪和忽略的文件,但有时它们可能会干扰你在代码库中要做的其他事情。
|
||||
|
||||
你可以使用附加选项让 `git stash` 来处理未跟踪和忽略的文件:
|
||||
|
||||
* `git stash -u` 或 `git stash --includ-untracked` 储存未追踪的文件。
|
||||
* `git stash -a` 或 `git stash --all` 储存未跟踪的文件和忽略的文件。
|
||||
|
||||
要存储特定的文件,你可以使用 `git stash -p` 或 `git stash -patch` 命令:
|
||||
|
||||
```
|
||||
$ git stash --patch
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 32174593..8d81be6e 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -3,6 +3,7 @@
|
||||
# dependencies
|
||||
node_modules/
|
||||
/.pnp
|
||||
+f,fmfm
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
(1/1) Stash this hunk [y,n,q,a,d,e,?]?
|
||||
```
|
||||
|
||||
### 列出你的暂存
|
||||
|
||||
你可以用 `git stash list` 命令查看你的暂存。暂存是后进先出(LIFO)方式保存的:
|
||||
|
||||
```
|
||||
$ git stash list
|
||||
stash@{0}: WIP on master: d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
默认情况下,暂存会显示在你创建它的分支和提交的顶部,被标记为 `WIP`。然而,当你有多个暂存时,这种有限的信息量并没有帮助,因为很难记住或单独检查它们的内容。要为暂存添加描述,可以使用命令 `git stash save <description>`:
|
||||
|
||||
```
|
||||
$ git stash save "remove semi-colon from schema"
|
||||
Saved working directory and index state On master: remove semi-colon from schema
|
||||
|
||||
$ git stash list
|
||||
stash@{0}: On master: remove semi-colon from schema
|
||||
stash@{1}: WIP on master: d7435644 Feat: configure graphql endpoint
|
||||
```
|
||||
|
||||
### 检索暂存起来的变化
|
||||
|
||||
你可以用 `git stash apply` 和 `git stash pop` 这两个命令来重新应用暂存的变更。这两个命令都会重新应用最新的暂存(即 `stash@{0}`)中的改动。`apply` 会重新应用变更;而 `pop` 则会将暂存的变更重新应用到工作副本中,并从暂存中删除。如果你不需要再次重新应用被暂存的更改,则首选 `pop`。
|
||||
|
||||
你可以通过传递标识符作为最后一个参数来选择你想要弹出或应用的储藏:
|
||||
|
||||
```
|
||||
$ git stash pop stash@{1}
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```
|
||||
$ git stash apply stash@{1}
|
||||
```
|
||||
|
||||
### 清理暂存
|
||||
|
||||
删除不再需要的暂存是好的习惯。你必须用以下命令手动完成:
|
||||
|
||||
* `git stash clear` 通过删除所有的暂存库来清空该列表。
|
||||
* `git stash drop <stash_id>` 从暂存列表中删除一个特定的暂存。
|
||||
|
||||
### 检查暂存的差异
|
||||
|
||||
命令 `git stash show <stash_id>` 允许你查看一个暂存的差异:
|
||||
|
||||
```
|
||||
$ git stash show stash@{1}
|
||||
console/console-init/ui/.graphqlrc.yml | 4 +-
|
||||
console/console-init/ui/generated-frontend.ts | 742 +++++++++---------
|
||||
console/console-init/ui/package.json | 2 +-
|
||||
```
|
||||
|
||||
要获得更详细的差异,需要传递 `--patch` 或 `-p` 标志:
|
||||
|
||||
```
|
||||
$ git stash show stash@{0} --patch
|
||||
diff --git a/console/console-init/ui/package.json b/console/console-init/ui/package.json
|
||||
index 755912b97..5b5af1bd6 100644
|
||||
--- a/console/console-init/ui/package.json
|
||||
+++ b/console/console-init/ui/package.json
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
- "name": "my-usepatternfly",
|
||||
+ "name": "my-usepatternfly-2",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"proxy": "http://localhost:4000"
|
||||
diff --git a/console/console-init/ui/src/AppNavHeader.tsx b/console/console-init/ui/src/AppNavHeader.tsx
|
||||
index a4764d2f3..da72b7e2b 100644
|
||||
--- a/console/console-init/ui/src/AppNavHeader.tsx
|
||||
+++ b/console/console-init/ui/src/AppNavHeader.tsx
|
||||
@@ -9,8 +9,8 @@ import { css } from "@patternfly/react-styles";
|
||||
|
||||
interface IAppNavHeaderProps extends PageHeaderProps {
|
||||
- toolbar?: React.ReactNode;
|
||||
- avatar?: React.ReactNode;
|
||||
+ toolbar?: React.ReactNode;
|
||||
+ avatar?: React.ReactNode;
|
||||
}
|
||||
|
||||
export class AppNavHeader extends React.Component<IAppNavHeaderProps>{
|
||||
render()
|
||||
```
|
||||
|
||||
### 签出到新的分支
|
||||
|
||||
你可能会遇到这样的情况:一个分支和你的暂存中的变更有分歧,当你试图重新应用暂存时,会造成冲突。一个简单的解决方法是使用 `git stash branch <new_branch_name stash_id>` 命令,它将根据创建暂存时的提交创建一个新分支,并将暂存中的修改弹出:
|
||||
|
||||
```
|
||||
$ git stash branch test_2 stash@{0}
|
||||
Switched to a new branch 'test_2'
|
||||
On branch test_2
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
modified: .graphqlrc.yml
|
||||
modified: generated-frontend.ts
|
||||
modified: package.json
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
Dropped stash@{0} (fe4bf8f79175b8fbd3df3c4558249834ecb75cd1)
|
||||
```
|
||||
|
||||
### 在不打扰暂存参考日志的情况下进行暂存
|
||||
|
||||
在极少数情况下,你可能需要创建一个暂存,同时保持暂存参考日志(`reflog`)的完整性。这些情况可能出现在你需要一个脚本作为一个实现细节来暂存的时候。这可以通过 `git stash create` 命令来实现;它创建了一个暂存条目,并返回它的对象名,而不将其推送到暂存参考日志中:
|
||||
|
||||
```
|
||||
$ git stash create "sample stash"
|
||||
63a711cd3c7f8047662007490723e26ae9d4acf9
|
||||
```
|
||||
|
||||
有时,你可能会决定将通过 `git stash create` 创建的暂存条目推送到暂存参考日志:
|
||||
|
||||
```
|
||||
$ git stash store -m "sample stash testing.." "63a711cd3c7f8047662007490723e26ae9d4acf9"
|
||||
$ git stash list
|
||||
stash @{0}: sample stash testing..
|
||||
```
|
||||
|
||||
### 结论
|
||||
|
||||
我希望你觉得这篇文章很有用,并学到了新的东西。如果我遗漏了任何有用的使用暂存的选项,请在评论中告诉我。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-stash
|
||||
|
||||
作者:[Ramakrishna Pattnaik][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://opensource.com/users/rkpattnaik780
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
|
||||
[2]: https://insights.stackoverflow.com/survey/2018#work-_-version-control
|
||||
[3]: https://opensource.com/downloads/cheat-sheet-git
|
@ -0,0 +1,135 @@
|
||||
[#]: subject: (Experiment on your code freely with Git worktree)
|
||||
[#]: via: (https://opensource.com/article/21/4/git-worktree)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
使用 Git 工作树对你的代码进行自由实验
|
||||
======
|
||||
|
||||
> 获得自由尝试的权利,同时在你的实验出错时可以安全地拥有一个新的、链接的克隆存储库。
|
||||
|
||||
![带烧杯的科学实验室][1]
|
||||
|
||||
Git 的设计部分是为了进行实验。如果你知道你的工作会被安全地跟踪,并且在出现严重错误时有安全状态存在,你就不会害怕尝试新的想法。不过,创新的部分代价是,你很可能会在过程中弄得一团糟。文件会被重新命名、移动、删除、更改、切割成碎片;新的文件被引入;你不打算跟踪的临时文件会在你的工作目录中占据一席之地等等。
|
||||
|
||||
简而言之,你的工作空间变成了纸牌屋,在“快好了!”和“哦,不,我做了什么?”之间岌岌可危地平衡着。那么,当你需要把仓库恢复到下午的一个已知状态,以便完成一些真正的工作时,该怎么办?我立刻想到了 `git branch` 和 [git stash][2] 这两个经典命令,但这两个命令都不是用来处理未被跟踪的文件的,而且文件路径的改变和其他重大的转变也会让人困惑,它们只能把工作藏(`stash`)起来以备后用。解决这个需求的答案是 Git 工作树。
|
||||
|
||||
### 什么是 Git 工作树
|
||||
|
||||
Git 工作树是 Git 仓库的一个链接副本,允许你同时签出多个分支。工作树与主工作副本的路径是分开的,它可以处于不同的状态和不同的分支上。在 Git 中新建工作树的好处是,你可以在不干扰当前工作环境的情况下,做出与当前任务无关的修改,提交修改,然后在以后再合并。
|
||||
|
||||
直接从 `git-worktree` 手册中找到了一个典型的例子:当你正在为一个项目做一个令人兴奋的新功能时,你的项目经理告诉你有一个紧急的修复工作。问题是你的工作仓库(你的“工作树”)处于混乱状态,因为你正在开发一个重要的新功能。你不想在当前的冲刺中“偷偷地”进行修复,而且你也不愿意把变更藏(`stash`)起来,为修复创建一个新的分支。相反,你决定创建一个新的工作树,这样你就可以在那里进行修复:
|
||||
|
||||
```
|
||||
$ git branch | tee
|
||||
* dev
|
||||
trunk
|
||||
$ git worktree add -b hotfix ~/code/hotfix trunk
|
||||
Preparing ../hotfix (identifier hotfix)
|
||||
HEAD is now at 62a2daf commit
|
||||
```
|
||||
|
||||
在你的 `code` 目录中,你现在有一个新的目录叫做 `hotfix`,它是一个与你的主项目仓库相连的 Git 工作树,它的 `HEAD` 停在叫做 `trunk` 的分支上。现在你可以把这个工作树当作你的主工作区来对待。你可以把目录切换到它里面,进行紧急修复、提交、并最终删除这个工作树:
|
||||
|
||||
```
|
||||
$ cd ~/code/hotfix
|
||||
$ sed -i 's/teh/the/' hello.txt
|
||||
$ git commit --all --message 'urgent hot fix'
|
||||
```
|
||||
|
||||
一旦你完成了你的紧急工作,你就可以回到你之前的任务。你可以控制你的热修复何时被集成到主项目中。例如,你可以直接将变更从其工作树推送到项目的远程存储库中:
|
||||
|
||||
```
|
||||
$ git push origin HEAD
|
||||
$ cd ~/code/myproject
|
||||
```
|
||||
|
||||
或者你可以将工作树存档为 TAR 或 ZIP 文件:
|
||||
|
||||
```
|
||||
$ cd ~/code/myproject
|
||||
$ git archive --format tar --output hotfix.tar master
|
||||
```
|
||||
|
||||
或者你可以从单独的工作树中获取本地的变化:
|
||||
|
||||
```
|
||||
$ git worktree list
|
||||
/home/seth/code/myproject 15fca84 [dev]
|
||||
/home/seth/code/hotfix 09e585d [master]
|
||||
```
|
||||
|
||||
从那里,你可以使用任何最适合你和你的团队的策略合并你的变化。
|
||||
|
||||
### 列出活动工作树
|
||||
|
||||
你可以使用 `git worktree list` 命令获得工作树的列表,并查看每个工作树签出的分支:
|
||||
|
||||
```
|
||||
$ git worktree list
|
||||
/home/seth/code/myproject 15fca84 [dev]
|
||||
/home/seth/code/hotfix 09e585d [master]
|
||||
```
|
||||
|
||||
你可以在任何一个工作树中使用这个功能。工作树始终是链接的(除非你手动移动它们,破坏 Git 定位工作树的能力,从而切断链接)。
|
||||
|
||||
### 移动工作树
|
||||
|
||||
Git 会跟踪项目 `.git` 目录下工作树的位置和状态:
|
||||
|
||||
```
|
||||
$ cat ~/code/myproject/.git/worktrees/hotfix/gitdir
|
||||
/home/seth/code/hotfix/.git
|
||||
```
|
||||
|
||||
如果你需要重定位一个工作树,必须使用 `git worktree move`;否则,当 Git 试图更新工作树的状态时,就会失败:
|
||||
|
||||
```
|
||||
$ mkdir ~/Temp
|
||||
$ git worktree move hotfix ~/Temp
|
||||
$ git worktree list
|
||||
/home/seth/code/myproject 15fca84 [dev]
|
||||
/home/seth/Temp/hotfix 09e585d [master]
|
||||
```
|
||||
|
||||
### 移除工作树
|
||||
|
||||
当你完成你的工作时,你可以用 `remove` 子命令删除它:
|
||||
|
||||
```
|
||||
$ git worktree remove hotfix
|
||||
$ git worktree list
|
||||
/home/seth/code/myproject 15fca84 [dev]
|
||||
```
|
||||
|
||||
为了确保你的 `.git` 目录是干净的,在删除工作树后使用 `prune` 子命令:
|
||||
|
||||
```
|
||||
$ git worktree remove prune
|
||||
```
|
||||
|
||||
### 何时使用工作树
|
||||
|
||||
与许多选项一样,无论是标签还是书签还是自动备份,都要靠你来跟踪你产生的数据,否则可能会变得不堪重负。不要经常使用工作树,要不你最终会有 20 份存储库的副本,每份副本的状态都略有不同。我发现最好是创建一个工作树,做需要它的任务,提交工作,然后删除树。保持简单和专注。
|
||||
|
||||
重要的是,工作树为你管理 Git 存储库的方式提供了更好的灵活性。在需要的时候使用它们,再也不用为了检查另一个分支上的内容而争先恐后地保存工作状态了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-worktree
|
||||
|
||||
作者:[Seth Kenlon][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://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/science_experiment_beaker_lab.png?itok=plKWRhlU (Science lab with beakers)
|
||||
[2]: https://opensource.com/article/21/4/git-stash
|
Loading…
Reference in New Issue
Block a user