diff --git a/published/20200112 What I learned going from prison to Python.md b/published/20200112 What I learned going from prison to Python.md new file mode 100644 index 0000000000..283212f4b4 --- /dev/null +++ b/published/20200112 What I learned going from prison to Python.md @@ -0,0 +1,104 @@ +[#]: collector: (lujun9972) +[#]: translator: (heguangzhi) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-11893-1.html) +[#]: subject: (What I learned going from prison to Python) +[#]: via: (https://opensource.com/article/20/1/prison-to-python) +[#]: author: (Shadeed "Sha" Wallace-Stepter https://opensource.com/users/shastepter) + +从监狱到 Python +====== + +> 入狱后,开源编程是如何提供机会的。 + +![书架上的编程书籍][1] + +不到一年前,我还在圣昆廷州立监狱服刑,我是无期徒刑。 + +我高三的时候,我抢劫了一个人并向他开了枪。现在,我经过一段时间才意识到并承认自己做错了,这是在经历了陪审团审判并看到我的行为带来的恶果后,我知道需要改变自己,我也确实做到了。尽管我对我的行为表示懊悔,但我毕竟开枪打了一个人,并差点杀了他。做这样的事是有后果的,这是理所当然的。所以在我 18 岁的时候,我被判了终身监禁。 + +监狱是一个非常可怕的地方;我是不推荐你去的。但是我必须去,所以我去了。我不告诉你具体的细节,但你可以放心,这是一个没有太多动机去改变的地方,许多人在这里养成的坏习惯比他们过去在别处养成的更多。 + +我是幸运儿之一。当我在服刑的时候,发生了一些不同寻常的事情。我开始想象自己出狱后的的未来,虽然在这之前,我还是已经在那里度过了我整个成年生活。 + +现在你想想:我是黑人,只受过高中教育。我没有工作经历,如果我离开监狱,在被释放前,我还是一个被定罪的重罪犯。当每个雇主看到我的简历,都不会有“我需要雇用这个人”想法,我认为是正常的。 + +我不知道我的选择是什么,但我已经下定决心了。我需要做些活下去的事情,并且这和我入狱前的生活一点也不像。 + +### Python 之路 + +最终,我被关在了圣昆廷州立监狱,我不知道我为何幸运地被关在那里。圣昆廷提供了几个自助和教育编程项目。这些[改造机会][2]帮助囚犯使他们拥有在获释后避免再次犯罪的技能。 + +作为其中一个编程项目的一部分,2017 年我通过圣昆廷媒体项目认识了[杰西卡·麦凯拉][3]。杰西卡是编程语言 [Python][4] 的爱好者,她开始向我推荐 Python 有多棒,以及它是刚起步的人学习的完美语言。这就是故事变得比小说更精彩的地方。 + +> 感谢 [@northbaypython][5] 让 [@ShaStepter][6] 和我重复 [@pycon][7] 的主题演讲,让他们被录制下来。我很荣幸与大家分享: +> +> 从监狱到 Pythone: https://t.co/rcumoAgZHm +> +> 大规模裁员:如果我们不雇佣被判重罪的人,谁会呢? https://t.co/fENDUFdxfX +> +> [pic.Twitter.com/kpjo8d3ul6][8] +> +> —杰西卡·麦凯拉(@jessicamckellar)[2019 年 11 月 5 日][9] + +杰西卡向我介绍了一些 Python 视频教程,这些教程是她为一家名叫 [O’Reilly Media][10] 的公司做的,课程是在线的,如果我能接触到它们,那该有多好呀。不幸的是,在监狱里上网是不可能的。但是,我遇到了一个叫 Tim O’Reilly 的人,他最近刚来到圣昆廷。在他访问之后,Tim 从他的公司 O’Reilly Media 公司向监狱的编程班捐赠了大量内容。最终,我拿到了一款平板电脑,上面有杰西卡的 Python 教程,并学会了如何使用这些 Python 教程进行编码。 + +真是难以置信。背景和生活与我完全不同的陌生人把这些联系在一起,让我学会了编码。 + +### 对 Python 社区的热爱 + +在这之后,我开始经常和杰西卡见面,她开始告诉我关于开源社区的情况。我了解到,从根本上说,开源社区就是关于伙伴关系和协作的社区。之所以如此有效,是因为没有人被排除在外。 + +对我来说,一个努力寻找自己定位的人,我所看到的是一种非常基本的爱——通过合作和接受的爱,通过接触的爱,通过包容的爱。我渴望成为其中的一部分。所以我继续学习 Python,不幸的是,我无法获得更多的教程,但是我能够从开源社区收集的大量书面知识中获益。我读一切提到 Python 的东西,从平装本到晦涩难懂的杂志文章,我使用平板电脑来解决我读到的 Python 问题。 + +我对 Python 和编程的热情不是我的许多同龄人所共有的。除了监狱编程课上的极少数人之外,我认识的其他人都没有提到过编程;一般囚犯都不知道。我认为这是因为有过监禁经历的人无法接触编程,尤其是如果你是有色人种。 + +### 监狱外的 Python 生活 + +然而,在 2018 年 8 月 17 日,我得到了生命中的惊喜。时任州长的杰里·布朗将我 27 年的刑期减刑,在服刑将近 19 年后,我被释放出狱了。 + +但现实情况是,这也是为什么我认为编程和开源社区如此有价值。我是一名 37 岁的黑人罪犯,没有工作经历,刚刚在监狱服刑 18 年。我有犯罪史,并且现存偏见导致没有多少职业适合我。但是编程是少数例外之一。 + +现在,监禁后重返社会的人们迫切需要包容,但当谈及工作场所的多样性以及对多样性的需求时,你真的听不到这个群体被提及或包容。 + +> 还有什么: +> +> 1、背景调查:询问他们在你的公司是如何使用的。 +> +> 2、初级角色:删除虚假的、不必要的先决条件,这些条件将排除有记录的合格人员。 +> +> 3、积极拓展:与当地再就业项目合作,创建招聘渠道。 +> +> [pic.twitter.com/WnzdEUTuxr][11] +> +> —杰西卡·麦凯拉(@jessicamckellar)[2019 年 5 月 12 日][12] +  + +因此,我想谦卑地挑战开源社区的所有程序员和成员,让他们围绕包容和多样性展开思考。今天,我自豪地站在你们面前,代表一个大多数人都没有想到的群体——以前被监禁的人。但是我们存在,我们渴望证明我们的价值,最重要的是,我们期待被接受。当我们重返社会时,许多挑战等待着我们,我请求你们允许我们有机会展示我们的价值。欢迎我们,接受我们,最重要的是,包容我们。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/1/prison-to-python + +作者:[Shadeed "Sha" Wallace-Stepter][a] +选题:[lujun9972][b] +译者:[heguangzhi](https://github.com/heguangzhi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/shastepter +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/books_programming_languages.jpg?itok=KJcdnXM2 (Programming books on a shelf) +[2]: https://www.dailycal.org/2019/02/27/san-quentin-rehabilitation-programs-offer-inmates-education-a-voice/ +[3]: https://twitter.com/jessicamckellar?lang=en +[4]: https://www.python.org/ +[5]: https://twitter.com/northbaypython?ref_src=twsrc%5Etfw +[6]: https://twitter.com/ShaStepter?ref_src=twsrc%5Etfw +[7]: https://twitter.com/pycon?ref_src=twsrc%5Etfw +[8]: https://t.co/Kpjo8d3ul6 +[9]: https://twitter.com/jessicamckellar/status/1191601209917837312?ref_src=twsrc%5Etfw +[10]: http://shop.oreilly.com/product/110000448.do +[11]: https://t.co/WnzdEUTuxr +[12]: https://twitter.com/jessicamckellar/status/1127640222504636416?ref_src=twsrc%5Etfw diff --git a/translated/tech/20200205 Getting started with GnuCash.md b/published/20200205 Getting started with GnuCash.md similarity index 75% rename from translated/tech/20200205 Getting started with GnuCash.md rename to published/20200205 Getting started with GnuCash.md index 69ef66261d..00dc0465c5 100644 --- a/translated/tech/20200205 Getting started with GnuCash.md +++ b/published/20200205 Getting started with GnuCash.md @@ -1,31 +1,31 @@ [#]: collector: (lujun9972) [#]: translator: (geekpi) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-11895-1.html) [#]: subject: (Getting started with GnuCash) [#]: via: (https://opensource.com/article/20/2/gnucash) [#]: author: (Don Watkins https://opensource.com/users/don-watkins) 开始使用 GnuCash ====== -使用 GnuCash 管理你的个人或小型企业会计。 -![A dollar sign in a network][1] -在过去的四年里,我一直在用 [GnuCash][2] 来管理我的个人财务,我对此非常满意。这个开源 (GPL v3) 项目自 1998 年首次发布以来一直成长和改进,2019 年 12 月发布的最新版本 3.8 增加了许多改进和 bug 修复。 +> 使用 GnuCash 管理你的个人或小型企业会计。 + +![](https://img.linux.net.cn/data/attachment/album/202002/15/124236wz5e0z5vq7571qby.jpg) + +在过去的四年里,我一直在用 [GnuCash][2] 来管理我的个人财务,我对此非常满意。这个开源(GPL v3)项目自 1998 年首次发布以来一直成长和改进,2019 年 12 月发布的最新版本 3.8 增加了许多改进和 bug 修复。 GnuCash 可在 Windows、MacOS 和 Linux 中使用。它实现了一个复式记账系统,并可以导入各种流行的开放和专有文件格式,包括 QIF、QFX、OFX、CSV 等。这使得从其他财务应用转换(包括 Quicken)而来很容易,它是为取代这些而出现的。 -借助 GnuCash,你可以跟踪个人财务状况以及小型企业会计和开票。它没有一个集成的工资系统。根据文档,你可以在 GnuCash 中跟踪工资支出,但你必须在软件外部计算税金和扣减。 +借助 GnuCash,你可以跟踪个人财务状况以及小型企业会计和开票。它没有集成的工资系统。根据文档,你可以在 GnuCash 中跟踪工资支出,但你必须在该软件外计算税金和扣减。 ### 安装 要在 Linux 上安装 GnuCash: - * 在 Red Hat、CentOS 或 Fedora 中: **$ sudo dnf install gnucash** - * 在 Debian、Ubuntu 或 Pop_OS 中: **$ sudo apt install gnucash** - - + * 在 Red Hat、CentOS 或 Fedora 中: `$ sudo dnf install gnucash` + * 在 Debian、Ubuntu 或 Pop_OS 中: `$ sudo apt install gnucash` 你也可以从 [Flathub][3] 安装它,我在运行 Elementary OS 的笔记本上使用它。(本文中的所有截图都来自此次安装)。 @@ -37,7 +37,7 @@ GnuCash 可在 Windows、MacOS 和 Linux 中使用。它实现了一个复式记 #### 个人账户 -如果你选择第一个选项(正如我所做的那样),GnuCash 会打开一个页面给你向导。它收集初始数据并设置账户首选项,例如账户类型和名称、商业数据(例如,税号)和首选货币。 +如果你选择第一个选项(正如我所做的那样),GnuCash 会打开一个页面帮你起步。它收集初始数据并设置账户首选项,例如账户类型和名称、商业数据(例如,税号)和首选货币。 ![GnuCash new account setup][5] @@ -49,7 +49,7 @@ GnuCash 支持个人银行账户、商业账户、汽车贷款、CD 和货币市 #### 开票 -GnuCash 还支持小型企业功能,包括客户、供应商和开票。要创建发票,请在 **Business ->Invoice** 中输入数据。 +GnuCash 还支持小型企业功能,包括客户、供应商和开票。要创建发票,请在 “Business -> Invoice” 中输入数据。 ![GnuCash create invoice][7] @@ -63,7 +63,7 @@ GnuCash 还支持小型企业功能,包括客户、供应商和开票。要创 ![GnuCash help][9] -项目的网站包含许多有用的信息的链接,例如 GnuCash [功能][10]的概述。GnuCash 还提供了[详细的文档][11],可供下载和离线阅读,它还有一个 [wiki][12],为用户和开发人员提供了有用的信息。 +该项目的网站包含许多有用的信息的链接,例如 GnuCash [功能][10]的概述。GnuCash 还提供了[详细的文档][11],可供下载和离线阅读,它还有一个 [wiki][12],为用户和开发人员提供了有用的信息。 你可以在项目的 [GitHub][13] 仓库中找到其他文件和文档。GnuCash 项目由志愿者驱动。如果你想参与,请查看项目的 wiki 上的 [Getting involved][14] 部分。 @@ -73,8 +73,8 @@ via: https://opensource.com/article/20/2/gnucash 作者:[Don Watkins][a] 选题:[lujun9972][b] -译者:[geekpi]](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/talk/20200212 A SASE Crash Course.md b/sources/talk/20200212 A SASE Crash Course.md new file mode 100644 index 0000000000..88e85a9c15 --- /dev/null +++ b/sources/talk/20200212 A SASE Crash Course.md @@ -0,0 +1,67 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (A SASE Crash Course) +[#]: via: (https://www.networkworld.com/article/3526455/a-sase-crash-course.html) +[#]: author: (Cato Networks https://www.networkworld.com/author/Matt-Conran/) + +A SASE Crash Course +====== +Get up to speed fast on the Secure Access Service Edge, an emerging converged networking and security category that Gartner has labelled transformational. +peshkov + +2020! What could better motivate you to push ahead with your resolutions and organization’s digital transformation than a new year AND a new decade. As you put together your digital strategy, check out a new transformation-empowering (and transformational) technology category Gartner coined the [Secure Access Service Edge][1] or SASE (pronounced “Sassy”). SASE converges wide area networking and identity-based security into a cloud service targeted directly to your branch offices, mobile users, cloud services, and even IoT devices, wherever they happen to be. The result: consistently high WAN performance, security, productivity, agility, and flexibility across the global, mobile, cloud-enabled enterprise. + +To jumpstart your research into one of the few networking categories Gartner has labelled “transformational,” we’ve put together a very workable SASE crash course and reading list. Each lesson helps you dig a little deeper into SASE, so you can develop a good grasp of its components and transformational potential. + +**Lesson 1: SASE as Defined by Gartner** + +So, what is SASE exactly and why should you care? SASE was coined by [Gartner][2] analysts Neil McDonald and Joe Skorupa in a [July 29, 2019 Networking Hype Cycle][3] [Market Trends Report, How to Win as WAN Edge and Security Converge into the Secure Access Service Edge][4] and an August 30, 2019 [Gartner][2] report, The Future of Network Security is in the Cloud. If you don’t have access to these reports, Cato quotes the highlights of the former word for word in this short blog: [The Secure Access Service Edge (SASE), as Described in Gartner’s Hype Cycle for Enterprise Networking, 2019][5]. It’s a great place to get started on exactly what Gartner has to say about SASE and its drivers, likely development, and place in the digitally transforming enterprise. There are also some valuable links to more information on SASE and exactly how the Cato cloud fits into the SASE trend. + +**Lesson 2: What SASE _Is_ and What It _Isn’t_** + +After Gartner piques your interest, get some valuable insight from Cato in this blog: [The Secure Access Service Edge (SASE): Here’s Where Your Digital Business Network Starts][6]. Here you can learn why convergence of wide area networking and security is absolutely vital for the agile, digitally transforming enterprise and why legacy data center-centric solutions can’t deliver any more in a world of user mobility and the cloud. This blog breaks down the four essential attributes of SASE—identity driven, cloud native, support for all edges, and globally distributed—in detail. It also explains why SASE is _not_ anything like telco-managed services and summarizes how Cato delivers SASE effectively. + +**Lesson 3: How Cato Delivers SASE** + +Sometimes visual/audio-based learning can bring things into better focus than straight text, and few people are better at explaining WAN and security concepts than Yishay Yovel, Cato Network’s Chief Marketing Officer. In this short, 17-minute video presentation, [Intro to SASE by Yishay][7], Yishay digs into Gartner’s take on SASE, why WAN and security need to converge, and why SASE is one of only three (out of 29) Networking Hype Cycle categories that Gartner has labeled “transformational.” Yishay gets into a lot of nitty-gritty SASE details and offers valuable perspective on how Cato Networks delivers a complete cloud-native SASE software stack that supports all edges and is identity-driven, scalable, flexible, and easy to deploy and manage. Yishay also explains clearly why some of the other WAN and security solutions out there don’t fulfill some essential requirements of SASE, such as processing traffic close to the source. For visual learners, there are also some great architectural diagrams. + +**Lesson 4: Gartner Webinar Breaks Down SASE and its Implications** + +You’ve heard it from Yishay, now hear it from Gartner’s VP Distinguished Analyst Neil MacDonald _and_ Yishay in this 37-minute [Gartner Webinar: Is SASE the Future of SD-WAN and Network Security][8]? MacDonald explains SASE elements and drivers in depth, why SASE belongs in the cloud, how enterprises will adopt SASE, and how organizations should evaluate SASE offerings. There’s some good detail here on how SASE works in different contexts and scenarios, such as a mobile employee connecting to Salesforce securely from the airport, a contractor accessing a Web application from an unmanaged device, and even wind turbines collecting and aggregating data and sending it to the cloud for processing. Neil digs into core SASE requirements and recommends additional services and some other useful options. Yishay then takes over with why Cato is the world’s first true SASE platform. + +**Lesson 5: The White Paper** + +But wait, there’s more. Here’s a clear and concise white paper from Cato, [The Network for the Digital Business Starts with the Secure Access Service Edge][9]. This is a good piece to give out to the other digital transformation stakeholders in your business if you want them to get up to speed on SASE fast. It’s a quick read that explains why the digital, mobile, cloud-enabled business needs a new converged network/security model. It also covers the four elements of SASE, core SASE capabilities, SASE benefits, and clear examples of what SASE _isn’t_ and why. It describes the features that make Cato one of the most comprehensive SASE offerings on the market. It’s a clear, concise presentation broken into short paragraphs and bullet points to provide a fast introduction to SASE and the Cato Cloud. + +**Lesson 6: Icing on the Cake: The Short and Sweet Video** + +[SASE (Secure Access Service Edge)][10] is a short YouTube video to go along with the white paper, combining perspective and information from Gartner and Cato on why you need SASE simplicity for your digital transforming business. + +We hope you have a happy, healthy, transforming New Year. To accelerate your organization’s digital transformation over the next decade, get up to speed on SASE with these useful blogs, videos, and white papers and find out how SASE can help you make that transformation happen quickly and more easily. + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3526455/a-sase-crash-course.html + +作者:[Cato Networks][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Matt-Conran/ +[b]: https://github.com/lujun9972 +[1]: http://www.catonetworks.com/sase?utm_source=idg +[2]: https://en.wikipedia.org/wiki/Gartner +[3]: https://www.gartner.com/en/documents/3947237 +[4]: https://www.gartner.com/en/documents/3953690/market-trends-how-to-win-as-wan-edge-and-security-conver +[5]: https://www.catonetworks.com/blog/the-secure-access-service-edge-sase-as-described-in-gartners-hype-cycle-for-enterprise-networking-2019/ +[6]: https://www.catonetworks.com/blog/the-secure-access-service-edge-sase?utm_source=idg +[7]: https://catonetworks.wistia.com/medias/kn86smj7q4 +[8]: https://go.catonetworks.com/VOD-REG-Gartner-SASE?utm_source=idg +[9]: https://go.catonetworks.com/The-Network-Starts-with-SASE?utm_source=idg +[10]: https://www.youtube.com/watch?v=gLN4NUbjml8 diff --git a/sources/talk/20200213 Server sales projected to decline 10- due to coronavirus.md b/sources/talk/20200213 Server sales projected to decline 10- due to coronavirus.md new file mode 100644 index 0000000000..32852586e1 --- /dev/null +++ b/sources/talk/20200213 Server sales projected to decline 10- due to coronavirus.md @@ -0,0 +1,63 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Server sales projected to decline 10% due to coronavirus) +[#]: via: (https://www.networkworld.com/article/3526605/server-sales-projected-to-decline-10-due-to-coronavirus.html) +[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/) + +Server sales projected to decline 10% due to coronavirus +====== +Demand isn’t tapering off, but China is grinding to a halt under the strain of the pandemic. +Writerfantast / Getty Images + +Global server sales had been projected to grow by 1.2% compared to the most recent quarter, but the chaos wrought by the coronavirus in China will cause sales to decline 9.8% sequentially, according to DigiTimes Research. + +DigiTimes is an IT publication based in Taiwan. Its proximity to Taiwanese and Chinese vendors gives it some good sources, but it can also be way off target. However, the signs are piling up that coronavirus is causing some real mayhem. + +For example, DigiTimes also [reported][1] that less than 20% of Chinese factory employees would return to work after an extended Lunar New Year break due to the coronavirus outbreak, and that many components plants in China have decided not to restart production until February 25. + +**[ Now read: [What is quantum computing (and why enterprises should care)][2] ]** + +The Lunar New Year was January 25, so that means Chinese factories have been idle for a month. That’s a lot of supply not being answered, and DigiTimes notes that server demand from large data centers remained strong in the first quarter of 2020. + +Facebook in particular is interested in buying high-density models from white box vendors like Wiwynn and Quanta Computer, but due to the outbreak, these orders, which were originally scheduled for shipment this quarter, have been postponed. + +So it’s not like an economic crash is causing sales to go off a cliff like in 2008. Demand is there, but China can’t make the product right now. This year was expected to be a good year for the server vendors, with all of them projecting sales increases over last year. AMD is ramping up Epyc production, and Intel is expected to release its next-generation “Ice Lake” Xeon platform in the third or the fourth quarter of 2020. + +The good news here is that Wuhan isn’t a major tech manufacturing hub. It does have five display fabs, both LCD and OLED, but so does Shanhai. However, Wuhan has the most advanced display fabs, producing flexible OLEDs, and has the largest capacity, according to David Hsieh, senior director, displays, at Omdia. + +**[ [Get certified as an Apple Technical Coordinator with this seven-part online course from PluralSight.][3] ]** + +Vladimir Galabov, principal analyst for data-center compute in Omdia’s cloud and data-center research practice, also expects to see server shipments impacted by the coronavirus driving a prolonged holiday period in China. + +“I think the majority of the hit will be in the Chinese market,” he said. “This does impact server shipments globally as China represents about 30% of server shipments worldwide. So, I expect the quarterly decline to be more significant than the seasonal 10%. I expect that China will have a 5% additional downward impact on the growth.” + +He added that Q4 of 2019 did significantly overachieve his expectations due to cloud service providers making massive purchases. Omdia expected servers shipped in 2019 to be flat compared to 2018 based on data from 1Q19-3Q19. Instead, it was up 2% to 3% for the year, thanks to the fourth-quarter spurt. + +And servers aren’t the only products taking a hit. DigiTimes says that should the outbreak of the coronavirus last until June, sales of smartphones in the country would be slashed by about 30%, from a projected 400 million units to 280 million units in 2020. + +Also, Mobile World Congress in Barcelona is cancelled due to concerns about the global coronavirus outbreak. The [official cancellation][4] came after a number of big-name companies, including Intel, Cisco, Amazon, Sony, NTT Docomo LG, ZTE, Nvidia, and Ericsson, bowed out of various events that were set for the show.  + +Join the Network World communities on [Facebook][5] and [LinkedIn][6] to comment on topics that are top of mind. + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3526605/server-sales-projected-to-decline-10-due-to-coronavirus.html + +作者:[Andy Patrizio][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Andy-Patrizio/ +[b]: https://github.com/lujun9972 +[1]: https://www.digitimes.com/news/a20200210VL202.html +[2]: https://www.networkworld.com/article/3275367/what-s-quantum-computing-and-why-enterprises-need-to-care.html +[3]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fpaths%2Fapple-certified-technical-trainer-10-11 +[4]: https://www.mwcbarcelona.com/attend/safety-security/gsma-statement-on-mwc-2020/ +[5]: https://www.facebook.com/NetworkWorld/ +[6]: https://www.linkedin.com/company/network-world diff --git a/sources/talk/20200214 Linux is our love language.md b/sources/talk/20200214 Linux is our love language.md new file mode 100644 index 0000000000..397ddee4d3 --- /dev/null +++ b/sources/talk/20200214 Linux is our love language.md @@ -0,0 +1,83 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Linux is our love language) +[#]: via: (https://opensource.com/article/20/2/linux-love-language) +[#]: author: (Christopher Cherry https://opensource.com/users/chcherry) + +Linux is our love language +====== +When a wife teaches a husband some new tech skills, they both learn a +lot more than they expect. +![Red heart with text "you are not alone"][1] + +2019 was a year of learning in the Cherry household. I am a senior software engineer who set out to learn new skills and, along the way, I taught my husband, Chris. By teaching him some of the things I learned and asking him to work through my technology walkthrough articles, I helped Chris learn new skills that enabled him to pivot his career deeper into the technology field. And I learned new ways to make my walkthroughs and training materials more accessible for readers to digest. + +In this article, we talk about what we learned individually and from each other, then we explore what it means for their future. + +### Questions for the student + +**Jess:** Chris, what made you want to learn more about my field? + +**Chris:** It was primarily to further my career. Being in network engineering has shown me that being an expert only on networks is not as valuable as it once was, and I have to know a little bit of everything. Since the network is often blamed for outages or application challenges these days, I wanted to understand more from a developer's perspective on writing applications so I could see how they depend on the network as a resource. + +**Jess:** What did I teach you first, and what did you learn from it? + +**Chris:** It all started with installing Linux for the first time, then adding [Ansible][2]. Each Linux distribution I worked with was easy enough to install, as long as the hardware was compatible, but compatibility wasn't always clear. That meant sometimes I learned first-hand how to troubleshoot Linux within the first five minutes of running an installation (and I liked it). Ansible gave me a reason to learn Linux package managers to install the software. Once it was installed, I quickly learned how package management handles dependencies as I looked at the files that yum installed, so Ansible, which is written in Python, can run on my system. From there, I started to install all kinds of applications with Ansible. + +**Jessica:** Do you like the way I taught you? + +**Chris:** We had our struggles at first, until we ironed out how I like to learn and how you should present the best way for me to learn. In the beginning, it was hard to follow what you meant. For instance, when you said things like "a Docker container," I had no reference to what you were talking about. Early on, the response was, "well, it's a container," which meant nothing to me at the time. Once I got you to explain it in more detail, it became a lot more fun to learn. + +**Jess:** To be fair, this was a big lesson for me as well. I hadn't trained anyone with less knowledge on this technology than me before you, so you helped me realize that I needed to be clearer with my explanations. Thanks for that. + +How did you feel about testing my articles, the ones where I had you run through the steps? + +**Chris:** Personally, I thought it would be easy, and boy, was I wrong. One of the main things I learned from these, like your [introduction to Vagrant][3], was how each Linux distribution varies more than I realized. The operating system (OS) changes how you set it up, the requirements to run, and the specific commands. It seems like a lot more variability than there is with the network gear I've worked on. So I started to pay a lot more attention to the instructions and whether they were written for my OS or another one (and how difficult it can be to know sometimes). I seemed to break a lot of things along the way. + +**Jess:** I break stuff all day, so different paths for different problems are daily occurrences for me. + +### Questions for the teacher + +**Chris:** Jess, would you change anything with the way you taught me so far? + +**Jess:** I'd have liked to make you read more, as I do. Learning new technology has me churning through books. I read a book and a half, if not two books, a week, and that's with spending one hour in the morning and one hour before bed every day. I also pick one project to run through for two weeks for about an hour a day to reinforce the book skills. And that's in addition to the tech articles I read for the first hour of my day while taking in an immense amount of coffee. When I think about your goal to grow your career, I think books are an important element alongside the great blog posts and articles we talk about. I feel my reading regiment has kept me up to speed, and if you did the same, you would catch up to me pretty quickly. + +**Chris:** So did the student teach the teacher in any way? + +**Jess:** I learned a great deal about being patient from you. For instance, after walking through an installation of Ansible, I asked what you wanted to do next. Your first answer was, "I don't know," which was hard for me because I want you to learn what you want to learn. So I changed my approach, and now we talk more about what you want to achieve before walking through installing anything. When we moved on to the Vagrant article we worked on together, I created it with an end goal in mind, so we had something to achieve right away. + +This actually made a massive change in how I do training at work. Now I ask more questions on how people learn and work hand-in-hand more often than I did before. I am more likely to sit and go through and make sure someone understands what I'm saying and what we're doing. I wasn't really before. + +### What we learned together + +As a couple, we both grew from collaborating on technology over the last year. + +**Chris:** I'm blown away at how much I learned. Over the course of a year, I understand new operating systems, how to use an API, web application deployment with Ansible, and standing up virtual machines with Vagrant. I also learned how documentation makes life better, so it's worth the time it takes to write some. In this field of work, however, behavior isn't always documented, so I've learned to be ready to work through tough issues and document how I fix them. + +**Jess:** Beyond what I learned from teaching you, I've focused on learning a good deal about Kubernetes in cloud environments. That includes deployment strategies, the complexity of the Kubernetes API, building my own containers, and securing these environments. I've also saved time to dabble: toying around with serverless code, AI models, Python, and graphically displaying heat maps. It's been a good year. + +What's next for us? It's yet to be seen, but I can assure you that we're going to share it here on Opensource.com. + +**Who did you mentor in 2019, or who are you mentoring in 2020? Tell us about it in the comments.** + +I can see the brightness of curiosity in my six year old niece Shuchi's eyes when she explores a... + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/linux-love-language + +作者:[Christopher Cherry][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/chcherry +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/red-love-heart-alone-stone-path.jpg?itok=O3q1nEVz (Red heart with text "you are not alone") +[2]: https://opensource.com/resources/what-ansible +[3]: https://opensource.com/resources/vagrant diff --git a/sources/talk/20200215 The Background Story of AppImage -Interview.md b/sources/talk/20200215 The Background Story of AppImage -Interview.md new file mode 100644 index 0000000000..d3e95a1a0f --- /dev/null +++ b/sources/talk/20200215 The Background Story of AppImage -Interview.md @@ -0,0 +1,128 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (The Background Story of AppImage [Interview]) +[#]: via: (https://itsfoss.com/appimage-interview/) +[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/) + +The Background Story of AppImage [Interview] +====== + +As a Linux user, you might have come across [AppImages][1]. This is a portable packaging format that allows you to run an application on any Linux distribution. + +[Using AppImage][2] is really simple. You just need to give it execute permission and double click to run it, like the .exe files in Windows. This solves a major problem in Linux as different kind of distributions have different kind of packaging formats. You cannot [install .deb files][3] (of Debian/Ubuntu) on [Fedora][4] and vice versa. + +We talked to Simon, the developer of AppImage, about how and why he created this project. Read some of the interesting background story and insights Simon shares about AppImage. + +### Interacting with Simon Peter, the creator of AppImage + +![][5] + +_**It’s FOSS: Few people know about the person behind AppImage. How about sharing a little background information about yourself?**_ + +**Simon:** Hi, I’m Simon Peter, based near Frankfurt in Germany. My background is in Economics and Business Administration, but I’ve always been a tinkerer and hacker in my free time, and been working in tech ever since I graduated. + +AppImage, though, is strictly a hobby which I enjoy working on in my spare time. I do a lot of my AppImage work while I’m on a train going from here to there. Somehow I seem to be on the move all the time. Professionally, I work in the product management of a large telecommunications company. + +_**It’s FOSS: Why did you create AppImage?**_ + +**Simon:** The first computer I could get my hands on was a [Macintosh][6] in the late 80s. For me, this is the benchmark when it comes to simplicity and usability. When I started to experiment with Linux on the desktop, I always wished it was as elegant and simple to operate and gave me as much flexibility as the early Macs. + +When I tried Linux for the first time in the late 90s, I had to go through a cumbersome process formatting and partitioning hard disks, installing stuff – it took a lot of time and was really cumbersome. A couple of years later, I tried out a Linux Live CD-ROM. It was a complete game changer. You popped in the CD, booted the computer, and everything just worked, right out of the box. No installation, no configuration. The system was always in factory-new state whenever you rebooted the machine. Exactly how I liked it. + +There was only one downside: You could not install additional applications on a read-only CD. Packages always insisted on writing in /usr, where the Live CD was not writeable. Thus, I asked myself: Why can’t I just put applications wherever I want, like on a USB drive or a network share, as I am used from the Mac? How cool would it be if every application was just one single file that I could put wherever I want? And thus the idea for AppImage was born (back then under the name of “klik”). + +Turns out that over time Live systems have become more capable, but I still like the simplicity and freedom that comes with the “one app = one file” idea. For example, I want to be in control of where stuff resides on my hard disks. I want to decide what to update or not to update and when. For most tasks I need a stable, rarely-changing operating system with the latest applications. To this day all I ever run are Live systems, because the operating system “just works” out of the box without any installation or configuration on my side, and every time I reboot the machine I have a “factory new”, known-good state. + +_**It’s FOSS: What challenges did you face in the past and what challenges are you facing right now?**_ + +**Simon:** People told me that the idea was nuts, and I had no clue how “things are done on Linux”. Just about when I was beginning to give in, I came across a video of [Linus Torvalds][7] of all people who I noticed was complaining about many of the same things that I always had felt were too complicated when it came to distributing applications for Linux. While I was watching his rant, I also noticed, hey, AppImage actually solves many of those issues. Some time later, Linus came across AppImage, and he apparently liked the idea. That made me think, maybe it’s not that stupid an idea as people had made me believe all the time up to that point. + +Today, people tend to mention AppImage as “one of the new package formats” together with [Snap][8] and [Flatpak][9]. I think that’s comparing apples to oranges. Not only is AppImage not “new” (it’s been around since well over a decade by now), but also it has very different objectives and design principles than the other systems. AppImage is all about single-file application bundles that can be “managed” by nothing else than a web browser and a file manager. It’s meant for “mere morals”, end users, not system administrators. It needs no package manager, it needs no root rights, it needs nothing to be installed on the system. It gives complete freedom to application developers and users. + +_**It’s FOSS: AppImage is a “universal packaging system” and there you compete with Snap (backed by Ubuntu) and Flatpak (backed by Fedora). How do you plan to ‘fight’ against these big corporates?**_ + +**Simon:** See? That’s what I mean. AppImage plays in an entirely different playing field. + +AppImage wants to be what exe files or PortableApps are for Windows and what apps inside dmg files are on the Mac – but better. + +Besides, Snap (backed by [Canonical][10]) does not work out-of-the-box on Fedora, and Flatpak (backed by [Red Hat][11]) does not work out-of-the-box on Ubuntu. AppImages can run on either system, and many more, without the need to install anything. + +_**It’s FOSS: How do you see the adoption of AppImage? Are you happy with its growth?**_ + +**Simon:** As of early 2020, there are now around 1,000 official AppImages made by the respective application authors that are passing my compatibility tests and can run on the oldest still-supported Ubuntu LTS release, and hundreds more are being worked on as we speak. “Household name” applications like Inkscape, Kdenlive, KDevelop, LibreOffice, PrusaSlicer, Scribus, Slic3r, Ultimaker Cura (too many to name them all) are being distributed in AppImage format. This makes me very happy and I am always excited when I read about a new version being released on Twitter, and then am able to download and run the AppImage instantly, without having to wait for my Linux distribution to carry that new version, and without having to throw away the old (known-good) version just because I want to try out the new (bleeding edge) one. + +The adoption of AppImage is especially strong for nightly and continuous builds. This is because the “one app = one file” concept of AppImage lends itself especially well to try-out software, where you keep multiple versions around for testing purposes, and never have to install anything into the running system. Worst thing that can happen with AppImage is that an application does not launch. In that case, file a bug, delete the file, done. Worst thing that can happen with distribution packages: complete system breakage… + +_**It’s FOSS: One major issue with AppImage is that not all the developers provide an easy way of updating the AppImage versions. Any suggestions for handling it?**_ + +**Simon:** AppImage has this concept of “binary delta updates”. Think of it as “diff for applications”. A new version of an application comes out, you download only the parts that have changed, and apply them to the old version. As a result, you get both the old and the new version and can keep them in parallel until you have determined that you don’t need the old version any longer, and throw it away. + +In general, I don’t want to enforce anything with AppImage. Application authors are at liberty to control the whole experience. Up to now, application authors have to do some setup work to make AppImages with this update capability. That being said, I am convinced that if we make it easy enough for developers to get working binary delta updates “for free”, then many will offer them. To this end, I am currently working on a new set of tools written in Go that will set up updates almost automatically, and I hope this will significantly increase the percentage of AppImages that come with this capability. + +_**It’s FOSS: [Nitrux][12] is one of the rare distributions that relies heavily on AppImage. Or there any other such distributions? What can be done make AppImage more popular?**_ + +**Simon:** Linux distributions traditionally have thought of themselves as more than just the base operating system itself – they also wanted to control application distribution. Now, as Apple and Microsoft are trying to get more control over application distribution on their desktop platforms, the trend is slowly reversing in Linux land where people are slowly beginning to understand that distributions could be much more polished if they focused on the base operating system and left the packaging of applications to the application authors. + +To make AppImage more popular, I think users and application authors should continue to spread the word that upstream-provided AppImages are in many cases working better than distribution packages. With AppImage, you get a software stack where the application author had a chance to cherry-pick which versions of libraries work together, test and tune both functionality and performance. Who is surprised that the result tends to work better than a “random” combination of whatever versions happened to be in a Linux distribution at a certain, random point in time when a distribution release was put together? + +[Desktop environments][13] could greatly increase usability, not only for AppImages, but also for any other kind of “side-loaded” applications that are not being installed. Just see how a desktop environments handles double-clicking on an executable file that is missing the executable bit. Some are doing a great job in this regard, like [Deepin Linux][14]. Stuff tends to “just work” there as it should. + +Finally, I am currently working on a new set of tools written in Go which I hope will greatly simplify, and make yet more enjoyable, the production and consumption of AppImages. My goal here is to make things less complex for users, remove the need for configuration, make things “just work”, like on the early Macintoshes. Are there any Go developers out here interested to join the effort? + +_**It’s FOSS: I can see there is a website that lists available AppImage applications. Do you have plans to integrate it with other software managers on Linux or create a software manager for AppImage?**_ + +**Simon:** [appimage.github.io][15] lists AppImages that have passed my compatibility tests on the oldest still-supported Ubuntu LTS release. Projects creating app stores or software managers are free to use this data. Myself, I am not much interested in those things as I always download AppImages right from the respective project’s download pages. My typical AppImage discovery goes like this: + + 1. Read on Twitter that PrusaSlicer has this cool new feature + 2. Go to the PrusaSlicer GitHub project and read the release notes there + 3. While there, download the AppImage and have it running a few seconds later + + + +So for me personally, I have no need for app centers and app stores, but if people like them, they are free to put AppImages in there. I just never felt the need… + +_**It’s FOSS: What plans do you have for AppImage in future (new features that you plan to add)?**_ + +**Simon:** Simplify things even more, remove configuration options, make things “just work”. Reduce the number of GitHub projects needed to get the core AppImage experience for producing and consuming AppImages, including aspects like binary delta updates, sandboxing, etc. Improve usability. + +_**It’s FOSS: Does AppImage project makes money? What kind of support (if any) do you seek from the end users?**_ + +**Simon:** No, AppImage makes no money whatsoever. + +I’ll just request the readers to spread the word. Tell your favorite application’s authors that you’d like to see an AppImage, and why. + +* * * + +Team It’s FOSS congratulates Simon for his hard work. Please feel free to convey any message and queries to him in the comment section. + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/appimage-interview/ + +作者:[Abhishek Prakash][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/abhishek/ +[b]: https://github.com/lujun9972 +[1]: https://appimage.org/ +[2]: https://itsfoss.com/use-appimage-linux/ +[3]: https://itsfoss.com/install-deb-files-ubuntu/ +[4]: https://getfedora.org/ +[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/appimage_simon_interview.jpg?ssl=1 +[6]: https://en.wikipedia.org/wiki/Macintosh +[7]: https://itsfoss.com/linus-torvalds-facts/ +[8]: https://itsfoss.com/install-snap-linux/ +[9]: https://flatpak.org/ +[10]: https://canonical.com/ +[11]: https://www.redhat.com/en +[12]: https://itsfoss.com/nitrux-linux-overview/ +[13]: https://itsfoss.com/best-linux-desktop-environments/ +[14]: https://www.deepin.org/en/ +[15]: https://appimage.github.io/ diff --git a/sources/tech/20190729 How to structure a multi-file C program- Part 1.md b/sources/tech/20190729 How to structure a multi-file C program- Part 1.md deleted file mode 100644 index b9e026ca4b..0000000000 --- a/sources/tech/20190729 How to structure a multi-file C program- Part 1.md +++ /dev/null @@ -1,197 +0,0 @@ -[#]: collector: (lujun9972) -[#]: translator: (mengxinayan) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (How to structure a multi-file C program: Part 1) -[#]: via: (https://opensource.com/article/19/7/structure-multi-file-c-part-1) -[#]: author: (Erik O'Shaughnessy https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions) - -How to structure a multi-file C program: Part 1 -====== -Grab your favorite beverage, editor, and compiler, crank up some tunes, -and start structuring a C program composed of multiple files. -![Programming keyboard.][1] - -It has often been said that the art of computer programming is part managing complexity and part naming things. I contend that this is largely true with the addition of "and sometimes it requires drawing boxes." - -In this article, I'll name some things and manage some complexity while writing a small C program that is loosely based on the program structure I discussed in "[How to write a good C main function][2]"—but different. This one will do something. Grab your favorite beverage, editor, and compiler, crank up some tunes, and let's write a mildly interesting C program together. - -### Philosophy of a good Unix program - -The first thing to know about this C program is that it's a [Unix][3] command-line tool. This means that it runs on (or can be ported to) operating systems that provide a Unix C runtime environment. When Unix was invented at Bell Labs, it was imbued from the beginning with a [design philosophy][4]. In my own words: _programs do one thing, do it well, and act on files_. While it makes sense to do one thing and do it well, the part about "acting on files" seems a little out of place. - -It turns out that the Unix abstraction of a "file" is very powerful. A Unix file is a stream of bytes that ends with an end-of-file (EOF) marker. That's it. Any other structure in a file is imposed by the application and not the operating system. The operating system provides system calls that allow a program to perform a set of standard operations on files: open, read, write, seek, and close (there are others, but those are the biggies). Standardizing access to files allows different programs to share a common abstraction and work together even when different people implement them in different programming languages. - -Having a shared file interface makes it possible to build programs that are _composable_. The output of one program can be the input of another program. The Unix family of operating systems provides three files by default whenever a program is executed: standard in (**stdin**), standard out (**stdout**), and standard error (**stderr**). Two of these files are opened in write-only mode: **stdout** and **stderr**, while **stdin** is opened read-only. We see this in action whenever we use file redirection in a command shell like Bash: - - -``` -`$ ls | grep foo | sed -e 's/bar/baz/g' > ack` -``` - -This construction can be described briefly as: the output of **ls** is written to stdout, which is redirected to the stdin of **grep**, whose stdout is redirected to **sed**, whose stdout is redirected to write to a file called **ack** in the current directory. - -We want our program to play well in this ecosystem of equally flexible and awesome programs, so let's write a program that reads and writes files. - -### MeowMeow: A stream encoder/decoder concept - -When I was a dewy-eyed kid studying computer science in the <mumbles>s, there were a plethora of encoding schemes. Some of them were for compressing files, some were for packaging files together, and others had no purpose but to be excruciatingly silly. An example of the last is the [MooMoo encoding scheme][5]. - -To give our program a purpose, I'll update this concept for the [2000s][6] and implement a concept called MeowMeow encoding (since the internet loves cats). The basic idea here is to take files and encode each nibble (half of a byte) with the text "meow." A lower-case letter indicates a zero, and an upper-case indicates a one. Yes, it will balloon the size of a file since we are trading 4 bits for 32 bits. Yes, it's pointless. But imagine the surprise on someone's face when this happens: - - -``` -$ cat /home/your_sibling/.super_secret_journal_of_my_innermost_thoughts -MeOWmeOWmeowMEoW... -``` - -This is going to be awesome. - -### Implementation, finally - -The full source for this can be found on [GitHub][7], but I'll talk through my thought process while writing it. The object is to illustrate how to structure a C program composed of multiple files. - -Having already established that I want to write a program that encodes and decodes files in MeowMeow format, I fired up a shell and issued the following commands: - - -``` -$ mkdir meowmeow -$ cd meowmeow -$ git init -$ touch Makefile     # recipes for compiling the program -$ touch main.c       # handles command-line options -$ touch main.h       # "global" constants and definitions -$ touch mmencode.c   # implements encoding a MeowMeow file -$ touch mmencode.h   # describes the encoding API -$ touch mmdecode.c   # implements decoding a MeowMeow file -$ touch mmdecode.h   # describes the decoding API -$ touch table.h      # defines encoding lookup table values -$ touch .gitignore   # names in this file are ignored by git -$ git add . -$ git commit -m "initial commit of empty files" -``` - -In short, I created a directory full of empty files and committed them to git. - -Even though the files are empty, you can infer the purpose of each from its name. Just in case you can't, I annotated each **touch** with a brief description. - -Usually, a program starts as a single, simple **main.c** file, with only two or three functions that solve the problem. And then the programmer rashly shows that program to a friend or her boss, and suddenly the number of functions in the file balloons to support all the new "features" and "requirements" that pop up. The first rule of "Program Club" is don't talk about "Program Club." The second rule is to minimize the number of functions in one file. - -To be honest, the C compiler does not care one little bit if every function in your program is in one file. But we don't write programs for computers or compilers; we write them for other people (who are sometimes us). I know that is probably a surprise, but it's true. A program embodies a set of algorithms that solve a problem with a computer, and it's important that people understand it when the parameters of the problem change in unanticipated ways. People will have to modify the program, and they will curse your name if you have all 2,049 functions in one file. - -So we good and true programmers break functions out, grouping similar functions into separate files. Here I've got files **main.c**, **mmencode.c**, and **mmdecode.c**. For small programs like this, it may seem like overkill. But small programs rarely stay small, so planning for expansion is a "Good Idea." - -But what about those **.h** files? I'll explain them in general terms later, but in brief, those are called _header_ files, and they can contain C language type definitions and C preprocessor directives. Header files should _not_ have any functions in them. You can think of headers as a definition of the application programming interface (API) offered by the **.c** flavored file that is used by other **.c** files. - -### But what the heck is a Makefile? - -I know all you cool kids are using the "Ultra CodeShredder 3000" integrated development environment to write the next blockbuster app, and building your project consists of mashing on Ctrl-Meta-Shift-Alt-Super-B. But back in my day (and also today), lots of useful work got done by C programs built with Makefiles. A Makefile is a text file that contains recipes for working with files, and programmers use it to automate building their program binaries from source (and other stuff too!). - -Take, for instance, this little gem: - - -``` -00 # Makefile -01 TARGET= my_sweet_program -02 $(TARGET): main.c -03    cc -o my_sweet_program main.c -``` - -Text after an octothorpe/pound/hash is a comment, like in line 00. - -Line 01 is a variable assignment where the variable **TARGET** takes on the string value **my_sweet_program**. By convention, OK, my preference, all Makefile variables are capitalized and use underscores to separate words. - -Line 02 consists of the name of the file that the recipe creates and the files it depends on. In this case, the target is **my_sweet_program**, ****and the dependency is **main.c**. - -The final line, 03, is indented with a tab and not four spaces. This is the command that will be executed to create the target. In this case, we call **cc** the C compiler frontend to compile and link **my_sweet_program**. - -Using a Makefile is simple: - - -``` -$ make -cc -o my_sweet_program main.c -$ ls -Makefile  main.c  my_sweet_program -``` - -The [Makefile][8] that will build our MeowMeow encoder/decoder is considerably more sophisticated than this example, but the basic structure is the same. I'll break it down Barney-style in another article. - -### Form follows function - -My idea here is to write a program that reads a file, transforms it, and writes the transformed data to another file. The following fabricated command-line interaction is how I imagine using the program: - - -``` -        $ meow < clear.txt > clear.meow -        $ unmeow < clear.meow > meow.tx -        $ diff clear.txt meow.tx -        $ -``` - -We need to write code to handle command-line parsing and managing the input and output streams. We need a function to encode a stream and write it to another stream. And finally, we need a function to decode a stream and write it to another stream. Wait a second, I've only been talking about writing one program, but in the example above, I invoke two commands: **meow** and **unmeow**? I know you are probably thinking that this is getting complex as heck. - -### Minor sidetrack: argv[0] and the ln command - -If you recall, the signature of a C main function is: - - -``` -`int main(int argc, char *argv[])` -``` - -where **argc** is the number of command-line arguments, and **argv** is a list of character pointers (strings). The value of **argv[0]** is the path of the file containing the program being executed. Many Unix utility programs with complementary functions (e.g., compress and uncompress) look like two programs, but in fact, they are one program with two names in the filesystem. The two-name trick is accomplished by creating a filesystem "link" using the **ln** command. - -An example from **/usr/bin** on my laptop is: - - -``` -   $ ls -li /usr/bin/git* -3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git -3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git-receive-pack -... -``` - -Here **git** and **git-receive-pack** are the same file with different names. We can tell it's the same file because they have the same inode number (the first column). An inode is a feature of the Unix filesystem and is super outside the scope of this article. - -Good and/or lazy programmers can use this feature of the Unix filesystem to write less code but double the number of programs they deliver. First, we write a program that changes its behavior based on the value of **argv[0]**, then we make sure to create links with the names that cause the behavior. - -In our Makefile, the **unmeow** link is created using this recipe: - - -``` - # Makefile - ... - $(DECODER): $(ENCODER) -         $(LN) -f $< $@ -        ... -``` - -I tend to parameterize everything in my Makefiles, rarely using a "bare" string. I group all the definitions at the top of the Makefile, which makes it easy to find and change them. This makes a big difference when you are trying to port software to a new platform and you need to change all your rules to use **xcc** instead of **cc**. - -The recipe should appear relatively straightforward except for the two built-in variables **$@** and **$<**. The first is a shortcut for the target of the recipe; in this case, **$(DECODER)**. (I remember this because the at-sign looks like a target to me.) The second, **$<** is the rule dependency; in this case, it resolves to **$(ENCODER)**. - -Things are getting complex for sure, but it's managed. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/19/7/structure-multi-file-c-part-1 - -作者:[Erik O'Shaughnessy][a] -选题:[lujun9972][b] -译者:[萌新阿岩](https://github.com/mengxinayan) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions -[b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_keyboard_coding.png?itok=E0Vvam7A (Programming keyboard.) -[2]: https://opensource.com/article/19/5/how-write-good-c-main-function -[3]: https://en.wikipedia.org/wiki/Unix -[4]: http://harmful.cat-v.org/cat-v/ -[5]: http://www.jabberwocky.com/software/moomooencode.html -[6]: https://giphy.com/gifs/nyan-cat-sIIhZliB2McAo -[7]: https://github.com/JnyJny/meowmeow -[8]: https://github.com/JnyJny/meowmeow/blob/master/Makefile diff --git a/sources/tech/20200206 3 ways to use PostgreSQL commands.md b/sources/tech/20200206 3 ways to use PostgreSQL commands.md deleted file mode 100644 index 645baf65e0..0000000000 --- a/sources/tech/20200206 3 ways to use PostgreSQL commands.md +++ /dev/null @@ -1,230 +0,0 @@ -[#]: collector: (lujun9972) -[#]: translator: (Morisun029) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (3 ways to use PostgreSQL commands) -[#]: via: (https://opensource.com/article/20/2/postgresql-commands) -[#]: author: (Greg Pittman https://opensource.com/users/greg-p) - -3 ways to use PostgreSQL commands -====== -Whether you need something simple, like a shopping list, or complex, -like a color swatch generator, PostgreSQL commands make it easy. -![Team checklist and to dos][1] - -In _[Getting started with PostgreSQL][2]_, I explained how to install, set up, and begin using the open source database software. But there's a lot more you can do with commands in [PostgreSQL][3]. - -For example, I use Postgres to keep track of my grocery shopping list. I do most of the grocery shopping in our home, and the bulk of it happens once a week. I go to several places to buy the things on my list because each store offers a particular selection or quality or maybe a better price. Initially, I made an HTML form page to manage my shopping list, but it couldn't save my entries. So, I had to wait to make my list all at once, and by then I usually forgot some items we need or I want. - -Instead, with PostgreSQL, I can enter bits when I think of them as the week goes on and print out the whole thing right before I go shopping. Here's how you can do that, too. - -### Create a simple shopping list - -First, enter the database with the **psql **command, then create a table for your list with: - - -``` -`Create table groc (item varchar(20), comment varchar(10));` -``` - -Type commands like the following to add items to your list: - - -``` -insert into groc values ('milk', 'K'); -insert into groc values ('bananas', 'KW'); -``` - -There are two pieces of information (separated by a comma) inside the parentheses: the item you want to buy and letters indicating where you want to buy it and whether it's something you usually buy every week (W). - -Since **psql** has a history, you can press the Up arrow and edit the data between the parentheses instead of having to type the whole line for each item. - -After entering a handful of items, check what you've entered with: - - -``` -Select * from groc order by comment; - -      item      | comment -\----------------+--------- - ground coffee  | H - butter         | K - chips          | K - steak          | K - milk           | K - bananas        | KW - raisin bran    | KW - raclette       | L - goat cheese    | L - onion          | P - oranges        | P - potatoes       | P - spinach        | PW - broccoli       | PW - asparagus      | PW - cucumber       | PW - sugarsnap peas | PW - salmon         | S -(18 rows) -``` - -This command orders the results by the _comment_ column so that the items are grouped by where you buy them to make it easier to shop. - -By using a W to indicate your weekly purchases, you can keep your weekly items on the list when you clear out the table to prepare for the next week's list. To so that, enter: - - -``` -`delete from groc where comment not like '%W';` -``` - -Notice that in PostgreSQL, **%** is the wildcard character (instead of an asterisk). So, to save typing, you might type: - - -``` -`delete from groc where item like 'goat%';` -``` - -You can't use **item = 'goat%'**; it won't work. - -When you're ready to shop, output your list to print it or send it to your phone with: - - -``` -\o groclist.txt -select * from groc order by comment; -\o -``` - -The last command, **\o**, with nothing afterward, resets the output to the command line. Otherwise, all output will continue to go to the groc file you created. - -### Analyze complex tables - -This item-by-item entry may be okay for short tables, but what about really big ones? A couple of years ago, I was helping the team at [FreieFarbe.de][4] to create a swatchbook of the free colors (freieFarbe means "free colors" in German) from its HLC color palette, where virtually any imaginable print color can be specified by its hue, luminosity (brightness), and chroma (saturation). The result was the [HLC Color Atlas][5], and here's how we did it. - -The team sent me files with color specifications so I could write Python scripts that would work with Scribus to generate the swatchbooks of color patches easily. One example started like: - - -``` -HLC, C, M, Y, K -H010_L15_C010, 0.5, 49.1, 0.1, 84.5 -H010_L15_C020, 0.0, 79.7, 15.1, 78.9 -H010_L25_C010, 6.1, 38.3, 0.0, 72.5 -H010_L25_C020, 0.0, 61.8, 10.6, 67.9 -H010_L25_C030, 0.0, 79.5, 18.5, 62.7 -H010_L25_C040, 0.4, 94.2, 17.3, 56.5 -H010_L25_C050, 0.0, 100.0, 15.1, 50.6 -H010_L35_C010, 6.1, 32.1, 0.0, 61.8 -H010_L35_C020, 0.0, 51.7, 8.4, 57.5 -H010_L35_C030, 0.0, 68.5, 17.1, 52.5 -H010_L35_C040, 0.0, 81.2, 22.0, 46.2 -H010_L35_C050, 0.0, 91.9, 20.4, 39.3 -H010_L35_C060, 0.1, 100.0, 17.3, 31.5 -H010_L45_C010, 4.3, 27.4, 0.1, 51.3 -``` - -This is slightly modified from the original, which separated the data with tabs. I transformed it into a CSV (comma-separated value) file, which I prefer to use with Python. (CSV files are also very useful because they can be imported easily into a spreadsheet program.) - -In each line, the first item is the color name, and it's followed by its C, M, Y, and K color values. The file consisted of 1,793 colors, and I wanted a way to analyze the information to get a sense of the range of values. This is where PostgreSQL comes into play. I did not want to enter all of this data manually—I don't think I could without errors (and headaches). Fortunately, PostgreSQL has a command for this. - -My first step was to create the database with: - - -``` -`Create table hlc_cmyk (color varchar(40), c decimal, m decimal, y decimal, k decimal);` -``` - -Then I brought in the data with: - - -``` -`\copy  hlc_cmyk from '/home/gregp/HLC_Atlas_CMYK_SampleData.csv' with (header, format CSV);` -``` - -The backslash at the beginning is there because using the plain **copy** command is restricted to root and the Postgres superuser. In the parentheses, **header** means the first line contains headings and should be ignored, and **CSV** means the file format is CSV. Note that parentheses are not required around the color name in this method. - -If the operation is successful, I see a message that says **COPY NNNN**, where the N's refer to the number of rows inserted into the table. - -Finally, I can query the table with: - - -``` -select * from hlc_cmyk; - -     color     |   c   |   m   |   y   |  k   -\---------------+-------+-------+-------+------ - H010_L15_C010 |   0.5 |  49.1 |   0.1 | 84.5 - H010_L15_C020 |   0.0 |  79.7 |  15.1 | 78.9 - H010_L25_C010 |   6.1 |  38.3 |   0.0 | 72.5 - H010_L25_C020 |   0.0 |  61.8 |  10.6 | 67.9 - H010_L25_C030 |   0.0 |  79.5 |  18.5 | 62.7 - H010_L25_C040 |   0.4 |  94.2 |  17.3 | 56.5 - H010_L25_C050 |   0.0 | 100.0 |  15.1 | 50.6 - H010_L35_C010 |   6.1 |  32.1 |   0.0 | 61.8 - H010_L35_C020 |   0.0 |  51.7 |   8.4 | 57.5 - H010_L35_C030 |   0.0 |  68.5 |  17.1 | 52.5 -``` - -It goes on like this for all 1,793 rows of data. In retrospect, I can't say that this query was absolutely necessary for the HLC and Scribus task, but it allayed some of my anxieties about the project. - -To generate the HLC Color Atlas, I automated creating the color charts with Scribus for the 13,000+ colors in those pages of color swatches. - -I could have used the **copy** command to output my data: - - -``` -`\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV);` -``` - -I also could restrict the output according to certain values with a **where** clause. - -For example, the following command will only send the table values for the hues that begin with H10. - - -``` -`\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV) where color like 'H10%';` -``` - -### Back up or transfer a database or table - -The final command I will mention here is **pg_dump**, which is used to back up a PostgreSQL database and runs outside of the **psql** console. For example: - - -``` -pg_dump gregp -t hlc_cmyk > hlc.out -pg_dump gregp > dball.out -``` - -The first line exports the **hlc_cmyk** table along with its structure. The second line dumps all the tables inside the **gregp** database. This is very useful for backing up or transferring a database or tables.  - -To transfer a database or table to another computer, first, create a database on the other computer (see my "[getting started][2]" article for details), then do the reverse process: - - -``` -`psql -d gregp -f dball.out` -``` - -This creates all the tables and enters the data in one step. - -### Conclusion - -In this article, we have seen how to use the **WHERE** parameter to restrict operations, along with the use of the PostgreSQL wildcard character **%**. We've also seen how to load a large amount of data into a table, then output some or all of the table data to a file, or even your entire database with all its individual tables. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/20/2/postgresql-commands - -作者:[Greg Pittman][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/greg-p -[b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos) -[2]: https://opensource.com/article/19/11/getting-started-postgresql -[3]: https://www.postgresql.org/ -[4]: http://freiefarbe.de -[5]: https://www.freiefarbe.de/en/thema-farbe/hlc-colour-atlas/ diff --git a/sources/tech/20200210 Top hacks for the YaCy open source search engine.md b/sources/tech/20200210 Top hacks for the YaCy open source search engine.md deleted file mode 100644 index 7b559e9c5e..0000000000 --- a/sources/tech/20200210 Top hacks for the YaCy open source search engine.md +++ /dev/null @@ -1,100 +0,0 @@ -[#]: collector: (lujun9972) -[#]: translator: (HankChow) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (Top hacks for the YaCy open source search engine) -[#]: via: (https://opensource.com/article/20/2/yacy-search-engine-hacks) -[#]: author: (Seth Kenlon https://opensource.com/users/seth) - -Top hacks for the YaCy open source search engine -====== -Rather than adapting to someone else's vision, customize you search -engine for the internet you want with YaCY. -![Browser of things][1] - -In my article about [getting started with YaCy][2], I explained how to install and start using the [YaCy][3] peer-to-peer search engine. One of the most exciting things about YaCy, however, is the fact that it's a local client. Each user owns and operates a node in a globally distributed search engine infrastructure, which means each user is in full control of how they navigate and experience the World Wide Web. - -For instance, Google used to provide the URL google.com/linux as a shortcut to filter searches for Linux-related topics. It was a small feature that many people found useful, but [topical shortcuts were dropped][4] in 2011.  - -YaCy makes it possible to customize your search experience. - -### Customize YaCy - -Once you've installed YaCy, navigate to your search page at **localhost:8090**. To customize your search engine, click the **Administration** button in the top-right corner (it may be concealed in a menu icon on small screens). - -The admin panel allows you to configure how YaCy uses your system resources and how it interacts with other YaCy clients. - -![YaCy profile selector][5] - -For instance, to configure an alternative port and set RAM and disk usage, use the **First steps** menu in the sidebar. To monitor YaCy activity, use the **Monitoring** panel. Most features are discoverable by clicking through the panels, but here are some of my favorites. - -### Search appliance - -Several companies have offered [intranet search appliances][6], but with YaCy, you can implement it for free. Whether you want to search through your own data or to implement a search system for local file shares at your business, you can choose to run YaCy as an internal indexer for files accessible over HTTP, FTP, and SMB (Samba). People in your local network can use your personalized instance of YaCy to find shared files, and none of the data is shared with users outside your network. - -### Network configuration - -YaCy favors isolation and privacy by default. You can adjust how you connect to the peer-to-peer network in the **Network Configuration** panel, which is revealed by clicking the link located at the top of the **Use Case & Account** configuration screen. - -![YaCy network configuration][7] - -### Crawl a site - -Peer-to-peer indexing is user-driven. There's no mega-corporation initiating searches on every accessible page on the internet, so a site isn't indexed until someone deliberately crawls it with YaCy. - -The YaCy client provides two options to help you help crawl the web: you can perform a manual crawl, and you can make YaCy available for suggested crawls. - -![YaCy advanced crawler][8] - -#### Start a manual crawling job - -A manual crawl is when you enter the URL of a site you want to index and start a YaCy crawl job. To do this, click the **Advanced Crawler** link in the **Production** sidebar. Enter one or more URLs, then scroll to the bottom of the page and enable the **Do remote indexing** option. This enables your client to broadcast the URLs it is indexing, so clients that have opted to accept requests can help you perform the crawl. - -To start the crawl, click the **Start New Crawl Job** button at the bottom of the page. I use this method to index sites I use frequently or find useful. - -Once the crawl job starts, YaCy indexes the URLs you enter and stores the index on your local machine. As long as you are running in senior mode (meaning your firewall permits incoming and outgoing traffic on port 8090), your index is available to YaCy users all over the globe. - -#### Join in on a crawl - -While some very dedicated YaCy senior users may crawl the internet compulsively, there are a _lot_ of sites out there in the world. It might seem impossible to match the resources of popular spiders and bots, but because YaCy has so many users, they can band together as a community to index more of the internet than any one user could do alone. If you activate YaCy to broadcast requests for site crawls, participating clients can work together to crawl sites you might not otherwise think to crawl manually. - -To configure your client to accept jobs from others, click the **Advanced Crawler** link in the left sidebar menu. In the **Advanced Crawler** panel, click the **Remote Crawling** link under the **Network Harvesting** heading at the top of the page. Enable remote crawls by placing a tick in the checkbox next to the **Load** setting. - -![YaCy remote crawling][9] - -### YaCy monitoring and more - -YaCy is a surprisingly robust search engine, providing you with the opportunity to theme and refine your experience in nearly any way you could want. You can monitor the activity of your YaCy client in the **Monitoring** panel, so you can get an idea of how many people are benefiting from the work of the YaCy community and also see what kind of activity it's generating for your computer and network. - -![YaCy monitoring screen][10] - -### Search engines make a difference - -The more time you spend with the Administration screen, the more fun it becomes to ponder how the search engine you use can change your perspective. Your experience of the internet is shaped by the results you get back for even the simplest of queries. You might notice, in fact, how different one person's "internet" is from another person's when you talk to computer users from a different industry. For some people, the web is littered with ads and promoted searches and suffers from the tunnel vision of learned responses to queries. For instance, if someone consistently searches for answers about X, most commercial search engines will give weight to query responses that concern X. That's a useful feature on the one hand, but it occludes answers that require Y, even though that might be the better solution for a specific task. - -As in real life, stepping outside a manufactured view of the world can be healthy and enlightening. Try YaCy, and see what you discover. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/20/2/yacy-search-engine-hacks - -作者:[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/browser_desktop_website_checklist_metrics.png?itok=OKKbl1UR (Browser of things) -[2]: https://opensource.com/article/20/2/open-source-search-engine -[3]: https://yacy.net/ -[4]: https://www.linuxquestions.org/questions/linux-news-59/is-there-no-more-linux-google-884306/ -[5]: https://opensource.com/sites/default/files/uploads/yacy-profiles.jpg (YaCy profile selector) -[6]: https://en.wikipedia.org/wiki/Vivisimo -[7]: https://opensource.com/sites/default/files/uploads/yacy-network-config.jpg (YaCy network configuration) -[8]: https://opensource.com/sites/default/files/uploads/yacy-advanced-crawler.jpg (YaCy advanced crawler) -[9]: https://opensource.com/sites/default/files/uploads/yacy-remote-crawl-accept.jpg (YaCy remote crawling) -[10]: https://opensource.com/sites/default/files/uploads/yacy-monitor.jpg (YaCy monitoring screen) diff --git a/sources/tech/20200213 Manage complex Git workspaces with Great Teeming Workspaces.md b/sources/tech/20200213 Manage complex Git workspaces with Great Teeming Workspaces.md new file mode 100644 index 0000000000..ef41241e35 --- /dev/null +++ b/sources/tech/20200213 Manage complex Git workspaces with Great Teeming Workspaces.md @@ -0,0 +1,1169 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Manage complex Git workspaces with Great Teeming Workspaces) +[#]: via: (https://opensource.com/article/20/2/git-great-teeming-workspaces) +[#]: author: (Daniel Gryniewicz https://opensource.com/users/dang) + +Manage complex Git workspaces with Great Teeming Workspaces +====== +GTWS is a set of scripts that make it easy to have development +environments for different projects and different versions of a project. +![Coding on a computer][1] + +Great Teeming Workspaces ([GTWS][2]) is a complex workspace management package for Git that makes it easy to have development environments for different projects and different versions of a project. + +Somewhat like Python [venv][3], but for languages other than Python, GTWS handles workspaces for multiple versions of multiple projects. You can create, update, enter, and leave workspaces easily, and each project or version combination has (at most) one local origin that syncs to and from the upstream—all other workspaces update from the local origin. + +### Layout + + +``` +${GTWS_ORIGIN}/<project>/<repo>[/<version>] +${GTWS_BASE_SRCDIR}/<project>/<version>/<workspacename>/{<repo>[,<repo>...]} +``` + +Each level in the source tree (plus the homedir for globals) can contain a **.gtwsrc** file that maintains settings and Bash code relevant to that level. Each more specific level overrides the higher levels. + +### Setup + +Check out GTWS with: + + +``` +`git clone https://github.com/dang/gtws.git` +``` + +Set up your **${HOME}/.gtwsrc**. It should include **GTWS_ORIGIN** and optionally **GTWS_SETPROMPT**. + +Add the repo directory to your path: + + +``` +`export PATH="${PATH}:/path/to/gtws` +``` + +### Configuration + +Configuration is via cascading **.gtwsrc** files. It walks the real path down from the root, and each **.gtwsrc** file it finds is sourced in turn. More specific files override less specific files. + +Set the following in your top-level **~/.gtws/.gtwsrc**: + + * **GTWS_BASE_SRCDIR:** This is the base of all the projects' source trees. It defaults to **$HOME/src**. + * **GTWS_ORIGIN:** This sets the location of the origin Git trees. It defaults to **$HOME/origin**. + * **GTWS_SETPROMPT:** This is optional. If it's set, the shell prompt will have the workspace name in it. + * **GTWS_DEFAULT_PROJECT:** This is the project used when no project is given or known. If it is not given, projects must be specified on the command line. + * **GTWS_DEFAULT_PROJECT_VERSION:** This is the default version to check out. It defaults to **master**. + + + +Set the following at the project level of each project: + + * **GTWS_PROJECT:** The name (and base directory) of the project. + * **gtws_project_clone:** This function is used to clone a specific version of a project. If it is not defined, then it is assumed that the origin for the project contains a single directory per version, and that contains a set of Git repos to clone. + * **gtws_project_setup:** This optional function is called after all cloning is done and allows any additional setup necessary for the project, such as setting up workspaces in an IDE. + + + +Set this at the project version level: + + * **GTWS_PROJECT_VERSION:** This is the version of the project. It's used to pull from the origin correctly. In Git, this is likely the branch name. + + + +These things can go anywhere in the tree and can be overridden multiple times, if it makes sense: + + * **GTWS_PATH_EXTRA:** These are extra path elements to be added to the path inside the workspace. + * **GTWS_FILES_EXTRA:** These are extra files not under version control that should be copied into each checkout in the workspace. This includes things like **.git/info/exclude**, and each file is relative to the base of its repo. + + + +### Origin directories + +**GTWS_ORIGIN** (in most scripts) points to the pristine Git checkouts to pull from and push to. + +Layout of **${GTWS_ORIGIN}**: + + * **/<project>** + * This is the base for repos for a project. + * If **gtws_project_clone** is given, this can have any layout you desire. + * If **gtws_project_clone** is not given, this must contain a single subdirectory named **git** that contains a set of bare Git repos to clone. + + + +### Workflow example + +Suppose you have a project named **Foo** that has an upstream repository at **github.com/foo/foo.git**. This repo has a submodule named **bar** with an upstream at **github.com/bar/bar.git**. The Foo project does development in the master branch and uses stable version branches. + +Before you can use GTWS with Foo, first you must set up the directory structure. These examples assume you are using the default directory structure. + + * Set up your top level **.gtwsrc**: + * **cp ${GTWS_LOC}/examples/gtwsrc.top ~/.gtwsrc** + * Edit **~/.gtwsrc** and change as necessary. + * Create top-level directories: + * **mkdir -p ~/origin ~/src** + * Create and set up the project directory: + * **mkdir -p ~/src/foo** +**cp ${GTWS_LOC}/examples/gtwsrc.project ~/src/foo/.gtwsrc** + * Edit **~/src/foo/.gtwsrc** and change as necessary. + * Create and set up the master version directory: + * **mkdir -p ~/src/foo/master** +**cp ${GTWS_LOC}/examples/gtwsrc.version ~/src/foo/master/.gtwsrc** + * Edit **~/src/foo/master/.gtwsrc** and change as necessary. + * Go to the version directory and create a temporary workspace to set up the mirrors: + * **mkdir -p ~/src/foo/master/tmp** +**cd ~/src/foo/master/tmp +git clone --recurse-submodules git://github.com/foo/foo.git +cd foo +gtws-mirror -o ~/origin -p foo** + * This will create **~/origin/foo/git/foo.git** and **~/origin/foo/submodule/bar.git**. + * Future clones will clone from these origins rather than from upstream. + * This workspace can be deleted now. + + + +At this point, work can be done on the master branch of Foo. Suppose you want to fix a bug named **bug1234**. You can create a workspace for this work to keep it isolated from anything else you're working on, and then work within this workspace. + + * Go to the version directory, and create a new workspace: + * **cd ~/src/foo/master +mkws bug1234** + * This creates **bug1234/**, and inside it checks out Foo (and its submodule **bar**) and makes **build/foo** for building it. + * Enter the workspace. There are two ways to do this: + * **cd ~/src/foo/master/bug1234 +startws** +or +**cd ~/src/foo/master/** +**startws bug1234** + * This starts a subshell within the bug1234 workspace. This shell has the GTWS environment plus any environment you set up in your stacked **.gtwsrc** files. It also adds the base of the workspace to your CD path, so you can **cd** into relative paths from that base. + * At this point, you can do work on bug1234, build it, test it, and commit your changes. When you're ready to push to upstream, do this:  +**cd foo +wspush**  + * **wspush** will push the branch associated with your workspace—first to your local origin and then to the upstream. + * If upstream changes. you can sync your local checkout using:  +**git sync** + * This envokes the **git-sync** script in GTWS, which will update your checkout from the local origin. To update the local origin, use:  +**git sync -o**  + * This will update your local origin and submodules' mirrors, then use those to update your checkout. **git-sync** has other nice features. + * When you're done using the workspace, just exit the shell: +**exit** + * You can re-enter the workspace at any time and have multiple shells in the same workspace at the same time. + * When you're done with a workspace, you can remove it using the **rmws** command or just remove its directory tree.  + * There is a script named **tmws** that enters a workspace within tmux, creating a set of windows/panes that are fairly specific to my workflow.  Feel free to modify it to suit your needs. + + + +### The script + + +``` +#!/bin/bash +# Functions for gtws +# + +GTWS_LOC=$(readlink -f $(dirname "${BASH_SOURCE[0]}")) +export GTWS_LOC + +# if is_interactive; then echo "interactive" fi +# +# Check for an interactive shell +is_interactive() { +        case $- in +                *i*) +                        # Don't die in interactive shells +                        return 0 +                        ;; +                *) +                        return 1 +                        ;; +        esac +} + +# if can_die; then exit +# +# Check to see if it's legal to exit during die +can_die() { +        if (( BASH_SUBSHELL > 0 )); then +                debug_print "\t\tbaby shell; exiting" +                return 0 +        fi +        if ! is_interactive; then +                debug_print "\t\tNot interactive; exiting" +                return 0 +        fi +        debug_print "\t\tParent interactive; not exiting" +        return 1 +} + +# In a function: +# command || die "message" || return 1 +# Outside a function: +# command || die "message" +# +# Print a message and exit with failure +die() { +        echo -e "Failed: $1" >&2 +        if [ ! -z "$(declare -F | grep "GTWScleanup")" ]; then +                GTWScleanup +        fi +        if can_die; then +                exit 1 +        fi +        return 1 +} + +# Alternativess for using die properly to handle both interactive and script useage: +# +# Version 1: +# +#testfunc() { +#       command1 || die "${FUNCNAME}: command1 failed" || return 1 +#       command2 || die "${FUNCNAME}: command2 failed" || return 1 +#       command3 || die "${FUNCNAME}: command3 failed" || return 1 +#} +# +# Version 2: +# +#testfunc() { +#       ( +#               command1 || die "${FUNCNAME}: command1 failed" +#               command2 || die "${FUNCNAME}: command2 failed" +#               command3 || die "${FUNCNAME}: command3 failed" +#       ) +#       return $? +#} +# +# Optionally, the return can be replaced with this: +#       local val=$? +#       [[ "${val}" == "0" ]] || die +#       return ${val} +# This will cause the contaning script to abort + +# usage "You need to provide a frobnicator" +# +# Print a message and the usage for the current script and exit with failure. +usage() { +        local myusage; +        if [ -n "${USAGE}" ]; then +                myusage=${USAGE} +        else +                myusage="No usage given" +        fi +        local me; +        if [ -n "${ME}" ]; then +                me=${ME} +        else +                me=$(basename $0) +        fi +        if [ -n "$1" ]; then +                echo "$@" +        fi +        echo "" +        if [ -n "${DESCRIPTION}" ]; then +                echo -e "${me}: ${DESCRIPTION}" +                echo "" +        fi +        echo "Usage:" +        echo "${me} ${myusage}" +        if [ -n "${LONGUSAGE}" ]; then +                echo -e "${LONGUSAGE}" +        fi +        exit 1 +} + +# debug_print "Print debug information" +# +# Print debug information based on GTWS_VERBOSE +debug_print() { +        if [ -n "${GTWS_VERBOSE}" ]; then +                echo -e "${GTWS_INDENT}$@" >&2 +        fi +} + +# debug_trace_start +# +# Start tracing all commands +debug_trace_start() { +        if [ -n "${GTWS_VERBOSE}" ]; then +                set -x +        fi +} + +# debug_trace_stop +# +# Stop tracing all commands +debug_trace_stop() { +        set +x +} + +# cmd_exists ${cmd} +# +# Determine if a command exists on the system +function cmd_exists { +        which $1 > /dev/null 2>&1 +        if [ "$?" == "1" ]; then +                die "You don't have $1 installed, sorry" || return 1 +        fi +} + +# is_git_repo ${dir} +# +# return success if ${dir} is in a git repo, or failure otherwise +is_git_repo() { +        debug_print "is_git_repo $1" +        if [[ $1 == *:* ]]; then +                debug_print "    remote; assume good" +                return 0 +        elif [ ! -d "$1" ]; then +                debug_print "    fail: not dir" +                return 1 +        fi +        cd "$1" +        git rev-parse --git-dir >/dev/null 2>&1 +        local ret=$? +        cd - > /dev/null +        debug_print "    retval: $ret" +        return $ret +} + +# find_git_repo ${basedir} ${repo_name} repo_dir +# +# Find the git repo for ${repo_name} in ${basedir}.  It's one of ${repo_name} +# or ${repo_name}.git +# +# Result will be in the local variable repo_dir  Or: +# +# repo_dir=$(find_git_repo ${basedir} ${repo_name}) +# +function find_git_repo { +        local basedir=$1 +        local repo_name=$2 +        local __resultvar=$3 +        local try="${basedir}/${repo_name}" + +        if ! is_git_repo "${try}" ; then +                try=${try}.git +        fi + +        is_git_repo "${try}" || die "${repo_name} in ${basedir} is not a git repository" || return 1 + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$try'" +        else +                echo "$try" +        fi +} + +# git_top_dir top +# +# Get the top level of the git repo contaning PWD, or return failure; +# +# Result will be in local variable top  Or: +# +# top = $(git_top_dir) +# +# Result will be in local variable top +function git_top_dir { +        local  __resultvar=$1 +        local __top="$(git rev-parse --show-toplevel 2>/dev/null)" + +        if [ -z "${__top}" ]; then +                die "${PWD} is not a git repo" || return 1 +        fi +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__top'" +        else +                echo "$__top" +        fi +} + +# is_git_rebase +# +# return success if git repo is in a rebase +is_git_rebase() { +        debug_print "is_git_rebase $1" +        (test -d "$(git rev-parse --git-path rebase-merge)" || \ +                test -d "$(git rev-parse --git-path rebase-apply)" ) +        local ret=$? +        debug_print "    retval: $ret" +        return $ret +} + +# is_docker +# +# return success if process is running inside docker +is_docker() { +        debug_print "is_docker" +        grep -q docker /proc/self/cgroup +        return $? +} + +# is_gtws +# +# return success if process is running inside a workspace +is_gtws() { +        if [ -n "${GTWS_WS_GUARD}" ]; then +                return 0 +        fi +        return 1 +} + +function gtws_rcp { +        rsync --rsh=ssh -avzS --progress --ignore-missing-args --quiet "$@" +} + +function gtws_cpdot { +        local srcdir=$1 +        local dstdir=$2 + +        debug_print "${FUNCNAME} - ${srcdir} to ${dstdir}" +        if [ -d "${srcdir}" ] && [ -d "${dstdir}" ]; then +                shopt -s dotglob +                cp -a "${srcdir}"/* "${dstdir}"/ +                shopt -u dotglob +        fi +} + +# gtws_find_dockerfile dockerfile +# +# Result will be in local variable dockerfile  Or: +# +# dockerfile = $(gtws_find_dockerfile) +# +# Result will be in local variable dockerfile +# +# Get the path to the most-specific Dockerfile +function gtws_find_dockerfile { +        local  __resultvar=$1 +        local __dir="${GTWS_WSPATH}" +        local __file="Dockerfile" + +        debug_print "${FUNCNAME} - trying ${__dir}/${__file}" +        if [ ! -f "${__dir}/${__file}" ]; then +                # Version dir +                __dir=$(dirname "${__dir}") +                debug_print "${FUNCNAME} - trying ${__dir}/${__file}" +        fi +        if [ ! -f "${__dir}/${__file}" ]; then +                # Project dir +                __dir=$(dirname "${__dir}") +                debug_print "${FUNCNAME} - trying ${__dir}/${__file}" +        fi +        if [ ! -f "${__dir}/${__file}" ]; then +                # Top level, flavor +                __dir="${GTWS_LOC}/dockerfiles" +                __file="Dockerfile-${FLAVOR}" +                debug_print "${FUNCNAME} - trying ${__dir}/${__file}" +        fi +        if [ ! -f "${__dir}/${__file}" ]; then +                # Top level, base +                __dir="${GTWS_LOC}/dockerfiles" +                __file="Dockerfile-base" +                debug_print "${FUNCNAME} - trying ${__dir}/${__file}" +        fi +        if [ ! -f "${__dir}/${__file}" ]; then +                die "Could not find a Dockerfile" || return 1 +        fi + +        debug_print "${FUNCNAME} - found ${__dir}/${__file}" +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'${__dir}/${__file}'" +        else +                echo "$__dir" +        fi +} + +# gtws_smopvn ${GTWS_SUBMODULE_ORIGIN:-${GTWS_ORIGIN}} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} ${GTWS_WSNAME} smopvn +# +# Result will be in local variable smopvn.  Or: +# +# smopvn = $(gtws_smopvn ${GTWS_SUBMODULE_ORIGIN:-${GTWS_ORIGIN}} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} ${GTWS_WSNAME}) +# +# Result will be in local variable smovpn +# +# Get the path to submodules for this workspace +function gtws_smopvn { +        local origin=$1 +        local project=$2 +        local version=$3 +        local name=$4 +        local  __resultvar=$5 +        local __smopv="${origin}/${project}/submodule" + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__smopv'" +        else +                echo "$__smopv" +        fi +} + +# gtws_opvn ${GTWS_ORIGIN} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} ${GTWS_WSNAME} opvn +# +# Result will be in local variable opvn.  Or: +# +# opvn = $(gtws_opvn ${GTWS_ORIGIN} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} ${GTWS_WSNAME}) +# +# Result will be in local variable opvn. +# +# Get the path to git repos for this workspace +function gtws_opvn { +        local origin=$1 +        local project=$2 +        local version=$3 +        local name=$4 +        local  __resultvar=$5 +        local __opv="${origin}/${project}/${version}" + +        if [[ $__opv == *:* ]]; then +                __opv="${__opv}/${name}" +                debug_print "remote; using opvn $__opv" +        elif [ ! -d "${__opv}" ]; then +                __opv="${origin}/${project}/git" +                if [ ! -d "${__opv}" ]; then +                        die "No opvn for ${origin} ${project} ${version}" || return 1 +                fi +        fi +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__opv'" +        else +                echo "$__opv" +        fi +} + +# gtws_submodule_url ${submodule} url +# +# Result will be in local variable url  Or: +# +# url = $(gtws_submodule_url ${submodule}) +# +# Result will be in local variable url +# +# Get the URL for a submodule +function gtws_submodule_url { +        local sub=$1 +        local  __resultvar=$2 +        local __url=$(git config --list | grep "submodule.*url" | grep "\<${sub}\>" | cut -d = -f 2) + +        if [ -z "${__url}" ]; then +                local rpath=${PWD} +                local subsub=$(basename "${sub}") +                cd "$(dirname "${sub}")" +                debug_print "${FUNCNAME} trying ${PWD}" +                __url=$(git config --list | grep submodule | grep "\<${subsub}\>" | cut -d = -f 2) +                cd "${rpath}" +        fi + +        debug_print "${FUNCNAME} $sub url: $__url" +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__url'" +        else +                echo "$__url" +        fi +} + +# gtws_submodule_mirror ${smopv} ${submodule} ${sub_sub_basename} mloc +# +# Result will be in local variable mloc  Or: +# +# mloc = $(gtws_submodule_mirror ${smopv} ${submodule} ${sub_sub_basename}) +# +# Result will be in local variable mloc +# +# Get the path to a local mirror of the submodule, if it exists +function gtws_submodule_mirror { +        local smopv=$1 +        local sub=$2 +        local sub_sub=$3 +        local  __resultvar=$4 +        local __mloc="" +        local url=$(gtws_submodule_url ${sub}) +        if [ -n "${url}" ]; then +                local urlbase=$(basename ${url}) +                # XXX TODO - handle remote repositories +                #if [[ ${smopv} == *:* ]]; then +                ## Remote SMOPV means clone from that checkout; I don't cm +                #refopt="--reference ${smopv}/${name}/${sub}" +                if [ -d "${smopv}/${urlbase}" ]; then +                        __mloc="${smopv}/${urlbase}" +                fi +        fi + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__mloc'" +        else +                echo "$__mloc" +        fi +} + +# gtws_submodule_paths subpaths +# +# Result will be in local variable subpaths  Or: +# +# subpaths = $(gtws_submodule_paths) +# +# Result will be in local variable subpaths +# +# Get the paths to submodules in a get repo.  Does not recurse +function gtws_submodule_paths { +        local  __resultvar=$1 +        local __subpaths=$(git submodule status | sed 's/^ *//' | cut -d ' ' -f 2) + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__subpaths'" +        else +                echo "$__subpaths" +        fi +} + +# gtws_submodule_clone [<base-submodule-path>] [<sub-sub-basename>] +# +# This will set up all the submodules in a repo.  Should be called from inside +# the parent repo +function gtws_submodule_clone { +        local smopv=$1 +        local sub_sub=$2 +        local sub_paths=$(gtws_submodule_paths) +        local rpath="${PWD}" + +        if [ -z "${smopv}" ]; then +                smopv=$(gtws_smopvn "${GTWS_SUBMODULE_ORIGIN:-${GTWS_ORIGIN}}" "${GTWS_PROJECT}" "${GTWS_PROJECT_VERSION}" "${GTWS_WSNAME}") +        fi +        git submodule init || die "${FUNCNAME}: Failed to init submodules" || return 1 +        for sub in ${sub_paths}; do +                local refopt="" +                local mirror=$(gtws_submodule_mirror "${smopv}" "${sub}" "${sub_sub}") +                debug_print "${FUNCNAME} mirror: ${mirror}" +                if [ -n "${mirror}" ]; then +                        refopt="--reference ${mirror}" +                fi +                git submodule update ${refopt} "${sub}" +                # Now see if there are recursive submodules +                cd "${sub}" +                gtws_submodule_clone "${smopv}/${sub}_submodule" "${sub}" || return 1 +                cd "${rpath}" +        done +} + +# gtws_repo_clone <base-repo-path> <repo> <branch> [<base-submodule-path>] [<target-directory>] +function gtws_repo_clone { +        local baserpath=${1%/} +        local repo=$2 +        local branch=$3 +        local basesmpath=$4 +        local rname=${5:-${repo%.git}} +        local rpath="${baserpath}/${repo}" +        local origpath=${PWD} + +        if [[ ${rpath} != *:* ]]; then +                if [ ! -d "${rpath}" ]; then +                        rpath="${rpath}.git" +                fi +        fi +        if [ -z "${basesmpath}" ]; then +                basesmpath="${baserpath}" +        fi +        debug_print "${FUNCNAME}: cloning ${baserpath} - ${repo} : ${branch} into ${GTWS_WSNAME}/${rname} submodules: ${basesmpath}" + +        # Main repo +        #git clone --recurse-submodules -b "${branch}" "${rpath}" || die "failed to clone ${rpath}:${branch}" || return 1 +        git clone -b "${branch}" "${rpath}" ${rname} || die "${FUNCNAME}: failed to clone ${rpath}:${branch}" || return 1 + +        # Update submodules +        cd "${rname}" || die "${FUNCNAME}: failed to cd to ${rpath}" || return 1 +        gtws_submodule_clone "${basesmpath}" || return 1 +        cd "${origpath}" || die "${FUNCNAME}: Failed to cd to ${origpath}" || return 1 + +        # Copy per-repo settings, if they exist +        gtws_cpdot "${baserpath%/git}/extra/repo/${rname}" "${origpath}/${rname}" + +        # Extra files +        for i in ${GTWS_FILES_EXTRA}; do +                local esrc= + +                IFS=':' read -ra ARR <<< "$i" +                if [ -n "${ARR[1]}" ]; then +                        dst="${rname}/${ARR[1]}" +                else +                        dst="${rname}/${ARR[0]}" +                fi + +                if [ -n "${GTWS_REMOTE_IS_WS}" ]; then +                        esrc="${baserpath}/${dst}" +                else +                        esrc="${baserpath%/git}" +                fi + +                gtws_rcp "${esrc}/${ARR[0]}" "${dst}" +        done +} + +# gtws_project_clone_default ${GTWS_ORIGIN} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} ${GTWS_WSNAME} [${SUBMODULE_BASE}] +# +# Clone a version of a project into ${GTWS_WSPATH} (which is the current working directory).  This is the default version of this that clones <origin>/<project>/<version>/* +function gtws_project_clone_default { +        local origin=$1 +        local project=$2 +        local version=$3 +        local name=$4 +        local basesmpath=$5 +        local opv=$(gtws_opvn "${origin}" "${project}" "${version}" "${name}") +        local wspath=${PWD} +        local repos= +        local -A branches + +        if [ -z "${GTWS_PROJECT_REPOS}" ]; then +                for i in "${opv}"/*; do +                        repos="$(basename $i) $repos" +                        branches[$i]=${version} +                done +        else +                for i in ${GTWS_PROJECT_REPOS}; do +                        IFS=':' read -ra ARR <<< "$i" +                        repos="${ARR[0]} $repos" +                        if [ -n "${ARR[1]}" ]; then +                                branches[${ARR[0]}]=${ARR[1]} +                        else +                                branches[${ARR[0]}]=${version} +                        fi +                done +        fi + +        if [ -z "${basesmpath}" ] || [ ! -d "${basesmpath}" ]; then +                basesmpath="${opv}" +        fi + +        for repo in ${repos}; do +                gtws_repo_clone "${opv}" "${repo}" "${branches[${repo}]}" "${basesmpath}" +        done + +        # Copy per-WS settings, if they exist +        gtws_cpdot "${opv%/git}/extra/ws" "${wspath}" +} + +# gtws_repo_setup ${wspath} ${repo_path} +# +# The project can define gtws_repo_setup_local taking the same args to do +# project-specific setup.  It will be called last. +# +# Post-clone setup for an individual repo +function gtws_repo_setup { +        local wspath=$1 +        local rpath=$2 +        local savedir="${PWD}" + +        if [ ! -d "${rpath}" ]; then +                return 0 +        fi + +        cd "${rpath}/src" 2>/dev/null \ +                || cd ${rpath} \ +                || die "Couldn't cd to ${rpath}" || return 1 + +        maketags ${GTWS_MAKETAGS_OPTS} > /dev/null 2> /dev/null & + +        cd ${wspath} || die "Couldn't cd to ${wspath}" || return 1 + +        mkdir -p "${wspath}/build/$(basename ${rpath})" + +        cd "${savedir}" + +        if [ -n "$(declare -F | grep "\<gtws_repo_setup_local\>")" ]; then +                gtws_repo_setup_local "${wspath}" "${rpath}" \ +                        || die "local repo setup failed" || return 1 +        fi +} + +# gtws_project_setup${GTWS_WSNAME} ${GTWS_ORIGIN} ${GTWS_PROJECT} ${GTWS_PROJECT_VERSION} +# +# The project can define gtws_project_setup_local taking the same args to do +# project-specific setup.  It will be called last. +# +# Post clone setup of a workspace in ${GTWS_WSPATH} (which is PWD) +function gtws_project_setup { +        local wsname=$1 +        local origin=$2 +        local project=$3 +        local version=$4 +        local wspath=${PWD} +        local opv=$(gtws_opvn "${origin}" "${project}" "${version}" "placeholder") + +        for i in "${wspath}"/*; do +                gtws_repo_setup "${wspath}" "${i}" +        done + +        mkdir "${wspath}"/install +        mkdir "${wspath}"/chroots +        mkdir "${wspath}"/patches + +        if [ -n "$(declare -F | grep "\<gtws_project_setup_local\>")" ]; then +                gtws_project_setup_local "${wsname}" "${origin}" "${project}" \ +                        "${version}" || die "local project setup failed" || return 1 +        fi +} + +# load_rc /path/to/workspace +# +# This should be in the workspace-level gtwsrc file +# Recursively load all RC files, starting at / +function load_rc { +        local BASE=$(readlink -f "${1}") +        # Load base RC first +        debug_print "load_rc: Enter + Top: ${BASE}" +        source "${HOME}"/.gtwsrc +        while [ "${BASE}" !=  "/" ]; do +                if [ -f "${BASE}"/.gtwsrc ]; then +                        load_rc "$(dirname ${BASE})" +                        debug_print "\tLoading ${BASE}/.gtwsrc" +                        source "${BASE}"/.gtwsrc +                        return 0 +                fi +                BASE=$(readlink -f $(dirname "${BASE}")) +        done +        # Stop at / + +        return 1 +} + +# clear_env +# +# Clear the environment of GTWS_* except for the contents of GTWS_SAVEVARS. +# The default values for GTWS_SAVEVARS are below. +function clear_env { +        local savevars=${GTWS_SAVEVARS:-"LOC PROJECT PROJECT_VERSION VERBOSE WSNAME"} +        local verbose="${GTWS_VERBOSE}" +        debug_print "savevars=$savevars" + +        # Reset prompt +        if [ -n "${GTWS_SAVEPS1}" ]; then +                PS1="${GTWS_SAVEPS1}" +        fi +        if [ -n "${GTWS_SAVEPATH}" ]; then +                export PATH=${GTWS_SAVEPATH} +        fi +        unset LD_LIBRARY_PATH +        unset PYTHONPATH +        unset PROMPT_COMMAND +        unset CDPATH +        unset SDIRS + +        # Save variables +        for i in ${savevars}; do +                SRC=GTWS_${i} +                DST=SAVE_${i} +                debug_print "\t $i: ${DST} = ${!SRC}" +                eval ${DST}=${!SRC} +        done + +        # Clear GTWS evironment +        for i in ${!GTWS*} ; do +                if [ -n "${verbose}" ]; then +                        echo -e "unset $i" >&2 +                fi +                unset $i +        done + +        # Restore variables +        for i in ${savevars}; do +                SRC=SAVE_${i} +                DST=GTWS_${i} +                if [ -n "${verbose}" ]; then +                        echo -e "\t $i: ${DST} = ${!SRC}" >&2 +                fi +                if [ -n "${!SRC}" ]; then +                        eval export ${DST}=${!SRC} +                fi +                unset ${SRC} +        done +} + +# save_env ${file} ${nukevars} +# +# Save the environment of GTWS_* to the give file, except for the variables +# given to nuke.  The default values to nuke are given below. +function save_env { +        local fname=${1} +        local nukevars=${2:-"SAVEPATH ORIGIN WS_GUARD LOC SAVEPS1"} +        debug_print "nukevars=$nukevars" + +        for i in ${!GTWS*} ; do +                for j in ${nukevars}; do +                        if [ "${i}" == "GTWS_${j}" ]; then +                                debug_print "skipping $i" +                                continue 2 +                        fi +                done +                debug_print "saving $i" +                echo "export $i=\"${!i}\"" >> "${fname}" +        done +} + +# gtws_tmux_session_name ${PROJECT} ${VERSION} ${WSNAME} sesname +# +# Result will be in local variable sesname  Or: +# +# sesname = $(gtws_tmux_session_name ${PROJECT} ${VERSION} ${WSNAME}) +# +# Result will be in local variable sesname +# +# Get the tmux session name for a given workspace +function gtws_tmux_session_name { +        local project=$1 +        local version=$2 +        local wsname=$3 +        local  __resultvar=$4 +        local sesname="${project//./_}/${version//./_}/${wsname//./_}" + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$sesname'" +        else +                echo "$sesname" +        fi +} + +# gtws_tmux_session_info ${SESSION_NAME} running attached +# +# Determine if a session is running, and if it is attached +# +# Result will be in local variables running and attached +# +# Test with: +# if $running ; then +#       echo "is running" +# fi + +function gtws_tmux_session_info { +        local ses_name=$1 +        local  __result_running=$2 +        local  __result_attached=$3 + +        local __num_ses=$(tmux ls | grep "^${ses_name}" | wc -l) +        local __attached=$(tmux ls | grep "^${ses_name}" | grep attached) + +        echo "$ses_name ses=${__num_ses}" + +        if [[ "$__result_running" ]]; then +                if [ "${__num_ses}" != "0" ]; then +                        eval $__result_running="true" +                else +                        eval $__result_running="false" +                fi +        fi +        if [[ "$__result_attached" ]]; then +                if [ -n "${__attached}" ]; then +                        eval $__result_attached="true" +                else +                        eval $__result_attached="false" +                fi +        fi +} + +# gtws_tmux_kill ${BASENAME} +# +# Kill all sessiont matching a pattern +function gtws_tmux_kill { +        local basename=$1 +        local old_sessions=$(tmux ls 2>/dev/null | fgrep "${basename}" | cut -f 1 -d:) +        for session in ${old_sessions}; do +                tmux kill-session -t "${session}" +        done +} + +# gtws_tmux_cleanup +# +# Clean up defunct tmux sessions +function gtws_tmux_cleanup { +        local old_sessions=$(tmux ls 2>/dev/null | egrep "^[0-9]{14}.*[0-9]+\\)$" | cut -f 1 -d:) +        for session in ${old_sessions}; do +                tmux kill-session -t "${session}" +        done +} + +# gtws_tmux_attach ${SESSION_NAME} +# +# Attach to a primary session.  It will remain after detaching. +function gtws_tmux_attach { +        local ses_name=$1 + +        tmux attach-session -t "${ses_name}" +} + +# gtws_tmux_slave ${SESSION_NAME} +# +# Create a secondary session attached to the primary session.  It will exit it +# is detached. +function gtws_tmux_slave { +        local ses_name=$1 + +        # Session is is date and time to prevent conflict +        local session=`date +%Y%m%d%H%M%S` +        # Create a new session (without attaching it) and link to base session +        # to share windows +        tmux new-session -d -t "${ses_name}" -s "${session}" +        # Attach to the new session +        gtws_tmux_attach "${session}" +        # When we detach from it, kill the session +        tmux kill-session -t "${session}" +} + +function cdorigin() { +        if [ -n "$(declare -F | grep "gtws_project_cdorigin")" ]; then +                gtws_project_cdorigin $@ +        else +                gtws_cdorigin $@ +        fi +} + +function gtws_get_origin { +        local opv=$1 +        local target=$2 +        local __origin= +        local  __resultvar=$3 + +        # If it's a git repo with a local origin, use that. +        __origin=$(git config --get remote.origin.url) +        if [ ! -d "${__origin}" ]; then +                __origin="${__origin}.git" +        fi +        if [ ! -d "${__origin}" ]; then +                # Try to figure it out +                if [ ! -d "${opv}" ]; then +                        die "No opv for $target" || return 1 +                fi +                find_git_repo "${opv}" "${target}" __origin || return 1 +        fi + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$__origin'" +        else +                echo "$__origin" +        fi +} + +function gtws_cdorigin() { +        local opv=$(gtws_opvn "${GTWS_ORIGIN}" "${GTWS_PROJECT}" "${GTWS_PROJECT_VERSION}" "${GTWS_WSNAME}") +        local gitdir="" +        local target="" +        if [ -n "$1" ]; then +                target="$@" +        else +                git_top_dir gitdir || return 1 +                target=$(basename $gitdir) +        fi + +        gtws_get_origin $opv $target origin || return 1 +        cd "${origin}" +} + +# Copy files to another machine in the same workspace +function wsrcp { +        local target="${!#}" +        local length=$(($#-1)) +        local base=${PWD} + +        if [ -z "${1}" -o -z "${2}" ]; then +                echo "usage: ${FUNCNAME} <path> [<path>...] <target>" +                return 1 +        fi + +        for path in "${@:1:$length}"; do +                gtws_rcp "${path}" "${target}:${base}/${path}" +        done +} + +# Override "cd" inside the workspace to go to GTWS_WSPATH by default +function cd { +        if [ -z "$@" ]; then +                cd "${GTWS_WSPATH}" +        else +                builtin cd $@ +        fi +} + +# Generate diffs/interdiffs for changes and ship to WS on other boxes +function gtws_interdiff { +        local targets=$@ +        local target= +        local savedir=${PWD} +        local topdir=$(git_top_dir) +        local repo=$(basename ${topdir}) +        local mainpatch="${GTWS_WSPATH}/patches/${repo}-full.patch" +        local interpatch="${GTWS_WSPATH}/patches/${repo}-incremental.patch" + +        if [ -z "${targets}" ]; then +                echo "Usage: ${FUNCNAME} <targethost>" +                die "Must give targethost" || return 1 +        fi +        cd "${topdir}" +        if [ -f "${mainpatch}" ]; then +                git diff | interdiff "${mainpatch}" - > "${interpatch}" +        fi +        git diff > "${mainpatch}" +        for target in ${targets}; do +                gtws_rcp "${mainpatch}" "${interpatch}" \ +                        "${target}:${GTWS_WSPATH}/patches" +        done +        cd "${savedir}" +} + +function gtws_debug { +        local cmd=$1 +        if [ -z "${cmd}" ]; then +                echo "Must give a command" +                echo +                die "${FUNCNAME} <cmd-path>" || return 1 +        fi +        local cmdbase=$(basename $cmd) +        local pid=$(pgrep "${cmdbase}") + +        ASAN_OPTIONS="abort_on_error=1" cgdb ${cmd} ${pid} +} + +# remote_cmd "${target}" "${command}" output +# +# Result will be in local variable output  Or: +# +# output = $(remote_cmd "${target}" "${command}") +# +# Result will be in local variable output +# +# Run a command remotely and capture sdtout.  Make sure to quote the command +# appropriately. +remote_cmd() { +        local target=$1 +        local cmd=$2 +        local  __resultvar=$3 +        local output= + +        if [ -z "${GTWS_VERBOSE}" ]; then +                output=$(ssh "${target}" "${cmd}" 2>/dev/null) +        else +                output=$(ssh "${target}" "${cmd}") +        fi +        local ret=$? + +        if [[ "$__resultvar" ]]; then +                eval $__resultvar="'$output'" +        else +                echo "${output}" +        fi +        return ${ret} +} +``` + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/git-great-teeming-workspaces + +作者:[Daniel Gryniewicz][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/dang +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer) +[2]: https://github.com/dang/gtws +[3]: https://docs.python.org/3/library/venv.html diff --git a/sources/tech/20200213 Why developers like to code at night.md b/sources/tech/20200213 Why developers like to code at night.md new file mode 100644 index 0000000000..b01246d62a --- /dev/null +++ b/sources/tech/20200213 Why developers like to code at night.md @@ -0,0 +1,95 @@ +[#]: collector: (lujun9972) +[#]: translator: (Morisun029) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Why developers like to code at night) +[#]: via: (https://opensource.com/article/20/2/why-developers-code-night) +[#]: author: (Matt Shealy https://opensource.com/users/mshealy) + +Why developers like to code at night +====== +A nocturnal work schedule is the key to creativity and productivity for +many open source programmers. +![Person programming on a laptop on a building][1] + +If you ask most developers when they prefer to work, many will say their most productive hours are at night. This may be especially true for open source contributors who are contributing to projects outside of their day job (though hopefully within healthy limits to [avoid burnout][2]). + +Some like to start in the evening and work till the early hours while others get up super early—say, 4 a.m.—to get most of the programming work done before the daily grind kicks in. + +This work habit may make many developers seem like oddballs and misfits. However, there are quite a few reasons why so many programmers prefer to work during the odd hours: + +### The maker's schedule + +According to [Paul Graham][3], people who "produce stuff" tend to adhere to the maker's schedule—they prefer to use time in units of a half-day or longer. In fact, most [developers have the same preference][4]. + +For one thing, developers work on large abstract systems and need the mental space to process a model in its entirety. Having their schedules sliced into 15- or 30-minute chunks for emails, meetings, phone calls, and interruptions from co-workers is simply counterproductive. + +For another, it's often not possible to program effectively in units of an hour; that's barely enough time to wrap your head around the task at hand and get started. + +Programming is also adversely affected by context-switching. By working at night, developers can avoid as many distractions as possible. Without the constant barrage of interruptions, they can spend a few solid hours focusing on the task at hand and be as productive as possible. + +### The peaceful quiet + +With the background noise of various activities (e.g., office chatter, traffic on the street) mostly absent at night or in the early hours, many programmers experience a sense of relaxation. This allows them to be more creative and productive—especially when tackling mentally stimulating tasks such as coding. + +The solitude and peacefulness, plus knowing that they'll have a few uninterrupted hours, often take the stress and time pressure associated with a daytime work schedule off their shoulders, allowing them to produce higher quality work. + +Not to mention, there's nothing like indulging in your favorite midnight snacks when you have solved a thorny problem! + +### Communication + +Developers working on open source projects can have a different communication cadence than a programmer working in-house at a company. Most open source communication is done asynchronously through channels like mailing lists or GitHub comments. A lot of times, other programmers are in different countries and time zones, so communicating in real-time often requires developers to be night owls. + +### The sleepy brain + +This may sound counterintuitive, but as the day wears on, the brain gets tired enough so it can only focus on a single task. This essentially eliminates multitasking, which is a major hurdle to staying focused and productive. But with a sleepy brain, you can't afford not to stay focused! + +Also, many developers often make the most significant progress when they go to sleep thinking about the problem they're trying to solve. The subconscious mind goes to work, and the answers often come to them in the early hours when they're still half asleep. + +This is not surprising since [sleep boosts brain functions][5], helping us make sense of new information and think more creatively. When the solutions present themselves in the wee hours, these developers just get up and hit the ground running without missing a beat. + +### Flexible and creative thinking + +Many programmers experience an upswing in creativity at night. The prefrontal cortex, the part of the brain associated with the ability to concentrate, gets tired at the end of the day. This seems to clear the way for more flexible and creative thinking for some people. + +According to [Brant Hasler][6], assistant professor of psychiatry at the University of Pittsburgh School of Medicine, "with less of that top-down control and 'cognitive inhibition,' the brain might be freed up for more divergent thinking, allowing one to make new associations between different concepts more easily." Combined with the positive mood made possible by a more relaxed environment, developers can come up with innovative ideas more easily. + +Also, without distractions and having the space to concentrate for several hours, you can "get in the zone." This helps you better focus on a project and get in the flow without worrying about things happening around you. + +### Bright computer screens + +The sleep cycle of many programmers is delayed because they look at bright screens all day. The blue light from computer screens [disrupts our circadian rhythm][7] by delaying the release of sleep-inducing melatonin, increasing alertness, and resetting the body's internal clock to a later schedule. As a result, developers tend to go to bed later and later. + +### Influence from the past + +In the past, most developers worked at night out of necessity because shared servers didn't have the computing power to support programming work while everyone else in the company is using the servers during the day. Developers needed to wait until late at night to perform tasks that weren't feasible during the day, such as testing projects, running extensive code-compile-run-debug cycles, and deploying new codes. Even though servers are more powerful now and most can support the demand, the trend to work at night continues as part of the culture. + +### Final thoughts + +While there are many reasons why developers prefer to work at night, keep in mind that being a night owl doesn't mean you should skimp on sleep. Lack of sleep leads to stress and anxiety and, ultimately, burnout. + +Getting enough quality sleep is the key to maintaining good physical health and brain functions. For example, it helps you integrate new information, cement memories, think creatively, remove accumulated toxins, regulate your appetite, and prevent premature aging. + +No matter what your schedule is, make sure to give your brain the rest it needs so you can be on your game and as productive as possible—all day, every day! + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/why-developers-code-night + +作者:[Matt Shealy][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/mshealy +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_code_programming_laptop.jpg?itok=ormv35tV (Person programming on a laptop on a building) +[2]: https://opensource.com/article/19/11/burnout-open-source-communities +[3]: http://www.paulgraham.com/makersschedule.html +[4]: https://www.chamberofcommerce.com/business-advice/software-development-trends-overtaking-the-market +[5]: https://amerisleep.com/blog/sleep-impacts-brain-health/ +[6]: https://www.vice.com/en_us/article/mb58a8/late-night-creativity-spike +[7]: https://www.sleepfoundation.org/articles/how-blue-light-affects-kids-sleep diff --git a/sources/tech/20200214 Digging up IP addresses with the Linux dig command.md b/sources/tech/20200214 Digging up IP addresses with the Linux dig command.md new file mode 100644 index 0000000000..1a941f9ff8 --- /dev/null +++ b/sources/tech/20200214 Digging up IP addresses with the Linux dig command.md @@ -0,0 +1,200 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Digging up IP addresses with the Linux dig command) +[#]: via: (https://www.networkworld.com/article/3527430/digging-up-ip-addresses-with-the-dig-command.html) +[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/) + +Digging up IP addresses with the Linux dig command +====== +The dig command is extremely versatile both for retrieving information from domain name servers and for troubleshooting. +Thinkstock + +Not unlike **nslookup** in function, but with a lot more options, the **dig** command provides information that name servers manage and can be very useful for troubleshooting problems. It’s both simple to use and has lots of useful options. + +The name “dig” stands for “domain information groper” since domain groping is basically what it does. The amount of information that it provides depends on a series of options that you can use to tailor its output to your needs. Dig can provide a lot of detail or be surprisingly terse. + +[[Get regularly scheduled insights by signing up for Network World newsletters.]][1] + +### Just the IP, please + +To get _just_ the IP address for a system, add the **+short** option to your dig command like this: + +``` +$ dig facebook.com +short +31.13.66.35 +``` + +Don't be surprised, however, if some domains are tied to multiple IP addresses to make the sites they support more reliable. + +``` +$ dig networkworld.com +short +151.101.2.165 +151.101.66.165 +151.101.130.165 +151.101.194.165 +``` + +Also, don't be surprised if the order of the IP addresses changes from one query to the next. This is a side effect of load balancing. + +``` +$ dig networkworld.com +short +151.101.130.165 +151.101.194.165 +151.101.2.165 +151.101.66.165 +``` + +### Standard dig output + +The standard dig display provides details on dig itself along with the response from the name server. + +``` +$ dig networkworld.com + +; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>*gt; networkworld.com +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39932 +;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 65494 +;; QUESTION SECTION: +;networkworld.com. IN A + +;; ANSWER SECTION: +networkworld.com. 300 IN A 151.101.194.165 +networkworld.com. 300 IN A 151.101.130.165 +networkworld.com. 300 IN A 151.101.66.165 +networkworld.com. 300 IN A 151.101.2.165 + +;; Query time: 108 msec +;; SERVER: 127.0.0.53#53(127.0.0.53) +;; WHEN: Thu Feb 13 13:49:53 EST 2020 +;; MSG SIZE rcvd: 109 +``` + +Since name servers generally cache collected data for a while, the query time shown at the bottom of dig output might sometimes might say "0 msec": + +[][2] + +``` +;; Query time: 0 msec <== +;; SERVER: 127.0.0.53#53(127.0.0.53) +;; WHEN: Thu Feb 13 15:30:09 EST 2020 +;; MSG SIZE rcvd: 109 +``` + +### Who you gonna ask? + +By default, dig will refer to your **/etc/resolv.conf** file to determine what name server to query, but you can refer queries to other DNS servers by adding an **@** option. + +In the example below, for example, the query is being sent to Google's name server (i.e., 8.8.8.8). + +``` +$ dig @8.8.8.8 networkworld.com + +; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>> @8.8.8.8 networkworld.com +; (1 server found) +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21163 +;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 512 +;; QUESTION SECTION: +;networkworld.com. IN A + +;; ANSWER SECTION: +networkworld.com. 299 IN A 151.101.130.165 +networkworld.com. 299 IN A 151.101.66.165 +networkworld.com. 299 IN A 151.101.194.165 +networkworld.com. 299 IN A 151.101.2.165 + +;; Query time: 48 msec +;; SERVER: 8.8.8.8#53(8.8.8.8) +;; WHEN: Thu Feb 13 14:26:14 EST 2020 +;; MSG SIZE rcvd: 109 +``` + +To determine what version of dig you’re using, use the **-v** option. You should see something like this: + +``` +$ dig -v +DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu +``` + +or this: + +``` +$ dig -v +DiG 9.11.4-P2-RedHat-9.11.4-22.P2.el8 +``` + +To get just the answer portion of this response, you can omit name server details, but still get the answer you're looking for by using both a **+noall** (don't show everything) and a **+answer** (but show the answer section) like this: + +``` +$ dig networkworld.com +noall +answer + +; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>> networkworld.com +noall +answer +;; global options: +cmd +networkworld.com. 300 IN A 151.101.194.165 +networkworld.com. 300 IN A 151.101.130.165 +networkworld.com. 300 IN A 151.101.66.165 +networkworld.com. 300 IN A 151.101.2.165 +``` + +### Looking up a batch of systems + +If you want to dig for a series of domain names, you can list the domain names in a file and then use a command like this one to have dig run through the list and provide the information. + +``` +$ dig +noall +answer -f domains +networkworld.com. 300 IN A 151.101.66.165 +networkworld.com. 300 IN A 151.101.2.165 +networkworld.com. 300 IN A 151.101.130.165 +networkworld.com. 300 IN A 151.101.194.165 +world.std.com. 77972 IN A 192.74.137.5 +uushenandoah.org. 1982 IN A 162.241.24.209 +amazon.com. 18 IN A 176.32.103.205 +amazon.com. 18 IN A 176.32.98.166 +amazon.com. 18 IN A 205.251.242.103 +``` + +You could add +short to the command above but, with some sites having multiple IP addresses, this might not be very useful. To cut down on the detail but be sure that you can tell which IP belongs to which domain, you could instead pass the output to **awk** to display just the first and last columns of data: + +``` +$ dig +noall +answer -f domains | awk '{print $1,$NF}' +networkworld.com. 151.101.66.165 +networkworld.com. 151.101.130.165 +networkworld.com. 151.101.194.165 +networkworld.com. 151.101.2.165 +world.std.com. 192.74.137.5 +amazon.com. 176.32.98.166 +amazon.com. 205.251.242.103 +amazon.com. 176.32.103.205 +``` + +Join the Network World communities on [Facebook][3] and [LinkedIn][4] to comment on topics that are top of mind. + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3527430/digging-up-ip-addresses-with-the-dig-command.html + +作者:[Sandra Henry-Stocker][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[b]: https://github.com/lujun9972 +[1]: https://www.networkworld.com/newsletters/signup.html +[2]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE21620&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage) +[3]: https://www.facebook.com/NetworkWorld/ +[4]: https://www.linkedin.com/company/network-world diff --git a/sources/tech/20200214 How to restore a single-core computer with Linux.md b/sources/tech/20200214 How to restore a single-core computer with Linux.md new file mode 100644 index 0000000000..a88a2c157d --- /dev/null +++ b/sources/tech/20200214 How to restore a single-core computer with Linux.md @@ -0,0 +1,270 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How to restore a single-core computer with Linux) +[#]: via: (https://opensource.com/article/20/2/restore-old-computer-linux) +[#]: author: (Howard Fosdick https://opensource.com/users/howtech) + +How to restore a single-core computer with Linux +====== +Let's have some geeky fun refurbishing your prehistoric Pentium with +Linux and open source. +![Two animated computers waving one missing an arm][1] + +In a [previous article][2], I explained how I refurbish old dual-core computers ranging from roughly five to 15 years old. Properly restored, these machines can host a fully capable lightweight Linux distribution like [Mint/Xfce][3], [Xubuntu][4], or [Lubuntu][5] and perform everyday tasks. But what if you have a really old computer gathering dust in your attic or basement? Like a Pentium 4 desktop or Pentium M laptop? Yikes! Can you even do anything with a relic like that? + +### Why restore a relic? + +For starters, you might learn a bit about hardware and open source software by refurbishing it. And you could have some fun along the way. Whether you can make much use of it depends on your expectations. + +A single-core computer can perform well for a specific purpose. For example, my friend created a dandy retro gaming box (like I describe below) that runs hundreds of Linux and old Windows and DOS games. His kids love it! + +Another friend uses his Pentium 4 for running design spreadsheets in his workshop. He finds it convenient to have a dedicated machine tucked into a corner of his shop. He likes that he doesn't have to worry about heat or dust ruining an expensive modern computer. + +My romance author acquaintance employs her Pentium M as a "novelist's workstation" lodged in her cozy attic hideaway. The laptop functions as her private word processor. + +I've used old computers to teach beginners how to build and repair hardware. Old equipment makes the best testbed because it's expendable. If someone makes a mistake and fries a board, it doesn't much matter. (Contrast this to how you would feel if you wrecked your main computer!) + +The web suggests many [other potential uses][6] for old Pentiums: security cam monitors, network-attached storage (NAS) servers, [SETI][7] boxes, torrent servers, anonymous [Tails][8] servers, Bitcoin miners, programming workstations, thin clients, terminal emulators, routers, file servers, and more. To me, many of these applications sound more like fun projects than practical uses for single-core computers. That doesn't mean they aren't worth your while; it's just that you want to be clear-eyed about any project you take on. + +By current standards, P-4s and Ms are terribly [weak processors][9]. For example, using them for web surfing is problematic because webpage size and programming complexity have [grown exponentially][10]. And the open web is closing—increasingly, sites won't allow you access unless you let them run all those ads that can overwhelm old processors. (I'll discuss web surfing performance tricks later in this article.) Another shortcoming of old computers is their energy consumption. Better electricity-to-performance ratios often make newer computers more sensible. This especially true when a [tablet or smartphone][11] can fulfill your needs. + +Nevertheless, you can still have fun and learn a lot by tinkering with an old P-4 or M. They're great educational tools, they're expendable, and they can be useful in dedicated roles. Best of all, you can get them for free. I'll tell you how. + +Still reading? Okay, let's have some geeky fun refurbishing your prehistoric Pentium. + +### Understand hardware evolution + +As a quick level-set, here are the common names for the P-4 and M class processors and their rough dates of manufacture: + +**Desktops (2000-2008)** + + * Pentium 4 + * Pentium 4 HT (Hyper-Threading) + * Pentium 4 EE (Extreme Edition) + + + +**Desktops (2005-2008)** + + * Pentium D (early dual-core) + + + +**Mobile (2002-2008)** + + * Pentium M + * Pentium 4-M + * Mobile Pentium 4 + * Mobile Pentium 4 HT + + + +Sources: Wikipedia (for the [P-4][12], [P-M][13], and [processor][14] lists), [CPU World,][15] [Revolvy][16]. + +Machines hosting these processors typically use either DDR2 or DDR memory. Dual-core processors entered the market in 2005 and displaced single-core CPUs within a few years. I'll assume you have some version of what's in the above table. Or you might have an equivalent [AMD][17] or [Celeron][18] processor from the same era. + +The big draw of this old hardware is that you can get it for free. People consider it junk. They'll be only too glad to give you their castoffs. If you don't have a machine on hand, just ask your friends or family. Or drop by the local recycling center. Unless they have strict rules, they'll be happy to give you this old equipment. You can even advertise on [Craigslist][19], [Freecycle,][20] or [other reuse websites][21]. + +**A quick tip:** Grab more than one machine. With old hardware, you often need to cannibalize parts from several computers to build one good working one. + +### Prepare the hardware + +Before you can use your old computer, you must refurbish it. The steps to fixing it up are: + + 1. Clean it + 2. Identify what hardware you have + 3. Verify the hardware works + + + +Start by opening up the box and cleaning out the dirt. Dust causes the heat that kills electronics. A can of compressed air helps. + +Always keep yourself grounded when touching things so that you don't harm the electronics. And don't rub anything with a cleaning rag! Even a shock you can't feel can damage computer circuitry. + +While you've got the box open, learn everything you can about your hardware. Write it all down, so you remember it later: + + * Count the open memory slots, if any. Is the RAM DDR or DDR2 (or something else)? + * Read the hard drive label to learn its capacity and age. (It'll probably be an old IDE drive. You can identify IDE drives by their wide connector ribbons.) + * Check the optical drive label to see what kinds of discs it reads and/or writes, at what speed, and to what standard(s). + * Note other peripherals, add-in cards, or anything unusual. + + + +Close and boot the machine into its boot-time [BIOS][22] panels. [This list][23] tells you what program function (PF) key to press to access those startup panels for your specific computer. Now you can complete your hardware identification by rounding out the details on your processor, memory, video memory, and more. + +### Verify the hardware + +Once you know what you've got, verify that it all works. Test: + + * Memory + * Disk + * Motherboard + * Peripherals (optical drive, USB ports, sound, etc.) + + + +Run any diagnostic tests in the computer's boot or BIOS panels. Free resource kits like [Hiren's BootCD][24] or the [Ultimate Boot CD][25] can round out your testing with any diagnostics your boot panels lack. These kits offer dozens of testing programs: all are free, but not all are open source. You can boot them off a live USB or DVD so that you don't have to install anything on the computer. + +Be sure to run the "extended" or long tests for the memory and disk drive. Run tests overnight if you have to. Do this job right! If you miss a problem now, it could cause you big headaches later. + +If you find a problem, refer to my _[Quick guide to fixing hardware][26]_ to solve common issues. + +### Essential hardware upgrades + +You'll want to make two key hardware upgrades. First, increase memory to the computer's maximum. (You can find the maximum for your computer with a quick web search for its specs.) The practical minimum to run many lightweight Linux distros is 1GB RAM; 2GB or more is ideal. While the maximum allowable memory varies by the machine, the great majority of these computers will upgrade to at least 2GB. + +Second—if the desktop doesn't already have one—add a video card. This offloads graphics processing from the motherboard to the video card and increases the computer's video memory. Bumping up the VRAM from 32 or 64MB to 256GB or more greatly increases the range of applications an old computer can run. Especially if you want to run games. + +Be sure the video card fits your computer's [video slot][27] (AGP, PCI, or PCI-Express) and has the right [cable connector][28] (VGA or DVI). You can issue a couple of [Linux line commands][29] to see how much VRAM your system has, or look in the BIOS boot panels. + +These two simple upgrade hacks—increasing memory and video power—take a marginal machine and make it _way_ more functional. Your goal is to build the most powerful P-4 or M ever. That way, you can squeeze the most performance from this aging design. + +The good news is that with the old computers we're talking about, you can get any parts you need for free. Just cannibalize them from other discarded PC's. + +### Select the software + +Choosing the right software for a P-4 or M is critical. [Don't][30] use an [unsupported][31] Windows version just because it's already on the PC; malware might plague you if you do. A fresh install is mandatory. + +Open source software is the way to go. [Many][32] Linux [distributions][33] are specifically designed for older computers. And with Linux, you can install, move, copy, and clone the operating system and its apps at will. This makes your job easier: You won't run into activation or licensing issues, and it's all free. + +Which distribution should you pick? Assuming you have at least 2GB of memory, start your search by trying a _lightweight distribution_—these feature resource-stingy [desktop environments][34]. Xfce or LXQt are excellent desktop environment choices. Products that [consume more resources][35] or produce fancier graphics—like Unity, GNOME, KDE, MATE, and Cinnamon—won't perform well. + +The lightweight Linux distros I've enjoyed success with are Mint/Xfce, Xubuntu, and Lubuntu. The first two use Xfce while Lubuntu employs LXQt. You can find [many other][36] excellent candidate distros beyond these three choices that I can vouch for. + +Be sure to download the 32-bit versions of the operating systems; 64-bit versions don't make much sense unless a computer has at least 4GB of memory. + +The lightweight Linux distros I've cited offer friendly menus and feature huge software repositories backed by active forums. They'll enable your old computer to do everything it's capable of. However, they won't run on every computer from the P-4 era. If one of these products runs on your computer and you like it, great! You've found your distro. + +If your computer doesn't perform well with these selections, won't boot, or you have less than 2GB of memory, try an _ultralight distribution_. Ultralights reduce resource use by replacing desktop environments with [window managers][37] like Fluxbox, FLWM, IceWM, JWM, or Openbox. Window managers use fewer resources than desktop environments. The trade-off is that they're less flexible. As an example, you may have to dip into code to alter your desktop or taskbar icons. + +My go-to ultralight distro is [Puppy Linux][38]. It comes in several variants that run well on Pentium 4's and M's with only 1GB of memory. Puppy's big draw is that it has versions designed specifically for older computers. This means you'll avoid the hassles you might run into with other distros. For example, Puppy versions run on old CPUs that don't support features like PAE or SSE3. They'll even help you run an older kernel or obsolete bootstrap program if your hardware requires it. + +And Puppy runs _fast_ on limited-resource computers! It optimizes performance by loading the operating system entirely into memory to avoid slow disk access. It bundles a full range of apps that have been carefully selected to use minimal hardware resources. + +Puppy is also user-friendly. Even a naive end user can use its simple menus and attractive desktop. But be advised—it takes expertise to install and configure the product. You might have to spend some time on Puppy's [forum][39] to get oriented. The forum is especially useful because many who post there work with old computers. + +A fun alternative to Puppy is [Tiny Core][40] Linux. With Tiny Core, you install only the software components you want. So you build up your environment from the absolute minimum. This takes time but results in a lean, mean system. Tiny Core is perfect for creating a dedicated server. It's a great learning tool, too, so check out its [free eBook][41]. + +If you want a quick, no-hassles install, you might try [antiX][42]. It's Debian-based, offers a selection of lightweight interfaces, and runs well on machines with only a gigabyte of memory. I've had excellent results installing antiX on a variety of old PCs. + +_**Caution:**_ Many distros casually claim that they run on "old computers" when they really mean that they run on _limited-resource computers_. There's a big difference. Old computers sometimes do not support all the CPU features required by newer operating systems. Avoid problems by selecting a Linux proven to run on your hardware. + +Don't know if a distro will run on your box? Save yourself some time by posting a message on the distro's forum and asking for responses from folks using hardware like yours. You should receive some success stories. If nobody can say they've done what you're trying to do, I'd avoid that product. + +### How to use your refurbished computer + +Will you be happy using your restored PC? It depends on what you expect. + +People who use aging systems learn to leverage minimal resources. For example, they run resource-stingy programs like GNOME Office in place of LibreOffice. They forgo CPU-intense programs like emulators, graphics-heavy apps, video processing, and virtual machine hosting. They focus on one task at a time and don't expect much concurrency. And they know how to manage machine resources proactively. + +Old hardware can perform well in dedicated situations. Earlier, I mentioned my friends who use their old computers for design spreadsheets and as a writer's workbench. And I wrote this article on my personal retro box—a Dell GX280 desktop with a Pentium 4 at 3.2GHz, with 2GB DDR-2 RAM and two 40GB IDE disks, dual-booting Puppy and antiX. + +#### Create a retro game box + +You can also create a fantastic retro game box. First, install an appropriate distro. Then install [Wine][43], a program designed to run Windows software on Linux. Now you'll be able to run nearly all your old Windows XP, ME/98/95, and 3.1 games. [DOSBox][44] supports tons more [free DOS games][45]. And Linux offers over a thousand more. + +I've enjoyed nostalgic fun on a P-4 running antiX and all the old games I remember from years ago. Just be sure you've maxed out system memory and added a good video card for the best results. + +#### Access the web + +The big challenge with old computers is web surfing. [This study][46] claims that average website size has increased 100% over a three-year period, while [this article][47] tells how bloated news sites have become. Videos, animation, images, trackers, ad requests—they all make websites slower than just a few years ago. + +Worse, websites increasingly refuse you access unless you allow them to run their ads. This is a problem because the ads can overwhelm old CPUs. In fact, for most websites, the resources required to run ads and trackers are _way_ greater than that required for the actual website content. + +Here are the performance tricks you need to know if you web surf with an older computer: + + * Run the fastest, lightest browser possible. Chrome, Firefox, and Opera are probably the top mainstream offerings. + * Try alternative [minimalist browsers][48] to see if they can meet your needs: [Dillo][49], [NetSurf][50], [Dooble][51], [Lynx][52], [Links][53], or others. + * Actively manage your browser. + * Don't open many browser tabs. + * Manually start and stop processing in specific tabs. + * Block ads and trackers: + * Offload this chore to your virtual private network (VPN) if at all possible. + * Otherwise, use a browser extension. + * Don't slow down your browser by installing add-ons or extensions beyond the minimum required. + * Disable autoplay for videos and Flash. + * Toggle JavaScript off and on. + * Ensure the browser renders text before graphics. + * Don't run background tasks while web surfing. + * Manually clear cookies to avoid page-access limits on some websites. + * Linux means you don't have to run real-time anti-malware (which consumes a CPU core on many Windows PCs). + + + +Employing some of these tricks, I happily use refurbished dual-core computers for all my web surfing. But with today's internet, I find single-core processors inadequate for anything beyond the occasional web lookup. In other words, they're acceptable for _web access_ but insufficient for _web surfing_. That's just my opinion. Yours may vary depending on your expectations and the nature of your web activity. + +### Enjoy free educational fun + +However you use your refurbished P-4 or M, you'll know a lot more about computer hardware and open source software than when you started. It won't cost you a penny, and you'll have some fun along the way! + +Please share your own refurbishing experiences in the comments. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/restore-old-computer-linux + +作者:[Howard Fosdick][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/howtech +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_other11x_cc.png?itok=I_kCDYj0 (Two animated computers waving one missing an arm) +[2]: http://opensource.com/article/19/7/how-make-old-computer-useful-again +[3]: http://linuxmint.com/ +[4]: https://xubuntu.org/ +[5]: http://lubuntu.me/ +[6]: http://www.google.com/search?q=uses+for+a+pentium+IV +[7]: https://en.wikipedia.org/wiki/Search_for_extraterrestrial_intelligence +[8]: https://en.wikipedia.org/wiki/Tails_(operating_system) +[9]: http://www.cpubenchmark.net/low_end_cpus.html +[10]: http://www.digitaltrends.com/web/internet-is-getting-slower/ +[11]: https://www.forbes.com/sites/christopherhelman/2013/09/07/how-much-energy-does-your-iphone-and-other-devices-use-and-what-to-do-about-it/#ba4918e2f702 +[12]: https://en.wikipedia.org/wiki/Pentium_4 +[13]: https://en.wikipedia.org/wiki/Pentium_M +[14]: https://en.wikipedia.org/wiki/List_of_Intel_Pentium_4_microprocessors +[15]: http://www.cpu-world.com/CPUs/Pentium_4/index.html +[16]: https://www.revolvy.com/page/List-of-Intel-Pentium-4-microprocessors?cr=1 +[17]: https://en.wikipedia.org/wiki/List_of_AMD_microprocessors +[18]: https://en.wikipedia.org/wiki/Celeron +[19]: https://www.craigslist.org/about/sites +[20]: https://www.freecycle.org/ +[21]: https://alternativeto.net/software/freecycle/ +[22]: http://en.wikipedia.org/wiki/BIOS +[23]: http://www.disk-image.com/faq-bootmenu.htm +[24]: http://www.hirensbootcd.org/download/ +[25]: http://www.ultimatebootcd.com/ +[26]: http://www.rexxinfo.org/Quick_Guide/Quick_Guide_To_Fixing_Computer_Hardware +[27]: http://www.playtool.com/pages/vidslots/slots.html +[28]: https://silentpc.com/articles/video-connectors +[29]: https://www.cyberciti.biz/faq/howto-find-linux-vga-video-card-ram/ +[30]: https://fusetg.com/dangers-running-unsupported-operating-system/ +[31]: http://home.bt.com/tech-gadgets/computing/windows-7/windows-7-support-end-11364081315419 +[32]: https://itsfoss.com/lightweight-linux-beginners/ +[33]: https://fossbytes.com/best-lightweight-linux-distros/ +[34]: https://en.wikipedia.org/wiki/Desktop_environment +[35]: http://www.phoronix.com/scan.php?page=article&item=ubu-1704-desktops&num=3 +[36]: https://www.google.com/search?ei=TfIoXtG5OYmytAbl04z4Cw&q=best+lightweight+linux+distros+for+old+computers&oq=best+lightweight+linux+distros+for+old&gs_l=psy-ab.1.0.0i22i30l8j0i333.6806.8527..10541...2.2..0.159.1119.2j8......0....1..gws-wiz.......0i71j0.a6LTmaIXan0 +[37]: https://en.wikipedia.org/wiki/X_window_manager +[38]: http://puppylinux.com/ +[39]: http://murga-linux.com/puppy/ +[40]: http://tinycorelinux.net/ +[41]: http://tinycorelinux.net/book.html +[42]: http://antixlinux.com/ +[43]: https://www.winehq.org/ +[44]: https://en.wikipedia.org/wiki/DOSBox +[45]: https://www.dosgamesarchive.com/ +[46]: https://www.digitaltrends.com/web/internet-is-getting-slower/ +[47]: https://www.forbes.com/sites/kalevleetaru/2016/02/06/why-the-web-is-so-slow-and-what-it-tells-us-about-the-future-of-online-journalism/#34475c2072f4 +[48]: http://en.wikipedia.org/wiki/Comparison_of_lightweight_web_browsers +[49]: http://www.dillo.org/ +[50]: http://www.netsurf-browser.org/ +[51]: http://textbrowser.github.io/dooble/ +[52]: http://lynx.browser.org/ +[53]: http://en.wikipedia.org/wiki/Links_%28web_browser%29 diff --git a/sources/tech/20200214 How to set up your own fast, private open source mesh network.md b/sources/tech/20200214 How to set up your own fast, private open source mesh network.md new file mode 100644 index 0000000000..b68b57da3d --- /dev/null +++ b/sources/tech/20200214 How to set up your own fast, private open source mesh network.md @@ -0,0 +1,110 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How to set up your own fast, private open source mesh network) +[#]: via: (https://opensource.com/article/20/2/mesh-network-freemesh) +[#]: author: (Spencer Thomason https://opensource.com/users/spencerthomason) + +How to set up your own fast, private open source mesh network +====== +FreeMesh is an affordable, performant, privacy-respecting mesh system +that installs in less than 10 minutes. +![people on top of a connected globe][1] + +The [FreeMesh][2] system promises to bring fully open source mesh networking to the masses. I recently had a chance to test it; it installed quickly, and the performance was great—especially for the price. + +### Why mesh and open source? + +The reason to use open source is simple: privacy. With FreeMesh, your data is your own. It doesn't track or collect data. Don't trust it? You can easily check—it's open source, after all! With some other popular mesh solutions, say those provided by very large tech conglomerates, would you trust them with your data? + +Another important factor: updates. FreeMesh says it is committed to pushing out security and performance updates regularly. What about 10 years from now? With an open source solution, you are free to update the product for as long as you want. + +So why mesh? In a mesh network, multiple wireless routers work together to broadcast a single, very large wireless network. Each router in a mesh network intelligently communicates with the other(s) to provide the best "path" for your data. The following images from FreeMesh's website highlight the difference between using a single wireless router and a mesh network. The red network represents a single wireless router, and the green is a mesh network. + +![Single-router network][3] | ![Mesh network][4] +---|--- + +### Get the equipment + +To get started with FreeMesh, [order a kit][5]. Two kits are available: standard and 4G LTE. + +The 4G LTE kit, as the name suggests, supports cellular data connections. This feature is a rarity in the consumer networking space, and it will be _very_ useful to some folks. You can set up a portable mesh network anywhere with power and cell service with full fast-failover capability. + +The FreeMesh kits come with a primary router and two nodes. The router and nodes use 802.11ac, 802.11r, and 802.11s standards. The included firmware runs a customized version of [OpenWrt][6], a Linux distro for embedded devices. + +The FreeMesh router has some really good specs: + + * **CPU:** Dual-core 880MHz MediaTek MT7621AT (two cores/four threads!) + * **RAM:** DDR3 512MB + * **Interfaces:** 1x GbE WAN, 4x GbE LAN, 1x USB 2.0 ports, 1x microSD card slot, 1x SIM slot + * **Antenna:** 2x 5dBi 2.4GHz, 2x 5dBi 5GHz, 2x 3dBi 3G/4G (built-in) + * **4G LTE modem:** LTE category 4 module, 150Mbps downlink and 50Mbps uplink + + + +### Setup + +Setup is easy, and FreeMesh's [README][7] offers simple instructions and diagrams. Start by setting up the primary router first. Then follow these simple steps: + + 1. Connect the first node (blue WAN port) to the primary router (yellow LAN port). +![FreeMesh setup step 1][8] + 2. Wait about 30 to 60 seconds. The node will flash its LEDs when the setup is complete. +![FreeMesh setup step 2][9] + 3. Move the node to another location. + + + +That's it! There is no manual setup required for the nodes; you simply plug them into the primary router, and it does the rest. You can add more nodes the same way; just repeat the steps above. + +### Features + +Out of the box, FreeMesh runs a combination of OpenWRT and LuCI. It has all the features you'd expect from a router. Want to install new features or packages? SSH in and start hacking! + +![Real-time load on FreeMesh network][10] + +![Overview of FreeMesh network][11] + +![OpenWrt status report][12] + +### Performance + +After setting up the FreeMesh system, I moved the nodes to various places around my house. I used [iPerf][13] to test the bandwidth and was getting around 150Mbps. WiFi can be affected by any number of environmental variables, so your mileage may vary. Distance between the nodes and the primary router also plays a large factor in bandwidth. + +However, the real advantage of a mesh network isn't its top-end speed but much better average speed across a space. Even at the far reaches of my home, I was still able to stream videos and work without interruption. I was even able to work in my backyard. I simply repositioned one of the nodes in front of a window before heading outside. + +### Conclusion + +FreeMesh is really compelling; it offers performance, privacy, and price, all in a simple, open source package. + +In my experience, setup is a breeze, and it is more than fast enough. The range is excellent and far exceeds any single-router setup. You are free to hack and customize your FreeMesh setup, but I didn't feel the need to. It has everything I need out of the box. + +If you are looking for an affordable, performant, privacy-respecting mesh system that installs in less than 10 minutes, you might want to consider FreeMesh. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/mesh-network-freemesh + +作者:[Spencer Thomason][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/spencerthomason +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-networking.png?itok=fHmulI9p (people on top of a connected globe) +[2]: https://freemeshwireless.com/ +[3]: https://opensource.com/sites/default/files/uploads/singlerouternetwork.png (Single-router network) +[4]: https://opensource.com/sites/default/files/uploads/meshnetwork.png (Mesh network) +[5]: https://freemeshwireless.com/#pricing +[6]: https://openwrt.org/ +[7]: https://gitlab.com/slthomason/freemesh/-/blob/master/README.md +[8]: https://opensource.com/sites/default/files/uploads/connecttorouter.png (FreeMesh setup step 1) +[9]: https://opensource.com/sites/default/files/uploads/setupcomplete.png (FreeMesh setup step 2) +[10]: https://opensource.com/sites/default/files/uploads/freemeshrealtimeload.png (Real-time load on FreeMesh network) +[11]: https://opensource.com/sites/default/files/uploads/freemeshwirelessoverview.png (Overview of FreeMesh network) +[12]: https://opensource.com/sites/default/files/uploads/openwrt.png (OpenWrt status report) +[13]: https://opensource.com/article/20/1/internet-speed-tests diff --git a/sources/tech/20200214 PHP Development on Fedora with Eclipse.md b/sources/tech/20200214 PHP Development on Fedora with Eclipse.md new file mode 100644 index 0000000000..a682381686 --- /dev/null +++ b/sources/tech/20200214 PHP Development on Fedora with Eclipse.md @@ -0,0 +1,89 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (PHP Development on Fedora with Eclipse) +[#]: via: (https://fedoramagazine.org/php-development-on-fedora-with-eclipse/) +[#]: author: (Mehdi Haghgoo https://fedoramagazine.org/author/powergame/) + +PHP Development on Fedora with Eclipse +====== + +![][1] + +[Eclipse][2] is a full-featured free and open source IDE developed by the Eclipse Foundation. It has been around since 2001. You can write anything from C/C++ and Java to PHP, Python, HTML, JavaScript, Kotlin, and more in this IDE. + +### Installation + +The software is available from Fedora’s official repository. To install it, invoke: + +``` +sudo dnf install eclipse +``` + +This will install the base IDE and Eclipse platform, which enables you to develop Java applications. In order to add PHP development support to the IDE, run this command: + +``` +sudo dnf install eclipse-pdt +``` + +This will install PHP development tools like PHP project wizard, PHP server configurations, composer support, etc. + +### Features + +This IDE has many features that make PHP development easier. For example, it has a comprehensive project wizard (where you can configure many options for your new projects). It also has built-in features like composer support, debugging support, a browser,a terminal, and more. + +### Sample project + +Now that the IDE is installed, let’s create a simple PHP project. Go to _File →New → Project_. From the resulting dialog, select _PHP project_. Enter a name for your project. There are some other options you might want to change, like changing the project’s default location, enabling JavaScript, and changing PHP version. See the following screenshot. + +![Create A New PHP Project in Eclipse][3] + +You can click the _Finish_ button to create the project or press _Next_ to configure other options like adding include and build paths. You don’t need to change those in most cases. + +Once the project is created, right click on the project folder and select _New → PHP File_ to add a new PHP file to the project. For this tutorial I named it _index.php_, the conventionally-recognized default file in every PHP project. + +![][4] + +Then add the your code to the new file. + +![Demo PHP code][5] + +In the example above, I used CSS, JavaScript, and PHP tags on the same page mainly to show that the IDE is capable of supporting all of them together. + +Once your page is ready, you can see the result output by moving the file to your web server document root or by creating a development PHP server in the project directory. + +Thanks to the built-in terminal in Eclipse, we can launch a PHP development server right from within the IDE. Simply click the terminal icon on the toolbar (![Terminal Icon][6]) and click _OK_. In the new terminal, change to the project directory and run the following command: + +``` +php -S localhost:8080 -t . index.php +``` + +![Terminal output][7] + +Now, open a browser and head over to . If everything has been done correctly per instructions and your code is error-free, you will see the output of your PHP script in the browser. + +![PHP output in Fedora][8] + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/php-development-on-fedora-with-eclipse/ + +作者:[Mehdi Haghgoo][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://fedoramagazine.org/author/powergame/ +[b]: https://github.com/lujun9972 +[1]: https://fedoramagazine.org/wp-content/uploads/2020/02/php-eclipse-816x346.png +[2]: https://projects.eclipse.org/projects/eclipse +[3]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-01-58-39.png +[4]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-02-02-05-1024x576.png +[5]: https://fedoramagazine.org/wp-content/uploads/2020/02/code-1024x916.png +[6]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-03-50-05.png +[7]: https://fedoramagazine.org/wp-content/uploads/2020/02/terminal-1024x239.png +[8]: https://fedoramagazine.org/wp-content/uploads/2020/02/output.png diff --git a/translated/tech/20190729 How to structure a multi-file C program- Part 1.md b/translated/tech/20190729 How to structure a multi-file C program- Part 1.md new file mode 100644 index 0000000000..92166f2895 --- /dev/null +++ b/translated/tech/20190729 How to structure a multi-file C program- Part 1.md @@ -0,0 +1,189 @@ +[#]: collector: (lujun9972) +[#]: translator: (mengxinayan) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How to structure a multi-file C program: Part 1) +[#]: via: (https://opensource.com/article/19/7/structure-multi-file-c-part-1) +[#]: author: (Erik O'Shaughnessy https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions) + +如何组织构建多文件 C 语言程序:第一部分 +====== + +准备好你喜欢的饮料,编辑器和编译器,放一些音乐,然后开始构建一个由多个文件组成的 C 语言程序。 +![Programming keyboard.][1] + +大家常说计算机编程的艺术是管理复杂性和命名某些事物中的一部分。此外,我认为“有时需要添加绘图”是很正确的。 + +在这篇文章里,我会在编写一个小型 C 程序时命名一些东西同时管理一些复杂性。程序的结构基于我所在 “[如何写一个好的 C 语言 main 函数][2]” 文中讨论的。但是,这次做一些不同的事。准备好你喜欢的饮料,编辑器和编译器,放一些音乐,让我们一起编写一个有趣的 C 语言程序。 + +### 好的 Unix 程序中的哲学 + +首先你要知道这个 C 程序是一个 [Unix][3] 命令行工具。这意味着它运行在那些提供(或者可被移植) Unix C 运行环境的操作系统中。当 Unix 在贝尔实验室被发明后,它从一开始便充满了 [设计哲学][4]。用我的话来说:程序只做一件事,并做好它,然后对文件进行一些操作。虽然只做一件事并做好它是有意义的,但是“对文件进行一些操作”在这儿有一点儿不合适。 + +“文件” 在 Unix 中的抽象非常强大。一个 Unix 文件是以 end-of-file (EOF) 标志为结尾的字节流。文件中其他结构均由应用添加而非操作系统。操作系统提供了系统调用,使得程序能够对文件执行标准操作:打开,读取,写入,寻找和关闭(还有其他,但那是庞大的额外内容)。对于文件的标准化访问使得不同人用不同语言编写的程序能共用相同的抽象同时一起工作。 + +具有共享文件接口可以构建 _可组合的_ 的程序。一个程序的输出可以作为另一个程序的输入。Unix 系操作系统默认为每个运行中程序提供了三个文件:标准输入(`stdin`),标准输出(`stdout`),和标准错误(`stderr`)。其中两个文件是只写的:`stdout` 和 `stderr`。而 `stdin` 是只读的。当我们在常见的 Shell 比如 Bash 中使用文件重定向时,可以看到其效果。 + +``` +`$ ls | grep foo | sed -e 's/bar/baz/g' > ack` +``` + +这条指令可以被简要地描述为:`ls` 的结果被写入标准输出,它重定向到 `grep` 的标准输入,`grep` 的标准输出重定向到 `sed`的标准输入,`sed` 的标准输出重定向到当前目录下文件名为 `ack` 的文件中。 + +我们希望我们的程序在系统中灵活而又出色,因此让我们编写一个可以读写文件的程序。 + +### MeowMeow: 流编码器/解码器概念 + +当我还是一个孩子在 ltmumblesgts 里学习计算机科学时,有许多编码方案。他们中的有些用于压缩文件,有些用于打包文件,另一些毫无用处因此显得十分愚蠢。列举一个最后一种情况例子:[MooMoo 编码方式][5]。 + +为了给我们程序一个目的,我将在 [2000s][6] 更新该概念并且完成一个名为 “MeowMeow” 的编码方式(因为在互联网上大家都喜欢猫)。这里的基本的想法获取文件并且使用文本 “meow” 对每半个字节进行编码。小写字母代表 0,大写字母代表 1。因为它会将 4 比特替换为 32 比特,因此会扩大文件的大小。这毫无实际意义。但想象一下人们看到经过这样编码后的结果。 + +``` +$ cat /home/your_sibling/.super_secret_journal_of_my_innermost_thoughts +MeOWmeOWmeowMEoW... +``` + +这非常棒。 + +### 最后完成 + +完整的源代码可以在 [GitHub][7] 上面找到,但是我会写下我在编写程序时的思考。目的是说明如何组织构建多文件 C 语言程序。 + +当我已经确定要编写一个 MeowMeow 编码和解码的程序时,我在 Shell 中执行了以下的命令 : + +``` +$ mkdir meowmeow +$ cd meowmeow +$ git init +$ touch Makefile     # recipes for compiling the program +$ touch main.c       # handles command-line options +$ touch main.h       # "global" constants and definitions +$ touch mmencode.c   # implements encoding a MeowMeow file +$ touch mmencode.h   # describes the encoding API +$ touch mmdecode.c   # implements decoding a MeowMeow file +$ touch mmdecode.h   # describes the decoding API +$ touch table.h      # defines encoding lookup table values +$ touch .gitignore   # names in this file are ignored by git +$ git add . +$ git commit -m "initial commit of empty files" +``` + +简单的说,我创建了一个空文件并且使用 git 提交。 +In short, I created a directory full of empty files and committed them to git. + +即使文件中没有内容,你依旧可以从它的文件名推断功能。为了避免万一你无法理解,我在每条 `touch` 命令后面进行了简单描述。 + +通常,一个程序从一个简单 `main.c` 文件开始,只需要两三个函数便可以解决问题。然后程序员便可以向自己的朋友或者老板展示该程序,同时突然显示了文件提示框支持所有新的“功能”和“需求”。“程序俱乐部”的第一条规则便是不谈论“程序俱乐部”。第二条规则是最小化单个文件的功能。 + +坦率地说,C 编译器并不关心程序中的所有函数是否都在一个文件中。但是我们并不是为计算机或编译器写程序,我们是为其他人(有时也包括我们)而去写程序的。我知道这有些奇怪,但这就是事实。程序是计算机解决问题所采用的一系列算法,保证人们可以理解它们是非常重要的,即使问题的参数发生了意料之外的变化。当在人们修改程序时,发现一个文件中有 2049 函数时会诅咒你的。 + +因此,好的程序员会将函数分隔开,将相似的函数分组到不同的文件中。这里我用了三个文件 `main.c`,`mmencode.c` 和 `mmdecode.c`。对于这样的小程序,也许看起来有些过头了。但是小程序很难保证一直小下去,因此计划拓展是一个好主意。 + +但是那些 `.h` 文件呢?我会在后面解释一般的术语,简单地说,它们被称为头文件,同时它们可以包含 C 语言类型 和 C 预处理指令。头文件中不应该包含任何函数。你可以认为头文件和对应 `.c` 文件提供了用户编程接口(API)的定义,以便其他 `.c` 文件使用。 + +### 但是 Makefile 是什么呢? + +我知道所有的酷小孩都使用 “Ultra CodeShredder 3000” 集成开发环境来编写下一个轰动一时的应用,同时构建你的项目包括在 Ctrl-Meta-Shift-Alt-Super-B 上进行混搭。但是回到今天,使用 Makefile 文件可以帮助做很多有用的工作在构建 C 程序时。Makefile 是一个包含如何处理文件的方式的文本文件,程序员可以使用其自动地从源代码构建二进制程序(包括其他东西!) + +以下面这个小程序为例: + +``` +00 # Makefile +01 TARGET= my_sweet_program +02 $(TARGET): main.c +03    cc -o my_sweet_program main.c +``` + +‘#’ 符号后面的文本是注释,例如 00 行 + +01 行是一个变量赋值,将 `TARGET` 变量赋值为字符串 `my_sweet_program`。按照惯例我的习惯是,所有 Makefile 变量均使用大写字母并用下划线分隔单词。 + +02 行包含要创建的文件名和其依赖的文件。在本例中,构建目标是 `my_sweet_program`,其依赖是 `main.c`。 + +03 行是最后一行使用了一个制表符号(tab)而不是四个空格。这是将执行创建目标的命令。在本例中,我们使用 C 编译器前端 `cc` 以编译链接到 `my_sweet_program`。 + +使用 Makefile 是非常简单的。 + +``` +$ make +cc -o my_sweet_program main.c +$ ls +Makefile  main.c  my_sweet_program +``` + +将构建我们 MeowMeow 编码和解码器的 [Makefile][8] 比上面的例子要复杂,但其基本结构是相同的。我将在另一篇文章中将其分解为 Barney 风格。 + +### 形式伴随着功能 + +我的想法是程序从一个文件中读取,转换它,并将转换后的结果存储到另一个文件中。以下是我想象使用程序命令行交互时的情况: + +``` +        $ meow < clear.txt > clear.meow +        $ unmeow < clear.meow > meow.tx +        $ diff clear.txt meow.tx +        $ +``` + +我们需要编写命令行解析和处理输入/输出流的代码。我们需要一个函数对流进行编码并将结果写到另一个流中。最后,我们需要一个函数对流进行解码并将结果写到另一个流中。等一下,我们在讨论如何写一个程序,但是在上面的例子中,我调用了两个指令:`meow` 和 `unmeow`?我知道你可能会认为这会导致越变越复杂。 + +### 次要内容:argv[0] 和 ln 指令 + +回想一下,C 语言 main 函数的结构如下: + +``` +`int main(int argc, char *argv[])` +``` + +其中 `argc` 是命令行参数数量,`argv` 是字符指针列表(字符串)。`argv[0]` 是正在运行中的文件的路径。在 Unix 系统中许多互补功能的程序(比如:压缩和解压缩)看起来像两个命令,但事实上,它们在文件系统中是拥有两个名称的一个程序。使用 `ln` 命令通过创建文件系统链接来实现两个名称的功能。 + +一个在我笔记本中 `/usr/bin` 的例子如下: + +``` +   $ ls -li /usr/bin/git* +3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git +3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git-receive-pack +... +``` + +这里 `git` 和 `git-receive-pack` 是同一个文件但是拥有不同的名字。我们说它们是相同的文件因为它们具有相同的 inode 值(第一列)。inode 是一个 Unix 文件系统的特点,其超越了本文的内容。 + +优秀或懒惰的程序可以通过 Unix 文件系统此特点已达到写更少的代码但是交付双倍的程序。首先,我们编写一个基于其 `argv[0]` 的值而作出相应改变的程序,然后我们确保为该行为的名称创建链接。 + +在我们的 Makefile 中,`unmeow` 链接通过以下的方式来创建: + +``` + # Makefile + ... + $(DECODER): $(ENCODER) +         $(LN) -f $< $@ +        ... +``` + +我喜欢在 Makefile 中将所有内容参数化,很少使用 “裸” 字符串。我将所有的定义都放置在 Makefile 文件顶部,以便可以简单地找到并改变它们。当您尝试将程序移植到新的平台上时,需要将 `cc` 改变为 `xcc`时,这会产生很大影响。 + +除了两个内置变量 `$@` 和 `$<` 之外,其余的变量显得很简单的。第一个便是创建目标的快捷方式,在本例中,`$(DECODER)` (我记忆它因为它看起来像一个目标)。第二个,`$<` 是规则依赖项,在本例中,它解析为 `$(ENCODER)`。 + +事情当然在变得复杂,但是它易于管理。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/19/7/structure-multi-file-c-part-1 + +作者:[Erik O'Shaughnessy][a] +选题:[lujun9972][b] +译者:[萌新阿岩](https://github.com/mengxinayan) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_keyboard_coding.png?itok=E0Vvam7A (Programming keyboard.) +[2]: https://opensource.com/article/19/5/how-write-good-c-main-function +[3]: https://en.wikipedia.org/wiki/Unix +[4]: http://harmful.cat-v.org/cat-v/ +[5]: http://www.jabberwocky.com/software/moomooencode.html +[6]: https://giphy.com/gifs/nyan-cat-sIIhZliB2McAo +[7]: https://github.com/JnyJny/meowmeow +[8]: https://github.com/JnyJny/meowmeow/blob/master/Makefile diff --git a/translated/tech/20200112 What I learned going from prison to Python.md b/translated/tech/20200112 What I learned going from prison to Python.md deleted file mode 100644 index 83f78c55aa..0000000000 --- a/translated/tech/20200112 What I learned going from prison to Python.md +++ /dev/null @@ -1,102 +0,0 @@ -[#]: collector: (lujun9972) -[#]: translator: (heguangzhi) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (What I learned going from prison to Python) -[#]: via: (https://opensource.com/article/20/1/prison-to-python) -[#]: author: (Shadeed "Sha" Wallace-Stepter https://opensource.com/users/shastepter) - -我在监狱从 Python 中学到了什么 -====== - -开源编程是如何在入监狱中提供机会的![书架上的编程书籍][1] - -不到一年前,我还在圣昆廷州立监狱服刑,我是无期徒刑。 - -我高三的时候,我抢劫了一个人并向他开了枪。现在,我经过一段时间才意识到并承认自己做错了,这是在经历了陪审团审判并看到我的行为带来的恶果后,我知道需要改变自己,我也确实做到了。尽管我对我的行为表示懊悔,但我毕竟开枪打了一个人,并差点杀了他。做这样的事是有后果的,这是理所当然的。所以在我18岁的时候,我被判了终身监禁。 - -监狱是一个非常可怕的地方;我是也不向你推荐的。但是我必须去,所以我去了。我不告诉你具体的细节,但你可以放心,这是一个不可能有太多想法的的地方,许多人在这里养成的坏习惯比他们过去在别处养成的更多。 - -我是幸运儿。当我在服刑的时候,发生了一些不同的事情。我开始想象自己出狱后的的未来,虽然在这之前,我还是已经度过了我所有的成年生活。 - -现在你想想:我是黑人,只受过高中教育。我没有工作经历,如果我离开监狱,在被释放前,我还是一个被定罪的重罪犯。当每个雇主看到我的简历,都不会有“我需要雇用这个人” -想法,我认为是正常的。 - -我不知道我的选择是什么,但我已经下定决心了。我需要做些活下去的事情,并且这和我入狱前的生活一点也不像。 - -### Python 之路 - -最终,我被关在了圣昆廷州立监狱,我不知道我在那里有多幸运。圣昆廷提供了几个自助教育编程项目。这些[改造机会][2]帮助囚犯使他们拥有在获释后避免再次犯罪的技能。 - -作为其中一个编程项目的一部分,2017年我通过圣昆廷媒体项目认识了[杰西卡·麦凯拉]。杰西卡是编程语言[Pythone][4]的爱好者,她开始向我推荐 Python 有多棒,以及它是刚起步的人学习的完美语言。这就是故事变得比小说更精彩的地方。 - - -> 感谢[@northbaypython][5]让[@ShaStepter][6]和我重复[@pycon][7]的主题演讲,让他们被录制下来。我很荣幸与大家分享: -> -> 从监狱到 Pythone: https://t.co/rcumoAgZHm -> -> 大规模裁员:如果我们不雇佣被判重罪的人,谁会呢? https://t.co/fENDUFdxfX [pic.Twitter.com/kpjo8d3ul6][8] -> -> —杰西卡·麦凯拉(@ jessicamckellar)[2019年11月5日][9] - -杰西卡告诉我一些 Python 视频教程,这些教程是她为一家名叫[O’Reilly Media][10]的公司做的,课程是在线的,如果我能接触到它们,那该有多好呀。不幸的是,在监狱里上网是不可能的。但是,我遇到了一个叫 Tim O’Reilly 的人,他最近刚来到圣昆廷。在他访问之后,Tim 从他的公司 O’Reilly Media 公司向监狱的编程班捐赠了大量内容。最终,我拿到了一款平板电脑,上面有杰西卡的 Python 教程,并学会了如何使用这些Python教程进行编码。 - -真是难以置信。背景和生活与我完全不同的陌生人把这些联系在一起,让我学会了编码。 - - -### 对 Python 社区的热爱 - -在这之后,我开始经常和杰西卡见面,她开始告诉我关于开源社区的情况。从根本上说,开源社区就是关于伙伴关系和协作的社区。因为没有人被排除在外,所以效果很好。 - -对我来说,一个努力寻找我自己的定位的人,我所看到的是一种非常基本的爱——通过合作和接受的爱,通过接触的爱,通过包容的爱。我渴望成为其中的一部分。所以我继续学习Python,不幸的是,我无法获得更多的教程,但是我能够从开源社区编译的大量书面知识中获益。我读过任何提到 Python 的东西,从平装本到晦涩难懂的杂志文章,我使用平板电脑来解决我读到的 Python 问题。 - -我对 Python 和编程的热情不是我的许多同龄人所共有的。除了监狱编程课上的极少数人之外,我认识的其他人都没有提到过编程;一般囚犯都不知道。我认为这是因为有过监禁经历的人无法接触编程,尤其是如果你是有色人种。 -` -### 监狱外的 Python 生活 - -然而,在2018年8月17日,我得到了生命中的惊喜。杰里·布朗州长将我27年的刑期减为无期徒刑,在服刑近19年后,我被释放出狱了。 - -但现实情况是,这也是为什么我认为编程和开源社区如此有价值。我是一名37岁的黑人罪犯,没有工作经历,刚刚在监狱服刑18年。我有犯罪史,并且现存偏见导致没有多少职业适合我。但是编程是少数例外之一。 - -监禁后重返社会的人们迫切需要包容,但当谈话转向工作场所的多样性以及对多样性的需求时,你真的听不到这个群体被提及或包容。 -  - -> 还有什么: -> -> 1\. 背景调查:询问他们在你的公司是如何使用的。 -> -> 2\. 初级角色:删除虚假的、不必要的先决条件,这些条件将排除有记录的合格人员。 -> -> 3\. 积极拓展:与当地再就业项目合作,创建招聘渠道。[11] -> -> —杰西卡·麦凯拉(@ jessicamckellar)[2019年5月12日][12] -  - -因此,我想谦卑地挑战开源社区的所有程序员和成员,让他们围绕包容和多样性展开思考。今天,我自豪地站在你们面前,代表一个大多数人都没有想到的群体——以前被监禁的人。但是我们存在,我们渴望证明我们的价值,最重要的是,我们期待被接受。当我们重返社会时,许多挑战等待着我们,我请求你们允许我们有机会展示我们的价值。欢迎我们,接受我们,最重要的是,包容我们。 - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/20/1/prison-to-python - -作者:[Shadeed "Sha" Wallace-Stepter][a] -选题:[lujun9972][b] -译者:[heguangzhi](https://github.com/heguangzhi) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/shastepter -[b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/books_programming_languages.jpg?itok=KJcdnXM2 (Programming books on a shelf) -[2]: https://www.dailycal.org/2019/02/27/san-quentin-rehabilitation-programs-offer-inmates-education-a-voice/ -[3]: https://twitter.com/jessicamckellar?lang=en -[4]: https://www.python.org/ -[5]: https://twitter.com/northbaypython?ref_src=twsrc%5Etfw -[6]: https://twitter.com/ShaStepter?ref_src=twsrc%5Etfw -[7]: https://twitter.com/pycon?ref_src=twsrc%5Etfw -[8]: https://t.co/Kpjo8d3ul6 -[9]: https://twitter.com/jessicamckellar/status/1191601209917837312?ref_src=twsrc%5Etfw -[10]: http://shop.oreilly.com/product/110000448.do -[11]: https://t.co/WnzdEUTuxr -[12]: https://twitter.com/jessicamckellar/status/1127640222504636416?ref_src=twsrc%5Etfw diff --git a/translated/tech/20200206 3 ways to use PostgreSQL commands.md b/translated/tech/20200206 3 ways to use PostgreSQL commands.md new file mode 100644 index 0000000000..9f5890f370 --- /dev/null +++ b/translated/tech/20200206 3 ways to use PostgreSQL commands.md @@ -0,0 +1,228 @@ +[#]: collector: (lujun9972) +[#]: translator: (Morisun029) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (3 ways to use PostgreSQL commands) +[#]: via: (https://opensource.com/article/20/2/postgresql-commands) +[#]: author: (Greg Pittman https://opensource.com/users/greg-p) + +3种使用 PostgreSQL 命令的方式 +====== +无论你需要的东西简单(如一个购物清单)亦或复杂(如色卡生成器) + PostgreSQL 命令都能使它变得容易起来。 + +![Team checklist and to dos][1] + +在 _[PostgreSQL 入门][2]_ 一文中, 我解释了如何安装,设置和开始使用开源数据库软件。然而,使用 [PostgreSQL][3] 中的命令可以做更多事情。 + +例如,我使用 Postgres 来跟踪我杂货店的购物清单。我杂货店里的大多数购物是在家里进行的,其中每周进行一次大批量的采购。我去几个不同的地方购买清单上的东西,因为每家商店都提供特定的选择或质量,亦或更好的价格。最初,我制作了一个HTML表单页面来管理我的购物清单,但这样无法保存我的输入内容。因此,在想到要购买的物品时我必须要马上列出清单,因为到采购时我常常会忘记一些我需要或想要的东西。 + +相反,使用 PostgreSQL,当我想到需要的物品时,我可以随时输入,并在购物前打印出来。你也可以这样做。 + + +### 创建一个简单的购物清单 + + +首先,数据库中输入**psql ** 命令,然后用下面的命令创建一个表: +``` +`Create table groc (item varchar(20), comment varchar(10));` +``` + +输入如下命令在清单中加入商品: + +``` +insert into groc values ('milk', 'K'); +insert into groc values ('bananas', 'KW'); +``` + +括号中有两个信息(逗号隔开):前面是你需要买的东西,后面字母代表你要购买的地点以及哪些东西是你每周通常都要买的(W)。 + +因为 **psql** 有历史记录,你可以按向上键在括号内编辑信息,而无需输入商品的整行信息。 + +在输入一小部分商品后,输入下面命令来检查前面的输入内容。 + +``` +Select * from groc order by comment; + + item | comment +\----------------+--------- + ground coffee | H + butter | K + chips | K + steak | K + milk | K + bananas | KW + raisin bran | KW + raclette | L + goat cheese | L + onion | P + oranges | P + potatoes | P + spinach | PW + broccoli | PW + asparagus | PW + cucumber | PW + sugarsnap peas | PW + salmon | S +(18 rows) +``` + +此命令按_comment_ 列对结果进行排序,以便按购买地点对商品进行分组,从而是你的购物更加方便。 + +使用W来指明你每周要买的东西,当你要清除表单为下周的列表做准备时,你可以将每周的商品保留在购物清单上。输入: + +``` +`delete from groc where comment not like '%W';` +``` + +注意,在 PostgreSQL 中 **%** 表示通配符(而非星号)。所以,要保存输入内容,需要输入: + +``` +`delete from groc where item like 'goat%';` +``` + +不能使用**item = 'goat%'**,这样没用。 + + +在购物时,用以下命令输出清单并打印出来发送到你的手机: + +``` +\o groclist.txt +select * from groc order by comment; +\o +``` + +最后一个命令**\o*,重置输出到命令行。否则,所有的输出会继续输出到你创建的杂货店购物文件中。 + +### 分析复杂的表 + +This item-by-item entry may be okay for short tables, but what about really big ones? A couple of years ago, I was helping the team at [FreieFarbe.de][4] to create a swatchbook of the free colors (freieFarbe means "free colors" in German) from its HLC color palette, where virtually any imaginable print color can be specified by its hue, luminosity (brightness), and chroma (saturation). The result was the [HLC Color Atlas][5], and here's how we did it. + +逐个输入对于数据量小的表来说没有问题,但是对于数据量大的表呢?几年前,我帮团队从 HLC 调色板中创建一个自由色的色样册。事实上,任何能想象到的打印色都可按色调、亮度、浓度(饱和度)来规定。最终结果是[HLC Color Atlas][5],下面是我们如何实现的。 + +该团队向我发送了具有颜色规范的文件,因此我可以编写可与 Scribus 配合使用的 Python 脚本,以轻松生成色样册。一个例子像这样开始: + + +``` +HLC, C, M, Y, K +H010_L15_C010, 0.5, 49.1, 0.1, 84.5 +H010_L15_C020, 0.0, 79.7, 15.1, 78.9 +H010_L25_C010, 6.1, 38.3, 0.0, 72.5 +H010_L25_C020, 0.0, 61.8, 10.6, 67.9 +H010_L25_C030, 0.0, 79.5, 18.5, 62.7 +H010_L25_C040, 0.4, 94.2, 17.3, 56.5 +H010_L25_C050, 0.0, 100.0, 15.1, 50.6 +H010_L35_C010, 6.1, 32.1, 0.0, 61.8 +H010_L35_C020, 0.0, 51.7, 8.4, 57.5 +H010_L35_C030, 0.0, 68.5, 17.1, 52.5 +H010_L35_C040, 0.0, 81.2, 22.0, 46.2 +H010_L35_C050, 0.0, 91.9, 20.4, 39.3 +H010_L35_C060, 0.1, 100.0, 17.3, 31.5 +H010_L45_C010, 4.3, 27.4, 0.1, 51.3 +``` + +这与原文件相比,稍有修改,将数据用制表符分隔。我将其转换成 CSV 格式(逗号分割值),我更喜欢其与 Python 一起使用(CSV 文也很有用因为它可轻松导入到电子表格程序中)。 + +在每一行中,第一项是颜色名称,其后是其 C,M,Y 和 K 颜色值。 该文件包含1,793种颜色,我想要一种分析信息的方法,以了解这些值的范围。 这就是 PostgreSQL 发挥作用的地方。 我不想手动输入所有数据-我认为输入过程中我不可能不出错。 幸运的是,PostgreSQL 为此提供了一个命令。 + +首先用以下命令创建数据库: + +``` +`Create table hlc_cmyk (color varchar(40), c decimal, m decimal, y decimal, k decimal);` +``` + +然后通过以下命令引入数据: + + +``` +`\copy hlc_cmyk from '/home/gregp/HLC_Atlas_CMYK_SampleData.csv' with (header, format CSV);` +``` + + +开头有反斜杠,是因为使用纯**copy** 命令仅限于 root 用户和 Postgres 的超级用户。 在括号中,**header** 表示第一行包含标题,应忽略,**CSV** 表示文件格式为 CSV。 请注意,在此方法中,颜色名称周围不需要括号。 + +如果操作成功,会看到 **COPY NNNN**,其中 N 表示插入到表中的行号。 + +最后,可以用下列命令查询: + +``` +select * from hlc_cmyk; + + color | c | m | y | k +\---------------+-------+-------+-------+------ + H010_L15_C010 | 0.5 | 49.1 | 0.1 | 84.5 + H010_L15_C020 | 0.0 | 79.7 | 15.1 | 78.9 + H010_L25_C010 | 6.1 | 38.3 | 0.0 | 72.5 + H010_L25_C020 | 0.0 | 61.8 | 10.6 | 67.9 + H010_L25_C030 | 0.0 | 79.5 | 18.5 | 62.7 + H010_L25_C040 | 0.4 | 94.2 | 17.3 | 56.5 + H010_L25_C050 | 0.0 | 100.0 | 15.1 | 50.6 + H010_L35_C010 | 6.1 | 32.1 | 0.0 | 61.8 + H010_L35_C020 | 0.0 | 51.7 | 8.4 | 57.5 + H010_L35_C030 | 0.0 | 68.5 | 17.1 | 52.5 +``` + + +所有1,793行数据都是这样的。 回想起来,我不能说此查询对于HLC和Scribus任务是绝对必要的,但是它减轻了我对该项目的一些担忧。 + +为了生成 HLC 色谱,我使用 Scribus 为色板页面中的13,000多种颜色自动创建了颜色图表。 + +我可以使用 **copy** 命令输出数据: + +``` +`\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV);` +``` + + +我还可以使用 ** where ** 子句根据某些值来限制输出。 + +例如,以下命令将仅发送以 H10 开头的色调值。 + + +``` +`\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV) where color like 'H10%';` +``` + +### 备份或传输数据库或表 + +我在此要提到的最后一个命令是**pg_dump**,它用于备份 PostgreSQL 数据库,并在 **psql** 控制台之外运行。 例如: + +``` +pg_dump gregp -t hlc_cmyk > hlc.out +pg_dump gregp > dball.out +``` + +第一行是导出 **hlc_cmyk** 表及其结构。第二行将转储 **gregp** 数据库中的所有表。 这对于备份或传输数据库或表非常有用。 + + +要将数据库或表转到另一台电脑( 查看"[ PostgreSQL 入门][2]" 那篇文章获取详细信息),首先在要转入的电脑上创建一个数据库,然后执行相反的操作。 + +``` +`psql -d gregp -f dball.out` +``` + +一步创建所有表并输入数据。 + +### 总结 + +在本文中,我们了解了如何使用 **WHERE** 参数限制操作,以及如何使用 PostgreSQL 通配符 **%**。 我们还了解了如何将大批量数据加载到表中,然后将部分或全部表数据输出到文件,甚至是将整个数据库及其所有单个表输出。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/postgresql-commands + +作者:[Greg Pittman][a] +选题:[lujun9972][b] +译者:[Morisun029](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/greg-p +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos) +[2]: https://opensource.com/article/19/11/getting-started-postgresql +[3]: https://www.postgresql.org/ +[4]: http://freiefarbe.de +[5]: https://www.freiefarbe.de/en/thema-farbe/hlc-colour-atlas/ diff --git a/translated/tech/20200210 Top hacks for the YaCy open source search engine.md b/translated/tech/20200210 Top hacks for the YaCy open source search engine.md new file mode 100644 index 0000000000..54c4b2f869 --- /dev/null +++ b/translated/tech/20200210 Top hacks for the YaCy open source search engine.md @@ -0,0 +1,99 @@ +[#]: collector: (lujun9972) +[#]: translator: (HankChow) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Top hacks for the YaCy open source search engine) +[#]: via: (https://opensource.com/article/20/2/yacy-search-engine-hacks) +[#]: author: (Seth Kenlon https://opensource.com/users/seth) + +使用开源搜索引擎 YaCy 的技巧 +====== +> 不想再受制于各种版本的搜索引擎?使用 YaCy 自定义一款吧。 +![Browser of things][1] + +在我以前介绍 [YaCy 入门][2]的文章中讲述过 [YaCy][3] 这个点对点peer-to-peer式的搜索引擎是如何安装和使用的。YaCy 最大的一个特点就是可以在本地部署,全球范围内的每一个 YaCy 用户都是构成整个分布式搜索引擎架构的其中一个节点,因此每个用户都可以掌控自己的互联网搜索体验。 + +Google 曾经提供过 `google.com/linux` 这样的简便方式以便快速筛选出和 Linux 相关的搜索内容,这个功能受到了很多人的青睐,但 Google 最终还是在 2011 年的时候把它[下线][4]了。 + +而 YaCy 则让自定义搜索引擎变得可能。 + +### 自定义 YaCy + +YaCy 安装好之后,只需要访问 `localhost:8090` 就可以使用了。要开始自定义搜索引擎,只需要点击右上角的“管理Administration”按钮,如果没有找到,需要点击菜单图标打开菜单。 + +你可以在管理面板中配置 YaCy 对系统资源的使用策略,以及如何跟其它的 YaCy 客户端进行交互。 + +![YaCy profile selector][5] + +例如,点击侧栏中的“初步First steps”按钮可以配置备用端口,以及设置 YaCy 对内存和硬盘的使用量;而“监控Monitoring”面板则可以监控 YaCy 的运行状况。大多数功能都只需要在面板上点击几下就可以完成了,例如以下几个常用的功能。 + +### 搜索应用 + +目前市面上也有不少公司推出了[内网搜索应用][6],而 YaCy 的优势是免费使用。对于能够通过 HTTP、FTP、Samba 等协议访问的文件,YaCy 都可以进行索引,因此无论是作为私人的文件搜索还是企业内部的本地共享文件搜索,YaCy 都可以实现。它可以让内部网络中的用户使用自定义配置的 YaCy 查找共享文件,于此同时保持对内部网络以外的用户不可见。 + +### 网络配置 + +YaCy 在默认情况下就对隐私隔离有比较好的支持。点击“用例与账号Use Case & Account”页面顶部的“网络配置Network Configuration”链接,即可进入网络配置面板设置点对点网络。 + +![YaCy network configuration][7] + +### 爬取站点 + +YaCy 点对点的分布式运作方式决定了它对页面的爬取是由用户驱动的。任何一个公司的爬虫都不可能完全访问到整个互联网上的所有页面,对于 YaCy 来说也是这样,一个站点只有在被用户指定爬取的前提下,才会被 YaCy 爬取并进入索引。 + +YaCy 客户端提供了两种爬取页面的方式:一是自定义爬虫,二是使用 YaCy 推荐的爬虫。 + +![YaCy advanced crawler][8] + +#### 自定义爬虫任务 + +自定义爬虫是指由用户输入指定的网站 URL 并启动 YaCy 的爬虫任务。只需要点击“高级爬虫Advanced Crawler”并输入计划爬取的 URL,然后选择页面底部的“进行远程索引Do Remote indexing”选项,这个选项会让客户端将上面输入的 URL 向互联网广播,接收到广播的其它远程客户端就会开始爬取这些 URL 所指向的页面。 + +点击页面底部的“开始新爬虫任务Start New Crawl Job”按钮就可以开始进行爬取了,我就是这样对一些常用和有用站点进行爬取和索引的。 + +爬虫任务启动之后,YaCy 会将这些 URL 对应的页面在本地生成和存储索引。在高级模式下,也就是本地计算机允许 8090 端口流量进出时,全网的 YaCy 用户都可以使用到这一份索引。 + +#### 加入爬虫任务 + +尽管 YaCy 用户已经在互联网上爬取了很多页面,但对于全网浩如烟海的页面而言也只是沧海一粟。单个用户所拥有的资源远不及很多大公司的网络爬虫,但大量 YaCy 用户如果联合起来成为一个社区,能产生的力量就大得多了。只要开启了 YaCy 的爬虫请求广播功能,就可以让其它客户端参与进来爬取更多页面。 + +只需要在“高级爬虫Advanced Crawler”面板中点击页面顶部的“远程爬取Remote Crawling”,勾选“加载Load”复选框,就可以让你的客户端接受其它人发来的爬虫任务请求了。 + +![YaCy remote crawling][9] + +### YaCy 监控相关 + +YaCy 除了作为一个非常强大的搜索引擎,还提供了很丰富的用户体验。你可以在“监控Monitor”面板中监控 YaCy 客户端的网络运行状况,甚至还可以了解到有多少人从 YaCy 社区中获取到了自己所需要的东西。 + +![YaCy monitoring screen][10] + +### 搜索引擎发挥了作用 + +你使用 YaCy 的时间越长,就越会思考搜索引擎如何改变自己的视野,因为你对互联网的体验很大一部分来自于你在搜索引擎中一次次简单查询的结果。实际上,当你和不同行业的人交流时,可能会注意到每个人对“互联网”的理解都有所不同。有些人会认为,互联网的搜索引擎中充斥着各种广告和推广,同时也仅仅能从搜索结果中获取到有限的信息。例如,假设有人不断搜索关于关键词 X 的内容,那么大部分商业搜索引擎都会在搜索结果中提高关键词 X 的权重,但与此同时,另一个关键词 Y 的权重则会相对降低,从而让关键词 Y 被淹没在搜索结果当中。 + +就像在现实生活中一样,走出舒适圈会让你看到一个更广阔的世界。尝试使用 YaCy,看看你会不会有所收获。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/20/2/yacy-search-engine-hacks + +作者:[Seth Kenlon][a] +选题:[lujun9972][b] +译者:[HankChow](https://github.com/HankChow) +校对:[校对者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/browser_desktop_website_checklist_metrics.png?itok=OKKbl1UR (Browser of things) +[2]: https://opensource.com/article/20/2/open-source-search-engine +[3]: https://yacy.net/ +[4]: https://www.linuxquestions.org/questions/linux-news-59/is-there-no-more-linux-google-884306/ +[5]: https://opensource.com/sites/default/files/uploads/yacy-profiles.jpg (YaCy profile selector) +[6]: https://en.wikipedia.org/wiki/Vivisimo +[7]: https://opensource.com/sites/default/files/uploads/yacy-network-config.jpg (YaCy network configuration) +[8]: https://opensource.com/sites/default/files/uploads/yacy-advanced-crawler.jpg (YaCy advanced crawler) +[9]: https://opensource.com/sites/default/files/uploads/yacy-remote-crawl-accept.jpg (YaCy remote crawling) +[10]: https://opensource.com/sites/default/files/uploads/yacy-monitor.jpg (YaCy monitoring screen)