mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
commit
43c10395e7
@ -0,0 +1,107 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13262-1.html)
|
||||
[#]: subject: (How to set up a homelab from hardware to firewall)
|
||||
[#]: via: (https://opensource.com/article/19/3/home-lab)
|
||||
[#]: author: (Michael Zamot https://opensource.com/users/mzamot)
|
||||
|
||||
如何从硬件到防火墙建立一个家庭实验室
|
||||
======
|
||||
|
||||
> 了解一下用于构建自己的家庭实验室的硬件和软件方案。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/02/215222t2fiqpt17gfpkkii.jpg)
|
||||
|
||||
你有想过创建一个家庭实验室吗?或许你想尝试不同的技术,构建开发环境、亦或是建立自己的私有云。拥有一个家庭实验室的理由很多,本教程旨在使入门变得更容易。
|
||||
|
||||
规划家庭实验室时,需要考虑三方面:硬件、软件和维护。我们将在这里查看前两方面,并在以后的文章中讲述如何节省维护计算机实验室的时间。
|
||||
|
||||
### 硬件
|
||||
|
||||
在考虑硬件需求时,首先要考虑如何使用实验室以及你的预算、噪声、空间和电力使用情况。
|
||||
|
||||
如果购买新硬件过于昂贵,请搜索当地的大学、广告以及诸如 eBay 或 Craigslist 之类的网站,能获取二手服务器的地方。它们通常很便宜,并且服务器级的硬件可以使用很多年。你将需要三类硬件:虚拟化服务器、存储设备和路由器/防火墙。
|
||||
|
||||
#### 虚拟化服务器
|
||||
|
||||
一个虚拟化服务器允许你去运行多个共享物理机资源的虚拟机,同时最大化利用和隔离资源。如果你弄坏了一台虚拟机,无需重建整个服务器,只需虚拟一个好了。如果你想进行测试或尝试某些操作而不损坏整个系统,仅需要新建一个虚拟机来运行即可。
|
||||
|
||||
在虚拟服务器中,需考虑两个最重要的因素是 CPU 的核心数及其运行速度以及内存容量。如果没有足够的资源够全部虚拟机共享,那么它们将被过度分配并试着获取其他虚拟机的 CPU 的周期和内存。
|
||||
|
||||
因此,考虑一个多核 CPU 的平台。你要确保 CPU 支持虚拟化指令(因特尔的 VT-x 指令集和 AMD 的 AMD-V 指令集)。能够处理虚拟化的优质的消费级处理器有因特尔的 i5 或 i7 和 AMD 的 Ryzen 处理器。如果你考虑服务器级的硬件,那么因特尔的志强系列和 AMD 的 EPYC 都是不错的选择。内存可能很昂贵,尤其是最近的 DDR4 内存。当我们估计所需多少内存时,请为主机操作系统的内存至少分配 2 GB 的空间。
|
||||
|
||||
如果你担心电费或噪声,则诸如因特尔 NUC 设备之类的解决方案虽然外形小巧、功耗低、噪音低,但是却以牺牲可扩展性为代价。
|
||||
|
||||
#### NAS
|
||||
|
||||
如果希望装有硬盘驱动器的计算机存储你的所有个人数据,电影,图片等,并为虚拟化服务器提供存储,则需要<ruby>网络附加存储<rt>Network-attached storage</rt></ruby>(NAS)。
|
||||
|
||||
在大多数情况下,你不太可能需要一颗强力的 CPU。实际上,许多商业 NAS 的解决方案使用低功耗的 ARM CPU。支持多个 SATA 硬盘的主板是必须的。如果你的主板没有足够的端口,请使用<ruby>主机总线适配器<rt>host bus adapter</rt><ruby>(HBA)SAS 控制器添加额外的端口。
|
||||
|
||||
网络性能对于 NAS 来说是至关重要的,因此最好选择<ruby>千兆<rt>gigabit</rt></ruby>网络(或更快网络)。
|
||||
|
||||
内存需求根据你的文件系统而有所不同。ZFS 是 NAS 上最受欢迎的文件系统之一,你需要更多内存才能使用诸如缓存或重复数据删除之类的功能。<ruby>纠错码<rt>Error-correcting code</rt></ruby>(ECC)的内存是防止数据损坏的最佳选择(但在购买前请确保你的主板支持)。最后但同样重要的,不要忘记使用<ruby>不间断电源<rt>uninterruptible power supply</rt></ruby>(UPS),因为断电可能会使得数据出错。
|
||||
|
||||
#### 防火墙和路由器
|
||||
|
||||
你是否曾意识到,廉价的路由器/防火墙通常是保护你的家庭网络不受外部环境影响的主要部分?这些路由器很少及时收到安全更新(如果有的话)。现在害怕了吗?好吧,[确实][2]!
|
||||
|
||||
通常,你不需要一颗强大的 CPU 或是大量内存来构建你自己的路由器/防火墙,除非你需要高吞吐率或是执行 CPU 密集型任务,像是虚拟私有网络服务器或是流量过滤。在这种情况下,你将需要一个支持 AES-NI 的多核 CPU。
|
||||
|
||||
你可能想要至少 2 个千兆或更快的<ruby>以太网卡<rt>Ethernet network interface cards</rt></ruby>(NIC),这不是必需的,但我推荐使用一个管理型交换机来连接你自己的装配的路由器,以创建 VLAN 来进一步隔离和保护你的网络。
|
||||
|
||||
![Home computer lab PfSense][4]
|
||||
|
||||
### 软件
|
||||
|
||||
在选择完你的虚拟化服务器、NAS 和防火墙/路由器后,下一步是探索不同的操作系统和软件,以最大程度地发挥其作用。尽管你可以使用 CentOS、Debian或 Ubuntu 之类的常规 Linux 发行版,但是与以下软件相比,它们通常花费更多的时间进行配置和管理。
|
||||
|
||||
#### 虚拟化软件
|
||||
|
||||
[KVM][5](<ruby>基于内核的虚拟机<rt>Kernel-based Virtual Machine</rt></ruby>)使你可以将 Linux 变成虚拟机监控程序,以便可以在同一台机器中运行多个虚拟机。最好的是,KVM 作为 Linux 的一部分,它是许多企业和家庭用户的首选。如果你愿意,可以安装 [libvirt][6] 和 [virt-manager][7] 来管理你的虚拟化平台。
|
||||
|
||||
[Proxmox VE][8] 是一个强大的企业级解决方案,并且是一个完全开源的虚拟化和容器平台。它基于 Debian,使用 KVM 作为其虚拟机管理程序,并使用 LXC 作为容器。Proxmox 提供了强大的网页界面、API,并且可以扩展到许多群集节点,这很有用,因为你永远不知道何时实验室容量不足。
|
||||
|
||||
[oVirt][9](RHV)是另一种使用 KVM 作为虚拟机管理程序的企业级解决方案。不要因为它是企业级的,就意味着你不能在家中使用它。oVirt 提供了强大的网页界面和 API,并且可以处理数百个节点(如果你运行那么多服务器,我可不想成为你的邻居!)。oVirt 用于家庭实验室的潜在问题是它需要一套最低限度的节点:你将需要一个外部存储(例如 NAS)和至少两个其他虚拟化节点(你可以只在一个节点上运行,但你会遇到环境维护方面的问题)。
|
||||
|
||||
#### 网络附加存储软件
|
||||
|
||||
[FreeNAS][10] 是最受欢迎的开源 NAS 发行版,它基于稳定的 FreeBSD 操作系统。它最强大的功能之一是支持 ZFS 文件系统,该文件系统提供了数据完整性检查、快照、复制和多个级别的冗余(镜像、条带化镜像和条带化)。最重要的是,所有功能都通过功能强大且易于使用的网页界面进行管理。在安装 FreeNAS 之前,请检查硬件是否支持,因为它不如基于 Linux 的发行版那么广泛。
|
||||
|
||||
另一个流行的替代方法是基于 Linux 的 [OpenMediaVault][11]。它的主要功能之一是模块化,带有可扩展和添加特性的插件。它包括的功能包括基于网页管理界面,CIFS、SFTP、NFS、iSCSI 等协议,以及卷管理,包括软件 RAID、资源配额,<ruby>访问控制列表<rt>access control lists</rt></ruby>(ACL)和共享管理。由于它是基于 Linux 的,因此其具有广泛的硬件支持。
|
||||
|
||||
#### 防火墙/路由器软件
|
||||
|
||||
[pfSense][12] 是基于 FreeBSD 的开源企业级路由器和防火墙发行版。它可以直接安装在服务器上,甚至可以安装在虚拟机中(以管理虚拟或物理网络并节省空间)。它有许多功能,可以使用软件包进行扩展。尽管它也有命令行访问权限,但也可以完全使用网页界面对其进行管理。它具有你所希望路由器和防火墙提供的所有功能,例如 DHCP 和 DNS,以及更高级的功能,例如入侵检测(IDS)和入侵防御(IPS)系统。你可以侦听多个不同接口或使用 VLAN 的网络,并且只需鼠标点击几下即可创建安全的 VPN 服务器。pfSense 使用 pf,这是一种有状态的数据包筛选器,它是为 OpenBSD 操作系统开发的,使用类似 IPFilter 的语法。许多公司和组织都有使用 pfSense。
|
||||
|
||||
* * *
|
||||
|
||||
考虑到所有的信息,是时候动手开始建立你的实验室了。在之后的文章中,我将介绍运行家庭实验室的第三方面:自动化进行部署和维护。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/home-lab
|
||||
|
||||
作者:[Michael Zamot (Red Hat)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wyxplus](https://github.com/wyxplus)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mzamot
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_code_woman.png?itok=vbYz6jjb
|
||||
[2]: https://opensource.com/article/18/5/how-insecure-your-router
|
||||
[3]: /file/427426
|
||||
[4]: https://opensource.com/sites/default/files/uploads/pfsense2.png (Home computer lab PfSense)
|
||||
[5]: https://www.linux-kvm.org/page/Main_Page
|
||||
[6]: https://libvirt.org/
|
||||
[7]: https://virt-manager.org/
|
||||
[8]: https://www.proxmox.com/en/proxmox-ve
|
||||
[9]: https://ovirt.org/
|
||||
[10]: https://freenas.org/
|
||||
[11]: https://www.openmediavault.org/
|
||||
[12]: https://www.pfsense.org/
|
@ -0,0 +1,138 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: 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)
|
||||
|
||||
值得现在就去尝试的四款开源聊天应用软件
|
||||
======
|
||||
|
||||
> 现在,远程协作已作为一项必不可少的能力,让开源实时聊天成为你工具箱中必不可少的一部分吧。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/06/103454xundd858446u08r0.jpg)
|
||||
|
||||
清晨起床后,我们通常要做的第一件事是检查手机,看看是否有同事和朋友发来的重要信息。无论这是否是一个好习惯,但这种行为早已成为我们日常生活的一部分。
|
||||
|
||||
> 人是理性动物。他可以为任何他想相信的事情想出一个理由。
|
||||
> – 阿纳托尔·法朗士
|
||||
|
||||
无论理由是否合理,我们每天都在使用的一系列的通讯工具,例如电子邮件、电话、网络会议工具或社交网络。甚至在 COVID-19 之前,居家办公就已经使这些通信工具成为我们生活中的重要部分。随着疫情出现,居家办公成为新常态,我们交流方式的方方面面正面临着前所未有的改变,这让这些工具变得不可或缺。
|
||||
|
||||
### 为什么需要聊天?
|
||||
|
||||
作为全球团队的一部分进行远程工作时,我们必须要有一个相互协作的环境。聊天应用软件在帮助我们保持相互联系中起着至关重要的作用。与电子邮件相比,聊天应用软件可提供与全球各地的同事快速、实时的通信。
|
||||
|
||||
选择一款聊天应用软件需要考虑很多因素。为了帮助你选择最适合你的应用软件,在本文中,我将探讨四款开源聊天应用软件,和一个当你需要与同事“面对面”时的开源视频通信工具,然后概述在高效的通讯应用软件中,你应当考虑的一些功能。
|
||||
|
||||
### 四款开源聊天软件
|
||||
|
||||
#### Rocket.Chat
|
||||
|
||||
![Rocket.Chat][2]
|
||||
|
||||
[Rocket.Chat][3] 是一个综合性的通讯平台,其将频道分为公开房间(任何人都可以加入)和私有房间(仅受邀请)。你还可以直接将消息发送给已登录的人员。其能共享文档、链接、照片、视频和<ruby>动态图<rt>GIF</rt></ruby>,以及进行视频通话,并可以在平台中发送语音信息。
|
||||
|
||||
Rocket.Chat 是自由开源软件,但是其独特之处在于其可自托管的聊天系统。你可以将其下载到你的服务器上,无论它是本地服务器或是在公有云上的虚拟专用服务器。
|
||||
|
||||
Rocket.Chat 是完全免费,其 [源码][4] 可在 Github 获得。许多开源项目都使用 Rocket.Chat 作为他们官方交流平台。该软件在持续不断的发展且不断更新和改进新功能。
|
||||
|
||||
我最喜欢 Rocket.Chat 的地方是其能够根据用户需求来进行自定义操作,并且它使用机器学习在用户通讯间进行自动的、实时消息翻译。你也可以下载适用于你移动设备的 Rocket.Chat,以便能随时随地使用。
|
||||
|
||||
#### IRC
|
||||
|
||||
![IRC on WeeChat 0.3.5][5]
|
||||
|
||||
IRC(<ruby>[互联网中继聊天][6]<rt>Internet Relay Chat</rt></ruby>)是一款实时、基于文本格式的通信软件。尽管其是最古老的电子通讯形式之一,但在许多知名的软件项目中仍受欢迎。
|
||||
|
||||
IRC 频道是单独的聊天室。它可以让你在一个开放的频道中与多人进行聊天或与某人私下一对一聊天。如果频道名称以 `#` 开头,则可以假定它是官方的聊天室,而以 `##` 开头的聊天室通常是非官方的聊天室。
|
||||
|
||||
[上手 IRC][7] 很容易。你的 IRC 昵称可以让人们找到你,因此它必须是唯一的。但是,你可以完全自主地选择 IRC 客户端。如果你需要比标准 IRC 客户端更多功能的应用程序,则可以使用 [Riot.im][8] 连接到 IRC。
|
||||
|
||||
考虑到它悠久的历史,你为什么还要继续使用 IRC?出于一个原因是,其仍是我们所依赖的许多自由及开源项目的家园。如果你想参于开源软件开发和社区,可以选择用 IRC。
|
||||
|
||||
#### Zulip
|
||||
|
||||
![Zulip][9]
|
||||
|
||||
[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。
|
||||
|
||||
Zulip 是开源的(你可以在 GitHub 上访问其 [源码][11])并且免费使用,但它有提供预置支持、[LDAP][12] 集成和更多存储类型的付费产品。
|
||||
|
||||
#### Let's Chat
|
||||
|
||||
![Let's Chat][13]
|
||||
|
||||
[Let's Chat][14] 是一个面向小型团队的自托管的聊天解决方案。它使用 Node.js 和 MongoDB 编写运行,只需鼠标点击几下即可将其部署到本地服务器或云服务器。它是自由开源软件,可以在 GitHub 上查看其 [源码][15]。
|
||||
|
||||
Let's Chat 与其他开源聊天工具的不同之处在于其企业功能:它支持 LDAP 和 [Kerberos][16] 身份验证。它还具有新用户想要的所有功能:你可以在历史记录中搜索过往消息,并使用 @username 之类的标签来标记人员。
|
||||
|
||||
我喜欢 Let's Chat 的地方是它拥有私人的受密码保护的聊天室、发送图片、支持 GIPHY 和代码粘贴。它不断更新,不断增加新功能。
|
||||
|
||||
### 附加:开源视频聊天软件 Jitsi
|
||||
|
||||
![Jitsi][17]
|
||||
|
||||
有时,文字聊天还不够,你还可能需要与某人面谈。在这种情况下,如果不能选择面对面开会交流,那么视频聊天是最好的选择。[Jitsi][18] 是一个完全开源的、支持多平台且兼容 WebRTC 的视频会议工具。
|
||||
|
||||
Jitsi 从 Jitsi Desktop 开始,已经发展成为许多 [项目][19],包括 Jitsi Meet、Jitsi Videobridge、jibri 和 libjitsi,并且每个项目都在 GitHub 上开放了 [源码][20]。
|
||||
|
||||
Jitsi 是安全且可扩展的,并支持诸如<ruby>联播<rt>simulcast</rt></ruby>和<ruby>带宽预估<rt>bandwidth estimation</rt></ruby>之类的高级视频路由的概念,还包括音频、录制、屏幕共享和拨入功能等经典功能。你可以来为你的视频聊天室设置密码以保护其不受干扰,并且它还支持通过 YouTube 进行直播。你还可以搭建自己的 Jitsi 服务器,并将其托管在本地或<ruby>虚拟专用服务器<rt>virtual private server</rt></ruby>(例如 Digital Ocean Droplet)上。
|
||||
|
||||
我最喜欢 Jitsi 的是它是免费且低门槛的。任何人都可以通过访问 [meet.jit.si][21] 来立即召开会议,并且用户无需注册或安装即可轻松参加会议。(但是,注册的话能拥有日程安排功能。)这种入门级低门槛的视频会议服务让 Jitsi 迅速普及。
|
||||
|
||||
### 选择一个聊天应用软件的建议
|
||||
|
||||
各种各样的开源聊天应用软件可能让你很难抉择。以下是一些选择一款聊天应用软件的一般准则。
|
||||
|
||||
* 最好具有交互式的界面和简单的导航工具。
|
||||
* 最好寻找一种功能强大且能让人们以各种方式使用它的工具。
|
||||
* 如果与你所使用的工具有进行集成整合的话,可以重点考虑。一些工具与 GitHub 或 GitLab 以及某些应用程序具有良好的无缝衔接,这将是一个非常有用的功能。
|
||||
* 有能托管到云主机的工具将十分方便。
|
||||
* 应考虑到聊天服务的安全性。在私人服务器上托管服务的能力对许多组织和个人来说是必要的。
|
||||
* 最好选择那些具有丰富的隐私设置,并拥有私人聊天室和公共聊天室的通讯工具。
|
||||
|
||||
由于人们比以往任何时候都更加依赖在线服务,因此拥有备用的通讯平台是明智之举。例如,如果一个项目正在使用 Rocket.Chat,则必要之时,它还应具有跳转到 IRC 的能力。由于这些软件在不断更新,你可能会发现自己已经连接到多个渠道,因此集成整合其他应用将变得非常有价值。
|
||||
|
||||
在各种可用的开源聊天服务中,你喜欢和使用哪些?这些工具又是如何帮助你进行远程办公?请在评论中分享你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/4/open-source-chat
|
||||
|
||||
作者:[Sudeshna Sur][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wyxplus](https://github.com/wyxplus)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/sudeshna-sur
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_communication_team.png?itok=CYfZ_gE7 (Chat bubbles)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/rocketchat.png (Rocket.Chat)
|
||||
[3]: https://rocket.chat/
|
||||
[4]: https://github.com/RocketChat/Rocket.Chat
|
||||
[5]: https://opensource.com/sites/default/files/uploads/irc.png (IRC on WeeChat 0.3.5)
|
||||
[6]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
|
||||
[7]: https://opensource.com/article/16/6/getting-started-irc
|
||||
[8]: https://opensource.com/article/17/5/introducing-riot-IRC
|
||||
[9]: https://opensource.com/sites/default/files/uploads/zulip.png (Zulip)
|
||||
[10]: https://zulipchat.com/
|
||||
[11]: https://github.com/zulip/zulip
|
||||
[12]: https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol
|
||||
[13]: https://opensource.com/sites/default/files/uploads/lets-chat.png (Let's Chat)
|
||||
[14]: https://sdelements.github.io/lets-chat/
|
||||
[15]: https://github.com/sdelements/lets-chat
|
||||
[16]: https://en.wikipedia.org/wiki/Kerberos_(protocol)
|
||||
[17]: https://opensource.com/sites/default/files/uploads/jitsi_0_0.jpg (Jitsi)
|
||||
[18]: https://jitsi.org/
|
||||
[19]: https://jitsi.org/projects/
|
||||
[20]: https://github.com/jitsi
|
||||
[21]: http://meet.jit.si
|
529
published/20200707 Use systemd timers instead of cronjobs.md
Normal file
529
published/20200707 Use systemd timers instead of cronjobs.md
Normal file
@ -0,0 +1,529 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (tt67wq)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13307-1.html)
|
||||
[#]: subject: (Use systemd timers instead of cronjobs)
|
||||
[#]: via: (https://opensource.com/article/20/7/systemd-timers)
|
||||
[#]: author: (David Both https://opensource.com/users/dboth)
|
||||
|
||||
使用 systemd 定时器代替 cron 作业
|
||||
======
|
||||
|
||||
> 定时器提供了比 cron 作业更为细粒度的事件控制。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/18/104406dgszkj3eeibkea55.jpg)
|
||||
|
||||
我正在致力于将我的 [cron][2] 作业迁移到 systemd 定时器上。我已经使用定时器多年了,但通常来说,我的学识只足以支撑我当前的工作。但在我研究 [systemd 系列][3] 的过程中,我发现 systemd 定时器有一些非常有意思的能力。
|
||||
|
||||
与 cron 作业类似,systemd 定时器可以在特定的时间间隔触发事件(shell 脚本和程序),例如每天一次或在一个月中的特定某一天(或许只有在周一生效),或在从上午 8 点到下午 6 点的工作时间内每隔 15 分钟一次。定时器也可以做到 cron 作业无法做到的一些事情。举个例子,定时器可以在特定事件发生后的一段时间后触发一段脚本或者程序去执行,例如开机、启动、上个任务完成,甚至于定时器调用的上个服务单元的完成的时刻。
|
||||
|
||||
### 操作系统维护的计时器
|
||||
|
||||
当在一个新系统上安装 Fedora 或者是任意一个基于 systemd 的发行版时,作为系统维护过程的一部分,它会在 Linux 宿主机的后台中创建多个定时器。这些定时器会触发事件来执行必要的日常维护任务,比如更新系统数据库、清理临时目录、轮换日志文件,以及更多其他事件。
|
||||
|
||||
作为示例,我会查看一些我的主要工作站上的定时器,通过执行 `systemctl status *timer` 命令来展示主机上的所有定时器。星号的作用与文件通配相同,所以这个命令会列出所有的 systemd 定时器单元。
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemctl status *timer
|
||||
● mlocate-updatedb.timer - Updates mlocate database every day
|
||||
Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
|
||||
Triggers: ● mlocate-updatedb.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.
|
||||
|
||||
● logrotate.timer - Daily rotation of log files
|
||||
Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
|
||||
Triggers: ● logrotate.service
|
||||
Docs: man:logrotate(8)
|
||||
man:logrotate.conf(5)
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.
|
||||
|
||||
● sysstat-summary.timer - Generate summary of yesterday's process accounting
|
||||
Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
|
||||
Triggers: ● sysstat-summary.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.
|
||||
|
||||
● fstrim.timer - Discard unused blocks once a week
|
||||
Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
|
||||
Triggers: ● fstrim.service
|
||||
Docs: man:fstrim
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.
|
||||
|
||||
● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
|
||||
Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
|
||||
Triggers: ● sysstat-collect.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.
|
||||
|
||||
● dnf-makecache.timer - dnf makecache --timer
|
||||
Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
|
||||
Triggers: ● dnf-makecache.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.
|
||||
|
||||
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
|
||||
Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
|
||||
Triggers: ● systemd-tmpfiles-clean.service
|
||||
Docs: man:tmpfiles.d(5)
|
||||
man:systemd-tmpfiles(8)
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.
|
||||
```
|
||||
|
||||
每个定时器至少有六行相关信息:
|
||||
|
||||
* 定时器的第一行有定时器名字和定时器目的的简短介绍
|
||||
* 第二行展示了定时器的状态,是否已加载,定时器单元文件的完整路径以及预设信息。
|
||||
* 第三行指明了其活动状态,包括该定时器激活的日期和时间。
|
||||
* 第四行包括了该定时器下次被触发的日期和时间和距离触发的大概时间。
|
||||
* 第五行展示了被定时器触发的事件或服务名称。
|
||||
* 部分(不是全部)systemd 单元文件有相关文档的指引。我虚拟机上输出中有三个定时器有文档指引。这是一个很好(但非必要)的信息。
|
||||
* 最后一行是计时器最近触发的服务实例的日志条目。
|
||||
|
||||
你也许有一些不一样的定时器,取决于你的主机。
|
||||
|
||||
### 创建一个定时器
|
||||
|
||||
尽管我们可以解构一个或多个现有的计时器来了解其工作原理,但让我们创建我们自己的 [服务单元][4] 和一个定时器去触发它。为了保持简单,我们将使用一个相当简单的例子。当我们完成这个实验之后,就能更容易理解其他定时器的工作原理以及发现它们正在做什么。
|
||||
|
||||
首先,创建一个运行基础东西的简单的服务,例如 `free` 命令。举个例子,你可能想定时监控空余内存。在 `/etc/systemd/system` 目录下创建如下的 `myMonitor.server` 单元文件。它不需要是可执行文件:
|
||||
|
||||
```
|
||||
# This service unit is for testing timer units
|
||||
# By David Both
|
||||
# Licensed under GPL V2
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description=Logs system statistics to the systemd journal
|
||||
Wants=myMonitor.timer
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/free
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
这大概是你能创建的最简单的服务单元了。现在我们查看一下服务状态同时测试一下服务单元确保它和我们预期一样可用。
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemctl status myMonitor.service
|
||||
● myMonitor.service - Logs system statistics to the systemd journal
|
||||
Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
|
||||
Active: inactive (dead)
|
||||
[root@testvm1 system]# systemctl start myMonitor.service
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
输出在哪里呢?默认情况下,systemd 服务单元执行程序的标准输出(`STDOUT`)会被发送到系统日志中,它保留了记录供现在或者之后(直到某个时间点)查看。(在本系列的后续文章中,我将介绍系统日志的记录和保留策略)。专门查看你的服务单元的日志,而且只针对今天。`-S` 选项,即 `--since` 的缩写,允许你指定 `journalctl` 工具搜索条目的时间段。这并不代表你不关心过往结果 —— 在这个案例中,不会有过往记录 —— 如果你的机器以及运行了很长时间且堆积了大量的日志,它可以缩短搜索时间。
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -u myMonitor.service
|
||||
-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
|
||||
Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: total used free shared buff/cache available
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: Mem: 12635740 522868 11032860 8016 1080012 11821508
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: Swap: 8388604 0 8388604
|
||||
Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
由服务触发的任务可以是单个程序、一组程序或者是一个脚本语言写的脚本。通过在 `myMonitor.service` 单元文件里的 `[Service]` 块末尾中添加如下行可以为服务添加另一个任务:
|
||||
|
||||
```
|
||||
ExecStart=/usr/bin/lsblk
|
||||
```
|
||||
|
||||
再次启动服务,查看日志检查结果,结果应该看上去像这样。你应该在日志中看到两条命令的结果输出:
|
||||
|
||||
```
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: total used free shared buff/cache available
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: Mem: 12635740 531788 11019540 8024 1084412 11812272
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: Swap: 8388604 0 8388604
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda 8:0 0 120G 0 disk
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
```
|
||||
|
||||
现在你知道了你的服务可以按预期工作了,在 `/etc/systemd/system` 目录下创建 `myMonitor.timer` 定时器单元文件,添加如下代码:
|
||||
|
||||
```
|
||||
# This timer unit is for testing
|
||||
# By David Both
|
||||
# Licensed under GPL V2
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description=Logs some system statistics to the systemd journal
|
||||
Requires=myMonitor.service
|
||||
|
||||
[Timer]
|
||||
Unit=myMonitor.service
|
||||
OnCalendar=*-*-* *:*:00
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
在 `myMonitor.timer` 文件中的 `OnCalendar` 时间格式,`*-*-* *:*:00`,应该会每分钟触发一次定时器去执行 `myMonitor.service` 单元。我会在文章的后面进一步探索 `OnCalendar` 设置。
|
||||
|
||||
到目前为止,在服务被计时器触发运行时观察与之有关的日志记录。你也可以跟踪计时器,跟踪服务可以让你接近实时的看到结果。执行 `journalctl` 时带上 `-f` 选项:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
|
||||
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
|
||||
```
|
||||
|
||||
执行但是不启用该定时器,看看它运行一段时间后发生了什么:
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemctl start myMonitor.service
|
||||
[root@testvm1 ~]#
|
||||
```
|
||||
|
||||
一条结果立即就显示出来了,下一条大概在一分钟后出来。观察几分钟日志,看看你有没有跟我发现同样的事情:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
|
||||
-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: total used free shared buff/cache available
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: Mem: 12635740 556604 10965516 8036 1113620 11785628
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: total used free shared buff/cache available
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: Mem: 12635740 555228 10966836 8036 1113676 11786996
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: total used free shared buff/cache available
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: Mem: 12635740 553488 10968564 8036 1113688 11788744
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
```
|
||||
|
||||
别忘了检查下计时器和服务的状态。
|
||||
|
||||
你在日志里大概至少注意到两件事。第一,你不需要特地做什么来让 `myMonitor.service` 单元中 `ExecStart` 触发器产生的 `STDOUT` 存储到日志里。这都是用 systemd 来运行服务的一部分功能。然而,它确实意味着你需要小心对待服务单元里面执行的脚本和它们能产生多少 `STDOUT`。
|
||||
|
||||
第二,定时器并不是精确在每分钟的 :00 秒执行的,甚至每次执行的时间间隔都不是刚好一分钟。这是特意的设计,但是有必要的话可以改变这种行为(如果只是它挑战了你的系统管理员的敏感神经)。
|
||||
|
||||
这样设计的初衷是为了防止多个服务在完全相同的时刻被触发。举个例子,你可以用例如 Weekly,Daily 等时间格式。这些快捷写法都被定义为在某一天的 00:00:00 执行。当多个定时器都这样定义的话,有很大可能它们会同时执行。
|
||||
|
||||
systemd 定时器被故意设计成在规定时间附近随机波动的时间点触发,以避免同一时间触发。它们在一个时间窗口内半随机触发,时间窗口开始于预设的触发时间,结束于预设时间后一分钟。根据 `systemd.timer` 的手册页,这个触发时间相对于其他已经定义的定时器单元保持在稳定的位置。你可以在日志条目中看到,定时器在启动后立即触发,然后在每分钟后的 46 或 47 秒触发。
|
||||
|
||||
大部分情况下,这种概率抖动的定时器是没事的。当调度类似执行备份的任务,只需要它们在下班时间运行,这样是没问题的。系统管理员可以选择确定的开始时间来确保不和其他任务冲突,例如 01:05:00 这样典型的 cron 作业时间,但是有很大范围的时间值可以满足这一点。在开始时间上的一个分钟级别的随机往往是无关紧要的。
|
||||
|
||||
然而,对某些任务来说,精确的触发时间是个硬性要求。对于这类任务,你可以向单元文件的 `Timer` 块中添加如下声明来指定更高的触发时间跨度精确度(精确到微秒以内):
|
||||
|
||||
```
|
||||
AccuracySec=1us
|
||||
```
|
||||
|
||||
时间跨度可用于指定所需的精度,以及定义重复事件或一次性事件的时间跨度。它能识别以下单位:
|
||||
|
||||
* `usec`、`us`、`µs`
|
||||
* `msec`、`ms`
|
||||
* `seconds`、`second`、`sec`、`s`
|
||||
* `minutes`、`minute`、`min`、`m`
|
||||
* `hours`、`hour`、`hr`、`h`
|
||||
* `days`、`day`、`d`
|
||||
* `weeks`、`week`、`w`
|
||||
* `months`、`month`、`M`(定义为 30.44 天)
|
||||
* `years`、`year`、`y`(定义为 365.25 天)
|
||||
|
||||
所有 `/usr/lib/systemd/system` 中的定时器都指定了一个更宽松的时间精度,因为精准时间没那么重要。看看这些系统创建的定时器的时间格式:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
|
||||
/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
|
||||
/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
|
||||
/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
|
||||
/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
|
||||
/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
|
||||
/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
看下 `/usr/lib/systemd/system` 目录下部分定时器单元文件的完整内容,看看它们是如何构建的。
|
||||
|
||||
在本实验中不必让这个定时器在启动时激活,但下面这个命令可以设置开机自启:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemctl enable myMonitor.timer
|
||||
```
|
||||
|
||||
你创建的单元文件不需要是可执行的。你同样不需要启用服务,因为它是被定时器触发的。如果你需要的话,你仍然可以在命令行里手动触发该服务单元。尝试一下,然后观察日志。
|
||||
|
||||
关于定时器精度、事件时间规格和触发事件的详细信息,请参见 systemd.timer 和 systemd.time 的手册页。
|
||||
|
||||
### 定时器类型
|
||||
|
||||
systemd 定时器还有一些在 cron 中找不到的功能,cron 只在确定的、重复的、具体的日期和时间触发。systemd 定时器可以被配置成根据其他 systemd 单元状态发生改变时触发。举个例子,定时器可以配置成在系统开机、启动后,或是某个确定的服务单元激活之后的一段时间被触发。这些被称为单调计时器。“单调”指的是一个持续增长的计数器或序列。这些定时器不是持久的,因为它们在每次启动后都会重置。
|
||||
|
||||
表格 1 列出了一些单调定时器以及每个定时器的简短定义,同时有 `OnCalendar` 定时器,这些不是单调的,它们被用于指定未来有可能重复的某个确定时间。这个信息来自于 `systemd.timer` 的手册页,有一些不重要的修改。
|
||||
|
||||
定时器 | 单调性 | 定义
|
||||
---|---|---
|
||||
`OnActiveSec=` | X | 定义了一个与定时器被激活的那一刻相关的定时器。
|
||||
`OnBootSec=` | X | 定义了一个与机器启动时间相关的计时器。
|
||||
`OnStartupSec=` | X | 定义了一个与服务管理器首次启动相关的计时器。对于系统定时器来说,这个定时器与 `OnBootSec=` 类似,因为系统服务管理器在机器启动后很短的时间后就会启动。当以在每个用户服务管理器中运行的单元进行配置时,它尤其有用,因为用户的服务管理器通常在首次登录后启动,而不是机器启动后。
|
||||
`OnUnitActiveSec=` | X | 定义了一个与将要激活的定时器上次激活时间相关的定时器。
|
||||
`OnUnitInactiveSec=` | X | 定义了一个与将要激活的定时器上次停用时间相关的定时器。
|
||||
`OnCalendar=` | | 定义了一个有日期事件表达式语法的实时(即时钟)定时器。查看 `systemd.time(7)` 的手册页获取更多与日历事件表达式相关的语法信息。除此以外,它的语义和 `OnActiveSec=` 类似。
|
||||
|
||||
_Table 1: systemd 定时器定义_
|
||||
|
||||
单调计时器可使用同样的简写名作为它们的时间跨度,即我们之前提到的 `AccuracySec` 表达式,但是 systemd 将这些名字统一转换成了秒。举个例子,比如你想规定某个定时器在系统启动后五天触发一次事件;它可能看起来像 `OnBootSec=5d`。如果机器启动于 `2020-06-15 09:45:27`,这个定时器会在 `2020-06-20 09:45:27` 或在这之后的一分钟内触发。
|
||||
|
||||
### 日历事件格式
|
||||
|
||||
日历事件格式是定时器在所需的重复时间触发的关键。我们开始看下一些 `OnCalendar` 设置一起使用的格式。
|
||||
|
||||
与 crontab 中的格式相比,systemd 及其计时器使用的时间和日历格式风格不同。它比 crontab 更为灵活,而且可以使用类似 `at` 命令的方式允许模糊的日期和时间。它还应该足够熟悉使其易于理解。
|
||||
|
||||
systemd 定时器使用 `OnCalendar=` 的基础格式是 `DOW YYYY-MM-DD HH:MM:SS`。DOW(星期几)是选填的,其他字段可以用一个星号(`*`)来匹配此位置的任意值。所有的日历时间格式会被转换成标准格式。如果时间没有指定,它会被设置为 `00:00:00`。如果日期没有指定但是时间指定了,那么下次匹配的时间可能是今天或者明天,取决于当前的时间。月份和星期可以使用名称或数字。每个单元都可以使用逗号分隔的列表。单元范围可以在开始值和结束值之间用 `..` 指定。
|
||||
|
||||
指定日期有一些有趣的选项,波浪号(`~`)可以指定月份的最后一天或者最后一天之前的某几天。`/` 可以用来指定星期几作为修饰符。
|
||||
|
||||
这里有几个在 `OnCalendar` 表达式中使用的典型时间格式例子。
|
||||
|
||||
日期事件格式 | 描述
|
||||
---|---
|
||||
`DOW YYYY-MM-DD HH:MM:SS` |
|
||||
`*-*-* 00:15:30` | 每年每月每天的 0 点 15 分 30 秒
|
||||
`Weekly` | 每个周一的 00:00:00
|
||||
`Mon *-*-* 00:00:00` | 同上
|
||||
`Mon` | 同上
|
||||
`Wed 2020-*-*` | 2020 年每个周三的 00:00:00
|
||||
`Mon..Fri 2021-*-*` | 2021 年的每个工作日(周一到周五)的 00:00:00
|
||||
`2022-6,7,8-1,15 01:15:00` | 2022 年 6、7、8 月的 1 到 15 号的 01:15:00
|
||||
`Mon *-05~03` | 每年五月份的下个周一同时也是月末的倒数第三天
|
||||
`Mon..Fri *-08~04` | 任何年份 8 月末的倒数第四天,同时也须是工作日
|
||||
`*-05~03/2` | 五月末的倒数第三天,然后 2 天后再来一次。每年重复一次。注意这个表达式使用了波浪号(`~`)。
|
||||
`*-05-03/2` | 五月的第三天,然后每两天重复一次直到 5 月底。注意这个表达式使用了破折号(`-`)。
|
||||
|
||||
_Table 2: `OnCalendar` 事件时间格式例子_
|
||||
|
||||
|
||||
### 测试日历格式
|
||||
|
||||
systemd 提供了一个绝佳的工具用于检测和测试定时器中日历时间事件的格式。`systemd-analyze calendar` 工具解析一个时间事件格式,提供标准格式和其他有趣的信息,例如下次“经过”(即匹配)的日期和时间,以及距离下次触发之前大概时间。
|
||||
|
||||
首先,看看未来没有时间的日(注意 `Next elapse` 和 `UTC` 的时间会根据你当地时区改变):
|
||||
|
||||
```
|
||||
[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
|
||||
Original form: 2030-06-17
|
||||
Normalized form: 2030-06-17 00:00:00
|
||||
Next elapse: Mon 2030-06-17 00:00:00 EDT
|
||||
(in UTC): Mon 2030-06-17 04:00:00 UTC
|
||||
From now: 10 years 0 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
现在添加一个时间,在这个例子中,日期和时间是当作无关的部分分开解析的:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
|
||||
Original form: 2030-06-17
|
||||
Normalized form: 2030-06-17 00:00:00
|
||||
Next elapse: Mon 2030-06-17 00:00:00 EDT
|
||||
(in UTC): Mon 2030-06-17 04:00:00 UTC
|
||||
From now: 10 years 0 months left
|
||||
|
||||
Original form: 15:21:16
|
||||
Normalized form: *-*-* 15:21:16
|
||||
Next elapse: Mon 2020-06-15 15:21:16 EDT
|
||||
(in UTC): Mon 2020-06-15 19:21:16 UTC
|
||||
From now: 3h 55min left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
为了把日期和时间当作一个单元来分析,可以把它们包在引号里。你在定时器单元里 `OnCalendar=` 时间格式中使用的时候记得把引号去掉,否则会报错:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
|
||||
Normalized form: 2030-06-17 15:21:16
|
||||
Next elapse: Mon 2030-06-17 15:21:16 EDT
|
||||
(in UTC): Mon 2030-06-17 19:21:16 UTC
|
||||
From now: 10 years 0 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
现在我们测试下 Table2 里的例子。我尤其喜欢最后一个:
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
|
||||
Original form: 2022-6,7,8-1,15 01:15:00
|
||||
Normalized form: 2022-06,07,08-01,15 01:15:00
|
||||
Next elapse: Wed 2022-06-01 01:15:00 EDT
|
||||
(in UTC): Wed 2022-06-01 05:15:00 UTC
|
||||
From now: 1 years 11 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
让我们看一个例子,这个例子里我们列出了时间表达式的五个经过时间。
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
|
||||
Original form: Mon *-05~3
|
||||
Normalized form: Mon *-05~03 00:00:00
|
||||
Next elapse: Mon 2023-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2023-05-29 04:00:00 UTC
|
||||
From now: 2 years 11 months left
|
||||
Iter. #2: Mon 2028-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2028-05-29 04:00:00 UTC
|
||||
From now: 7 years 11 months left
|
||||
Iter. #3: Mon 2034-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2034-05-29 04:00:00 UTC
|
||||
From now: 13 years 11 months left
|
||||
Iter. #4: Mon 2045-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2045-05-29 04:00:00 UTC
|
||||
From now: 24 years 11 months left
|
||||
Iter. #5: Mon 2051-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2051-05-29 04:00:00 UTC
|
||||
From now: 30 years 11 months left
|
||||
[root@testvm1 ~]#
|
||||
```
|
||||
|
||||
这些应该为你提供了足够的信息去开始测试你的 `OnCalendar` 时间格式。`systemd-analyze` 工具可用于其他有趣的分析,我会在这个系列的下一篇文章来探索这些。
|
||||
|
||||
### 总结
|
||||
|
||||
systemd 定时器可以用于执行和 cron 工具相同的任务,但是通过按照日历和单调时间格式去触发事件的方法提供了更多的灵活性。
|
||||
|
||||
虽然你为此次实验创建的服务单元通常是由定时器调用的,你也可以随时使用 `systemctl start myMonitor.service` 命令去触发它。可以在一个定时器中编写多个维护任务的脚本;它们可以是 Bash 脚本或者其他 Linux 程序。你可以通过触发定时器来运行所有的脚本来运行服务,也可以按照需要执行单独的脚本。
|
||||
|
||||
我会在下篇文章中更加深入的探索 systemd 时间格式的用处。
|
||||
|
||||
我还没有看到任何迹象表明 cron 和 at 将被废弃。我希望这种情况不会发生,因为至少 `at` 在执行一次性调度任务的时候要比 systemd 定时器容易的多。
|
||||
|
||||
### 参考资料
|
||||
|
||||
网上有大量的关于 systemd 的参考资料,但是大部分都有点简略、晦涩甚至有误导性。除了本文中提到的资料,下列的网页提供了跟多可靠且详细的 systemd 入门信息。
|
||||
|
||||
* Fedora 项目有一篇切实好用的 [systemd 入门][5],它囊括了几乎所有你需要知道的关于如何使用 systemd 配置、管理和维护 Fedora 计算机的信息。
|
||||
* Fedora 项目也有一个不错的 [备忘录][6],交叉引用了过去 SystemV 命令和 systemd 命令做对比。
|
||||
* 关于 systemd 的技术细节和创建这个项目的原因,请查看 [Freedesktop.org][7] 上的 [systemd 描述][8]。
|
||||
* [Linux.com][9] 的“更多 systemd 的乐趣”栏目提供了更多高级的 systemd [信息和技巧][10]。
|
||||
|
||||
此外,还有一系列深度的技术文章,是由 systemd 的设计者和主要实现者 Lennart Poettering 为 Linux 系统管理员撰写的。这些文章写于 2010 年 4 月至 2011 年 9 月间,但它们现在和当时一样具有现实意义。关于 systemd 及其生态的许多其他好文章都是基于这些文章:
|
||||
|
||||
* [Rethinking PID 1][11]
|
||||
* [systemd for Administrators,Part I][12]
|
||||
* [systemd for Administrators,Part II][13]
|
||||
* [systemd for Administrators,Part III][14]
|
||||
* [systemd for Administrators,Part IV][15]
|
||||
* [systemd for Administrators,Part V][16]
|
||||
* [systemd for Administrators,Part VI][17]
|
||||
* [systemd for Administrators,Part VII][18]
|
||||
* [systemd for Administrators,Part VIII][19]
|
||||
* [systemd for Administrators,Part IX][20]
|
||||
* [systemd for Administrators,Part X][21]
|
||||
* [systemd for Administrators,Part XI][22]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/7/systemd-timers
|
||||
|
||||
作者:[David Both][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[tt67wq](https://github.com/tt67wq)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dboth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/checklist_todo_clock_time_team.png?itok=1z528Q0y (Team checklist)
|
||||
[2]: https://opensource.com/article/17/11/how-use-cron-linux
|
||||
[3]: https://opensource.com/users/dboth
|
||||
[4]: https://opensource.com/article/20/5/manage-startup-systemd
|
||||
[5]: https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html
|
||||
[6]: https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet
|
||||
[7]: http://Freedesktop.org
|
||||
[8]: http://www.freedesktop.org/wiki/Software/systemd
|
||||
[9]: http://Linux.com
|
||||
[10]: https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/
|
||||
[11]: http://0pointer.de/blog/projects/systemd.html
|
||||
[12]: http://0pointer.de/blog/projects/systemd-for-admins-1.html
|
||||
[13]: http://0pointer.de/blog/projects/systemd-for-admins-2.html
|
||||
[14]: http://0pointer.de/blog/projects/systemd-for-admins-3.html
|
||||
[15]: http://0pointer.de/blog/projects/systemd-for-admins-4.html
|
||||
[16]: http://0pointer.de/blog/projects/three-levels-of-off.html
|
||||
[17]: http://0pointer.de/blog/projects/changing-roots
|
||||
[18]: http://0pointer.de/blog/projects/blame-game.html
|
||||
[19]: http://0pointer.de/blog/projects/the-new-configuration-files.html
|
||||
[20]: http://0pointer.de/blog/projects/on-etc-sysinit.html
|
||||
[21]: http://0pointer.de/blog/projects/instances.html
|
||||
[22]: http://0pointer.de/blog/projects/inetd.html
|
201
published/20201109 Getting started with Stratis encryption.md
Normal file
201
published/20201109 Getting started with Stratis encryption.md
Normal file
@ -0,0 +1,201 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13311-1.html)
|
||||
[#]: subject: (Getting started with Stratis encryption)
|
||||
[#]: via: (https://fedoramagazine.org/getting-started-with-stratis-encryption/)
|
||||
[#]: author: (briansmith https://fedoramagazine.org/author/briansmith/)
|
||||
|
||||
Stratis 加密入门
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/19/094919orzaxwl5axiqqfiu.jpg)
|
||||
|
||||
Stratis 在其 [官方网站][2] 上被描述为“_易于使用的 Linux 本地存储管理_”。请看这个 [短视频][3],快速演示基础知识。该视频是在 Red Hat Enterprise Linux 8 系统上录制的。视频中显示的概念也适用于 Fedora 中的 Stratis。
|
||||
|
||||
Stratis 2.1 版本引入了对加密的支持。继续阅读以了解如何在 Stratis 中开始加密。
|
||||
|
||||
### 先决条件
|
||||
|
||||
加密需要 Stratis 2.1 或更高版本。这篇文章中的例子使用的是 Fedora 33 的预发布版本。Stratis 2.1 将用在 Fedora 33 的最终版本中。
|
||||
|
||||
你还需要至少一个可用的块设备来创建一个加密池。下面的例子是在 KVM 虚拟机上完成的,虚拟磁盘驱动器为 5GB(`/dev/vdb`)。
|
||||
|
||||
### 在内核密钥环中创建一个密钥
|
||||
|
||||
Linux 内核<ruby>密钥环<rt>keyring</rt></ruby>用于存储加密密钥。关于内核密钥环的更多信息,请参考 `keyrings` 手册页(`man keyrings`)。
|
||||
|
||||
使用 `stratis key set` 命令在内核钥匙圈中设置密钥。你必须指定从哪里读取密钥。要从标准输入中读取密钥,使用 `-capture-key` 选项。要从文件中读取密钥,使用 `-keyfile-path <file>` 选项。最后一个参数是一个密钥描述。它将稍后你创建加密的 Stratis 池时使用。
|
||||
|
||||
例如,要创建一个描述为 `pool1key` 的密钥,并从标准输入中读取密钥,可以输入:
|
||||
|
||||
```
|
||||
# stratis key set --capture-key pool1key
|
||||
Enter desired key data followed by the return key:
|
||||
```
|
||||
|
||||
该命令提示我们输入密钥数据/密码,然后密钥就创建在内核密钥环中了。
|
||||
|
||||
要验证密钥是否已被创建,运行 `stratis key list`:
|
||||
|
||||
```
|
||||
# stratis key list
|
||||
Key Description
|
||||
pool1key
|
||||
```
|
||||
|
||||
这将验证是否创建了 `pool1key`。请注意,这些密钥不是持久的。如果主机重启,在访问加密的 Stratis 池之前,需要再次提供密钥(此过程将在后面介绍)。
|
||||
|
||||
如果你有多个加密池,它们可以有一个单独的密钥,也可以共享同一个密钥。
|
||||
|
||||
也可以使用以下 `keyctl` 命令查看密钥:
|
||||
|
||||
```
|
||||
# keyctl get_persistent @s
|
||||
318044983
|
||||
# keyctl show
|
||||
Session Keyring
|
||||
701701270 --alswrv 0 0 keyring: _ses
|
||||
649111286 --alswrv 0 65534 \_ keyring: _uid.0
|
||||
318044983 ---lswrv 0 65534 \_ keyring: _persistent.0
|
||||
1051260141 --alswrv 0 0 \_ user: stratis-1-key-pool1key
|
||||
```
|
||||
|
||||
### 创建加密的 Stratis 池
|
||||
|
||||
现在已经为 Stratis 创建了一个密钥,下一步是创建加密的 Stratis 池。加密池只能在创建池时进行。目前不可能对现有的池进行加密。
|
||||
|
||||
使用 `stratis pool create` 命令创建一个池。添加 `-key-desc` 和你在上一步提供的密钥描述(`pool1key`)。这将向 Stratis 发出信号,池应该使用提供的密钥进行加密。下面的例子是在 `/dev/vdb` 上创建 Stratis 池,并将其命名为 `pool1`。确保在你的系统中指定一个空的/可用的设备。
|
||||
|
||||
```
|
||||
# stratis pool create --key-desc pool1key pool1 /dev/vdb
|
||||
```
|
||||
|
||||
你可以使用 `stratis pool list` 命令验证该池是否已经创建:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
pool1 4.98 GiB / 37.63 MiB / 4.95 GiB ~Ca, Cr
|
||||
```
|
||||
|
||||
在上面显示的示例输出中,`~Ca` 表示禁用了缓存(`~` 否定了该属性)。`Cr` 表示启用了加密。请注意,缓存和加密是相互排斥的。这两个功能不能同时启用。
|
||||
|
||||
接下来,创建一个文件系统。下面的例子演示了创建一个名为 `filesystem1` 的文件系统,将其挂载在 `/filesystem1` 挂载点上,并在新文件系统中创建一个测试文件:
|
||||
|
||||
```
|
||||
# stratis filesystem create pool1 filesystem1
|
||||
# mkdir /filesystem1
|
||||
# mount /stratis/pool1/filesystem1 /filesystem1
|
||||
# cd /filesystem1
|
||||
# echo "this is a test file" > testfile
|
||||
```
|
||||
|
||||
### 重启后访问加密池
|
||||
|
||||
当重新启动时,你会发现 Stratis 不再显示你的加密池或它的块设备:
|
||||
|
||||
```
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
```
|
||||
|
||||
```
|
||||
# stratis blockdev list
|
||||
Pool Name Device Node Physical Size Tier
|
||||
```
|
||||
|
||||
要访问加密池,首先要用之前使用的相同的密钥描述和密钥数据/口令重新创建密钥:
|
||||
|
||||
```
|
||||
# stratis key set --capture-key pool1key
|
||||
Enter desired key data followed by the return key:
|
||||
```
|
||||
|
||||
接下来,运行 `stratis pool unlock` 命令,并验证现在可以看到池和它的块设备:
|
||||
|
||||
```
|
||||
# stratis pool unlock
|
||||
# stratis pool list
|
||||
Name Total Physical Properties
|
||||
pool1 4.98 GiB / 583.65 MiB / 4.41 GiB ~Ca, Cr
|
||||
# stratis blockdev list
|
||||
Pool Name Device Node Physical Size Tier
|
||||
pool1 /dev/dm-2 4.98 GiB Data
|
||||
```
|
||||
|
||||
接下来,挂载文件系统并验证是否可以访问之前创建的测试文件:
|
||||
|
||||
```
|
||||
# mount /stratis/pool1/filesystem1 /filesystem1/
|
||||
# cat /filesystem1/testfile
|
||||
this is a test file
|
||||
```
|
||||
|
||||
### 使用 systemd 单元文件在启动时自动解锁 Stratis 池
|
||||
|
||||
可以在启动时自动解锁 Stratis 池,无需手动干预。但是,必须有一个包含密钥的文件。在某些环境下,将密钥存储在文件中可能会有安全问题。
|
||||
|
||||
下图所示的 systemd 单元文件提供了一个简单的方法来在启动时解锁 Stratis 池并挂载文件系统。欢迎提供更好的/替代方法的反馈。你可以在文章末尾的评论区提供建议。
|
||||
|
||||
首先用下面的命令创建你的密钥文件。确保用之前输入的相同的密钥数据/密码来代替`passphrase`。
|
||||
|
||||
```
|
||||
# echo -n passphrase > /root/pool1key
|
||||
```
|
||||
|
||||
确保该文件只能由 root 读取:
|
||||
|
||||
```
|
||||
# chmod 400 /root/pool1key
|
||||
# chown root:root /root/pool1key
|
||||
```
|
||||
|
||||
在 `/etc/systemd/system/stratis-filesystem1.service` 创建包含以下内容的 systemd 单元文件:
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description = stratis mount pool1 filesystem1 file system
|
||||
After = stratisd.service
|
||||
|
||||
[Service]
|
||||
ExecStartPre=sleep 2
|
||||
ExecStartPre=stratis key set --keyfile-path /root/pool1key pool1key
|
||||
ExecStartPre=stratis pool unlock
|
||||
ExecStartPre=sleep 3
|
||||
ExecStart=mount /stratis/pool1/filesystem1 /filesystem1
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy = multi-user.target
|
||||
```
|
||||
|
||||
接下来,启用服务,使其在启动时运行:
|
||||
|
||||
```
|
||||
# systemctl enable stratis-filesystem1.service
|
||||
```
|
||||
|
||||
现在重新启动并验证 Stratis 池是否已自动解锁,其文件系统是否已挂载。
|
||||
|
||||
### 结语
|
||||
|
||||
在今天的环境中,加密是很多人和组织的必修课。本篇文章演示了如何在 Stratis 2.1 中启用加密功能。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/getting-started-with-stratis-encryption/
|
||||
|
||||
作者:[briansmith][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://fedoramagazine.org/author/briansmith/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/11/stratis-encryption-2-816x345.jpg
|
||||
[2]: https://stratis-storage.github.io/
|
||||
[3]: https://www.youtube.com/watch?v=CJu3kmY-f5o
|
134
published/20201209 Program a simple game with Elixir.md
Normal file
134
published/20201209 Program a simple game with Elixir.md
Normal file
@ -0,0 +1,134 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (tt67wq)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13292-1.html)
|
||||
[#]: subject: (Program a simple game with Elixir)
|
||||
[#]: via: (https://opensource.com/article/20/12/elixir)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
使用 Elixir 语言编写一个小游戏
|
||||
======
|
||||
|
||||
> 通过编写“猜数字”游戏来学习 Elixir 编程语言,并将它与一个你熟知的语言做对比。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/12/223351t68886wmza1m9jnt.jpg)
|
||||
|
||||
为了更好的学习一门新的编程语言,最好的方法是去关注主流语言的一些共有特征:
|
||||
|
||||
* 变量
|
||||
* 表达式
|
||||
* 语句
|
||||
|
||||
这些概念是大多数编程语言的基础。因为这些相似性,只要你通晓了一门编程语言,你可以通过对比差异来熟知另一门编程语言。
|
||||
|
||||
另外一个学习新编程语言的好方法是开始编写一个简单标准的程序。它可以让你集中精力在语言上而非程序的逻辑本身。在这个系列的文章中,我们使用“猜数字”程序来实现,在这个程序中,计算机会选择一个介于 1 到 100 之间的数字,并要求你来猜测它。程序会循环执行,直到你正确猜出该数字为止。
|
||||
|
||||
“猜数字”这个程序使用了编程语言的以下概念:
|
||||
|
||||
* 变量
|
||||
* 输入
|
||||
* 输出
|
||||
* 条件判断
|
||||
* 循环
|
||||
|
||||
这是一个学习新编程语言的绝佳实践。
|
||||
|
||||
### 猜数字的 Elixir 实现
|
||||
|
||||
[Elixir][2] 是一门被设计用于构建稳定可维护应用的动态类型的函数式编程语言。它与 [Erlang][3] 运行于同一虚拟机之上,吸纳了 Erlang 的众多长处的同时拥有更加简单的语法。
|
||||
|
||||
你可以编写一个 Elixir 版本的“猜数字”游戏来体验这门语言。
|
||||
|
||||
这是我的实现方法:
|
||||
|
||||
```
|
||||
defmodule Guess do
|
||||
def guess() do
|
||||
random = Enum.random(1..100)
|
||||
IO.puts "Guess a number between 1 and 100"
|
||||
Guess.guess_loop(random)
|
||||
end
|
||||
def guess_loop(num) do
|
||||
data = IO.read(:stdio, :line)
|
||||
{guess, _rest} = Integer.parse(data)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
Guess.guess()
|
||||
```
|
||||
|
||||
Elixir 通过列出变量的名称后面跟一个 `=` 号来为了给变量分配一个值。举个例子,表达式 `random = 0` 给 `random` 变量分配一个数值 0。
|
||||
|
||||
代码以定义一个模块开始。在 Elixir 语言中,只有模块可以包含命名函数。
|
||||
|
||||
紧随其后的这行代码定义了入口函数 `guess()`,这个函数:
|
||||
|
||||
* 调用 `Enum.random()` 函数来获取一个随机整数
|
||||
* 打印游戏提示
|
||||
* 调用循环执行的函数
|
||||
|
||||
剩余的游戏逻辑实现在 `guess_loop()` 函数中。
|
||||
|
||||
`guess_loop()` 函数利用 [尾递归][4] 来实现循环。Elixir 中有好几种实现循环的方法,尾递归是比较常用的一种方式。`guess_loop()` 函数做的最后一件事就是调用自身。
|
||||
|
||||
`guess_loop()` 函数的第一行读取用户输入。下一行调用 `parse()` 函数将输入转换成一个整数。
|
||||
|
||||
`cond` 表达式是 Elixir 版本的多重分支表达式。与其他语言中的 `if/elif` 或者 `if/elsif` 表达式不同,Elixir 对于的首个分支或者最后一个没有分支并没有区别对待。
|
||||
|
||||
这个 `cond` 表达式有三路分支:猜测的结果可以比随机数大、小或者相等。前两个选项先输出不等式的方向然后递归调用 `guess_loop()`,循环返回至函数开始。最后一个选项输出 `That's right`,然后这个函数就完成了。
|
||||
|
||||
### 输出例子
|
||||
|
||||
现在你已经编写了你的 Elixir 代码,你可以运行它来玩“猜数字”的游戏。每次你执行这个程序,Elixir 会选择一个不同的随机数,你可以一直猜下去直到你找到正确的答案:
|
||||
|
||||
```
|
||||
$ elixir guess.exs
|
||||
Guess a number between 1 and 100
|
||||
50
|
||||
Too high
|
||||
30
|
||||
Too high
|
||||
20
|
||||
Too high
|
||||
10
|
||||
Too low
|
||||
15
|
||||
Too high
|
||||
13
|
||||
Too low
|
||||
14
|
||||
That's right!
|
||||
```
|
||||
|
||||
“猜数字”游戏是一个学习一门新编程语言的绝佳入门程序,因为它用了非常直接的方法实践了常用的几个编程概念。通过用不同语言实现这个简单的小游戏,你可以实践各个语言的核心概念并且比较它们的细节。
|
||||
|
||||
你是否有你最喜爱的编程语言?你将怎样用它来编写“猜数字”这个游戏?关注这个系列的文章来看看其他你可能感兴趣的语言实现。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/elixir
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[tt67wq](https://github.com/tt67wq)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/dice_tabletop_board_gaming_game.jpg?itok=y93eW7HN (A die with rainbow color background)
|
||||
[2]: https://elixir-lang.org/
|
||||
[3]: https://www.erlang.org/
|
||||
[4]: https://en.wikipedia.org/wiki/Tail_call
|
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 将如何激发你为这个社区做出贡献呢?
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/10/131305ei6yyuyujui9fkkr.jpg)
|
||||
|
||||
到了 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 为你做。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/06/084133bphrxxeolhoyqr0o.jpg)
|
||||
|
||||
在 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
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13242-1.html)
|
||||
[#]: subject: (How to automate your cryptocurrency trades with Python)
|
||||
[#]: via: (https://opensource.com/article/20/4/python-crypto-trading-bot)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
@ -11,11 +11,11 @@
|
||||
如何使用 Python 来自动交易加密货币
|
||||
======
|
||||
|
||||
在本教程中,教你如何设置和使用 Pythonic 来编程。它是一个图形化编程工具,用户可以很容易地使用现成的函数模块创建 Python 程序。
|
||||
> 在本教程中,教你如何设置和使用 Pythonic 来编程。它是一个图形化编程工具,用户可以很容易地使用现成的函数模块创建 Python 程序。
|
||||
|
||||
![scientific calculator][1]
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/28/093858qu0bh3w2sd3rh20s.jpg)
|
||||
|
||||
然而,不像纽约证券交易所这样的传统证券交易所一样,有一段固定的交易时间。对于加密货币而言,则是 7×24 小时交易,任何人都无法独自盯着市场。
|
||||
然而,不像纽约证券交易所这样的传统证券交易所一样,有一段固定的交易时间。对于加密货币而言,则是 7×24 小时交易,这使得任何人都无法独自盯着市场。
|
||||
|
||||
在以前,我经常思考与加密货币交易相关的问题:
|
||||
|
||||
@ -24,21 +24,19 @@
|
||||
- 为什么下单?
|
||||
- 为什么不下单?
|
||||
|
||||
通常的解决手段是当在你做其他事情时,例如睡觉、与家人在一起或享受空闲时光,使用加密交易机器人代替你下单。虽然有很多商业解决方案可用,但是我选择开源的解决方案,因此我编写了加密交易机器人 [Pythonic][2]。 正如去年 [我写过的文章][3] 一样,“ Pythonic 是一种图形化编程工具,它让用户可以轻松使用现成的功能模块来创建Python应用程序。” 最初它是作为加密货币机器人使用,并具有可扩展的日志记录引擎以及经过精心测试的可重用部件,例如调度器和计时器。
|
||||
通常的解决手段是使用加密交易机器人,当在你做其他事情时,例如睡觉、与家人在一起或享受空闲时光,代替你下单。虽然有很多商业解决方案可用,但是我选择开源的解决方案,因此我编写了加密交易机器人 [Pythonic][2]。 正如去年 [我写过的文章][3] 一样,“Pythonic 是一种图形化编程工具,它让用户可以轻松使用现成的函数模块来创建 Python 应用程序。” 最初它是作为加密货币机器人使用,并具有可扩展的日志记录引擎以及经过精心测试的可重用部件,例如调度器和计时器。
|
||||
|
||||
### 开始
|
||||
|
||||
本教程将教你如何开始使用 Pythonic 进行自动交易。我选择 [币安][6]Binance<ruby>[币安][6]<rt>Binance</rt></ruby> 交易所的 [波场][4]Tron<ruby>[波场][4]<rt>Tron</rt></ruby> 与 [比特币][3]Bitcoin<ruby>[比特币][3]<rt>Bitcoin</rt></ruby>
|
||||
本教程将教你如何开始使用 Pythonic 进行自动交易。我选择 <ruby>[币安][6]<rt>Binance</rt></ruby> 交易所的 <ruby>[波场][4]<rt>Tron</rt></ruby> 与 <ruby>[比特币][3]<rt>Bitcoin</rt></ruby> 交易对为例。我之所以选择这个加密货币对,是因为它们彼此之间的波动性大,而不是出于个人喜好。
|
||||
|
||||
交易对为例。我之所以选择这些加密货币,是因为它们彼此之间的波动性大,而不是出于个人喜好。
|
||||
|
||||
机器人将根据 [指数移动平均][7] (EMAs)来做出决策。
|
||||
机器人将根据 <ruby>[指数移动平均][7]<rt>exponential moving averages</rt></ruby> (EMA)来做出决策。
|
||||
|
||||
![TRX/BTC 1-hour candle chart][8]
|
||||
|
||||
TRX/BTC 1 小时 K 线图
|
||||
*TRX/BTC 1 小时 K 线图*
|
||||
|
||||
EMA 指标通常是指加权移动平均线,可以对近期价格数据赋予更多权重。尽管移动平均线可能只是一个简单的指标,但我能熟练使用它。
|
||||
EMA 指标通常是一个加权的移动平均线,可以对近期价格数据赋予更多权重。尽管移动平均线可能只是一个简单的指标,但我对它很有经验。
|
||||
|
||||
上图中的紫色线显示了 EMA-25 指标(这表示要考虑最近的 25 个值)。
|
||||
|
||||
@ -48,20 +46,16 @@ EMA 指标通常是指加权移动平均线,可以对近期价格数据赋予
|
||||
|
||||
### 工具链
|
||||
|
||||
|
||||
|
||||
将在本教程使用如下工具:
|
||||
|
||||
- 币安专业交易视图(已经有其他人做了数据可视化,所以不需要重复造轮子)
|
||||
- Jupyter Notebook:用于数据科学任务
|
||||
- Jupyter 笔记本:用于数据科学任务
|
||||
- Pythonic:作为整体框架
|
||||
- PythonicDaemon :作为终端运行(仅适用于控制台和 Linux)
|
||||
|
||||
|
||||
|
||||
### 数据挖掘
|
||||
|
||||
为了使加密货币交易机器人尽可能能做出正确的决定,以可靠的方式获取资产的美国线([OHLC][9])数据是至关重要。你可以使用 Pythonic 的内置元素,还可以根据自己逻辑来对其进行扩展。
|
||||
为了使加密货币交易机器人尽可能做出正确的决定,以可靠的方式获取资产的<ruby>美国线<rt>open-high-low-close chart</rt></ruby>([OHLC][9])数据是至关重要。你可以使用 Pythonic 的内置元素,还可以根据自己逻辑来对其进行扩展。
|
||||
|
||||
一般的工作流程:
|
||||
|
||||
@ -70,31 +64,28 @@ EMA 指标通常是指加权移动平均线,可以对近期价格数据赋予
|
||||
3. 从文件中把 OHLC 数据加载到内存
|
||||
4. 比较数据集并扩展更新数据集
|
||||
|
||||
|
||||
|
||||
这个工作流程可能有点夸张,但是它能使得程序更加健壮,甚至在停机和断开连接时,也能平稳运行。
|
||||
|
||||
一开始,你需要 **币安 OHLC 查询**Binance OHLC Query<ruby>**币安 OHLC 查询**<rt>Binance OHLC Query</rt></ruby> 元素和一个 **基础操作**Basic Operation<ruby>**基础操作**<rt>Basic Operation</rt></ruby> 元素来执行你的代码。
|
||||
一开始,你需要 <ruby>**币安 OHLC 查询**<rt>Binance OHLC Query</rt></ruby> 元素和一个 <ruby>**基础操作**<rt>Basic Operation</rt></ruby> 元素来执行你的代码。
|
||||
|
||||
![Data-mining workflow][10]
|
||||
|
||||
数据挖掘工作流程
|
||||
*数据挖掘工作流程*
|
||||
|
||||
OHLC 查询设置为每隔一小时查询一次 **TRXBTC** 资产对(波场/比特币)。
|
||||
|
||||
![Configuration of the OHLC query element][11]
|
||||
|
||||
配置 OHLC 查询元素
|
||||
*配置 OHLC 查询元素*
|
||||
|
||||
其中输出的元素是 [Pandas DataFrame][12]。你可以在 **基础操作** 元素中使用 **输入**input<ruby>**输入**<rt>input</rt></ruby> 变量来访问 DataFrame。其中,将 Vim 设置为 **基础操作** 元素的默认代码编辑器。
|
||||
其中输出的元素是 [Pandas DataFrame][12]。你可以在 **基础操作** 元素中使用 <ruby>**输入**<rt>input</rt></ruby> 变量来访问 DataFrame。其中,将 Vim 设置为 **基础操作** 元素的默认代码编辑器。
|
||||
|
||||
![Basic Operation element set up to use Vim][13]
|
||||
|
||||
使用 Vim 编辑基础操作元素
|
||||
*使用 Vim 编辑基础操作元素*
|
||||
|
||||
具体代码如下:
|
||||
|
||||
|
||||
```
|
||||
import pickle, pathlib, os
|
||||
import pandas as pd
|
||||
@ -121,38 +112,38 @@ if isinstance(input, pd.DataFrame):
|
||||
output = df
|
||||
```
|
||||
|
||||
首先,检查输入是否为 DataFrame 元素。然后在用户的家目录(**〜/ **)中查找名为 **TRXBTC_1h.bin** 的文件。如果存在,则将其打开,执行新代码段(**try** 部分中的代码),并删除重复项。如果文件不存在,则触发异常并执行 **except** 部分中的代码,创建一个新文件。
|
||||
首先,检查输入是否为 DataFrame 元素。然后在用户的家目录(`~/`)中查找名为 `TRXBTC_1h.bin` 的文件。如果存在,则将其打开,执行新代码段(`try` 部分中的代码),并删除重复项。如果文件不存在,则触发异常并执行 `except` 部分中的代码,创建一个新文件。
|
||||
|
||||
只要启用了复选框 **日志输出**log output<ruby>**日志输出**<rt>log output</rt></ruby>,你就可以使用命令行工具 **tail** 查看日志记录:
|
||||
只要启用了复选框 <ruby>**日志输出**<rt>log output</rt></ruby>,你就可以使用命令行工具 `tail` 查看日志记录:
|
||||
|
||||
|
||||
```
|
||||
`$ tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txt`
|
||||
$ tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txt
|
||||
```
|
||||
|
||||
出于开发目的,现在跳过与币安时间的同步和计划执行,这将在下面实现。
|
||||
|
||||
### 准备数据
|
||||
|
||||
下一步是在单独的 网格Grid<ruby>网格<rt>Grid</rt></ruby> 中处理评估逻辑。因此,你必须借助 **返回元素**Return element<ruby>**返回元素**<rt>Return element</rt></ruby> 将 DataFrame 从网格 1 传递到网格 2 的第一个元素。
|
||||
下一步是在单独的 <ruby>网格<rt>Grid</rt></ruby> 中处理评估逻辑。因此,你必须借助<ruby>**返回元素**<rt>Return element</rt></ruby> 将 DataFrame 从网格 1 传递到网格 2 的第一个元素。
|
||||
|
||||
在网格 2 中,通过使 DataFrame 通过 **基础技术分析**Basic Technical Analysis<ruby>**基础技术分析**<rt>Basic Technical Analysis</rt></ruby> 元素,将 DataFrame 扩展包含 EMA 值的一列。
|
||||
在网格 2 中,通过使 DataFrame 通过 <ruby>**基础技术分析**<rt>Basic Technical Analysis</rt></ruby> 元素,将 DataFrame 扩展包含 EMA 值的一列。
|
||||
|
||||
![Technical analysis workflow in Grid 2][14]
|
||||
|
||||
在网格 2 中技术分析工作流程
|
||||
*在网格 2 中技术分析工作流程*
|
||||
|
||||
配置技术分析元素以计算 25 个值的 EMAs。
|
||||
配置技术分析元素以计算 25 个值的 EMA。
|
||||
|
||||
![Configuration of the technical analysis element][15]
|
||||
|
||||
配置技术分析元素
|
||||
*配置技术分析元素*
|
||||
|
||||
当你运行整个程序并开启 **技术分析**Technical Analysis<ruby>**技术分析**<rt>Technical Analysis</rt></ruby> 元素的调试输出时,你将发现 EMA-25 列的值似乎都相同。
|
||||
当你运行整个程序并开启 <ruby>**技术分析**<rt>Technical Analysis</rt></ruby> 元素的调试输出时,你将发现 EMA-25 列的值似乎都相同。
|
||||
|
||||
![Missing decimal places in output][16]
|
||||
|
||||
输出中精度不够
|
||||
*输出中精度不够*
|
||||
|
||||
这是因为调试输出中的 EMA-25 值仅包含六位小数,即使输出保留了 8 个字节完整精度的浮点值。
|
||||
|
||||
@ -160,31 +151,31 @@ if isinstance(input, pd.DataFrame):
|
||||
|
||||
![Workflow in Grid 2][17]
|
||||
|
||||
网格 2 中的工作流程
|
||||
*网格 2 中的工作流程*
|
||||
|
||||
使用 **基础操作** 元素,将 DataFrame 与添加的 EMA-25 列一起转储,以便可以将其加载到 Jupyter Notebook中;
|
||||
使用 **基础操作** 元素,将 DataFrame 与添加的 EMA-25 列一起转储,以便可以将其加载到 Jupyter 笔记本中;
|
||||
|
||||
![Dump extended DataFrame to file][18]
|
||||
|
||||
将扩展后的 DataFrame 存储到文件中
|
||||
*将扩展后的 DataFrame 存储到文件中*
|
||||
|
||||
### 评估策略
|
||||
|
||||
在 Juypter Notebook 中开发评估策略,让你可以更直接地访问代码。要加载 DataFrame,你需要使用如下代码:
|
||||
在 Juypter 笔记本中开发评估策略,让你可以更直接地访问代码。要加载 DataFrame,你需要使用如下代码:
|
||||
|
||||
![Representation with all decimal places][19]
|
||||
|
||||
用全部小数位表示
|
||||
*用全部小数位表示*
|
||||
|
||||
你可以使用 [**iloc**][20] 和列名来访问最新的 EMA-25 值,并且会保留所有小数位。
|
||||
你可以使用 [iloc][20] 和列名来访问最新的 EMA-25 值,并且会保留所有小数位。
|
||||
|
||||
你已经知道如何来获得最新的数据。上面示例的最后一行仅显示该值。为了能将该值拷贝到不同的变量中,你必须使用如下图所示的 **.at** 方法方能成功。
|
||||
你已经知道如何来获得最新的数据。上面示例的最后一行仅显示该值。为了能将该值拷贝到不同的变量中,你必须使用如下图所示的 `.at` 方法方能成功。
|
||||
|
||||
你也可以直接计算出你下一步所需的交易参数。
|
||||
|
||||
![Buy/sell decision][21]
|
||||
|
||||
买卖决策
|
||||
*买卖决策*
|
||||
|
||||
### 确定交易参数
|
||||
|
||||
@ -194,31 +185,31 @@ if isinstance(input, pd.DataFrame):
|
||||
|
||||
![Validation function][22]
|
||||
|
||||
回测功能
|
||||
*回测功能*
|
||||
|
||||
在此示例中,**buy_factor** 和 **sell_factor** 是预先定义好的。因此,发散思维用直接计算出表现最佳的参数。
|
||||
在此示例中,`buy_factor` 和 `sell_factor` 是预先定义好的。因此,发散思维用直接计算出表现最佳的参数。
|
||||
|
||||
![Nested for loops for determining the buy and sell factor][23]
|
||||
|
||||
嵌套的 _for_ 循环,用于确定购买和出售的参数
|
||||
*嵌套的 for 循环,用于确定购买和出售的参数*
|
||||
|
||||
这要跑 81 个循环(9x9),在我的机器(Core i7 267QM)上花费了几分钟。
|
||||
|
||||
![System utilization while brute forcing][24]
|
||||
|
||||
在暴力运算时系统的利用率
|
||||
*在暴力运算时系统的利用率*
|
||||
|
||||
在每个循环之后,它将 **buy_factor**,**sell_factor** 元组和生成的 **利润**profit<ruby>**利润**<rt>profit</rt></ruby> 元组追加到 **trading_factors** 列表中。按利润降序对列表进行排序。
|
||||
在每个循环之后,它将 `buy_factor`、`sell_factor` 元组和生成的 `profit` 元组追加到 `trading_factors` 列表中。按利润降序对列表进行排序。
|
||||
|
||||
![Sort profit with related trading factors in descending order][25]
|
||||
|
||||
将利润与相关的交易参数按降序排序
|
||||
*将利润与相关的交易参数按降序排序*
|
||||
|
||||
当你打印出列表时,你会看到 0.002 是最好的参数。
|
||||
|
||||
![Sorted list of trading factors and profit][26]
|
||||
|
||||
交易要素和收益的有序列表
|
||||
*交易要素和收益的有序列表*
|
||||
|
||||
当我在 2020 年 3 月写下这篇文章时,价格的波动还不足以呈现出更理想的结果。我在 2 月份得到了更好的结果,但即使在那个时候,表现最好的交易参数也在 0.002 左右。
|
||||
|
||||
@ -230,73 +221,73 @@ if isinstance(input, pd.DataFrame):
|
||||
|
||||
![Implemented evaluation logic][27]
|
||||
|
||||
实现评估策略
|
||||
*实现评估策略*
|
||||
|
||||
如果输出 **1** 表示你应该购买,如果输出 **2** 则表示你应该卖出。 输出 **0** 表示现在无需操作。使用 **分支**Branch<ruby>**分支**<rt>Branch</rt></ruby> 元素来控制执行路径。
|
||||
如果输出 `1` 表示你应该购买,如果输出 `2` 则表示你应该卖出。 输出 `0` 表示现在无需操作。使用 <ruby>**分支**<rt>Branch</rt></ruby> 元素来控制执行路径。
|
||||
|
||||
![Branch element: Grid 3 Position 2A][28]
|
||||
|
||||
Branch 元素:网格 3,2A 位置
|
||||
*分支元素:网格 3,2A 位置*
|
||||
|
||||
|
||||
|
||||
因为 **0** 和 **-1** 的处理流程一样,所以你需要在最右边添加一个分支元素来判断你是否应该卖出。
|
||||
因为 `0` 和 `-1` 的处理流程一样,所以你需要在最右边添加一个分支元素来判断你是否应该卖出。
|
||||
|
||||
![Branch element: Grid 3 Position 3B][29]
|
||||
|
||||
分支元素:网格 3,3B 位置
|
||||
*分支元素:网格 3,3B 位置*
|
||||
|
||||
网格 3 应该现在如下图所示:
|
||||
|
||||
![Workflow on Grid 3][30]
|
||||
|
||||
网格 3 的工作流程
|
||||
*网格 3 的工作流程*
|
||||
|
||||
### 下单
|
||||
|
||||
由于无需在一个周期中购买两次,因此必须在周期之间保留一个持久变量,以指示你是否已经购买。
|
||||
|
||||
你可以利用 **栈**Stack<ruby>**栈**<rt>Stack</rt></ruby> 元素来实现。顾名思义,栈元素表示可以用任何 Python 数据类型来放入的基于文件的栈。
|
||||
你可以利用 <ruby>**栈**<rt>Stack</rt></ruby> 元素来实现。顾名思义,栈元素表示可以用任何 Python 数据类型来放入的基于文件的栈。
|
||||
|
||||
你需要定义栈仅包含一个布尔类型,该布尔类型决定是否购买了(**True**)或(**False**)。因此,你必须使用 **False** 来初始化栈。例如,你可以在网格 4 中简单地通过将 **False** 传递给栈来进行设置。![Forward a False-variable to the subsequent Stack element][31]
|
||||
你需要定义栈仅包含一个布尔类型,该布尔类型决定是否购买了(`True`)或(`False`)。因此,你必须使用 `False` 来初始化栈。例如,你可以在网格 4 中简单地通过将 `False` 传递给栈来进行设置。
|
||||
|
||||
将 **False** 变量传输到后续的栈元素中
|
||||
![Forward a False-variable to the subsequent Stack element][31]
|
||||
|
||||
*将 False 变量传输到后续的栈元素中*
|
||||
|
||||
在分支树后的栈实例可以进行如下配置:
|
||||
|
||||
![Configuration of the Stack element][32]
|
||||
|
||||
设置栈元素
|
||||
*设置栈元素*
|
||||
|
||||
在栈元素设置中,将 **Do this with input** 设置成 **Nothing**。否则,布尔值将被 1 或 0 覆盖。
|
||||
在栈元素设置中,将 <ruby>对输入的操作<rt>Do this with input</rt></ruby> 设置成 <ruby>无<rt>Nothing</rt></ruby>。否则,布尔值将被 `1` 或 `0` 覆盖。
|
||||
|
||||
该设置确保仅将一个值保存于栈中(**True** 或 **False**),并且只能读取一个值(为了清楚起见)。
|
||||
该设置确保仅将一个值保存于栈中(`True` 或 `False`),并且只能读取一个值(为了清楚起见)。
|
||||
|
||||
在栈元素之后,你需要另外一个 **分支** 元素来判断栈的值,然后再放置 **币安订单**Binance Order<ruby>**币安订单**<rt>Binance Order</rt></ruby> 元素。
|
||||
在栈元素之后,你需要另外一个 **分支** 元素来判断栈的值,然后再放置 <ruby>币安订单<rt>Binance Order</rt></ruby> 元素。
|
||||
|
||||
![Evaluate the variable from the stack][33]
|
||||
|
||||
判断栈中的变量
|
||||
*判断栈中的变量*
|
||||
|
||||
将币安订单元素添加到分支元素的 **True** 路径。网格 3 上的工作流现在应如下所示:
|
||||
将币安订单元素添加到分支元素的 `True` 路径。网格 3 上的工作流现在应如下所示:
|
||||
|
||||
![Workflow on Grid 3][34]
|
||||
|
||||
网格 3 的工作流程
|
||||
*网格 3 的工作流程*
|
||||
|
||||
币安订单元素应如下配置:
|
||||
|
||||
![Configuration of the Binance Order element][35]
|
||||
|
||||
编辑币安订单元素
|
||||
*编辑币安订单元素*
|
||||
|
||||
你可以在币安网站上的帐户设置中生成 API 和密钥。
|
||||
|
||||
![Creating an API key in Binance][36]
|
||||
|
||||
在币安账户设置中创建一个 API key
|
||||
*在币安账户设置中创建一个 API 密钥*
|
||||
|
||||
在本文中,每笔交易都是作为市价交易执行的,交易量为10,000 TRX(2020 年 3 月约为 150 美元)(出于教学的目的,我通过使用市价下单来演示整个过程。因此,我建议至少使用限价下单。)
|
||||
在本文中,每笔交易都是作为市价交易执行的,交易量为 10,000 TRX(2020 年 3 月约为 150 美元)(出于教学的目的,我通过使用市价下单来演示整个过程。因此,我建议至少使用限价下单。)
|
||||
|
||||
如果未正确执行下单(例如,网络问题、资金不足或货币对不正确),则不会触发后续元素。因此,你可以假定如果触发了后续元素,则表示该订单已下达。
|
||||
|
||||
@ -304,7 +295,7 @@ Branch 元素:网格 3,2A 位置
|
||||
|
||||
![Output of a successfully placed sell order][37]
|
||||
|
||||
成功卖单的输出
|
||||
*成功卖单的输出*
|
||||
|
||||
该行为使后续步骤更加简单:你可以始终假设只要成功输出,就表示订单成功。因此,你可以添加一个 **基础操作** 元素,该元素将简单地输出 **True** 并将此值放入栈中以表示是否下单。
|
||||
|
||||
@ -312,21 +303,21 @@ Branch 元素:网格 3,2A 位置
|
||||
|
||||
![Logging output of Binance Order element][38]
|
||||
|
||||
币安订单元素中的输出日志信息
|
||||
*币安订单元素中的输出日志信息*
|
||||
|
||||
### 调度和同步
|
||||
|
||||
对于日程调度和同步,请在网格 1 中将整个工作流程置于 **币安调度器**Binance Scheduler<ruby>**币安调度器**<rt>Binance Scheduler</rt></ruby> 元素的前面。
|
||||
对于日程调度和同步,请在网格 1 中将整个工作流程置于 <ruby>币安调度器<rt>Binance Scheduler</rt></ruby> 元素的前面。
|
||||
|
||||
![Binance Scheduler at Grid 1, Position 1A][39]
|
||||
|
||||
在网格 1,1A 位置的币安调度器
|
||||
*在网格 1,1A 位置的币安调度器*
|
||||
|
||||
由于币安调度器元素只执行一次,因此请在网格 1 的末尾拆分执行路径,并通过将输出传递回币安调度器来强制让其重新同步。
|
||||
|
||||
![Grid 1: Split execution path][40]
|
||||
|
||||
网格 1:拆分执行路径
|
||||
*网格 1:拆分执行路径*
|
||||
|
||||
5A 元素指向 网格 2 的 1A 元素,并且 5B 元素指向网格 1 的 1A 元素(币安调度器)。
|
||||
|
||||
@ -336,40 +327,34 @@ Branch 元素:网格 3,2A 位置
|
||||
|
||||
![PythonicDaemon console interface][41]
|
||||
|
||||
PythonicDaemon 控制台
|
||||
|
||||
PythonicDaemon 是基础程序的一部分。要使用它,请保存完整的工作流程,将其传输到远程运行的系统中(例如,通过安全拷贝协议Secure Copy<ruby>安全拷贝协议<rt>Secure Copy</rt></ruby> [SCP]),然后把工作流程文件作为参数来启动 PythonicDaemon:
|
||||
*PythonicDaemon 控制台*
|
||||
|
||||
PythonicDaemon 是基础程序的一部分。要使用它,请保存完整的工作流程,将其传输到远程运行的系统中(例如,通过<ruby>安全拷贝协议<rt>Secure Copy</rt></ruby> SCP),然后把工作流程文件作为参数来启动 PythonicDaemon:
|
||||
|
||||
```
|
||||
`$ PythonicDaemon trading_bot_one`
|
||||
$ PythonicDaemon trading_bot_one
|
||||
```
|
||||
|
||||
为了能在系统启动时自启 PythonicDaemon,可以将一个条目添加到 crontab 中:
|
||||
|
||||
|
||||
```
|
||||
`# crontab -e`
|
||||
# crontab -e
|
||||
```
|
||||
|
||||
![Crontab on Ubuntu Server][42]
|
||||
|
||||
在 Ubuntu 服务器上的 Crontab
|
||||
*在 Ubuntu 服务器上的 Crontab*
|
||||
|
||||
### 下一步
|
||||
|
||||
正如我在一开始时所说的,本教程只是自动交易的入门。对交易机器人进行编程大约需要 10% 的编程和 90% 的测试。当涉及到让你的机器人用金钱交易时,你肯定会对编写的代码再三思考。因此,我建议你编码时要尽可能简单和易于理解。
|
||||
|
||||
|
||||
|
||||
如果你想自己继续开发交易机器人,接下来所需要做的事:
|
||||
|
||||
- 收益自动计算(希望你有正收益!)
|
||||
- 计算你想买的价格
|
||||
- 比较你的预订单(例如,订单是否填写完整?)
|
||||
|
||||
|
||||
|
||||
你可以从 [GitHub][2] 上获取完整代码。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -379,7 +364,7 @@ via: https://opensource.com/article/20/4/python-crypto-trading-bot
|
||||
作者:[Stephan Avenwedde][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/) 荣誉推出
|
||||
|
@ -0,0 +1,256 @@
|
||||
[#]: subject: (Visualize multi-threaded Python programs with an open source tool)
|
||||
[#]: via: (https://opensource.com/article/21/3/python-viztracer)
|
||||
[#]: author: (Tian Gao https://opensource.com/users/gaogaotiantian)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13253-1.html)
|
||||
|
||||
用一个开源工具实现多线程 Python 程序的可视化
|
||||
======
|
||||
|
||||
> VizTracer 可以跟踪并发的 Python 程序,以帮助记录、调试和剖析。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/30/230404xi9pox38ookk8xe2.jpg)
|
||||
|
||||
并发是现代编程中必不可少的一部分,因为我们有多个核心,有许多需要协作的任务。然而,当并发程序不按顺序运行时,就很难理解它们。对于工程师来说,在这些程序中发现 bug 和性能问题不像在单线程、单任务程序中那么容易。
|
||||
|
||||
在 Python 中,你有多种并发的选择。最常见的可能是用 `threading` 模块的多线程,用`subprocess` 和 `multiprocessing` 模块的多进程,以及最近用 `asyncio` 模块提供的 `async` 语法。在 [VizTracer][2] 之前,缺乏分析使用了这些技术程序的工具。
|
||||
|
||||
VizTracer 是一个追踪和可视化 Python 程序的工具,对日志、调试和剖析很有帮助。尽管它对单线程、单任务程序很好用,但它在并发程序中的实用性是它的独特之处。
|
||||
|
||||
### 尝试一个简单的任务
|
||||
|
||||
从一个简单的练习任务开始:计算出一个数组中的整数是否是质数并返回一个布尔数组。下面是一个简单的解决方案:
|
||||
|
||||
```
|
||||
def is_prime(n):
|
||||
for i in range(2, n):
|
||||
if n % i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_prime_arr(arr):
|
||||
return [is_prime(elem) for elem in arr]
|
||||
```
|
||||
|
||||
试着用 VizTracer 以单线程方式正常运行它:
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
num_arr = [random.randint(100, 10000) for _ in range(6000)]
|
||||
get_prime_arr(num_arr)
|
||||
```
|
||||
|
||||
```
|
||||
viztracer my_program.py
|
||||
```
|
||||
|
||||
![Running code in a single thread][3]
|
||||
|
||||
调用堆栈报告显示,耗时约 140ms,大部分时间花在 `get_prime_arr` 上。
|
||||
|
||||
![call-stack report][5]
|
||||
|
||||
这只是在数组中的元素上一遍又一遍地执行 `is_prime` 函数。
|
||||
|
||||
这是你所期望的,而且它并不有趣(如果你了解 VizTracer 的话)。
|
||||
|
||||
### 试试多线程程序
|
||||
|
||||
试着用多线程程序来做:
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
num_arr = [random.randint(100, 10000) for i in range(2000)]
|
||||
thread1 = Thread(target=get_prime_arr, args=(num_arr,))
|
||||
thread2 = Thread(target=get_prime_arr, args=(num_arr,))
|
||||
thread3 = Thread(target=get_prime_arr, args=(num_arr,))
|
||||
|
||||
thread1.start()
|
||||
thread2.start()
|
||||
thread3.start()
|
||||
|
||||
thread1.join()
|
||||
thread2.join()
|
||||
thread3.join()
|
||||
```
|
||||
|
||||
为了配合单线程程序的工作负载,这就为三个线程使用了一个 2000 元素的数组,模拟了三个线程共享任务的情况。
|
||||
|
||||
![Multi-thread program][6]
|
||||
|
||||
如果你熟悉 Python 的全局解释器锁(GIL),就会想到,它不会再快了。由于开销太大,花了 140ms 多一点的时间。不过,你可以观察到多线程的并发性:
|
||||
|
||||
![Concurrency of multiple threads][7]
|
||||
|
||||
当一个线程在工作(执行多个 `is_prime` 函数)时,另一个线程被冻结了(一个 `is_prime` 函数);后来,它们进行了切换。这是由于 GIL 的原因,这也是 Python 没有真正的多线程的原因。它可以实现并发,但不能实现并行。
|
||||
|
||||
### 用多进程试试
|
||||
|
||||
要想实现并行,办法就是 `multiprocessing` 库。下面是另一个使用 `multiprocessing` 的版本:
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
num_arr = [random.randint(100, 10000) for _ in range(2000)]
|
||||
|
||||
p1 = Process(target=get_prime_arr, args=(num_arr,))
|
||||
p2 = Process(target=get_prime_arr, args=(num_arr,))
|
||||
p3 = Process(target=get_prime_arr, args=(num_arr,))
|
||||
|
||||
p1.start()
|
||||
p2.start()
|
||||
p3.start()
|
||||
|
||||
p1.join()
|
||||
p2.join()
|
||||
p3.join()
|
||||
```
|
||||
|
||||
要使用 VizTracer 运行它,你需要一个额外的参数:
|
||||
|
||||
```
|
||||
viztracer --log_multiprocess my_program.py
|
||||
```
|
||||
|
||||
![Running with extra argument][8]
|
||||
|
||||
整个程序在 50ms 多一点的时间内完成,实际任务在 50ms 之前完成。程序的速度大概提高了三倍。
|
||||
|
||||
为了和多线程版本进行比较,这里是多进程版本:
|
||||
|
||||
![Multi-process version][9]
|
||||
|
||||
在没有 GIL 的情况下,多个进程可以实现并行,也就是多个 `is_prime` 函数可以并行执行。
|
||||
|
||||
不过,Python 的多线程也不是一无是处。例如,对于计算密集型和 I/O 密集型程序,你可以用睡眠来伪造一个 I/O 绑定的任务:
|
||||
|
||||
```
|
||||
def io_task():
|
||||
time.sleep(0.01)
|
||||
```
|
||||
|
||||
在单线程、单任务程序中试试:
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
for _ in range(3):
|
||||
io_task()
|
||||
```
|
||||
|
||||
![I/O-bound single-thread, single-task program][10]
|
||||
|
||||
整个程序用了 30ms 左右,没什么特别的。
|
||||
|
||||
现在使用多线程:
|
||||
|
||||
```
|
||||
if __name__ == "__main__":
|
||||
thread1 = Thread(target=io_task)
|
||||
thread2 = Thread(target=io_task)
|
||||
thread3 = Thread(target=io_task)
|
||||
|
||||
thread1.start()
|
||||
thread2.start()
|
||||
thread3.start()
|
||||
|
||||
thread1.join()
|
||||
thread2.join()
|
||||
thread3.join()
|
||||
```
|
||||
|
||||
![I/O-bound multi-thread program][11]
|
||||
|
||||
程序耗时 10ms,很明显三个线程是并发工作的,这提高了整体性能。
|
||||
|
||||
### 用 asyncio 试试
|
||||
|
||||
Python 正在尝试引入另一个有趣的功能,叫做异步编程。你可以制作一个异步版的任务:
|
||||
|
||||
```
|
||||
import asyncio
|
||||
|
||||
async def io_task():
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
async def main():
|
||||
t1 = asyncio.create_task(io_task())
|
||||
t2 = asyncio.create_task(io_task())
|
||||
t3 = asyncio.create_task(io_task())
|
||||
|
||||
await t1
|
||||
await t2
|
||||
await t3
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
由于 `asyncio` 从字面上看是一个带有任务的单线程调度器,你可以直接在它上使用 VizTracer:
|
||||
|
||||
![VizTracer with asyncio][12]
|
||||
|
||||
依然花了 10ms,但显示的大部分函数都是底层结构,这可能不是用户感兴趣的。为了解决这个问题,可以使用 `--log_async` 来分离真正的任务:
|
||||
|
||||
```
|
||||
viztracer --log_async my_program.py
|
||||
```
|
||||
|
||||
![Using --log_async to separate tasks][13]
|
||||
|
||||
现在,用户任务更加清晰了。在大部分时间里,没有任务在运行(因为它唯一做的事情就是睡觉)。有趣的部分是这里:
|
||||
|
||||
![Graph of task creation and execution][14]
|
||||
|
||||
这显示了任务的创建和执行时间。Task-1 是 `main()` 协程,创建了其他任务。Task-2、Task-3、Task-4 执行 `io_task` 和 `sleep` 然后等待唤醒。如图所示,因为是单线程程序,所以任务之间没有重叠,VizTracer 这样可视化是为了让它更容易理解。
|
||||
|
||||
为了让它更有趣,可以在任务中添加一个 `time.sleep` 的调用来阻止异步循环:
|
||||
|
||||
```
|
||||
async def io_task():
|
||||
time.sleep(0.01)
|
||||
await asyncio.sleep(0.01)
|
||||
```
|
||||
|
||||
![time.sleep call][15]
|
||||
|
||||
程序耗时更长(40ms),任务填补了异步调度器中的空白。
|
||||
|
||||
这个功能对于诊断异步程序的行为和性能问题非常有帮助。
|
||||
|
||||
### 看看 VizTracer 发生了什么?
|
||||
|
||||
通过 VizTracer,你可以在时间轴上查看程序的进展情况,而不是从复杂的日志中想象。这有助于你更好地理解你的并发程序。
|
||||
|
||||
VizTracer 是开源的,在 Apache 2.0 许可证下发布,支持所有常见的操作系统(Linux、macOS 和 Windows)。你可以在 [VizTracer 的 GitHub 仓库][16]中了解更多关于它的功能和访问它的源代码。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/python-viztracer
|
||||
|
||||
作者:[Tian Gao][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/gaogaotiantian
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/colorful_sound_wave.png?itok=jlUJG0bM (Colorful sound wave graph)
|
||||
[2]: https://readthedocs.org/projects/viztracer/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/viztracer_singlethreadtask.png (Running code in a single thread)
|
||||
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[5]: https://opensource.com/sites/default/files/uploads/viztracer_callstackreport.png (call-stack report)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/viztracer_multithread.png (Multi-thread program)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/viztracer_concurrency.png (Concurrency of multiple threads)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/viztracer_multithreadrun.png (Running with extra argument)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/viztracer_comparewithmultiprocess.png (Multi-process version)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/io-bound_singlethread.png (I/O-bound single-thread, single-task program)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/io-bound_multithread.png (I/O-bound multi-thread program)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/viztracer_asyncio.png (VizTracer with asyncio)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/log_async.png (Using --log_async to separate tasks)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/taskcreation.png (Graph of task creation and execution)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/time.sleep_call.png (time.sleep call)
|
||||
[16]: https://github.com/gaogaotiantian/viztracer
|
@ -0,0 +1,274 @@
|
||||
[#]: subject: (Learn how file input and output works in C)
|
||||
[#]: via: (https://opensource.com/article/21/3/file-io-c)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13252-1.html)
|
||||
|
||||
学习如何用 C 语言来进行文件输入输出操作
|
||||
======
|
||||
|
||||
> 理解 I/O 有助于提升你的效率。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/30/222717gyuegz88ryu8ry7i.jpg)
|
||||
|
||||
如果你打算学习 C 语言的输入、输出,可以从 `stdio.h` 包含文件开始。正如你从其名字中猜到的,该文件定义了所有的标准(“std”)的输入和输出(“io”)函数。
|
||||
|
||||
大多数人学习的第一个 `stdio.h` 的函数是打印格式化输出的 `printf` 函数。或者是用来打印一个字符串的 `puts` 函数。这些函数非常有用,可以将信息打印给用户,但是如果你想做更多的事情,则需要了解其他函数。
|
||||
|
||||
你可以通过编写一个常见 Linux 命令的副本来了解其中一些功能和方法。`cp` 命令主要用于复制文件。如果你查看 `cp` 的帮助手册,可以看到 `cp` 命令支持非常多的参数和选项。但最简单的功能,就是复制文件:
|
||||
|
||||
```
|
||||
cp infile outfile
|
||||
```
|
||||
|
||||
你只需使用一些读写文件的基本函数,就可以用 C 语言来自己实现 `cp` 命令。
|
||||
|
||||
### 一次读写一个字符
|
||||
|
||||
你可以使用 `fgetc` 和 `fputc` 函数轻松地进行输入输出。这些函数一次只读写一个字符。该用法被定义在 `stdio.h`,并且这也很浅显易懂:`fgetc` 是从文件中读取一个字符,`fputc` 是将一个字符保存到文件中。
|
||||
|
||||
```
|
||||
int fgetc(FILE *stream);
|
||||
int fputc(int c, FILE *stream);
|
||||
```
|
||||
|
||||
编写 `cp` 命令需要访问文件。在 C 语言中,你使用 `fopen` 函数打开一个文件,该函数需要两个参数:文件名和打开文件的模式。模式通常是从文件读取(`r`)或向文件写入(`w`)。打开文件的方式也有其他选项,但是对于本教程而言,仅关注于读写操作。
|
||||
|
||||
因此,将一个文件复制到另一个文件就变成了打开源文件和目标文件,接着,不断从第一个文件读取字符,然后将该字符写入第二个文件。`fgetc` 函数返回从输入文件中读取的单个字符,或者当文件完成后返回文件结束标记(`EOF`)。一旦读取到 `EOF`,你就完成了复制操作,就可以关闭两个文件。该代码如下所示:
|
||||
|
||||
```
|
||||
do {
|
||||
ch = fgetc(infile);
|
||||
if (ch != EOF) {
|
||||
fputc(ch, outfile);
|
||||
}
|
||||
} while (ch != EOF);
|
||||
```
|
||||
|
||||
你可以使用此循环编写自己的 `cp` 程序,以使用 `fgetc` 和 `fputc` 函数一次读写一个字符。`cp.c` 源代码如下所示:
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
int ch;
|
||||
|
||||
/* parse the command line */
|
||||
|
||||
/* usage: cp infile outfile */
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Incorrect usage\n");
|
||||
fprintf(stderr, "Usage: cp infile outfile\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
|
||||
infile = fopen(argv[1], "r");
|
||||
if (infile == NULL) {
|
||||
fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* open the output file */
|
||||
|
||||
outfile = fopen(argv[2], "w");
|
||||
if (outfile == NULL) {
|
||||
fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]);
|
||||
fclose(infile);
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* copy one file to the other */
|
||||
|
||||
/* use fgetc and fputc */
|
||||
|
||||
do {
|
||||
ch = fgetc(infile);
|
||||
if (ch != EOF) {
|
||||
fputc(ch, outfile);
|
||||
}
|
||||
} while (ch != EOF);
|
||||
|
||||
/* done */
|
||||
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
你可以使用 `gcc` 来将 `cp.c` 文件编译成一个可执行文件:
|
||||
|
||||
```
|
||||
$ gcc -Wall -o cp cp.c
|
||||
```
|
||||
|
||||
`-o cp` 选项告诉编译器将编译后的程序保存到 `cp` 文件中。`-Wall` 选项告诉编译器提示所有可能的警告,如果你没有看到任何警告,则表示一切正常。
|
||||
|
||||
### 读写数据块
|
||||
|
||||
通过每次读写一个字符来实现自己的 `cp` 命令可以完成这项工作,但这并不是很快。在复制“日常”文件(例如文档和文本文件)时,你可能不会注意到,但是在复制大型文件或通过网络复制文件时,你才会注意到差异。每次处理一个字符需要大量的开销。
|
||||
|
||||
实现此 `cp` 命令的一种更好的方法是,读取一块的输入数据到内存中(称为缓存),然后将该数据集合写入到第二个文件。这样做的速度要快得多,因为程序可以一次读取更多的数据,这就就减少了从文件中“读取”的次数。
|
||||
|
||||
你可以使用 `fread` 函数将文件读入一个变量中。这个函数有几个参数:将数据读入的数组或内存缓冲区的指针(`ptr`),要读取的最小对象的大小(`size`),要读取对象的个数(`nmemb`),以及要读取的文件(`stream`):
|
||||
|
||||
```
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
```
|
||||
|
||||
不同的选项为更高级的文件输入和输出(例如,读取和写入具有特定数据结构的文件)提供了很大的灵活性。但是,在从一个文件读取数据并将数据写入另一个文件的简单情况下,可以使用一个由字符数组组成的缓冲区。
|
||||
|
||||
你可以使用 `fwrite` 函数将缓冲区中的数据写入到另一个文件。这使用了与 `fread` 函数有相似的一组选项:要从中读取数据的数组或内存缓冲区的指针,要读取的最小对象的大小,要读取对象的个数以及要写入的文件。
|
||||
|
||||
```
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
```
|
||||
|
||||
如果程序将文件读入缓冲区,然后将该缓冲区写入另一个文件,则数组(`ptr`)可以是固定大小的数组。例如,你可以使用长度为 200 个字符的字符数组作为缓冲区。
|
||||
|
||||
在该假设下,你需要更改 `cp` 程序中的循环,以将数据从文件读取到缓冲区中,然后将该缓冲区写入另一个文件中:
|
||||
|
||||
```
|
||||
while (!feof(infile)) {
|
||||
buffer_length = fread(buffer, sizeof(char), 200, infile);
|
||||
fwrite(buffer, sizeof(char), buffer_length, outfile);
|
||||
}
|
||||
```
|
||||
|
||||
这是更新后的 `cp` 程序的完整源代码,该程序现在使用缓冲区读取和写入数据:
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
char buffer[200];
|
||||
size_t buffer_length;
|
||||
|
||||
/* parse the command line */
|
||||
|
||||
/* usage: cp infile outfile */
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Incorrect usage\n");
|
||||
fprintf(stderr, "Usage: cp infile outfile\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
|
||||
infile = fopen(argv[1], "r");
|
||||
if (infile == NULL) {
|
||||
fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* open the output file */
|
||||
|
||||
outfile = fopen(argv[2], "w");
|
||||
if (outfile == NULL) {
|
||||
fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]);
|
||||
fclose(infile);
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* copy one file to the other */
|
||||
|
||||
/* use fread and fwrite */
|
||||
|
||||
while (!feof(infile)) {
|
||||
buffer_length = fread(buffer, sizeof(char), 200, infile);
|
||||
fwrite(buffer, sizeof(char), buffer_length, outfile);
|
||||
}
|
||||
|
||||
/* done */
|
||||
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
由于你想将此程序与其他程序进行比较,因此请将此源代码另存为 `cp2.c`。你可以使用 `gcc` 编译程序:
|
||||
|
||||
```
|
||||
$ gcc -Wall -o cp2 cp2.c
|
||||
```
|
||||
|
||||
和之前一样,`-o cp2` 选项告诉编译器将编译后的程序保存到 `cp2` 程序文件中。`-Wall` 选项告诉编译器打开所有警告。如果你没有看到任何警告,则表示一切正常。
|
||||
|
||||
### 是的,这真的更快了
|
||||
|
||||
使用缓冲区读取和写入数据是实现此版本 `cp` 程序更好的方法。由于它可以一次将文件的多个数据读取到内存中,因此该程序不需要频繁读取数据。在小文件中,你可能没有注意到使用这两种方案的区别,但是如果你需要复制大文件,或者在较慢的介质(例如通过网络连接)上复制数据时,会发现明显的差距。
|
||||
|
||||
我使用 Linux `time` 命令进行了比较。此命令可以运行另一个程序,然后告诉你该程序花费了多长时间。对于我的测试,我希望了解所花费时间的差距,因此我复制了系统上的 628 MB CD-ROM 镜像文件。
|
||||
|
||||
我首先使用标准的 Linux 的 `cp` 命令复制了映像文件,以查看所需多长时间。一开始通过运行 Linux 的 `cp` 命令,同时我还避免使用 Linux 内置的文件缓存系统,使其不会给程序带来误导性能提升的可能性。使用 Linux `cp` 进行的测试,总计花费不到一秒钟的时间:
|
||||
|
||||
```
|
||||
$ time cp FD13LIVE.iso tmpfile
|
||||
|
||||
real 0m0.040s
|
||||
user 0m0.001s
|
||||
sys 0m0.003s
|
||||
```
|
||||
|
||||
运行我自己实现的 `cp` 命令版本,复制同一文件要花费更长的时间。每次读写一个字符则花了将近五秒钟来复制文件:
|
||||
|
||||
```
|
||||
$ time ./cp FD13LIVE.iso tmpfile
|
||||
|
||||
real 0m4.823s
|
||||
user 0m4.100s
|
||||
sys 0m0.571s
|
||||
```
|
||||
|
||||
从输入读取数据到缓冲区,然后将该缓冲区写入输出文件则要快得多。使用此方法复制文件花不到一秒钟:
|
||||
|
||||
```
|
||||
$ time ./cp2 FD13LIVE.iso tmpfile
|
||||
|
||||
real 0m0.944s
|
||||
user 0m0.224s
|
||||
sys 0m0.608s
|
||||
```
|
||||
|
||||
我演示的 `cp` 程序使用了 200 个字符大小的缓冲区。我确信如果一次将更多文件数据读入内存,该程序将运行得更快。但是,通过这种比较,即使只有 200 个字符的缓冲区,你也已经看到了性能上的巨大差异。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/file-io-c
|
||||
|
||||
作者:[Jim Hall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wyxplus](https://github.com/wyxplus)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/file_system.jpg?itok=pzCrX1Kc "4 manilla folders, yellow, green, purple, blue"
|
||||
[2]: http://www.opengroup.org/onlinepubs/009695399/functions/fgetc.html
|
||||
[3]: http://www.opengroup.org/onlinepubs/009695399/functions/fputc.html
|
||||
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
|
||||
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
|
||||
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/fclose.html
|
||||
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/feof.html
|
||||
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/fread.html
|
||||
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/fwrite.html
|
@ -3,48 +3,45 @@
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13250-1.html)
|
||||
|
||||
如何在 WebAssembly 中写 “Hello World”?
|
||||
======
|
||||
通过这个分步教程,开始用人类可读的文本编写 WebAssembly。
|
||||
![Hello World inked on bread][1]
|
||||
> 通过这个分步教程,开始用人类可读的文本编写 WebAssembly。
|
||||
|
||||
WebAssembly 是一种字节码格式,[几乎所有的浏览器][2]都可以将它编译成其主机系统的机器代码。除了 JavaScript 和 WebGL 之外,WebAssembly 还满足了将应用移植到浏览器中以实现平台独立的需求。作为 C++ 和 Rust 的编译目标,WebAssembly 使 Web 浏览器能够以接近原生的速度执行代码。
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/30/095907r6ecev48dw0l9w44.jpg)
|
||||
|
||||
当你谈论 WebAssembly、应用时,你必须区分三种状态:
|
||||
WebAssembly 是一种字节码格式,[几乎所有的浏览器][2] 都可以将它编译成其宿主操作系统的机器代码。除了 JavaScript 和 WebGL 之外,WebAssembly 还满足了将应用移植到浏览器中以实现平台独立的需求。作为 C++ 和 Rust 的编译目标,WebAssembly 使 Web 浏览器能够以接近原生的速度执行代码。
|
||||
|
||||
当谈论 WebAssembly 应用时,你必须区分三种状态:
|
||||
|
||||
1. **源码(如 C++ 或 Rust):** 你有一个用兼容语言编写的应用,你想把它在浏览器中执行。
|
||||
2. **WebAssembly 字节码:** 你选择 WebAssembly 字节码作为编译目标。最后,你得到一个 `.wasm` 文件。
|
||||
3. **机器码(opcode):** 浏览器加载 `.wasm` 文件,并将其编译成主机系统的相应机器码。
|
||||
|
||||
|
||||
|
||||
WebAssembly 还有一种文本格式,用人类可读的文本表示二进制格式。为了简单起见,我将其称为 **WASM-text**。WASM-text 可以比作高级汇编语言。当然,你不会基于 WASM-text 来编写一个完整的应用,但了解它的底层工作原理是很好的(特别是对于调试和性能优化)。
|
||||
|
||||
本文将指导你在 WASM-text 中创建经典的 _Hello World_ 程序。
|
||||
本文将指导你在 WASM-text 中创建经典的 “Hello World” 程序。
|
||||
|
||||
### 创建 .wat 文件
|
||||
|
||||
WASM-text 文件通常以 `.wat` 结尾。第一步创建一个名为 `helloworld.wat` 的空文本文件,用你最喜欢的文本编辑器打开它,然后粘贴进去:
|
||||
|
||||
|
||||
|
||||
```
|
||||
(module
|
||||
;; Imports from JavaScript namespace
|
||||
(import "console" "log" (func $log (param i32 i32))) ;; Import log function
|
||||
(import "js" "mem" (memory 1)) ;; Import 1 page of memory (54kb)
|
||||
;; 从 JavaScript 命名空间导入
|
||||
(import "console" "log" (func $log (param i32 i32))) ;; 导入 log 函数
|
||||
(import "js" "mem" (memory 1)) ;; 导入 1 页 内存(64kb)
|
||||
|
||||
;; Data section of our module
|
||||
;; 我们的模块的数据段
|
||||
(data (i32.const 0) "Hello World from WebAssembly!")
|
||||
|
||||
;; Function declaration: Exported as helloWorld(), no arguments
|
||||
;; 函数声明:导出 helloWorld(),无参数
|
||||
(func (export "helloWorld")
|
||||
i32.const 0 ;; pass offset 0 to log
|
||||
i32.const 29 ;; pass length 29 to log (strlen of sample text)
|
||||
i32.const 0 ;; 传递偏移 0 到 log
|
||||
i32.const 29 ;; 传递长度 29 到 log(示例文本的字符串长度)
|
||||
call $log
|
||||
)
|
||||
)
|
||||
@ -52,28 +49,26 @@ WASM-text 文件通常以 `.wat` 结尾。第一步创建一个名为 `helloworl
|
||||
|
||||
WASM-text 格式是基于 S 表达式的。为了实现交互,JavaScript 函数用 `import` 语句导入,WebAssembly 函数用 `export` 语句导出。在这个例子中,从 `console` 模块中导入 `log` 函数,它需要两个类型为 `i32` 的参数作为输入,以及一页内存(64KB)来存储字符串。
|
||||
|
||||
字符串将被写入偏移量 `0` 的 `data` 部分。`data` 部分是你的内存的覆盖,内存是在 JavaScript 部分分配的。
|
||||
字符串将被写入偏移量 为 `0` 的数据段。数据段是你的内存的<ruby>叠加投影<rt>overlay</rt></ruby>,内存是在 JavaScript 部分分配的。
|
||||
|
||||
函数用关键字 `func` 标记。当进入函数时,栈是空的。在调用另一个函数之前,函数参数会被压入栈中(这里是偏移量和长度)(见 `call $log`)。当一个函数返回一个 `f32` 类型时(例如),当离开函数时,一个 `f32` 变量必须保留在栈中(但在本例中不是这样)。
|
||||
|
||||
### 创建 .wasm 文件
|
||||
|
||||
WASM-text 和 WebAssembly 字节码有 1:1 的对应关系,这意味着你可以将 WASM-text 转换成字节码(反之亦然)。你已经有了 WASM-text,现在将创建字节码。
|
||||
WASM-text 和 WebAssembly 字节码是 1:1 对应的,这意味着你可以将 WASM-text 转换成字节码(反之亦然)。你已经有了 WASM-text,现在将创建字节码。
|
||||
|
||||
转换可以通过 [WebAssembly Binary Toolkit][3](WABT)来完成。从链接克隆仓库,并按照安装说明进行安装。
|
||||
转换可以通过 [WebAssembly Binary Toolkit][3](WABT)来完成。从该链接克隆仓库,并按照安装说明进行安装。
|
||||
|
||||
建立工具链后,打开控制台并输入以下内容,将 WASM-text 转换为字节码:
|
||||
|
||||
|
||||
```
|
||||
`wat2wasm helloworld.wat -o helloworld.wasm`
|
||||
wat2wasm helloworld.wat -o helloworld.wasm
|
||||
```
|
||||
|
||||
你也可以用以下方法将字节码转换为 WASM-text:
|
||||
|
||||
|
||||
```
|
||||
`wasm2wat helloworld.wasm -o helloworld_reverse.wat`
|
||||
wasm2wat helloworld.wasm -o helloworld_reverse.wat
|
||||
```
|
||||
|
||||
一个从 `.wasm` 文件创建的 `.wat` 文件不包括任何函数或参数名称。默认情况下,WebAssembly 用它们的索引来识别函数和参数。
|
||||
@ -84,42 +79,41 @@ WASM-text 和 WebAssembly 字节码有 1:1 的对应关系,这意味着你可
|
||||
|
||||
创建一个空的文本文件,并将其命名为 `helloworld.html`,然后打开你喜欢的文本编辑器并粘贴进去:
|
||||
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple template</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var memory = new WebAssembly.Memory({initial:1});
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple template</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var memory = new WebAssembly.Memory({initial:1});
|
||||
|
||||
function consoleLogString(offset, length) {
|
||||
var bytes = new Uint8Array(memory.buffer, offset, length);
|
||||
var string = new TextDecoder('utf8').decode(bytes);
|
||||
console.log(string);
|
||||
};
|
||||
function consoleLogString(offset, length) {
|
||||
var bytes = new Uint8Array(memory.buffer, offset, length);
|
||||
var string = new TextDecoder('utf8').decode(bytes);
|
||||
console.log(string);
|
||||
};
|
||||
|
||||
var importObject = {
|
||||
console: {
|
||||
log: consoleLogString
|
||||
},
|
||||
js : {
|
||||
mem: memory
|
||||
}
|
||||
};
|
||||
|
||||
WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)
|
||||
.then(obj => {
|
||||
obj.instance.exports.helloWorld();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
var importObject = {
|
||||
console: {
|
||||
log: consoleLogString
|
||||
},
|
||||
js : {
|
||||
mem: memory
|
||||
}
|
||||
};
|
||||
|
||||
WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)
|
||||
.then(obj => {
|
||||
obj.instance.exports.helloWorld();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
`WebAssembly.Memory(...)` 方法返回一个大小为 64KB 的内存页。函数 `consoleLogString` 根据长度和偏移量从该内存页读取一个字符串。这两个对象作为 `importObject` 的一部分传递给你的 WebAssembly 模块。
|
||||
@ -128,19 +122,15 @@ WASM-text 和 WebAssembly 字节码有 1:1 的对应关系,这意味着你可
|
||||
|
||||
![Firefox setting][4]
|
||||
|
||||
(Stephan Avenwedde, [CC BY-SA 4.0][5])
|
||||
|
||||
> **注意:** 这样做会使你容易受到 [CVE-2019-11730][6] 安全问题的影响。
|
||||
|
||||
现在,在 Firefox 中打开 `helloworld.html`,按下 **Ctrl**+**K** 打开开发者控制台。
|
||||
现在,在 Firefox 中打开 `helloworld.html`,按下 `Ctrl+K` 打开开发者控制台。
|
||||
|
||||
![Debugger output][7]
|
||||
|
||||
(Stephan Avenwedde, [CC BY-SA 4.0][5])
|
||||
|
||||
### 了解更多
|
||||
|
||||
这个 Hello World 的例子只是 MDN 的[了解 WebAssembly 文本格式][8]文档中的教程之一。如果你想了解更多关于 WebAssembly 的知识以及它的工作原理,可以看看这些文档。
|
||||
这个 Hello World 的例子只是 MDN 的 [了解 WebAssembly 文本格式][8] 文档中的教程之一。如果你想了解更多关于 WebAssembly 的知识以及它的工作原理,可以看看这些文档。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -149,7 +139,7 @@ via: https://opensource.com/article/21/3/hello-world-webassembly
|
||||
作者:[Stephan Avenwedde][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/) 荣誉推出
|
||||
|
@ -3,106 +3,100 @@
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-13247-1.html"
|
||||
|
||||
练习使用 Linux 的 grep 命令
|
||||
======
|
||||
来学习下搜索文件中内容的基本操作,然后下载我们的备忘录作为 grep 和正则表达式的快速参考指南。
|
||||
![Hand putting a Linux file folder into a drawer][1]
|
||||
|
||||
grep(<ruby>全局正则表达式打印<rt>Global Regular Expression Print</rt></ruby>)是早在 1974 年由 Ken Thompson 开发的基本 Unix 命令之一。在计算领域,它无处不在,通常被用作为动词(“搜索一个文件中的内容”)。如果你的谈话对象有极客精神,那么它也能在真实生活场景中使用。(例如,“我会搜索我的内存库来回想起那些信息。”)简而言之,grep 是一种用特定的字符模式来搜索文件中内容的方式。如果你感觉这听起来像是文字处理器或文本编辑器的现代 Find 功能,那么你就已经在计算行业感受到了grep 的影响。
|
||||
> 来学习下搜索文件中内容的基本操作,然后下载我们的备忘录作为 grep 和正则表达式的快速参考指南。
|
||||
|
||||
grep 绝不是被现代技术抛弃的远古命令,它的强大体现在两个方面:
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/29/093323yn6ilqvg6z6iizcf.jpg)
|
||||
|
||||
* grep 可以在终端操作数据流,因此你可以把它嵌入到复杂的处理中。你不仅可以在一个文本文件中*查找*文字,还可以提取文字后把它发给另一个命令。
|
||||
* grep 使用正则表达式来提供灵活的搜索能力。
|
||||
`grep`(<ruby>全局正则表达式打印<rt>Global Regular Expression Print</rt></ruby>)是由 Ken Thompson 早在 1974 年开发的基本 Unix 命令之一。在计算领域,它无处不在,通常被用作为动词(“搜索一个文件中的内容”)。如果你的谈话对象有极客精神,那么它也能在真实生活场景中使用。(例如,“我会 `grep` 我的内存条来回想起那些信息。”)简而言之,`grep` 是一种用特定的字符模式来搜索文件中内容的方式。如果你感觉这听起来像是文字处理器或文本编辑器的现代 Find 功能,那么你就已经在计算行业感受到了 `grep` 的影响。
|
||||
|
||||
`grep` 绝不是被现代技术抛弃的远古命令,它的强大体现在两个方面:
|
||||
|
||||
* `grep` 可以在终端操作数据流,因此你可以把它嵌入到复杂的处理中。你不仅可以在一个文本文件中*查找*文字,还可以提取文字后把它发给另一个命令。
|
||||
* `grep` 使用正则表达式来提供灵活的搜索能力。
|
||||
|
||||
虽然需要一些练习,但学习 `grep` 命令还是很容易的。本文会介绍一些我认为 grep 最有用的功能。
|
||||
虽然需要一些练习,但学习 `grep` 命令还是很容易的。本文会介绍一些我认为 `grep` 最有用的功能。
|
||||
|
||||
**[下载我们免费的 [grep 备忘录][2]]**
|
||||
- 下载我们免费的 [grep 备忘录][2]
|
||||
|
||||
### 安装 grep
|
||||
|
||||
Linux 默认安装 grep。
|
||||
Linux 默认安装了 `grep`。
|
||||
|
||||
MacOS 默认安装了 BSD 版的 grep。BSD 版的 grep 跟 GNU 版有一点不一样,因此如果你想完全参照本文,那么请使用 [Homebrew][3] 或 [MacPorts][4] 安装 GNU 版的 grep。
|
||||
MacOS 默认安装了 BSD 版的 `grep`。BSD 版的 `grep` 跟 GNU 版有一点不一样,因此如果你想完全参照本文,那么请使用 [Homebrew][3] 或 [MacPorts][4] 安装 GNU 版的 `grep`。
|
||||
|
||||
### 基础的 grep
|
||||
|
||||
所有版本的 grep 基础语法都一样。入参是匹配模式和你需要搜索的文件。它会把匹配到的每一行输出到你的终端。
|
||||
|
||||
所有版本的 `grep` 基础语法都一样。入参是匹配模式和你需要搜索的文件。它会把匹配到的每一行输出到你的终端。
|
||||
|
||||
```
|
||||
$ grep gnu gpl-3.0.txt
|
||||
along with this program. If not, see <[http://www.gnu.org/licenses/\>][5].
|
||||
<[http://www.gnu.org/licenses/\>][5].
|
||||
<[http://www.gnu.org/philosophy/why-not-lgpl.html\>][6].
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
```
|
||||
|
||||
`grep` 命令默认大小写敏感,因此 “gnu”、“GNU"、”Gnu“ 是三个不同的值。你可以使用 `--ignore-case` 选项来忽略大小写。
|
||||
|
||||
`grep` 命令默认大小写敏感,因此 “gnu”、“GNU”、“Gnu” 是三个不同的值。你可以使用 `--ignore-case` 选项来忽略大小写。
|
||||
|
||||
```
|
||||
$ grep --ignore-case gnu gpl-3.0.txt
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
[...16 more results...]
|
||||
<[http://www.gnu.org/licenses/\>][5].
|
||||
<[http://www.gnu.org/philosophy/why-not-lgpl.html\>][6].
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
```
|
||||
|
||||
你也可以通过 `--invert-match` 选项来输出所有没有匹配到的行:
|
||||
|
||||
|
||||
```
|
||||
$ grep --invert-match \
|
||||
\--ignore-case gnu gpl-3.0.txt
|
||||
Version 3, 29 June 2007
|
||||
--ignore-case gnu gpl-3.0.txt
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <[http://fsf.org/\>][7]
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
[...648 lines...]
|
||||
Public License instead of this License. But first, please read
|
||||
Public License instead of this License. But first, please read
|
||||
```
|
||||
|
||||
### 管道
|
||||
|
||||
能搜索文件中的文本内容是很有用的,但是 [POSIX][8] 的真正强大之处是可以通过”管道“来连接多条命令。我发现我使用 grep 最好的方式是把它与其他工具如 cut、tr 或 [curl][9] 联合使用。
|
||||
|
||||
假如现在有一个文件,文件中每一行是我想要下载的技术论文。我可以打开文件手动点击每一个链接,然后点击火狐的选项把每一个文件保存到我的硬盘,但是需要点击多次且耗费很长时间。而我还可以搜索文件中的链接,用 `--only-matching` 选项*只*打印出匹配到的字符串。
|
||||
能搜索文件中的文本内容是很有用的,但是 [POSIX][8] 的真正强大之处是可以通过“管道”来连接多条命令。我发现我使用 `grep` 最好的方式是把它与其他工具如 `cut`、`tr` 或 [curl][9] 联合使用。
|
||||
|
||||
假如现在有一个文件,文件中每一行是我想要下载的技术论文。我可以打开文件手动点击每一个链接,然后点击火狐浏览器的选项把每一个文件保存到我的硬盘,但是需要点击多次且耗费很长时间。而我还可以搜索文件中的链接,用 `--only-matching` 选项*只*打印出匹配到的字符串。
|
||||
|
||||
```
|
||||
$ grep --only-matching http\:\/\/.*pdf example.html
|
||||
<http://example.com/linux\_whitepaper.pdf>
|
||||
<http://example.com/bsd\_whitepaper.pdf>
|
||||
<http://example.com/important\_security\_topic.pdf>
|
||||
http://example.com/linux_whitepaper.pdf
|
||||
http://example.com/bsd_whitepaper.pdf
|
||||
http://example.com/important_security_topic.pdf
|
||||
```
|
||||
|
||||
输出是一系列的 URL,每行一个。而这与 Bash 处理数据的方式完美契合,因此我不再把 URL 打印到终端,而是把它们通过管道传给 `curl`:
|
||||
|
||||
|
||||
```
|
||||
$ grep --only-matching http\:\/\/.*pdf \
|
||||
example.html | curl --remote-name
|
||||
```
|
||||
|
||||
这条命令可以下载每一个文件,然后以各自远程的文件名命名保存在我的硬盘上。
|
||||
这条命令可以下载每一个文件,然后以各自的远程文件名命名保存在我的硬盘上。
|
||||
|
||||
这个例子中我的搜索模式可能很晦涩。那是因为它用的是正则表达式,一种在大量文本中进行模糊搜索时非常有用的”通配符“语言。
|
||||
|
||||
### 正则表达式
|
||||
|
||||
没有人会觉得正则表达式(简称 ”regex“)很简单。然而,我发现它的名声通常并不好。不可否认,很多人在使用正则表达式时”过于聪明”,以致于可读性很差,太过模糊以致于前面的模式覆盖了后面的模式,但是你仍大可不必滥用正则。这里是我使用正则的一个简明的教程。
|
||||
没有人会觉得<ruby>正则表达式<rt>regular expression</rt></ruby>(简称 “regex”)很简单。然而,我发现它的名声往往比它应得的要差。诚然,很多人在使用正则表达式时“过于炫耀聪明”,直到它变得难以阅读,大而全,以至于复杂得换行才好理解,但是你不必过度使用正则。这里简单介绍一下我使用正则表达式的方式。
|
||||
|
||||
首先,创建一个名为 `example.txt` 的文件,输入以下内容:
|
||||
|
||||
|
||||
```
|
||||
Albania
|
||||
Algeria
|
||||
@ -113,8 +107,7 @@ Canada
|
||||
11
|
||||
```
|
||||
|
||||
最基础的元素是谦逊的 `.` 字符。它表示一个字符。
|
||||
|
||||
最基础的元素是不起眼的 `.` 字符。它表示一个字符。
|
||||
|
||||
```
|
||||
$ grep Can.da example.txt
|
||||
@ -128,22 +121,18 @@ Canada
|
||||
* `?` 匹配前面的模式零次或一次
|
||||
* `*` 匹配前面的模式零次或多次
|
||||
* `+` 匹配前面的模式一次或多次
|
||||
* `{4}` 匹配前面的模式最多 4 次(或是你在括号中写的其他次数)
|
||||
|
||||
|
||||
* `{4}` 匹配前面的模式 4 次(或是你在括号中写的其他次数)
|
||||
|
||||
了解了这些知识后,你可以用你认为有意思的所有模式来在 `example.txt` 中做练习。可能有些会成功,有些不会成功。重要的是你要去分析结果,这样你才会知道原因。
|
||||
|
||||
例如,下面的命令匹配不到任何国家:
|
||||
|
||||
|
||||
```
|
||||
`$ grep A.a example.txt`
|
||||
$ grep A.a example.txt
|
||||
```
|
||||
|
||||
因为 `.` 字符只能匹配一个字符,除非你增加匹配次数。使用 `*` 字符,告诉 `grep` 匹配一个字符零次或者必要的任意多次直到单词末尾。因为你知道你要处理的内容,因此在本例中*零次*是没有必要的。在这个列表中一定没有单个字母的国家。因此,你可以用 `+` 来匹配一个字符至少一次且任意多次直到单词末尾:
|
||||
|
||||
|
||||
```
|
||||
$ grep A.+a example.txt
|
||||
Albania
|
||||
@ -152,7 +141,6 @@ Algeria
|
||||
|
||||
你可以使用方括号来提供一系列的字母:
|
||||
|
||||
|
||||
```
|
||||
$ grep [A,C].+a example.txt
|
||||
Albania
|
||||
@ -162,7 +150,6 @@ Canada
|
||||
|
||||
也可以用来匹配数字。结果可能会震惊你:
|
||||
|
||||
|
||||
```
|
||||
$ grep [1-9] example.txt
|
||||
1
|
||||
@ -180,7 +167,7 @@ $ grep [1-9] example.txt
|
||||
|
||||
### 下载备忘录
|
||||
|
||||
`grep` 命令还有很多文章中没有列出的选项。有用来更好地展示匹配结果、列出文件、列出匹配到的行号、通过打印匹配到的行周围的内容来显示上下文的选项,等等。如果你在学习 grep,或者你经常使用它并且通过查阅它的`帮助`页面来查看选项,那么你可以下载我们的备忘录。这个备忘录使用短选项(例如,使用 `-v`,而不是 `--invert-matching`)来帮助你更好地熟悉 grep。它还有一部分正则表达式可以帮你记住用途最广的正则表达式代码。 [现在就下载 grep 备忘录!][2]
|
||||
`grep` 命令还有很多文章中没有列出的选项。有用来更好地展示匹配结果、列出文件、列出匹配到的行号、通过打印匹配到的行周围的内容来显示上下文的选项,等等。如果你在学习 `grep`,或者你经常使用它并且通过查阅它的`帮助`页面来查看选项,那么你可以下载我们的备忘录。这个备忘录使用短选项(例如,使用 `-v`,而不是 `--invert-matching`)来帮助你更好地熟悉 `grep`。它还有一部分正则表达式可以帮你记住用途最广的正则表达式代码。 [现在就下载 grep 备忘录!][2]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -189,7 +176,7 @@ via: https://opensource.com/article/21/3/grep-cheat-sheet
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -3,28 +3,26 @@
|
||||
[#]: author: (Jakub Kadlčík https://fedoramagazine.org/author/frostyx/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13243-1.html)
|
||||
|
||||
COPR 仓库中 4 个很酷的新项目(2021.03)
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
COPR 是个人软件仓库[集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
> COPR 是个人软件仓库 [集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
|
||||
本文介绍了 COPR 中一些有趣的新项目。如果你第一次使用 COPR,请参阅 [COPR 用户文档][3]。
|
||||
|
||||
### [][4]
|
||||
|
||||
### Ytfzf
|
||||
|
||||
[Ytfzf][5] 是一个简单的命令行工具,用于搜索和观看 YouTube 视频。它提供了围绕模糊查找程序 [fzf][6] 构建的快速直观的界面。它使用 [youtube-dl][7] 来下载选定的视频,并打开外部视频播放器来观看。由于这种方式,_ytfzf_ 比使用浏览器观看 YouTube 资源占用要少得多。它支持缩略图(通过 [ueberzug][8])、历史记录保存、多个视频排队或下载它们以供以后使用、频道订阅以及其他方便的功能。多亏了像 [dmenu][9] 或 [rofi][10] 这样的工具,它甚至可以在终端之外使用。
|
||||
[Ytfzf][5] 是一个简单的命令行工具,用于搜索和观看 YouTube 视频。它提供了围绕模糊查找程序 [fzf][6] 构建的快速直观的界面。它使用 [youtube-dl][7] 来下载选定的视频,并打开外部视频播放器来观看。由于这种方式,`ytfzf` 比使用浏览器观看 YouTube 资源占用要少得多。它支持缩略图(通过 [ueberzug][8])、历史记录保存、多个视频排队或下载它们以供以后使用、频道订阅以及其他方便的功能。多亏了像 [dmenu][9] 或 [rofi][10] 这样的工具,它甚至可以在终端之外使用。
|
||||
|
||||
![][11]
|
||||
|
||||
#### [][12] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
目前[仓库][13]为 Fedora 33 和 34 提供 Ytfzf。要安装它,请使用以下命令:
|
||||
|
||||
@ -33,7 +31,7 @@ sudo dnf copr enable bhoman/ytfzf
|
||||
sudo dnf install ytfzf
|
||||
```
|
||||
|
||||
### [][14] Gemini 客户端
|
||||
### Gemini 客户端
|
||||
|
||||
你有没有想过,如果万维网走的是一条完全不同的路线,不采用 CSS 和客户端脚本,你的互联网浏览体验会如何?[Gemini][15] 是 HTTPS 协议的现代替代品,尽管它并不打算取代 HTTPS 协议。[stenstorp/gemini][16] COPR 项目提供了各种客户端来浏览 Gemini _网站_,有 [Castor][17]、[Dragonstone][18]、[Kristall][19] 和 [Lagrange][20]。
|
||||
|
||||
@ -41,9 +39,9 @@ sudo dnf install ytfzf
|
||||
|
||||
![][22]
|
||||
|
||||
#### [][23] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][16]目前为 Fedora 32、33、34 和 Fedora Rawhide 提供 Gemini 客户端。EPEL 7 和 8,以及 CentOS Stream 也可使用。要安装浏览器,请从这里显示的安装命令中选择:
|
||||
该 [仓库][16] 目前为 Fedora 32、33、34 和 Fedora Rawhide 提供 Gemini 客户端。EPEL 7 和 8,以及 CentOS Stream 也可使用。要安装浏览器,请从这里显示的安装命令中选择:
|
||||
|
||||
```
|
||||
sudo dnf copr enable stenstorp/gemini
|
||||
@ -54,22 +52,22 @@ sudo dnf install kristall
|
||||
sudo dnf install lagrange
|
||||
```
|
||||
|
||||
### [][24] Ly
|
||||
### Ly
|
||||
|
||||
[Ly][25] 是一个 Linux 和 BSD 的轻量级登录管理器。它有一个类似于 ncurses 的基于文本的用户界面。理论上,它应该支持所有的 X 桌面环境和窗口管理器(其中很多都[经过测试][26])。Ly 还提供了基本的 Wayland 支持(Sway 也工作良好)。在配置的某个地方,有一个复活节彩蛋选项,可以在背景中启用著名的 [PSX DOOM fire][27] 动画,就其本身而言,值得一试。
|
||||
[Ly][25] 是一个 Linux 和 BSD 的轻量级登录管理器。它有一个类似于 ncurses 的基于文本的用户界面。理论上,它应该支持所有的 X 桌面环境和窗口管理器(其中很多都 [经过测试][26])。Ly 还提供了基本的 Wayland 支持(Sway 也工作良好)。在配置的某个地方,有一个复活节彩蛋选项,可以在背景中启用著名的 [PSX DOOM fire][27] 动画,就其本身而言,值得一试。
|
||||
|
||||
![][28]
|
||||
|
||||
#### [][29] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][30]目前为 Fedora 32、33 和 Fedora Rawhide 提供 Ly。要安装它,请使用以下命令:
|
||||
该 [仓库][30] 目前为 Fedora 32、33 和 Fedora Rawhide 提供 Ly。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable dhalucario/ly
|
||||
sudo dnf install ly
|
||||
```
|
||||
|
||||
在将 Ly 设置为系统登录界面之前,请在终端中运行 _ly_ 命令以确保其正常工作。然后关闭当前的登录管理器,启用 Ly。
|
||||
在将 Ly 设置为系统登录界面之前,请在终端中运行 `ly` 命令以确保其正常工作。然后关闭当前的登录管理器,启用 Ly。
|
||||
|
||||
```
|
||||
sudo systemctl disable gdm
|
||||
@ -78,22 +76,22 @@ sudo systemctl enable ly
|
||||
|
||||
最后,重启计算机,使其更改生效。
|
||||
|
||||
### [][31] AWS CLI v2
|
||||
### AWS CLI v2
|
||||
|
||||
[AWS CLI v2][32] 带来基于社区反馈进行的稳健而有条理的演变,而不是对原有客户端的大规模重新设计。它引入了配置凭证的新机制,现在允许用户从 AWS 控制台中生成的 _.csv_ 文件导入凭证。它还提供了对 AWS SSO 的支持。其他大的改进是服务端自动补全,以及交互式参数生成。一个新功能是交互式向导,它提供了更高层次的抽象,并结合多个 AWS API 调用来创建、更新或删除 AWS 资源。
|
||||
[AWS CLI v2][32] 带来基于社区反馈进行的稳健而有条理的演变,而不是对原有客户端的大规模重新设计。它引入了配置凭证的新机制,现在允许用户从 AWS 控制台中生成的 `.csv` 文件导入凭证。它还提供了对 AWS SSO 的支持。其他主要改进是服务端自动补全,以及交互式参数生成。一个新功能是交互式向导,它提供了更高层次的抽象,并结合多个 AWS API 调用来创建、更新或删除 AWS 资源。
|
||||
|
||||
![][33]
|
||||
|
||||
#### [][34] 安装说明
|
||||
#### 安装说明
|
||||
|
||||
该[仓库][35]目前为 Fedora Linux 32、33、34 和 Fedora Rawhide 提供 AWS CLI v2。要安装它,请使用以下命令:
|
||||
该 [仓库][35] 目前为 Fedora Linux 32、33、34 和 Fedora Rawhide 提供 AWS CLI v2。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable spot/aws-cli-2
|
||||
sudo dnf install aws-cli-2
|
||||
```
|
||||
|
||||
自然地,访问 AWS 账户是必要的。
|
||||
自然地,访问 AWS 账户凭证是必要的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -102,7 +100,7 @@ via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-march-202
|
||||
作者:[Jakub Kadlčík][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,300 @@
|
||||
[#]: subject: (5 everyday sysadmin tasks to automate with Ansible)
|
||||
[#]: via: (https://opensource.com/article/21/3/ansible-sysadmin)
|
||||
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13256-1.html)
|
||||
|
||||
用 Ansible 自动化系统管理员的 5 个日常任务
|
||||
======
|
||||
|
||||
> 通过使用 Ansible 自动执行可重复的日常任务,提高工作效率并避免错误。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/31/233904oo7q68eo2njfmf8o.jpg)
|
||||
|
||||
如果你讨厌执行重复性的任务,那么我有一个提议给你,去学习 [Ansible][2]!
|
||||
|
||||
Ansible 是一个工具,它可以帮助你更轻松、更快速地完成日常任务,这样你就可以更有效地利用时间,比如学习重要的新技术。对于系统管理员来说,它是一个很好的工具,因为它可以帮助你实现标准化,并在日常活动中进行协作,包括:
|
||||
|
||||
1. 安装、配置和调配服务器和应用程序;
|
||||
2. 定期更新和升级系统;
|
||||
3. 监测、减轻和排除问题。
|
||||
|
||||
通常,许多这些基本的日常任务都需要手动步骤,而根据个人的技能的不同,可能会造成不一致并导致配置发生漂移。这在小规模的实施中可能是可以接受的,因为你管理一台服务器,并且知道自己在做什么。但当你管理数百或数千台服务器时会发生什么?
|
||||
|
||||
如果不小心,这些手动的、可重复的任务可能会因为人为的错误而造成延误和问题,而这些错误可能会影响你及你的组织的声誉。
|
||||
|
||||
这就是自动化的价值所在。而 [Ansible][3] 是自动化这些可重复的日常任务的完美工具。
|
||||
|
||||
自动化的一些原因是:
|
||||
|
||||
1. 你想要一个一致和稳定的环境。
|
||||
2. 你想要促进标准化。
|
||||
3. 你希望减少停机时间,减少严重事故案例,以便可以享受生活。
|
||||
4. 你想喝杯啤酒,而不是排除故障问题!
|
||||
|
||||
本文提供了一些系统管理员可以使用 Ansible 自动化的日常任务的例子。我把本文中的剧本和角色放到了 GitHub 上的 [系统管理员任务仓库][4] 中,以方便你使用它们。
|
||||
|
||||
这些剧本的结构是这样的(我的注释前面有 `==>`)。
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# tree -L 2
|
||||
.
|
||||
├── ansible.cfg ==> 负责控制 Ansible 行为的配置文件
|
||||
├── ansible.log
|
||||
├── inventory
|
||||
│ ├── group_vars
|
||||
│ ├── hosts ==> 包含我的目标服务器列表的清单文件
|
||||
│ └── host_vars
|
||||
├── LICENSE
|
||||
├── playbooks ==> 包含我们将在本文中使用的剧本的目录
|
||||
│ ├── c_logs.yml
|
||||
│ ├── c_stats.yml
|
||||
│ ├── c_uptime.yml
|
||||
│ ├── inventory
|
||||
│ ├── r_cron.yml
|
||||
│ ├── r_install.yml
|
||||
│ └── r_script.yml
|
||||
├── README.md
|
||||
├── roles ==> 包含我们将在本文中使用的角色的目录
|
||||
│ ├── check_logs
|
||||
│ ├── check_stats
|
||||
│ ├── check_uptime
|
||||
│ ├── install_cron
|
||||
│ ├── install_tool
|
||||
│ └── run_scr
|
||||
└── templates ==> 包含 jinja 模板的目录
|
||||
├── cron_output.txt.j2
|
||||
├── sar.txt.j2
|
||||
└── scr_output.txt.j2
|
||||
```
|
||||
|
||||
清单类似这样的:
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# cat inventory/hosts
|
||||
[rhel8]
|
||||
master ansible_ssh_host=192.168.1.12
|
||||
workernode1 ansible_ssh_host=192.168.1.15
|
||||
|
||||
[rhel8:vars]
|
||||
ansible_user=ansible ==> 请用你的 ansible 用户名更新它
|
||||
```
|
||||
|
||||
这里有五个你可以用 Ansible 自动完成的日常系统管理任务。
|
||||
|
||||
### 1、检查服务器的正常运行时间
|
||||
|
||||
你需要确保你的服务器一直处于正常运行状态。机构会拥有企业监控工具来监控服务器和应用程序的正常运行时间,但自动监控工具时常会出现故障,你需要登录进去验证一台服务器的状态。手动验证每台服务器的正常运行时间需要花费大量的时间。你的服务器越多,你需要花费的时间就越长。但如果有了自动化,这种验证可以在几分钟内完成。
|
||||
|
||||
使用 [check_uptime][5] 角色和 `c_uptime.yml` 剧本:
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# ansible-playbook -i inventory/hosts playbooks/c_uptime.yml -k
|
||||
SSH password:
|
||||
PLAY [Check Uptime for Servers] ****************************************************************************************************************************************
|
||||
TASK [check_uptime : Capture timestamp] *************************************************************************************************
|
||||
.
|
||||
截断...
|
||||
.
|
||||
PLAY RECAP *************************************************************************************************************************************************************
|
||||
master : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
workernode1 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
[root@homebase 6_sysadmin_tasks]#
|
||||
```
|
||||
|
||||
剧本的输出是这样的:
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# cat /var/tmp/uptime-master-20210221004417.txt
|
||||
-----------------------------------------------------
|
||||
Uptime for master
|
||||
-----------------------------------------------------
|
||||
00:44:17 up 44 min, 2 users, load average: 0.01, 0.09, 0.09
|
||||
-----------------------------------------------------
|
||||
[root@homebase 6_sysadmin_tasks]# cat /var/tmp/uptime-workernode1-20210221184525.txt
|
||||
-----------------------------------------------------
|
||||
Uptime for workernode1
|
||||
-----------------------------------------------------
|
||||
18:45:26 up 44 min, 2 users, load average: 0.01, 0.01, 0.00
|
||||
-----------------------------------------------------
|
||||
```
|
||||
|
||||
使用 Ansible,你可以用较少的努力以人类可读的格式获得多个服务器的状态,[Jinja 模板][6] 允许你根据自己的需要调整输出。通过更多的自动化,你可以按计划运行,并通过电子邮件发送输出,以达到报告的目的。
|
||||
|
||||
### 2、配置额外的 cron 作业
|
||||
|
||||
你需要根据基础设施和应用需求定期更新服务器的计划作业。这似乎是一项微不足道的工作,但必须正确且持续地完成。想象一下,如果你对数百台生产服务器进行手动操作,这需要花费多少时间。如果做错了,就会影响生产应用程序,如果计划的作业重叠,就会导致应用程序停机或影响服务器性能。
|
||||
|
||||
使用 [install_cron][7] 角色和 `r_cron.yml` 剧本:
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# ansible-playbook -i inventory/hosts playbooks/r_cron.yml -k
|
||||
SSH password:
|
||||
PLAY [Install additional cron jobs for root] ***************************************************************************************************************************
|
||||
.
|
||||
截断...
|
||||
.
|
||||
PLAY RECAP *************************************************************************************************************************************************************
|
||||
master : ok=10 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
workernode1 : ok=10 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
```
|
||||
|
||||
验证剧本的结果:
|
||||
|
||||
```
|
||||
[root@homebase 6_sysadmin_tasks]# ansible -i inventory/hosts all -m shell -a "crontab -l" -k
|
||||
SSH password:
|
||||
master | CHANGED | rc=0 >>
|
||||
1 2 3 4 5 /usr/bin/ls /tmp
|
||||
#Ansible: Iotop Monitoring
|
||||
0 5,2 * * * /usr/sbin/iotop -b -n 1 >> /var/tmp/iotop.log 2>> /var/tmp/iotop.err
|
||||
workernode1 | CHANGED | rc=0 >>
|
||||
1 2 3 4 5 /usr/bin/ls /tmp
|
||||
#Ansible: Iotop Monitoring
|
||||
0 5,2 * * * /usr/sbin/iotop -b -n 1 >> /var/tmp/iotop.log 2>> /var/tmp/iotop.err
|
||||
```
|
||||
|
||||
使用 Ansible,你可以以快速和一致的方式更新所有服务器上的 crontab 条目。你还可以使用一个简单的点对点 Ansible 命令来报告更新后的 crontab 的状态,以验证最近应用的变化。
|
||||
|
||||
### 3、收集服务器统计和 sars
|
||||
|
||||
在常规的故障排除过程中,为了诊断服务器性能或应用程序问题,你需要收集<ruby>系统活动报告<rt>system activity reports</rt></ruby>(sars)和服务器统计。在大多数情况下,服务器日志包含非常重要的信息,开发人员或运维团队需要这些信息来帮助解决影响整个环境的具体问题。
|
||||
|
||||
安全团队在进行调查时非常特别,大多数时候,他们希望查看多个服务器的日志。你需要找到一种简单的方法来收集这些文档。如果你能把收集任务委托给他们就更好了。
|
||||
|
||||
通过 [check_stats][8] 角色和 `c_stats.yml` 剧本来完成这个任务:
|
||||
|
||||
```
|
||||
$ ansible-playbook -i inventory/hosts playbooks/c_stats.yml
|
||||
|
||||
PLAY [Check Stats/sar for Servers] ***********************************************************************************************************************************
|
||||
|
||||
TASK [check_stats : Get current date time] ***************************************************************************************************************************
|
||||
changed: [master]
|
||||
changed: [workernode1]
|
||||
.
|
||||
截断...
|
||||
.
|
||||
PLAY RECAP ***********************************************************************************************************************************************************
|
||||
master : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
workernode1 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
```
|
||||
|
||||
输出看起来像这样:
|
||||
|
||||
```
|
||||
$ cat /tmp/sar-workernode1-20210221214056.txt
|
||||
-----------------------------------------------------
|
||||
sar output for workernode1
|
||||
-----------------------------------------------------
|
||||
Linux 4.18.0-193.el8.x86_64 (node1) 21/02/21 _x86_64_ (2 CPU)
|
||||
21:39:30 LINUX RESTART (2 CPU)
|
||||
-----------------------------------------------------
|
||||
```
|
||||
|
||||
### 4、收集服务器日志
|
||||
|
||||
除了收集服务器统计和 sars 信息,你还需要不时地收集日志,尤其是当你需要帮助调查问题时。
|
||||
|
||||
通过 [check_logs][9] 角色和 `r_cron.yml` 剧本来实现:
|
||||
|
||||
```
|
||||
$ ansible-playbook -i inventory/hosts playbooks/c_logs.yml -k
|
||||
SSH password:
|
||||
|
||||
PLAY [Check Logs for Servers] ****************************************************************************************************************************************
|
||||
.
|
||||
截断...
|
||||
.
|
||||
TASK [check_logs : Capture Timestamp] ********************************************************************************************************************************
|
||||
changed: [master]
|
||||
changed: [workernode1]
|
||||
PLAY RECAP ***********************************************************************************************************************************************************
|
||||
master : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
workernode1 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
```
|
||||
|
||||
为了确认输出,打开转储位置生成的文件。日志应该是这样的:
|
||||
|
||||
```
|
||||
$ cat /tmp/logs-workernode1-20210221214758.txt | more
|
||||
-----------------------------------------------------
|
||||
Logs gathered: /var/log/messages for workernode1
|
||||
-----------------------------------------------------
|
||||
|
||||
Feb 21 18:00:27 node1 kernel: Command line: BOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-193.el8.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto resume=/dev/mapper/rhel
|
||||
-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet
|
||||
Feb 21 18:00:27 node1 kernel: Disabled fast string operations
|
||||
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
|
||||
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
|
||||
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
|
||||
Feb 21 18:00:27 node1 kernel: x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256
|
||||
Feb 21 18:00:27 node1 kernel: x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'compacted' format.
|
||||
```
|
||||
|
||||
### 5、安装或删除软件包和软件
|
||||
|
||||
你需要能够持续快速地在系统上安装和更新软件和软件包。缩短安装或更新软件包和软件所需的时间,可以避免服务器和应用程序不必要的停机时间。
|
||||
|
||||
通过 [install_tool][10] 角色和 `r_install.yml` 剧本来实现这一点:
|
||||
|
||||
```
|
||||
$ ansible-playbook -i inventory/hosts playbooks/r_install.yml -k
|
||||
SSH password:
|
||||
PLAY [Install additional tools/packages] ***********************************************************************************
|
||||
|
||||
TASK [install_tool : Install specified tools in the role vars] *************************************************************
|
||||
ok: [master] => (item=iotop)
|
||||
ok: [workernode1] => (item=iotop)
|
||||
ok: [workernode1] => (item=traceroute)
|
||||
ok: [master] => (item=traceroute)
|
||||
|
||||
PLAY RECAP *****************************************************************************************************************
|
||||
master : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
workernode1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
```
|
||||
|
||||
这个例子安装了在 vars 文件中定义的两个特定包和版本。使用 Ansible 自动化,你可以比手动安装更快地安装多个软件包或软件。你也可以使用 vars 文件来定义你要安装的软件包的版本。
|
||||
|
||||
```
|
||||
$ cat roles/install_tool/vars/main.yml
|
||||
---
|
||||
# vars file for install_tool
|
||||
ins_action: absent
|
||||
package_list:
|
||||
- iotop-0.6-16.el8.noarch
|
||||
- traceroute
|
||||
```
|
||||
|
||||
### 拥抱自动化
|
||||
|
||||
要成为一名有效率的系统管理员,你需要接受自动化来鼓励团队内部的标准化和协作。Ansible 使你能够在更少的时间内做更多的事情,这样你就可以将时间花在更令人兴奋的项目上,而不是做重复的任务,如管理你的事件和问题管理流程。
|
||||
|
||||
有了更多的空闲时间,你可以学习更多的知识,让自己可以迎接下一个职业机会的到来。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/ansible-sysadmin
|
||||
|
||||
作者:[Mike Calizo][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/mcalizo
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/gears_devops_learn_troubleshooting_lightbulb_tips_520.png?itok=HcN38NOk (Tips and gears turning)
|
||||
[2]: https://www.ansible.com/
|
||||
[3]: https://opensource.com/tags/ansible
|
||||
[4]: https://github.com/mikecali/6_sysadmin_tasks
|
||||
[5]: https://github.com/mikecali/6_sysadmin_tasks/tree/main/roles/check_uptime
|
||||
[6]: https://docs.ansible.com/ansible/latest/user_guide/playbooks_templating.html
|
||||
[7]: https://github.com/mikecali/6_sysadmin_tasks/tree/main/roles/install_cron
|
||||
[8]: https://github.com/mikecali/6_sysadmin_tasks/tree/main/roles/check_stats
|
||||
[9]: https://github.com/mikecali/6_sysadmin_tasks/tree/main/roles/check_logs
|
||||
[10]: https://github.com/mikecali/6_sysadmin_tasks/tree/main/roles/install_tool
|
75
published/202103/20210323 3 new Java tools to try in 2021.md
Normal file
75
published/202103/20210323 3 new Java tools to try in 2021.md
Normal file
@ -0,0 +1,75 @@
|
||||
[#]: subject: (3 new Java tools to try in 2021)
|
||||
[#]: via: (https://opensource.com/article/21/3/enterprise-java-tools)
|
||||
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13249-1.html)
|
||||
|
||||
2021 年要尝试的 3 个新的 Java 工具
|
||||
======
|
||||
|
||||
> 通过这三个工具和框架,为你的企业级 Java 应用和你的职业生涯提供助力。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202103/29/212649w9j5e05b0ppi9bew.jpg)
|
||||
|
||||
尽管在 Kubernetes 上广泛使用 [Python][2]、[Go][3] 和 [Node.js][4] 实现 [人工智能][5] 和机器学习应用以及 [无服务函数][6],但 Java 技术仍然在开发企业应用中发挥着关键作用。根据 [开发者经济学][7] 的数据,在 2020 年第三季度,全球有 800 万名企业 Java 开发者。
|
||||
|
||||
虽然这门语言已经存在了超过 25 年,但 Java 世界中总是有新的趋势、工具和框架,可以为你的应用和你的职业生涯赋能。
|
||||
|
||||
绝大多数 Java 框架都是为具有动态行为的长时间运行的进程而设计的,这些动态行为用于运行可变的应用服务器,例如物理服务器和虚拟机。自从 Kubernetes 容器在 2014 年发布以来,情况已经发生了变化。在 Kubernetes 上使用 Java 应用的最大问题是通过减少内存占用、加快启动和响应时间以及减少文件大小来优化应用性能。
|
||||
|
||||
### 3 个值得考虑的新 Java 框架和工具
|
||||
|
||||
Java 开发人员也一直在寻找更简便的方法,将闪亮的新开源工具和项目集成到他们的 Java 应用和日常工作中。这极大地提高了开发效率,并激励更多的企业和个人开发者继续使用 Java 栈。
|
||||
|
||||
当试图满足上述企业 Java 生态系统的期望时,这三个新的 Java 框架和工具值得你关注。
|
||||
|
||||
#### 1、Quarkus
|
||||
|
||||
[Quarkus][8] 旨在以惊人的快速启动时间、超低的常驻内存集(RSS)和高密度内存利用率,在 Kubernetes 等容器编排平台中开发云原生的微服务和无服务。根据 JRebel 的 [第九届全球 Java 开发者生产力年度报告][9],Java 开发者对 Quarkus 的使用率从不到 1% 上升到 6%,[Micronaut][10] 和 [Vert.x][11] 均从去年的 1% 左右分别增长到 4% 和 2%。
|
||||
|
||||
#### 2、Eclipse JKube
|
||||
|
||||
[Eclipse JKube][12] 使 Java 开发者能够使用 [Docker][13]、[Jib][14] 或 [Source-To-Image][15] 构建策略,基于云原生 Java 应用构建容器镜像。它还能在编译时生成 Kubernetes 和 OpenShift 清单,并改善开发人员对调试、观察和日志工具的体验。
|
||||
|
||||
#### 3、MicroProfile
|
||||
|
||||
[MicroProfile][16] 解决了与优化企业 Java 的微服务架构有关的最大问题,而无需采用新的框架或重构整个应用。此外,MicroProfile [规范][17](即 Health、Open Tracing、Open API、Fault Tolerance、Metrics、Config)继续与 [Jakarta EE][18] 的实现保持一致。
|
||||
|
||||
### 总结
|
||||
|
||||
很难说哪个 Java 框架或工具是企业 Java 开发人员实现的最佳选择。只要 Java 栈还有改进的空间,并能加速企业业务的发展,我们就可以期待新的框架、工具和平台的出现,比如上面的三个。花点时间看看它们是否能在 2021 年改善你的企业 Java 应用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/enterprise-java-tools
|
||||
|
||||
作者:[Daniel Oh][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/daniel-oh
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://opensource.com/resources/python
|
||||
[3]: https://opensource.com/article/18/11/learning-golang
|
||||
[4]: https://opensource.com/article/18/7/node-js-interactive-cli
|
||||
[5]: https://opensource.com/article/18/12/how-get-started-ai
|
||||
[6]: https://opensource.com/article/19/4/enabling-serverless-kubernetes
|
||||
[7]: https://developereconomics.com/
|
||||
[8]: https://quarkus.io/
|
||||
[9]: https://www.jrebel.com/resources/java-developer-productivity-report-2021
|
||||
[10]: https://micronaut.io/
|
||||
[11]: https://vertx.io/
|
||||
[12]: https://www.eclipse.org/jkube/
|
||||
[13]: https://opensource.com/resources/what-docker
|
||||
[14]: https://github.com/GoogleContainerTools/jib
|
||||
[15]: https://www.openshift.com/blog/create-s2i-builder-image
|
||||
[16]: https://opensource.com/article/18/1/eclipse-microprofile
|
||||
[17]: https://microprofile.io/
|
||||
[18]: https://opensource.com/article/18/5/jakarta-ee
|
@ -0,0 +1,73 @@
|
||||
[#]: subject: (Affordable high-temperature 3D printers at home)
|
||||
[#]: via: (https://opensource.com/article/21/3/desktop-3d-printer)
|
||||
[#]: author: (Joshua Pearce https://opensource.com/users/jmpearce)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13255-1.html)
|
||||
|
||||
在家就能用得起的高温 3D 打印机
|
||||
======
|
||||
|
||||
> 有多实惠?低于 1000 美元。
|
||||
|
||||
![High-temperature 3D-printed mask][1]
|
||||
|
||||
3D 打印机从 20 世纪 80 年代就已经出现了,但是由于 [RepRap][2] 项目的出现,它们直到获得开源才受到人们的关注。RepRap 意即<ruby>自我复制快速原型机<rt>self-replicating rapid prototyper</rt></ruby>,它是一种基本上可以自己打印的 3D 打印机。它的开源计划[2004 年][3] 发布之后,导致 3D 打印机的成本从几十万美金降到了几百美金。
|
||||
|
||||
这些开源的桌面工具一直局限于 ABS 等低性能、低温热塑性塑料(如乐高积木)。市场上有几款高温打印机,但其高昂的成本(几万到几十万美元)使大多数人无法获得。直到最近,它们才参与了很多竞争,因为它们被一项专利 (US6722872B1) 锁定,该专利于 2021 年 2 月 27 日[到期][4]。
|
||||
|
||||
随着这个路障的消除,我们即将看到高温、低成本、熔融纤维 3D 打印机的爆发。
|
||||
|
||||
价格低到什么程度?低于 1000 美元如何。
|
||||
|
||||
在疫情最严重的时候,我的团队赶紧发布了一个 [开源高温 3D 打印机][5] 的设计,用于制造可高温消毒的个人防护装备(PPE)。该项目的想法是让人们能够 [用高温材料打印 PPE][6](如口罩),并将它放入家用烤箱进行消毒。我们称我们的设备为 Cerberus,它具有以下特点:
|
||||
|
||||
1. 可达到 200℃ 的加热床
|
||||
2. 可达到 500℃ 的热源
|
||||
3. 带有 1kW 加热器核心的隔离式加热室。
|
||||
4. 主电源(交流电源)电压室和床身加热,以便快速启动。
|
||||
|
||||
你可以用现成的零件来构建这个项目,其中一些零件你可以打印,价格不到 1000 美元。它可以成功打印聚醚酮酮 (PEKK) 和聚醚酰亚胺(PEI,以商品名 Ultem 出售)。这两种材料都比现在低成本打印机能打印的任何材料强得多。
|
||||
|
||||
![PPE printer][7]
|
||||
|
||||
这款高温 3D 打印机的设计是有三个头,但我们发布的时候只有一个头。Cerberus 是以希腊神话中的三头冥界看门狗命名的。通常情况下,我们不会发布只有一个头的打印机,但疫情改变了我们的优先级。[开源社区团结起来][9],帮助解决早期的供应不足,许多桌面 3D 打印机都在产出有用的产品,以帮助保护人们免受 COVID 的侵害。
|
||||
|
||||
那另外两个头呢?
|
||||
|
||||
其他两个头是为了高温熔融颗粒制造(例如,这个开源的 [3D打印机][10] 的高温版本)并铺设金属线(像在 [这个设计][11] 中),以建立一个开源的热交换器。Cerberus 打印机的其他功能可能是一个自动喷嘴清洁器和在高温下打印连续纤维的方法。另外,你还可以在转台上安装任何你喜欢的东西来制造高端产品。
|
||||
|
||||
把一个盒子放在 3D 打印机周围,而把电子元件留在外面的 [专利][12] 到期,为高温家用 3D 打印机铺平了道路,这将使这些设备以合理的成本从单纯的玩具变为工业工具。
|
||||
|
||||
已经有公司在 RepRap 传统的基础上,将这些低成本系统推向市场(例如,1250 美元的 [Creality3D CR-5 Pro][13] 3D 打印机可以达到 300℃)。Creality 销售最受欢迎的桌面 3D 打印机,并开源了部分设计。
|
||||
|
||||
然而,要打印超高端工程聚合物,这些打印机需要达到 350℃ 以上。开源计划已经可以帮助桌面 3D 打印机制造商开始与垄断公司竞争,这些公司由于躲在专利背后,已经阻碍了 3D 打印 20 年。期待低成本、高温桌面 3D 打印机的竞争将真正升温!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/desktop-3d-printer
|
||||
|
||||
作者:[Joshua Pearce][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/jmpearce
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/3d_printer_mask.jpg?itok=5ePZghTW (High-temperature 3D-printed mask)
|
||||
[2]: https://reprap.org/wiki/RepRap
|
||||
[3]: https://reprap.org/wiki/Wealth_Without_Money
|
||||
[4]: https://3dprintingindustry.com/news/stratasys-heated-build-chamber-for-3d-printer-patent-us6722872b1-set-to-expire-this-week-185012/
|
||||
[5]: https://doi.org/10.1016/j.ohx.2020.e00130
|
||||
[6]: https://www.appropedia.org/Open_Source_High-Temperature_Reprap_for_3-D_Printing_Heat-Sterilizable_PPE_and_Other_Applications
|
||||
[7]: https://opensource.com/sites/default/files/uploads/ppe-hight3dp.png (PPE printer)
|
||||
[8]: https://www.gnu.org/licenses/fdl-1.3.html
|
||||
[9]: https://opensource.com/article/20/3/volunteer-covid19
|
||||
[10]: https://www.liebertpub.com/doi/10.1089/3dp.2019.0195
|
||||
[11]: https://www.appropedia.org/Open_Source_Multi-Head_3D_Printer_for_Polymer-Metal_Composite_Component_Manufacturing
|
||||
[12]: https://www.academia.edu/17609790/A_Novel_Approach_to_Obviousness_An_Algorithm_for_Identifying_Prior_Art_Concerning_3-D_Printing_Materials
|
||||
[13]: https://creality3d.shop/collections/cr-series/products/cr-5-pro-h-3d-printer
|
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 一族的一些常见行为。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/08/233233asbjasbfuiuosiha.jpg)
|
||||
|
||||
我是最近才 [皈依 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/
|
@ -3,25 +3,27 @@
|
||||
[#]: author: (Simon Arneaud https://theartofmachinery.com)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (DCOLIVERSUN)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13258-1.html)
|
||||
|
||||
Reverse Engineering a Docker Image
|
||||
一次 Docker 镜像的逆向工程
|
||||
======
|
||||
|
||||
This started with a consulting snafu: Government organisation A got government organisation B to develop a web application. Government organisation B subcontracted part of the work to somebody. Hosting and maintenance of the project was later contracted out to a private-sector company C. Company C discovered that the subcontracted somebody (who was long gone) had built a custom Docker image and made it a dependency of the build system, but without committing the original Dockerfile. That left company C with a contractual obligation to manage a Docker image they had no source code for. Company C calls me in once in a while to do various things, so doing something about this mystery meat Docker image became my job.
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/01/215523oajrgjo77irb7nun.jpg)
|
||||
|
||||
Fortunately, the Docker image format is a lot more transparent than it could be. A little detective work is needed, but a lot can be figured out just by pulling apart an image file. As an example, here’s a quick walkthrough of an image for [the Prettier code formatter][1].
|
||||
这要从一次咨询的失误说起:政府组织 A 让政府组织 B 开发一个 Web 应用程序。政府机构 B 把部分工作外包给某个人。后来,项目的托管和维护被外包给一家私人公司 C。C 公司发现,之前外包的人(已经离开很久了)构建了一个自定义的 Docker 镜像,并将其成为系统构建的依赖项,但这个人没有提交原始的 Dockerfile。C 公司有合同义务管理这个 Docker 镜像,可是他们他们没有源代码。C 公司偶尔叫我进去做各种工作,所以处理一些关于这个神秘 Docker 镜像的事情就成了我的工作。
|
||||
|
||||
First let’s get the Docker daemon to pull the image, then extract the image to a file:
|
||||
幸运的是,Docker 镜像的格式比想象的透明多了。虽然还需要做一些侦查工作,但只要解剖一个镜像文件,就能发现很多东西。例如,这里有一个 [Prettier 代码格式化][1] 的镜像可供快速浏览。
|
||||
|
||||
首先,让 Docker <ruby>守护进程<rt>daemon</rt></ruby>拉取镜像,然后将镜像提取到文件中:
|
||||
|
||||
```
|
||||
docker pull tmknom/prettier:2.0.5
|
||||
docker save tmknom/prettier:2.0.5 > prettier.tar
|
||||
```
|
||||
|
||||
Yes, the file is just an archive in the classic tarball format:
|
||||
是的,该文件只是一个典型 tarball 格式的归档文件:
|
||||
|
||||
```
|
||||
$ tar xvf prettier.tar
|
||||
@ -42,7 +44,7 @@ manifest.json
|
||||
repositories
|
||||
```
|
||||
|
||||
As you can see, Docker uses hashes a lot for naming things. Let’s have a look at the `manifest.json`. It’s in hard-to-read compacted JSON, but the [`jq` JSON Swiss Army knife][2] can pretty print it for us:
|
||||
如你所见,Docker 在命名时经常使用<ruby>哈希<rt>hash</rt></ruby>。我们看看 `manifest.json`。它是以难以阅读的压缩 JSON 写的,不过 [JSON 瑞士军刀 jq][2] 可以很好地打印 JSON:
|
||||
|
||||
```
|
||||
$ jq . manifest.json
|
||||
@ -61,7 +63,7 @@ $ jq . manifest.json
|
||||
]
|
||||
```
|
||||
|
||||
Note that the three layers correspond to the three hash-named directories. We’ll look at them later. For now, let’s look at the JSON file pointed to by the `Config` key. It’s a little long, so I’ll just dump the first bit here:
|
||||
请注意,这三个<ruby>层<rt>Layer</rt></ruby>对应三个以哈希命名的目录。我们以后再看。现在,让我们看看 `Config` 键指向的 JSON 文件。它有点长,所以我只在这里转储第一部分:
|
||||
|
||||
```
|
||||
$ jq . 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json | head -n 20
|
||||
@ -87,9 +89,9 @@ $ jq . 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json | h
|
||||
"Image": "sha256:93e72874b338c1e0734025e1d8ebe259d4f16265dc2840f88c4c754e1c01ba0a",
|
||||
```
|
||||
|
||||
The most interesting part is the `history` list, which lists every single layer in the image. A Docker image is a stack of these layers. Almost every statement in a Dockerfile turns into a layer that describes the changes to the image made by that statement. If you have a `RUN script.sh` statement that creates `really_big_file` that you then delete with `RUN rm really_big_file`, you actually get two layers in the Docker image: one that contains `really_big_file`, and one that contains a `.wh.really_big_file` tombstone to cancel it out. The overall image file isn’t any smaller. That’s why you often see Dockerfile statements chained together like `RUN script.sh && rm really_big_file` — it ensures all changes are coalesced into one layer.
|
||||
最重要的是 `history` 列表,它列出了镜像中的每一层。Docker 镜像由这些层堆叠而成。Dockerfile 中几乎每条命令都会变成一个层,描述该命令对镜像所做的更改。如果你执行 `RUN script.sh` 命令创建了 `really_big_file`,然后用 `RUN rm really_big_file` 命令删除文件,Docker 镜像实际生成两层:一个包含 `really_big_file`,一个包含 `.wh.really_big_file` 记录来删除它。整个镜像文件大小不变。这就是为什么你会经常看到像 `RUN script.sh && rm really_big_file` 这样的 Dockerfile 命令链接在一起——它保障所有更改都合并到一层中。
|
||||
|
||||
Here are all the layers recorded in the Docker image. Notice that most layers don’t change the filesystem image and are marked `"empty_layer": true`. Only three are non-empty, which matches up with what we saw before.
|
||||
以下是该 Docker 镜像中记录的所有层。注意,大多数层不改变文件系统镜像,并且 `empty_layer` 标记为 `true`。以下只有三个层是非空的,与我们之前描述的相符。
|
||||
|
||||
```
|
||||
$ jq .history 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json
|
||||
@ -162,11 +164,11 @@ m=${NODEJS_VERSION} && npm install -g prettier@${PRETTIER_VERSION} && np
|
||||
]
|
||||
```
|
||||
|
||||
Fantastic! All the statements are right there in the `created_by` fields, so we can almost reconstruct the Dockerfile just from this. Almost. The `ADD` statement at the very top doesn’t actually give us the file we need to `ADD`. `COPY` statements are also going to be opaque. We also lose `FROM` statements because they expand out to all the layers inherited from the base Docker image.
|
||||
太棒了!所有的命令都在 `created_by` 字段中,我们几乎可以用这些命令重建 Dockerfile。但不是完全可以。最上面的 `ADD` 命令实际上没有给我们需要添加的文件。`COPY` 命令也没有全部信息。我们还失去了 `FROM` 语句,因为它们扩展成了从基础 Docker 镜像继承的所有层。
|
||||
|
||||
We can group the layers by Dockerfile by looking at the timestamps. Most layer timestamps are under a minute apart, representing how long each layer took to build. However, the first two layers are from `2020-04-24`, and the rest of the layers are from `2020-04-29`. This would be because the first two layers are from a base Docker image. Ideally we’d figure out a `FROM` statement that gets us that image, so that we have a maintainable Dockerfile.
|
||||
我们可以通过查看<ruby>时间戳<rt>timestamp</rt></ruby>,按 Dockerfile 对层进行分组。大多数层的时间戳相差不到一分钟,代表每一层构建所需的时间。但是前两层是 `2020-04-24`,其余的是 `2020-04-29`。这是因为前两层来自一个基础 Docker 镜像。理想情况下,我们可以找出一个 `FROM` 命令来获得这个镜像,这样我们就有了一个可维护的 Dockerfile。
|
||||
|
||||
The `manifest.json` says that the first non-empty layer is `a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar`. Let’s take a look:
|
||||
`manifest.json` 展示第一个非空层是 `a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar`。让我们看看它:
|
||||
|
||||
```
|
||||
$ cd a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/
|
||||
@ -183,7 +185,7 @@ bin/chmod
|
||||
bin/chown
|
||||
```
|
||||
|
||||
Okay, that looks like it might be an operating system base image, which is what you’d expect from a typical Dockerfile. There are 488 entries in the tarball, and if you scroll through them, some interesting ones stand out:
|
||||
看起来它可能是一个<ruby>操作系统<rt>operating system</rt></ruby>基础镜像,这也是你期望从典型 Dockerfile 中看到的。Tarball 中有 488 个条目,如果你浏览一下,就会发现一些有趣的条目:
|
||||
|
||||
```
|
||||
...
|
||||
@ -203,7 +205,7 @@ etc/conf.d/
|
||||
...
|
||||
```
|
||||
|
||||
Sure enough, it’s an [Alpine][3] image, which you might have guessed if you noticed that the other layers used an `apk` command to install packages. Let’s extract the tarball and look around:
|
||||
果不其然,这是一个 [Alpine][3] 镜像,如果你注意到其他层使用 `apk` 命令安装软件包,你可能已经猜到了。让我们解压 tarball 看看:
|
||||
|
||||
```
|
||||
$ mkdir files
|
||||
@ -215,9 +217,9 @@ $ cat etc/alpine-release
|
||||
3.11.6
|
||||
```
|
||||
|
||||
If you pull `alpine:3.11.6` and extract it, you’ll find that there’s one non-empty layer inside it, and the `layer.tar` is identical to the `layer.tar` in the base layer of the Prettier image.
|
||||
如果你拉取、解压 `alpine:3.11.6`,你会发现里面有一个非空层,`layer.tar` 与 Prettier 镜像基础层中的 `layer.tar` 是一样的。
|
||||
|
||||
Just for the heck of it, what’s in the other two non-empty layers? The second layer is the main layer containing the Prettier installation. It has 528 entries, including Prettier, a bunch of dependencies and certificate updates:
|
||||
出于兴趣,另外两个非空层是什么?第二层是包含 Prettier 安装包的主层。它有 528 个条目,包含 Prettier、一堆依赖项和证书更新:
|
||||
|
||||
```
|
||||
...
|
||||
@ -257,14 +259,14 @@ usr/share/ca-certificates/mozilla/Actalis_Authentication_Root_CA.crt
|
||||
...
|
||||
```
|
||||
|
||||
The third layer is created by the `WORKDIR /work` statement, and it contains exactly one entry:
|
||||
第三层由 `WORKDIR /work` 命令创建,它只包含一个条目:
|
||||
|
||||
```
|
||||
$ tar tf 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar
|
||||
work/
|
||||
```
|
||||
|
||||
[The original Dockerfile is in the Prettier git repo.][4]
|
||||
[原始 Dockerfile 在 Prettier 的 git 仓库中][4]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -272,8 +274,8 @@ via: https://theartofmachinery.com/2021/03/18/reverse_engineering_a_docker_image
|
||||
|
||||
作者:[Simon Arneaud][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[DCOLIVERSUN](https://github.com/DCOLIVERSUN)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
192
published/20210324 Read and write files with Bash.md
Normal file
192
published/20210324 Read and write files with Bash.md
Normal file
@ -0,0 +1,192 @@
|
||||
[#]: subject: (Read and write files with Bash)
|
||||
[#]: via: (https://opensource.com/article/21/3/input-output-bash)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13259-1.html)
|
||||
|
||||
用 Bash 读写文件
|
||||
======
|
||||
|
||||
> 学习 Bash 读取和写入数据的不同方式,以及何时使用每种方法。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/01/223653bc334ac33e5e4pwe.jpg)
|
||||
|
||||
当你使用 Bash 编写脚本时,有时你需要从一个文件中读取数据或向一个文件写入数据。有时文件可能包含配置选项,而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言处理这个任务的方式都有些不同,本文将演示如何使用 Bash 和其他 [POSIX][2] shell 处理数据文件。
|
||||
|
||||
### 安装 Bash
|
||||
|
||||
如果你在使用 Linux,你可能已经有了 Bash。如果没有,你可以在你的软件仓库里找到它。
|
||||
|
||||
在 macOS 上,你可以使用默认终端,Bash 或 [Zsh][3],这取决于你运行的 macOS 版本。
|
||||
|
||||
在 Windows 上,有几种方法可以体验 Bash,包括微软官方支持的 [Windows Subsystem for Linux][4](WSL)。
|
||||
|
||||
安装 Bash 后,打开你最喜欢的文本编辑器并准备开始。
|
||||
|
||||
### 使用 Bash 读取文件
|
||||
|
||||
除了是 [shell][5] 之外,Bash 还是一种脚本语言。有几种方法可以从 Bash 中读取数据。你可以创建一种数据流并解析输出, 或者你可以将数据加载到内存中。这两种方法都是有效的获取信息的方法,但每种方法都有相当具体的用例。
|
||||
|
||||
#### 在 Bash 中援引文件
|
||||
|
||||
当你在 Bash 中 “<ruby>援引<rt>source</rt></ruby>” 一个文件时,你会让 Bash 读取文件的内容,期望它包含有效的数据,Bash 可以将这些数据放入它建立的数据模型中。你不会想要从旧文件中援引数据,但你可以使用这种方法来读取配置文件和函数。
|
||||
|
||||
(LCTT 译注:在 Bash 中,可以通过 `source` 或 `.` 命令来将一个文件读入,这个行为称为 “sourcing”,英文原意为“一次性(试)采购”、“寻找供应商”、“获得”等,考虑到 Bash 的语境和发音,我建议可以翻译为“援引”,或有不当,供大家讨论参考 —— wxy)
|
||||
|
||||
例如,创建一个名为 `example.sh` 的文件,并输入以下内容:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
greet opensource.com
|
||||
|
||||
echo "The meaning of life is $var"
|
||||
```
|
||||
|
||||
运行这段代码,看见失败了:
|
||||
|
||||
```
|
||||
$ bash ./example.sh
|
||||
./example.sh: line 3: greet: command not found
|
||||
The meaning of life is
|
||||
```
|
||||
|
||||
Bash 没有一个叫 `greet` 的命令,所以无法执行那一行,也没有一个叫 `var` 的变量记录,所以文件没有意义。为了解决这个问题,建立一个名为 `include.sh` 的文件:
|
||||
|
||||
```
|
||||
greet() {
|
||||
echo "Hello ${1}"
|
||||
}
|
||||
|
||||
var=42
|
||||
```
|
||||
|
||||
修改你的 `example.sh` 脚本,加入一个 `source` 命令:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
source include.sh
|
||||
|
||||
greet opensource.com
|
||||
|
||||
echo "The meaning of life is $var"
|
||||
```
|
||||
|
||||
运行脚本,可以看到工作了:
|
||||
|
||||
```
|
||||
$ bash ./example.sh
|
||||
Hello opensource.com
|
||||
The meaning of life is 42
|
||||
```
|
||||
|
||||
`greet` 命令被带入你的 shell 环境,因为它被定义在 `include.sh` 文件中,它甚至可以识别参数(本例中的 `opensource.com`)。变量 `var` 也被设置和导入。
|
||||
|
||||
#### 在 Bash 中解析文件
|
||||
|
||||
另一种让数据“进入” Bash 的方法是将其解析为数据流。有很多方法可以做到这一点. 你可以使用 `grep` 或 `cat` 或任何可以获取数据并管道输出到标准输出的命令。另外,你可以使用 Bash 内置的东西:重定向。重定向本身并不是很有用,所以在这个例子中,我也使用内置的 `echo` 命令来打印重定向的结果:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
echo $( < include.sh )
|
||||
```
|
||||
|
||||
将其保存为 `stream.sh` 并运行它来查看结果:
|
||||
|
||||
```
|
||||
$ bash ./stream.sh
|
||||
greet() { echo "Hello ${1}" } var=42
|
||||
$
|
||||
```
|
||||
|
||||
对于 `include.sh` 文件中的每一行,Bash 都会将该行打印(或 `echo`)到你的终端。先用管道把它传送到一个合适的解析器是用 Bash 读取数据的常用方法。例如, 假设 `include.sh` 是一个配置文件, 它的键和值对用一个等号(`=`)分开. 你可以用 `awk` 甚至 `cut` 来获取值:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
myVar=`grep var include.sh | cut -d'=' -f2`
|
||||
|
||||
echo $myVar
|
||||
```
|
||||
|
||||
试着运行这个脚本:
|
||||
|
||||
```
|
||||
$ bash ./stream.sh
|
||||
42
|
||||
```
|
||||
|
||||
### 用 Bash 将数据写入文件
|
||||
|
||||
无论你是要存储用户用你的应用创建的数据,还是仅仅是关于用户在应用中做了什么的元数据(例如,游戏保存或最近播放的歌曲),都有很多很好的理由来存储数据供以后使用。在 Bash 中,你可以使用常见的 shell 重定向将数据保存到文件中。
|
||||
|
||||
例如, 要创建一个包含输出的新文件, 使用一个重定向符号:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
TZ=UTC
|
||||
date > date.txt
|
||||
```
|
||||
|
||||
运行脚本几次:
|
||||
|
||||
```
|
||||
$ bash ./date.sh
|
||||
$ cat date.txt
|
||||
Tue Feb 23 22:25:06 UTC 2021
|
||||
$ bash ./date.sh
|
||||
$ cat date.txt
|
||||
Tue Feb 23 22:25:12 UTC 2021
|
||||
```
|
||||
|
||||
要追加数据,使用两个重定向符号:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
TZ=UTC
|
||||
date >> date.txt
|
||||
```
|
||||
|
||||
运行脚本几次:
|
||||
|
||||
```
|
||||
$ bash ./date.sh
|
||||
$ bash ./date.sh
|
||||
$ bash ./date.sh
|
||||
$ cat date.txt
|
||||
Tue Feb 23 22:25:12 UTC 2021
|
||||
Tue Feb 23 22:25:17 UTC 2021
|
||||
Tue Feb 23 22:25:19 UTC 2021
|
||||
Tue Feb 23 22:25:22 UTC 2021
|
||||
```
|
||||
|
||||
### Bash 轻松编程
|
||||
|
||||
Bash 的优势在于简单易学,因为只需要一些基本的概念,你就可以构建复杂的程序。完整的文档请参考 GNU.org 上的 [优秀的 Bash 文档][6]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/input-output-bash
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bash_command_line.png?itok=k4z94W2U (bash logo on green background)
|
||||
[2]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[3]: https://opensource.com/article/19/9/getting-started-zsh
|
||||
[4]: https://opensource.com/article/19/7/ways-get-started-linux#wsl
|
||||
[5]: https://www.redhat.com/sysadmin/terminals-shells-consoles
|
||||
[6]: http://gnu.org/software/bash
|
@ -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 替代方案
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/10/110720jc8hckngaqr6wch1.jpg)
|
||||
|
||||
[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
|
140
published/20210326 How to read and write files in C.md
Normal file
140
published/20210326 How to read and write files in C.md
Normal file
@ -0,0 +1,140 @@
|
||||
[#]: subject: (How to read and write files in C++)
|
||||
[#]: via: (https://opensource.com/article/21/3/ccc-input-output)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wyxplus)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13263-1.html)
|
||||
|
||||
如何用 C++ 读写文件
|
||||
======
|
||||
|
||||
> 如果你知道如何在 C++ 中使用输入输出(I/O)流,那么(原则上)你便能够处理任何类型的输入输出设备。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/02/224507a2fq6ofotf4ff4rf.jpg)
|
||||
|
||||
在 C++ 中,对文件的读写可以通过使用输入输出流与流运算符 `>>` 和 `<<` 来进行。当读写文件的时候,这些运算符被应用于代表硬盘驱动器上文件类的实例上。这种基于流的方法有个巨大的优势:从 C++ 的角度,无论你要读取或写入的内容是文件、数据库、控制台,亦或是你通过网络连接的另外一台电脑,这都无关紧要。因此,知道如何使用流运算符来写入文件能够被转用到其他领域。
|
||||
|
||||
### 输入输出流类
|
||||
|
||||
C++ 标准库提供了 [ios_base][2] 类。该类作为所有 I/O 流的基类,例如 [basic_ofstream][3] 和 [basic_ifstream][4]。本例将使用读/写字符的专用类型 `ifstream` 和 `ofstream`。
|
||||
|
||||
- `ofstream`:输出文件流,并且其能通过插入运算符 `<<` 来实现。
|
||||
- `ifstream`:输入文件流,并且其能通过提取运算符 `>>` 来实现。
|
||||
|
||||
该两种类型都是在头文件 `<fstream>` 中所定义。
|
||||
|
||||
从 `ios_base` 继承的类在写入时可被视为数据接收器,在从其读取时可被视为数据源,与数据本身完全分离。这种面向对象的方法使 <ruby>[关注点分离][5]<rt>separation of concerns</rt></ruby> 和 <ruby>[依赖注入][6]<rt>dependency injection</rt></ruby> 等概念易于实现。
|
||||
|
||||
### 一个简单的例子
|
||||
|
||||
本例程是非常简单:实例化了一个 `ofstream` 来写入,和实例化一个 `ifstream` 来读取。
|
||||
|
||||
```
|
||||
#include <iostream> // cout, cin, cerr etc...
|
||||
#include <fstream> // ifstream, ofstream
|
||||
#include <string>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string sFilename = "MyFile.txt";
|
||||
|
||||
/******************************************
|
||||
* *
|
||||
* WRITING *
|
||||
* *
|
||||
******************************************/
|
||||
|
||||
std::ofstream fileSink(sFilename); // Creates an output file stream
|
||||
|
||||
if (!fileSink) {
|
||||
std::cerr << "Canot open " << sFilename << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* std::endl will automatically append the correct EOL */
|
||||
fileSink << "Hello Open Source World!" << std::endl;
|
||||
|
||||
|
||||
/******************************************
|
||||
* *
|
||||
* READING *
|
||||
* *
|
||||
******************************************/
|
||||
|
||||
std::ifstream fileSource(sFilename); // Creates an input file stream
|
||||
|
||||
if (!fileSource) {
|
||||
std::cerr << "Canot open " << sFilename << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
else {
|
||||
// Intermediate buffer
|
||||
std::string buffer;
|
||||
|
||||
// By default, the >> operator reads word by workd (till whitespace)
|
||||
while (fileSource >> buffer)
|
||||
{
|
||||
std::cout << buffer << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
该代码可以在 [GitHub][7] 上查看。当你编译并且执行它时,你应该能获得以下输出:
|
||||
|
||||
![Console screenshot][8]
|
||||
|
||||
这是个简化的、适合初学者的例子。如果你想去使用该代码在你自己的应用中,请注意以下几点:
|
||||
|
||||
* 文件流在程序结束的时候自动关闭。如果你想继续执行,那么应该通过调用 `close()` 方法手动关闭。
|
||||
* 这些文件流类继承自 [basic_ios][10](在多个层次上),并且重载了 `!` 运算符。这使你可以进行简单的检查是否可以访问该流。在 [cppreference.com][11] 上,你可以找到该检查何时会(或不会)成功的概述,并且可以进一步实现错误处理。
|
||||
* 默认情况下,`ifstream` 停在空白处并跳过它。要逐行读取直到到达 [EOF][13] ,请使用 `getline(...)` 方法。
|
||||
* 为了读写二进制文件,请将 `std::ios::binary` 标志传递给构造函数:这样可以防止 [EOL][13] 字符附加到每一行。
|
||||
|
||||
### 从系统角度进行写入
|
||||
|
||||
写入文件时,数据将写入系统的内存写入缓冲区中。当系统收到系统调用 [sync][14] 时,此缓冲区的内容将被写入硬盘。这也是你在不告知系统的情况下,不要卸下 U 盘的原因。通常,守护进程会定期调用 `sync`。为了安全起见,也可以手动调用 `sync()`:
|
||||
|
||||
|
||||
```
|
||||
#include <unistd.h> // needs to be included
|
||||
|
||||
sync();
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
在 C++ 中读写文件并不那么复杂。更何况,如果你知道如何处理输入输出流,(原则上)那么你也知道如何处理任何类型的输入输出设备。对于各种输入输出设备的库能让你更容易地使用流运算符。这就是为什么知道输入输出流的流程会对你有所助益的原因。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/ccc-input-output
|
||||
|
||||
作者:[Stephan Avenwedde][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wyxplus](https://github.com/wyxplus)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hansic99
|
||||
[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://en.cppreference.com/w/cpp/io/ios_base
|
||||
[3]: https://en.cppreference.com/w/cpp/io/basic_ofstream
|
||||
[4]: https://en.cppreference.com/w/cpp/io/basic_ifstream
|
||||
[5]: https://en.wikipedia.org/wiki/Separation_of_concerns
|
||||
[6]: https://en.wikipedia.org/wiki/Dependency_injection
|
||||
[7]: https://github.com/hANSIc99/cpp_input_output
|
||||
[8]: https://opensource.com/sites/default/files/uploads/c_console_screenshot.png "Console screenshot"
|
||||
[9]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[10]: https://en.cppreference.com/w/cpp/io/basic_ios
|
||||
[11]: https://en.cppreference.com/w/cpp/io/basic_ios/operator!
|
||||
[12]: https://en.wikipedia.org/wiki/End-of-file
|
||||
[13]: https://en.wikipedia.org/wiki/Newline
|
||||
[14]: https://en.wikipedia.org/wiki/Sync_%28Unix%29
|
67
published/20210326 Why you should care about service mesh.md
Normal file
67
published/20210326 Why you should care about service mesh.md
Normal file
@ -0,0 +1,67 @@
|
||||
[#]: subject: (Why you should care about service mesh)
|
||||
[#]: via: (https://opensource.com/article/21/3/service-mesh)
|
||||
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13261-1.html)
|
||||
|
||||
为什么需要关心服务网格
|
||||
======
|
||||
|
||||
> 在微服务环境中,服务网格为开发和运营提供了好处。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/02/201409os5r13omp5p5bssb.jpg)
|
||||
|
||||
很多开发者不知道为什么要关心<ruby>[服务网格][2]<rt>Service Mesh</rt></ruby>。这是我在开发者见面会、会议和实践研讨会上关于云原生架构的微服务开发的演讲中经常被问到的问题。我的回答总是一样的:“只要你想简化你的微服务架构,它就应该运行在 Kubernetes 上。”
|
||||
|
||||
关于简化,你可能也想知道,为什么分布式微服务必须设计得如此复杂才能在 Kubernetes 集群上运行。正如本文所解释的那样,许多开发人员通过服务网格解决了微服务架构的复杂性,并通过在生产中采用服务网格获得了额外的好处。
|
||||
|
||||
### 什么是服务网格?
|
||||
|
||||
服务网格是一个专门的基础设施层,用于提供一个透明的、独立于代码的 (polyglot) 方式,以消除应用代码中的非功能性微服务能力。
|
||||
|
||||
![Before and After Service Mesh][3]
|
||||
|
||||
### 为什么服务网格对开发者很重要
|
||||
|
||||
当开发人员将微服务部署到云时,无论业务功能如何,他们都必须解决非功能性微服务功能,以避免级联故障。这些功能通常可以体现在服务发现、日志、监控、<ruby>韧性<rt>resiliency</rt></ruby>、认证、<ruby>弹性<rt>elasticity</rt></ruby>和跟踪等方面。开发人员必须花费更多的时间将它们添加到每个微服务中,而不是开发实际的业务逻辑,这使得微服务变得沉重而复杂。
|
||||
|
||||
随着企业加速向云计算转移,服务网格 可以提高开发人员的生产力。Kubernetes 加服务网格平台不需要让服务负责处理这些复杂的问题,也不需要在每个服务中添加更多的代码来处理云原生的问题,而是负责向运行在该平台上的任何应用(现有的或新的,用任何编程语言或框架)提供这些服务。那么微服务就可以轻量级,专注于其业务逻辑,而不是云原生的复杂性。
|
||||
|
||||
### 为什么服务网格对运维很重要
|
||||
|
||||
这并没有回答为什么运维团队需要关心在 Kubernetes 上运行云原生微服务的服务网格。因为运维团队必须确保在 Kubernetes 环境上的大型混合云和多云上部署新的云原生应用的强大安全性、合规性和可观察性。
|
||||
|
||||
服务网格由一个用于管理代理路由流量的控制平面和一个用于注入<ruby>边车<rt>Sidecar</rt></ruby>的数据平面组成。边车允许运维团队做一些比如添加第三方安全工具和追踪所有服务通信中的流量,以避免安全漏洞或合规问题。服务网格还可以通过在图形面板上可视化地跟踪指标来提高观察能力。
|
||||
|
||||
### 如何开始使用服务网格
|
||||
|
||||
对于开发者和运维人员,以及从应用开发到平台运维来说,服务网格可以更有效地管理云原生功能。
|
||||
|
||||
你可能想知道从哪里开始采用服务网格来配合你的微服务应用和架构。幸运的是,有许多开源的服务网格项目。许多云服务提供商也在他们的 Kubernetes 平台中提供 服务网格。
|
||||
|
||||
![CNCF Service Mesh Landscape][5]
|
||||
|
||||
你可以在 [CNCF Service Mesh Landscape][6] 页面中找到最受欢迎的服务网格项目和服务的链接。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/service-mesh
|
||||
|
||||
作者:[Daniel Oh][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/daniel-oh
|
||||
[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://www.redhat.com/en/topics/microservices/what-is-a-service-mesh
|
||||
[3]: https://opensource.com/sites/default/files/uploads/vm-vs-service-mesh.png (Before and After Service Mesh)
|
||||
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[5]: https://opensource.com/sites/default/files/uploads/service-mesh-providers.png (CNCF Service Mesh Landscape)
|
||||
[6]: https://landscape.cncf.io/card-mode?category=service-mesh&grouping=category
|
95
published/20210329 Manipulate data in files with Lua.md
Normal file
95
published/20210329 Manipulate data in files with Lua.md
Normal file
@ -0,0 +1,95 @@
|
||||
[#]: subject: (Manipulate data in files with Lua)
|
||||
[#]: via: (https://opensource.com/article/21/3/lua-files)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13268-1.html)
|
||||
|
||||
用 Lua 操作文件中的数据
|
||||
======
|
||||
|
||||
> 了解 Lua 如何处理数据的读写。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/05/102424yczwucc3xcuyzkgw.jpg)
|
||||
|
||||
有些数据是临时的,存储在 RAM 中,只有在应用运行时才有意义。但有些数据是要持久的,存储在硬盘上供以后使用。当你编程时,无论是简单的脚本还是复杂的工具套件,通常都需要读取和写入文件。有时文件可能包含配置选项,而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言都会以不同的方式处理这项任务,本文将演示如何使用 Lua 处理文件数据。
|
||||
|
||||
### 安装 Lua
|
||||
|
||||
如果你使用的是 Linux,你可以从你的发行版软件库中安装 Lua。在 macOS 上,你可以从 [MacPorts][2] 或 [Homebrew][3] 安装 Lua。在 Windows 上,你可以从 [Chocolatey][4] 安装 Lua。
|
||||
|
||||
安装 Lua 后,打开你最喜欢的文本编辑器并准备开始。
|
||||
|
||||
### 用 Lua 读取文件
|
||||
|
||||
Lua 使用 `io` 库进行数据输入和输出。下面的例子创建了一个名为 `ingest` 的函数来从文件中读取数据,然后用 `:read` 函数进行解析。在 Lua 中打开一个文件时,有几种模式可以启用。因为我只需要从这个文件中读取数据,所以我使用 `r`(代表“读”)模式:
|
||||
|
||||
```
|
||||
function ingest(file)
|
||||
local f = io.open(file, "r")
|
||||
local lines = f:read("*all")
|
||||
f:close()
|
||||
return(lines)
|
||||
end
|
||||
|
||||
myfile=ingest("example.txt")
|
||||
print(myfile)
|
||||
```
|
||||
|
||||
在这段代码中,注意到变量 `myfile` 是为了触发 `ingest` 函数而创建的,因此,它接收该函数返回的任何内容。`ingest` 函数返回文件的行数(从一个称为 `lines` 的变量中0。当最后一步打印 `myfile` 变量的内容时,文件的行数就会出现在终端中。
|
||||
|
||||
如果文件 `example.txt` 中包含了配置选项,那么我会写一些额外的代码来解析这些数据,可能会使用另一个 Lua 库,这取决于配置是以 INI 文件还是 YAML 文件或其他格式存储。如果数据是 SVG 图形,我会写额外的代码来解析 XML,可能会使用 Lua 的 SVG 库。换句话说,你的代码读取的数据一旦加载到内存中,就可以进行操作,但是它们都需要加载 `io` 库。
|
||||
|
||||
### 用 Lua 将数据写入文件
|
||||
|
||||
无论你是要存储用户用你的应用创建的数据,还是仅仅是关于用户在应用中做了什么的元数据(例如,游戏保存或最近播放的歌曲),都有很多很好的理由来存储数据供以后使用。在 Lua 中,这是通过 `io` 库实现的,打开一个文件,将数据写入其中,然后关闭文件:
|
||||
|
||||
```
|
||||
function exgest(file)
|
||||
local f = io.open(file, "a")
|
||||
io.output(f)
|
||||
io.write("hello world\n")
|
||||
io.close(f)
|
||||
end
|
||||
|
||||
exgest("example.txt")
|
||||
```
|
||||
|
||||
为了从文件中读取数据,我以 `r` 模式打开文件,但这次我使用 `a` (用于”追加“)将数据写到文件的末尾。因为我是将纯文本写入文件,所以我添加了自己的换行符(`/n`)。通常情况下,你并不是将原始文本写入文件,你可能会使用一个额外的库来代替写入一个特定的格式。例如,你可能会使用 INI 或 YAML 库来帮助编写配置文件,使用 XML 库来编写 XML,等等。
|
||||
|
||||
### 文件模式
|
||||
|
||||
在 Lua 中打开文件时,有一些保护措施和参数来定义如何处理文件。默认值是 `r`,允许你只读数据:
|
||||
|
||||
* `r` 只读
|
||||
* `w` 如果文件不存在,覆盖或创建一个新文件。
|
||||
* `r+` 读取和覆盖。
|
||||
* `a` 追加数据到文件中,或在文件不存在的情况下创建一个新文件。
|
||||
* `a+` 读取数据,将数据追加到文件中,或文件不存在的话,创建一个新文件。
|
||||
|
||||
还有一些其他的(例如,`b` 代表二进制格式),但这些是最常见的。关于完整的文档,请参考 [Lua.org/manual][5] 上的优秀 Lua 文档。
|
||||
|
||||
### Lua 和文件
|
||||
|
||||
和其他编程语言一样,Lua 有大量的库支持来访问文件系统来读写数据。因为 Lua 有一个一致且简单语法,所以很容易对任何格式的文件数据进行复杂的处理。试着在你的下一个软件项目中使用 Lua,或者作为 C 或 C++ 项目的 API。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/lua-files
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_metrics_analytics_desktop_laptop.png?itok=9QXd7AUr (Person standing in front of a giant computer screen with numbers, data)
|
||||
[2]: https://opensource.com/article/20/11/macports
|
||||
[3]: https://opensource.com/article/20/6/homebrew-mac
|
||||
[4]: https://opensource.com/article/20/3/chocolatey
|
||||
[5]: http://lua.org/manual
|
@ -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 提升到一个新的高度。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/08/125206uvglkoqzukhfk3uv.jpg)
|
||||
|
||||
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,98 @@
|
||||
[#]: subject: (NewsFlash: A Modern Open-Source Feed Reader With Feedly Support)
|
||||
[#]: via: (https://itsfoss.com/newsflash-feedreader/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (DCOLIVERSUN)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13264-1.html)
|
||||
|
||||
NewsFlash: 一款支持 Feedly 的现代开源 Feed 阅读器
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/03/001037r2udx6u6xqu5sqzu.jpg)
|
||||
|
||||
有些人可能认为 RSS 阅读器已经不再,但它们仍然坚持在这里,特别是当你不想让大科技算法来决定你应该阅读什么的时候。Feed 阅读器可以帮你自助选择阅读来源。
|
||||
|
||||
我最近遇到一个很棒的 RSS 阅读器 NewsFlash。它支持通过基于网页的 Feed 阅读器增加 feed,例如 [Feedly][1] 和 NewsBlur。这是一个很大的安慰,因为如果你已经使用这种服务,就不必人工导入 feed,这节省了你的工作。
|
||||
|
||||
NewsFlash 恰好是 [FeedReadeer][2] 的精神继承者,原来的 FeedReader 开发人员也参与其中。
|
||||
|
||||
如果你正在找适用的 RSS 阅读器,我们整理了 [Linux Feed 阅读器][3] 列表供您参考。
|
||||
|
||||
### NewsFlash: 一款补充网页 RSS 阅读器账户的 Feed 阅读器
|
||||
|
||||
![][4]
|
||||
|
||||
请注意,NewsFlash 并不只是针对基于网页的 RSS feed 账户量身定做的,你也可以选择使用本地 RSS feed,而不必在多设备间同步。
|
||||
|
||||
不过,如果你在用是任何一款支持的基于网页的 feed 阅读器,那么 NewsFlash 特别有用。
|
||||
|
||||
这里,我将重点介绍 NewsFlash 提供的一些功能。
|
||||
|
||||
### NewsFlash 功能
|
||||
|
||||
![][5]
|
||||
|
||||
* 支持桌面通知
|
||||
* 快速搜索、过滤
|
||||
* 支持标签
|
||||
* 便捷、可重定义的键盘快捷键
|
||||
* 本地 feed
|
||||
* OPML 文件导入/导出
|
||||
* 无需注册即可在 Feedly 库中轻松找到不同 RSS Feed
|
||||
* 支持自定义字体
|
||||
* 支持多主题(包括深色主题)
|
||||
* 启动/禁止缩略图
|
||||
* 细粒度调整定期同步间隔时间
|
||||
* 支持基于网页的 Feed 账户,例如 Feedly、Fever、NewsBlur、feedbin、Miniflux
|
||||
|
||||
除上述功能外,当你调整窗口大小时,还可以打开阅读器视图,这是一个细腻的补充功能。
|
||||
|
||||
![newsflash 截图1][6]
|
||||
|
||||
账户重新设置也很容易,这将删除所有本地数据。是的,你可以手动清除缓存并设置到期时间,并为你关注的所有 feed 设置一个用户数据存在本地的到期时间。
|
||||
|
||||
### 在 Linux 上安装 NewsFlash
|
||||
|
||||
你无法找到适用于各种 Linux 发行版的官方软件包,只有 [Flatpak][8]。
|
||||
|
||||
对于 Arch 用户,可以从 [AUR][9] 下载。
|
||||
|
||||
幸运的是,[Flatpak][10] 软件包可以让你轻松在 Linux 发行版上安装 NewsFlash。具体请参阅我们的 [Flatpak 指南][11]。
|
||||
|
||||
你可以参考 NewsFlash 的 [GitLab 页面][12] 去解决大部分问题。
|
||||
|
||||
### 结束语
|
||||
|
||||
我现在用 NewsFlash 作为桌面本地解决方案,不用基于网页的服务。你可以通过直接导出 OPML 文件在移动 feed 应用上得到相同的 feed。这已经被我验证过了。
|
||||
|
||||
用户界面易于使用,也提供了数一数二的新版 UX。虽然这个 RSS 阅读器看似简单,但提供了你可以找到的所有重要功能。
|
||||
|
||||
你怎么看 NewsFlash?你喜欢用其他类似产品吗?欢迎在评论区中分享你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/newsflash-feedreader/
|
||||
|
||||
作者:[Ankush Das][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://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://feedly.com/
|
||||
[2]: https://jangernert.github.io/FeedReader/
|
||||
[3]: https://itsfoss.com/feed-reader-apps-linux/
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/newsflash.jpg?resize=945%2C648&ssl=1
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/newsflash-screenshot.jpg?resize=800%2C533&ssl=1
|
||||
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/newsflash-screenshot-1.jpg?resize=800%2C532&ssl=1
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2018/04/best-feed-reader-apps-linux.jpg?fit=800%2C450&ssl=1
|
||||
[8]: https://flathub.org/apps/details/com.gitlab.newsflash
|
||||
[9]: https://itsfoss.com/aur-arch-linux/
|
||||
[10]: https://itsfoss.com/what-is-flatpak/
|
||||
[11]: https://itsfoss.com/flatpak-guide/
|
||||
[12]: https://gitlab.com/news-flash/news_flash_gtk
|
@ -0,0 +1,181 @@
|
||||
[#]: subject: (3 reasons I use the Git cherry-pick command)
|
||||
[#]: via: (https://opensource.com/article/21/3/git-cherry-pick)
|
||||
[#]: author: (Manaswini Das https://opensource.com/users/manaswinidas)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13305-1.html)
|
||||
|
||||
我使用 Git cherry-pick 命令的 3 个理由
|
||||
======
|
||||
|
||||
> “遴选”可以解决 Git 仓库中的很多问题。以下是用 `git cherry-pick` 修复错误的三种方法。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/17/174429qw1im6if6mf6zi9i.jpg)
|
||||
|
||||
在版本控制系统中摸索前进是一件很棘手的事情。对于一个新手来说,这可能是非常难以应付的,但熟悉版本控制系统(如 Git)的术语和基础知识是开始为开源贡献的第一步。
|
||||
|
||||
熟悉 Git 也能帮助你在开源之路上走出困境。Git 功能强大,让你感觉自己在掌控之中 —— 没有哪一种方法会让你无法恢复到工作版本。
|
||||
|
||||
这里有一个例子可以帮助你理解“<ruby>遴选<rt>cherry-pick</rt></ruby>”的重要性。假设你已经在一个分支上做了好几个提交,但你意识到这是个错误的分支!你现在该怎么办?你现在要做什么?要么在正确的分支上重复所有的变更,然后重新提交,要么把这个分支合并到正确的分支上。等一下,前者太过繁琐,而你可能不想做后者。那么,还有没有办法呢?有的,Git 已经为你准备好了。这就是“遴选”的作用。顾名思义,你可以用它从一个分支中手工遴选一个提交,然后转移到另一个分支。
|
||||
|
||||
使用遴选的原因有很多。以下是其中的三个原因。
|
||||
|
||||
### 避免重复性工作
|
||||
|
||||
如果你可以直接将相同的提交复制到另一个分支,就没有必要在不同的分支中重做相同的变更。请注意,遴选出来的提交会在另一个分支中创建带有新哈希的新提交,所以如果你看到不同的提交哈希,请不要感到困惑。
|
||||
|
||||
如果您想知道什么是提交的哈希,以及它是如何生成的,这里有一个说明可以帮助你。提交哈希是用 [SHA-1][2] 算法生成的字符串。SHA-1 算法接收一个输入,然后输出一个唯一的 40 个字符的哈希值。如果你使用的是 [POSIX][3] 系统,请尝试在您的终端上运行这个命令:
|
||||
|
||||
```
|
||||
$ echo -n "commit" | openssl sha1
|
||||
```
|
||||
|
||||
这将输出一个唯一的 40 个字符的哈希值 `4015b57a143aec5156fd1444a017a32137a3fd0f`。这个哈希代表了字符串 `commit`。
|
||||
|
||||
Git 在提交时生成的 SHA-1 哈希值不仅仅代表一个字符串。它代表的是:
|
||||
|
||||
```
|
||||
sha1(
|
||||
meta data
|
||||
commit message
|
||||
committer
|
||||
commit date
|
||||
author
|
||||
authoring date
|
||||
Hash of the entire tree object
|
||||
)
|
||||
```
|
||||
|
||||
这就解释了为什么你对代码所做的任何细微改动都会得到一个独特的提交哈希值。哪怕是一个微小的改动都会被发现。这是因为 Git 具有完整性。
|
||||
|
||||
### 撤销/恢复丢失的更改
|
||||
|
||||
当你想恢复到工作版本时,遴选就很方便。当多个开发人员在同一个代码库上工作时,很可能会丢失更改,最新的版本会被转移到一个陈旧的或非工作版本上。这时,遴选提交到工作版本就可以成为救星。
|
||||
|
||||
#### 它是如何工作的?
|
||||
|
||||
假设有两个分支:`feature1` 和 `feature2`,你想把 `feature1` 中的提交应用到 `feature2`。
|
||||
|
||||
在 `feature1` 分支上,运行 `git log` 命令,复制你想遴选的提交哈希值。你可以看到一系列类似于下面代码示例的提交。`commit` 后面的字母数字代码就是你需要复制的提交哈希。为了方便起见,您可以选择复制前六个字符(本例中为 `966cf3`)。
|
||||
|
||||
```
|
||||
commit 966cf3d08b09a2da3f2f58c0818baa37184c9778 (HEAD -> master)
|
||||
Author: manaswinidas <me@example.com>
|
||||
Date: Mon Mar 8 09:20:21 2021 +1300
|
||||
|
||||
add instructions
|
||||
```
|
||||
|
||||
然后切换到 `feature2` 分支,在刚刚从日志中得到的哈希值上运行 `git cherry-pick`:
|
||||
|
||||
```
|
||||
$ git checkout feature2
|
||||
$ git cherry-pick 966cf3.
|
||||
```
|
||||
|
||||
如果该分支不存在,使用 `git checkout -b feature2` 来创建它。
|
||||
|
||||
这里有一个问题。你可能会遇到下面这种情况:
|
||||
|
||||
```
|
||||
$ git cherry-pick 966cf3
|
||||
On branch feature2
|
||||
You are currently cherry-picking commit 966cf3d.
|
||||
|
||||
nothing to commit, working tree clean
|
||||
The previous cherry-pick is now empty, possibly due to conflict resolution.
|
||||
If you wish to commit it anyway, use:
|
||||
|
||||
git commit --allow-empty
|
||||
|
||||
Otherwise, please use 'git reset'
|
||||
```
|
||||
|
||||
不要惊慌。只要按照建议运行 `git commit --allow-empty`:
|
||||
|
||||
```
|
||||
$ git commit --allow-empty
|
||||
[feature2 afb6fcb] add instructions
|
||||
Date: Mon Mar 8 09:20:21 2021 +1300
|
||||
```
|
||||
|
||||
这将打开你的默认编辑器,允许你编辑提交信息。如果你没有什么要补充的,可以保存现有的信息。
|
||||
|
||||
就这样,你完成了你的第一次遴选。如上所述,如果你在分支 `feature2` 上运行 `git log`,你会看到一个不同的提交哈希。下面是一个例子:
|
||||
|
||||
```
|
||||
commit afb6fcb87083c8f41089cad58deb97a5380cb2c2 (HEAD -> feature2)
|
||||
Author: manaswinidas <[me@example.com][4]>
|
||||
Date: Mon Mar 8 09:20:21 2021 +1300
|
||||
add instructions
|
||||
```
|
||||
|
||||
不要对不同的提交哈希感到困惑。这只是区分 `feature1` 和 `feature2` 的提交。
|
||||
|
||||
### 遴选多个提交
|
||||
|
||||
但如果你想遴选多个提交的内容呢?你可以使用:
|
||||
|
||||
```
|
||||
git cherry-pick <commit-hash1> <commit-hash2>... <commit-hashn>
|
||||
```
|
||||
|
||||
请注意,你不必使用整个提交的哈希值,你可以使用前五到六个字符。
|
||||
|
||||
同样,这也是很繁琐的。如果你想遴选的提交是一系列的连续提交呢?这种方法太费劲了。别担心,有一个更简单的方法。
|
||||
|
||||
假设你有两个分支:
|
||||
|
||||
* `feature1` 包括你想复制的提交(从更早的 `commitA` 到 `commitB`)。
|
||||
* `feature2` 是你想把提交从 `feature1` 转移到的分支。
|
||||
|
||||
然后:
|
||||
|
||||
1. 输入 `git checkout <feature1>`。
|
||||
2. 获取 `commitA` 和 `commitB` 的哈希值。
|
||||
3. 输入 `git checkout <branchB>`。
|
||||
4. 输入 `git cherry-pick <commitA>^..<commitB>` (请注意,这包括 `commitA` 和 `commitB`)。
|
||||
5. 如果遇到合并冲突,[像往常一样解决][5],然后输入 `git cherry-pick --continue` 恢复遴选过程。
|
||||
|
||||
### 重要的遴选选项
|
||||
|
||||
以下是 [Git 文档][6] 中的一些有用的选项,你可以在 `cherry-pick` 命令中使用。
|
||||
|
||||
* `-e`、`--edit`:用这个选项,`git cherry-pick` 可以让你在提交前编辑提交信息。
|
||||
* `-s`、`--signoff`:在提交信息的结尾添加 `Signed-off by` 行。更多信息请参见 `git-commit(1)` 中的 signoff 选项。
|
||||
* `-S[<keyid>]`、`--pgg-sign[=<keyid>]`:这些是 GPG 签名的提交。`keyid` 参数是可选的,默认为提交者身份;如果指定了,则必须嵌在选项中,不加空格。
|
||||
* `--ff`:如果当前 HEAD 与遴选的提交的父级提交相同,则会对该提交进行快进操作。
|
||||
|
||||
下面是除了 `--continue` 外的一些其他的后继操作子命令:
|
||||
|
||||
* `--quit`:你可以忘记当前正在进行的操作。这可以用来清除遴选或撤销失败后的后继操作状态。
|
||||
* `--abort`:取消操作并返回到操作序列前状态。
|
||||
|
||||
下面是一些关于遴选的例子:
|
||||
|
||||
* `git cherry-pick master`:应用 `master` 分支顶端的提交所引入的变更,并创建一个包含该变更的新提交。
|
||||
* `git cherry-pick master~4 master~2':应用 `master` 指向的第五个和第三个最新提交所带来的变化,并根据这些变化创建两个新的提交。
|
||||
|
||||
感到不知所措?你不需要记住所有的命令。你可以随时在你的终端输入 `git cherry-pick --help` 查看更多选项或帮助。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/3/git-cherry-pick
|
||||
|
||||
作者:[Manaswini 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://opensource.com/users/manaswinidas
|
||||
[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://en.wikipedia.org/wiki/SHA-1
|
||||
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[4]: mailto:me@example.com
|
||||
[5]: https://opensource.com/article/20/4/git-merge-conflict
|
||||
[6]: https://git-scm.com/docs/git-cherry-pick
|
@ -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 时监控变量。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/08/231614imw8zqfncz5qwwow.jpg)
|
||||
|
||||
在调试代码时,你经常面临着要弄清楚一个变量何时发生变化。如果没有任何高级工具,那么可以选择使用打印语句在期望它们更改时输出变量。然而,这是一种非常低效的方法,因为变量可能在很多地方发生变化,并且不断地将其打印到终端上会产生很大的干扰,而将它们打印到日志文件中则变得很麻烦。
|
||||
|
||||
这是一个常见的问题,但现在有一个简单而强大的工具可以帮助你监控变量:[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 提供了几种方式可以帮你快速查看提交中哪些文件被改变。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/11/093421yuololouo66woulu.jpg)
|
||||
|
||||
如果你每天使用 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 双启动设置中显示时间错误的问题
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/08/102102xaup3iofozn2uvbf.jpg)
|
||||
|
||||
如果你 [双启动 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
|
@ -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: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13293-1.html)
|
||||
|
||||
git stash 命令实用指南
|
||||
======
|
||||
|
||||
> 学习如何使用 `git stash` 命令,以及何时应该使用它。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/12/232830chuyr6lkzevrfuzr.jpg)
|
||||
|
||||
版本控制是软件开发人员日常生活中不可分割的一部分。很难想象有哪个团队在开发软件时不使用版本控制工具。同样也很难想象有哪个开发者没有使用过(或没有听说过)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)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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
|
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 可以解决什么问题?
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/05/094825y66126r56z361rz1.jpg)
|
||||
|
||||
昨天我 [在 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 或其他格式
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/07/095441bztj6cz68j89568u.jpg)
|
||||
|
||||
很多时候我与 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
|
@ -0,0 +1,135 @@
|
||||
[#]: 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: (stevenzdg988)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13313-1.html)
|
||||
|
||||
7个管理家目录的 Git 技巧
|
||||
======
|
||||
|
||||
> 这是我怎样设置 Git 来管理我的家目录的方法。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/20/095224mtq14szo7opfofq7.jpg)
|
||||
|
||||
我有好几台电脑。一台笔记本电脑用于工作,一台工作站放在家里,一台树莓派(或四台),一台 [Pocket CHIP][2],一台 [运行各种不同的 Linux 的 Chromebook][3],等等。我曾经在每台计算机上或多或少地按照相同的步骤设置我的用户环境,也经常告诉自己让每台计算机都略有不同。例如,我在工作中比在家里更经常使用 [Bash 别名][4],并且我在家里使用的辅助脚本可能对工作没有用。
|
||||
|
||||
这些年来,我对各种设备的期望开始相融,我会忘记我在家用计算机上建立的功能没有移植到我的工作计算机上,诸如此类。我需要一种标准化我的自定义工具包的方法。使我感到意外的答案是 Git。
|
||||
|
||||
Git 是版本跟踪软件。它以既可以用在非常大的开源项目也可以用在极小的开源项目而闻名,甚至最大的专有软件公司也在用它。但是它是为源代码设计的,而不是用在一个装满音乐和视频文件、游戏、照片等的家目录。我听说过有人使用 Git 管理其家目录,但我认为这是程序员们进行的一项附带实验,而不是像我这样的现实生活中的用户。
|
||||
|
||||
用 Git 管理我的家目录是一个不断发展的过程。随着时间的推移我一直在学习和适应。如果你决定使用 Git 管理家目录,则可能需要记住以下几点。
|
||||
|
||||
### 1、文本和二进制位置
|
||||
|
||||
![家目录][5]
|
||||
|
||||
当由 Git 管理时,除了配置文件之外,你的家目录对于所有内容而言都是“无人之地”。这意味着当你打开主目录时,除了可预见的目录的列表之外,你什么都看不到。不应有任何杂乱无章的照片或 LibreOffice 文档,也不应有 “我就在这里放一分钟” 的临时文件。
|
||||
|
||||
原因很简单:使用 Git 管理家目录时,家目录中所有 _未_ 提交的内容都会变成噪音。每次执行 `git status` 时,你都必须翻过去之前 Git 未跟踪的任何文件,因此将这些文件保存在子目录(添加到 `.gitignore` 文件中)至关重要。
|
||||
|
||||
许多 Linux 发行版提供了一组默认目录:
|
||||
|
||||
* `Documents`
|
||||
* `Downloads`
|
||||
* `Music`
|
||||
* `Photos`
|
||||
* `Templates`
|
||||
* `Videos`
|
||||
|
||||
如果需要,你可以创建更多。例如,我把创作的音乐(`Music`)和购买来聆听的音乐(`Albums`)区分开来。同样,我的电影(`Cinema`)目录包含了其他人的电影,而视频(`Videos`)目录包含我需要编辑的视频文件。换句话说,我的默认目录结构比大多数 Linux 发行版提供的默认设置更详细,但是我认为这样做有好处。如果没有适合你的目录结构,你更会将其存放在家目录中,因为没有更好的存放位置,因此请提前考虑并规划好适合你的工作目录。你以后总是可以添加更多,但是最好先开始擅长的。
|
||||
|
||||
### 2、、设置最优的 `.gitignore`
|
||||
|
||||
清理家目录后,你可以像往常一样将其作为 Git 存储库实例化:
|
||||
|
||||
```
|
||||
$ cd
|
||||
$ git init .
|
||||
```
|
||||
|
||||
你的 Git 仓库中还没有任何内容,你的家目录中的所有内容均未被跟踪。你的第一项工作是筛选未跟踪文件的列表,并确定要保持未跟踪状态的文件。要查看未跟踪的文件:
|
||||
|
||||
```
|
||||
$ git status
|
||||
.AndroidStudio3.2/
|
||||
.FBReader/
|
||||
.ICEauthority
|
||||
.Xauthority
|
||||
.Xdefaults
|
||||
.android/
|
||||
.arduino15/
|
||||
.ash_history
|
||||
[...]
|
||||
```
|
||||
|
||||
根据你使用家目录的时间长短,此列表可能很长。简单的是你在上一步中确定的目录。通过将它们添加到名为 `.gitignore` 的隐藏文件中,你告诉 Git 停止将它们列为未跟踪文件,并且永远不对其进行跟踪:
|
||||
|
||||
```
|
||||
$ \ls -lg | grep ^d | awk '{print $8}' >> ~/.gitignore
|
||||
```
|
||||
|
||||
完成后,浏览 `git status` 所示的其余未跟踪文件,并确定是否有其他文件需要排除。这个过程帮助我发现了几个陈旧的配置文件和目录,这些文件和目录最终被我全部丢弃了,而且还发现了一些特定于一台计算机的文件和目录。我在这里非常严格,因为许多配置文件在自动生成时会表现得更好。例如,我从不提交我的 KDE 配置文件,因为许多文件包含了诸如最新文档之类的信息以及其他机器上不存在的其他元素。
|
||||
|
||||
我会跟踪我的个性化配置文件、脚本和实用程序、配置文件和 Bash 配置,以及速查表和我经常引用的其他文本片段。如果有软件主要负责维护的文件,则将其忽略。当对一个文件不确定时,我将其忽略。你以后总是可以取消忽略它(通过从 `.gitignore` 文件中删除它)。
|
||||
|
||||
### 3、了解你的数据
|
||||
|
||||
我使用的是 KDE,因此我使用开源扫描程序 [Filelight][7] 来了解我的数据概况。Filelight 为你提供了一个图表,可让你查看每个目录的大小。你可以浏览每个目录以查看占用了空间的内容,然后回溯调查其他地方。这是一个令人着迷的系统视图,它使你可以以全新的方式看待你的文件。
|
||||
|
||||
![Filelight][8]
|
||||
|
||||
使用 Filelight 或类似的实用程序查找不需要提交的意外数据缓存。例如,KDE 文件索引器(Baloo)生成了大量特定于其主机的数据,我绝对不希望将其传输到另一台计算机。
|
||||
|
||||
### 4、不要忽略你的 `.gitignore` 文件
|
||||
|
||||
在某些项目中,我告诉 Git 忽略我的 `.gitignore` 文件,因为有时我要忽略的内容特定于我的工作目录,并且我不认为同一项目中的其他开发人员需要我告诉他们 `.gitignore` 文件应该是什么样子。因为我的家目录仅供我使用,所以我 _不_ 会忽略我的家目录的 `.gitignore` 文件。我将其与其他重要文件一起提交,因此它已在我的所有系统中被继承。当然,从家目录的角度来看,我所有的系统都是相同的:它们具有一组相同的默认文件夹和许多相同的隐藏配置文件。
|
||||
|
||||
### 5、不要担心二进制文件
|
||||
|
||||
我对我的系统进行了数周的严格测试,确信将二进制文件提交到 Git 绝对不是明智之举。我试过 GPG 加密的密码文件、试过 LibreOffice 文档、JPEG、PNG 等等。我甚至有一个脚本,可以在将 LibreOffice 文件添加到 Git 之前先解压缩,提取其中的 XML,以便仅提交 XML,然后重新构建 LibreOffice 文件,以便可以在 LibreOffice 中继续工作。我的理论是,提交 XML 会比使用 ZIP 文件(LibreOffice 文档实际上就是一个 ZIP 文件)会让 Git 存储库更小一些。
|
||||
|
||||
令我惊讶的是,我发现偶尔提交一些二进制文件并没有大幅增加我的 Git 存储库的大小。我使用 Git 已经很长时间了,我知道如果我要提交几千兆的二进制数据,我的存储库将会受到影响,但是偶尔提交几个二进制文件也不是不惜一切代价要避免的紧急情况。
|
||||
|
||||
有了这种信心,我将字体 OTF 和 TTF 文件添加到我的标准主存储库,以及 GDM 的 `.face` 文件以及其他偶尔小型二进制 Blob 文件。不要想太多,不要浪费时间去避免它。只需提交即可。
|
||||
|
||||
### 6、使用私有存储库
|
||||
|
||||
即使托管方提供了私人帐户,也不要将你的主目录提交到公共 Git 存储库。如果你像我一样,拥有 SSH 密钥、GPG 密钥链和 GPG 加密的文件,这些文件不应该出现在任何人的服务器上,而应该出现在我自己的服务器上。
|
||||
|
||||
我在树莓派上 [运行本地 Git 服务器][9](这比你想象的要容易),因此我可以在家里时随时更新任何一台计算机。我是一名远程工作者,所以通常情况下就足够了,但是我也可以在旅行时通过 [虚拟私人网络][10] 访问我的计算机。
|
||||
|
||||
### 7、要记得推送
|
||||
|
||||
Git 的特点是,只有当你告诉它要推送改动时,它才会把改动推送到你的服务器上。如果你是 Git 的老用户,则此过程可能对你很自然。对于可能习惯于 Nextcloud 或 Syncthing 自动同步的新用户,这可能需要一些时间来适应。
|
||||
|
||||
### Git 家目录
|
||||
|
||||
使用 Git 管理我的常用文件,不仅使我在不同设备上的生活更加便利。我知道我拥有所有配置和实用程序脚本的完整历史记录,这会鼓励我尝试新的想法,因为如果结果变得 _很糟糕_,则很容易回滚我的更改。Git 曾将我从在 `.bashrc` 文件中一个欠考虑的 `umask` 设置中解救出来、从深夜对包管理脚本的拙劣添加中解救出来、从当时看似很酷的 [rxvt][11] 配色方案的修改中解救出来,也许还有其他一些错误。在家目录中尝试 Git 吧,因为这些提交会让家目录融合在一起。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/git-home
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[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/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,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: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13301-1.html)
|
||||
|
||||
使用 Git 工作树对你的代码进行自由实验
|
||||
======
|
||||
|
||||
> 获得自由尝试的权利,同时在你的实验出错时可以安全地拥有一个新的、链接的克隆存储库。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/16/085512x3auafu5uaymk52u.jpg)
|
||||
|
||||
Git 的设计部分是为了进行实验。如果你知道你的工作会被安全地跟踪,并且在出现严重错误时有安全状态存在,你就不会害怕尝试新的想法。不过,创新的部分代价是,你很可能会在这个过程中弄得一团糟。文件会被重新命名、移动、删除、更改、切割成碎片;新的文件被引入;你不打算跟踪的临时文件会在你的工作目录中占据一席之地等等。
|
||||
|
||||
简而言之,你的工作空间变成了纸牌屋,在“快好了!”和“哦,不,我做了什么?”之间岌岌可危地平衡着。那么,当你需要把仓库恢复到下午的一个已知状态,以便完成一些真正的工作时,该怎么办?我立刻想到了 `git branch` 和 [git stash][2] 这两个经典命令,但这两个命令都不是用来处理未被跟踪的文件的,而且文件路径的改变和其他重大的转变也会让人困惑,它们只能把工作暂存(`stash`)起来以备后用。解决这个需求的答案是 Git 工作树。
|
||||
|
||||
### 什么是 Git 工作树
|
||||
|
||||
Git <ruby>工作树<rt>worktree</rt></ruby>是 Git 仓库的一个链接副本,允许你同时签出多个分支。工作树与主工作副本的路径是分开的,它可以处于不同的状态和不同的分支上。在 Git 中新建工作树的好处是,你可以在不干扰当前工作环境的情况下,做出与当前任务无关的修改、提交修改,然后在以后合并。
|
||||
|
||||
直接从 `git-worktree` 手册中找到了一个典型的例子:当你正在为一个项目做一个令人兴奋的新功能时,你的项目经理告诉你有一个紧急的修复工作。问题是你的工作仓库(你的“工作树”)处于混乱状态,因为你正在开发一个重要的新功能。你不想在当前的冲刺中“偷偷地”进行修复,而且你也不愿意把变更暂存起来,为修复创建一个新的分支。相反,你决定创建一个新的工作树,这样你就可以在那里进行修复:
|
||||
|
||||
```
|
||||
$ 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://linux.cn/article-13293-1.html
|
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 是一种专门为教人编程而设计的新型编程语言。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/12/111814w62da2sannsd2q76.jpg)
|
||||
|
||||
学习编程既要学习编程逻辑,又要学习特定编程语言的语法。我在大学上第一堂编程课的时候,教的语言是 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 细节
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/12/093818iie270mi8am6ttk7.jpg)
|
||||
|
||||
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/
|
187
published/20210407 What is Git cherry-picking.md
Normal file
187
published/20210407 What is Git cherry-picking.md
Normal file
@ -0,0 +1,187 @@
|
||||
[#]: 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: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13295-1.html)
|
||||
|
||||
什么是 Git 遴选(cherry-pick)?
|
||||
======
|
||||
|
||||
> 了解 `git cherry-pick` 命令是什么,为什么用以及如何使用。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/14/131735o63v3ow6y2wc281o.jpg)
|
||||
|
||||
当你和一群程序员一起工作时,无论项目大小,处理多个 Git 分支之间的变更都会变得很困难。有时,你不想将整个 Git 分支合并到另一个分支,而是想选择并移动几个特定的提交。这个过程被称为 “<ruby>遴选<rt>cherry-pick</rt></ruby>”。
|
||||
|
||||
本文将介绍“遴选”是什么、为何使用以及如何使用。
|
||||
|
||||
那么让我们开始吧。
|
||||
|
||||
### 什么是遴选?
|
||||
|
||||
使用遴选(`cherry-pick`)命令,Git 可以让你将任何分支中的个别提交合并到你当前的 [Git HEAD][2] 分支中。
|
||||
|
||||
当执行 `git merge` 或者 `git rebase` 时,一个分支的所有提交都会被合并。`cherry-pick` 命令允许你选择单个提交进行整合。
|
||||
|
||||
### 遴选的好处
|
||||
|
||||
下面的情况可能会让你更容易理解遴选功能。
|
||||
|
||||
想象一下,你正在为即将到来的每周冲刺实现新功能。当你的代码准备好了,你会把它推送到远程分支,准备进行测试。
|
||||
|
||||
然而,客户并不是对所有修改都满意,要求你只呈现某些修改。因为客户还没有批准下次发布的所有修改,所以 `git rebase` 不会有预期的结果。为什么会这样?因为 `git rebase` 或者 `git merge` 会把上一个冲刺的每一个调整都纳入其中。
|
||||
|
||||
遴选就是答案!因为它只关注在提交中添加的变更,所以遴选只会带入批准的变更,而不添加其他的提交。
|
||||
|
||||
还有其他几个原因可以使用遴选:
|
||||
|
||||
* 这对于 bug 修复是必不可少的,因为 bug 是出现在开发分支中对应的提交的。
|
||||
* 你可以通过使用 `git cherry-pick` 来避免不必要的工作,而不用使用其他选项例如 `git diff` 来应用特定变更。
|
||||
* 如果因为不同 Git 分支的版本不兼容而无法将整个分支联合起来,那么它是一个很有用的工具。
|
||||
|
||||
### 使用 cherry-pick 命令
|
||||
|
||||
在 `cherry-pick` 命令的最简单形式中,你只需使用 [SHA][3] 标识符来表示你想整合到当前 HEAD 分支的提交。
|
||||
|
||||
要获得提交的哈希值,可以使用 `git log` 命令:
|
||||
|
||||
```
|
||||
$ git log --oneline
|
||||
```
|
||||
|
||||
当你知道了提交的哈希值后,你就可以使用 `cherry-pick` 命令。
|
||||
|
||||
语法是:
|
||||
|
||||
```
|
||||
$ git cherry-pick <commit sha>
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
$ git cherry-pick 65be1e5
|
||||
```
|
||||
|
||||
这将会把指定的修改合并到当前已签出的分支上。
|
||||
|
||||
如果你想做进一步的修改,也可以让 Git 将提交的变更内容添加到你的工作副本中。
|
||||
|
||||
语法是:
|
||||
|
||||
```
|
||||
$ git cherry-pick <commit sha> --no-commit
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
$ git cherry-pick 65be1e5 --no-commit
|
||||
```
|
||||
|
||||
如果你想同时选择多个提交,请将它们的提交哈希值用空格隔开:
|
||||
|
||||
```
|
||||
$ git cherry-pick hash1 hash3
|
||||
```
|
||||
|
||||
当遴选提交时,你不能使用 `git pull` 命令,因为它能获取一个仓库的提交**并**自动合并到另一个仓库。`cherry-pick` 是一个专门不这么做的工具;另一方面,你可以使用 `git fetch`,它可以获取提交,但不应用它们。毫无疑问,`git pull` 很方便,但它不精确。
|
||||
|
||||
### 自己尝试
|
||||
|
||||
要尝试这个过程,启动终端并生成一个示例项目:
|
||||
|
||||
```
|
||||
$ mkdir fruit.git
|
||||
$ cd fruit.git
|
||||
$ git init .
|
||||
```
|
||||
|
||||
创建一些数据并提交:
|
||||
|
||||
```
|
||||
$ echo "Kiwifruit" > fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'First commit'
|
||||
```
|
||||
|
||||
现在,通过创建一个项目的复刻来代表一个远程开发者:
|
||||
|
||||
```
|
||||
$ mkdir ~/fruit.fork
|
||||
$ cd !$
|
||||
$ echo "Strawberry" >> fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'Added a fruit"
|
||||
```
|
||||
|
||||
这是一个有效的提交。现在,创建一个不好的提交,代表你不想合并到你的项目中的东西:
|
||||
|
||||
```
|
||||
$ echo "Rhubarb" >> fruit.txt
|
||||
$ git add fruit.txt
|
||||
$ git commit -m 'Added a vegetable that tastes like a fruit"
|
||||
```
|
||||
|
||||
返回你的仓库,从你的假想的开发者那里获取提交的内容:
|
||||
|
||||
```
|
||||
$ 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...
|
||||
```
|
||||
|
||||
```
|
||||
$ git log –oneline dev/master
|
||||
e858ab2 Added a vegetable that tastes like a fruit
|
||||
0664292 Added a fruit
|
||||
b56e0f8 First commit
|
||||
```
|
||||
|
||||
你已经从你想象中的开发者那里获取了提交的内容,但你还没有将它们合并到你的版本库中。你想接受第二个提交,但不想接受第三个提交,所以使用 `cherry-pick`。
|
||||
|
||||
```
|
||||
$ git cherry-pick 0664292
|
||||
```
|
||||
|
||||
第二次提交现在在你的仓库里了:
|
||||
|
||||
```
|
||||
$ cat fruit.txt
|
||||
Kiwifruit
|
||||
Strawberry
|
||||
```
|
||||
|
||||
将你的更改推送到远程服务器上,这就完成了!
|
||||
|
||||
### 避免使用遴选的原因
|
||||
|
||||
在开发者社区中,通常不鼓励所以遴选。主要原因是它会造成重复提交,而你也失去了跟踪你的提交历史的能力。
|
||||
|
||||
如果你不按顺序地遴选了大量的提交,这些提交会被记录在你的分支中,这可能会在 Git 分支中导致不理想的结果。
|
||||
|
||||
遴选是一个强大的命令,如果没有正确理解可能发生的情况,它可能会导致问题。不过,当你搞砸了,提交到错误的分支时,它可能会救你一命(至少是你当天的工作)。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/cherry-picking-git
|
||||
|
||||
作者:[Rajeev Bera][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/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,107 @@
|
||||
[#]: 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: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13308-1.html)
|
||||
|
||||
为什么我喜欢用 bspwm 来做我的 Linux 窗口管理器
|
||||
======
|
||||
|
||||
> 在 Fedora Linux 上安装、配置并开始使用 bspwm 窗口管理器。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/18/114637hxvqp4hfvbbhihb4.jpg)
|
||||
|
||||
有些人喜欢重新布置家具。还有的人喜欢尝试新鞋或定期重新装修他们的卧室。我呢,则是尝试 Linux 桌面。
|
||||
|
||||
在对网上看到的一些不可思议的桌面环境流口水之后,我对一个窗口管理器特别好奇:[bspwm][2]。
|
||||
|
||||
![bspwm desktop][3]
|
||||
|
||||
我喜欢 [i3][5] 窗口管理器已经有一段时间了,我很喜欢它的布局方式和上手的便捷性。但 bspwm 的某些特性吸引了我。有几个原因让我决定尝试一下:
|
||||
|
||||
* 它_只是_一个窗口管理器(WM)。
|
||||
* 它由几个易于配置的脚本管理。
|
||||
* 它默认支持窗口之间的间隙。
|
||||
|
||||
可能是最需要指出的第一个原因是它只是一个窗口管理器。和 i3 一样,默认情况下没有任何图形化的那些花哨东西。你当然可以随心所欲地定制它,但_你_需要付出努力来使它看起来像你想要的。这也是它吸引我的部分原因。
|
||||
|
||||
虽然它可以在许多发行版上使用,但在我这个例子中使用的是 Fedora Linux。
|
||||
|
||||
### 安装 bspwm
|
||||
|
||||
bspwm 在大多数常见的发行版中都有打包,所以你可以用系统的包管理器安装它。下面这个命令还会安装 [sxkhd][6],这是一个 X 窗口系统的守护程序,它“通过执行命令对输入事件做出反应”;还有 [dmenu][7],这是一个通用的 X 窗口菜单:
|
||||
|
||||
```
|
||||
dnf install bspwm sxkhd dmenu
|
||||
```
|
||||
|
||||
因为 bspwm 只是一个窗口管理器,所以没有任何内置的快捷键或键盘命令。这也是它与 i3 等软件的不同之处。所以,在你第一次启动窗口管理器之前,请先配置一下 `sxkhd`:
|
||||
|
||||
```
|
||||
systemctl start sxkhd
|
||||
systemctl enable sxkhd
|
||||
```
|
||||
|
||||
这样就可以在登录时启用 `sxkhd`,但你还需要一些基本功能的配置:
|
||||
|
||||
```
|
||||
curl https://raw.githubusercontent.com/baskerville/bspwm/master/examples/sxhkdrc --output ~/.config/sxkhd/sxkhdrc
|
||||
```
|
||||
|
||||
在你深入了解之前,不妨先看看这个文件,因为有些脚本调用的命令可能在你的系统中并不存在。一个很好的例子是调用 `urxvt` 的 `super + Return` 快捷键。把它改成你喜欢的终端,尤其是当你没有安装 `urxvt` 的时候:
|
||||
|
||||
```
|
||||
#
|
||||
# wm independent hotkeys
|
||||
#
|
||||
|
||||
# terminal emulator
|
||||
super + Return
|
||||
urxvt
|
||||
|
||||
# program launcher
|
||||
super + @space
|
||||
dmenu_run
|
||||
```
|
||||
|
||||
如果你使用的是 GDM、LightDM 或其他显示管理器(DM),只要在登录前选择 `bspwm` 即可。
|
||||
|
||||
### 配置 bspwm
|
||||
|
||||
当你登录后,你会看到屏幕上什么都没有。这不是你感觉到的空虚感。而是无限可能性!你现在可以开始摆弄桌面环境的所有部分了。你现在可以开始摆弄这些年你认为理所当然的桌面环境的所有部分了。从头开始构建并不容易,但一旦你掌握了诀窍,就会非常有收获。
|
||||
|
||||
任何窗口管理器最困难的是掌握快捷键。你开始会很慢,但在很短的时间内,你就可以只使用键盘在系统中到处操作,在你的朋友和家人面前看起来像一个终极黑客。
|
||||
|
||||
你可以通过编辑 `~/.config/bspwm/bspwmrc`,在启动时添加应用,设置桌面和显示器,并为你的窗口应该如何表现设置规则,随心所欲地定制系统。有一些默认设置的例子可以让你开始使用。键盘快捷键都是由 `sxkhdrc` 文件管理的。
|
||||
|
||||
还有更多的开源项目可以安装,让你的电脑看起来更漂亮,比如用于桌面背景的 [Feh][8]、状态栏的 [Polybar][9]、应用启动器的 [Rofi][10],还有 [Compton][11] 可以给你提供阴影和透明度,可以让你的电脑看起来焕然一新。
|
||||
|
||||
玩得愉快!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/bspwm-linux
|
||||
|
||||
作者:[Stephen Adams][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/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,84 @@
|
||||
[#]: 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: (DCOLIVERSUN)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13299-1.html)
|
||||
|
||||
开源为你带来竞争优势的 4 种方式
|
||||
======
|
||||
|
||||
> 使用开源技术可以帮助组织获得更好的业务结果。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/15/085345a2aani3axxj7wcis.jpg)
|
||||
|
||||
构建技术栈是每个组织的主要决策。选择合适的工具将让团队获得成功,选择错误的解决方案或平台会对生产率和利润率产生毁灭性影响。为了在当今快节奏的世界中脱颖而出,组织必须明智地选择数字解决方案,好的数字解决方案可以提升团队行动力与运营敏捷性。
|
||||
|
||||
这就是为什么越来越多的组织都采用开源解决方案的原因,这些组织来自各行各业,规模有大有小。根据 [麦肯锡][2] 最近的报告,高绩效组织的最大区别是采用不同的开源方案。
|
||||
|
||||
采用开源技术可以帮助组织提高竞争优势、获得更好业务成果的原因有以下四点。
|
||||
|
||||
### 1、可拓展性和灵活性
|
||||
|
||||
可以说,技术世界发展很快。例如,在 2014 年之前,Kubernetes 并不存在,但今天,它却令人印象深刻,无处不在。根据 CNCF [2020 云原生调查][3],91% 的团队正在以某种形式使用 Kubernetes。
|
||||
|
||||
组织投资开源的一个主要原因是因为开源赋予组织行动敏捷性,组织可以迅速地将新技术集成到技术栈中。这与传统方法不同,在传统方法中,团队需要几个季度甚至几年来审查、实施、采用软件,这导致团队不可能实现火速转变。
|
||||
|
||||
开源解决方案完整地提供源代码,团队可以轻松将软件与他们每天使用的工具连接起来。
|
||||
|
||||
简而言之,开源让开发团队能够为手头的东西构建完美的工具,而不是被迫改变工作方式来适应不灵活的专有工具。
|
||||
|
||||
### 2、安全性和高可信的协作
|
||||
|
||||
在数据泄露备受瞩目的时代,组织需要高度安全的工具来保护敏感数据的安全。
|
||||
|
||||
专有解决方案中的漏洞不易被发现,被发现时为时已晚。不幸的是,使用这些平台的团队无法看到源代码,本质上是他们将安全性外包给特定供应商,并希望得到最好的结果。
|
||||
|
||||
采用开源的另一个主要原因是开源工具使组织能够自己把控安全。例如,开源项目——尤其是拥有大型开源社区的项目——往往会收到更负责任的漏洞披露,因为每个人在使用过程中都可以彻底检查源代码。
|
||||
|
||||
由于源代码是免费提供的,因此披露通常伴随着修复缺陷的详细建议解决方案。这些方案使得开发团队能够快速解决问题,不断增强软件。
|
||||
|
||||
在远程办公时代,对于分布式团队来说,在知道敏感数据受到保护的情况下进行协作比以往任何时候都更重要。开源解决方案允许组织审核安全性、完全掌控自己数据,因此开源方案可以促进远程环境下高可信协作方式的成长。
|
||||
|
||||
### 3、不受供应商限制
|
||||
|
||||
根据 [最近的一项研究][4],68% 的 CIO 担心受供应商限制。当你受限于一项技术中,你会被迫接受别人的结论,而不是自己做结论。
|
||||
|
||||
当组织更换供应商时,专有解决方案通常会 [给你带走数据带来挑战][5]。另一方面,开源工具提供了组织需要的自由度和灵活性,以避免受供应商限制,开源工具可以让组织把数据带去任意地方。
|
||||
|
||||
### 4、顶尖人才和社区
|
||||
|
||||
随着越来越多的公司 [接受远程办公][6],人才争夺战变得愈发激烈。
|
||||
|
||||
在软件开发领域,获得顶尖人才始于赋予工程师先进工具,让工程师在工作中充分发挥潜力。开发人员 [越来越喜欢开源解决方案][7] 而不是专有解决方案,组织应该强烈考虑用开源替代商业解决方案,以吸引市场上最好的开发人员。
|
||||
|
||||
除了雇佣、留住顶尖人才更容易,公司能够通过开源平台利用贡献者社区,得到解决问题的建议,从平台中得到最大收益。此外,社区成员还可以 [直接为开源项目做贡献][8]。
|
||||
|
||||
### 开源带来自由
|
||||
|
||||
开源软件在企业团队中越来越受到欢迎——[这是有原因的][8]。它帮助团队灵活地构建完美的工作工具,同时使团队可以维护高度安全的环境。同时,开源允许团队掌控未来方向,而不是局限于供应商的路线图。开源还帮助公司接触才华横溢的工程师和开源社区成员。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/open-source-competitive-advantage
|
||||
|
||||
作者:[Jason Blais][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/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,119 @@
|
||||
[#]: 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: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13302-1.html)
|
||||
|
||||
如何在 Fedora 上安装 Steam
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/16/090703cg4t5npnseskhxhv.jpg)
|
||||
|
||||
Steam 对 Linux 游戏玩家来说是最好的东西了。由于 Steam,你可以在 Linux 上玩成百上千的游戏。
|
||||
|
||||
如果你还不知道,Steam 是最流行的 PC 游戏平台。2013 年,它开始可以在 Linux 使用。[Steam 最新的 Proton 项目][1] 允许你在 Linux 上玩为 Windows 平台创建的游戏。这让 Linux 游戏库增强了许多倍。
|
||||
|
||||
![][2]
|
||||
|
||||
Steam 提供了一个桌面客户端,你可以用它从 Steam 商店下载或购买游戏,然后安装并玩它。
|
||||
|
||||
过去我们曾讨论过 [在 Ubuntu 上安装 Steam][3]。在这个初学者教程中,我将向你展示在 Fedora Linux 上安装 Steam 的步骤。
|
||||
|
||||
### 在 Fedora 上安装 Steam
|
||||
|
||||
要在 Fedora 上使用 Steam,你必须使用 RMPFusion 软件库。[RPMFusion][4] 是一套第三方软件库,其中包含了 Fedora 选择不与它们的操作系统一起发布的软件。它们提供自由(开源)和非自由(闭源)的软件库。由于 Steam 在非自由软件库中,你将只安装那一个。
|
||||
|
||||
我将同时介绍终端和图形安装方法。
|
||||
|
||||
#### 方法 1:通过终端安装 Steam
|
||||
|
||||
这是最简单的方法,因为它需要的步骤最少。只需输入以下命令即可启用仓库:
|
||||
|
||||
```
|
||||
sudo dnf install https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
```
|
||||
|
||||
你会被要求输入密码。然后你会被要求验证是否要安装这些仓库。你同意后,仓库安装就会完成。
|
||||
|
||||
要安装 Steam,只需输入以下命令:
|
||||
|
||||
```
|
||||
sudo dnf install steam
|
||||
```
|
||||
|
||||
![Install Steam via command line][5]
|
||||
|
||||
输入密码后按 `Y` 接受。安装完毕后,打开 Steam,玩一些游戏。
|
||||
|
||||
#### 方法 2:通过 GUI 安装 Steam
|
||||
|
||||
你可以从软件中心 [启用 Fedora 上的第三方仓库][6]。打开软件中心并点击菜单。
|
||||
|
||||
![][7]
|
||||
|
||||
在 “软件仓库” 窗口中,你会看到顶部有一个 “第三方软件仓库”。点击 “安装” 按钮。当提示你输入密码时,就完成了。
|
||||
|
||||
![][8]
|
||||
|
||||
安装了 Steam 的 RPM Fusion 仓库后,更新你系统的软件缓存(如果需要),并在软件中心搜索 Steam。
|
||||
|
||||
![Steam in GNOME Software Center][9]
|
||||
|
||||
安装完成后,打开 GNOME 软件中心,搜索 Steam。找到 Steam 页面后,点击安装。当被问及密码时,输入你的密码就可以了。
|
||||
|
||||
安装完 Steam 后,启动应用,输入你的 Steam 帐户详情或注册它,然后享受你的游戏。
|
||||
|
||||
### 将 Steam 作为 Flatpak 使用
|
||||
|
||||
Steam 也可以作为 Flatpak 使用。Fedora 上默认安装 Flatpak。在使用该方法安装 Steam 之前,我们必须安装 Flathub 仓库。
|
||||
|
||||
![Install Flathub][10]
|
||||
|
||||
首先,在浏览器中打开 [Flatpak 网站][11]。现在,点击标有 “Flathub repository file” 的蓝色按钮。浏览器会询问你是否要在 GNOME 软件中心打开该文件。点击确定。在 GNOME 软件中心打开后,点击安装按钮。系统会提示你输入密码。
|
||||
|
||||
如果你在尝试安装 Flathub 仓库时出现错误,请在终端运行以下命令:
|
||||
|
||||
```
|
||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
```
|
||||
|
||||
安装好 Flathub 仓库后,你需要做的就是在 GNOME 软件中心搜索 Steam。找到后,安装它,你就可以开始玩了。
|
||||
|
||||
![Fedora Repo Select][12]
|
||||
|
||||
Flathub 版本的 Steam 也有几个附加组件可以安装。其中包括一个 DOS 兼容工具和几个 [Vulkan][13] 和 Proton 工具。
|
||||
|
||||
![][14]
|
||||
|
||||
我想这应该可以帮助你在 Fedora 上使用 Steam。享受你的游戏 :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-steam-fedora/
|
||||
|
||||
作者:[John Paul][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/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,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 发行版
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/11/103205t34lcaa3t0a3xjjw.jpg)
|
||||
|
||||
每当 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/
|
@ -0,0 +1,191 @@
|
||||
[#]: subject: (6 open source tools and tips to securing a Linux server for beginners)
|
||||
[#]: via: (https://opensource.com/article/21/4/securing-linux-servers)
|
||||
[#]: author: (Sahana Sreeram https://opensource.com/users/sahanasreeram01gmailcom)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13298-1.html)
|
||||
|
||||
6 个提升 Linux 服务器安全的开源工具和技巧
|
||||
======
|
||||
|
||||
> 使用开源工具来保护你的 Linux 环境不被入侵。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/15/082334ltqtgg40tu7l80rd.jpg)
|
||||
|
||||
如今我们的许多个人和专业数据都可以在网上获得,因此无论是专业人士还是普通互联网用户,学习安全和隐私的基本知识是非常重要的。作为一名学生,我通过学校的 CyberPatriot 活动获得了这方面的经验,在那里我有机会与行业专家交流,了解网络漏洞和建立系统安全的基本步骤。
|
||||
|
||||
本文基于我作为初学者迄今所学的知识,详细介绍了六个简单的步骤,以提高个人使用的 Linux 环境的安全性。在我的整个旅程中,我利用开源工具来加速我的学习过程,并熟悉了与提升 Linux 服务器安全有关的更高层次的概念。
|
||||
|
||||
我使用我最熟悉的 Ubuntu 18.04 版本测试了这些步骤,但这些步骤也适用于其他 Linux 发行版。
|
||||
|
||||
### 1、运行更新
|
||||
|
||||
开发者们不断地寻找方法,通过修补已知的漏洞,使服务器更加稳定、快速、安全。定期运行更新是一个好习惯,可以最大限度地提高安全性。运行它们:
|
||||
|
||||
```
|
||||
sudo apt-get update && apt-get upgrade
|
||||
```
|
||||
|
||||
### 2、启用防火墙保护
|
||||
|
||||
[启用防火墙][2] 可以更容易地控制服务器上的进站和出站流量。在 Linux 上有许多防火墙应用程序可以使用,包括 [firewall-cmd][3] 和 <ruby>简单防火墙<rt>Uncomplicated Firewall</rt></ruby>([UFW][4])。我使用 UFW,所以我的例子是专门针对它的,但这些原则适用于你选择的任何防火墙。
|
||||
|
||||
安装 UFW:
|
||||
|
||||
```
|
||||
sudo apt-get install ufw
|
||||
```
|
||||
|
||||
如果你想进一步保护你的服务器,你可以拒绝传入和传出的连接。请注意,这将切断你的服务器与世界的联系,所以一旦你封锁了所有的流量,你必须指定哪些出站连接是允许从你的系统中发出的:
|
||||
|
||||
```
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
```
|
||||
|
||||
你也可以编写规则来允许你个人使用所需要的传入连接:
|
||||
|
||||
```
|
||||
ufw allow <service>
|
||||
```
|
||||
|
||||
例如,允许 SSH 连接:
|
||||
|
||||
```
|
||||
ufw allow ssh
|
||||
```
|
||||
|
||||
最后,启用你的防火墙:
|
||||
|
||||
```
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
### 3、加强密码保护
|
||||
|
||||
实施强有力的密码政策是保持服务器安全、防止网络攻击和数据泄露的一个重要方面。密码策略的一些最佳实践包括强制要求最小长度和指定密码年龄。我使用 libpam-cracklib 软件包来完成这些任务。
|
||||
|
||||
安装 libpam-cracklib 软件包:
|
||||
|
||||
```
|
||||
sudo apt-get install libpam-cracklib
|
||||
```
|
||||
|
||||
强制要求密码的长度:
|
||||
|
||||
* 打开 `/etc/pam.d/common-password` 文件。
|
||||
* 将 `minlen=12` 行改为你需要的任意字符数,从而改变所有密码的最小字符长度要求。
|
||||
|
||||
为防止密码重复使用:
|
||||
|
||||
* 在同一个文件(`/etc/pam.d/common-password`)中,添加 `remember=x` 行。
|
||||
* 例如,如果你想防止用户重复使用他们最后 5 个密码中的一个,使用 `remember=5`。
|
||||
|
||||
要强制要求密码年龄:
|
||||
|
||||
* 在 `/etc/login.defs` 文件中找到以下几行,并用你喜欢的时间(天数)替换。例如:
|
||||
|
||||
```
|
||||
PASS_MIN_AGE: 3
|
||||
PASS_MAX_AGE: 90
|
||||
PASS_WARN_AGE: 14
|
||||
```
|
||||
|
||||
强制要求字符规格:
|
||||
|
||||
* 在密码中强制要求字符规格的四个参数是 `lcredit`(小写)、`ucredit`(大写)、`dcredit`(数字)和 `ocredit`(其他字符)。
|
||||
* 在同一个文件(`/etc/pam.d/common-password`)中,找到包含 `pam_cracklib.so` 的行。
|
||||
* 在该行末尾添加以下内容:`lcredit=-a ucredit=-b dcredit=-c ocredit=-d`。
|
||||
* 例如,下面这行要求密码必须至少包含一个每种字符。你可以根据你喜欢的密码安全级别来改变数字。`lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1`。
|
||||
|
||||
### 4、停用容易被利用的非必要服务。
|
||||
|
||||
停用不必要的服务是一种最好的做法。这样可以减少开放的端口,以便被利用。
|
||||
|
||||
安装 systemd 软件包:
|
||||
|
||||
```
|
||||
sudo apt-get install systemd
|
||||
```
|
||||
|
||||
查看哪些服务正在运行:
|
||||
|
||||
```
|
||||
systemctl list-units
|
||||
```
|
||||
|
||||
[识别][5] 哪些服务可能会导致你的系统出现潜在的漏洞。对于每个服务可以:
|
||||
|
||||
* 停止当前正在运行的服务:`systemctl stop <service>`。
|
||||
* 禁止服务在系统启动时启动:`systemctl disable <service>`。
|
||||
* 运行这些命令后,检查服务的状态:`systemctl status <service>`。
|
||||
|
||||
### 5、检查监听端口
|
||||
|
||||
开放的端口可能会带来安全风险,所以检查服务器上的监听端口很重要。我使用 [netstat][6] 命令来显示所有的网络连接:
|
||||
|
||||
```
|
||||
netstat -tulpn
|
||||
```
|
||||
|
||||
查看 “address” 列,确定 [端口号][7]。一旦你找到了开放的端口,检查它们是否都是必要的。如果不是,[调整你正在运行的服务][8],或者调整你的防火墙设置。
|
||||
|
||||
### 6、扫描恶意软件
|
||||
|
||||
杀毒扫描软件可以有用的防止病毒进入你的系统。使用它们是一种简单的方法,可以让你的服务器免受恶意软件的侵害。我首选的工具是开源软件 [ClamAV][9]。
|
||||
|
||||
安装 ClamAV:
|
||||
|
||||
```
|
||||
sudo apt-get install clamav
|
||||
```
|
||||
|
||||
更新病毒签名:
|
||||
|
||||
```
|
||||
sudo freshclam
|
||||
```
|
||||
|
||||
扫描所有文件,并打印出被感染的文件,发现一个就会响铃:
|
||||
|
||||
```
|
||||
sudo clamscan -r --bell -i /
|
||||
```
|
||||
|
||||
你可以而且应该设置为自动扫描,这样你就不必记住或花时间手动进行扫描。对于这样简单的自动化,你可以使用 [systemd 定时器][10] 或者你的 [喜欢的 cron][11] 来做到。
|
||||
|
||||
### 保证你的服务器安全
|
||||
|
||||
我们不能把保护服务器安全的责任只交给一个人或一个组织。随着威胁环境的不断迅速扩大,我们每个人都应该意识到服务器安全的重要性,并采用一些简单、有效的安全最佳实践。
|
||||
|
||||
这些只是你提升 Linux 服务器的安全可以采取的众多步骤中的一部分。当然,预防只是解决方案的一部分。这些策略应该与严格监控拒绝服务攻击、用 [Lynis][12] 做系统分析以及创建频繁的备份相结合。
|
||||
|
||||
你使用哪些开源工具来保证服务器的安全?在评论中告诉我们它们的情况。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/securing-linux-servers
|
||||
|
||||
作者:[Sahana Sreeram][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/sahanasreeram01gmailcom
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_linux11x_cc.png?itok=XMDOouJR (People work on a computer server with devices)
|
||||
[2]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[3]: https://opensource.com/article/20/2/firewall-cheat-sheet
|
||||
[4]: https://wiki.ubuntu.com/UncomplicatedFirewall
|
||||
[5]: http://www.yorku.ca/infosec/Administrators/UNIX_disable.html
|
||||
[6]: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/netstat
|
||||
[7]: https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
|
||||
[8]: https://opensource.com/article/20/5/systemd-units
|
||||
[9]: https://www.clamav.net/
|
||||
[10]: https://opensource.com/article/20/7/systemd-timers
|
||||
[11]: https://opensource.com/article/21/2/linux-automation
|
||||
[12]: https://opensource.com/article/20/5/linux-security-lynis
|
@ -0,0 +1,87 @@
|
||||
[#]: subject: (Encrypt your files with this open source software)
|
||||
[#]: via: (https://opensource.com/article/21/4/open-source-encryption)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13304-1.html)
|
||||
|
||||
用开源的 VeraCrypt 加密你的文件
|
||||
======
|
||||
|
||||
> VeraCrypt 提供跨平台的开源文件加密功能。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/17/110244p1g4tbpnw00tqwq3.jpg)
|
||||
|
||||
许多年前,有一个名为 [TrueCrypt][2] 的加密软件。它的源码是可以得到的,尽管没有任何人声称曾对它进行过审计或贡献过。它的作者是(至今仍是)匿名的。不过,它是跨平台的,易于使用,而且真的非常有用。
|
||||
|
||||
TrueCrypt 允许你创建一个加密的文件“保险库”,在那里你可以存储任何类型的敏感信息(文本、音频、视频、图像、PDF 等)。只要你有正确的口令,TrueCrypt 就可以解密保险库,并在任何运行 TrueCrypt 的电脑上提供读写权限。这是一项有用的技术,它基本上提供了一个虚拟的、可移动的、完全加密的驱动器(除了文件以外),你可以在其中安全地存储你的数据。
|
||||
|
||||
TrueCrypt 最终关闭了,但一个名为 VeraCrypt 的替代项目迅速兴起,填补了这一空白。[VeraCrypt][3] 基于 TrueCrypt 7.1a,比原来的版本有许多改进(包括标准加密卷和引导卷的算法的重大变化)。在 VeraCrypt 1.12 及以后的版本中,你可以使用自定义迭代来提高加密安全性。更好的是,VeraCrypt 可以加载旧的 TrueCrypt 卷,所以如果你是 TrueCrypt 用户,可以很容易地将它们转移到 VeraCrypt 上。
|
||||
|
||||
### 安装 VeraCrypt
|
||||
|
||||
你可以从 [VeraCrypt 下载页面][4] 下载相应的安装文件,之后在所有主流平台上安装 VeraCrypt。
|
||||
|
||||
另外,你也可以自己从源码构建它。在 Linux 上,它需要 wxGTK3、makeself 和通常的开发栈(Binutils、GCC 等)。
|
||||
|
||||
当你安装后,从你的应用菜单中启动 VeraCrypt。
|
||||
|
||||
### 创建一个 VeraCrypt 卷
|
||||
|
||||
如果你刚接触 VeraCrypt,你必须先创建一个 VeraCrypt 加密卷(否则,你没有任何东西可以解密)。在 VeraCrypt 窗口中,点击左侧的 “Create Volume” 按钮。
|
||||
|
||||
![Creating a volume with VeraCrypt][5]
|
||||
|
||||
在出现的 VeraCrypt 的卷创建向导窗口中,选择要创建一个加密文件容器还是要加密整个驱动器或分区。向导将为你的数据创建一个保险库,所以请按照提示进行操作。
|
||||
|
||||
在本文中,我创建了一个文件容器。VeraCrypt 容器和其他文件很像:它保存在硬盘、外置硬盘、云存储或其他任何你能想到的存储数据的地方。与其他文件一样,它可以被移动、复制和删除。与大多数其他文件不同的是,它可以_容纳_更多的文件,这就是为什么我认为它是一个“保险库”,而 VeraCrypt 开发者将其称为“容器”。它的开发者将 VeraCrypt 文件称为“容器”,是因为它可以包含其他数据对象;它与 LXC、Kubernetes 和其他现代 IT 机制所流行的容器技术无关。
|
||||
|
||||
#### 选择一个文件系统
|
||||
|
||||
在创建卷的过程中,你会被要求选择一个文件系统来决定你放在保险库中的文件的存储方式。微软 FAT 格式是过时的、非日志型,并且限制了卷和文件的大小,但它是所有平台都能读写的一种格式。如果你打算让你的 VeraCrypt 保险库跨平台,FAT 是你最好的选择。
|
||||
|
||||
除此之外,NTFS 适用于 Windows 和 Linux。开源的 EXT 系列适用于 Linux。
|
||||
|
||||
### 挂载 VeraCrypt 加密卷
|
||||
|
||||
当你创建了 VeraCrypt 卷,你就可以在 VeraCrypt 窗口中加载它。要挂载一个加密库,点击右侧的 “Select File” 按钮。选择你的加密文件,选择 VeraCrypt 窗口上半部分的一个编号栏,然后点击位于 VeraCrypt 窗口左下角的 “Mount” 按钮。
|
||||
|
||||
你挂载的卷在 VeraCrypt 窗口的可用卷列表中,你可以通过文件管理器访问该卷,就像访问一个外部驱动器一样。例如,在 KDE 上,我打开 [Dolphin][7],进入 `/media/veracrypt1`,然后我就可以把文件复制到我的保险库里。
|
||||
|
||||
只要你的设备上有 VeraCrypt,你就可以随时访问你的保险库。在你手动在 VeraCrypt 中挂载之前,文件都是加密的,在那里,文件会保持解密,直到你再次关闭卷。
|
||||
|
||||
### 关闭 VeraCrypt 卷
|
||||
|
||||
为了保证你的数据安全,当你不需要打开 VeraCrypt 卷时,关闭它是很重要的。这样可以保证数据的安全,不被人窥视,且不被人趁机犯罪。
|
||||
|
||||
![Mounting a VeraCrypt volume][8]
|
||||
|
||||
关闭 VeraCrypt 容器和打开容器一样简单。在 VeraCrypt 窗口中选择列出的卷,然后点击 “Dismount”。你就不能访问保险库中的文件了,其他人也不会再有访问权。
|
||||
|
||||
### VeraCrypt 轻松实现跨平台加密
|
||||
|
||||
有很多方法可以保证你的数据安全,VeraCrypt 试图为你提供方便,而无论你需要在什么平台上使用这些数据。如果你想体验简单、开源的文件加密,请尝试 VeraCrypt。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/open-source-encryption
|
||||
|
||||
作者:[Seth Kenlon][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/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum (Lock)
|
||||
[2]: https://en.wikipedia.org/wiki/TrueCrypt
|
||||
[3]: https://www.veracrypt.fr/en/Home.html
|
||||
[4]: https://www.veracrypt.fr/en/Downloads.html
|
||||
[5]: https://opensource.com/sites/default/files/uploads/veracrypt-create.jpg (Creating a volume with VeraCrypt)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://en.wikipedia.org/wiki/Dolphin_%28file_manager%29
|
||||
[8]: https://opensource.com/sites/default/files/uploads/veracrypt-volume.jpg (Mounting a VeraCrypt volume)
|
113
published/20210413 Create an encrypted file vault on Linux.md
Normal file
113
published/20210413 Create an encrypted file vault on Linux.md
Normal file
@ -0,0 +1,113 @@
|
||||
[#]: subject: (Create an encrypted file vault on Linux)
|
||||
[#]: via: (https://opensource.com/article/21/4/linux-encryption)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13296-1.html)
|
||||
|
||||
在 Linux 上创建一个加密文件保险库
|
||||
======
|
||||
|
||||
> 使用 Linux 统一密钥设置(LUKS)为物理驱动器或云存储上的敏感文件创建一个加密保险库。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/14/151220l5zkkxiukgzix54k.jpg)
|
||||
|
||||
最近,我演示了如何在 Linux 上使用<ruby>统一密钥设置<rt>Linux Unified Key Setup</rt></ruby>([LUKS][3])和 `cryptsetup` 命令 [实现全盘加密][2]。虽然加密整个硬盘在很多情况下是有用的,但也有一些原因让你不想对整个硬盘进行加密。例如,你可能需要让一个硬盘在多个平台上工作,其中一些平台可能没有集成 [LUKS][3]。此外,现在是 21 世纪,由于云的存在,你可能不会使用物理硬盘来处理所有的数据。
|
||||
|
||||
几年前,有一个名为 [TrueCrypt][4] 的系统,允许用户创建加密的文件保险库,可以通过 TrueCrypt 解密来提供读/写访问。这是一项有用的技术,基本上提供了一个虚拟的便携式、完全加密的驱动器,你可以在那里存储重要数据。TrueCrypt 项目关闭了,但它可以作为一个有趣的模型。
|
||||
|
||||
幸运的是,LUKS 是一个灵活的系统,你可以使用它和 `cryptsetup` 在一个独立的文件中创建一个加密保险库,你可以将其保存在物理驱动器或云存储中。
|
||||
|
||||
下面就来介绍一下怎么做。
|
||||
|
||||
### 1、建立一个空文件
|
||||
|
||||
首先,你必须创建一个预定大小的空文件。就像是一种保险库或保险箱,你可以在其中存储其他文件。你使用的命令是 `util-linux` 软件包中的 `fallocate`:
|
||||
|
||||
```
|
||||
$ fallocate --length 512M vaultfile.img
|
||||
```
|
||||
|
||||
这个例子创建了一个 512MB 的文件,但你可以把你的文件做成任何你想要的大小。
|
||||
|
||||
### 2、创建一个 LUKS 卷
|
||||
|
||||
接下来,在空文件中创建一个 LUKS 卷:
|
||||
|
||||
```
|
||||
$ cryptsetup --verify-passphrase \
|
||||
luksFormat vaultfile.img
|
||||
```
|
||||
|
||||
### 3、打开 LUKS 卷
|
||||
|
||||
要想创建一个可以存储文件的文件系统,必须先打开 LUKS 卷,并将其挂载到电脑上:
|
||||
|
||||
```
|
||||
$ sudo cryptsetup open \
|
||||
--type luks vaultfile.img myvault
|
||||
$ ls /dev/mapper
|
||||
myvault
|
||||
```
|
||||
|
||||
### 4、建立一个文件系统
|
||||
|
||||
在你打开的保险库中建立一个文件系统:
|
||||
|
||||
```
|
||||
$ sudo mkfs.ext4 -L myvault /dev/mapper/myvault
|
||||
```
|
||||
|
||||
如果你现在不需要它做什么,你可以关闭它:
|
||||
|
||||
```
|
||||
$ sudo cryptsetup close myvault
|
||||
```
|
||||
|
||||
### 5、开始使用你的加密保险库
|
||||
|
||||
现在一切都设置好了,你可以在任何需要存储或访问私人数据的时候使用你的加密文件库。要访问你的保险库,必须将其挂载为一个可用的文件系统:
|
||||
|
||||
```
|
||||
$ sudo cryptsetup open \
|
||||
--type luks vaultfile.img myvault
|
||||
$ ls /dev/mapper
|
||||
myvault
|
||||
$ sudo mkdir /myvault
|
||||
$ sudo mount /dev/mapper/myvault /myvault
|
||||
```
|
||||
|
||||
这个例子用 `cryptsetup` 打开保险库,然后把保险库从 `/dev/mapper` 下挂载到一个叫 `/myvault` 的新目录。和 Linux 上的任何卷一样,你可以把 LUKS 卷挂载到任何你想挂载的地方,所以除了 `/myvault`,你可以用 `/mnt` 或 `~/myvault` 或任何你喜欢的位置。
|
||||
|
||||
当它被挂载后,你的 LUKS 卷就会被解密。你可以像读取和写入文件一样读取和写入它,就像它是一个物理驱动器一样。
|
||||
|
||||
当使用完你的加密保险库时,请卸载并关闭它:
|
||||
|
||||
```
|
||||
$ sudo umount /myvault
|
||||
$ sudo cryptsetup close myvault
|
||||
```
|
||||
|
||||
### 加密的文件保险库
|
||||
|
||||
你用 LUKS 加密的镜像文件和其他文件一样,都是可移动的,因此你可以将你的保险库存储在硬盘、外置硬盘,甚至是互联网上。只要你可以使用 LUKS,就可以解密、挂载和使用它来保证你的数据安全。轻松加密,提高数据安全性,不妨一试。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/linux-encryption
|
||||
|
||||
作者:[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/life_bank_vault_secure_safe.png?itok=YoW93h7C (Secure safe)
|
||||
[2]: https://opensource.com/article/21/3/encryption-luks
|
||||
[3]: https://gitlab.com/cryptsetup/cryptsetup/blob/master/README.md
|
||||
[4]: https://en.wikipedia.org/wiki/TrueCrypt
|
@ -0,0 +1,108 @@
|
||||
[#]: subject: (Make your data boss-friendly with this open source tool)
|
||||
[#]: via: (https://opensource.com/article/21/4/visualize-data-eda)
|
||||
[#]: author: (Juanjo Ortilles https://opensource.com/users/jortilles)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-13310-1.html)
|
||||
|
||||
用这个开源工具让你的数据对老板友好起来
|
||||
======
|
||||
|
||||
> 企业数据分析旨在将数据可视化带给日常商务用户。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202104/19/092617elri0ff4r6lr06rr.jpg)
|
||||
|
||||
<ruby>企业数据分析<rt>Enterprise Data Analytics</rt></ruby>([EDA][2]) 是一个网页应用,它可以通过一个简单、清晰的界面来获取信息。
|
||||
|
||||
在巴塞罗那开源分析公司 [Jortilles][3] 工作几年后,我们意识到,现代世界强制性地收集数据,但普通人没有简单的方法来查看或解释这些数据。有一些强大的开源工具可用于此目的,但它们非常复杂。我们找不到一个工具设计成能让没有什么技术能力的普通人轻松使用。
|
||||
|
||||
我们之所以开发 EDA,是因为我们认为获取信息是现代组织的要求和义务,并希望为每个人提供获取信息的机会。
|
||||
|
||||
![EDA interface][4]
|
||||
|
||||
### 可视化你的数据
|
||||
|
||||
EDA 使用人们已经理解的商业术语提供了一个数据模型。你可以选择你想要的信息,并可以以你想要的方式查看它。它的目标是对用户友好,同时又功能强大。
|
||||
|
||||
EDA 通过元数据模型将数据库中的信息可视化和丰富化。它可以从 BigQuery、Postgres、[MariaDB、MySQL][6] 和其他一些数据库中读取数据。这就把技术性的数据库模型转化为熟悉的商业概念。
|
||||
|
||||
它还设计为加快信息传播的速度,因为它可以利用已经存储在数据库中的数据。EDA 可以发现数据库的拓扑结构,并提出业务模型。如果你设计了一个好的数据库模型,你就有了一个好的业务模型。EDA 还可以连接到生产服务器,提供实时分析。
|
||||
|
||||
这种数据和数据模型的结合意味着你和你组织中的任何人都可以分析其数据。然而,为了保护数据,你可以定义数据安全,可以精确到行,以授予正当的人访问正当的数据。
|
||||
|
||||
EDA 的一些功能包括:
|
||||
|
||||
* 自动生成数据模型
|
||||
* 一致的数据模型,防止出现不一致的查询
|
||||
* 高级用户的 SQL 模式
|
||||
* 数据可视化:
|
||||
* 标准图表(如柱状图、饼状图、线状图、树状图)
|
||||
* 地图整合(如 geoJSON shapefile、纬度、经度)
|
||||
* 电子邮件提醒,可通过关键绩效指标 (KPI) 来定义
|
||||
* 私人和公共信息控制,以启用私人和公共仪表板,你可以通过链接分享它。
|
||||
* 数据缓存和程序刷新。
|
||||
|
||||
### 如何使用 EDA
|
||||
|
||||
用 EDA 实现数据可视化的第一步是创建数据模型。
|
||||
|
||||
#### 创建数据模型
|
||||
|
||||
首先,在左侧菜单中选择 “New Datasource”。
|
||||
|
||||
接下来,选择你的数据存储的数据库系统(如 Postgres、MariaDB、MySQL、Vertica、SqlServer、Oracle、Big Query),并提供连接参数。
|
||||
|
||||
EDA 将自动为你生成数据模型。它读取表和列,并为它们定义名称以及表之间的关系。你还可以通过添加虚拟视图或 geoJSON 图来丰富你的数据模型。
|
||||
|
||||
#### 制作仪表板
|
||||
|
||||
现在你已经准备好制作第一个仪表板了。在 EDA 界面的主页面上,你应该会看到一个 “New dashboard” 按钮。点击它,命名你的仪表板,并选择你创建的数据模型。新的仪表板将出现一个面板供你配置。
|
||||
|
||||
要配置面板,请单击右上角的 “Configuration” 按钮,并选择你要做的事情。在 “Edit query” 中,选择你要显示的数据。这将出现一个新的窗口,你的数据模型由实体和实体的属性表示。选择你要查看的实体和你要使用的属性。例如,对于名为 “Customers” 的实体,你可能会显示 “Customer Name”,对于 “Sales” 实体,你可能希望显示 “Total Sales”。
|
||||
|
||||
接下来,运行一个查询,并选择你想要的可视化。
|
||||
|
||||
![EDA interface][7]
|
||||
|
||||
你可以添加任意数量的面板、过滤器和文本字段,所有这些都有说明。当你保存仪表板后,你可以查看它,与同事分享,甚至发布到互联网上。
|
||||
|
||||
### 获取 EDA
|
||||
|
||||
最快的方法是用 [公开演示][8] 来查看 EDA。但如果你想自己试一试,可以用 Docker 获取最新的 EDA 版本:
|
||||
|
||||
```
|
||||
$ docker run -p 80:80 jortilles / eda: latest
|
||||
```
|
||||
|
||||
我们还有一个 SaaS 选项,适用于任何想要使用 EDA 而无需进行安装、配置和持续更新的用户。你可以在我们的网站上查看 [云选项][9]。
|
||||
|
||||
如果你想看看它的实际运行情况,你可以在 YouTube 上观看一些 [演示][10]。
|
||||
|
||||
EDA 正在持续开发中,你可以在 GitHub 上找到它的 [源代码][11]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/visualize-data-eda
|
||||
|
||||
作者:[Juanjo Ortilles][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/jortilles
|
||||
[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://eda.jortilles.com/en/jortilles-english/
|
||||
[3]: https://www.jortilles.com/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/eda-display.jpeg (EDA interface)
|
||||
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]: https://opensource.com/article/20/10/mariadb-mysql-cheat-sheet
|
||||
[7]: https://opensource.com/sites/default/files/uploads/eda-chart.jpeg (EDA interface)
|
||||
[8]: https://demoeda.jortilles.com/
|
||||
[9]: https://eda.jortilles.com
|
||||
[10]: https://youtu.be/cBAAJbohHXQ
|
||||
[11]: https://github.com/jortilles/EDA
|
@ -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
|
@ -0,0 +1,116 @@
|
||||
[#]: subject: (13 ways to get involved with your favorite open source project)
|
||||
[#]: via: (https://opensource.com/article/21/4/open-source-project-level)
|
||||
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
13 ways to get involved with your favorite open source project
|
||||
======
|
||||
Apply GET/SET principles to connecting with open source projects.
|
||||
![Looking at a map for career journey][1]
|
||||
|
||||
Many of my [blog][2]'s readers already know lots about open source, but I'm also aware that many know little, if anything, about it. I'm a big, big proponent of open source software (and beyond, such as open hardware), and there are lots of great resources you can find to learn more about it.
|
||||
|
||||
One very good starting point is the one you're now reading, Opensource.com. It's run by a bunch of brilliant people for the broader community by my current employer, Red Hat. (I should add a disclaimer that I'm not only employed by Red Hat but also a [Correspondent][3] at Opensource.com—a kind of frequent contributor/Elder Thing.) It has articles on pretty much every aspect of open source that you can imagine.
|
||||
|
||||
I was thinking about APIs today (they're [in the news][4] as I'm writing this, after a US Supreme Court judgment on an argument between Google and Oracle), and it occurred to me that if I were interested in understanding how to interact with open source at the project level but didn't know much about it, then a quick guide might be useful. The same goes if I were involved in an open source project (e.g., [Enarx][5]) interested in attracting contributors (particularly techie contributors) who aren't already knowledgeable about open source.
|
||||
|
||||
Given that most programmers will understand what GET and SET methods do (one reads data, the other writes data), I thought this might be a useful framework for considering engagement.[1][6] I'll start with GET, as that's how you're likely to be starting off—finding out more about the project—and then move to SET methods for getting involved with an open source project.
|
||||
|
||||
This is far from an exhaustive list, but I hope that I've hit most of the key ways you're most likely to start getting involved or encouraging others to get involved. The order I've chosen reflects what I suspect is a fairly typical approach to finding out more about a project, particularly for those who aren't open source savvy already but, as they say, YMMV.[3][7]
|
||||
|
||||
I've managed to stop myself from using Enarx (which I co-founded) as the sole source of examples and have tried to find a variety of projects to give you a taster. Disclaimer: their inclusion here does not mean that I am a user or contributor to the project, nor is it any guarantee of their open source credentials, code quality, up to date-ness, project maturity, or community health.[4][8]
|
||||
|
||||
### GET methods
|
||||
|
||||
* **Landing page:** The first encounter you have with a project will probably be its landing page. Some projects go for something basic, others apply more design, but you should be able to use this as the starting point for your adventures around the project. You'd generally hope to find links to various of the other resources listed below from the landing page.
|
||||
* See [Sigstore][9]'s landing page.
|
||||
* **Wiki:** In many cases, the project will have a wiki. This could be simple, or it could be complex. It may allow editing by anyone or only by a select band of contributors to the project, and its relevance as a source of truth may be impacted by how up to date it is. Still, the wiki is usually an excellent place to start.
|
||||
* See the [Fedora Project][10] wiki.
|
||||
* **Videos:** Some projects maintain a set of videos about their project. These may include introductions to the concepts, talking-head interviews with team members, conference sessions, demos, how-tos, and more. It's also worth looking for videos put up by contributors to the project but not necessarily officially owned by the project.
|
||||
* See [Rust Language][11] videos.
|
||||
* **Code of conduct:** Many projects insist that their project members follow a code of conduct to reduce harassment, reduce friction, and generally make the project a friendly, more inclusive, and more diverse place to be.
|
||||
* See the [Linux kernel][12]'s CoC.
|
||||
* **Binary downloads:** As projects get more mature, they may choose to provide precompiled binary downloads for users. More technically inclined users may choose to compile their own binaries from the codebase (see below), but binary downloads can be a quick way to try out a project and see whether it does what you want.
|
||||
* See the binaries from [Chocolate Doom][13] (a Doom port).
|
||||
* **Design documentation:** Without design documentation, it can be very difficult to get really into a project. (I've written about the [importance of architecture diagrams][14] before.) This documentation is likely to include everything from an API definition to complex use cases and threat models.
|
||||
* See [Kubernetes][15]' design docs.
|
||||
* **Codebase:** You've found out all you need to get going: It's time to look at the code! This may vary from a few lines to many thousands, include documentation in comments, or include test cases, but if the code is not there, then the project can't legitimately call itself open source.
|
||||
* See [Rocket Rust web framework][16]'s code.[5][17]
|
||||
* **Email/chat:** Most projects like to have a way for contributors to discuss matters asynchronously. The preferred medium varies among projects, but most will choose an email list, a chat server, or both. These are where to get to know other users and contributors, ask questions, celebrate successful compiles, and just hang out.
|
||||
* See [Enarx chat][18].
|
||||
* **Meetups, videoconferences, calls, etc.:** Although in-person meetings are tricky for many at the moment (I'm writing as COVID-19 still reduces travel opportunities), having ways for community members and contributors to get together synchronously can be really helpful for everybody. Sometimes these are scheduled on a daily, weekly, or monthly basis; sometimes, they coincide with other, larger meetups, sometimes a project gets big enough to have its own meetups; sometimes, it's so big that there are meetups of subprojects or internal interest groups.
|
||||
* See the [Linux Security Summit Europe][19].
|
||||
|
||||
|
||||
|
||||
### PUT methods
|
||||
|
||||
* **Bug reports:** The first time many of us contribute anything substantive back to an open source project is when we file a bug report. Bug reports from new users can be really helpful for projects, as they not only expose bugs that may not already be known to the project, but they also give clues as to how actual users of the project are trying to use the code. If the project already publishes binary downloads (see above), you don't even need to compile the code to try it and submit a bug report. But bug reports related to compilation and build can also be extremely useful to the project. Sometimes, the mechanism for bug reporting also provides a way to ask more general questions about the project or to ask for new features.
|
||||
* See the issues page for [exa][20] (a replacement for the _ls_ command).
|
||||
* **Tests:** Once you've started using the project, another way to get involved (particularly once you start contributing code) can be to design and submit tests for how the project _ought_ to work. This can be a great way to unearth both your assumptions (and lack of knowledge!) about the project and the project's design assumptions (some of which may well be flawed). Tests are often part of the code repository, but not always.
|
||||
* See [GNOME Shell][21]'s test repository.
|
||||
* **Wiki:** A wiki can be a great way to contribute to the project, whether you're coding or not. Many projects don't have as much information available as they should, and that information may not be aimed at people coming to the project "fresh." If this is what you've done, then you're in a great position to write material that will help other "newbs" get into the project faster, as you'll know what would have helped you if it had been there.
|
||||
* See the wiki for [Wine][22] (Windows Emulator for Linux).
|
||||
* **Code:** Last but not least, you can write code. You may take hours, months, or years to get to this stage—or you may never reach it—but open source software is nothing without its code. If you've paid enough attention to the other steps, gotten involved in the community, understood what the project aims to do, and have the technical expertise (which you may well develop as you go!), then writing code may be the way you want to contribute.
|
||||
* See [Enarx][23] (again).
|
||||
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
1. I did consider standard RESTful verbs—GET, PUT, POST, and DELETE—but that felt rather contrived.[2][24]
|
||||
2. And I don't like the idea of DELETE in this context!
|
||||
3. "Your Mileage May Vary," meaning, basically, that your experience may be different, and that's to be expected.
|
||||
4. That said, I do use lots of them!
|
||||
5. I included this one because I've spent _far_ too much of my time looking at this over the past few months…
|
||||
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
_This article was originally published on [Alice, Eve, and Bob][25] and is reprinted with the author's permission._
|
||||
|
||||
Six non-code opportunities for contributing to open source software code and communities.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/open-source-project-level
|
||||
|
||||
作者:[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/career_journey_road_gps_path_map_520.png?itok=PpL6jJgY (Looking at a map for career journey)
|
||||
[2]: https://aliceevebob.com/
|
||||
[3]: https://opensource.com/correspondent-program
|
||||
[4]: https://www.eff.org/deeplinks/2021/04/victory-fair-use-supreme-court-reverses-federal-circuit-oracle-v-google
|
||||
[5]: https://enarx.dev/
|
||||
[6]: tmp.WF7h0s934j#1
|
||||
[7]: tmp.WF7h0s934j#3
|
||||
[8]: tmp.WF7h0s934j#4
|
||||
[9]: https://sigstore.dev/
|
||||
[10]: https://fedoraproject.org/wiki/Fedora_Project_Wiki
|
||||
[11]: https://www.youtube.com/channel/UCaYhcUwRBNscFNUKTjgPFiA
|
||||
[12]: https://www.kernel.org/doc/html/latest/process/code-of-conduct.html
|
||||
[13]: https://www.chocolate-doom.org/wiki/index.php/Downloads
|
||||
[14]: https://opensource.com/article/20/5/diagrams-documentation
|
||||
[15]: https://kubernetes.io/docs/reference/
|
||||
[16]: https://github.com/SergioBenitez/Rocket/tree/v0.4
|
||||
[17]: tmp.WF7h0s934j#5
|
||||
[18]: https://chat.enarx.dev/
|
||||
[19]: https://events.linuxfoundation.org/linux-security-summit-europe/
|
||||
[20]: https://github.com/ogham/exa/issues
|
||||
[21]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/tests/interactive
|
||||
[22]: https://wiki.winehq.org/Main_Page
|
||||
[23]: https://github.com/enarx
|
||||
[24]: tmp.WF7h0s934j#2
|
||||
[25]: https://aliceevebob.com/2021/04/06/get-set-methods-for-open-source-projects/
|
@ -0,0 +1,189 @@
|
||||
[#]: subject: (21 reasons why I think everyone should try Linux)
|
||||
[#]: via: (https://opensource.com/article/21/4/linux-reasons)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
||||
21 reasons why I think everyone should try Linux
|
||||
======
|
||||
Gaming, business, budgeting, art, programming, and more. These are just
|
||||
a few of the many ways anyone can use Linux.
|
||||
![Linux keys on the keyboard for a desktop computer][1]
|
||||
|
||||
When I go on holiday, I often end up at one or more used bookstores. I always find a good book I've been meaning to read, and I always justify the inevitable purchase by saying, "I'm on vacation; I should treat myself to this book." It works well, and I've acquired some of my favorite books this way. Yet, like so many traditions in life, it doesn't hold up to scrutiny. In reality, I don't need an excuse to buy a good book. All things being equal, I can do it any time I want. But having a reason does seem to make the process more enjoyable, somehow.
|
||||
|
||||
In my everyday life, I get a lot of questions about Linux. When caught unaware, I sometimes awkwardly ramble on about the history of open source software or the intellectual and economic benefits of sharing resources. Sometimes, I manage to mention some of my favorite features I enjoy on Linux and then end up reverse-engineering those benefits so they can be enjoyed on another operating system. These discussions are usually enjoyable and informative, but there's just one problem: None of it answers the question that people are really asking.
|
||||
|
||||
When a person asks you about Linux, they're often asking you to give them a reason to try it. There are exceptions, of course. People who have never heard the term "Linux" are probably asking for a literal definition of the word. But when your friends and colleagues confide that they're a little dissatisfied with their current operating system, it's probably safe to explain why you enjoy Linux, rather than lecturing them on why Linux is a better option than proprietary systems. In other words, you don't need a sales presentation; you need vacation photos (or used books you bought on vacation, if you're a bookworm).
|
||||
|
||||
To that end, the links below connect to 21 reasons I enjoy Linux, given to 21 separate people on 21 separate occasions.
|
||||
|
||||
### Gaming
|
||||
|
||||
![Gaming on Linux][2]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
When it comes to enjoying a computer, one of the most obvious activities is gaming, and when it comes to gaming, I love it all. I'm happy to spend an evening playing an 8-bit puzzler or a triple-A studio epic. Other times, I settle in for a board game or a tabletop role-playing game (RPG).
|
||||
|
||||
And I [do it all on a Linux computer][4].
|
||||
|
||||
### Office
|
||||
|
||||
![LibreOffice][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
One size doesn't fit all. This is as true for hats as it is for office work. It pains me to see colleagues locked into a singular workflow that doesn't suit them, and I enjoy the way Linux encourages users to find tools they love. I've used office applications ranging from big suites (like LibreOffice and OpenOffice) to lightweight word processors (such as Abiword) to minimal text editors (with Pandoc for conversion).
|
||||
|
||||
Regardless of what users around me are locked into, I have [the freedom to use the tools that work best][6] on my computer and with the way I want to work.
|
||||
|
||||
### Choice
|
||||
|
||||
![Linux login screen][7]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
One of open source's most valuable traits is the trust it allows users to have in the software they use. This trust is derived from a network of friends who can read the source code of the applications and operating systems they use. That means, even if you don't know good source code from bad, you can make friends within the [open source community][8] who do. These are important connections that Linux users can make as they explore the distribution they run. If you don't trust the community that builds and maintains a distribution, you can and should move to a different distribution. Many of us have done it, and it's one of the strengths of having many distros to choose from.
|
||||
|
||||
[Linux offers choice][9] as a feature. A strong community, filled with real human connections, combined with the freedom of choice that Linux provides all give users confidence in the software they run. Because I've read some source code, and because I trust the people who maintain the code I haven't read, [I trust Linux][10].
|
||||
|
||||
### Budgeting
|
||||
|
||||
![Skrooge][11]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
Budgeting isn't fun, but it's important. I learned early, while working menial jobs as I learned a _free_ operating system (Linux!) in my free time, that a budget isn't meant to track your money so much as it tracks your habits. That means that whether you're living paycheck to paycheck or you're well on the way to planning your retirement, you should [maintain a budget][12].
|
||||
|
||||
If you're in the United States, you can even [pay your taxes on Linux][13].
|
||||
|
||||
### Art
|
||||
|
||||
![MyPaint][14]
|
||||
|
||||
(Dogchicken, [CC BY-SA 4.0][3])
|
||||
|
||||
It doesn't matter whether you paint or do pixel art, [edit video][15], or scratch records, you can create great content on Linux. Some of the best art I've seen has been casually made with tools that aren't "industry standard," and it might surprise you just how much of the content you see is made the same way. Linux is a quiet engine, but it's a powerful one that drives indie artists as well as big producers.
|
||||
|
||||
Try using Linux [to create some art][16].
|
||||
|
||||
### Programming
|
||||
|
||||
![NetBeans][17]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
Look, using Linux to program is almost a foregone conclusion. Second only to server administration, open source code and Linux are an obvious combination. There are [many reasons for this][18], but the one I cite is that it's just more fun. I run into plenty of roadblocks when inventing something new, so the last thing I need is for an operating system or software development kit (SDK) to be the reason for failure. On Linux, I have access to everything. Literally everything.
|
||||
|
||||
### Packaging
|
||||
|
||||
![Packaging GNOME software][19]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
The thing nobody talks about when they tell you about programming is _packaging_. As a developer, you have to get your code to your users, or you won't have any users. Linux makes it easy for developers [to deliver apps][20] and easy for users to [install those applications][21].
|
||||
|
||||
It surprises many people, but [Linux can run many Windows applications][22] as if they were native apps. You shouldn't expect a Windows application to be executable on Linux. Still, many of the major common applications either already exist natively on Linux or else can be run through a compatibility layer called Wine.
|
||||
|
||||
### Technology
|
||||
|
||||
![Data center][23]
|
||||
|
||||
([Taylor Vick][24], [Unsplash License][25])
|
||||
|
||||
If you're looking for a career in IT, Linux is a great first step. As a former art student who stumbled into Linux to render video faster, I speak from experience!
|
||||
|
||||
Cutting-edge technology happens on Linux. Linux drives most of the internet, most of the world's fastest supercomputers, and the cloud itself. Today, Linux drives [edge computing][26], combining the power of cloud data centers with decentralized nodes for quick response.
|
||||
|
||||
You don't have to start at the top, though. You can learn to [automate][27] tasks on your laptop or desktop and remotely control systems with a [good terminal][28].
|
||||
|
||||
Linux is open to your new ideas and [available for customization][29].
|
||||
|
||||
### Share files
|
||||
|
||||
![Beach with cloudy sky][30]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
Whether you're a fledgling sysadmin or just a housemate with files to distribute to friends, Linux makes [file sharing a breeze][31].
|
||||
|
||||
### Media
|
||||
|
||||
![Waterfall][32]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
With all the talk about programming and servers, people sometimes envision Linux as just a black screen filled with green 1's and 0's. Unsurprisingly to those of us who use it, Linux [plays all your media][33], too.
|
||||
|
||||
### Easy install
|
||||
|
||||
![CentOS installation][34]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
Never installed an operating system before? Linux is shockingly easy. Step-by-step, Linux installers hold your hand through an operating system installation to make you feel like a computer expert in under an hour.
|
||||
|
||||
[Go install Linux][35]!
|
||||
|
||||
### Try Linux
|
||||
|
||||
![Porteus][36]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][3])
|
||||
|
||||
If you're not ready to install Linux, then you can _try_ Linux instead. No idea where to start? It's less intimidating than you may think. Here are some [things you should consider first][37]. Then take your pick, download a distro, and come up with your own 21 reasons to use Linux.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/4/linux-reasons
|
||||
|
||||
作者:[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/linux_keyboard_desktop.png?itok=I2nGw78_ (Linux keys on the keyboard for a desktop computer)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/game_0ad-egyptianpyramids.jpg (Gaming on Linux)
|
||||
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[4]: https://opensource.com/article/21/2/linux-gaming
|
||||
[5]: https://opensource.com/sites/default/files/uploads/office_libreoffice.jpg (LibreOffice)
|
||||
[6]: https://opensource.com/article/21/2/linux-workday
|
||||
[7]: https://opensource.com/sites/default/files/uploads/trust_sddm.jpg (Linux login screen)
|
||||
[8]: https://opensource.com/article/21/2/linux-community
|
||||
[9]: https://opensource.com/article/21/2/linux-choice
|
||||
[10]: https://opensource.com/article/21/2/open-source-security
|
||||
[11]: https://opensource.com/sites/default/files/uploads/skrooge_1.jpg (Skrooge)
|
||||
[12]: https://opensource.com/article/21/2/linux-skrooge
|
||||
[13]: https://opensource.com/article/21/2/linux-tax-software
|
||||
[14]: https://opensource.com/sites/default/files/uploads/art_mypaint.jpg (MyPaint)
|
||||
[15]: https://opensource.com/article/21/2/linux-python-video
|
||||
[16]: https://opensource.com/article/21/2/linux-art-design
|
||||
[17]: https://opensource.com/sites/default/files/uploads/programming_java-netbeans.jpg (NetBeans)
|
||||
[18]: https://opensource.com/article/21/2/linux-programming
|
||||
[19]: https://opensource.com/sites/default/files/uploads/packaging_gnome-software.png (Packaging GNOME software)
|
||||
[20]: https://opensource.com/article/21/2/linux-packaging
|
||||
[21]: https://opensource.com/article/21/2/linux-package-management
|
||||
[22]: https://opensource.com/article/21/2/linux-wine
|
||||
[23]: https://opensource.com/sites/default/files/uploads/edge_taylorvick-unsplash.jpg (Data center)
|
||||
[24]: https://unsplash.com/@tvick
|
||||
[25]: https://unsplash.com/license
|
||||
[26]: https://opensource.com/article/21/2/linux-edge-computing
|
||||
[27]: https://opensource.com/article/21/2/linux-automation
|
||||
[28]: https://opensource.com/article/21/2/linux-terminals
|
||||
[29]: https://opensource.com/article/21/2/linux-technology
|
||||
[30]: https://opensource.com/sites/default/files/uploads/cloud_beach-sethkenlon.jpg (Beach with cloudy sky)
|
||||
[31]: https://opensource.com/article/21/3/linux-server
|
||||
[32]: https://opensource.com/sites/default/files/uploads/media_waterfall.jpg (Waterfall)
|
||||
[33]: https://opensource.com/article/21/2/linux-media-players
|
||||
[34]: https://opensource.com/sites/default/files/uploads/install_centos8.jpg (CentOS installation)
|
||||
[35]: https://opensource.com/article/21/2/linux-installation
|
||||
[36]: https://opensource.com/sites/default/files/uploads/porteus_0.jpg (Porteus)
|
||||
[37]: https://opensource.com/article/21/2/try-linux
|
@ -1,107 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to set up a homelab from hardware to firewall)
|
||||
[#]: via: (https://opensource.com/article/19/3/home-lab)
|
||||
[#]: author: (Michael Zamot https://opensource.com/users/mzamot)
|
||||
|
||||
How to set up a homelab from hardware to firewall
|
||||
======
|
||||
|
||||
Take a look at hardware and software options for building your own homelab.
|
||||
|
||||
![][1]
|
||||
|
||||
Do you want to create a homelab? Maybe you want to experiment with different technologies, create development environments, or have your own private cloud. There are many reasons to have a homelab, and this guide aims to make it easier to get started.
|
||||
|
||||
There are three categories to consider when planning a home lab: hardware, software, and maintenance. We'll look at the first two categories here and save maintaining your computer lab for a future article.
|
||||
|
||||
### Hardware
|
||||
|
||||
When thinking about your hardware needs, first consider how you plan to use your lab as well as your budget, noise, space, and power usage.
|
||||
|
||||
If buying new hardware is too expensive, search local universities, ads, and websites like eBay or Craigslist for recycled servers. They are usually inexpensive, and server-grade hardware is built to last many years. You'll need three types of hardware: a virtualization server, storage, and a router/firewall.
|
||||
|
||||
#### Virtualization servers
|
||||
|
||||
A virtualization server allows you to run several virtual machines that share the physical box's resources while maximizing and isolating resources. If you break one virtual machine, you won't have to rebuild the entire server, just the virtual one. If you want to do a test or try something without the risk of breaking your entire system, just spin up a new virtual machine and you're ready to go.
|
||||
|
||||
The two most important factors to consider in a virtualization server are the number and speed of its CPU cores and its memory. If there are not enough resources to share among all the virtual machines, they'll be overallocated and try to steal each other's CPU cycles and memory.
|
||||
|
||||
So, consider a CPU platform with multiple cores. You want to ensure the CPU supports virtualization instructions (VT-x for Intel and AMD-V for AMD). Examples of good consumer-grade processors that can handle virtualization are Intel i5 or i7 and AMD Ryzen. If you are considering server-grade hardware, the Xeon class for Intel and EPYC for AMD are good options. Memory can be expensive, especially the latest DDR4 SDRAM. When estimating memory requirements, factor at least 2GB for the host operating system's memory consumption.
|
||||
|
||||
If your electricity bill or noise is a concern, solutions like Intel's NUC devices provide a small form factor, low power usage, and reduced noise, but at the expense of expandability.
|
||||
|
||||
#### Network-attached storage (NAS)
|
||||
|
||||
If you want a machine loaded with hard drives to store all your personal data, movies, pictures, etc. and provide storage for the virtualization server, network-attached storage (NAS) is what you want.
|
||||
|
||||
In most cases, you won't need a powerful CPU; in fact, many commercial NAS solutions use low-powered ARM CPUs. A motherboard that supports multiple SATA disks is a must. If your motherboard doesn't have enough ports, use a host bus adapter (HBA) SAS controller to add extras.
|
||||
|
||||
Network performance is critical for a NAS, so select a gigabit network interface (or better).
|
||||
|
||||
Memory requirements will differ based on your filesystem. ZFS is one of the most popular filesystems for NAS, and you'll need more memory to use features such as caching or deduplication. Error-correcting code (ECC) memory is your best bet to protect data from corruption (but make sure your motherboard supports it before you buy). Last, but not least, don't forget an uninterruptible power supply (UPS), because losing power can cause data corruption.
|
||||
|
||||
#### Firewall and router
|
||||
|
||||
Have you ever realized that a cheap router/firewall is usually the main thing protecting your home network from the exterior world? These routers rarely receive timely security updates, if they receive any at all. Scared now? Well, [you should be][2]!
|
||||
|
||||
You usually don't need a powerful CPU or a great deal of memory to build your own router/firewall, unless you are handling a huge throughput or want to do CPU-intensive tasks, like a VPN server or traffic filtering. In such cases, you'll need a multicore CPU with AES-NI support.
|
||||
|
||||
You may want to get at least two 1-gigabit or better Ethernet network interface cards (NICs), also, not needed, but recommended, a managed switch to connect your DIY-router to create VLANs to further isolate and secure your network.
|
||||
|
||||
![Home computer lab PfSense][4]
|
||||
|
||||
### Software
|
||||
|
||||
After you've selected your virtualization server, NAS, and firewall/router, the next step is exploring the different operating systems and software to maximize their benefits. While you could use a regular Linux distribution like CentOS, Debian, or Ubuntu, they usually take more time to configure and administer than the following options.
|
||||
|
||||
#### Virtualization software
|
||||
|
||||
**[KVM][5]** (Kernel-based Virtual Machine) lets you turn Linux into a hypervisor so you can run multiple virtual machines in the same box. The best thing is that KVM is part of Linux, and it is the go-to option for many enterprises and home users. If you are comfortable, you can install **[libvirt][6]** and **[virt-manager][7]** to manage your virtualization platform.
|
||||
|
||||
**[Proxmox VE][8]** is a robust, enterprise-grade solution and a full open source virtualization and container platform. It is based on Debian and uses KVM as its hypervisor and LXC for containers. Proxmox offers a powerful web interface, an API, and can scale out to many clustered nodes, which is helpful because you'll never know when you'll run out of capacity in your lab.
|
||||
|
||||
**[oVirt][9] (RHV)** is another enterprise-grade solution that uses KVM as the hypervisor. Just because it's enterprise doesn't mean you can't use it at home. oVirt offers a powerful web interface and an API and can handle hundreds of nodes (if you are running that many servers, I don't want to be your neighbor!). The potential problem with oVirt for a home lab is that it requires a minimum set of nodes: You'll need one external storage, such as a NAS, and at least two additional virtualization nodes (you can run it just on one, but you'll run into problems in maintenance of your environment).
|
||||
|
||||
#### NAS software
|
||||
|
||||
**[FreeNAS][10]** is the most popular open source NAS distribution, and it's based on the rock-solid FreeBSD operating system. One of its most robust features is its use of the ZFS filesystem, which provides data-integrity checking, snapshots, replication, and multiple levels of redundancy (mirroring, striped mirrors, and striping). On top of that, everything is managed from the powerful and easy-to-use web interface. Before installing FreeNAS, check its hardware support, as it is not as wide as Linux-based distributions.
|
||||
|
||||
Another popular alternative is the Linux-based **[OpenMediaVault][11]**. One of its main features is its modularity, with plugins that extend and add features. Among its included features are a web-based administration interface; protocols like CIFS, SFTP, NFS, iSCSI; and volume management, including software RAID, quotas, access control lists (ACLs), and share management. Because it is Linux-based, it has extensive hardware support.
|
||||
|
||||
#### Firewall/router software
|
||||
|
||||
**[pfSense][12]** is an open source, enterprise-grade FreeBSD-based router and firewall distribution. It can be installed directly on a server or even inside a virtual machine (to manage your virtual or physical networks and save space). It has many features and can be expanded using packages. It is managed entirely using the web interface, although it also has command-line access. It has all the features you would expect from a router and firewall, like DHCP and DNS, as well as more advanced features, such as intrusion detection (IDS) and intrusion prevention (IPS) systems. You can create multiple networks listening on different interfaces or using VLANs, and you can create a secure VPN server with a few clicks. pfSense uses pf, a stateful packet filter that was developed for the OpenBSD operating system using a syntax similar to IPFilter. Many companies and organizations use pfSense.
|
||||
|
||||
* * *
|
||||
|
||||
With all this information in mind, it's time for you to get your hands dirty and start building your lab. In a future article, I will get into the third category of running a home lab: using automation to deploy and maintain it.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/home-lab
|
||||
|
||||
作者:[Michael Zamot (Red Hat)][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/mzamot
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_code_woman.png?itok=vbYz6jjb
|
||||
[2]: https://opensource.com/article/18/5/how-insecure-your-router
|
||||
[3]: /file/427426
|
||||
[4]: https://opensource.com/sites/default/files/uploads/pfsense2.png (Home computer lab PfSense)
|
||||
[5]: https://www.linux-kvm.org/page/Main_Page
|
||||
[6]: https://libvirt.org/
|
||||
[7]: https://virt-manager.org/
|
||||
[8]: https://www.proxmox.com/en/proxmox-ve
|
||||
[9]: https://ovirt.org/
|
||||
[10]: https://freenas.org/
|
||||
[11]: https://www.openmediavault.org/
|
||||
[12]: https://www.pfsense.org/
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( chensanle )
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,139 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: 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)
|
||||
|
||||
4 open source chat applications you should use right now
|
||||
======
|
||||
Collaborating remotely is an essential capability now, making open
|
||||
source real-time chat an essential piece of your toolbox.
|
||||
![Chat bubbles][1]
|
||||
|
||||
The first thing we usually do after waking up in the morning is to check our cellphone to see if there are important messages from our colleagues and friends. Whether or not it's a good idea, this behavior has become part of our daily lifestyle.
|
||||
|
||||
> _"Man is a rational animal. He can think up a reason for anything he wants to believe."_
|
||||
> _– Anatole France_
|
||||
|
||||
No matter the soundness of the reason, we all have a suite of communication tools—email, phone calls, web-conferencing tools, or social networking—we use on a daily basis. Even before COVID-19, working from home already made these communication tools an essential part of our world. And as the pandemic has made working from home the new normal, we're facing unprecedented changes to how we communicate, which makes these tools not merely essential but now required.
|
||||
|
||||
### Why chat?
|
||||
|
||||
When working remotely as a part of a globally distributed team, we must have a collaborative environment. Chat applications play a vital role in helping us stay connected. In contrast to email, chat applications provide fast, real-time communications with colleagues around the globe.
|
||||
|
||||
There are a lot of factors involved in choosing a chat application. To help you pick the right one for you, in this article, I'll explore four open source chat applications and one open source video-communication tool (for when you need to be "face-to-face" with your colleagues), then outline some of the features you should look for in an effective communication application.
|
||||
|
||||
### 4 open source chat apps
|
||||
|
||||
#### Rocket.Chat
|
||||
|
||||
![Rocket.Chat][2]
|
||||
|
||||
[Rocket.Chat][3] is a comprehensive communication platform that classifies channels as public (open to anyone who joins) or private (invitation-only) rooms. You can also send direct messages to people who are logged in; share documents, links, photos, videos, and GIFs; make video calls; and send audio messages without leaving the platform.
|
||||
|
||||
Rocket.Chat is free and open source, but what makes it unique is its self-hosted chat system. You can download it onto your server, whether it's an on-premises server or a virtual private server on a public cloud.
|
||||
|
||||
Rocket.Chat is completely free, and its [source code][4] is available on GitHub. Many open source projects use Rocket.Chat as their official communication platform. It is constantly evolving with new features and improvements.
|
||||
|
||||
The things I like the most about Rocket.Chat are its ability to be customized according to user requirements and that it uses machine learning to do automatic, real-time message translation between users. You can also download Rocket.Chat for your mobile device and use it on the go.
|
||||
|
||||
#### IRC
|
||||
|
||||
![IRC on WeeChat 0.3.5][5]
|
||||
|
||||
[Internet Relay Chat (IRC)][6] is a real-time, text-based form of communication. Although it's one of the oldest forms of electronic communication, it remains popular among many well-known software projects.
|
||||
|
||||
IRC channels are discrete chat rooms. It allows you to have conversations with multiple people in an open channel or chat with someone privately one-on-one. If a channel name starts with a #, you can assume it to be official, whereas chat rooms that begin with ## are unofficial and usually casual.
|
||||
|
||||
[Getting started with IRC][7] is easy. Your IRC handle or nickname is what allows people to find you, so it must be unique. But your choice of IRC client is completely your decision. If you want a more feature-rich application than a standard IRC client, you can connect to IRC with [Riot.im][8].
|
||||
|
||||
Given its age, why should you still be on IRC? For one reason, it remains the home for many of the free and open source projects we depend on. If you want to participate in open source software and communities, IRC is the option to get started.
|
||||
|
||||
#### Zulip
|
||||
|
||||
![Zulip][9]
|
||||
|
||||
[Zulip][10] is a popular group-chat application that follows the topic-based threading model. In Zulip, you subscribe to streams, just like in IRC channels or Rocket.Chat. But each Zulip stream opens a topic that is unique, which helps you track conversations later, thus making it more organized.
|
||||
|
||||
Like other platforms, it supports emojis, inline images, video, and tweet previews. It also supports LaTeX for sharing math formulas or equations and Markdown and syntax highlighting for sharing code.
|
||||
|
||||
Zulip is cross-platform and offers APIs for building your own integrations. Something I especially like about Zulip is its integration feature with GitHub: if I'm working on an issue, I can use Zulip's marker to link back to the pull request ID.
|
||||
|
||||
Zulip is open source (you can access its [source code][11] on GitHub) and free to use, but it has paid offerings for on-premises support, [LDAP][12] integration, and more storage.
|
||||
|
||||
#### Let's Chat
|
||||
|
||||
![Let's Chat][13]
|
||||
|
||||
[Let's Chat][14] is a self-hosted chat solution for small teams. It runs on Node.js and MongoDB and can be deployed to local servers or hosted services with a few clicks. It's free and open source, with the [source code][15] available on GitHub.
|
||||
|
||||
What differentiates Let's Chat from other open source chat tools is its enterprise features: it supports LDAP and [Kerberos][16] authentication. It also has all the features a new user would want: you can search message history in the archives and tag people with mentions like @username.
|
||||
|
||||
What I like about Let's Chat is that it has private and password-protected rooms, image embeds, GIPHY support, and code pasting. It is constantly evolving and adding more features to its bucket.
|
||||
|
||||
### Bonus: Open source video chat with Jitsi
|
||||
|
||||
![Jitsi][17]
|
||||
|
||||
Sometimes text chat isn't enough, and you need to talk to someone face-to-face. In times like these, when in-person meetings aren't an option, video chat is the best alternative. [Jitsi][18] is a complete, open source, multi-platform, and WebRTC-compliant videoconferencing tool.
|
||||
|
||||
Jitsi began with Jitsi Desktop and has evolved into multiple [projects][19], including Jitsi Meet, Jitsi Videobridge, jibri, and libjitsi, with [source code][20] published for each on GitHub.
|
||||
|
||||
Jitsi is secure and scalable and supports advanced video-routing concepts such as simulcast and bandwidth estimation, as well as typical capabilities like audio, recording, screen-sharing, and dial-in features. You can set a password to secure your video-chat room and protect it against intruders, and it also supports live-streaming over YouTube. You can also build your own Jitsi server and host it on-premises or on a virtual private server, such as a Digital Ocean Droplet.
|
||||
|
||||
What I like most about Jitsi is that it is free and frictionless; anyone can start a meeting in no time by visiting [meet.jit.si][21], and users are good to go with no need for registration or installation. (However, registration gives you calendar integrations.) This low-barrier-to-entry alternative to popular videoconferencing services is helping Jitsi's popularity spread rapidly.
|
||||
|
||||
### Tips for choosing a chat application
|
||||
|
||||
The variety of open source chat applications can make it hard to pick one. The following are some general guidelines for choosing a chat app.
|
||||
|
||||
* Tools that have an interactive interface and simple navigation are ideal.
|
||||
* It's better to look for a tool that has great features and allows people to use it in various ways.
|
||||
* Integrations with tools you use can play an important role in your decision. Some tools have great and seamless integrations with GitHub, GitLab, and certain applications, which is a useful feature.
|
||||
* It's convenient to use tools that have a pathway to hosting on cloud-based services.
|
||||
* The security of the chat service should be taken into account. The ability to host services on a private server is necessary for many organizations and individuals.
|
||||
* It's best to select communication tools that have rich privacy settings and allow for both private and public chat rooms.
|
||||
|
||||
|
||||
|
||||
Since people are more dependent than ever on online services, it is smart to have a backup communication platform available. For example, if a project is using Rocket.Chat, it should also have the option to hop into IRC, if necessary. Since these services are continuously updating, you may find yourself connected to multiple channels, and this is where integration becomes so valuable.
|
||||
|
||||
Of the different open source chat services available, which ones do you like and use? How do these tools help you work remotely? Please share your thoughts in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/4/open-source-chat
|
||||
|
||||
作者:[Sudeshna Sur][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/sudeshna-sur
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_communication_team.png?itok=CYfZ_gE7 (Chat bubbles)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/rocketchat.png (Rocket.Chat)
|
||||
[3]: https://rocket.chat/
|
||||
[4]: https://github.com/RocketChat/Rocket.Chat
|
||||
[5]: https://opensource.com/sites/default/files/uploads/irc.png (IRC on WeeChat 0.3.5)
|
||||
[6]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
|
||||
[7]: https://opensource.com/article/16/6/getting-started-irc
|
||||
[8]: https://opensource.com/article/17/5/introducing-riot-IRC
|
||||
[9]: https://opensource.com/sites/default/files/uploads/zulip.png (Zulip)
|
||||
[10]: https://zulipchat.com/
|
||||
[11]: https://github.com/zulip/zulip
|
||||
[12]: https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol
|
||||
[13]: https://opensource.com/sites/default/files/uploads/lets-chat.png (Let's Chat)
|
||||
[14]: https://sdelements.github.io/lets-chat/
|
||||
[15]: https://github.com/sdelements/lets-chat
|
||||
[16]: https://en.wikipedia.org/wiki/Kerberos_(protocol)
|
||||
[17]: https://opensource.com/sites/default/files/uploads/jitsi_0_0.jpg (Jitsi)
|
||||
[18]: https://jitsi.org/
|
||||
[19]: https://jitsi.org/projects/
|
||||
[20]: https://github.com/jitsi
|
||||
[21]: http://meet.jit.si
|
@ -1,551 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Use systemd timers instead of cronjobs)
|
||||
[#]: via: (https://opensource.com/article/20/7/systemd-timers)
|
||||
[#]: author: (David Both https://opensource.com/users/dboth)
|
||||
|
||||
Use systemd timers instead of cronjobs
|
||||
======
|
||||
Timers provide finer-grained control of events than cronjobs.
|
||||
![Team checklist][1]
|
||||
|
||||
I am in the process of converting my [cron][2] jobs to systemd timers. I have used timers for a few years, but usually, I learned just enough to perform the task I was working on. While doing research for this [systemd series][3], I learned that systemd timers have some very interesting capabilities.
|
||||
|
||||
Like cron jobs, systemd timers can trigger events—shell scripts and programs—at specified time intervals, such as once a day, on a specific day of the month (perhaps only if it is a Monday), or every 15 minutes during business hours from 8am to 6pm. Timers can also do some things that cron jobs cannot. For example, a timer can trigger a script or program to run a specific amount of time after an event such as boot, startup, completion of a previous task, or even the previous completion of the service unit called by the timer.
|
||||
|
||||
### System maintenance timers
|
||||
|
||||
When Fedora or any systemd-based distribution is installed on a new system, it creates several timers that are part of the system maintenance procedures that happen in the background of any Linux host. These timers trigger events necessary for common maintenance tasks, such as updating system databases, cleaning temporary directories, rotating log files, and more.
|
||||
|
||||
As an example, I'll look at some of the timers on my primary workstation by using the `systemctl status *timer` command to list all the timers on my host. The asterisk symbol works the same as it does for file globbing, so this command lists all systemd timer units:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemctl status *timer
|
||||
● mlocate-updatedb.timer - Updates mlocate database every day
|
||||
Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
|
||||
Triggers: ● mlocate-updatedb.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day.
|
||||
|
||||
● logrotate.timer - Daily rotation of log files
|
||||
Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left
|
||||
Triggers: ● logrotate.service
|
||||
Docs: man:logrotate(8)
|
||||
man:logrotate.conf(5)
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files.
|
||||
|
||||
● sysstat-summary.timer - Generate summary of yesterday's process accounting
|
||||
Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left
|
||||
Triggers: ● sysstat-summary.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting.
|
||||
|
||||
● fstrim.timer - Discard unused blocks once a week
|
||||
Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left
|
||||
Triggers: ● fstrim.service
|
||||
Docs: man:fstrim
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week.
|
||||
|
||||
● sysstat-collect.timer - Run system activity accounting tool every 10 minutes
|
||||
Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left
|
||||
Triggers: ● sysstat-collect.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes.
|
||||
|
||||
● dnf-makecache.timer - dnf makecache --timer
|
||||
Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left
|
||||
Triggers: ● dnf-makecache.service
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer.
|
||||
|
||||
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
|
||||
Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
|
||||
Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago
|
||||
Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left
|
||||
Triggers: ● systemd-tmpfiles-clean.service
|
||||
Docs: man:tmpfiles.d(5)
|
||||
man:systemd-tmpfiles(8)
|
||||
|
||||
Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.
|
||||
```
|
||||
|
||||
Each timer has at least six lines of information associated with it:
|
||||
|
||||
* The first line has the timer's file name and a short description of its purpose.
|
||||
* The second line displays the timer's status, whether it is loaded, the full path to the timer unit file, and the vendor preset.
|
||||
* The third line indicates its active status, which includes the date and time the timer became active.
|
||||
* The fourth line contains the date and time the timer will be triggered next and an approximate time until the trigger occurs.
|
||||
* The fifth line shows the name of the event or the service that is triggered by the timer.
|
||||
* Some (but not all) systemd unit files have pointers to the relevant documentation. Three of the timers in my virtual machine's output have pointers to documentation. This is a nice (but optional) bit of data.
|
||||
* The final line is the journal entry for the most recent instance of the service triggered by the timer.
|
||||
|
||||
|
||||
|
||||
Depending upon your host, you will probably have a different set of timers.
|
||||
|
||||
### Create a timer
|
||||
|
||||
Although we can deconstruct one or more of the existing timers to learn how they work, let’s create our own [service unit][4] and a timer unit to trigger it. We will use a fairly trivial example in order to keep this simple. After we have finished this, it will be easier to understand how the other timers work and to determine what they are doing.
|
||||
|
||||
First, create a simple service that will run something basic, such as the `free` command. For example, you may want to monitor free memory at regular intervals. Create the following `myMonitor.service` unit file in the `/etc/systemd/system` directory. It does not need to be executable:
|
||||
|
||||
|
||||
```
|
||||
# This service unit is for testing timer units
|
||||
# By David Both
|
||||
# Licensed under GPL V2
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description=Logs system statistics to the systemd journal
|
||||
Wants=myMonitor.timer
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/free
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
This is about the simplest service unit you can create. Now let’s look at the status and test our service unit to ensure that it works as we expect it to.
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemctl status myMonitor.service
|
||||
● myMonitor.service - Logs system statistics to the systemd journal
|
||||
Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)
|
||||
Active: inactive (dead)
|
||||
[root@testvm1 system]# systemctl start myMonitor.service
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
Where is the output? By default, the standard output (`STDOUT`) from programs run by systemd service units is sent to the systemd journal, which leaves a record you can view now or later—up to a point. (I will look at systemd journaling and retention strategies in a future article in this series.) Look at the journal specifically for your service unit and for today only. The `-S` option, which is the short version of `--since`, allows you to specify the time period that the `journalctl` tool should search for entries. This isn't because you don't care about previous results—in this case, there won't be any—it is to shorten the search time if your host has been running for a long time and has accumulated a large number of entries in the journal:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -u myMonitor.service
|
||||
\-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --
|
||||
Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: total used free shared buff/cache available
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: Mem: 12635740 522868 11032860 8016 1080012 11821508
|
||||
Jun 11 09:12:09 testvm1.both.org free[377966]: Swap: 8388604 0 8388604
|
||||
Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
A task triggered by a service can be a single program, a series of programs, or a script written in any scripting language. Add another task to the service by adding the following line to the end of the `[Service]` section of the `myMonitor.service` unit file:
|
||||
|
||||
|
||||
```
|
||||
`ExecStart=/usr/bin/lsblk`
|
||||
```
|
||||
|
||||
Start the service again and check the journal for the results, which should look like this. You should see the results from both commands in the journal:
|
||||
|
||||
|
||||
```
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: total used free shared buff/cache available
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: Mem: 12635740 531788 11019540 8024 1084412 11812272
|
||||
Jun 11 15:42:18 testvm1.both.org free[379961]: Swap: 8388604 0 8388604
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sda 8:0 0 120G 0 disk
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
```
|
||||
|
||||
Now that you know your service works as expected, create the timer unit file, `myMonitor.timer` in `/etc/systemd/system`, and add the following:
|
||||
|
||||
|
||||
```
|
||||
# This timer unit is for testing
|
||||
# By David Both
|
||||
# Licensed under GPL V2
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description=Logs some system statistics to the systemd journal
|
||||
Requires=myMonitor.service
|
||||
|
||||
[Timer]
|
||||
Unit=myMonitor.service
|
||||
OnCalendar=*-*-* *:*:00
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
The `OnCalendar` time specification in the `myMonitor.timer file`, `*-*-* *:*:00`, should trigger the timer to execute the `myMonitor.service` unit every minute. I will explore `OnCalendar` settings a bit later in this article.
|
||||
|
||||
For now, observe any journal entries pertaining to running your service when it is triggered by the timer. You could also follow the timer, but following the service allows you to see the results in near real time. Run `journalctl` with the `-f` (follow) option:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
|
||||
\-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
|
||||
```
|
||||
|
||||
Start but do not enable the timer, and see what happens after it runs for a while:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemctl start myMonitor.service
|
||||
[root@testvm1 ~]#
|
||||
```
|
||||
|
||||
One result shows up right away, and the next ones come at—sort of—one-minute intervals. Watch the journal for a few minutes and see if you notice the same things I did:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# journalctl -S today -f -u myMonitor.service
|
||||
\-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: total used free shared buff/cache available
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: Mem: 12635740 556604 10965516 8036 1113620 11785628
|
||||
Jun 13 08:39:19 testvm1.both.org free[630566]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: total used free shared buff/cache available
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: Mem: 12635740 555228 10966836 8036 1113676 11786996
|
||||
Jun 13 08:40:46 testvm1.both.org free[630572]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: total used free shared buff/cache available
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: Mem: 12635740 553488 10968564 8036 1113688 11788744
|
||||
Jun 13 08:41:46 testvm1.both.org free[630580]: Swap: 8388604 0 8388604
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sda 8:0 0 120G 0 disk
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1 8:1 0 4G 0 part /boot
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2 8:2 0 116G 0 part
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-root 253:0 0 5G 0 lvm /
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-swap 253:1 0 8G 0 lvm [SWAP]
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-usr 253:2 0 30G 0 lvm /usr
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-tmp 253:3 0 10G 0 lvm /tmp
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─VG01-var 253:4 0 20G 0 lvm /var
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: └─VG01-home 253:5 0 10G 0 lvm /home
|
||||
Jun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0 11:0 1 1024M 0 rom
|
||||
Jun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.
|
||||
Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.
|
||||
```
|
||||
|
||||
Be sure to check the status of both the timer and the service.
|
||||
|
||||
You probably noticed at least two things in the journal. First, you do not need to do anything special to cause the `STDOUT` from the `ExecStart` triggers in the `myMonitor.service` unit to be stored in the journal. That is all part of using systemd for running services. However, it does mean that you might need to be careful about running scripts from a service unit and how much `STDOUT` they generate.
|
||||
|
||||
The second thing is that the timer does not trigger exactly on the minute at :00 seconds or even exactly one minute from the previous instance. This is intentional, but it can be overridden if necessary (or if it just offends your sysadmin sensibilities).
|
||||
|
||||
The reason for this behavior is to prevent multiple services from triggering at exactly the same time. For example, you can use time specifications such as Weekly, Daily, and more. These shortcuts are all defined to trigger at 00:00:00 hours on the day they are triggered. When multiple timers are specified this way, there is a strong likelihood that they would attempt to start simultaneously.
|
||||
|
||||
systemd timers are intentionally designed to trigger somewhat randomly around the specified time to try to prevent simultaneous triggers. They trigger semi-randomly within a time window that starts at the specified trigger time and ends at the specified time plus one minute. This trigger time is maintained at a stable position with respect to all other defined timer units, according to the `systemd.timer` man page. You can see in the journal entries above that the timer triggered immediately when it started and then about 46 or 47 seconds after each minute.
|
||||
|
||||
Most of the time, such probabilistic trigger times are fine. When scheduling tasks such as backups to run, so long as they run during off-hours, there will be no problems. A sysadmin can select a deterministic start time, such as 01:05:00 in a typical cron job specification, to not conflict with other tasks, but there is a large range of time values that will accomplish that. A one-minute bit of randomness in a start time is usually irrelevant.
|
||||
|
||||
However, for some tasks, exact trigger times are an absolute requirement. For those, you can specify greater trigger time-span accuracy (to within a microsecond) by adding a statement like this to the `Timer` section of the timer unit file:
|
||||
|
||||
|
||||
```
|
||||
`AccuracySec=1us`
|
||||
```
|
||||
|
||||
Time spans can be used to specify the desired accuracy as well as to define time spans for repeating or one-time events. It recognizes the following units:
|
||||
|
||||
* usec, us, µs
|
||||
* msec, ms
|
||||
* seconds, second, sec, s
|
||||
* minutes, minute, min, m
|
||||
* hours, hour, hr, h
|
||||
* days, day, d
|
||||
* weeks, week, w
|
||||
* months, month, M (defined as 30.44 days)
|
||||
* years, year, y (defined as 365.25 days)
|
||||
|
||||
|
||||
|
||||
All the default timers in `/usr/lib/systemd/system` specify a much larger range for accuracy because exact times are not critical. Look at some of the specifications in the system-created timers:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer
|
||||
/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h
|
||||
/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h
|
||||
/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h
|
||||
/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h
|
||||
/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h
|
||||
/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
View the complete contents of some of the timer unit files in the `/usr/lib/systemd/system` directory to see how they are constructed.
|
||||
|
||||
You do not have to enable the timer in this experiment to activate it at boot time, but the command to do so would be:
|
||||
|
||||
|
||||
```
|
||||
`[root@testvm1 system]# systemctl enable myMonitor.timer`
|
||||
```
|
||||
|
||||
The unit files you created do not need to be executable. You also did not enable the service unit because it is triggered by the timer. You can still trigger the service unit manually from the command line, should you want to. Try that and observe the journal.
|
||||
|
||||
See the man pages for `systemd.timer` and `systemd.time` for more information about timer accuracy, event-time specifications, and trigger events.
|
||||
|
||||
### Timer types
|
||||
|
||||
systemd timers have other capabilities that are not found in cron, which triggers only on specific, repetitive, real-time dates and times. systemd timers can be configured to trigger based on status changes in other systemd units. For example, a timer might be configured to trigger a specific elapsed time after system boot, after startup, or after a defined service unit activates. These are called monotonic timers. Monotonic refers to a count or sequence that continually increases. These timers are not persistent because they reset after each boot.
|
||||
|
||||
Table 1 lists the monotonic timers along with a short definition of each, as well as the `OnCalendar` timer, which is not monotonic and is used to specify future times that may or may not be repetitive. This information is derived from the `systemd.timer` man page with a few minor changes.
|
||||
|
||||
Timer | Monotonic | Definition
|
||||
---|---|---
|
||||
`OnActiveSec=` | X | This defines a timer relative to the moment the timer is activated.
|
||||
`OnBootSec=` | X | This defines a timer relative to when the machine boots up.
|
||||
`OnStartupSec=` | X | This defines a timer relative to when the service manager first starts. For system timer units, this is very similar to `OnBootSec=`, as the system service manager generally starts very early at boot. It's primarily useful when configured in units running in the per-user service manager, as the user service manager generally starts on first login only, not during boot.
|
||||
`OnUnitActiveSec=` | X | This defines a timer relative to when the timer that is to be activated was last activated.
|
||||
`OnUnitInactiveSec=` | X | This defines a timer relative to when the timer that is to be activated was last deactivated.
|
||||
`OnCalendar=` | | This defines real-time (i.e., wall clock) timers with calendar event expressions. See `systemd.time(7)` for more information on the syntax of calendar event expressions. Otherwise, the semantics are similar to `OnActiveSec=` and related settings. This timer is the one most like those used with the cron service.
|
||||
|
||||
_Table 1: systemd timer definitions_
|
||||
|
||||
The monotonic timers can use the same shortcut names for their time spans as the `AccuracySec` statement mentioned before, but systemd normalizes those names to seconds. For example, you might want to specify a timer that triggers an event one time, five days after the system boots; that might look like: `OnBootSec=5d`. If the host booted at `2020-06-15 09:45:27`, the timer would trigger at `2020-06-20 09:45:27` or within one minute after.
|
||||
|
||||
### Calendar event specifications
|
||||
|
||||
Calendar event specifications are a key part of triggering timers at desired repetitive times. Start by looking at some specifications used with the `OnCalendar` setting.
|
||||
|
||||
systemd and its timers use a different style for time and date specifications than the format used in crontab. It is more flexible than crontab and allows fuzzy dates and times in the manner of the `at` command. It should also be familiar enough that it will be easy to understand.
|
||||
|
||||
The basic format for systemd timers using `OnCalendar=` is `DOW YYYY-MM-DD HH:MM:SS`. DOW (day of week) is optional, and other fields can use an asterisk (*) to match any value for that position. All calendar time forms are converted to a normalized form. If the time is not specified, it is assumed to be 00:00:00. If the date is not specified but the time is, the next match might be today or tomorrow, depending upon the current time. Names or numbers can be used for the month and day of the week. Comma-separated lists of each unit can be specified. Unit ranges can be specified with `..` between the beginning and ending values.
|
||||
|
||||
There are a couple interesting options for specifying dates. The Tilde (~) can be used to specify the last day of the month or a specified number of days prior to the last day of the month. The “/” can be used to specify a day of the week as a modifier.
|
||||
|
||||
Here are some examples of some typical time specifications used in `OnCalendar` statements.
|
||||
|
||||
Calendar event specification | Description
|
||||
---|---
|
||||
DOW YYYY-MM-DD HH:MM:SS |
|
||||
*-*-* 00:15:30 | Every day of every month of every year at 15 minutes and 30 seconds after midnight
|
||||
Weekly | Every Monday at 00:00:00
|
||||
Mon *-*-* 00:00:00 | Same as weekly
|
||||
Mon | Same as weekly
|
||||
Wed 2020-*-* | Every Wednesday in 2020 at 00:00:00
|
||||
Mon..Fri 2021-*-* | Every weekday in 2021 at 00:00:00
|
||||
2022-6,7,8-1,15 01:15:00 | The 1st and 15th of June, July, and August of 2022 at 01:15:00am
|
||||
Mon *-05~03 | The next occurrence of a Monday in May of any year which is also the 3rd day from the end of the month.
|
||||
Mon..Fri *-08~04 | The 4th day preceding the end of August for any years in which it also falls on a weekday.
|
||||
*-05~03/2 | The 3rd day from the end of the month of May and then again two days later. Repeats every year. Note that this expression uses the Tilde (~).
|
||||
*-05-03/2 | The third day of the month of may and then every 2nd day for the rest of May. Repeats every year. Note that this expression uses the dash (-).
|
||||
|
||||
_Table 2: Sample `OnCalendar` event specifications_
|
||||
|
||||
### Test calendar specifications
|
||||
|
||||
systemd provides an excellent tool for validating and examining calendar time event specifications in a timer. The `systemd-analyze calendar` tool parses a calendar time event specification and provides the normalized form as well as other interesting information such as the date and time of the next "elapse," i.e., match, and the approximate amount of time before the trigger time is reached.
|
||||
|
||||
First, look at a date in the future without a time (note that the times for `Next elapse` and `UTC` will differ based on your local time zone):
|
||||
|
||||
|
||||
```
|
||||
[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
|
||||
Original form: 2030-06-17
|
||||
Normalized form: 2030-06-17 00:00:00
|
||||
Next elapse: Mon 2030-06-17 00:00:00 EDT
|
||||
(in UTC): Mon 2030-06-17 04:00:00 UTC
|
||||
From now: 10 years 0 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
Now add a time. In this example, the date and time are analyzed separately as non-related entities:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
|
||||
Original form: 2030-06-17
|
||||
Normalized form: 2030-06-17 00:00:00
|
||||
Next elapse: Mon 2030-06-17 00:00:00 EDT
|
||||
(in UTC): Mon 2030-06-17 04:00:00 UTC
|
||||
From now: 10 years 0 months left
|
||||
|
||||
Original form: 15:21:16
|
||||
Normalized form: *-*-* 15:21:16
|
||||
Next elapse: Mon 2020-06-15 15:21:16 EDT
|
||||
(in UTC): Mon 2020-06-15 19:21:16 UTC
|
||||
From now: 3h 55min left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
To analyze the date and time as a single unit, enclose them together in quotes. Be sure to remove the quotes when using them in the `OnCalendar=` event specification in a timer unit or you will get errors:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
|
||||
Normalized form: 2030-06-17 15:21:16
|
||||
Next elapse: Mon 2030-06-17 15:21:16 EDT
|
||||
(in UTC): Mon 2030-06-17 19:21:16 UTC
|
||||
From now: 10 years 0 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
Now test the entries in Table 2. I like the last one, especially:
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
|
||||
Original form: 2022-6,7,8-1,15 01:15:00
|
||||
Normalized form: 2022-06,07,08-01,15 01:15:00
|
||||
Next elapse: Wed 2022-06-01 01:15:00 EDT
|
||||
(in UTC): Wed 2022-06-01 05:15:00 UTC
|
||||
From now: 1 years 11 months left
|
||||
[root@testvm1 system]#
|
||||
```
|
||||
|
||||
Let’s look at one example in which we list the next five elapses for the timestamp expression.
|
||||
|
||||
|
||||
```
|
||||
[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
|
||||
Original form: Mon *-05~3
|
||||
Normalized form: Mon *-05~03 00:00:00
|
||||
Next elapse: Mon 2023-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2023-05-29 04:00:00 UTC
|
||||
From now: 2 years 11 months left
|
||||
Iter. #2: Mon 2028-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2028-05-29 04:00:00 UTC
|
||||
From now: 7 years 11 months left
|
||||
Iter. #3: Mon 2034-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2034-05-29 04:00:00 UTC
|
||||
From now: 13 years 11 months left
|
||||
Iter. #4: Mon 2045-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2045-05-29 04:00:00 UTC
|
||||
From now: 24 years 11 months left
|
||||
Iter. #5: Mon 2051-05-29 00:00:00 EDT
|
||||
(in UTC): Mon 2051-05-29 04:00:00 UTC
|
||||
From now: 30 years 11 months left
|
||||
[root@testvm1 ~]#
|
||||
```
|
||||
|
||||
This should give you enough information to start testing your `OnCalendar` time specifications. The `systemd-analyze` tool can be used for other interesting analyses, which I will begin to explore in the next article in this series.
|
||||
|
||||
### Summary
|
||||
|
||||
systemd timers can be used to perform the same kinds of tasks as the cron tool but offer more flexibility in terms of the calendar and monotonic time specifications for triggering events.
|
||||
|
||||
Even though the service unit you created for this experiment is usually triggered by the timer, you can also use the `systemctl start myMonitor.service` command to trigger it at any time. Multiple maintenance tasks can be scripted in a single timer; these can be Bash scripts or Linux utility programs. You can run the service triggered by the timer to run all the scripts, or you can run individual scripts as needed.
|
||||
|
||||
I will explore systemd's use of time and time specifications in much more detail in the next article.
|
||||
|
||||
I have not yet seen any indication that `cron` and `at` will be deprecated. I hope that does not happen because `at`, at least, is much easier to use for one-off task scheduling than systemd timers.
|
||||
|
||||
### Resources
|
||||
|
||||
There is a great deal of information about systemd available on the internet, but much is terse, obtuse, or even misleading. In addition to the resources mentioned in this article, the following webpages offer more detailed and reliable information about systemd startup.
|
||||
|
||||
* The Fedora Project has a good, practical [guide to systemd][5]. It has pretty much everything you need to know in order to configure, manage, and maintain a Fedora computer using systemd.
|
||||
* The Fedora Project also has a good [cheat sheet][6] that cross-references the old SystemV commands to comparable systemd ones.
|
||||
* For detailed technical information about systemd and the reasons for creating it, check out [Freedesktop.org][7]'s [description of systemd][8].
|
||||
* [Linux.com][9]'s "More systemd fun" offers more advanced systemd [information and tips][10].
|
||||
|
||||
|
||||
|
||||
There is also a series of deeply technical articles for Linux sysadmins by Lennart Poettering, the designer and primary developer of systemd. These articles were written between April 2010 and September 2011, but they are just as relevant now as they were then. Much of everything else good that has been written about systemd and its ecosystem is based on these papers.
|
||||
|
||||
* [Rethinking PID 1][11]
|
||||
* [systemd for Administrators, Part I][12]
|
||||
* [systemd for Administrators, Part II][13]
|
||||
* [systemd for Administrators, Part III][14]
|
||||
* [systemd for Administrators, Part IV][15]
|
||||
* [systemd for Administrators, Part V][16]
|
||||
* [systemd for Administrators, Part VI][17]
|
||||
* [systemd for Administrators, Part VII][18]
|
||||
* [systemd for Administrators, Part VIII][19]
|
||||
* [systemd for Administrators, Part IX][20]
|
||||
* [systemd for Administrators, Part X][21]
|
||||
* [systemd for Administrators, Part XI][22]
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/7/systemd-timers
|
||||
|
||||
作者:[David Both][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/dboth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/checklist_todo_clock_time_team.png?itok=1z528Q0y (Team checklist)
|
||||
[2]: https://opensource.com/article/17/11/how-use-cron-linux
|
||||
[3]: https://opensource.com/users/dboth
|
||||
[4]: https://opensource.com/article/20/5/manage-startup-systemd
|
||||
[5]: https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html
|
||||
[6]: https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet
|
||||
[7]: http://Freedesktop.org
|
||||
[8]: http://www.freedesktop.org/wiki/Software/systemd
|
||||
[9]: http://Linux.com
|
||||
[10]: https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/
|
||||
[11]: http://0pointer.de/blog/projects/systemd.html
|
||||
[12]: http://0pointer.de/blog/projects/systemd-for-admins-1.html
|
||||
[13]: http://0pointer.de/blog/projects/systemd-for-admins-2.html
|
||||
[14]: http://0pointer.de/blog/projects/systemd-for-admins-3.html
|
||||
[15]: http://0pointer.de/blog/projects/systemd-for-admins-4.html
|
||||
[16]: http://0pointer.de/blog/projects/three-levels-of-off.html
|
||||
[17]: http://0pointer.de/blog/projects/changing-roots
|
||||
[18]: http://0pointer.de/blog/projects/blame-game.html
|
||||
[19]: http://0pointer.de/blog/projects/the-new-configuration-files.html
|
||||
[20]: http://0pointer.de/blog/projects/on-etc-sysinit.html
|
||||
[21]: http://0pointer.de/blog/projects/instances.html
|
||||
[22]: http://0pointer.de/blog/projects/inetd.html
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user