mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-29 21:41:00 +08:00
Merge branch 'master' of https://github.com/LCTT/TranslateProject into translating
This commit is contained in:
commit
a1363f3b8d
273
published/20190809 Mutation testing is the evolution of TDD.md
Normal file
273
published/20190809 Mutation testing is the evolution of TDD.md
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Morisun029)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-11468-1.html)
|
||||||
|
[#]: subject: (Mutation testing is the evolution of TDD)
|
||||||
|
[#]: via: (https://opensource.com/article/19/8/mutation-testing-evolution-tdd)
|
||||||
|
[#]: author: (Alex Bunardzic https://opensource.com/users/alex-bunardzic)
|
||||||
|
|
||||||
|
变异测试是测试驱动开发(TDD)的演变
|
||||||
|
======
|
||||||
|
|
||||||
|
> 测试驱动开发技术是根据大自然的运作规律创建的,变异测试自然成为 DevOps 演变的下一步。
|
||||||
|
|
||||||
|
![Ants and a leaf making the word "open"][1]
|
||||||
|
|
||||||
|
在 “[故障是无懈可击的开发运维中的一个特点][2]”,我讨论了故障在通过征求反馈来交付优质产品的过程中所起到的重要作用。敏捷 DevOps 团队就是用故障来指导他们并推动开发进程的。<ruby>[测试驱动开发][3]<rt>Test-driven development</rt></ruby>(TDD)是任何敏捷 DevOps 团队评估产品交付的[必要条件][4]。以故障为中心的 TDD 方法仅在与可量化的测试配合使用时才有效。
|
||||||
|
|
||||||
|
TDD 方法仿照大自然是如何运作的以及自然界在进化博弈中是如何产生赢家和输家为模型而建立的。
|
||||||
|
|
||||||
|
### 自然选择
|
||||||
|
|
||||||
|
![查尔斯·达尔文][5]
|
||||||
|
|
||||||
|
1859 年,<ruby>[查尔斯·达尔文][6]<rt>Charles Darwin</rt></ruby>在他的《<ruby>[物种起源][7]<rt>On the Origin of Species</rt></ruby>》一书中提出了进化论学说。达尔文的论点是,自然变异是由生物个体的自发突变和环境压力共同造成的。环境压力淘汰了适应性较差的生物体,而有利于其他适应性强的生物的发展。每个生物体的染色体都会发生变异,而这些自发的变异会携带给下一代(后代)。然后在自然选择下测试新出现的变异性 —— 当下存在的环境压力是由变异性的环境条件所导致的。
|
||||||
|
|
||||||
|
这张简图说明了调整适应环境条件的过程。
|
||||||
|
|
||||||
|
![环境压力对鱼类的影响][8]
|
||||||
|
|
||||||
|
*图1. 不同的环境压力导致自然选择下的不同结果。图片截图来源于[理查德·道金斯的一个视频][9]。*
|
||||||
|
|
||||||
|
该图显示了一群生活在自己栖息地的鱼。栖息地各不相同(海底或河床底部的砾石颜色有深有浅),每条鱼长的也各不相同(鱼身图案和颜色也有深有浅)。
|
||||||
|
|
||||||
|
这张图还显示了两种情况(即环境压力的两种变化):
|
||||||
|
|
||||||
|
1. 捕食者在场
|
||||||
|
2. 捕食者不在场
|
||||||
|
|
||||||
|
在第一种情况下,在砾石颜色衬托下容易凸显出来的鱼被捕食者捕获的风险更高。当砾石颜色较深时,浅色鱼的数量会更少一些。反之亦然,当砾石颜色较浅时,深色鱼的数量会更少。
|
||||||
|
|
||||||
|
在第二种情况下,鱼完全放松下来进行交配。在没有捕食者和没有交配仪式的情况下,可以预料到相反的结果:在砾石背景下显眼的鱼会有更大的机会被选来交配并将其特性传递给后代。
|
||||||
|
|
||||||
|
### 选择标准
|
||||||
|
|
||||||
|
变异性在进行选择时,绝不是任意的、反复无常的、异想天开的或随机的。选择过程中的决定性因素通常是可以度量的。该决定性因素通常称为测试或目标。
|
||||||
|
|
||||||
|
一个简单的数学例子可以说明这一决策过程。(在该示例中,这种选择不是由自然选择决定的,而是由人为选择决定。)假设有人要求你构建一个小函数,该函数将接受一个正数,然后计算该数的平方根。你将怎么做?
|
||||||
|
|
||||||
|
敏捷 DevOps 团队的方法是快速验证失败。谦虚一点,先承认自己并不真的知道如何开发该函数。这时,你所知道的就是如何描述你想做的事情。从技术上讲,你已准备好进行单元测试。
|
||||||
|
|
||||||
|
“<ruby>单元测试<rt>unit test</rt></ruby>”描述了你的具体期望结果是什么。它可以简单地表述为“给定数字 16,我希望平方根函数返回数字 4”。你可能知道 16 的平方根是 4。但是,你不知道一些较大数字(例如 533)的平方根。
|
||||||
|
|
||||||
|
但至少,你已经制定了选择标准,即你的测试或你的期望值。
|
||||||
|
|
||||||
|
### 进行故障测试
|
||||||
|
|
||||||
|
[.NET Core][10] 平台可以演示该测试。.NET 通常使用 xUnit.net 作为单元测试框架。(要跟随进行这个代码示例,请安装 .NET Core 和 xUnit.net。)
|
||||||
|
|
||||||
|
打开命令行并创建一个文件夹,在该文件夹实现平方根解决方案。例如,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir square_root
|
||||||
|
```
|
||||||
|
|
||||||
|
再输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd square_root
|
||||||
|
```
|
||||||
|
|
||||||
|
为单元测试创建一个单独的文件夹:
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir unit_tests
|
||||||
|
```
|
||||||
|
|
||||||
|
进入 `unit_tests` 文件夹下(`cd unit_tests`),初始化 xUnit 框架:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet new xunit
|
||||||
|
```
|
||||||
|
|
||||||
|
现在,转到 `square_root` 下, 创建 `app` 文件夹:
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir app
|
||||||
|
cd app
|
||||||
|
```
|
||||||
|
|
||||||
|
如果有必要的话,为你的代码创建一个脚手架:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet new classlib
|
||||||
|
```
|
||||||
|
|
||||||
|
现在打开你最喜欢的编辑器开始编码!
|
||||||
|
|
||||||
|
在你的代码编辑器中,导航到 `unit_tests` 文件夹,打开 `UnitTest1.cs`。
|
||||||
|
|
||||||
|
将 `UnitTest1.cs` 中自动生成的代码替换为:
|
||||||
|
|
||||||
|
```
|
||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
using app;
|
||||||
|
|
||||||
|
namespace unit_tests{
|
||||||
|
|
||||||
|
public class UnitTest1{
|
||||||
|
Calculator calculator = new Calculator();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenPositiveNumberCalculateSquareRoot(){
|
||||||
|
var expected = 4;
|
||||||
|
var actual = calculator.CalculateSquareRoot(16);
|
||||||
|
Assert.Equal(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
该单元测试描述了变量的**期望值**应该为 4。下一行描述了**实际值**。建议通过将输入值发送到称为`calculator` 的组件来计算**实际值**。对该组件的描述是通过接收数值来处理`CalculateSquareRoot` 信息。该组件尚未开发。但这并不重要,我们在此只是描述期望值。
|
||||||
|
|
||||||
|
最后,描述了触发消息发送时发生的情况。此时,判断**期望值**是否等于**实际值**。如果是,则测试通过,目标达成。如果**期望值**不等于**实际值**,则测试失败。
|
||||||
|
|
||||||
|
接下来,要实现称为 `calculator` 的组件,在 `app` 文件夹中创建一个新文件,并将其命名为`Calculator.cs`。要实现计算平方根的函数,请在此新文件中添加以下代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
namespace app {
|
||||||
|
public class Calculator {
|
||||||
|
public double CalculateSquareRoot(double number) {
|
||||||
|
double bestGuess = number;
|
||||||
|
return bestGuess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在测试之前,你需要通知单元测试如何找到该新组件(`Calculator`)。导航至 `unit_tests` 文件夹,打开 `unit_tests.csproj` 文件。在 `<ItemGroup>` 代码块中添加以下代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
<ProjectReference Include="../app/app.csproj" />
|
||||||
|
```
|
||||||
|
|
||||||
|
保存 `unit_test.csproj` 文件。现在,你可以运行第一个测试了。
|
||||||
|
|
||||||
|
切换到命令行,进入 `unit_tests` 文件夹。运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet test
|
||||||
|
```
|
||||||
|
|
||||||
|
运行单元测试,会输出以下内容:
|
||||||
|
|
||||||
|
![单元测试失败后xUnit的输出结果][12]
|
||||||
|
|
||||||
|
*图2. 单元测试失败后 xUnit 的输出结果*
|
||||||
|
|
||||||
|
正如你所看到的,单元测试失败了。期望将数字 16 发送到 `calculator` 组件后会输出数字 4,但是输出(`Actual`)的是 16。
|
||||||
|
|
||||||
|
恭喜你!创建了第一个故障。单元测试为你提供了强有力的反馈机制,敦促你修复故障。
|
||||||
|
|
||||||
|
### 修复故障
|
||||||
|
|
||||||
|
要修复故障,你必须要改进 `bestGuess`。当下,`bestGuess` 仅获取函数接收的数字并返回。这不够好。
|
||||||
|
|
||||||
|
但是,如何找到一种计算平方根值的方法呢? 我有一个主意 —— 看一下大自然母亲是如何解决问题的。
|
||||||
|
|
||||||
|
### 效仿大自然的迭代
|
||||||
|
|
||||||
|
在第一次(也是唯一的)尝试中要得出正确值是非常难的(几乎不可能)。你必须允许自己进行多次尝试猜测,以增加解决问题的机会。允许多次尝试的一种方法是进行迭代。
|
||||||
|
|
||||||
|
要迭代,就要将 `bestGuess` 值存储在 `previousGuess` 变量中,转换 `bestGuess` 的值,然后比较两个值之间的差。如果差为 0,则说明问题已解决。否则,继续迭代。
|
||||||
|
|
||||||
|
这是生成任何正数的平方根的函数体:
|
||||||
|
|
||||||
|
```
|
||||||
|
double bestGuess = number;
|
||||||
|
double previousGuess;
|
||||||
|
|
||||||
|
do {
|
||||||
|
previousGuess = bestGuess;
|
||||||
|
bestGuess = (previousGuess + (number/previousGuess))/2;
|
||||||
|
} while((bestGuess - previousGuess) != 0);
|
||||||
|
|
||||||
|
return bestGuess;
|
||||||
|
```
|
||||||
|
|
||||||
|
该循环(迭代)将 `bestGuess` 值集中到设想的解决方案。现在,你精心设计的单元测试通过了!
|
||||||
|
|
||||||
|
![单元测试通过了][13]
|
||||||
|
|
||||||
|
*图 3. 单元测试通过了。*
|
||||||
|
|
||||||
|
### 迭代解决了问题
|
||||||
|
|
||||||
|
正如大自然母亲解决问题的方法,在本练习中,迭代解决了问题。增量方法与逐步改进相结合是获得满意解决方案的有效方法。该示例中的决定性因素是具有可衡量的目标和测试。一旦有了这些,就可以继续迭代直到达到目标。
|
||||||
|
|
||||||
|
### 关键点!
|
||||||
|
|
||||||
|
好的,这是一个有趣的试验,但是更有趣的发现来自于使用这种新创建的解决方案。到目前为止,`bestGuess` 从开始一直把函数接收到的数字作为输入参数。如果更改 `bestGuess` 的初始值会怎样?
|
||||||
|
|
||||||
|
为了测试这一点,你可以测试几种情况。 首先,在迭代多次尝试计算 25 的平方根时,要逐步细化观察结果:
|
||||||
|
|
||||||
|
![25 平方根的迭代编码][14]
|
||||||
|
|
||||||
|
*图 4. 通过迭代来计算 25 的平方根。*
|
||||||
|
|
||||||
|
以 25 作为 `bestGuess` 的初始值,该函数需要八次迭代才能计算出 25 的平方根。但是,如果在设计 `bestGuess` 初始值上犯下荒谬的错误,那将怎么办? 尝试第二次,那 100 万可能是 25 的平方根吗? 在这种明显错误的情况下会发生什么?你写的函数是否能够处理这种低级错误。
|
||||||
|
|
||||||
|
直接来吧。回到测试中来,这次以一百万开始:
|
||||||
|
|
||||||
|
![逐步求精法][15]
|
||||||
|
|
||||||
|
*图 5. 在计算 25 的平方根时,运用逐步求精法,以 100 万作为 bestGuess 的初始值。*
|
||||||
|
|
||||||
|
哇! 以一个荒谬的数字开始,迭代次数仅增加了两倍(从八次迭代到 23 次)。增长幅度没有你直觉中预期的那么大。
|
||||||
|
|
||||||
|
### 故事的寓意
|
||||||
|
|
||||||
|
啊哈! 当你意识到,迭代不仅能够保证解决问题,而且与你的解决方案的初始猜测值是好是坏也没有关系。 不论你最初理解得多么不正确,迭代过程以及可衡量的测试/目标,都可以使你走上正确的道路并得到解决方案。
|
||||||
|
|
||||||
|
图 4 和 5 显示了陡峭而戏剧性的燃尽图。一个非常错误的开始,迭代很快就产生了一个绝对正确的解决方案。
|
||||||
|
|
||||||
|
简而言之,这种神奇的方法就是敏捷 DevOps 的本质。
|
||||||
|
|
||||||
|
### 回到一些更深层次的观察
|
||||||
|
|
||||||
|
敏捷 DevOps 的实践源于人们对所生活的世界的认知。我们生活的世界存在不确定性、不完整性以及充满太多的困惑。从科学/哲学的角度来看,这些特征得到了<ruby>[海森堡的不确定性原理][16]<rt>Heisenberg's Uncertainty Principle</rt></ruby>(涵盖不确定性部分),<ruby>[维特根斯坦的逻辑论哲学][17]<rt>Wittgenstein's Tractatus Logico-Philosophicus</rt></ruby>(歧义性部分),<ruby>[哥德尔的不完全性定理][18]<rt>Gödel's incompleteness theorems</rt></ruby>(不完全性方面)以及<ruby>[热力学第二定律][19]<rt>Second Law of Thermodynamics</rt></ruby>(无情的熵引起的混乱)的充分证明和支持。
|
||||||
|
|
||||||
|
简而言之,无论你多么努力,在尝试解决任何问题时都无法获得完整的信息。因此,放下傲慢的姿态,采取更为谦虚的方法来解决问题对我们会更有帮助。谦卑会给为你带来巨大的回报,这个回报不仅是你期望的一个解决方案,还会有它的副产品。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
大自然在不停地运作,这是一个持续不断的过程。大自然没有总体规划。一切都是对先前发生的事情的回应。 反馈循环是非常紧密的,明显的进步/倒退都是逐步实现的。大自然中随处可见,任何事物的都在以一种或多种形式逐步完善。
|
||||||
|
|
||||||
|
敏捷 DevOps 是工程模型逐渐成熟的一个非常有趣的结果。DevOps 基于这样的认识,即你所拥有的信息总是不完整的,因此你最好谨慎进行。获得可衡量的测试(例如,假设、可测量的期望结果),进行简单的尝试,大多数情况下可能失败,然后收集反馈,修复故障并继续测试。除了同意每个步骤都必须要有可衡量的假设/测试之外,没有其他方法。
|
||||||
|
|
||||||
|
在本系列的下一篇文章中,我将仔细研究变异测试是如何提供及时反馈来推动实现结果的。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/8/mutation-testing-evolution-tdd
|
||||||
|
|
||||||
|
作者:[Alex Bunardzic][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Morisun029](https://github.com/Morisun029)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/alex-bunardzic
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520X292_openanttrail-2.png?itok=xhD3WmUd (Ants and a leaf making the word "open")
|
||||||
|
[2]: https://opensource.com/article/19/7/failure-feature-blameless-devops
|
||||||
|
[3]: https://en.wikipedia.org/wiki/Test-driven_development
|
||||||
|
[4]: https://www.merriam-webster.com/dictionary/conditio%20sine%20qua%20non
|
||||||
|
[5]: https://opensource.com/sites/default/files/uploads/darwin.png (Charles Darwin)
|
||||||
|
[6]: https://en.wikipedia.org/wiki/Charles_Darwin
|
||||||
|
[7]: https://en.wikipedia.org/wiki/On_the_Origin_of_Species
|
||||||
|
[8]: https://opensource.com/sites/default/files/uploads/environmentalconditions2.png (Environmental pressures on fish)
|
||||||
|
[9]: https://www.youtube.com/watch?v=MgK5Rf7qFaU
|
||||||
|
[10]: https://dotnet.microsoft.com/
|
||||||
|
[11]: https://xunit.net/
|
||||||
|
[12]: https://opensource.com/sites/default/files/uploads/xunit-output.png (xUnit output after the unit test run fails)
|
||||||
|
[13]: https://opensource.com/sites/default/files/uploads/unit-test-success.png (Unit test successful)
|
||||||
|
[14]: https://opensource.com/sites/default/files/uploads/iterating-square-root.png (Code iterating for the square root of 25)
|
||||||
|
[15]: https://opensource.com/sites/default/files/uploads/bestguess.png (Stepwise refinement)
|
||||||
|
[16]: https://en.wikipedia.org/wiki/Uncertainty_principle
|
||||||
|
[17]: https://en.wikipedia.org/wiki/Tractatus_Logico-Philosophicus
|
||||||
|
[18]: https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems
|
||||||
|
[19]: https://en.wikipedia.org/wiki/Second_law_of_thermodynamics
|
@ -0,0 +1,98 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-11469-1.html)
|
||||||
|
[#]: subject: (Command line quick tips: Locate and process files with find and xargs)
|
||||||
|
[#]: via: (https://fedoramagazine.org/command-line-quick-tips-locate-and-process-files-with-find-and-xargs/)
|
||||||
|
[#]: author: (Ben Cotton https://fedoramagazine.org/author/bcotton/)
|
||||||
|
|
||||||
|
命令行技巧:使用 find 和 xargs 查找和处理文件
|
||||||
|
======
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
`find` 是日常工具箱中功能强大、灵活的命令行程序之一。它如它名字所暗示的:查找符合你指定条件的文件和目录。借助 `-exec` 或 `-delete` 之类的参数,你可以让它对找到的文件进行操作。
|
||||||
|
|
||||||
|
在[命令行提示][2]系列的这一期中,你将会看到 `find` 命令的介绍,并学习如何使用内置命令或使用 `xargs` 命令处理文件。
|
||||||
|
|
||||||
|
### 查找文件
|
||||||
|
|
||||||
|
`find` 至少要加上查找的路径。例如,此命令将查找(并打印)系统上的每个文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
find /
|
||||||
|
```
|
||||||
|
|
||||||
|
由于一切皆文件,因此你会看到大量的输出。这可能无法帮助你找到所需的内容。你可以更改路径参数缩小范围,但这实际上并没有比使用 `ls` 命令更好。因此,你需要考虑要查找的内容。
|
||||||
|
|
||||||
|
也许你想在家目录中查找所有 JPEG 文件。 `-name` 参数允许你将结果限制为与给定模式匹配的文件。
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ -name '*jpg'
|
||||||
|
```
|
||||||
|
|
||||||
|
但是等等!如果其中一些扩展名是大写怎么办? `-iname` 类似于 `-name`,但不区分大小写:
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ -iname '*jpg'
|
||||||
|
```
|
||||||
|
|
||||||
|
很好!但是 8.3 命名方案出自 1985 年。某些图片的扩展名可能是 .jpeg。幸运的是,我们可以将模式使用“或”(`-o`)进行组合。括号需要转义,以便使 `find` 命令而不是 shell 程序尝试解释它们。
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -iname 'jpeg' -o -iname 'jpg' \)
|
||||||
|
```
|
||||||
|
|
||||||
|
更进一步。如果你有一些以 `jpg` 结尾的目录怎么办?(我不懂你为什么将目录命名为 `bucketofjpg` 而不是 `pictures`?)我们可以加上 `-type` 参数来仅查找文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f
|
||||||
|
```
|
||||||
|
|
||||||
|
或者,也许你想找到那些名字奇怪的目录,以便之后可以重命名它们:
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type d
|
||||||
|
```
|
||||||
|
|
||||||
|
最近你拍摄了很多照片,因此使用 `-mtime`(修改时间)将范围缩小到最近一周修改过的文件。 `-7` 表示 7 天或更短时间内修改的所有文件。
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用 xargs 进行操作
|
||||||
|
|
||||||
|
`xargs` 命令从标准输入流中获取参数,并基于它们执行命令。继续使用上一节中的示例,假设你要将上周修改过的家目录中的所有 JPEG 文件复制到 U 盘,以便插到电子相册上。假设你已经将 U 盘挂载到 `/media/photo_display`。
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7 -print0 | xargs -0 cp -t /media/photo_display
|
||||||
|
```
|
||||||
|
|
||||||
|
这里的 `find` 命令与以前的版本略有不同。`-print0` 命令让输出有一些更改:它不使用换行符,而是添加了一个 `null` 字符。`xargs` 的 `-0`(零)选项可调整解析以达到预期效果。这很重要,不然对包含空格、引号或其他特殊字符的文件名执行操作可能无法按预期进行。对文件采取任何操作时,都应使用这些选项。
|
||||||
|
|
||||||
|
`cp` 命令的 `-t` 参数很重要,因为 `cp` 通常要求目的地址在最后。你可以不使用 `xargs` 而使用 `find` 的 `-exec` 执行此操作,但是 `xargs` 的方式会更快,尤其是对于大量文件,因为它会单次调用 `cp`。
|
||||||
|
|
||||||
|
### 了解更多
|
||||||
|
|
||||||
|
这篇文章仅仅是 `find` 可以做的事情的表面。 `find` 支持基于权限、所有者、访问时间等的测试。它甚至可以将搜索路径中的文件与其他文件进行比较。将测试与布尔逻辑相结合,可以为你提供惊人的灵活性,以精确地找到你要查找的文件。使用内置命令或管道传递给 `xargs`,你可以快速处理大量文件。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/command-line-quick-tips-locate-and-process-files-with-find-and-xargs/
|
||||||
|
|
||||||
|
作者:[Ben Cotton][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[geekpi](https://github.com/geekpi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://fedoramagazine.org/author/bcotton/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://fedoramagazine.org/wp-content/uploads/2018/10/commandlinequicktips-816x345.jpg
|
||||||
|
[2]: https://fedoramagazine.org/?s=command+line+quick+tips
|
||||||
|
[3]: https://opensource.com/article/18/4/how-use-find-linux
|
||||||
|
[4]: https://unsplash.com/@wflwong?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||||
|
[5]: https://unsplash.com/s/photos/search?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
@ -0,0 +1,124 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (singledo)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-11470-1.html)
|
||||||
|
[#]: subject: (How to Unzip a Zip File in Linux [Beginner’s Tutorial])
|
||||||
|
[#]: via: (https://itsfoss.com/unzip-linux/)
|
||||||
|
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||||
|
|
||||||
|
新手教程:如何在 Linux 下解压 Zip 文件
|
||||||
|
======
|
||||||
|
|
||||||
|
> 本文将会向你展示如何在 Ubuntu 和其他 Linux 发行版本上解压文件。终端和图形界面的方法都会讨论。
|
||||||
|
|
||||||
|
[Zip][1] 是一种创建压缩存档文件的最普通、最流行的方法。它也是一种古老的文件归档文件格式,这种格式创建于 1989 年。由于它的广泛使用,你会经常遇见 zip 文件。
|
||||||
|
|
||||||
|
在更早的一份教程里,我介绍了[如何在 Linux 上用 zip 压缩一个文件夹][2]。在这篇面向初学者的快速教程中,我会介绍如何在 Linux 上解压文件。
|
||||||
|
|
||||||
|
先决条件:检查你是否安装了 `unzip`。
|
||||||
|
|
||||||
|
为了解压 zip 归档文件,你必须在你的系统上安装了 unzip 软件包。大多数现代的的 Linux 发行版本提供了解压 zip 文件的支持,但是对这些 zip 文件进行校验以避免以后出现损坏总是没有坏处的。
|
||||||
|
|
||||||
|
在基于 [Unbutu][3] 和 [Debian][4] 的发行版上,你能够使用下面的命令来安装 `unzip`。如果你已经安装了,你会被告知已经被安装。
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install unzip
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦你能够确认你的系统中安装了 `unzip`,你就可以通过 `unzip` 来解压 zip 归档文件。
|
||||||
|
|
||||||
|
你也能够使用命令行或者图形工具来达到目的,我会向你展示两种方法:
|
||||||
|
|
||||||
|
### 使用命令行解压文件
|
||||||
|
|
||||||
|
在 Linux 下使用 `unzip` 命令是非常简单的。在你放 zip 文件的目录,用下面的命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
unzip zipped_file.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
你可以给 zip 文件提供解压路径而不是解压到当前所在路径。你会在终端输出中看到提取的文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
unzip metallic-container.zip -d my_zip
|
||||||
|
Archive: metallic-container.zip
|
||||||
|
inflating: my_zip/625993-PNZP34-678.jpg
|
||||||
|
inflating: my_zip/License free.txt
|
||||||
|
inflating: my_zip/License premium.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的命令有一个小问题。它会提取 zip 文件中所有的内容到现在的文件夹。你会在当前文件夹下留下一堆没有组织的文件,这不是一件很好的事情。
|
||||||
|
|
||||||
|
#### 解压到文件夹下
|
||||||
|
|
||||||
|
在 Linux 命令行下,对于把文件解压到一个文件夹下是一个好的做法。这种方式下,所有的提取文件都会被存储到你所指定的文件夹下。如果文件夹不存在,会创建该文件夹。
|
||||||
|
|
||||||
|
```
|
||||||
|
unzip zipped_file.zip -d unzipped_directory
|
||||||
|
```
|
||||||
|
|
||||||
|
现在 `zipped_file.zip` 中所有的内容都会被提取到 `unzipped_directory` 中。
|
||||||
|
|
||||||
|
由于我们在讨论好的做法,这里有另一个注意点,我们可以查看压缩文件中的内容而不用实际解压。
|
||||||
|
|
||||||
|
#### 查看压缩文件中的内容而不解压压缩文件
|
||||||
|
|
||||||
|
```
|
||||||
|
unzip -l zipped_file.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
下面是该命令的输出:
|
||||||
|
|
||||||
|
```
|
||||||
|
unzip -l metallic-container.zip
|
||||||
|
Archive: metallic-container.zip
|
||||||
|
Length Date Time Name
|
||||||
|
--------- ---------- ----- ----
|
||||||
|
6576010 2019-03-07 10:30 625993-PNZP34-678.jpg
|
||||||
|
1462 2019-03-07 13:39 License free.txt
|
||||||
|
1116 2019-03-07 13:39 License premium.txt
|
||||||
|
--------- -------
|
||||||
|
6578588 3 files
|
||||||
|
```
|
||||||
|
|
||||||
|
在 Linux 下,还有些 `unzip` 的其它用法,但我想你现在已经对在 Linux 下使用解压文件有了足够的了解。
|
||||||
|
|
||||||
|
### 使用图形界面来解压文件
|
||||||
|
|
||||||
|
如果你使用桌面版 Linux,那你就不必总是使用终端。在图形化的界面下,我们又要如何解压文件呢? 我使用的是 [GNOME 桌面][7],不过其它桌面版 Linux 发行版也大致相同。
|
||||||
|
|
||||||
|
打开文件管理器,然后跳转到 zip 文件所在的文件夹下。在文件上点击鼠标右键,你会在弹出的窗口中看到 “提取到这里”,选择它。
|
||||||
|
|
||||||
|
![Unzip File in Ubuntu][8]
|
||||||
|
|
||||||
|
与 `unzip` 命令不同,这个提取选项会创建一个和压缩文件名相同的文件夹(LCTT 译注:文件夹没有 `.zip` 扩展名),并且把压缩文件中的所有内容存储到创建的文件夹下。相对于 `unzip` 命令的默认行为是将压缩文件提取到当前所在的文件下,图形界面的解压对于我来说是一件非常好的事情。
|
||||||
|
|
||||||
|
这里还有一个选项“提取到……”,你可以选择特定的文件夹来存储提取的文件。
|
||||||
|
|
||||||
|
你现在知道如何在 Linux 解压文件了。你也许还对学习[在 Linux 下使用 7zip][9] 感兴趣?
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/unzip-linux/
|
||||||
|
|
||||||
|
作者:[Abhishek Prakash][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[octopus](https://github.com/singledo)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://itsfoss.com/author/abhishek/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Zip_(file_format)
|
||||||
|
[2]: https://itsfoss.com/linux-zip-folder/
|
||||||
|
[3]: https://ubuntu.com/
|
||||||
|
[4]: https://www.debian.org/
|
||||||
|
[5]: tmp.eqEocGssC8#terminal
|
||||||
|
[6]: tmp.eqEocGssC8#gui
|
||||||
|
[7]: https://gnome.org/
|
||||||
|
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/10/unzip-files-ubuntu.jpg?ssl=1
|
||||||
|
[9]: https://itsfoss.com/use-7zip-ubuntu-linux/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (algzjh)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-11474-1.html)
|
||||||
|
[#]: subject: (4 Free and Open Source Alternatives to Adobe Photoshop)
|
||||||
|
[#]: via: (https://itsfoss.com/open-source-photoshop-alternatives/)
|
||||||
|
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||||
|
|
||||||
|
Adobe Photoshop 的 4 种自由开源替代品
|
||||||
|
======
|
||||||
|
|
||||||
|
> 想寻找免费的 Photoshop 替代品?这里有一些最好的自由开源软件,你可以用它们来代替 Adobe Photoshop。
|
||||||
|
|
||||||
|
Adobe Photoshop 是一个可用于 Windows 和 macOS 的高级图像编辑和设计工具。毫无疑问,几乎每个人都知道它。其十分受欢迎。在 Linux 上,你可以在虚拟机中使用 Windows 或[通过 Wine][1] 来使用 Photoshop,但这并不是一种理想的体验。
|
||||||
|
|
||||||
|
一般来说,我们没有太多可以替代 Adobe Photoshop 的选项。然而,在本文中,我们将提到一些在 Linux 上可用的最佳的开源 Photoshop 替代品(也支持跨平台)。
|
||||||
|
|
||||||
|
请注意 Photoshop 不仅仅是一个图片编辑器。摄影师、数码艺术家、专业编辑使用它用于各种用途。此处的替代软件可能不具备 Photoshop 的所有功能,但你可以将它们用于在 Photoshop 中完成的各种任务。
|
||||||
|
|
||||||
|
### 适用于 Linux、Windows 和 macOS 的 Adobe Photoshop 的开源替代品
|
||||||
|
|
||||||
|
![][2]
|
||||||
|
|
||||||
|
最初,我想只关注 Linux 中的 Photoshop 替代品,但为什么要把这个列表局限于 Linux 呢?其他操作系统用户也可使用开源软件。
|
||||||
|
|
||||||
|
**如果你正在使用 Linux,则所有提到的软件都应该可以在你的发行版的存储库中找到。你可以使用软件中心或包管理器进行安装。**
|
||||||
|
|
||||||
|
对于其他平台,请查看官方项目网站以获取安装文件。
|
||||||
|
|
||||||
|
*该列表没有特定的排名顺序*
|
||||||
|
|
||||||
|
#### 1、GIMP:真正的 Photoshop 替代品
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
主要特点:
|
||||||
|
|
||||||
|
* 可定制的界面
|
||||||
|
* 数字级修饰
|
||||||
|
* 照片增强(使用变换工具)
|
||||||
|
* 支持广泛的硬件(压敏平板、音乐数字接口等)
|
||||||
|
* 几乎支持所有主要的图像文件
|
||||||
|
* 支持图层管理
|
||||||
|
|
||||||
|
可用平台:Linux、Windows 和 macOS
|
||||||
|
|
||||||
|
[GIMP][4] 是我处理任何事情的必备工具,无论任务多么基础/高级。也许,这是你在 Linux 下最接近 Photoshop 的替代品。除此之外,它还是一个开源和免费的解决方案,适合希望在 Linux 上创作伟大作品的艺术家。
|
||||||
|
|
||||||
|
它具有任何类型的图像处理所必需的所有功能。当然,还有图层管理支持。根据你的经验水平,利用率会有所不同。因此,如果你想充分利用它,则应阅读 [文档][5] 并遵循 [官方教程][6]。
|
||||||
|
|
||||||
|
#### 2、Krita
|
||||||
|
|
||||||
|
![][7]
|
||||||
|
|
||||||
|
主要特点:
|
||||||
|
|
||||||
|
* 支持图层管理
|
||||||
|
* 转换工具
|
||||||
|
* 丰富的笔刷/绘图工具
|
||||||
|
|
||||||
|
可用平台:Linux、Windows 和 macOS
|
||||||
|
|
||||||
|
[Krita][8] 是一个令人印象深刻的开源的数字绘画工具。图层管理支持和转换工具的存在使它成为 Photoshop 的基本编辑任务的替代品之一。
|
||||||
|
|
||||||
|
如果你喜欢素描/绘图,这将对你很有帮助。
|
||||||
|
|
||||||
|
#### 3、Darktable
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
主要特点:
|
||||||
|
|
||||||
|
* RAW 图像显影
|
||||||
|
* 支持多种图像格式
|
||||||
|
* 多个带有混合运算符的图像操作模块
|
||||||
|
|
||||||
|
可用平台:Linux、Windows 和 macOS
|
||||||
|
|
||||||
|
[Darktable][10] 是一个由摄影师制作的开源摄影工作流应用程序。它可以让你在数据库中管理你的数码底片。从你的收藏中,显影 RAW 格式的图像并使用可用的工具对其进行增强。
|
||||||
|
|
||||||
|
从基本的图像编辑工具到支持混合运算符的多个图像模块,你将在探索中发现许多。
|
||||||
|
|
||||||
|
#### 4、Inkscape
|
||||||
|
|
||||||
|
![][11]
|
||||||
|
|
||||||
|
主要特点:
|
||||||
|
|
||||||
|
* 创建对象的工具(最适合绘图/素描)
|
||||||
|
* 支持图层管理
|
||||||
|
* 用于图像处理的转换工具
|
||||||
|
* 颜色选择器(RGB、HSL、CMYK、色轮、CMS)
|
||||||
|
* 支持所有主要文件格式
|
||||||
|
|
||||||
|
可用平台:Linux、Windows 和 macOS
|
||||||
|
|
||||||
|
[Inkscape][12] 是一个非常流行的开源矢量图形编辑器,许多专业人士都使用它。它提供了灵活的设计工具,可帮助你创作漂亮的艺术作品。从技术上说,它是 Adobe Illustrator 的直接替代品,但它也提供了一些技巧,可以帮助你将其作为 Photoshop 的替代品。
|
||||||
|
|
||||||
|
与 GIMP 的官方资源类似,你可以利用 [Inkscape 的教程][13] 来最大程度地利用它。
|
||||||
|
|
||||||
|
### 在你看来,真正的 Photoshop 替代品是什么?
|
||||||
|
|
||||||
|
很难提供与 Adobe Photoshop 完全相同的功能。然而,如果你遵循官方文档和资源,则可以使用上述 Photoshop 替代品做很多很棒的事情。
|
||||||
|
|
||||||
|
Adobe 提供了一系列的图形工具,并且我们有 [整个 Adobe 创意套件的开源替代方案][14]。 你也可以去看看。
|
||||||
|
|
||||||
|
你觉得我们在此提到的 Photoshop 替代品怎么样?你是否知道任何值得提及的更好的替代方案?请在下面的评论中告诉我们。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/open-source-photoshop-alternatives/
|
||||||
|
|
||||||
|
作者:[Ankush Das][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[algzjh](https://github.com/algzjh)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://itsfoss.com/author/ankush/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://itsfoss.com/install-latest-wine/
|
||||||
|
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/10/open_source_photoshop_alternatives.png?ssl=1
|
||||||
|
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/08/gimp-screenshot.jpg?ssl=1
|
||||||
|
[4]: https://www.gimp.org/
|
||||||
|
[5]: https://www.gimp.org/docs/
|
||||||
|
[6]: https://www.gimp.org/tutorials/
|
||||||
|
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/krita-paint.png?ssl=1
|
||||||
|
[8]: https://krita.org/
|
||||||
|
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/darktable.jpg?ssl=1
|
||||||
|
[10]: https://www.darktable.org/
|
||||||
|
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2017/12/inkscape-screenshot.jpg?ssl=1
|
||||||
|
[12]: https://inkscape.org/
|
||||||
|
[13]: https://inkscape.org/learn/
|
||||||
|
[14]: https://itsfoss.com/adobe-alternatives-linux/
|
@ -1,266 +0,0 @@
|
|||||||
[#]: collector: (lujun9972)
|
|
||||||
[#]: translator: (wxy)
|
|
||||||
[#]: reviewer: ( )
|
|
||||||
[#]: publisher: ( )
|
|
||||||
[#]: url: ( )
|
|
||||||
[#]: subject: (How writers can get work done better with Git)
|
|
||||||
[#]: via: (https://opensource.com/article/19/4/write-git)
|
|
||||||
[#]: author: (Seth Kenlon https://opensource.com/users/sethhttps://opensource.com/users/noreplyhttps://opensource.com/users/seth)
|
|
||||||
|
|
||||||
How writers can get work done better with Git
|
|
||||||
======
|
|
||||||
If you're a writer, you could probably benefit from using Git. Learn how
|
|
||||||
in our series about little-known uses of Git.
|
|
||||||
![Writing Hand][1]
|
|
||||||
|
|
||||||
[Git][2] is one of those rare applications that has managed to encapsulate so much of modern computing into one program that it ends up serving as the computational engine for many other applications. While it's best-known for tracking source code changes in software development, it has many other uses that can make your life easier and more organized. In this series leading up to Git's 14th anniversary on April 7, we'll share seven little-known ways to use Git. Today, we'll look at ways writers can use Git to get work done.
|
|
||||||
|
|
||||||
### Git for writers
|
|
||||||
|
|
||||||
Some people write fiction; others write academic papers, poetry, screenplays, technical manuals, or articles about open source. Many do a little of each. The common thread is that if you're a writer, you could probably benefit from using Git. While Git is famously a highly technical tool used by computer programmers, it's ideal for the modern author, and this article will demonstrate how it can change the way you write—and why you'd want it to.
|
|
||||||
|
|
||||||
Before talking about Git, though, it's important to talk about what _copy_ (or _content_ , for the digital age) really is, and why it's different from your delivery _medium_. It's the 21 st century, and the tool of choice for most writers is a computer. While computers are deceptively good at combining processes like copy editing and layout, writers are (re)discovering that separating content from style is a good idea, after all. That means you should be writing on a computer like it's a typewriter, not a word processor. In computer lingo, that means writing in _plaintext_.
|
|
||||||
|
|
||||||
### Writing in plaintext
|
|
||||||
|
|
||||||
It used to be a safe assumption that you knew what market you were writing for. You wrote content for a book, or a website, or a software manual. These days, though, the market's flattened: you might decide to use content you write for a website in a printed book project, and the printed book might release an EPUB version later. And in the case of digital editions of your content, the person reading your content is in ultimate control: they may read your words on the website where you published them, or they might click on Firefox's excellent [Reader View][3], or they might print to physical paper, or they could dump the web page to a text file with Lynx, or they may not see your content at all because they use a screen reader.
|
|
||||||
|
|
||||||
It makes sense to write your words as words, leaving the delivery to the publishers. Even if you are also your own publisher, treating your words as a kind of source code for your writing is a smarter and more efficient way to work, because when it comes time to publish, you can use the same source (your plaintext) to generate output appropriate to your target (PDF for print, EPUB for e-books, HTML for websites, and so on).
|
|
||||||
|
|
||||||
Writing in plaintext not only means you don't have to worry about layout or how your text is styled, but you also no longer require specialized tools. Anything that can produce text becomes a valid "word processor" for you, whether it's a basic notepad app on your mobile or tablet, the text editor that came bundled with your computer, or a free editor you download from the internet. You can write on practically any device, no matter where you are or what you're doing, and the text you produce integrates perfectly with your project, no modification required.
|
|
||||||
|
|
||||||
And, conveniently, Git specializes in managing plaintext.
|
|
||||||
|
|
||||||
### The Atom editor
|
|
||||||
|
|
||||||
When you write in plaintext, a word processor is overkill. Using a text editor is easier because text editors don't try to "helpfully" restructure your input. It lets you type the words in your head onto the screen, no interference. Better still, text editors are often designed around a plugin architecture, such that the application itself is woefully basic (it edits text), but you can build an environment around it to meet your every need.
|
|
||||||
|
|
||||||
A great example of this design philosophy is the [Atom][4] editor. It's a cross-platform text editor with built-in Git integration. If you're new to working in plaintext and new to Git, Atom is the easiest way to get started.
|
|
||||||
|
|
||||||
#### Install Git and Atom
|
|
||||||
|
|
||||||
First, make sure you have Git installed on your system. If you run Linux or BSD, Git is available in your software repository or ports tree. The command you use will vary depending on your distribution; on Fedora, for instance:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`$ sudo dnf install git`
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also download and install Git for [Mac][5] and [Windows][6].
|
|
||||||
|
|
||||||
You won't need to use Git directly, because Atom serves as your Git interface. Installing Atom is the next step.
|
|
||||||
|
|
||||||
If you're on Linux, install Atom from your software repository through your software installer or the appropriate command, such as:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`$ sudo dnf install atom`
|
|
||||||
```
|
|
||||||
|
|
||||||
Atom does not currently build on BSD. However, there are very good alternatives available, such as [GNU Emacs][7]. For Mac and Windows users, you can find installers on the [Atom website][4].
|
|
||||||
|
|
||||||
Once your installs are done, launch the Atom editor.
|
|
||||||
|
|
||||||
#### A quick tour
|
|
||||||
|
|
||||||
If you're going to live in plaintext and Git, you need to get comfortable with your editor. Atom's user interface may be more dynamic than what you are used to. You can think of it more like Firefox or Chrome than as a word processor, in fact, because it has tabs and panels that can be opened and closed as they are needed, and it even has add-ons that you can install and configure. It's not practical to try to cover all of Atom's many features, but you can at least get familiar with what's possible.
|
|
||||||
|
|
||||||
When Atom opens, it displays a welcome screen. If nothing else, this screen is a good introduction to Atom's tabbed interface. You can close the welcome screens by clicking the "close" icons on the tabs at the top of the Atom window and create a new file using **File > New File**.
|
|
||||||
|
|
||||||
Working in plaintext is a little different than working in a word processor, so here are some tips for writing content in a way that a human can connect with and that Git and computers can parse, track, and convert.
|
|
||||||
|
|
||||||
#### Write in Markdown
|
|
||||||
|
|
||||||
These days, when people talk about plaintext, mostly they mean Markdown. Markdown is more of a style than a format, meaning that it intends to provide a predictable structure to your text so computers can detect natural patterns and convert the text intelligently. Markdown has many definitions, but the best technical definition and cheatsheet is on [CommonMark's website][8].
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
# Chapter 1
|
|
||||||
|
|
||||||
This is a paragraph with an *italic* word and a **bold** word in it.
|
|
||||||
And it can even reference an image.
|
|
||||||
|
|
||||||
![An image will render here.](drawing.jpg)
|
|
||||||
```
|
|
||||||
|
|
||||||
As you can tell from the example, Markdown isn't meant to read or feel like code, but it can be treated as code. If you follow the expectations of Markdown defined by CommonMark, then you can reliably convert, with just one click of a button, your writing from Markdown to .docx, .epub, .html, MediaWiki, .odt, .pdf, .rtf, and a dozen other formats _without_ loss of formatting.
|
|
||||||
|
|
||||||
You can think of Markdown a little like a word processor's styles. If you've ever written for a publisher with a set of styles that govern what chapter titles and section headings look like, this is basically the same thing, except that instead of selecting a style from a drop-down menu, you're adding little notations to your text. These notations look natural to any modern reader who's used to "txt speak," but are swapped out with fancy text stylings when the text is rendered. It is, in fact, what word processors secretly do behind the scenes. The word processor shows bold text, but if you could see the code generated to make your text bold, it would be a lot like Markdown (actually it's the far more complex XML). With Markdown, that barrier is removed, which looks scarier on the one hand, but on the other hand, you can write Markdown on literally anything that generates text without losing any formatting information.
|
|
||||||
|
|
||||||
The popular file extension for Markdown files is .md. If you're on a platform that doesn't know what a .md file is, you can associate the extension to Atom manually or else just use the universal .txt extension. The file extension doesn't change the nature of the file; it just changes how your computer decides what to do with it. Atom and some platforms are smart enough to know that a file is plaintext no matter what extension you give it.
|
|
||||||
|
|
||||||
#### Live preview
|
|
||||||
|
|
||||||
Atom features the **Markdown Preview** plugin, which shows you both the plain Markdown you're writing and the way it will (commonly) render.
|
|
||||||
|
|
||||||
![Atom's preview screen][9]
|
|
||||||
|
|
||||||
To activate this preview pane, select **Packages > Markdown Preview > Toggle Preview** or press **Ctrl+Shift+M**.
|
|
||||||
|
|
||||||
This view provides you with the best of both worlds. You get to write without the burden of styling your text, but you also get to see a common example of what your text will look like, at least in a typical digital format. Of course, the point is that you can't control how your text is ultimately rendered, so don't be tempted to adjust your Markdown to force your render preview to look a certain way.
|
|
||||||
|
|
||||||
#### One sentence per line
|
|
||||||
|
|
||||||
Your high school writing teacher doesn't ever have to see your Markdown.
|
|
||||||
|
|
||||||
It won't come naturally at first, but maintaining one sentence per line makes more sense in the digital world. Markdown ignores single line breaks (when you've pressed the Return or Enter key) and only creates a new paragraph after a single blank line.
|
|
||||||
|
|
||||||
![Writing in Atom][10]
|
|
||||||
|
|
||||||
The advantage of writing one sentence per line is that your work is easier to track. That is, if you've changed one word at the start of a paragraph, then it's easy for Atom, Git, or any application to highlight that change in a meaningful way if the change is limited to one line rather than one word in a long paragraph. In other words, a change to one sentence should only affect that sentence, not the whole paragraph.
|
|
||||||
|
|
||||||
You might be thinking, "many word processors track changes, too, and they can highlight a single word that's changed." But those revision trackers are bound to the interface of that word processor, which means you can't look through revisions without being in front of that word processor. In a plaintext workflow, you can review revisions in plaintext, which means you can make or approve edits no matter what you have on hand, as long as that device can deal with plaintext (and most of them can).
|
|
||||||
|
|
||||||
Writers admittedly don't usually think in terms of line numbers, but it's a useful tool for computers, and ultimately a great reference point in general. Atom numbers the lines of your text document by default. A _line_ is only a line once you have pressed the Enter or Return key.
|
|
||||||
|
|
||||||
![Writing in Atom][11]
|
|
||||||
|
|
||||||
If a line has a dot instead of a number, that means it's part of the previous line wrapped for you because it couldn't fit on your screen.
|
|
||||||
|
|
||||||
#### Theme it
|
|
||||||
|
|
||||||
If you're a visual person, you might be very particular about the way your writing environment looks. Even if you are writing in plain Markdown, it doesn't mean you have to write in a programmer's font or in a dark window that makes you look like a coder. The simplest way to modify what Atom looks like is to use [theme packages][12]. It's conventional for theme designers to differentiate dark themes from light themes, so you can search with the keyword Dark or Light, depending on what you want.
|
|
||||||
|
|
||||||
To install a theme, select **Edit > Preferences**. This opens a new tab in the Atom interface. Yes, tabs are used for your working documents _and_ for configuration and control panels. In the **Settings** tab, click on the **Install** category.
|
|
||||||
|
|
||||||
In the **Install** panel, search for the name of the theme you want to install. Click the **Themes** button on the right of the search field to search only for themes. Once you've found your theme, click its **Install** button.
|
|
||||||
|
|
||||||
![Atom's themes][13]
|
|
||||||
|
|
||||||
To use a theme you've installed or to customize a theme to your preference, navigate to the **Themes** category in your **Settings** tab. Pick the theme you want to use from the drop-down menu. The changes take place immediately, so you can see exactly how the theme affects your environment.
|
|
||||||
|
|
||||||
You can also change your working font in the **Editor** category of the **Settings** tab. Atom defaults to monospace fonts, which are generally preferred by programmers. But you can use any font on your system, whether it's serif or sans or gothic or cursive. Whatever you want to spend your day staring at, it's entirely up to you.
|
|
||||||
|
|
||||||
On a related note, by default Atom draws a vertical marker down its screen as a guide for people writing code. Programmers often don't want to write long lines of code, so this vertical line is a reminder to them to simplify things. The vertical line is meaningless to writers, though, and you can remove it by disabling the **wrap-guide** package.
|
|
||||||
|
|
||||||
To disable the **wrap-guide** package, select the **Packages** category in the **Settings** tab and search for **wrap-guide**. When you've found the package, click its **Disable** button.
|
|
||||||
|
|
||||||
#### Dynamic structure
|
|
||||||
|
|
||||||
When creating a long document, I find that writing one chapter per file makes more sense than writing an entire book in a single file. Furthermore, I don't name my chapters in the obvious syntax **chapter-1.md** or **1.example.md** , but by chapter titles or keywords, such as **example.md**. To provide myself guidance in the future about how the book is meant to be assembled, I maintain a file called **toc.md** (for "Table of Contents") where I list the (current) order of my chapters.
|
|
||||||
|
|
||||||
I do this because, no matter how convinced I am that chapter 6 just couldn't possibly happen before chapter 1, there's rarely a time that I don't swap the order of one or two chapters or sections before I'm finished with a book. I find that keeping it dynamic from the start helps me avoid renaming confusion, and it also helps me treat the material less rigidly.
|
|
||||||
|
|
||||||
### Git in Atom
|
|
||||||
|
|
||||||
Two things every writer has in common is that they're writing for keeps and their writing is a journey. You don't sit down to write and finish with a final draft; by definition, you have a first draft. And that draft goes through revisions, each of which you carefully save in duplicate and triplicate just in case one of your files turns up corrupted. Eventually, you get to what you call a final draft, but more than likely you'll be going back to it one day, either to resurrect the good parts or to fix the bad.
|
|
||||||
|
|
||||||
The most exciting feature in Atom is its strong Git integration. Without ever leaving Atom, you can interact with all of the major features of Git, tracking and updating your project, rolling back changes you don't like, integrating changes from a collaborator, and more. The best way to learn it is to step through it, so here's how to use Git within the Atom interface from the beginning to the end of a writing project.
|
|
||||||
|
|
||||||
First thing first: Reveal the Git panel by selecting **View > Toggle Git Tab**. This causes a new tab to open on the right side of Atom's interface. There's not much to see yet, so just keep it open for now.
|
|
||||||
|
|
||||||
#### Starting a Git project
|
|
||||||
|
|
||||||
You can think of Git as being bound to a folder. Any folder outside a Git directory doesn't know about Git, and Git doesn't know about it. Folders and files within a Git directory are ignored until you grant Git permission to keep track of them.
|
|
||||||
|
|
||||||
You can create a Git project by creating a new project folder in Atom. Select **File > Add Project Folder** and create a new folder on your system. The folder you create appears in the left **Project Panel** of your Atom window.
|
|
||||||
|
|
||||||
#### Git add
|
|
||||||
|
|
||||||
Right-click on your new project folder and select **New File** to create a new file in your project folder. If you have files you want to import into your new project, right-click on the folder and select **Show in File Manager** to open the folder in your system's file viewer (Dolphin or Nautilus on Linux, Finder on Mac, Explorer on Windows), and then drag-and-drop your files.
|
|
||||||
|
|
||||||
With a project file (either the empty one you created or one you've imported) open in Atom, click the **Create Repository** button in the **Git** tab. In the pop-up dialog box, click **Init** to initialize your project directory as a local Git repository. Git adds a **.git** directory (invisible in your system's file manager, but visible to you in Atom) to your project folder. Don't be fooled by this: The **.git** directory is for Git to manage, not you, so you'll generally stay out of it. But seeing it in Atom is a good reminder that you're working in a project actively managed by Git; in other words, revision history is available when you see a **.git** directory.
|
|
||||||
|
|
||||||
In your empty file, write some stuff. You're a writer, so type some words. It can be any set of words you please, but remember the writing tips above.
|
|
||||||
|
|
||||||
Press **Ctrl+S** to save your file and it will appear in the **Unstaged Changes** section of the **Git** tab. That means the file exists in your project folder but has not yet been committed over to Git's purview. Allow Git to keep track of your file by clicking on the **Stage All** button in the top-right of the **Git** tab. If you've used a word processor with revision history, you can think of this step as permitting Git to record changes.
|
|
||||||
|
|
||||||
#### Git commit
|
|
||||||
|
|
||||||
Your file is now staged. All that means is Git is aware that the file exists and is aware that it has been changed since the last time Git was made aware of it.
|
|
||||||
|
|
||||||
A Git commit sends your file into Git's internal and eternal archives. If you're used to word processors, this is similar to naming a revision. To create a commit, enter some descriptive text in the **Commit** message box at the bottom of the **Git** tab. You can be vague or cheeky, but it's more useful if you enter useful information for your future self so that you know why the revision was made.
|
|
||||||
|
|
||||||
The first time you make a commit, you must create a branch. Git branches are a little like alternate realities, allowing you to switch from one timeline to another to make changes that you may or may not want to keep forever. If you end up liking the changes, you can merge one experimental branch into another, thereby unifying different versions of your project. It's an advanced process that's not worth learning upfront, but you still need an active branch, so you have to create one for your first commit.
|
|
||||||
|
|
||||||
Click on the **Branch** icon at the very bottom of the **Git** tab to create a new branch.
|
|
||||||
|
|
||||||
![Creating a branch][14]
|
|
||||||
|
|
||||||
It's customary to name your first branch **master**. You don't have to; you can name it **firstdraft** or whatever you like, but adhering to the local customs can sometimes make talking about Git (and looking up answers to questions) a little easier because you'll know that when someone mentions **master** , they really mean **master** and not **firstdraft** or whatever you called your branch.
|
|
||||||
|
|
||||||
On some versions of Atom, the UI may not update to reflect that you've created a new branch. Don't worry; the branch will be created (and the UI updated) once you make your commit. Press the **Commit** button, whether it reads **Create detached commit** or **Commit to master**.
|
|
||||||
|
|
||||||
Once you've made a commit, the state of your file is preserved forever in Git's memory.
|
|
||||||
|
|
||||||
#### History and Git diff
|
|
||||||
|
|
||||||
A natural question is how often you should make a commit. There's no one right answer to that. Saving a file with **Ctrl+S** and committing to Git are two separate processes, so you will continue to do both. You'll probably want to make commits whenever you feel like you've done something significant or are about to try out a crazy new idea that you may want to back out of.
|
|
||||||
|
|
||||||
To get a feel for what impact a commit has on your workflow, remove some text from your test document and add some text to the top and bottom. Make another commit. Do this a few times until you have a small history at the bottom of your **Git** tab, then click on a commit to view it in Atom.
|
|
||||||
|
|
||||||
![Viewing differences][15]
|
|
||||||
|
|
||||||
When viewing a past commit, you see three elements:
|
|
||||||
|
|
||||||
1. Text in green was added to a document when the commit was made.
|
|
||||||
2. Text in red was removed from the document when the commit was made.
|
|
||||||
3. All other text was untouched.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Remote backup
|
|
||||||
|
|
||||||
One of the advantages of using Git is that, by design, it is distributed, meaning you can commit your work to your local repository and push your changes out to any number of servers for backup. You can also pull changes in from those servers so that whatever device you happen to be working on always has the latest changes.
|
|
||||||
|
|
||||||
For this to work, you must have an account on a Git server. There are several free hosting services out there, including GitHub, the company that produces Atom but oddly is not open source, and GitLab, which is open source. Preferring open source to proprietary, I'll use GitLab in this example.
|
|
||||||
|
|
||||||
If you don't already have a GitLab account, sign up for one and start a new project. The project name doesn't have to match your project folder in Atom, but it probably makes sense if it does. You can leave your project private, in which case only you and anyone you give explicit permissions to can access it, or you can make it public if you want it to be available to anyone on the internet who stumbles upon it.
|
|
||||||
|
|
||||||
Do not add a README to the project.
|
|
||||||
|
|
||||||
Once the project is created, it provides you with instructions on how to set up the repository. This is great information if you decide to use Git in a terminal or with a separate GUI, but Atom's workflow is different.
|
|
||||||
|
|
||||||
Click the **Clone** button in the top-right of the GitLab interface. This reveals the address you must use to access the Git repository. Copy the **SSH** address (not the **https** address).
|
|
||||||
|
|
||||||
In Atom, click on your project's **.git** directory and open the **config**. Add these configuration lines to the file, adjusting the **seth/example.git** part of the **url** value to match your unique address.
|
|
||||||
|
|
||||||
* * *
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
[remote "origin"]
|
|
||||||
url = [git@gitlab.com][16]:seth/example.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
|
||||||
[branch "master"]
|
|
||||||
remote = origin
|
|
||||||
merge = refs/heads/master
|
|
||||||
```
|
|
||||||
|
|
||||||
At the bottom of the **Git** tab, a new button has appeared, labeled **Fetch**. Since your server is brand new and therefore has no data for you to fetch, right-click on the button and select **Push**. This pushes your changes to your Gitlab account, and now your project is backed up on a Git server.
|
|
||||||
|
|
||||||
Pushing changes to a server is something you can do after each commit. It provides immediate offsite backup and, since the amount of data is usually minimal, it's practically as fast as a local save.
|
|
||||||
|
|
||||||
### Writing and Git
|
|
||||||
|
|
||||||
Git is a complex system, useful for more than just revision tracking and backups. It enables asynchronous collaboration and encourages experimentation. This article has covered the basics, but there are many more articles—and entire books—on Git and how to use it to make your work more efficient, more resilient, and more dynamic. It all starts with using Git for small tasks. The more you use it, the more questions you'll find yourself asking, and eventually the more tricks you'll learn.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
via: https://opensource.com/article/19/4/write-git
|
|
||||||
|
|
||||||
作者:[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/sethhttps://opensource.com/users/noreplyhttps://opensource.com/users/seth
|
|
||||||
[b]: https://github.com/lujun9972
|
|
||||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/write-hand_0.jpg?itok=Uw5RJD03 (Writing Hand)
|
|
||||||
[2]: https://git-scm.com/
|
|
||||||
[3]: https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages
|
|
||||||
[4]: http://atom.io
|
|
||||||
[5]: https://git-scm.com/download/mac
|
|
||||||
[6]: https://git-scm.com/download/win
|
|
||||||
[7]: http://gnu.org/software/emacs
|
|
||||||
[8]: https://commonmark.org/help/
|
|
||||||
[9]: https://opensource.com/sites/default/files/uploads/atom-preview.jpg (Atom's preview screen)
|
|
||||||
[10]: https://opensource.com/sites/default/files/uploads/atom-para.jpg (Writing in Atom)
|
|
||||||
[11]: https://opensource.com/sites/default/files/uploads/atom-linebreak.jpg (Writing in Atom)
|
|
||||||
[12]: https://atom.io/themes
|
|
||||||
[13]: https://opensource.com/sites/default/files/uploads/atom-theme.jpg (Atom's themes)
|
|
||||||
[14]: https://opensource.com/sites/default/files/uploads/atom-branch.jpg (Creating a branch)
|
|
||||||
[15]: https://opensource.com/sites/default/files/uploads/git-diff.jpg (Viewing differences)
|
|
||||||
[16]: mailto:git@gitlab.com
|
|
@ -1,5 +1,5 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: ( )
|
[#]: translator: (lnrCoder)
|
||||||
[#]: reviewer: ( )
|
[#]: reviewer: ( )
|
||||||
[#]: publisher: ( )
|
[#]: publisher: ( )
|
||||||
[#]: url: ( )
|
[#]: url: ( )
|
||||||
@ -243,7 +243,7 @@ via: https://itsfoss.com/install-postgresql-ubuntu/
|
|||||||
|
|
||||||
作者:[Sergiu][a]
|
作者:[Sergiu][a]
|
||||||
选题:[lujun9972][b]
|
选题:[lujun9972][b]
|
||||||
译者:[译者ID](https://github.com/译者ID)
|
译者:[lnrCoder](https://github.com/lnrCoder)
|
||||||
校对:[校对者ID](https://github.com/校对者ID)
|
校对:[校对者ID](https://github.com/校对者ID)
|
||||||
|
|
||||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: ( )
|
[#]: translator: (wxy)
|
||||||
[#]: reviewer: ( )
|
[#]: reviewer: ( )
|
||||||
[#]: publisher: ( )
|
[#]: publisher: ( )
|
||||||
[#]: url: ( )
|
[#]: url: ( )
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: ( )
|
[#]: translator: (wenwensnow)
|
||||||
[#]: reviewer: ( )
|
[#]: reviewer: ( )
|
||||||
[#]: publisher: ( )
|
[#]: publisher: ( )
|
||||||
[#]: url: ( )
|
[#]: url: ( )
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: ( )
|
[#]: translator: (geekpi)
|
||||||
[#]: reviewer: ( )
|
[#]: reviewer: ( )
|
||||||
[#]: publisher: ( )
|
[#]: publisher: ( )
|
||||||
[#]: url: ( )
|
[#]: url: ( )
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
[#]: collector: (lujun9972)
|
|
||||||
[#]: translator: ( )
|
|
||||||
[#]: reviewer: ( )
|
|
||||||
[#]: publisher: ( )
|
|
||||||
[#]: url: ( )
|
|
||||||
[#]: subject: (4 Free and Open Source Alternatives to Adobe Photoshop)
|
|
||||||
[#]: via: (https://itsfoss.com/open-source-photoshop-alternatives/)
|
|
||||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
|
||||||
|
|
||||||
4 Free and Open Source Alternatives to Adobe Photoshop
|
|
||||||
======
|
|
||||||
|
|
||||||
_**Looking for a free Photoshop alternative? Here are some of the best free and open source software that you can use instead of Adobe Photoshop.**_
|
|
||||||
|
|
||||||
Adobe Photoshop is a premium image editing and design tool available for Windows and macOS. Undoubtedly, almost everyone knows about it. It’s that popular. Well, you can use Photoshop on Linux using Windows in a virtual machine or by [using Wine][1] – but that is not an ideal experience.
|
|
||||||
|
|
||||||
In general, we don’t have a lot of options available as a replacement for Adobe Photoshop. However, in this article, we shall mention some of the best open-source Photoshop alternatives available for Linux (with cross-platform support as well).
|
|
||||||
|
|
||||||
Do note that Photoshop is not just a photo editor. It’s used by photographers, digital artists, professional editors for various usage. The alternative software here may not have all the features of Photoshop but you can use them for various task that you do in Photoshop.
|
|
||||||
|
|
||||||
### Open Source Alternatives to Adobe Photoshop for Linux, Windows and macOS
|
|
||||||
|
|
||||||
![][2]
|
|
||||||
|
|
||||||
Initially, I thought of focusing only on Photoshop alternatives for Linux but why confine this list for Linux only? Other operating system users should also use the open source software.
|
|
||||||
|
|
||||||
_**If you are using Linux, all the mentioned software should be available in the repositories of your distribution. You can install it using the software center or the package manager.**_
|
|
||||||
|
|
||||||
For other platforms, please check the official project websites to get the installer files.
|
|
||||||
|
|
||||||
_The list is in no particular order of ranking_.
|
|
||||||
|
|
||||||
#### 1\. GIMP: The true Photoshop alternative
|
|
||||||
|
|
||||||
![][3]
|
|
||||||
|
|
||||||
Key Features:
|
|
||||||
|
|
||||||
* Customizable Interface
|
|
||||||
* Digital Retouching
|
|
||||||
* Photo Enhancement (using transform tools)
|
|
||||||
* Wide range of hardware support (pressure-sensitive tablets, MIDIs, etc.)
|
|
||||||
* Almost every major image file supported
|
|
||||||
* Layer management support
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Platforms available for:** Linux, Windows and macOS
|
|
||||||
|
|
||||||
[GIMP][4] is my go-to tool for everything – no matter how basic/advanced the task is. Probably, this is the closest that you will get as a replacement for Photoshop on Linux. In addition to this, it is an open source and free solution for an artist looking to create great artwork on Linux.
|
|
||||||
|
|
||||||
It features all the necessary features for any kind of image manipulation. Of course, there’s layer management support. Depending on your experience level – the utilization will differ. So, if you are looking to make the most out of it, you should read the [documentation][5] and follow the [official tutorials][6].
|
|
||||||
|
|
||||||
#### 2\. Krita
|
|
||||||
|
|
||||||
![][7]
|
|
||||||
|
|
||||||
Key Features:
|
|
||||||
|
|
||||||
* Layer management support
|
|
||||||
* Transformation tools
|
|
||||||
* Variety of brushes/drawing tools
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Platforms available for:** Linux, Windows and macOS
|
|
||||||
|
|
||||||
[Krita][8] is an impressive open source tool for digital painting. The layer management support and the presence of transformation tools help makes it one of the Photoshop alternatives for basic editing tasks.
|
|
||||||
|
|
||||||
If you’re into sketching/drawing, this will help you a lot.
|
|
||||||
|
|
||||||
#### 3\. Darktable
|
|
||||||
|
|
||||||
![][9]
|
|
||||||
|
|
||||||
Key Features:
|
|
||||||
|
|
||||||
* Develop RAW images
|
|
||||||
* Variety of Image formats supported
|
|
||||||
* Several Image operation modules with blending operators
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Platforms available for**: Linux, Windows and macOS
|
|
||||||
|
|
||||||
[Darktable][10] is an open source photography workflow application made by photographers. It lets you manage your digital negatives in a database. From your collection, develop raw images and enhance them using the tools available.
|
|
||||||
|
|
||||||
Starting from the basic image editing tools to several image modules supporting blending operators, you will find a lot of things as you explore.
|
|
||||||
|
|
||||||
#### 4\. Inkscape
|
|
||||||
|
|
||||||
![][11]
|
|
||||||
|
|
||||||
Key Features:
|
|
||||||
|
|
||||||
* Tools for object creation (best for drawing/sketching)
|
|
||||||
* Layer management support
|
|
||||||
* Transformation tools for image manipulation
|
|
||||||
* Color selector (RGB, HSL, CMYK, color wheel, CMS)
|
|
||||||
* Support for all major file formats
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Platforms available for**: Linux, Windows and macOS
|
|
||||||
|
|
||||||
[Inkscape][12] is a quite popular open-source vector graphics editor used by many professionals. It provides flexible designing tools to help you create/manipulate beautiful artworks. It is technically a direct alternative to Adobe Illustrator – but it pulls off some tricks that can help you utilize this as a Photoshop alternative as well.
|
|
||||||
|
|
||||||
Similar to GIMP’s official resources, you can utilize [Inkscape’s tutorials][13] to make the most out of it.
|
|
||||||
|
|
||||||
**What’s the true Photoshop alternative in your opinion?**
|
|
||||||
|
|
||||||
It’s tough to offer the exact same features that Adobe Photoshop provides. However, if you follow the official documentations and resources, you can do a lot of great stuff using the above-mentioned Photoshop alternatives.
|
|
||||||
|
|
||||||
Adobe has a range of grpahics tools and we have [open source alternatives to entire Adobe Creative Suite][14]. You may check that out as well.
|
|
||||||
|
|
||||||
What do you think about the Photoshop alternatives that we mentioned here? Do you know about any better alternative that deserves the mention? Let us know about it in the comments below.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
via: https://itsfoss.com/open-source-photoshop-alternatives/
|
|
||||||
|
|
||||||
作者:[Ankush Das][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/ankush/
|
|
||||||
[b]: https://github.com/lujun9972
|
|
||||||
[1]: https://itsfoss.com/install-latest-wine/
|
|
||||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/10/open_source_photoshop_alternatives.png?ssl=1
|
|
||||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/08/gimp-screenshot.jpg?ssl=1
|
|
||||||
[4]: https://www.gimp.org/
|
|
||||||
[5]: https://www.gimp.org/docs/
|
|
||||||
[6]: https://www.gimp.org/tutorials/
|
|
||||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/krita-paint.png?ssl=1
|
|
||||||
[8]: https://krita.org/
|
|
||||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/darktable.jpg?ssl=1
|
|
||||||
[10]: https://www.darktable.org/
|
|
||||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2017/12/inkscape-screenshot.jpg?ssl=1
|
|
||||||
[12]: https://inkscape.org/
|
|
||||||
[13]: https://inkscape.org/learn/
|
|
||||||
[14]: https://itsfoss.com/adobe-alternatives-linux/
|
|
@ -0,0 +1,261 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: ( )
|
||||||
|
[#]: publisher: ( )
|
||||||
|
[#]: url: ( )
|
||||||
|
[#]: subject: (How writers can get work done better with Git)
|
||||||
|
[#]: via: (https://opensource.com/article/19/4/write-git)
|
||||||
|
[#]: author: (Seth Kenlon https://opensource.com/users/sethhttps://opensource.com/users/noreplyhttps://opensource.com/users/seth)
|
||||||
|
|
||||||
|
用 Git 帮助写作者更好地完成工作
|
||||||
|
======
|
||||||
|
|
||||||
|
> 如果你是一名写作者,你也能从使用 Git 中受益。在我们的系列文章中了解有关 Git 鲜为人知的用法。
|
||||||
|
|
||||||
|
![Writing Hand][1]
|
||||||
|
|
||||||
|
[Git][2] 是一个少有的能将如此多的现代计算封装到一个程序之中的应用程序,它可以用作许多其他应用程序的计算引擎。虽然它以跟踪软件开发中的源代码更改而闻名,但它还有许多其他用途,可以让你的生活更轻松、更有条理。在这个 Git 系列中,我们将分享七种鲜为人知的使用 Git 的方法。
|
||||||
|
|
||||||
|
今天我们来看看写作者如何使用 Git 更好的地完成工作。
|
||||||
|
|
||||||
|
### 写作者的 Git
|
||||||
|
|
||||||
|
有些人写小说,也有人撰写学术论文、诗歌、剧本、技术手册或有关开源的文章。许多人都在做一点各种写作。相同的是,如果你是一名写作者,则或许能从使用 Git 中受益。尽管 Git 是著名的计算机程序员所使用的高度技术性工具,但它也是现代写作者的理想之选,本文将向你演示如何改变你的书写方式以及为什么要这么做的原因。
|
||||||
|
|
||||||
|
但是,在谈论 Git 之前,重要的是先谈谈“副本”(或者叫“内容”,对于数字时代而言)到底是什么,以及为什么它与你的交付*媒介*不同。这是 21 世纪,大多数写作者选择的工具是计算机。尽管计算机看似擅长将副本的编辑和布局等过程结合在一起,但写作者还是(重新)发现将内容与样式分开是一个好主意。这意味着你应该在计算机上像在打字机上而不是在文字处理器中进行书写。以计算机术语而言,这意味着以*纯文本*形式写作。
|
||||||
|
|
||||||
|
### 以纯文本写作
|
||||||
|
|
||||||
|
这个假设曾经是毫无疑问的:你知道自己的写作所要针对的市场,你可以为书籍、网站或软件手册等不同市场编写内容。但是,近来各种市场趋于扁平化:你可能决定在纸质书中使用为网站编写的内容,并且纸质书可能会在以后发布 EPUB 版本。对于你的内容的数字版本,读者才是最终控制者:他们可以在你发布内容的网站上阅读你的文字,也可以点击 Firefox 出色的[阅读视图][3],还可能会打印到纸张上,或者可能会使用 Lynx 将网页转储到文本文件中,甚至可能因为使用屏幕阅读器而根本看不到你的内容。
|
||||||
|
|
||||||
|
你只需要逐字写下你的内容,而将交付工作留给发布者。即使你是自己发布,将字词作为写作作品的一种源代码也是一种更聪明、更有效的工作方式,因为在发布时,你可以使用相同的源(你的纯文本)生成适合你的目标输出(用于打印的 PDF、用于电子书的 EPUB、用于网站的 HTML 等)。
|
||||||
|
|
||||||
|
用纯文本编写不仅意味着你不必担心布局或文本样式,而且也不再需要专门的工具。无论是手机或平板电脑上的基本记事本应用程序、计算机附带的文本编辑器,还是从互联网上下载的免费编辑器,任何能够产生文本内容的工具对你而言都是有效的“文字处理器”。无论你身在何处或在做什么,几乎可以在任何设备上书写,并且所生成的文本可以与你的项目完美集成,而无需进行任何修改。
|
||||||
|
|
||||||
|
而且,Git 专门用来管理纯文本。
|
||||||
|
|
||||||
|
### Atom 编辑器
|
||||||
|
|
||||||
|
当你以纯文本形式书写时,文字处理程序会显得过于庞大。使用文本编辑器更容易,因为文本编辑器不会尝试“有效地”重组输入内容。它使你可以将脑海中的单词输入到屏幕中,而不会受到干扰。更好的是,文本编辑器通常是围绕插件体系结构设计的,这样应用程序本身就很基础(它用来编辑文本),但是你可以围绕它构建一个环境来满足你的各种需求。
|
||||||
|
|
||||||
|
[Atom][4] 编辑器就是这种设计理念的一个很好的例子。这是一个具有内置 Git 集成的跨平台文本编辑器。如果你不熟悉纯文本格式,也不熟悉 Git,那么 Atom 是最简单的入门方法。
|
||||||
|
|
||||||
|
#### 安装 Git 和 Atom
|
||||||
|
|
||||||
|
首先,请确保你的系统上已安装 Git。如果运行 Linux 或 BSD,则 Git 在软件存储库或 ports 树中可用。你使用的命令将根据你的发行版而有所不同。例如在 Fedora 上:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo dnf install git
|
||||||
|
```
|
||||||
|
|
||||||
|
你也可以下载并安装适用于 [Mac][5] 和 [Windows][6] 的 Git。
|
||||||
|
|
||||||
|
你不需要直接使用 Git,因为 Atom 会充当你的 Git 界面。下一步是安装 Atom。
|
||||||
|
|
||||||
|
如果你使用的是 Linux,请通过软件安装程序或适当的命令从软件存储库中安装 Atom,例如:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo dnf install atom
|
||||||
|
```
|
||||||
|
|
||||||
|
Atom 当前没有在 BSD 上构建。但是,有很好的替代方法,例如 [GNU Emacs][7]。对于 Mac 和 Windows 用户,可以在 [Atom 网站][4]上找到安装程序。
|
||||||
|
|
||||||
|
安装完成后,启动 Atom 编辑器。
|
||||||
|
|
||||||
|
#### 快速指导
|
||||||
|
|
||||||
|
如果要使用纯文本和 Git,则需要适应你的编辑器。Atom 的用户界面可能比你习惯的更加动态。实际上,你可以将它视为 Firefox 或 Chrome,而不是文字处理程序,因为它具有可以根据需要打开和关闭的选项卡和面板,甚至还可以安装和配置附件。尝试全部掌握 Atom 如许之多的功能是不切实际的,但是你至少可以知道有什么功能。
|
||||||
|
|
||||||
|
当 Atom 打开时,它将显示一个欢迎屏幕。如果不出意外,此屏幕很好地介绍了 Atom 的选项卡式界面。你可以通过单击 Atom 窗口顶部选项卡上的“关闭”图标来关闭欢迎屏幕,并使用“文件 > 新建文件”创建一个新文件。
|
||||||
|
|
||||||
|
使用纯文本格式与使用文字处理程序有点不同,因此这里有一些技巧,以人可以连接的方式编写内容,并且 Git 和计算机可以解析,跟踪和转换。
|
||||||
|
|
||||||
|
#### 用 Markdown 书写
|
||||||
|
|
||||||
|
如今,当人们谈论纯文本时,大多是指 Markdown。Markdown 与其说是格式,不如说是样式,这意味着它旨在为文本提供可预测的结构,以便计算机可以检测自然的模式并智能地转换文本。Markdown 有很多定义,但是最好的技术定义和备忘单在 [CommonMark 的网站][8]上。
|
||||||
|
|
||||||
|
```
|
||||||
|
# Chapter 1
|
||||||
|
|
||||||
|
This is a paragraph with an *italic* word and a **bold** word in it.
|
||||||
|
And it can even reference an image.
|
||||||
|
|
||||||
|
![An image will render here.](drawing.jpg)
|
||||||
|
```
|
||||||
|
|
||||||
|
从示例中可以看出,Markdown 读起来感觉不像代码,但可以将其视为代码。如果你遵循 CommonMark 定义的 Markdown 规范,那么一键就可以可靠地将 Markdown 的文字转换为 .docx、.epub、.html、MediaWiki、.odt、.pdf、.rtf 和各种其他的格式,而*不会*失去格式。
|
||||||
|
|
||||||
|
你可以认为 Markdown 有点像文字处理程序的样式。如果你曾经为出版社撰写过一套样式来控制章节标题和章节标题的样式,那基本上就是一回事,除了不是从下拉菜单中选择样式以外,你要给你的文字添加一些小记号。对于任何习惯“以文字交谈”的现代阅读者来说,这些表示法都是很自然的,但是在呈现文本时,它们会被精美的文本样式替换掉。实际上,这是文字处理程序在后台秘密进行的操作。文字处理器显示粗体文本,但是如果你可以看到使文本变为粗体的生成代码,则它与 Markdown 很像(实际上,它是更复杂的 XML)。使用 Markdown 可以消除这种代码和样式之间的阻隔,一方面看起来更可怕,但另一方面,你可以在几乎所有可以生成文本的东西上书写 Markdown 而不会丢失任何格式信息。
|
||||||
|
|
||||||
|
Markdown 文件流行d 文件扩展名是 .md。如果你使用的平台不知道 .md 文件是什么,则可以手动将扩展名与 Atom 关联,或者仅使用通用的 .txt 扩展名。文件扩展名不会更改文件的性质。它只会改变你的计算机决定如何处理它的方式。Atom 和某些平台足够聪明,可以知道该文件是纯文本格式,无论你给它以什么扩展名。
|
||||||
|
|
||||||
|
#### 实时预览
|
||||||
|
|
||||||
|
Atom 具有 “Markdown 预览” 插件,该插件可以向你显示正在编写的纯文本 Markdown 及其(通常)呈现的方式。
|
||||||
|
|
||||||
|
![Atom's preview screen][9]
|
||||||
|
|
||||||
|
要激活此预览窗格,请选择“包 > Markdown 预览 > 切换预览” 或按 `Ctrl + Shift + M`。
|
||||||
|
|
||||||
|
此视图为你提供了两全其美的方法。无需承担为你的文本添加样式的负担,就可以写作,而你也可以看到一个通用的示例外观,至少是以典型的数字化格式显示了文本的外观。当然,关键是你无法控制文本的最终呈现方式,因此不要试图调整 Markdown 来强制以某种方式显示呈现的预览。
|
||||||
|
|
||||||
|
#### 每行一句话
|
||||||
|
|
||||||
|
你的高中写作老师不会看你的 Markdown。
|
||||||
|
|
||||||
|
一开始它并那么自然,但是在数字世界中,保持每行一个句子更有意义。Markdown 忽略单个换行符(当你按下 Return 或 Enter 键时),并且只在单个空行之后才会创建一个新段落。
|
||||||
|
|
||||||
|
![Writing in Atom][10]
|
||||||
|
|
||||||
|
每行写一个句子的好处是你的工作更容易跟踪。也就是说,如果你在段落的开头更改了一个单词,那么如果更改仅限于一行而不是一个长的段落中的一个单词,那么 Atom、Git 或任何应用程序很容易以有意义的方式突出显示该更改。换句话说,对一个句子的更改只会影响该句子,而不会影响整个段落。
|
||||||
|
|
||||||
|
你可能会想:“许多文字处理器也可以跟踪更改,它们可以突出显示已更改的单个单词。”但是这些修订跟踪器绑定到该字处理器的界面上,这意味着你必须先打开该字处理器才能浏览修订。在纯文本工作流程中,你可以以纯文本形式查看修订,这意味着无论手头有什么,只要该设备可以处理纯文本(大多数都可以),就可以进行编辑或批准编辑。
|
||||||
|
|
||||||
|
诚然,写作者通常不会考虑行号,但它对于计算机有用,并且通常是一个很好的参考点。默认情况下,Atom 为文本文档的行进行编号。按下 Enter 键或 Return 键后,一*行*就是一行。
|
||||||
|
|
||||||
|
![Writing in Atom][11]
|
||||||
|
|
||||||
|
如果一行中有一个点而不是一个数字,则表示它是上一行折叠的一部分,因为它不超出了你的屏幕。
|
||||||
|
|
||||||
|
#### 主题
|
||||||
|
|
||||||
|
如果你是一个在意视觉形象的人,那么你可能会非常注重自己的写作环境。即使你使用普通的 Markdown 进行编写,也并不意味着你必须使用程序员的字体或在使你看起来像码农的黑窗口中进行书写。修改 Atom 外观的最简单方法是使用[主题包][12]。主题设计人员通常将深色主题与浅色主题区分开,因此你可以根据需要使用关键字“Dark”或“Light”进行搜索。
|
||||||
|
|
||||||
|
要安装主题,请选择“编辑 > 首选项”。这将在 Atom 界面中打开一个新标签页。是的,标签页可以用于处理文档*和*用于配置及控制面板。在“设置”标签页中,单击“安装”类别。
|
||||||
|
|
||||||
|
在“安装”面板中,搜索要安装的主题的名称。单击搜索字段右侧的“主题”按钮,以仅搜索主题。找到主题后,单击其“安装”按钮。
|
||||||
|
|
||||||
|
![Atom's themes][13]
|
||||||
|
|
||||||
|
要使用已安装的主题或根据喜好自定义主题,请导航至“设置”标签页中的“主题”类别中。从下拉菜单中选择要使用的主题。更改会立即进行,因此你可以准确了解主题如何影响您的环境。
|
||||||
|
|
||||||
|
你也可以在“设置”标签的“编辑器”类别中更改工作字体。Atom 默认采用等宽字体,程序员通常首选这种字体。但是你可以使用系统上的任何字体,无论是衬线字体、无衬线字体、哥特式字体还是草书字体。无论你想整天盯着什么字体都行。
|
||||||
|
|
||||||
|
作为相关说明,默认情况下,Atom 会在其屏幕上绘制一条垂直线,以提示编写代码的人员。程序员通常不想编写太长的代码行,因此这条垂直线会提醒他们不要写太长的代码行。不过,这条竖线对写作者而言毫无意义,你可以通过禁用 “wrap-guide” 包将其删除。
|
||||||
|
|
||||||
|
要禁用 “wrap-guide” 软件包,请在“设置”标签中选择“折行”类别,然后搜索 “wrap-guide”。找到该程序包后,单击其“禁用”按钮。
|
||||||
|
|
||||||
|
#### 动态结构
|
||||||
|
|
||||||
|
创建长文档时,我发现每个文件写一个章节比在一个文件中写整本书更有意义。此外,我不会以明显的语法 ` chapter-1.md` 或 `1.example.md` 来命名我的章节,而是以章节标题或关键词(例如 `example.md`)命名。为了将来为自己提供有关如何编写本书的指导,我维护了一个名为 `toc.md` (用于“目录”)的文件,其中列出了各章的(当前)顺序。
|
||||||
|
|
||||||
|
我这样做是因为,无论我多么相信第 6 章都不可能出现在第 1 章之前,但在我完成整本书之前,几乎不大可能出现我不会交换一两个章节的顺序。我发现从一开始就保持动态变化可以帮助我避免重命名混乱,也可以帮助我避免僵化的结构。
|
||||||
|
|
||||||
|
### 在 Atom 中使用 Git
|
||||||
|
|
||||||
|
每位写作者的共同点是两件事:他们为流传而写作,而他们的写作是一段旅程。你无需坐下来写作就完成最终稿件。顾名思义,你有一个初稿。该草稿会经过修订,你会仔细地将每个修订保存一式两份或三份,以防万一你的文件损坏了。最终,你得到了所谓的最终草案,但很有可能你有一天还会回到这份最终草案,要么恢复好的部分要么修改坏的部分。
|
||||||
|
|
||||||
|
Atom 最令人兴奋的功能是其强大的 Git 集成。无需离开 Atom,你就可以与 Git 的所有主要功能进行交互,跟踪和更新项目、回滚你不喜欢的更改、集成来自协作者的更改等等。最好的学习方法就是逐步学习,因此这是从写作项目开始到结束在 Atom 界面中使用 Git 的方法。
|
||||||
|
|
||||||
|
第一件事:通过选择 “视图 > 切换 Git 标签页” 来显示 Git 面板。这将在 Atom 界面的右侧打开一个新标签页。现在没什么可看的,所以暂时保持打开状态就行。
|
||||||
|
|
||||||
|
#### 建立一个 Git 项目
|
||||||
|
|
||||||
|
你可以将 Git 视为它被绑定到文件夹。Git 目录之外的任何文件夹都不知道 Git,而 Git 也不知道外面。Git 目录中的文件夹和文件将被忽略,直到你授予 Git 权限来跟踪它们为止。
|
||||||
|
|
||||||
|
你可以通过在 Atom 中创建新的项目文件夹来创建 Git 项目。选择 “文件 > 添加项目文件夹”,然后在系统上创建一个新文件夹。你创建的文件夹将出现在 Atom 窗口的左侧“项目面板”中。
|
||||||
|
|
||||||
|
#### Git 添加文件
|
||||||
|
|
||||||
|
右键单击你的新项目文件夹,然后选择“新建文件”以在项目文件夹中创建一个新文件。如果你要导入文件到新项目中,请右键单击该文件夹,然后选择“在文件管理器中显示”,以在系统的文件查看器中打开该文件夹(Linux 上为 Dolphin 或 Nautilus,Mac 上为 Finder,在 Windows 上是 Explorer),然后拖放文件到你的项目文件夹。
|
||||||
|
|
||||||
|
在 Atom 中打开一个项目文件(你创建的空文件或导入的文件)后,单击 Git 标签中的 “<ruby>创建存储库<rt>Create Repository</rt></ruby>” 按钮。在弹出的对话框中,单击 “<ruby>初始化<rt>Init</rt></ruby>” 以将你的项目目录初始化为本地 Git 存储库。 Git 会将 `.git` 目录(在系统的文件管理器中不可见,但在 Atom 中可见)添加到项目文件夹中。不要被这个愚弄了:`.git` 目录是 Git 管理的,而不是由你管理的,因此你一般不要动它。但是在 Atom 中看到它可以很好地提醒你正在由 Git 管理的项目中工作。换句话说,当你看到 `.git` 目录时,就有了修订历史记录。
|
||||||
|
|
||||||
|
在你的空文件中,写一些东西。你是写作者,所以输入一些单词就行。你可以随意输入任何一组单词,但要记住上面的写作技巧。
|
||||||
|
|
||||||
|
按 `Ctrl + S` 保存文件,该文件将显示在 Git 标签的 “<ruby>未暂存的改变<rt>Unstaged Changes</rt></ruby>” 部分中。这意味着该文件存在于你的项目文件夹中,但尚未提交给 Git 管理。通过单击 Git 选项卡右上方的 “<ruby>暂存全部<rt>Stage All</rt></ruby>” 按钮,允许 Git 跟踪这些文件。如果你使用过带有修订历史记录的文字处理器,则可以将此步骤视为允许 Git记录更改。
|
||||||
|
|
||||||
|
#### Git 提交
|
||||||
|
|
||||||
|
你的文件现在已暂存。这意味着 Git 知道该文件存在,并且知道自上次 Git 知道该文件以来,该文件已被更改。
|
||||||
|
|
||||||
|
Git 的<ruby>提交<rt>commit</rt></ruby>会将你的文件发送到 Git 的内部和永久存档中。如果你习惯于文字处理程序,这就类似于给一个修订版命名。要创建一个提交,请在 Git 选项卡底部的“<ruby>提交<rt>Commit</rt></ruby>”消息框中输入一些描述性文本。你可能会感到含糊不清或随意写点什么,但如果你想在将来知道进行修订的原因,那么输入一些有用的信息会更有用。
|
||||||
|
|
||||||
|
第一次提交时,必须创建一个<ruby>分支<rt>branch</rt></ruby>。Git 分支有点像另外一个空间,它允许你从一个时间轴切换到另一个时间轴,以进行你可能想要或可能不想要永久保留的更改。如果最终喜欢该更改,则可以将一个实验分支合并到另一个实验分支,从而统一项目的不同版本。这是一个高级过程,不需要先学会,但是你仍然需要一个活动分支,因此你必须为首次提交创建一个分支。
|
||||||
|
|
||||||
|
单击 Git 选项卡最底部的“<ruby>分支<rt>Branch</rt></ruby>”图标,以创建新的分支。
|
||||||
|
|
||||||
|
![Creating a branch][14]
|
||||||
|
|
||||||
|
通常将第一个分支命名为 `master`,但不是必须如此;你可以将其命名为 `firstdraft` 或任何你喜欢的名称,但是遵守当地习俗有时会使谈论 Git(和查找问题的答案)变得容易一些,因为你会知道有人提到 “master” 时,它们的真正意思是“主干”而不是“初稿”或你给分支起的什么名字。
|
||||||
|
|
||||||
|
在某些版本的 Atom 上,UI 也许不会更新以反映你已经创建的新分支。不用担心,做了提交之后,它会创建分支(并更新 UI)。按下 “<ruby>提交<rt>Commit</rt></ruby>” 按钮,无论它显示的是 “<ruby>创建脱离的提交<rt>Create detached commit</rt></ruby>” 还是 “<ruby>提交到主干<rt>Commit to master</rt></ruby>。
|
||||||
|
|
||||||
|
提交后,文件的状态将永久保留在 Git 的记忆之中。
|
||||||
|
|
||||||
|
#### 历史记录和 Git 差异
|
||||||
|
|
||||||
|
一个自然而然的问题是你应该多久做一次提交。这并没有正确的答案。使用 `Ctrl + S` 保存文件并提交到 Git 是两个单独的过程,因此你会一直做这两个过程。每当你觉得自己已经做了重要的事情或打算尝试一个可能要被干掉的疯狂的新想法时,你可能都会想要做个提交。
|
||||||
|
|
||||||
|
要了解提交对工作流程的影响,请从测试文档中删除一些文本,然后在顶部和底部添加一些文本。再次提交。 这样做几次,直到你在 Git 标签的底部有了一小段历史记录,然后单击其中一个提交以在 Atom 中查看它。
|
||||||
|
|
||||||
|
![Viewing differences][15]
|
||||||
|
|
||||||
|
查看过去的提交时,你会看到三种元素:
|
||||||
|
|
||||||
|
1. 绿色文本是该提交中已被添加到文档中的内容。
|
||||||
|
2. 红色文本是该提交中已从文档中删除的内容。
|
||||||
|
3. 其他所有文字均未做更改。
|
||||||
|
|
||||||
|
#### 远程备份
|
||||||
|
|
||||||
|
使用 Git 的优点之一是,按照设计,它是分布式的,这意味着你可以将工作提交到本地存储库,并将所做的更改推送到任意数量的服务器上进行备份。你还可以从这些服务器中拉取更改,以便你碰巧正在使用的任何设备始终具有最新更改。
|
||||||
|
|
||||||
|
为此,你必须在 Git 服务器上拥有一个帐户。有几种免费的托管服务,其中包括 GitHub,这个公司开发了 Atom,但奇怪的是 GitHub 不是开源的;而 GitLab 是开源的。相比私有的,我更喜欢开源,在本示例中,我将使用 GitLab。
|
||||||
|
|
||||||
|
如果你还没有 GitLab 帐户,请注册一个帐户并开始一个新项目。项目名称不必与 Atom 中的项目文件夹匹配,但是如果匹配,则可能更有意义。你可以将项目保留为私有,在这种情况下,只有你和任何一个你给予了明确权限的人可以访问它,或者,如果你希望该项目可供任何互联网上偶然发现它的人使用,则可以将其公开。
|
||||||
|
|
||||||
|
不要将 README 文件添加到项目中。
|
||||||
|
|
||||||
|
创建项目后,这个文件将为你提供有关如何设置存储库的说明。如果你决定在终端中或通过单独的 GUI 使用 Git,这是非常有用的信息,但是 Atom 的工作流程则有所不同。
|
||||||
|
|
||||||
|
单击 GitLab 界面右上方的 “<ruby>克隆<rt>Clone</rt></ruby>” 按钮。这显示了访问 Git 存储库必须使用的地址。复制 “SSH” 地址(而不是 “https” 地址)。
|
||||||
|
|
||||||
|
在 Atom 中,点击项目的 `.git` 目录,然后打开 `config` 文件。将下面这些配置行添加到该文件中,调整 `url` 值的 `seth/example.git` 部分以匹配你自己独有的地址。
|
||||||
|
|
||||||
|
```
|
||||||
|
[remote "origin"]
|
||||||
|
url = git@gitlab.com:seth/example.git
|
||||||
|
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||||
|
[branch "master"]
|
||||||
|
remote = origin
|
||||||
|
merge = refs/heads/master
|
||||||
|
```
|
||||||
|
|
||||||
|
在 Git 标签的底部,出现了一个新按钮,标记为 “<ruby>提取<rt>Fetch</rt></ruby>”。由于你的服务器是全新的服务器,因此没有可供你提取的数据,因此请右键单击该按钮,然后选择“<ruby>推送<rt>Push</rt></ruby>”。这会将你的更改推送到你的 GitLab 帐户,现在你的项目已备份到 Git 服务器上。
|
||||||
|
|
||||||
|
你可以在每次提交后将更改推送到服务器。它提供了立即的异地备份,并且由于数据量通常很少,因此它几乎与本地保存一样快。
|
||||||
|
|
||||||
|
### 撰写而 Git
|
||||||
|
|
||||||
|
Git 是一个复杂的系统,不仅对修订跟踪和备份有用。它还支持异步协作并鼓励实验。本文介绍了一些基础知识,但还有更多关于 Git 的文章和整本的书,以及如何使用它使你的工作更高效、更具弹性和更具活力。 从使用 Git 完成小任务开始,使用的次数越多,你会发现自己提出的问题就越多,最终你将学到的技巧越多。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/4/write-git
|
||||||
|
|
||||||
|
作者:[Seth Kenlon][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[wxy](https://github.com/wxy)
|
||||||
|
校对:[校对者ID](https://github.com/校对者ID)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/sethhttps://opensource.com/users/noreplyhttps://opensource.com/users/seth
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/write-hand_0.jpg?itok=Uw5RJD03 (Writing Hand)
|
||||||
|
[2]: https://git-scm.com/
|
||||||
|
[3]: https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages
|
||||||
|
[4]: http://atom.io
|
||||||
|
[5]: https://git-scm.com/download/mac
|
||||||
|
[6]: https://git-scm.com/download/win
|
||||||
|
[7]: http://gnu.org/software/emacs
|
||||||
|
[8]: https://commonmark.org/help/
|
||||||
|
[9]: https://opensource.com/sites/default/files/uploads/atom-preview.jpg (Atom's preview screen)
|
||||||
|
[10]: https://opensource.com/sites/default/files/uploads/atom-para.jpg (Writing in Atom)
|
||||||
|
[11]: https://opensource.com/sites/default/files/uploads/atom-linebreak.jpg (Writing in Atom)
|
||||||
|
[12]: https://atom.io/themes
|
||||||
|
[13]: https://opensource.com/sites/default/files/uploads/atom-theme.jpg (Atom's themes)
|
||||||
|
[14]: https://opensource.com/sites/default/files/uploads/atom-branch.jpg (Creating a branch)
|
||||||
|
[15]: https://opensource.com/sites/default/files/uploads/git-diff.jpg (Viewing differences)
|
||||||
|
[16]: mailto:git@gitlab.com
|
@ -1,305 +0,0 @@
|
|||||||
[#]: collector: (lujun9972)
|
|
||||||
[#]: translator: (Morisun029)
|
|
||||||
[#]: reviewer: ( )
|
|
||||||
[#]: publisher: ( )
|
|
||||||
[#]: url: ( )
|
|
||||||
[#]: subject: (Mutation testing is the evolution of TDD)
|
|
||||||
[#]: via: (https://opensource.com/article/19/8/mutation-testing-evolution-tdd)
|
|
||||||
[#]: author: (Alex Bunardzic https://opensource.com/users/alex-bunardzic)
|
|
||||||
|
|
||||||
变异测试是 TDD 的演变
|
|
||||||
======
|
|
||||||
测试驱动开发技术是根据大自然的运作规律创建的,变异测试自然成为 DevOps 发展的下一步。
|
|
||||||
![Ants and a leaf making the word "open"][1]
|
|
||||||
|
|
||||||
在 "[故障是无懈可击的开发运维中的一个特点][2]," 我讨论了故障以征求反馈的机制在交付优质产品过程中所起到的重要作用。 敏捷DevOps团队就是用故障来指导他们并推动开发进程的。 [测试驱动开发(TDD)][3] 是任何敏捷 DevOps 团队评估产品交付的[必要条件][4]。 以故障为中心的 TDD 方法仅在与可量化的测试配合使用时才有效。
|
|
||||||
|
|
||||||
TDD 方法仿照大自然是如何运作的以及自然界在进化博弈中是如何产生赢家和输家为模型而建立的。
|
|
||||||
|
|
||||||
|
|
||||||
### 自然选择
|
|
||||||
|
|
||||||
![查尔斯·达尔文][5]
|
|
||||||
|
|
||||||
1859年, [查尔斯·达尔文][6] 在他的[物种起源][7]_一书中提出了进化论学说。 达尔文的论点是,自然变异是由生物个体的自发突变和环境压力共同造成的。 环境压力淘汰了适应性较差的生物体,而有利于其他适应性强的生物的发展。 每个生物体的染色体都会发生变异,而这些自发的变异会携带给下一代(后代)。 然后在自然选择下测试新出现的变异性-当下存在的环境压力是由变异性的环境条件所导致的。
|
|
||||||
|
|
||||||
这张简图说明了调整适应环境条件的过程。
|
|
||||||
|
|
||||||
![环境压力对鱼类的影响][8]
|
|
||||||
|
|
||||||
图1. 不同的环境压力导致自然选择下的不同结果。图片截图来源于[理查德•道金斯的一个视频][9]。
|
|
||||||
|
|
||||||
该图显示了一群生活在自己栖息地的鱼。 栖息地各不相同(海底或河床底部的砾石颜色有深有浅),每条鱼长的也各不相同(鱼身图案和颜色也有深有浅)。
|
|
||||||
|
|
||||||
这张图还显示了两种情况(即环境压力的两种变化)::
|
|
||||||
|
|
||||||
1. 捕食者在场
|
|
||||||
|
|
||||||
|
|
||||||
2. 捕食者不在场
|
|
||||||
|
|
||||||
|
|
||||||
在第一种情况下,在砾石颜色衬托下容易凸显出来的鱼被捕食者捕获的风险更高。 当砾石颜色较深时,浅色鱼的数量会更少一些。 反之亦然-当砾石颜色较浅时,深色鱼的数量会更少。
|
|
||||||
|
|
||||||
在第二种情况下,鱼完全放松下来进行交配。 在没有捕食者和没有交配仪式的情况下,可以预料到相反的结果:在砾石背景下显眼的鱼会有更大的机会被选来交配并将其特性传递给后代。
|
|
||||||
|
|
||||||
|
|
||||||
### 选择标准
|
|
||||||
|
|
||||||
|
|
||||||
变异性在进行选择时,绝不是任意的,反复无常的,异想天开的或随机的。选择过程中的决定性因素通常是可以度量的。 该决定性因素通常称为测试或目标。
|
|
||||||
|
|
||||||
一个简单的数学例子可以说明这一决策过程。 (在该示例中,这种选择不是由自然选择决定的,而是由人为选择决定。)假设有人要求您构建一个小函数,该函数将选用一个正数,然后计算该数的平方根。你将怎么做?
|
|
||||||
|
|
||||||
敏捷 DevOps 团队的方法是快速验证失败。 谦虚一点,承认自己真的不知道如何开发该功能。 这时,你所知道的就是如何描述你想做的事情。 从技术上讲,你已准备好进行单元测试。
|
|
||||||
|
|
||||||
“单元测试”描述了你的具体期望结果是什么。 它可以简单地表述为“给定数字16,我希望平方根函数返回数字4”。 您可能知道16的平方根是4。但是,你不知道一些较大数字(例如533)的平方根。
|
|
||||||
|
|
||||||
但至少,你已经制定了选择标准,即你的测试或你的期望值。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 进行故障测试
|
|
||||||
|
|
||||||
[.NET Core][10] 平台可以实现该测试。.NET 通常使用 xUnit.net 作为单元测试框架。(要遵循编码示例,请安装 .NET Core 和 xUnit.net。)
|
|
||||||
|
|
||||||
打开命令行并创建一个文件夹,在该文件夹实现平方根解决方案。 例如,输入:
|
|
||||||
|
|
||||||
```
|
|
||||||
`mkdir square_root`
|
|
||||||
```
|
|
||||||
|
|
||||||
再输入:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`cd square_root`
|
|
||||||
```
|
|
||||||
|
|
||||||
为单元测试创建一个单独的文件夹:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`mkdir unit_tests`
|
|
||||||
```
|
|
||||||
|
|
||||||
进入 **unit_tests** 文件夹下(**cd unit_tests**) ,初始化xUnit 框架:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`dotnet new xunit`
|
|
||||||
```
|
|
||||||
|
|
||||||
现在,将文件夹移动到 **square_root** 下, 创建 **app** 文件夹:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir app
|
|
||||||
cd app
|
|
||||||
```
|
|
||||||
|
|
||||||
如果有必要的话,为你的代码创建一个脚手架:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`dotnet new classlib`
|
|
||||||
```
|
|
||||||
|
|
||||||
现在打开你最喜欢的编辑器开始编码!
|
|
||||||
|
|
||||||
在你的代码编辑器中,导航到 **unit_tests** 文件夹,打开 **UnitTest1.cs**。
|
|
||||||
将 **UnitTest1.cs** 中自动生成的代码替换为:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
using System;
|
|
||||||
using Xunit;
|
|
||||||
using app;
|
|
||||||
|
|
||||||
namespace unit_tests{
|
|
||||||
|
|
||||||
public class UnitTest1{
|
|
||||||
Calculator calculator = new Calculator();
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GivenPositiveNumberCalculateSquareRoot(){
|
|
||||||
var expected = 4;
|
|
||||||
var actual = calculator.CalculateSquareRoot(16);
|
|
||||||
Assert.Equal(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
该单元测试描述了变量的**期望值**应该为4。下一行描述了**实际值**。 建议通过将输入值发送到称为**calculator** 的组件来计算**实际值**。对该组件的描述是通过接收数值来处理**CalculateSquareRoot**信息。 该组件尚未开发。 但这并不重要,我们在此只是描述期望值。
|
|
||||||
|
|
||||||
最后,描述了触发消息发送时发生的情况。 此时,判断**期望值** 是否等于**实际值**。 如果是,则测试通过,目标达成。 如果**期望值** 不等于**实际值**,则测试失败。
|
|
||||||
|
|
||||||
接下来,要实现称为**calculator**的组件,在 **app** 文件夹中创建一个新文件,并将其命名为**Calculator.cs**。 要实现计算平方根的功能,请在此新文件中添加以下代码:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
namespace app {
|
|
||||||
public class Calculator {
|
|
||||||
public double CalculateSquareRoot(double number) {
|
|
||||||
double bestGuess = number;
|
|
||||||
return bestGuess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Before you can test this implementation, you need to instruct the unit test how to find this new component (**Calculator**). Navigate to the **unit_tests** folder and open the **unit_tests.csproj** file. Add the following line in the **<ItemGroup>** code block:
|
|
||||||
在测试之前,你需要通知单元测试如何找到该新组件(**Calculator**)。 导航至**unit_tests** 文件夹,打开**unit_tests.csproj**文件。 在 **<ItemGroup>** 代码块中添加以下代码:
|
|
||||||
|
|
||||||
```
|
|
||||||
`<ProjectReference Include="../app/app.csproj" />`
|
|
||||||
```
|
|
||||||
|
|
||||||
保存 **unit_test.csproj** 文件。现在,你可以运行第一个测试了。
|
|
||||||
|
|
||||||
切换到命令行,进入 **unit_tests** 文件夹。 运行以下命令:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
`dotnet test`
|
|
||||||
```
|
|
||||||
|
|
||||||
运行单元测试,会输出以下内容:
|
|
||||||
|
|
||||||
![单元测试失败后xUnit的输出结果][12]
|
|
||||||
|
|
||||||
图2. 单元测试失败后xUnit的输出结果
|
|
||||||
|
|
||||||
|
|
||||||
正如你所看到的,单元测试失败了。 期望将数字16发送到**calculator** 组件后会输出数字4,但是输出(**实际值**)的是16。
|
|
||||||
恭喜你! 创建了第一个故障。 单元测试为你提供了强有力的反馈机制,敦促你修复故障。
|
|
||||||
|
|
||||||
|
|
||||||
### 修复故障
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
要修复故障,你必须要改进 **bestGuess**。 当下,**bestGuess** 仅获取函数接收的数字并返回。 这不够好。
|
|
||||||
但是,如何找到一种计算平方根值的方法呢? 我有一个主意-看一下大自然母亲是如何解决问题的。
|
|
||||||
|
|
||||||
|
|
||||||
### 效仿大自然的迭代
|
|
||||||
|
|
||||||
|
|
||||||
在第一次(也是唯一的)尝试中要得出正确值是非常难的(几乎不可能)。 你必须允许自己进行多次尝试猜测,以增加解决问题的机会。 允许多次尝试的一种方法是进行迭代。
|
|
||||||
|
|
||||||
要迭代,就要将 **bestGuess**值存储在 **previousGuess** 变量中,转换**bestGuess**的值,然后比较两个值之间的差。 如果差为0,则说明问题已解决。 否则,继续迭代。
|
|
||||||
|
|
||||||
这是生成任何正数的平方根的函数体:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
double bestGuess = number;
|
|
||||||
double previousGuess;
|
|
||||||
|
|
||||||
do {
|
|
||||||
previousGuess = bestGuess;
|
|
||||||
bestGuess = (previousGuess + (number/previousGuess))/2;
|
|
||||||
} while((bestGuess - previousGuess) != 0);
|
|
||||||
|
|
||||||
return bestGuess;
|
|
||||||
```
|
|
||||||
|
|
||||||
该循环(迭代)将bestGuess值集中到设想的解决方案。 现在,你精心设计的单元测试通过了!
|
|
||||||
|
|
||||||
![单元测试通过了][13]
|
|
||||||
|
|
||||||
图 3. 单元测试通过了。
|
|
||||||
|
|
||||||
### 迭代解决了问题
|
|
||||||
|
|
||||||
正如大自然母亲解决问题的方法,在本练习中,迭代解决了问题。 增量方法与逐步改进相结合是获得满意解决方案的有效方法。 该示例中的决定性因素是具有可衡量的目标和测试。 一旦有了这些,就可以继续迭代直到达到目标。
|
|
||||||
|
|
||||||
|
|
||||||
### 关键点!
|
|
||||||
|
|
||||||
好的,这是一个有趣的试验,但是更有趣的发现来自于使用这种新创建的解决方案。 到目前为止,**bestGuess** 从开始一直把函数接收到的数字作为输入参数。 如果更改**bestGuess**的初始值会怎样?
|
|
||||||
|
|
||||||
为了测试这一点,你可以测试几种情况。 首先,在迭代多次尝试计算25的平方根时,要逐步细化观察结果:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
![25平方根的迭代编码][14]
|
|
||||||
|
|
||||||
图 4. 通过迭代来计算25的平方根。
|
|
||||||
|
|
||||||
以25作为 **bestGuess** 的初始值,该函数需要八次迭代才能计算出25的平方根。但是,如果在设计 **bestGuess** 初始值上犯下荒谬的错误,那将怎么办? 尝试第二次,那100万可能是25的平方根吗? 在这种明显错误的情况下会发生什么? 你写的功能是否能够处理这种低级错误。
|
|
||||||
|
|
||||||
直接来吧。回到测试中来,这次以一百万开始:
|
|
||||||
|
|
||||||
![逐步求精法][15]
|
|
||||||
|
|
||||||
图 5. 在计算25的平方根时,运用逐步求精法,以100万作为**bestGuess**的初始值。
|
|
||||||
|
|
||||||
哇! 以一个荒谬的数字开始,迭代次数仅增加了两倍(从八次迭代到23次)。 增长幅度没有你直觉中预期的那么大。
|
|
||||||
|
|
||||||
### 故事的寓意
|
|
||||||
|
|
||||||
啊哈! 当你意识到,迭代不仅能够保证解决问题,而且与你的解决方案的初始猜测值是好是坏也没有关系。 不论你最初理解得多么不正确,迭代过程以及可衡量的测试/目标,都可以使你走上正确的道路并得到解决方案。
|
|
||||||
|
|
||||||
图4和5显示了陡峭而戏剧性的燃尽图。 一个非常错误得开始,迭代很快就产生了一个绝对正确的解决方案。
|
|
||||||
|
|
||||||
简而言之,这种神奇的方法就是敏捷 DevOps 的本质。
|
|
||||||
|
|
||||||
|
|
||||||
### 回到一些更深层次的观察
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
敏捷DevOps的实践源于人们对所生活的世界的认知。我们生活的世界存在不确定性,不完整性以及充满太多的困惑。 从科学/哲学的角度来看,这些特征得到了[海森堡的不确定性原理][16] (涵盖不确定性部分), [维特根斯坦的逻辑论哲学][17] (歧义性部分), [哥德尔的不完全性定理][18] (不完全性方面), 以及[热力学第二定律][19] (无情的熵引起的混乱)的充分证明和支持。
|
|
||||||
|
|
||||||
简而言之,无论你多么努力,在尝试解决任何问题时都无法获得完整的信息。 因此,放下傲慢的姿态,采取更为谦虚的方法来解决问题对我们会更有帮助。 谦卑会给为你带来巨大的回报,这个回报不仅是你期望的一个解决方案,还会有它的副产品。
|
|
||||||
|
|
||||||
|
|
||||||
### 总结
|
|
||||||
|
|
||||||
大自然在不停地运作,这是一个持续不断的过程。 大自然没有总体规划。 一切都是对先前发生的事情的回应。 反馈循环是非常紧密的,明显的进步/倒退都是逐步实现的。大自然中随处可见,任何事物的都在以一种或多种形式逐步完善。
|
|
||||||
|
|
||||||
敏捷 DevOps 是工程模型逐渐成熟的一个非常有趣的结果。 DevOps 基于这样的认识,即你所拥有的信息总是不完整的,因此你最好谨慎进行。 获得可衡量的测试(例如,假设,可测量的期望结果),进行简单的尝试,大多数情况下可能失败,然后收集反馈,修复故障并继续测试。 除了同意每个步骤都必须要有可衡量的假设/测试之外,没有其他方法。
|
|
||||||
|
|
||||||
在本系列的下一篇文章中,我将仔细研究变异测试是如何提供及时反馈来推动实现结果的。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
via: https://opensource.com/article/19/8/mutation-testing-evolution-tdd
|
|
||||||
|
|
||||||
作者:[Alex Bunardzic][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/alex-bunardzic
|
|
||||||
[b]: https://github.com/lujun9972
|
|
||||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520X292_openanttrail-2.png?itok=xhD3WmUd (Ants and a leaf making the word "open")
|
|
||||||
[2]: https://opensource.com/article/19/7/failure-feature-blameless-devops
|
|
||||||
[3]: https://en.wikipedia.org/wiki/Test-driven_development
|
|
||||||
[4]: https://www.merriam-webster.com/dictionary/conditio%20sine%20qua%20non
|
|
||||||
[5]: https://opensource.com/sites/default/files/uploads/darwin.png (Charles Darwin)
|
|
||||||
[6]: https://en.wikipedia.org/wiki/Charles_Darwin
|
|
||||||
[7]: https://en.wikipedia.org/wiki/On_the_Origin_of_Species
|
|
||||||
[8]: https://opensource.com/sites/default/files/uploads/environmentalconditions2.png (Environmental pressures on fish)
|
|
||||||
[9]: https://www.youtube.com/watch?v=MgK5Rf7qFaU
|
|
||||||
[10]: https://dotnet.microsoft.com/
|
|
||||||
[11]: https://xunit.net/
|
|
||||||
[12]: https://opensource.com/sites/default/files/uploads/xunit-output.png (xUnit output after the unit test run fails)
|
|
||||||
[13]: https://opensource.com/sites/default/files/uploads/unit-test-success.png (Unit test successful)
|
|
||||||
[14]: https://opensource.com/sites/default/files/uploads/iterating-square-root.png (Code iterating for the square root of 25)
|
|
||||||
[15]: https://opensource.com/sites/default/files/uploads/bestguess.png (Stepwise refinement)
|
|
||||||
[16]: https://en.wikipedia.org/wiki/Uncertainty_principle
|
|
||||||
[17]: https://en.wikipedia.org/wiki/Tractatus_Logico-Philosophicus
|
|
||||||
[18]: https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems
|
|
||||||
[19]: https://en.wikipedia.org/wiki/Second_law_of_thermodynamics
|
|
@ -1,103 +0,0 @@
|
|||||||
[#]: collector: (lujun9972)
|
|
||||||
[#]: translator: (geekpi)
|
|
||||||
[#]: reviewer: ( )
|
|
||||||
[#]: publisher: ( )
|
|
||||||
[#]: url: ( )
|
|
||||||
[#]: subject: (Command line quick tips: Locate and process files with find and xargs)
|
|
||||||
[#]: via: (https://fedoramagazine.org/command-line-quick-tips-locate-and-process-files-with-find-and-xargs/)
|
|
||||||
[#]: author: (Ben Cotton https://fedoramagazine.org/author/bcotton/)
|
|
||||||
|
|
||||||
命令行提示:使用 find 和 xargs 查找和处理文件
|
|
||||||
======
|
|
||||||
|
|
||||||
![][1]
|
|
||||||
|
|
||||||
**find** 是日常工具箱中功能更强大,更灵活的命令行程序之一。它如它名字所暗示的:查找符合你指定条件的文件和目录。借助 **-exec** 或 **-delete** 之类的参数,你可以让它对找到的文件进行操作。
|
|
||||||
|
|
||||||
在[命令行提示][2]系列的这一期中,你将会看到 **find** 命令的介绍,并学习如何使用内置命令或使用 **xargs** 命令处理文件。
|
|
||||||
|
|
||||||
### 查找文件
|
|
||||||
|
|
||||||
**find** 至少要加上查找的路径。例如,此命令将查找(并打印)系统上的每个文件:
|
|
||||||
|
|
||||||
```
|
|
||||||
find /
|
|
||||||
```
|
|
||||||
|
|
||||||
由于所有东西都是文件,因此你会看到大量的输出。这可能无法帮助你找到所需的内容。你可以更改路径参数缩小范围,但这实际上并没有比使用 **ls** 命令更好。因此,你需要考虑要查找的内容。
|
|
||||||
|
|
||||||
也许你想在家目录中查找所有 JPEG 文件。 **-name** 参数允许你将结果限制为与给定模式匹配的文件。
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ -name '*jpg'
|
|
||||||
```
|
|
||||||
|
|
||||||
但是等等!如果其中一些扩展名是大写怎么办? **-iname** 类似于 **-name**,但不区分大小写:
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ -iname '*jpg'
|
|
||||||
```
|
|
||||||
|
|
||||||
很好!但是 8.3 命名方案出自 1985 年。某些图片的扩展名可能是 .jpeg。幸运的是,我们可以将模式使用“或”(**-o**)进行组合。括号会被转义,以便是 **find** 命令而不是 shell 程序尝试解释它们。
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ \( -iname 'jpeg' -o -iname 'jpg' \)
|
|
||||||
```
|
|
||||||
|
|
||||||
更进一步。如果你有一些以 jpg 结尾的目录怎么办? (为什么你将目录命名为 **bucketofjpg** 而不是 **pictures**。)我们可以加上 **-type** 参数来仅查找文件:
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f
|
|
||||||
```
|
|
||||||
|
|
||||||
或者,也许你想找到那些名字奇怪的目录,以便之后可以重命名它们:
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type d
|
|
||||||
```
|
|
||||||
|
|
||||||
最近你拍摄了很多照片,因此使用 **-mtime**(修改时间)将范围缩小到最近一周修改过的文件。 **-7** 表示 7 天或更短时间内修改的所有文件。
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7
|
|
||||||
```
|
|
||||||
|
|
||||||
### 使用 xargs 进行操作
|
|
||||||
|
|
||||||
**xargs** 命令从标准输入流中获取参数,并基于它们执行命令。继续使用上一节中的示例,假设你要将上周修改过的家目录中的所有 JPEG 文件复制到 U 盘,以便插到电子相册上。假设你已经将 U 盘挂载到 _/media/photo_display_。
|
|
||||||
|
|
||||||
```
|
|
||||||
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7 -print0 | xargs -0 cp -t /media/photo_display
|
|
||||||
```
|
|
||||||
|
|
||||||
**find**命令与以前的版本略有不同。**-print0** 命令让输出有一些更改:它不使用换行符,而是添加了一个空字符。**xargs** 的 **-0**(零)选项可调整解析以达到预期效果。这很重要,不然对包含空格、引号或其他特殊字符的文件名执行操作可能无法按预期进行。对文件采取任何操作时,都应使用这些选项。
|
|
||||||
|
|
||||||
|
|
||||||
**cp**的 **-t** 参数很重要,因为 **cp** 通常要求目的地址在最后。你可以不使用 **xargs** 而使用 **find** 的 **-exec** 执行此操作,但是 **xargs** 的方式会更快,尤其是对于大量文件,因为它会单次调用 **cp**。
|
|
||||||
|
|
||||||
### 了解更多
|
|
||||||
|
|
||||||
这篇文章仅是 **find** 可以做的事情的表面。 **find** 支持基于权限、所有者、访问时间等的测试。它甚至可以将搜索路径中的文件与其他文件进行比较。将测试与布尔逻辑相结合,可以为你提供惊人的灵活性,以精确地找到你要查找的文件。使用内置命令或管道传递给 **xargs**,你可以快速处理大量文件。
|
|
||||||
|
|
||||||
_这篇文章的部分内容先前已发布在 [Opensource.com][3]。_ _ 照片由 [_Warren Wong_][4] 在 [Unsplash] [5] 上发表。_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
via: https://fedoramagazine.org/command-line-quick-tips-locate-and-process-files-with-find-and-xargs/
|
|
||||||
|
|
||||||
作者:[Ben Cotton][a]
|
|
||||||
选题:[lujun9972][b]
|
|
||||||
译者:[geekpi](https://github.com/geekpi)
|
|
||||||
校对:[校对者ID](https://github.com/校对者ID)
|
|
||||||
|
|
||||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
|
||||||
|
|
||||||
[a]: https://fedoramagazine.org/author/bcotton/
|
|
||||||
[b]: https://github.com/lujun9972
|
|
||||||
[1]: https://fedoramagazine.org/wp-content/uploads/2018/10/commandlinequicktips-816x345.jpg
|
|
||||||
[2]: https://fedoramagazine.org/?s=command+line+quick+tips
|
|
||||||
[3]: https://opensource.com/article/18/4/how-use-find-linux
|
|
||||||
[4]: https://unsplash.com/@wflwong?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
|
||||||
[5]: https://unsplash.com/s/photos/search?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
|
@ -1,126 +0,0 @@
|
|||||||
[#]: collector: (lujun9972)
|
|
||||||
[#]: translator: ( )
|
|
||||||
[#]: reviewer: ( )
|
|
||||||
[#]: publisher: ( )
|
|
||||||
[#]: url: ( )
|
|
||||||
[#]: subject: (How to Unzip a Zip File in Linux [Beginner’s Tutorial])
|
|
||||||
[#]: via: (https://itsfoss.com/unzip-linux/)
|
|
||||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
|
||||||
|
|
||||||
如何在 linux 下解压 Zip 文件
|
|
||||||
======
|
|
||||||
|
|
||||||
_**摘要: 将会向你展示如何在 ubuntu 和其他 linux 发行版本上解压文件 . 终端和图形界面的方法都会被讨论 **_
|
|
||||||
|
|
||||||
[Zip][1] 是一种最普通 , 最流行的方法来创建压缩存档文件 . 它也是一种古老的文件归档文件格式,创建于 1989 年 . 自从它被广泛的使用 , 你会经常遇见 zip 文件 .
|
|
||||||
|
|
||||||
在更早的一份教程 , 我展示了 [how to zip a folder in Linux][2] . 在这篇快速教程中 , 对于初学者我会展示如何在 linux 上解压文件 .
|
|
||||||
|
|
||||||
**先决条件: 检查你是否安装了 unzip**
|
|
||||||
|
|
||||||
为了解压 zip 归档文件 , 你必须解压安装包到你的系统 . 大多数现代的的 linux 发行版本提供解压 zip 文件的原生支持 . 校验它来避免以后出现坏的惊喜 .
|
|
||||||
|
|
||||||
以 [Unbutu][3] 和 [Debian][4] 为基础的发行版本 , 你能够使用下面的命令来安装 unzip. 如果你已经安装了, 你会被告知已经被安装 .
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt install unzip
|
|
||||||
```
|
|
||||||
|
|
||||||
一旦你能够确认你的系统中安装了 unzip, 你就可以通过 unzip 来解压 zip 归档文件.
|
|
||||||
|
|
||||||
你也能够使用命令行或者图形工具来达到目的, 我会向你展示两种方法.
|
|
||||||
|
|
||||||
* [Unzip files in Linux terminal][5]
|
|
||||||
* [Unzip files in Ubuntu via GUI][6]
|
|
||||||
|
|
||||||
|
|
||||||
### 使用命令行解压文件
|
|
||||||
|
|
||||||
在 linux 下使用 unzip 命令是非常简单. 当你向解压 zip 文件, 用下面的命令:
|
|
||||||
|
|
||||||
```
|
|
||||||
unzip zipped_file.zip
|
|
||||||
```
|
|
||||||
|
|
||||||
你可以给 zip 文件提供解压路径而不是当前所在路径 . 你会在终端输出中看到提取的文件:
|
|
||||||
|
|
||||||
```
|
|
||||||
unzip metallic-container.zip -d my_zip
|
|
||||||
Archive: metallic-container.zip
|
|
||||||
inflating: my_zip/625993-PNZP34-678.jpg
|
|
||||||
inflating: my_zip/License free.txt
|
|
||||||
inflating: my_zip/License premium.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
上面的命令有一个小问题. 它会提取 zip 文件中所有的内容到现在的文件夹 . 你会在当前文件夹下留下一堆没有组织的文件, 这不是一件很好的事情.
|
|
||||||
|
|
||||||
#### 解压到文件夹下
|
|
||||||
|
|
||||||
在 linux 命令行下, 对于把文件解压到一个文件夹下是一个好的做法. 这种方式下, 所有的提取文件都会被存储到你所指定的文件夹下. 如果文件夹不存在, 文件夹会被创建.
|
|
||||||
|
|
||||||
```
|
|
||||||
unzip zipped_file.zip -d unzipped_directory
|
|
||||||
```
|
|
||||||
|
|
||||||
现在 zipped_file.zip 中所有的内容都会被提取到 unzipped_directory 中.
|
|
||||||
|
|
||||||
从我们讨论好的做法, 另一个注意点, 我们可以查看压缩文件中的内容而不用真实的解压 .
|
|
||||||
|
|
||||||
#### 查看压缩文件中的内容而不解压压缩文件
|
|
||||||
|
|
||||||
```
|
|
||||||
unzip -l zipped_file.zip
|
|
||||||
```
|
|
||||||
|
|
||||||
下面是命令的输出:
|
|
||||||
```
|
|
||||||
unzip -l metallic-container.zip
|
|
||||||
Archive: metallic-container.zip
|
|
||||||
Length Date Time Name
|
|
||||||
--------- ---------- ----- ----
|
|
||||||
6576010 2019-03-07 10:30 625993-PNZP34-678.jpg
|
|
||||||
1462 2019-03-07 13:39 License free.txt
|
|
||||||
1116 2019-03-07 13:39 License premium.txt
|
|
||||||
--------- -------
|
|
||||||
6578588 3 files
|
|
||||||
```
|
|
||||||
|
|
||||||
在 linux 下, 这里还有些其他的 unzip 的用法, 你对在 linux 下使用解压文件有了足够的知识.
|
|
||||||
|
|
||||||
### 使用图形界面来解压文件
|
|
||||||
|
|
||||||
如果你使用桌面版 linux , 那你就不必总是使用终端. 在图形化的界面下,我们又要如何解压文件呢? 我使用 [GNOME desktop][7]. 和其他的桌面版 linux 发行版本相同 .
|
|
||||||
打开文件管理器,然后跳转到压缩文件所在的文件夹下. 点击鼠标右键, 你会在弹出的窗口中看到 "extract here",选择它.
|
|
||||||
|
|
||||||
![Unzip File in Ubuntu][8]
|
|
||||||
|
|
||||||
与 unzip 命令不同, 提取选项会创建一个和压缩文件名相同的文件夹,并且把压缩文件中的所有内容存储到创建的文件夹下. 相对于 unzip 命令的默认行为是将压缩文件提取到当前所在的文件下,图形界面的解压对于我来说是一件非常好的事情.
|
|
||||||
|
|
||||||
这里还有一个选项 "extract to", 你可以悬着特定的文件夹来存储提取文件.
|
|
||||||
|
|
||||||
你现在知道如何在 linux 解压文件. 你也许对学习有兴趣 [using 7zip in Linux][9] .
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
via: https://itsfoss.com/unzip-linux/
|
|
||||||
|
|
||||||
作者:[Abhishek Prakash][a]
|
|
||||||
选题:[lujun9972][b]
|
|
||||||
译者:[octopus](https://github.com/singledo)
|
|
||||||
校对:[校对者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://en.wikipedia.org/wiki/Zip_(file_format)
|
|
||||||
[2]: https://itsfoss.com/linux-zip-folder/
|
|
||||||
[3]: https://ubuntu.com/
|
|
||||||
[4]: https://www.debian.org/
|
|
||||||
[5]: tmp.eqEocGssC8#terminal
|
|
||||||
[6]: tmp.eqEocGssC8#gui
|
|
||||||
[7]: https://gnome.org/
|
|
||||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/10/unzip-files-ubuntu.jpg?ssl=1
|
|
||||||
[9]: https://itsfoss.com/use-7zip-ubuntu-linux/
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user