mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-24 02:20:09 +08:00
commit
f93c87507c
@ -0,0 +1,186 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12956-1.html)
|
||||
[#]: subject: (3 Ways to Install Deb Files on Ubuntu Linux)
|
||||
[#]: via: (https://itsfoss.com/install-deb-files-ubuntu)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
在 Ubuntu Linux 上安装 Deb 文件的 3 种方法
|
||||
======
|
||||
|
||||
> 这篇初学者文章解释了如何在 Ubuntu 中安装 deb 软件包。它稍后也向你展示如何移除这些 deb 软件包。
|
||||
|
||||
这是 Ubuntu 初学者系列的另一篇文章。如果你对 Ubuntu 很陌生,你可能会想知道 [如何安装应用程序][1]。
|
||||
|
||||
最简单的方法是使用 Ubuntu 软件中心。在软件中心中搜索应用程序的名称并安装它。如果你能在软件中心中找到所有的应用程序,那么生活就太惬意了。但是,不幸的是,这是不可能的发生的。
|
||||
|
||||
一些软件包可以通过 DEB 软件包的形式获得。它们是以 .deb 扩展名为结尾的存档文件。你可以把 .deb 文件看作为 Windows 中的 .exe 文件。在 Windows 中,你双击 .exe 文件,它将开始安装过程。DEB 软件包也是非常类似的。
|
||||
|
||||
你可以从软件提供商网站的下载区域找到这些 DEB 软件包。例如,如果你想 [在 Ubuntu 上安装 Google Chrome][2] ,你可以从它的网站下载 Chrome 的 DEB 软件包。
|
||||
|
||||
现在问题产生了,你将如何安装 deb 文件呢?在 Ubuntu 中有多种安装 DEB 软件包的方法。在这篇教程中,我将向你依次地展示它们。
|
||||
|
||||
![在 Ubuntu 中安装 deb 文件][3]
|
||||
|
||||
### 在 Ubuntu 和基于 Debian 的 Linux 发行版中安装 .deb 文件
|
||||
|
||||
你可以选择一个 GUI 工具或一个命令行工具来安装一个 deb 软件包。你拥有选择权。
|
||||
|
||||
让我们继续看看如何安装 deb 文件。
|
||||
|
||||
#### 方法 1: 使用默认的软件中心
|
||||
|
||||
在 Ubuntu 中,最简单的方法是使用默认的软件中心。在这里你不必要做任何特别的事。只需要转到你所下载的 .deb 文件的文件夹下(它应该是 Downloads 文件夹),并在这个文件上双击。
|
||||
|
||||
![在 Ubuntu 上的 Google Chrome 的 deb 文件][4]
|
||||
|
||||
在已下载的 .deb 文件上双击以开始安装。
|
||||
|
||||
它将打开软件中心,并且你将看到安装软件时的选项。你所需要做的全部工作就是:点击安装按钮并输入你的登录密码。
|
||||
|
||||
![在 Ubuntu 软件中心中安装 Google Chrome][5]
|
||||
|
||||
.deb 文件的安装将通过软件中心来执行。
|
||||
|
||||
看,它甚至比在 Windows 中安装一个 .exe 文件更简单,不是吗?
|
||||
|
||||
#### 方法 2: 使用 Gdebi 应用程序来安装 deb 软件包及其依赖项
|
||||
|
||||
再提一次,如果事情总是进展顺利,生活可能会更简单一些。但是生活并不是我们熟知的那样。
|
||||
|
||||
现在,你已经知道 .deb 文件可以简单地通过软件中心来安装,接下来,让我告诉你一些软件包可能会遇到的依赖项的错误。
|
||||
|
||||
发生错误的原因是,一个程序可能依赖于另外一个软件包(库)。当开发者为你准备 DEB 软件包时,他/她可能会假设你的系统中已经有了所依赖的软件包(库)。
|
||||
|
||||
但是如果情况并不是这样的,你的系统没有这些所需要的软件包(库),你将遇到臭名昭著的“依赖项错误”。
|
||||
|
||||
软件中心不能处理这样的错误,因此你不得不使用另外一个名称为 [gdebi][6] 的工具。
|
||||
|
||||
gdebi 是一个轻量级的 GUI 应用程序,它只有安装 deb 软件包的一个用途。
|
||||
|
||||
它将识别依赖项,并尝试在安装 .deb 文件的同时安装这些依赖项。
|
||||
|
||||
![gdebi 在安装 deb 软件包时处理依赖项][7]
|
||||
|
||||
就我个人而言,我更喜欢使用 gdebi 而不是使用软件包中心来安装 deb 文件。它是一个轻量级应用程序,因此安装过程看起来更快一点。更多的信息,你可以阅读[使用 gDebi ,并使其成为安装 DEB 软件包的默认设置][6]。
|
||||
|
||||
你可以从软件中心或使用下面的命令来安装 gdebi :
|
||||
|
||||
```
|
||||
sudo apt install gdebi
|
||||
```
|
||||
|
||||
#### 方法 3: 在命令行中使用 dpkg 安装 .deb 文件
|
||||
|
||||
如果你想在命令行中安装 deb 软件包,你可以使用 `apt` 命令或者 `dpkg` 命令。实际上,`apt` 命令在底层上使用 [dpkg][9] 命令,但是 `apt` 却更流行和易于使用。
|
||||
|
||||
如果你想对 deb 文件使用 `apt` 命令,像这样使用它:
|
||||
|
||||
```
|
||||
sudo apt install path_to_deb_file
|
||||
```
|
||||
|
||||
如果你想对将要安装的 deb 软件包使用 `dpkg` 命令,在这里是如何完成它:
|
||||
|
||||
```
|
||||
sudo dpkg -i path_to_deb_file
|
||||
```
|
||||
|
||||
在这两个命令中,你应该使用你已下载的 deb 文件的路径和名称来替换 `path_to_deb_file` 。
|
||||
|
||||
![在 Ubuntu 中使用 dpkg 命令安装 deb 文件][10]
|
||||
|
||||
如果你在安装 deb 软件包的过程中得到一个依赖项的错误,你可以使用下面的命令来修复依赖项的问题:
|
||||
|
||||
```
|
||||
sudo apt install -f
|
||||
```
|
||||
|
||||
### 如何移除 deb 软件包
|
||||
|
||||
移除一个 deb 软件包也不是一件什么大事。并且,你不需要用于安装程序的原始的 deb 文件。
|
||||
|
||||
#### 方法 1: 使用 apt 命令移除 deb 软件包
|
||||
|
||||
你所需要的全部东西就是你所已安装程序的名称,接下来你可以使用 `apt` 或 `dpkg` 来移除这个程序。
|
||||
|
||||
```
|
||||
sudo apt remove program_name
|
||||
```
|
||||
|
||||
现在,问题来了,在移除命令中,你如何找到你所需要使用的准确的程序名称?为此,`apt` 命令也有一个解决方案。
|
||||
|
||||
你可以使用 `apt` 命令找到所有已安装文件的列表,但是手动完成这一过程将会是一件令人头疼的事。因此,你可以使用 `grep` 命令来搜索你的软件包。
|
||||
|
||||
例如,在先前的部分中,我已安装 AppGrid 应用程序,但是如果我想知道准确的程序名称,我可以像这样使用一些东西:
|
||||
|
||||
```
|
||||
sudo apt list --installed | grep grid
|
||||
```
|
||||
|
||||
这将给予我全部的名称中含有 “grid” 的软件包,从这里,我可以得到准确的程序名称。
|
||||
|
||||
```
|
||||
apt list --installed | grep grid
|
||||
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
|
||||
appgrid/now 0.298 all [installed,local]
|
||||
```
|
||||
|
||||
正如你所看到的,一个名称为 “appgrid” 的软件包已经安装。现在,你可以在 `apt remove` 命令中使用这个程序名称。
|
||||
|
||||
#### 方法2: 使用 dpkg 命令移除 deb 软件包
|
||||
|
||||
你可以使用 `dpkg` 来找到已安装程序的名称:
|
||||
|
||||
```
|
||||
dpkg -l | grep grid
|
||||
```
|
||||
|
||||
该输出将给予所有的名称中有 “grid” 的软件包。
|
||||
|
||||
```
|
||||
dpkg -l | grep grid
|
||||
|
||||
ii appgrid 0.298 all Discover and install apps for Ubuntu
|
||||
```
|
||||
|
||||
在上面的命令输出中的 `ii` 意味着软件包已经被正确地安装。
|
||||
|
||||
现在,你有了程序名称,你可以使用 `dpkg` 命令来移除它:
|
||||
|
||||
```
|
||||
dpkg -r program_name
|
||||
```
|
||||
|
||||
**提示:更新 deb 软件包**
|
||||
|
||||
一些 deb 软件包 (像 Chrome)通过系统更新来提供其更新,但是对于大多数的其它的程序,你将不得不先移除已存在的程序,并在接下来安装更新的版本。
|
||||
|
||||
我希望这篇初学者指南能够帮助你在 Ubuntu 上安装 deb 软件包。我添加了移除部分,以便你可以更好地控制你所安装的程序。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-deb-files-ubuntu
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/remove-install-software-ubuntu/
|
||||
[2]: https://itsfoss.com/install-chrome-ubuntu/
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/deb-packages-ubuntu.png?resize=800%2C450&ssl=1
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/install-google-chrome-ubuntu-4.jpeg?resize=800%2C347&ssl=1
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/install-google-chrome-ubuntu-5.jpeg?resize=800%2C516&ssl=1
|
||||
[6]: https://itsfoss.com/gdebi-default-ubuntu-software-center/
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/gdebi-handling-dependency.jpg?ssl=1
|
||||
[8]: http://xmodulo.com
|
||||
[9]: https://help.ubuntu.com/lts/serverguide/dpkg.html.en
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/install-deb-file-with-dpkg.png?ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/deb-packages-ubuntu.png?fit=800%2C450&ssl=1
|
@ -0,0 +1,158 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zxp93)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12935-1.html)
|
||||
[#]: subject: (How I use Python to map the global spread of COVID-19)
|
||||
[#]: via: (https://opensource.com/article/20/4/python-map-covid-19)
|
||||
[#]: author: (AnuragGupta https://opensource.com/users/999anuraggupta)
|
||||
|
||||
如何使用 Python 绘制 COVID-19 的全球扩散图
|
||||
======
|
||||
|
||||
> 使用这些开源框架创建一个彩色地图,显示病毒的可能的传播路径。
|
||||
|
||||

|
||||
|
||||
对于一个全球旅行司空见惯的世界来说,疾病的传播是一个真正令人担忧的问题。一些组织会跟踪重大的流行病(还有所有普遍的流行病),并将他们的跟踪工作获得的数据公开出来。不过,这些原始的数据对人来说可能很难处理,这就是为什么数据科学如此重要的原因。比如,用 Python 和 Pandas 可视化 COVID-19 在全球范围内的传播路径可能对这些数据的分析有所帮助。
|
||||
|
||||
最开始,当面对如此大数量的原始数据时可能难以下手。但当你开始处理数据之后,慢慢地就会发现一些处理数据的方式。下面是用于处理 COVID-19 数据的一些常见的情况:
|
||||
|
||||
1. 从 GitHub 上下载 COVID-19 的国家每日传播数据,保存为一个 Pandas 中的 DataFrame 对象。这时你需要使用 Python 中的 Pandas 库。
|
||||
2. 处理并清理下载好的数据,使其满足可视化数据的输入格式。所下载的数据的情况很好(数据规整)。这个数据有一个问题是它用国家的名字来标识国家,但最好是使用三位数的 ISO 3 码(国家代码表)来标识国家。为了生成 ISO 3 码,可是使用 `pycountry` 这个 Python 库。生成了这些代码之后,可以在原有的 DataFrame 上增加一列,然后用这些代码填充进去。
|
||||
3. 最后为了实现可视化,使用 Plotly 库中的 `express` 模块。这篇文章是使用名为choropleth 的地图(可在 Plotly 库中获得)来可视化该疾病在全球的传播。
|
||||
|
||||
### 第一步:Corona 数据
|
||||
|
||||
从下面这个网站上下载最新的 corona 数据(LCTT 译注:2020-12-14 仍可访问,有墙):
|
||||
|
||||
- <https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv>
|
||||
|
||||
我们之间将这个下载好的数据载入为 Pandas 的 DataFrame。Pandas 提供了一个函数, `read_csv()`,可以直接使用 URL 读取数据,并返回一个 DataFrame 对象,具体如下所示:
|
||||
|
||||
```
|
||||
import pycountry
|
||||
import plotly.express as px
|
||||
import pandas as pd
|
||||
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
|
||||
df1 = pd.read_csv(URL_DATASET)
|
||||
print(df1.head(3)) # Get first 3 entries in the dataframe
|
||||
print(df1.tail(3)) # Get last 3 entries in the dataframe
|
||||
```
|
||||
|
||||
在 Jupyter 上的输出截图:
|
||||
|
||||
![Jupyter screenshot][2]
|
||||
|
||||
从这个输出可以看到这个 DataFrame(`df1`)包括以下几列数据:
|
||||
|
||||
1. `Date`
|
||||
2. `Country`
|
||||
3. `Confirmed`
|
||||
4. `Recovered`
|
||||
5. `Dead`
|
||||
|
||||
之后还可以看到 `Date` 这一列包含了从 1 月 22 日到 3 月 31 日的条目信息。这个数据是每天更新的,所以你会得到你当天的值。
|
||||
|
||||
### 第二步:清理和修改 DataFrame
|
||||
|
||||
我们要往这个 DataFrame 中增加一列数据,就是那个包含了 ISO 3 编码。可以通过以下三步完成这个任务:
|
||||
|
||||
1. 创建一个包含所有国家的列表。因为在 `df1` 的 `Country` 列中,国家都是每个日期就重复一次。所以实际上 `Country` 列中对每个国家就会有多个条目。我使用 `unique().tolist()` 函数完成这个任务。
|
||||
2. 我使用 `d_country_code` 字典对象(初始为空),然后将其键设置为国家的名称,然后它的值设置为其对应的 ISO 3 编码。
|
||||
3. 我使用 `pycountry.countries.search_fuzzy(country)` 为每个国家生成 ISO 3 编码。你需要明白的是这个函数的返回值是一个 `Country` 对象的列表。我将这个函数的返回值赋给 `country_data` 对象。以这个对象的第一个元素(序号 `0`)为例。这个 `\` 对象有一个 `alpha_3` 属性。所以我使用 `country_data[0].alpha_3` 就能“获得”第一个元素的 ISO 3 编码。然而,在这个 DataFrame 中有些国家的名称可能没有对应的 ISO 3 编码(比如有争议的领土)。那么对这些“国家/地区”,我就用一个空白字符串来替代 ISO 3 编码。你也可以用一个 `try-except` 代码来替换这部分。`except` 中的语句可以写:`print(‘could not add ISO 3 code for ->', country)`。这样就能在找不到这些“国家/地区”对应的 ISO 3 编码时给出一个输出提示。实际上,你会发现这些“国家/地区”会在最后的输出中用白色来表示。
|
||||
4. 在获得了每个国家的 ISO 3 编码(有些是空白字符串)之后,我把这些国家的名称(作为键)还有国家对应的 ISO 3 编码(作为值)添加到之前的字典 `d_country_code` 中。可以使用 Python 中字典对象的 `update()` 方法来完成这个任务。
|
||||
5. 在创建好了一个包含国家名称和对应 ISO 3 编码的字典之后,我使用一个简单的循环将他们加入到 DataFrame 中。
|
||||
|
||||
### 第三步:使用 Plotly 可视化传播路径
|
||||
|
||||
choropleth 地图是一个由彩色多边形组成的地图。它常常用来表示一个变量在空间中的变化。我们使用 Plotly 中的 `px` 模块来创建 choropleth 图,具体函数为:`px.choropleth`。
|
||||
|
||||
这个函数的所包含的参数如下:
|
||||
|
||||
```
|
||||
plotly.express.choropleth(data_frame=None, lat=None, lon=None, locations=None, locationmode=None, geojson=None, featureidkey=None, color=None, hover_name=None, hover_data=None, custom_data=None, animation_frame=None, animation_group=None, category_orders={}, labels={}, color_discrete_sequence=None, color_discrete_map={}, color_continuous_scale=None, range_color=None, color_continuous_midpoint=None, projection=None, scope=None, center=None, title=None, template=None, width=None, height=None)
|
||||
```
|
||||
|
||||
`choropleth()` 这个函数还有几点需要注意:
|
||||
|
||||
1. `geojson` 是一个 `geometry` 对象(上面函数第六个参数)。这个对象有点让人困扰,因为在函数文档中没有明确地提到这个对象。你可以提供,也可以不提供 `geojson` 对象。如果你提供了 `geojson` 对象,那么这个对象就会被用来绘制地球特征,如果不提供 `geojson` 对象,那这个函数默认就会使用一个内建的 `geometry` 对象。(在我们的实验中,我们使用内建的 `geometry` 对象,因此我们不会为 `geojson` 参数提供值)
|
||||
2. DataFrame 对象有一个 `data_frame` 属性,在这里我们先前就提供了一个我们创建好的`df1`。
|
||||
3. 我们用 `Confirmed`(确诊数)来决定每个国家多边形的颜色。
|
||||
4. 最后,我们 `Date` 列创建一个 `animation_frame`。这样我们就能通过日期来划分数据,国家的颜色会随着 `Confirmed` 的变化而变化。
|
||||
|
||||
最后完整的代码如下:
|
||||
|
||||
```
|
||||
import pycountry
|
||||
import plotly.express as px
|
||||
import pandas as pd
|
||||
# ----------- Step 1 ------------
|
||||
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
|
||||
df1 = pd.read_csv(URL_DATASET)
|
||||
# print(df1.head) # Uncomment to see what the dataframe is like
|
||||
# ----------- Step 2 ------------
|
||||
list_countries = df1['Country'].unique().tolist()
|
||||
# print(list_countries) # Uncomment to see list of countries
|
||||
d_country_code = {} # To hold the country names and their ISO
|
||||
for country in list_countries:
|
||||
try:
|
||||
country_data = pycountry.countries.search_fuzzy(country)
|
||||
# country_data is a list of objects of class pycountry.db.Country
|
||||
# The first item ie at index 0 of list is best fit
|
||||
# object of class Country have an alpha_3 attribute
|
||||
country_code = country_data[0].alpha_3
|
||||
d_country_code.update({country: country_code})
|
||||
except:
|
||||
print('could not add ISO 3 code for ->', country)
|
||||
# If could not find country, make ISO code ' '
|
||||
d_country_code.update({country: ' '})
|
||||
|
||||
# print(d_country_code) # Uncomment to check dictionary
|
||||
|
||||
# create a new column iso_alpha in the df
|
||||
# and fill it with appropriate iso 3 code
|
||||
for k, v in d_country_code.items():
|
||||
df1.loc[(df1.Country == k), 'iso_alpha'] = v
|
||||
|
||||
# print(df1.head) # Uncomment to confirm that ISO codes added
|
||||
# ----------- Step 3 ------------
|
||||
fig = px.choropleth(data_frame = df1,
|
||||
locations= "iso_alpha",
|
||||
color= "Confirmed", # value in column 'Confirmed' determines color
|
||||
hover_name= "Country",
|
||||
color_continuous_scale= 'RdYlGn', # color scale red, yellow green
|
||||
animation_frame= "Date")
|
||||
|
||||
fig.show()
|
||||
```
|
||||
|
||||
这段代码的输出就是下面这个图的内容:
|
||||
|
||||
![Map][3]
|
||||
|
||||
你可以从这里下载并运行[完整代码][4]。
|
||||
|
||||
最后,这里还有一些关于 Plotly 绘制 choropleth 图的不错的资源。
|
||||
|
||||
* <https://github.com/plotly/plotly.py/blob/master/doc/python/choropleth-maps.md>
|
||||
* <https://plotly.com/python/reference/#choropleth>
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/4/python-map-covid-19
|
||||
|
||||
作者:[AnuragGupta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zhangxiangping](https://github.com/zxp93)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/999anuraggupta
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cloud-globe.png?itok=_drXt4Tn (Globe up in the clouds)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/jupyter_screenshot.png (Jupyter screenshot)
|
||||
[3]: https://opensource.com/sites/default/files/uploads/map_2.png (Map)
|
||||
[4]: https://github.com/ag999git/jupyter_notebooks/blob/master/corona_spread_visualization
|
||||
[5]: tmp.azs72dmHFd#choropleth
|
@ -0,0 +1,111 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (mengxinayan)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12965-1.html)
|
||||
[#]: subject: (How the Linux kernel handles interrupts)
|
||||
[#]: via: (https://opensource.com/article/20/10/linux-kernel-interrupts)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
|
||||
Linux 内核如何处理中断
|
||||
======
|
||||
|
||||
> 中断是计算机处理数据的关键部分。
|
||||
|
||||

|
||||
|
||||
中断是现代 CPU 工作方式中重要的部分。例如:当你每次在键盘上按下一个按键后,CPU 会被中断以使得 PC 读取用户键盘的输入。这个过程发生得相当快,以致于在使用体验上你不会感到任何变化或损害。
|
||||
|
||||
此外,键盘并不是导致中断的唯一组件。一般来说,有三种类型的事件会导致 CPU 发生中断:硬件中断、软件中断和异常。在具体介绍不同类型的中断前,我需要先定义一些术语。
|
||||
|
||||
### 定义
|
||||
|
||||
<ruby>中断请求<rt>interrupt request</rt></ruby>(IRQ)是由<ruby>可编程的中断控制器<rt>programmable interrupt controlle</rt></ruby>(PIC)发起的,其目的是为了中断 CPU 和执行<ruby>中断服务程序<rt>interrupt service routine</rt></ruby>(ISR)。中断服务程序(ISR)是一个小的程序,用来处理具体的数据,其具体的处理方式依赖于造成中断请求(IRQ)的原因。之前正在运行的进程在中断服务程序(ISR)运行结束前都会被中断。
|
||||
|
||||
在过去,中断请求由单独的芯片处理(中断控制器芯片 PIC),I/O 设备直接与中断控制器(PIC)相连。中断控制器(PIC)管理着多种硬件的中断请求(IRQ),并且可以直接与 CPU 通信。当一个中断请求(IRQ)产生后,中断控制器(PIC)向 CPU 写入数据,并且触发中断请求引脚(INTR)。
|
||||
|
||||
现如今,中断请求(IRQ)由 CPU 中的<ruby>高级可编程中断控制器<rt>advanced programmable interrupt controller</rt></ruby>(APIC)部分来处理。每个核中都拥有属于自己的高级可编程中断控制器。
|
||||
|
||||
### 中断的类型
|
||||
|
||||
正如我前文中提到的,中断可以根据其来源分为三种类型。
|
||||
|
||||
#### 硬件中断
|
||||
|
||||
当一个硬件设备想要告诉 CPU 某一需要处理的数据已经准备好后(例如:当键盘被按下或者一个数据包到了网络接口处),它将会发送一个中断请求(IRQ)来告诉 CPU 数据是可用的。接下来会调用在内核启动时设备驱动注册的对应的中断服务程序(ISR)。
|
||||
|
||||
#### 软件中断
|
||||
|
||||
当你在播放一个视频时,音频和视频是同步播放是相当重要的,这样音乐的速度才不会变化。这是由软件中断实现的,由精确的计时器系统(称为 [jiffies][2])重复发起的。这个计时器会使得你的音乐播放器同步。软件中断也可以被特殊的指令所调用,来读取或写入数据到硬件设备。
|
||||
|
||||
当系统需要实时性时(例如在工业应用中),软件中断会变得重要。你可以在 Linux 基金会的文章中找到更多相关信息:[面向嵌入式开发者的实时 Linux 介绍][3]。
|
||||
|
||||
#### 异常
|
||||
|
||||
<ruby>异常<rt>exception</rt></ruby>是你可能之前就知道的中断类型。当 CPU 执行一些将会导致除零或缺页错误的指令时,任何其他运行中的程序都会被中断。在这种情况下,你会被一个弹窗提醒,或在控制台输出中看到**<ruby>段错误<rt>segmentation fault</rt></ruby>(<ruby>核心已转储<rt>core dumped</rt></ruby>)**。但并不是所有异常都是由指令错误引起的。
|
||||
|
||||
异常可以进一步分为<ruby>错误<rt>Fault</rt></ruby>、<ruby>陷阱<rt>Trap</rt></ruby>和<ruby>终止<rt>Abort</rt></ruby>。
|
||||
|
||||
* **错误**:错误是系统可以纠正的异常。例如当一个进程尝试访问某个已经被换出到硬盘的页时。当请求的地址在进程的地址空间中,并且满足访问权限时,如果页不在内存(RAM)中,将会产生一个中断请求(IRQ),并开始启用**缺页异常处理程序**把所需的页加载到内存中。如果操作成功执行,程序将继续运行。
|
||||
* **陷阱**:陷阱主要用在调试中。如果你在某个程序中设置了一个断点,你就插入了一条可以触发陷阱执行的特殊指令。陷阱可以触发上下文切换来允许你的调试器读取和展示局部变量的值。之后程序可以继续运行。陷阱同样也是运行系统调用的方式(如杀死一个进程)
|
||||
* **终止**:终止是由系统表中的硬件错误或值不一致而导致的。终止不会报告造成异常的指令的所在位置。这是最严重的中断,终止将会调用系统的**终止异常处理程序**来结束造成异常的进程。
|
||||
|
||||
### 动手实践
|
||||
|
||||
中断请求按照高级可编程中断控制器(APIC)中的优先级高低排序(0是最高优先级)。前 32 个中断(0~31)是由 CPU 指定的固定序列。你可以在 [OsDev 异常][4] 页面找到关于它们的概述。随后的中断请求可以以不同的方式进行分配。<ruby>中断描述表<rt>interrupt descriptor table</rt></ruby>(IDT)中记录了中断请求(IRQ)和中断服务程序(ISR)的对应关系。Linux 中定义了从 0 到 256 的 IRQ 向量。
|
||||
|
||||
为了打印出在你的系统中已注册的中断,打开一个终端并输入:
|
||||
|
||||
```
|
||||
cat /proc/interrupts
|
||||
```
|
||||
|
||||
你应该会看到类似如下图的结果:
|
||||
|
||||
![注册的中断列表][5]
|
||||
|
||||
*内核版本为5.6.6中注册的中断 (Stephan Avenwedde, [CC BY-SA 4.0][6])*
|
||||
|
||||
从左到右各列的含义依次为:中断向量号、每个 CPU(0~n)中断发生次数、硬件来源、硬件源通道信息、以及造成中断请求的设备名。
|
||||
|
||||
在表的末尾,有一些非数字的中断。它们是特定于体系结构的中断,如<ruby>本地计时器中断<rt>local timer interrupt</rt></ruby>(LOC)的中断请求(IRQ)号为 236。其中一些在 Linux 内核源树中的[Linux IRQ 向量布局][7]中指定。
|
||||
|
||||
![特定于体系结构的中断][8]
|
||||
|
||||
*特定于体系结构的中断 (Stephan Avenwedde, [CC BY-SA 4.0][6])*
|
||||
|
||||
如果要实时获取该表,请运行如下命令:
|
||||
|
||||
```
|
||||
watch -n1 "cat /proc/interrupts"
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
正确的中断请求(IRQ)处理对于硬件、驱动和软件的正常交互是必要的。幸运地是,Linux 内核很好地完成了它,一个 PC 的普通用户几乎不会注意到内核的整个中断处理过程。
|
||||
|
||||
中断相当复杂,本文仅仅是一个关于中断的概述。如果想要深入了解该主题可以阅读 [Linux Inside 电子书][9](CC BY-NC-SA 4.0)和 [Linux 内核教程][10] 仓库。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/10/linux-kernel-interrupts
|
||||
|
||||
作者:[Stephan Avenwedde][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hansic99
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
|
||||
[2]: https://elinux.org/Kernel_Timer_Systems
|
||||
[3]: https://www.linuxfoundation.org/blog/2013/03/intro-to-real-time-linux-for-embedded-developers/
|
||||
[4]: https://wiki.osdev.org/Exceptions
|
||||
[5]: https://opensource.com/sites/default/files/uploads/proc_interrupts_1.png (Registered interrupts list)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/irq_vectors.h
|
||||
[8]: https://opensource.com/sites/default/files/uploads/proc_interrupts_2.png (Architecture-specific interrupts)
|
||||
[9]: https://0xax.gitbooks.io/linux-insides/content/Interrupts/
|
||||
[10]: https://linux-kernel-labs.github.io/refs/heads/master/lectures/interrupts.html#
|
@ -0,0 +1,134 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zxp93)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12941-1.html)
|
||||
[#]: subject: (The state of the art of microservices in 2020)
|
||||
[#]: via: (https://www.linux.com/news/the-state-of-the-art-of-microservices-in-2020/)
|
||||
[#]: author: (Linux.com Editorial Staff https://www.linux.com/author/linuxdotcom/)
|
||||
|
||||
2020 年微服务现状
|
||||
======
|
||||
|
||||

|
||||
|
||||
> “微服务架构风格是一种将 **单个应用程序** 开发为一套 **小型服务** 的方法,每个服务都在 **自己的进程中运行,并使用轻量级的通信机制(通常是 HTTP 类型的 API)进行通信**。这些服务是围绕 **业务能力** 构建的,并且可以通过 **全自动化的部署机制** 进行 **独立部署**。目前对这些服务几乎没有集中的管理,这些服务可以用 **不同的编程语言** 编写,也能使用 **不同的数据存储技术**。”
|
||||
>
|
||||
> —— James Lewis 和 Martin Fowler (2014) [^6]
|
||||
|
||||
### 介绍
|
||||
|
||||
预计在 2020 年,全球云端的微服务市场将以 22.5% 的速度增长,其中美国市场预计将保持 27.4% 的增长率[^5]。目前的趋势是,开发人员将从本地托管的应用程序转移到云端。这将有助于企业最大限度地减少停机时间、优化资源并降低基础设施成本。同时专家们还预测,到了 2022 年,90% 的应用程序将会使用微服务架构进行开发[^5]。本文将帮助你了解什么是微服务,以及目前的公司如何使用它的。
|
||||
|
||||
### 什么是微服务?
|
||||
|
||||
微服务已经在全球范围内被广泛使用。但是,微服务到底是什么?微服务是一种基于许多小型、互联服务的体系结构模式。它们基于 **单一责任原则**。根据 Robert C. Martin 的说法,“将因相同原因而变化的事物聚集起来,将因不同原因而变化的事物分离开来”。[^2]微服务架构也被扩展到了 **松耦合服务** 中,可以 **独立地开发、部署和维护**[^2]。
|
||||
|
||||
### 远离单体架构
|
||||
|
||||
微服务通常和传统的单体软件架构做对比。在单体架构中,软件是被设计为自足的,也就是说,这个程序中的各个组件都是互相连通和互相依赖的,而不是松散耦合的。在一个紧耦合的架构中(<ruby>单体<rt>monolithic</rt></ruby>),每个组件和它相关联的组件必须按照指定的顺序组合起来,才能被执行或编译[^7]。当其中有一个组件需要更新时,整个应用都要被重写。
|
||||
|
||||
而这个现象在使用微服务架构的应用中就不会出现。因为每一个模块都是独立的,每个模块都可以更新修改而不影响程序的其他部分。因此,降低了对更改一个组件会对其他组件造成影响的风险。
|
||||
|
||||
如果公司的架构很难升级,或者维护过于复杂和昂贵,那么他们可能会遇到麻烦,不能扩展单体架构的应用[^4]。把一个复杂的任务分解成小组件,彼此独立工作,就是解决这个问题的方法。
|
||||
|
||||
![][1]
|
||||
|
||||
*单一体系架构 vs. 微服务架构 (图片来自 [^3])*
|
||||
|
||||
### 开发者如何构建属于自己的微服务
|
||||
|
||||
微服务以提高*可扩展性*和*性能*而闻名。然而,这些是世界各地的开发者开发属于他们自己的微服务的主要原因吗?《微服务 2020 研究现状》[^1]披露了全球开发者如何构建他们的微服务,以及他们对微服务的看法。这份报告是在来自欧洲、北美、中南美洲、中东、东南亚、澳大利亚和新西兰的 660 名微服务专家的帮助下完成的。下表列出了微服务成熟度相关问题的平均评分[^1]:
|
||||
|
||||
**分类** | **平均得分(满分为5分)**
|
||||
---|---
|
||||
创建新项目 | 3.8
|
||||
维护与调试 | 3.4
|
||||
工作效率 | 3.9
|
||||
解决可扩展性问题 | 4.3
|
||||
解决性能问题 | 3.9
|
||||
团队合作 | 3.9
|
||||
|
||||
从上表可知,大部分专家都对使用微服务来解决可扩展性问题感到满意。与之相反的是,维护与调试对他们来说似乎是一个挑战。
|
||||
|
||||
从他们所使用的架构技术来说,大部分专家使用 Javascript/Typescript (大约 ⅔ 的微服务是使用这些语言构建的),其次使用的是 Java。
|
||||
|
||||
尽管有很多部署微服务的选择,但大多数专家使用 AWS(49%),其次是他们自己的服务器。另外,有 62% 的人更喜欢用 AWS Lambda 作为无服务器解决方案。
|
||||
|
||||
这些人所使用的大多数微服务都使用 HTTP 进行通信,其次是 events 和 gRPC。此外,大多数专家将 RabbitMQ 用于消息代理,其次是 Kafka 和 Redis。
|
||||
|
||||
而且,大多数人使用微服务持续集成(CI)。在报告中,87% 的受访者使用诸如 GitLab CI、Jenkins 或 GitHub Actions 等 CI 解决方案。
|
||||
|
||||
在 86% 的受访者中,最受欢迎的调试解决方案是日志,其中 27% 的受访者**只**使用日志。
|
||||
|
||||
最后,大多数人认为微服务架构将成为更复杂的系统或后端开发的标准。
|
||||
|
||||
### 微服务的成功案例
|
||||
|
||||
许多公司已经从单体架构转向微服务架构。
|
||||
|
||||
#### 亚马逊
|
||||
|
||||
在 2001 年,开发延迟、编码挑战和服务相互依赖性使得<ruby>亚马逊<rt>Amazon</rt></ruby>无法满足其不断增长的用户群的可扩展性需求。由于需要从头开始重构他们的单体架构,亚马逊将其单体架构应用程序拆分为小型的、独立的、针对服务的应用程序[^3][^9]。
|
||||
|
||||
2001 年,在微服务这个词开始流行之前的几年,亚马逊决定改用微服务。这一变化使得亚马逊开发了好几种支持微服务架构的解决方案,比如亚马逊 AWS。随着对微服务的快速增长和适应,亚马逊成为全球市值最高的公司,截至 2020 年 7 月 1 日,亚马逊市值为 1.433 万亿美元[^8]。
|
||||
|
||||
#### 奈飞
|
||||
|
||||
<ruby>奈飞<rt>Netflix</rt></ruby>于 2007 年开始提供电影流媒体服务,到了 2008 年,它也面临着规模扩张的挑战。期间,他们经历了一次严重的数据库损坏,在三天之内,他们不能将 DVD 发送给他们的会员[^10]。这一事故使他们意识到需要将单点故障(如关系数据库)转向云中更可伸缩和更可靠的分布式系统。于是 2009 年,奈飞开始将其单体架构的应用重构为微服务。他们首先将其非面向客户的电影编码平台迁移到云端作为独立的微服务运行[^11]。在改用微服务之后,使奈飞能够解决扩展性挑战和服务中断的问题。并且它还允许他们按照每个流数据而不是数据中心的成本来降低成本[^10]。今天,奈飞每天向 190 个国家的 1.39 亿订户发送约 2.5 亿小时的内容[^11]。
|
||||
|
||||
#### Uber
|
||||
|
||||
在推出 Uber 服务之后,他们在开发和发布新功能、修复 bug,以及迅速整合新的变化方面遇到了困难。因此,他们决定改用微服务,并将应用程序结构拆分为基于云的微服务。换句话说,Uber 为每个功能创建了一个微服务,比如乘客管理和出行管理。转向微服务给 Uber 带来了很多好处,比如对每项服务的所有权都有一个清晰的概念。这提高了服务访问的速度和质量,通过允许团队只关注他们需要扩展的服务,在更新虚拟服务的同时而不中断其他服务,实现了更可靠的容错,从而促进了快速扩展[^11]。
|
||||
|
||||
### 这就是可扩展性!
|
||||
|
||||
关于如何提供可伸缩性的一个很好的例子是看看中国。中国人口众多,必须通过创造和试验新的解决方案来适应规模化的新挑战。统计数据显示,中国目前为大约 9 亿互联网用户提供服务[^14]。2019 年“双十一”期间(相当于国外的黑色星期五),阿里巴巴旗下各购物平台的交易峰值为每秒 544000 笔交易。阿里云处理的数据总量约为 970 PB[^15]。那么,这些数量的用户在技术上意味着什么呢?
|
||||
|
||||
为了解决可伸缩性问题,许多技术应运而生。例如,[Tars][2] 由腾讯于 2008 年创建,[2018 年贡献给 Linux 基金会][3]。它也在被大规模使用,并在 10 年内得到了很大的提升[^12]。TARS 是开源的,许多组织都在大力贡献和扩展框架的特性和价值[^12]。TARS 支持多种编程语言,包括 C++、Golang、java、node.js、PHP 和 Python;它可以快速构建系统并自动生成代码,使开发人员能够专注于业务逻辑,从而有效地提高操作效率。TARS 已广泛应用于腾讯的 QQ、微信社交网络、金融服务、边缘计算、汽车、视频、网络游戏、地图、应用市场、安全等诸多核心业务。[在 2020 三月,TARS 项目转变为 TARS 基金会][4],这是一个开源微服务基金会,在建立开放式微服务平台的社区方面中,致力于提升社区贡献和成员的快速增长[^12]。
|
||||
|
||||
|
||||
**一定要看看 Linux 基金会新的免费培训课程**:《[用 TARS 构建微服务平台][5]》
|
||||
|
||||
*关于作者:*
|
||||
|
||||
*Isabella Ferreira 是 Linux 基金会旗下的开源微服务基金会 TARS 基金会的布道师*
|
||||
|
||||
*Mark Shan(单致豪)是腾讯开源联盟的主席,也是 TARS 基金会的董事会主席。*
|
||||
|
||||
[^1]: https://tsh.io/state-of-microservices/#ebook
|
||||
[^2]: https://medium.com/hashmapinc/the-what-why-and-how-of-a-microservices-architecture-4179579423a9
|
||||
[^3]: https://www.plutora.com/blog/understanding-microservices
|
||||
[^4]: https://www.leanix.net/en/blog/a-brief-history-of-microservices
|
||||
[^5]: https://www.charterglobal.com/five-microservices-trends-in-2020/
|
||||
[^6]: https://martinfowler.com/articles/microservices.html#footnote-etymology
|
||||
[^7]: https://whatis.techtarget.com/definition/monolithic-architecture
|
||||
[^8]: https://ycharts.com/companies/AMZN/market_cap
|
||||
[^9]: https://thenewstack.io/led-amazon-microservices-architecture/
|
||||
[^10]: https://media.netflix.com/en/company-blog/completing-the-netflix-cloud-migration
|
||||
[^11]: https://blog.dreamfactory.com/microservices-examples/
|
||||
[^12]: https://www.linuxfoundation.org/blog/2020/03/the-tars-foundation-the-formation-of-a-microservices-ecosystem/
|
||||
[^13]: https://medium.com/microservices-architecture/top-10-microservices-framework-for-2020-eefb5e66d1a2
|
||||
[^14]: https://www.statista.com/statistics/265140/number-of-internet-users-in-china/
|
||||
[^15]: https://interconnected.blog/china-scale-technology-sandbox/
|
||||
|
||||
> 本篇 Linux 基金会白金赞助商内容由腾讯贡献。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/news/the-state-of-the-art-of-microservices-in-2020/
|
||||
|
||||
作者:[Linux.com][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zhangxiangping](https://github.com/zxp93)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/author/linuxdotcom/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/wp-content/uploads/2020/11/microservices_diagram_a.png
|
||||
[2]: https://tarscloud.org/foundation/index
|
||||
[3]: https://www.linuxfoundation.org/press-release/2018/06/tars-and-tseer-form-open-source-project-communities-under-the-linux-foundation-to-expand-adoption-and-pace-of-development/
|
||||
[4]: https://www.linuxfoundation.org/blog/2020/03/the-tars-foundation-the-formation-of-a-microservices-ecosystem/
|
||||
[5]: https://www.edx.org/course/building-microservice-platforms-with-tars
|
@ -0,0 +1,136 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12939-1.html)
|
||||
[#]: subject: (How to Write, Compile and Run a C Program in Ubuntu and Other Linux Distributions [Beginner’s Tip])
|
||||
[#]: via: (https://itsfoss.com/run-c-program-linux/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
如何在 Ubuntu/Debian Linux 上编写、编译和运行一个 C 程序
|
||||
======
|
||||
|
||||
![][2]
|
||||
|
||||
你是如何在 Linux 上使用 C 编写你的程序的?它确实是非常简单的,由三个简单的步骤组成。
|
||||
|
||||
**步骤 1**: 编写你的 C 程序,并使用一个 `.c` 的扩展名进行保存。例如,`my_program.c` 。
|
||||
|
||||
**步骤 2**: 在一个终端中使用 `gcc` 编译器来编译程序并生成目标文件,像这样:
|
||||
|
||||
```
|
||||
gcc -o my_program my_program.c
|
||||
```
|
||||
|
||||
**步骤 3**: 在 Linux 中,你可以以运行生成的对象文件的方式来运行你的 C 程序:
|
||||
|
||||
```
|
||||
./my_program
|
||||
```
|
||||
|
||||
![][1]
|
||||
|
||||
这只是如何在 Linux 中编译和运行 C 程序的简要总结。假设你是 C 语言或 Linux 系统的新手,我将仔细演示这些步骤,以便你能在 Linux 环境中舒服地编写 C 程序。
|
||||
|
||||
事实上,我将讨论如何在 Linux 终端中以及在代码编辑器中运行 C 程序的两种方式。
|
||||
|
||||
### 方法 1: 在 Linux 终端中运行 C 程序
|
||||
|
||||
为了在 Linux 中运行一个 C 程序,你需要在你的系统上有一个 C 编译器。最流行的编译器是 `gcc`(<ruby>[GNU 编译器套件][3]<rt>GNU Compiler Collection</rt></ruby>)。
|
||||
|
||||
你可以使用你发行版的软件包管理器来安装 `gcc` 。在基于 Debian 和 Ubuntu 的 Linux 发行版中,使用 `apt` 命令:
|
||||
|
||||
```
|
||||
sudo apt install gcc
|
||||
```
|
||||
|
||||
切换到保存你的 C 程序的目录(或者提供路径),然后通过编译程序生成对象文件:
|
||||
|
||||
```
|
||||
gcc -o my_program my_program.c
|
||||
```
|
||||
|
||||
记住,提供输出对象文件(`-o my_program`)是可选的。如果你不提供,那么将自动生成一个名称为 `a.out` 的对象文件。但是这样并不好,因为编译每个 C 程序都会覆盖它,而且你也不知道这个 `a.out` 对象文件究竟属于哪个程序。
|
||||
|
||||
在你的对象文件生成后,运行它来运行 C 程序。它已经能够执行了。像这样简单地使用它:
|
||||
|
||||
```
|
||||
./my_program
|
||||
```
|
||||
|
||||
接下来,如果你的程序是正确的,它将显示出你所期望的输出。正如你所看到的,这和 [在 Linux 中运行 C++ 程序][4] 没什么不同。
|
||||
|
||||
*每更改一次你的程序,你都必须先重新编译它,然后再次运行生成的对象文件来运行这个新的 C 程序。*
|
||||
|
||||
### 方法 2: 如何在 Linux 中使用一个诸如 VSCode 之类的代码编辑器来运行 C 程序
|
||||
|
||||
并不是每一个人都能适应命令行和终端,我完全理解这一点。
|
||||
|
||||
你可以使用一个诸如 Eclipse 或 Code Blocks 之类的真正的 C/C++ IDE ,但是它们是很重量级的程序,通常更适合于大型的项目。
|
||||
|
||||
我建议使用一个开源的代码编辑器,像 VSCode 或 Atom 。它们基本上是文本编辑器,但是你可以通过安装附加组件来直接在图形化的代码编辑器中编译和运行程序。
|
||||
|
||||
在这个示例中,我使用 [VSCode][5] 编辑器。它是一个来自微软的 [非常流行的开源的代码编辑器][6] 。
|
||||
|
||||
首先,在 Ubuntu 的 [软件中心中安装 VSCode][7] 。对于其它发行版来说,请检查你的 Linux 发行版的软件包管理器或软件中心。你可以参看它的官方网站来查看更多的信息。
|
||||
|
||||
启动 VSCode ,打开或创建一个工程,在这里创建你的 C 程序。我使用一个简单的 Hello World 程序作为示例。
|
||||
|
||||
![][8]
|
||||
|
||||
你必须确保你已经在你的 Linux 系统上安装了 `gcc` 编译器。
|
||||
|
||||
```
|
||||
sudo apt install gcc
|
||||
```
|
||||
|
||||
接下来你要做的事是使用一个允许你运行 C 代码的扩展。微软可能会提示你安装它的 C/C++ 程序扩展,但它的设置很复杂,因此我不推荐。
|
||||
|
||||
相反,我建议你使用 Code Runner 扩展。它是一个简单直接的扩展,你可以在不使用额外配置的情况下轻松地运行 C 和 C++ 代码。
|
||||
|
||||
转到扩展标签页,在其中搜索和安装 “Code Runner” 。
|
||||
|
||||
![安装 Code Runner 扩展来运行 C/C++ 程序][9]
|
||||
|
||||
重新启动 VSCode 。现在,你能够使用下面方法中的其中一个来运行 C 代码:
|
||||
|
||||
* 使用快捷键 `Ctrl+Alt+N` 。
|
||||
* 按下 `F1` ,接下来选择或输入 “Run Code” 。
|
||||
* 在文本编辑器中右键单击,从上下文菜单中单击 “Run code” 。
|
||||
|
||||
![右键单击程序文件,然后选择 Run Code][10]
|
||||
|
||||
当你运行这个 C 程序时,它将会被自动编译和运行。你可以在编辑器底部打开的终端中看到输出。还有比这更好的事情吗?
|
||||
|
||||
![程序输出显示在编辑器的底部][11]
|
||||
|
||||
你更喜欢哪一种方法?
|
||||
|
||||
在 Linux 命令行中运行一些 C 程序是没有问题的,但是使用一个代码编辑器会更容易一些,而且会节省时间。你不觉得吗?
|
||||
|
||||
你可以自己决定想使用哪一种方法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/run-c-program-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[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://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/running-c-program-linux.png?resize=795%2C399&ssl=1
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/Run-C-Program-Linux.png?resize=800%2C450&ssl=1
|
||||
[3]: https://gcc.gnu.org/
|
||||
[4]: https://itsfoss.com/c-plus-plus-ubuntu/
|
||||
[5]: https://code.visualstudio.com
|
||||
[6]: https://itsfoss.com/best-modern-open-source-code-editors-for-linux/
|
||||
[7]: https://itsfoss.com/install-visual-studio-code-ubuntu/
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/11/c-program-visual-studio-code-linux.png?resize=800%2C441&ssl=1
|
||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/running-c-program-in-linux-with-visual-studio-code.png?resize=800%2C500&ssl=1
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/11/running-c-program-in-linux-with-visual-studio-code.jpg?resize=800%2C500&ssl=1
|
||||
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/11/run-c-program-in-linux-with-visual-studio-code.jpg?resize=800%2C500&ssl=1
|
@ -0,0 +1,194 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zxp93)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12932-1.html)
|
||||
[#]: subject: (An attempt at implementing char-rnn with PyTorch)
|
||||
[#]: via: (https://jvns.ca/blog/2020/11/30/implement-char-rnn-in-pytorch/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
用 PyTorch 实现基于字符的循环神经网络
|
||||
======
|
||||
|
||||

|
||||
|
||||
在过去的几周里,我花了很多时间用 PyTorch 实现了一个 [char-rnn][1] 的版本。我以前从未训练过神经网络,所以这可能是一个有趣的开始。
|
||||
|
||||
这个想法(来自 [循环神经网络的不合理效应][1])可以让你在文本上训练一个基于字符的<ruby>循环神经网络<rt>recurrent neural network</rt></ruby>(RNN),并得到一些出乎意料好的结果。
|
||||
|
||||
不过,虽然没有得到我想要的结果,但是我还是想分享一些示例代码和结果,希望对其他开始尝试使用 PyTorch 和 RNN 的人有帮助。
|
||||
|
||||
这是 Jupyter 笔记本格式的代码:[char-rnn in PyTorch.ipynb][2]。你可以点击这个网页最上面那个按钮 “Open in Colab”,就可以在 Google 的 Colab 服务中打开,并使用免费的 GPU 进行训练。所有的东西加起来大概有 75 行代码,我将在这篇博文中尽可能地详细解释。
|
||||
|
||||
### 第一步:准备数据
|
||||
|
||||
首先,我们要下载数据。我使用的是<ruby>古登堡项目<rt>Project Gutenberg</rt></ruby>中的这个数据:[Hans Christian Anderson’s fairy tales][3]。
|
||||
|
||||
```
|
||||
!wget -O fairy-tales.txt
|
||||
```
|
||||
|
||||
这个是准备数据的代码。我使用 `fastai` 库中的 `Vocab` 类进行数据处理,它能将一堆字母转换成“词表”,然后用这个“词表”把字母变成数字。
|
||||
|
||||
之后我们就得到了一个大的数字数组(`training_set`),我们可以用于训练我们的模型。
|
||||
|
||||
```
|
||||
from fastai.text import *
|
||||
text = unidecode.unidecode(open('fairy-tales.txt').read())
|
||||
v = Vocab.create((x for x in text), max_vocab=400, min_freq=1)
|
||||
training_set = torch.Tensor(v.numericalize([x for x in text])).type(torch.LongTensor).cuda()
|
||||
num_letters = len(v.itos)
|
||||
```
|
||||
|
||||
### 第二步:定义模型
|
||||
|
||||
这个是 PyTorch 中 `LSTM` 类的封装。除了封装 `LSTM` 类以外,它还做了三件事:
|
||||
|
||||
1. 对输入向量进行 one-hot 编码,使得它们具有正确的维度。
|
||||
2. 在 `LSTM` 层后一层添加一个线性变换,因为 `LSTM` 输出的是一个长度为 `hidden_size` 的向量,我们需要的是一个长度为 `input_size` 的向量这样才能把它变成一个字符。
|
||||
3. 把 `LSTM` 隐藏层的输出向量(实际上有 2 个向量)保存成实例变量,然后在每轮运行结束后执行 `.detach()` 函数。(我很难解释清 `.detach()` 的作用,但我的理解是,它在某种程度上“结束”了模型的求导计算)(LCTT 译注:`detach()` 函数是将该张量的 `requires_grad` 参数设置为 `False`,即反向传播到该张量就结束。)
|
||||
|
||||
```
|
||||
class MyLSTM(nn.Module):
|
||||
def __init__(self, input_size, hidden_size):
|
||||
super().__init__()
|
||||
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
|
||||
self.h2o = nn.Linear(hidden_size, input_size)
|
||||
self.input_size=input_size
|
||||
self.hidden = None
|
||||
|
||||
def forward(self, input):
|
||||
input = torch.nn.functional.one_hot(input, num_classes=self.input_size).type(torch.FloatTensor).cuda().unsqueeze(0)
|
||||
if self.hidden is None:
|
||||
l_output, self.hidden = self.lstm(input)
|
||||
else:
|
||||
l_output, self.hidden = self.lstm(input, self.hidden)
|
||||
self.hidden = (self.hidden[0].detach(), self.hidden[1].detach())
|
||||
|
||||
return self.h2o(l_output)
|
||||
```
|
||||
|
||||
这个代码还做了一些比较神奇但是不太明显的功能。如果你的输入是一个向量(比如 `[1,2,3,4,5,6]`),对应六个字母,那么我的理解是 `nn.LSTM` 会在内部使用[沿时间反向传播][4]更新隐藏向量 6 次。
|
||||
|
||||
### 第三步:编写训练代码
|
||||
|
||||
模型不会自己训练的!
|
||||
|
||||
我最开始的时候尝试用 `fastai` 库中的一个辅助类(也是 PyTorch 中的封装)。我有点疑惑因为我不知道它在做什么,所以最后我自己编写了模型训练代码。
|
||||
|
||||
下面这些代码(`epoch()` 方法)就是有关于一轮训练过程的基本信息。基本上就是重复做下面这几件事情:
|
||||
|
||||
1. 往 RNN 模型中传入一个字符串,比如 `and they ought not to teas`。(要以数字向量的形式传入)
|
||||
2. 得到下一个字母的预测结果
|
||||
3. 计算 RNN 模型预测结果和真实的下一个字母之间的损失函数(`e`,因为 `tease` 这个单词是以 `e` 结尾的)
|
||||
4. 计算梯度(用 `loss.backward()` 函数)
|
||||
5. 沿着梯度下降的方向修改模型中参数的权重(用 `self.optimizer.step()` 函数)
|
||||
|
||||
```
|
||||
class Trainer():
|
||||
def __init__(self):
|
||||
self.rnn = MyLSTM(input_size, hidden_size).cuda()
|
||||
self.optimizer = torch.optim.Adam(self.rnn.parameters(), amsgrad=True, lr=lr)
|
||||
def epoch(self):
|
||||
i = 0
|
||||
while i < len(training_set) - 40:
|
||||
seq_len = random.randint(10, 40)
|
||||
input, target = training_set[i:i+seq_len],training_set[i+1:i+1+seq_len]
|
||||
i += seq_len
|
||||
# forward pass
|
||||
output = self.rnn(input)
|
||||
loss = F.cross_entropy(output.squeeze()[-1:], target[-1:])
|
||||
# compute gradients and take optimizer step
|
||||
self.optimizer.zero_grad()
|
||||
loss.backward()
|
||||
self.optimizer.step()
|
||||
```
|
||||
|
||||
### 使用 nn.LSTM 沿着时间反向传播,不要自己写代码
|
||||
|
||||
开始的时候我自己写代码每次传一个字母到 LSTM 层中,之后定期计算导数,就像下面这样:
|
||||
|
||||
```
|
||||
for i in range(20):
|
||||
input, target = next(iter)
|
||||
output, hidden = self.lstm(input, hidden)
|
||||
loss = F.cross_entropy(output, target)
|
||||
hidden = hidden.detach()
|
||||
self.optimizer.zero_grad()
|
||||
loss.backward()
|
||||
self.optimizer.step()
|
||||
```
|
||||
|
||||
这段代码每次传入 20 个字母,每次一个,并且在最后训练了一次。这个步骤就被称为[沿时间反向传播][4],Karpathy 在他的博客中就是用这种方法。
|
||||
|
||||
这个方法有些用处,我编写的损失函数开始能够下降一段时间,但之后就会出现峰值。我不知道为什么会出现这种现象,但之后我改为一次传入 20 个字符到 LSTM 之后(按 `seq_len` 维度),再进行反向传播,情况就变好了。
|
||||
|
||||
### 第四步:训练模型!
|
||||
|
||||
我在同样的数据上重复执行了这个训练代码大概 300 次,直到模型开始输出一些看起来像英文的文本。差不多花了一个多小时吧。
|
||||
|
||||
这种情况下我也不关注模型是不是过拟合了,但是如果你在真实场景中训练模型,应该要在验证集上验证你的模型。
|
||||
|
||||
### 第五步:生成输出!
|
||||
|
||||
最后一件要做的事就是用这个模型生成一些输出。我写了一个辅助方法从这个训练好的模型中生成文本(`make_preds` 和 `next_pred`)。这里主要是把向量的维度对齐,重要的一点是:
|
||||
|
||||
```
|
||||
output = rnn(input)
|
||||
prediction_vector = F.softmax(output/temperature)
|
||||
letter = v.textify(torch.multinomial(prediction_vector, 1).flatten(), sep='').replace('_', ' ')
|
||||
```
|
||||
|
||||
基本上做的事情就是这些:
|
||||
|
||||
1. RNN 层为字母表中的每一个字母或者符号输出一个数值向量(`output`)。
|
||||
2. 这个 `output` 向量**并不是**一个概率向量,所以需要 `F.softmax(output/temperature)` 操作,将其转换为概率值(也就是所有数值加起来和为 1)。`temperature` 某种程度上控制了对更高概率的权重,在限制范围内,如果设置 `temperature=0.0000001`,它将始终选择概率最高的字母。
|
||||
3. `torch.multinomial(prediction_vector)` 用于获取概率向量,并使用这些概率在向量中选择一个索引(如 `12`)。
|
||||
4. `v.textify` 把 `12` 转换为字母。
|
||||
|
||||
如果我们想要处理的文本长度为 300,那么只需要重复这个过程 300 次就可以了。
|
||||
|
||||
### 结果!
|
||||
|
||||
我把预测函数中的参数设置为 `temperature = 1` 得到了下面的这些由模型生成的结果。看起来有点像英语,这个结果已经很不错了,因为这个模型要从头开始“学习”英语,并且是在字符序列的级别上进行学习的。
|
||||
|
||||
虽然这些话没有什么*含义*,但我们也不知道到底想要得到什么输出。
|
||||
|
||||
> “An who was you colotal said that have to have been a little crimantable and beamed home the beetle. “I shall be in the head of the green for the sound of the wood. The pastor. “I child hand through the emperor’s sorthes, where the mother was a great deal down the conscious, which are all the gleam of the wood they saw the last great of the emperor’s forments, the house of a large gone there was nothing of the wonded the sound of which she saw in the converse of the beetle. “I shall know happy to him. This stories herself and the sound of the young mons feathery in the green safe.”
|
||||
>
|
||||
> “That was the pastor. The some and hand on the water sound of the beauty be and home to have been consider and tree and the face. The some to the froghesses and stringing to the sea, and the yellow was too intention, he was not a warm to the pastor. The pastor which are the faten to go and the world from the bell, why really the laborer’s back of most handsome that she was a caperven and the confectioned and thoughts were seated to have great made
|
||||
|
||||
下面这些结果是当 `temperature=0.1` 时生成的,它选择字符的方式更接近于“每次都选择出现概率最高的字符”。这就使得输出结果有很多是重复的。
|
||||
|
||||
> ole the sound of the beauty of the beetle. “She was a great emperor of the sea, and the sun was so warm to the confectioned the beetle. “I shall be so many for the beetle. “I shall be so many for the beetle. “I shall be so standen for the world, and the sun was so warm to the sea, and the sun was so warm to the sea, and the sound of the world from the bell, where the beetle was the sea, and the sound of the world from the bell, where the beetle was the sea, and the sound of the wood flowers and the sound of the wood, and the sound of the world from the bell, where the world from the wood, and the sound of the
|
||||
|
||||
这段输出对这几个单词 `beetles`、`confectioners`、`sun` 和 `sea` 有着奇怪的执念。
|
||||
|
||||
### 总结!
|
||||
|
||||
至此,我的结果远不及 Karpathy 的好,可能有一下几个原因:
|
||||
|
||||
1. 没有足够多的训练数据。
|
||||
2. 训练了一个小时之后我就没有耐心去查看 Colab 笔记本上的信息。
|
||||
3. Karpathy 使用了两层LSTM,包含了更多的参数,而我只使用了一层。
|
||||
4. 完全是另一回事。
|
||||
|
||||
但我得到了一些大致说得过去的结果!还不错!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2020/11/30/implement-char-rnn-in-pytorch/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zhangxiangping](https://github.com/zxp93)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://karpathy.github.io/2015/05/21/rnn-effectiveness/
|
||||
[2]: https://gist.github.com/jvns/b6dda36b2fdcc02b833ed5b0c7a09112
|
||||
[3]: https://www.gutenberg.org/cache/epub/27200/pg27200.txt
|
||||
[4]: https://en.wikipedia.org/wiki/Backpropagation_through_time
|
@ -0,0 +1,94 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12947-1.html)
|
||||
[#]: subject: (Get the most out of the Vi text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/vi-text-editor)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
初识 Vi 文本编辑器
|
||||
======
|
||||
|
||||
> Vi 是典型的 Unix 文本编辑器。来了解一下它或它的各种化身:Vim、Neovim、gVim、nvi 或 Elvis,它适用于 Linux、macOS、Windows 或 BSD。
|
||||
|
||||

|
||||
|
||||
不管你用的是 Vim、Neovim、gVim、nvi,甚至是 Elvis,其实都是这个典型的 Unix 编辑器 Vi。可能每一个 Linux 和 BSD 发行版中都包含了 Vi,Vi 是一个轻量级的简约型文本编辑器,由于其简单简洁的键盘快捷键和双模式设计,很多用户都喜欢它。
|
||||
|
||||
最初的 Vi 编辑器是由 [C shell][2] 的创建者 Bill Joy 编写的应用程序。现代 Vi 的化身已经[增加了许多功能][3],包括多级撤销、插入模式下更好的导航、行折叠、语法高亮、插件支持等等。Vim 被认为是它的最流行的现代实现,大多数人在提到 Vi 时实际上是指 Vim。
|
||||
|
||||
所有这些化身都是为了同一个目标,所以本文将从通用的场景来探讨 Vi。你的计算机上的版本可能略有不同,但你仍然可以从 Vi 编辑文本的方式中获益。
|
||||
|
||||
### 安装 Vi
|
||||
|
||||
如果你运行的是 Linux、macOS 或 BSD,那么你已经安装了 `vi` 命令。如果你在 Windows 上,你可以[下载 Vim 和 gVim][4]。
|
||||
|
||||
![gVim][5]
|
||||
|
||||
在 [NetBSD][7]上,nvi 是 Vi 的常见替代品,而 Slackware 则提供了 [Elvis][8](和 Vim),流行的 [Neovim][9] 复刻旨在帮助用户用 [Lua][10] 扩展 Vim。
|
||||
|
||||
### 启动 Vi
|
||||
|
||||
在终端中用 `vi` 命令启动 Vi 或 Vim。如果在你的系统中没有找到 `.vimrc` 文件,那么 Vim 就会以 Vi 兼容模式启动(也可以用 `-C` 选项强制启动该模式)。如果你想使用 gVim 以拥有一个图形用户界面(GUI),你可以从桌面的应用程序菜单中启动它。
|
||||
|
||||
如果你是一个刚刚学习 Vi 的新用户,使用图形用户界面是一个很好的方法,可以在你可能期望的文本编辑器的行为和 Vi 的设计行为之间提供一个缓冲带。图形用户界面版本有一个菜单栏,一些鼠标集成,一个工具栏和其他功能,这可以帮助你找到你可能认为在典型的文本编辑器中理所当然的基本功能,但还不知道如何在 Vi 中做。
|
||||
|
||||
### 如何使用 Vi
|
||||
|
||||
学习 Vi 最简单的方法可能是使用 `vimtutor`,这是一个与 Vim 打包在一起的交互式教程。要开始学习该教程,启动 `vimtutor` 并阅读说明,尝试每个练习。正如教程中所说,学好 Vi 不是记住什么键做什么,而是建立肌肉记忆,以在输入时调用常用的动作。
|
||||
|
||||
#### Esc 键
|
||||
|
||||
学习 Vi 的第一件重要的事就是掌握 `Esc` 键。`Esc` 是激活*命令模式*的工具,很快你就会明白,在 Vi 中,只要你不确定,就按 `Esc`。在命令模式下,你按下的任何键都不会被输入到你正在处理的文本文档中,而是被 Vi 解释为一条命令。例如,要将光标向左移动,你可以按键盘上的 `H` 键。如果你处于*插入*模式,那么按 `H` 键就会输入字母 H,就像你期望的那样。但在*命令*模式下,按 `H` 向左移动,`L` 向右移动,`J` 向下移动,`K` 向上移动。
|
||||
|
||||
命令模式和插入模式的分离与其他文本编辑器的工作方式形成了鲜明的对比,由于这种设计,这可能是 Vi 最显著的差异化。不过有趣的是,理论上来说,它与你可能已有的工作方式并没有太大的区别。毕竟,当你把手从键盘上拿开,用鼠标选择文本时,你基本上是将自己置于一种命令模式中。在 Vi 中,你不需要把手从键盘上移开来移动鼠标,也不需要按功能键或 `Ctrl` 键,而是将*编辑器*放入一种特殊的操作模式中,使你的按键重新分配到命令上,而不是文字输入。
|
||||
|
||||
#### 扩展 Vi
|
||||
|
||||
在 Vim 8.0 版本之前,Vi 在很大程度上“只是”一个文本编辑器。它有插件,但安装插件是一个手动的过程,很多用户从未想过要这么做。幸运的是,Vim 8 及以上版本提供了对插件管理的支持,使得安装和加载插件变得轻而易举。
|
||||
|
||||
安装 Vim 的插件可以通过 `vim-plug` 功能来完成。例如,要安装 Vi 文件浏览器 [NERDTree][11]:
|
||||
|
||||
```
|
||||
:PlugInstall NERDTree
|
||||
```
|
||||
|
||||
你也可以更新插件:
|
||||
|
||||
```
|
||||
:PlugUpdate NERDTree
|
||||
```
|
||||
|
||||
关于使用 `vim-plug` 和手动安装插件和主题的更多信息,请阅读我的文章《[如何安装 Vim 插件][12]》。
|
||||
|
||||
### 默认 Vi
|
||||
|
||||
Vi 不仅仅流行,它还是一个 [POSIX][13] 标准。它是每个系统管理员都应该知道如何使用的应用程序,即使他们不打算每天使用它。它也是一个快速而简单的编辑器,所以一旦你熟练掌握了它,它可能就是你一直在寻找的编辑器。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/vi-text-editor
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||
[2]: https://opensource.com/article/20/8/tcsh
|
||||
[3]: https://vimhelp.org/vi_diff.txt.html#vi-differences
|
||||
[4]: https://www.vim.org/download.php
|
||||
[5]: https://opensource.com/sites/default/files/uploads/gvim.jpg (gVim)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://opensource.com/article/19/3/netbsd-raspberry-pi
|
||||
[8]: https://github.com/mbert/elvis
|
||||
[9]: http://neovim.io
|
||||
[10]: https://opensource.com/article/20/2/lua-cheat-sheet
|
||||
[11]: https://www.vim.org/scripts/script.php?script_id=1658
|
||||
[12]: https://opensource.com/article/20/2/how-install-vim-plugins
|
||||
[13]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
@ -0,0 +1,272 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12936-1.html)
|
||||
[#]: subject: (Add storage to your Fedora system with LVM)
|
||||
[#]: via: (https://fedoramagazine.org/add-storage-to-your-fedora-system-with-lvm/)
|
||||
[#]: author: (Tim Bosse https://fedoramagazine.org/author/maztaim/)
|
||||
|
||||
使用 LVM 为你的 Fedora 系统添加存储
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
有时需要在系统中添加另一块磁盘。这就是<ruby>逻辑卷管理<rt>Logical Volume Management</rt></ruby>(LVM)的用武之地。LVM 的好处之处在于它相当灵活。有几种方法可以添加一块磁盘。这篇文章介绍了一种方法。
|
||||
|
||||
### 注意!
|
||||
|
||||
这篇文章并不包括将新的磁盘物理地安装到系统中的过程。请查阅你的系统和磁盘文档,了解如何正确地进行安装。
|
||||
|
||||
**重要:** 一定要确保你已经备份重要数据。如果新磁盘已有数据,那么本文中描述的步骤将破坏数据。
|
||||
|
||||
### 最好了解
|
||||
|
||||
本文并没有深入介绍 LVM 的每一个功能,重点是添加磁盘。但基本上你要了解,LVM 有<ruby>卷组<rt>volume group</rt></ruby>(VG),它由一个或多个分区和/或磁盘组成。你把这些分区或磁盘以<ruby>物理卷<rt>physical volume</rt></ruby>(PV)的方式添加到卷组。一个卷组可以分成许多<ruby>逻辑卷<rt>logical volume</rt></ruby>(LV)。逻辑卷可以作为文件系统、ramdisk 等其他存储使用。更多信息可以在[这里][2]中找到。
|
||||
|
||||
可以看作是,把物理卷形成一个存储池(一个卷组),然后从这个存储池中划分出逻辑卷,供你的系统直接使用。
|
||||
|
||||
### 准备
|
||||
|
||||
确保你能看到你要添加的磁盘。在添加磁盘之前使用 `lsblk` 查看哪些存储空间已经可用或正在使用。
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
zram0 251:0 0 989M 0 disk [SWAP]
|
||||
vda 252:0 0 20G 0 disk
|
||||
├─vda1 252:1 0 1G 0 part /boot
|
||||
└─vda2 252:2 0 19G 0 part
|
||||
└─fedora_fedora-root 253:0 0 19G 0 lvm /
|
||||
```
|
||||
|
||||
本文使用的是带有虚拟存储的虚拟机,因此设备名称以 `vda` 开头代表第一个磁盘,`vdb` 代表第二个磁盘,以此类推。你的设备名称可能不同。许多系统会将 `sda` 作为第一个物理磁盘,`sdb` 代表第二个磁盘,以此类推。
|
||||
|
||||
当已连接新磁盘,并且你的系统已备份且正在运行,再次使用 `lsblk` 来查看新的块设备。
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
zram0 251:0 0 989M 0 disk [SWAP]
|
||||
vda 252:0 0 20G 0 disk
|
||||
├─vda1 252:1 0 1G 0 part /boot
|
||||
└─vda2 252:2 0 19G 0 part
|
||||
└─fedora_fedora-root 253:0 0 19G 0 lvm /
|
||||
vdb 252:16 0 10G 0 disk
|
||||
```
|
||||
|
||||
现在有一个名为 `vdb` 的新设备。该设备的位置是 `/dev/vdb`。
|
||||
|
||||
```
|
||||
$ ls -l /dev/vdb
|
||||
brw-rw----. 1 root disk 252, 16 Nov 24 12:56 /dev/vdb
|
||||
```
|
||||
|
||||
我们可以看到磁盘,但我们还不能用 LVM 来使用它。如果你运行 `blkid`,你应该不会看到它被列出。对于这个和之后的命令,你需要确保你的系统[已配置好,这样你可以使用 sudo][3]:
|
||||
|
||||
```
|
||||
$ sudo blkid
|
||||
/dev/vda1: UUID="4847cb4d-6666-47e3-9e3b-12d83b2d2448" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="830679b8-01"
|
||||
/dev/vda2: UUID="k5eWpP-6MXw-foh5-Vbgg-JMZ1-VEf9-ARaGNd" TYPE="LVM2_member" PARTUUID="830679b8-02"
|
||||
/dev/mapper/fedora_fedora-root: UUID="f8ab802f-8c5f-4766-af33-90e78573f3cc" BLOCK_SIZE="4096" TYPE="ext4"
|
||||
/dev/zram0: UUID="fc6d7a48-2bd5-4066-9bcf-f062b61f6a60" TYPE="swap"
|
||||
```
|
||||
|
||||
### 将磁盘添加到 LVM 中
|
||||
|
||||
使用 `pvcreate` 初始化磁盘。你需要传递设备的完整路径。在这个例子中,它是 `/dev/vdb`。在你的系统中,它可能是 `/dev/sdb` 或其他设备名。
|
||||
|
||||
```
|
||||
$ sudo pvcreate /dev/vdb
|
||||
Physical volume "/dev/vdb" successfully created.
|
||||
```
|
||||
|
||||
当你运行 `blkid` 时,你应该看到磁盘已经被初始化为一个 `LVM2_member`:
|
||||
|
||||
```
|
||||
$ sudo blkid
|
||||
/dev/vda1: UUID="4847cb4d-6666-47e3-9e3b-12d83b2d2448" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="830679b8-01"
|
||||
/dev/vda2: UUID="k5eWpP-6MXw-foh5-Vbgg-JMZ1-VEf9-ARaGNd" TYPE="LVM2_member" PARTUUID="830679b8-02"
|
||||
/dev/mapper/fedora_fedora-root: UUID="f8ab802f-8c5f-4766-af33-90e78573f3cc" BLOCK_SIZE="4096" TYPE="ext4"
|
||||
/dev/zram0: UUID="fc6d7a48-2bd5-4066-9bcf-f062b61f6a60" TYPE="swap"
|
||||
/dev/vdb: UUID="4uUUuI-lMQY-WyS5-lo0W-lqjW-Qvqw-RqeroE" TYPE="LVM2_member"
|
||||
```
|
||||
|
||||
你可以使用 `pvs` 列出当前所有可用的物理卷:
|
||||
|
||||
```
|
||||
$ sudo pvs
|
||||
PV VG Fmt Attr PSize PFree
|
||||
/dev/vda2 fedora_fedora lvm2 a-- <19.00g 0
|
||||
/dev/vdb lvm2 --- 10.00g 10.00g
|
||||
```
|
||||
|
||||
`/dev/vdb` 被列为一个 PV (物理卷),但还没有分配到一个 VG (卷组)。
|
||||
|
||||
### 将物理卷添加到一个卷组
|
||||
|
||||
你可以使用 `vgs` 找到可用的卷组列表:
|
||||
|
||||
```
|
||||
$ sudo vgs
|
||||
VG #PV #LV #SN Attr VSize VFree
|
||||
fedora_fedora 1 1 0 wz--n- 19.00g 0
|
||||
```
|
||||
|
||||
在本例中,只有一个卷组可用。接下来,将物理卷添加到 `fedora_fedora`:
|
||||
|
||||
```
|
||||
$ sudo vgextend fedora_fedora /dev/vdb
|
||||
Volume group "fedora_fedora" successfully extended
|
||||
```
|
||||
|
||||
你现在应该看到物理卷已被添加到卷组中:
|
||||
|
||||
```
|
||||
$ sudo pvs
|
||||
PV VG Fmt Attr PSize PFree
|
||||
/dev/vda2 fedora_fedora lvm2 a– <19.00g 0
|
||||
/dev/vdb fedora_fedora lvm2 a– <10.00g <10.00g
|
||||
```
|
||||
|
||||
看一下卷组:
|
||||
|
||||
```
|
||||
$ sudo vgs
|
||||
VG #PV #LV #SN Attr VSize VFree
|
||||
fedora_fedora 2 1 0 wz–n- 28.99g <10.00g
|
||||
```
|
||||
|
||||
你也可以获得具体卷组和物理卷的详细列表:
|
||||
|
||||
```
|
||||
$ sudo vgdisplay fedora_fedora
|
||||
--- Volume group ---
|
||||
VG Name fedora_fedora
|
||||
System ID
|
||||
Format lvm2
|
||||
Metadata Areas 2
|
||||
Metadata Sequence No 3
|
||||
VG Access read/write
|
||||
VG Status resizable
|
||||
MAX LV 0
|
||||
Cur LV 1
|
||||
Open LV 1
|
||||
Max PV 0
|
||||
Cur PV 2
|
||||
Act PV 2
|
||||
VG Size 28.99 GiB
|
||||
PE Size 4.00 MiB
|
||||
Total PE 7422
|
||||
Alloc PE / Size 4863 / 19.00 GiB
|
||||
Free PE / Size 2559 / 10.00 GiB
|
||||
VG UUID C5dL2s-dirA-SQ15-TfQU-T3yt-l83E-oI6pkp
|
||||
```
|
||||
|
||||
看下物理卷:
|
||||
|
||||
```
|
||||
$ sudo pvdisplay /dev/vdb
|
||||
--- Physical volume ---
|
||||
PV Name /dev/vdb
|
||||
VG Name fedora_fedora
|
||||
PV Size 10.00 GiB / not usable 4.00 MiB
|
||||
Allocatable yes
|
||||
PE Size 4.00 MiB
|
||||
Total PE 2559
|
||||
Free PE 2559
|
||||
Allocated PE 0
|
||||
PV UUID 4uUUuI-lMQY-WyS5-lo0W-lqjW-Qvqw-RqeroE
|
||||
```
|
||||
|
||||
现在我们已经添加了磁盘,我们可以为逻辑卷 (LV) 分配空间:
|
||||
|
||||
```
|
||||
$ sudo lvs
|
||||
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
|
||||
root fedora_fedora -wi-ao---- 19.00g
|
||||
```
|
||||
|
||||
看一下逻辑卷。下面是详细的逻辑卷信息:
|
||||
|
||||
```
|
||||
$ sudo lvdisplay fedora_fedora/root
|
||||
--- Logical volume ---
|
||||
LV Path /dev/fedora_fedora/root
|
||||
LV Name root
|
||||
VG Name fedora_fedora
|
||||
LV UUID yqc9cw-AvOw-G1Ni-bCT3-3HAa-qnw3-qUSHGM
|
||||
LV Write Access read/write
|
||||
LV Creation host, time fedora, 2020-11-24 11:44:36 -0500
|
||||
LV Status available
|
||||
LV Size 19.00 GiB
|
||||
Current LE 4863
|
||||
Segments 1
|
||||
Allocation inherit
|
||||
Read ahead sectors auto
|
||||
- currently set to 256
|
||||
Block device 253:0
|
||||
```
|
||||
|
||||
查看根文件系统(`/`)的大小,并将它与逻辑卷大小进行比较。
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 19G 1.4G 17G 8% /
|
||||
```
|
||||
|
||||
逻辑卷和文件系统大小都为 19G。让我们给根逻辑卷(`root`)增加 5G。
|
||||
|
||||
```
|
||||
$ sudo lvresize -L +5G fedora_fedora/root
|
||||
Size of logical volume fedora_fedora/root changed from 19.00 GiB (4863 extents) to 24.00 GiB (6143 extents).
|
||||
Logical volume fedora_fedora/root successfully resized.
|
||||
```
|
||||
|
||||
我们现在有 24G 的逻辑卷可用。看看根文件系统(`/`)。
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 19G 1.4G 17G 8% /
|
||||
```
|
||||
|
||||
我们仍然显示只有 19G 的空闲空间,这是因为逻辑卷与文件系统不一样。要使用增加到逻辑卷的新空间,请调整文件系统的大小。
|
||||
|
||||
```
|
||||
$ sudo resize2fs /dev/fedora_fedora/root
|
||||
resize2fs 1.45.6 (20-Mar-2020)
|
||||
Filesystem at /dev/fedora_fedora/root is mounted on /; on-line resizing required
|
||||
old_desc_blocks = 3, new_desc_blocks = 3
|
||||
The filesystem on /dev/fedora_fedora/root is now 6290432 (4k) blocks long.
|
||||
```
|
||||
|
||||
看看文件系统的大小。
|
||||
|
||||
```
|
||||
$ df -h /
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/fedora_fedora-root 24G 1.4G 21G 7% /
|
||||
```
|
||||
|
||||
正如你所看到的,根文件系统(`/`)已经占用了逻辑卷上的所有可用空间,而且不需要重新启动。
|
||||
|
||||
现在你已经将一个磁盘初始化为物理卷,并使用新的物理卷扩展了卷组。之后,你增加了逻辑卷的大小,并调整了文件系统的大小,以使用逻辑卷的新空间。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/add-storage-to-your-fedora-system-with-lvm/
|
||||
|
||||
作者:[Tim Bosse][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/maztaim/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/11/lvm-add-disk-816x345.jpg
|
||||
[2]: https://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)
|
||||
[3]: https://fedoramagazine.org/howto-use-sudo/
|
@ -0,0 +1,123 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12962-1.html)
|
||||
[#]: subject: (Learn Bash by writing an interactive game)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-bash)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
|
||||
通过编写互动游戏学习 Bash
|
||||
======
|
||||
|
||||
> 编程一个简单的游戏是练习一门新语言并与其他你掌握的语言进行比较的好方法。
|
||||
|
||||

|
||||
|
||||
学习一门新的编程语言是很有趣的。每当我尝试学习一门新的语言时,我都会专注于定义变量、编写语句和评估表达式。一旦我对这些概念有了大致的了解,我通常可以自己弄清楚其余的概念。大多数编程语言都有一些相似之处,所以一旦你了解了一种编程语言,学习下一种编程语言就是要弄清楚其独特的细节,认识到其中的差异。
|
||||
|
||||
为了帮助我练习一种新的编程语言,我喜欢写一些测试程序。我经常写的一个示例程序是一个简单的“猜数字”程序,电脑在 1 到 100 之间选一个数字,让我猜这个数字。程序会一直循环,直到我猜对为止。
|
||||
|
||||
“猜数字”程序锻炼了编程语言中的几个概念:如何给变量赋值,如何写语句,如何进行条件判断和循环。对于学习一门新的编程语言来说,这是一个很好的实践实验。
|
||||
|
||||
### 用 Bash 猜数字
|
||||
|
||||
[Bash][2] 是大多数 Linux 系统的标准 shell。除了提供丰富的命令行用户界面外,Bash 还以*脚本*的形式支持完整的编程语言。
|
||||
|
||||
如果你对 Bash 不熟悉,我推荐你看这些介绍:
|
||||
|
||||
* [什么是 Bash?][3]。
|
||||
* [开始使用 Bash 编程][4]
|
||||
* [系统管理员的 Bash 脚本入门][5]
|
||||
* [如何在 Bash 中编写函数][6]
|
||||
* [阅读更多关于 Bash 的信息][7]
|
||||
|
||||
你可以通过编写一个 Bash 版本的“猜数字”游戏来探索它。这是我的实现:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
number=$(( $RANDOM % 100 + 1 ))
|
||||
|
||||
echo "Guess a number between 1 and 100"
|
||||
|
||||
guess=0
|
||||
|
||||
while [ "0$guess" -ne $number ] ; do
|
||||
read guess
|
||||
[ "0$guess" -lt $number ] && echo "Too low"
|
||||
[ "0$guess" -gt $number ] && echo "Too high"
|
||||
done
|
||||
|
||||
echo "That's right!"
|
||||
exit 0
|
||||
```
|
||||
|
||||
### 拆解这个脚本
|
||||
|
||||
脚本中的第一行,`#!/bin/bash` 告诉 Linux 使用 Bash shell 来运行这个脚本。每个脚本都以 `#!` 字符对(LCTT 译注:释伴)开始,这表示它是一个 shell 脚本。紧跟在`#!` 后面的是要运行的 shell。在本例中,`/bin/bash` 是指 Bash shell。
|
||||
|
||||
要给一个变量赋值,在变量名后面列出 `=` 号。例如,语句 `guess=0` 给 `guess` 变量分配一个零值。
|
||||
|
||||
你也可以使用 `read` 语句提示用户输入一个值。如果你写了 `read guess` 语句,Bash 会等待用户输入一些文本,然后把这个值存储在 `guess` 变量中。
|
||||
|
||||
要引用一个变量的值,在变量名前使用 `$`。所以, 在 `guess` 变量中存储了一个值后, 你可以使用 `$guess` 来检索它。
|
||||
|
||||
你可以使用任何你喜欢的变量名称,但是 Bash 为自己保留了一些特殊的变量名称。一个特殊的变量是 `RANDOM`,每次引用它都会产生一个很大的随机数。
|
||||
|
||||
如果你想在存储一个值的同时执行一个操作,你需要用特殊的括号把语句括起来。这将告诉 Bash 先执行该语句,而 `=` 则将结果值存储在变量中。要评估一个数学表达式,使用 `$(())` 围在你的语句上。双括号表示一个*算术表达式*。在我的例子中,`number=$(( $RANDOM % 100 + 1 ))` 评估表达式 `$RANDOM % 100 + 1`,然后将值存储在 `number` 变量中。
|
||||
|
||||
标准的算术运算符,如 `+`(加)、`-`(减)、`*`(乘)、`/`(除)和 `%`(模)都适用。
|
||||
|
||||
这意味着语句 `number=$(( $RANDOM % 100 + 1 ))` 产生一个 1 到 100 之间的随机数。模数运算符(`%`)返回两个数相除后的余数。在这种情况下,Bash 将一个随机数除以 100,剩下的余数范围是 0 到 99,通过在这个值上加 1,你可以得到一个介于 1 和 100 之间的随机数。
|
||||
|
||||
Bash 支持像循环这样的*条件表达式*和*流程控制*。在“猜数字”的游戏中,只要 `guess` 中的值不等于 `number`,Bash 就会继续循环。如果猜的数小于随机数,Bash 就会打印“太低”,如果猜的数大于数字,Bash 就会打印“太高”。
|
||||
|
||||
### 它是如何工作的
|
||||
|
||||
现在你已经写好了你的 Bash 脚本,你可以运行它来玩“猜数字”游戏。一直猜,直到你找到正确的数字:
|
||||
|
||||
```
|
||||
Guess a number between 1 and 100
|
||||
50
|
||||
Too high
|
||||
30
|
||||
Too high
|
||||
20
|
||||
Too high
|
||||
10
|
||||
Too low
|
||||
15
|
||||
Too high
|
||||
13
|
||||
Too low
|
||||
14
|
||||
That's right!
|
||||
```
|
||||
|
||||
每次运行这个脚本,Bash 都会随机选择一个不同的数字。
|
||||
|
||||
这个“猜数字”游戏是学习新的编程语言时的一个很好的入门程序,因为它以一种很直接的方式锻炼了几个常见的编程概念。通过在不同的编程语言中实现这个简单的游戏,你可以展示一些核心概念,并比较每种语言的细节。
|
||||
|
||||
你有喜欢的编程语言吗?你会如何用它来写“猜数字”游戏呢?请关注本系列文章,看看你可能感兴趣的其他编程语言的例子。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-bash
|
||||
|
||||
作者:[Jim Hall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jim-hall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bash_command_line.png?itok=k4z94W2U (bash logo on green background)
|
||||
[2]: https://en.wikipedia.org/wiki/Bash_(Unix_shell)
|
||||
[3]: https://opensource.com/resources/what-bash
|
||||
[4]: https://opensource.com/article/20/4/bash-programming-guide
|
||||
[5]: https://opensource.com/article/20/4/bash-sysadmins-ebook
|
||||
[6]: https://opensource.com/article/20/6/bash-functions
|
||||
[7]: https://opensource.com/tags/bash
|
@ -1,20 +1,22 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12938-1.html)
|
||||
[#]: subject: (Make medit your next Linux terminal text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/medit)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
让 medit 成为你的下一个 Linux 终端文本编辑器
|
||||
让 medit 成为你的下一个 Linux 代码编辑器
|
||||
======
|
||||
这款经典的文本编辑器提供了所有的基本功能和一些让你自定义你的体验的令人兴奋的功能。
|
||||
![Person drinking a hot drink at the computer][1]
|
||||
|
||||
这里有 [XEDIT][2]、jEdit、NEdit、[gedit][3],最后还有 [medit][4]。
|
||||
> 这款经典的文本编辑器提供了所有的基本功能和一些让你自定义你的体验的令人兴奋的功能。
|
||||
|
||||
在我开始搜索我还没有尝试过的编辑器之前,我还没有听说过 medit,但我很高兴发现了它。如果你正在寻找经典的 gedit 体验(大约是 Gnome 2),那么 medit 可能无意间是一种出色且现代的近似。它也有许多额外的功能,比如可以用 Python、Lua 或 C 语言编写插件,以及将 shell 脚本集成到菜单系统。所有其他常用的功能也都在这里:标签式界面、一个按需的 shell、缩进管理、语法高亮等等。
|
||||

|
||||
|
||||
有了 [XEDIT][2]、jEdit、NEdit、[gedit][3],最后还有 [medit][4]。
|
||||
|
||||
在我开始搜索我还没有尝试过的编辑器之前,我还没有听说过 medit,但我很高兴发现了它。如果你正在寻找经典的 gedit 体验(大约是 Gnome 2 上),那么 medit 可能无意间提供了一种出色且现代的近似体验。它也有许多额外的功能,比如可以使用 Python、Lua 或 C 语言编写插件,以及甚至可以将 shell 脚本集成到菜单系统。所有其他常用的功能也都在这里:标签式界面、一个即时的 shell、缩进管理、语法高亮等等。
|
||||
|
||||
### 安装 medit
|
||||
|
||||
@ -24,25 +26,25 @@
|
||||
|
||||
### 使用 medit
|
||||
|
||||
medit 标称自己是一个“为编程和围绕编程”的编辑器,事实上,它是作为一个名为 [GAP(Groups、Algorithms、Programming)][8] 的更大项目的一部分开始的。它的大部分功能都是针对典型的开发者期望的。例如,在 **Edit**菜单中,有增加和减少缩进的选项,这对于任何试图以视觉方式指示范围的程序员来说都是一个常见的任务 (对于 Python 程序员来说也是一个字面要求),还有注释或取消注释文本块的选项。
|
||||
medit 宣称自己是一个“为编程和围绕编程”打造的编辑器,事实上,它的诞生是作为一个名为 GAP(<ruby>[群组、算法、编程][8]<rt>Groups、Algorithms、Programming</rt></ruby>)的更大项目的一部分。它的大部分功能都是针对典型的开发者的期望而开发。例如,在 **Edit** 菜单中,有增加和减少缩进的选项,这对于任何试图以可视方式指示范围的程序员来说都是一个常见的任务(对于 Python 程序员来说也是一个明文要求),还有注释或取消注释文本块的选项。
|
||||
|
||||
有些功能对普通用户也很有用。medit 有一个易于使用的标签式界面 (既在窗口顶部,也在侧面的弹出式列表中),一个用于快速浏览文件系统的侧板,在文件中添加书签的功能等等。它还具有针对两种编程语言以及标记和 markdown 语言的语法高亮显示功能,因此它是代码和散文的有用编辑器。
|
||||
有些功能对普通用户也很有用。medit 有一个易于使用的标签式界面(既在窗口顶部,也在侧面的弹出式列表中),一个用于快速浏览文件系统的侧面板,在文件中添加书签的功能等等。它还具有针对两种编程语言以及标记语言和 Markdown 的语法高亮显示功能,因此它是可以用于编辑代码和普通文本的编辑器。
|
||||
|
||||
### 颜色方案
|
||||
|
||||
当编辑没有语法关联的纯文本或像 Asciidoc 这样的格式时,medit 没有预设的高亮方案,编辑器会采用你的系统默认值。我使用的是黑暗主题,所以 medit 在深灰色背景上显示白色文本。
|
||||
当编辑没有语法关联的纯文本或像 Asciidoc 这样的格式时,medit 没有预设的高亮方案,编辑器会采用你的系统默认值。我使用的是深色主题,所以 medit 在深灰色背景上显示白色文本。
|
||||
|
||||
不过对于语法高亮,文本会根据每个单词在其结构化语言中扮演的角色而变成彩色。一开始,我对 medit 的一些选择有些失望,很多颜色在我的深色背景下太暗,无法辨认,而且我觉得所有重要的元素都不够独特。如果你不同意 medit 的选择,这个问题的答案在 **Preferences** 中,你可以更改颜色主题。我把我的颜色改成了 Tango,它呈现出一个日光照射的颜色阵列,在我的深色编辑器背景下非常突出,甚至给在 medit 主题下保持白色的元素添加了颜色。
|
||||
不过对于语法高亮,文本会根据每个单词在其结构化语言中扮演的角色而变成彩色。一开始,我对 medit 的一些选择有些沮丧,很多颜色在我的深色背景下太暗,无法辨认,而且我觉得所有重要的元素都不够显眼。如果你不喜欢 medit 选择的方案,这个问题的答案在 **Preferences** 中,你可以更改颜色主题。我把我的颜色改成了 Tango,它呈现出一个日光照射的颜色阵列,在我的深色编辑器背景下非常出色,甚至给在 medit 主题下保持白色的元素添加了颜色。
|
||||
|
||||
![Medit terminal showing examples of Bash script in editor using Tango color scheme against dark background][9]
|
||||
|
||||
### 弹出式 Python
|
||||
### 弹出式 Python 控制台
|
||||
|
||||
在 medit 窗口的底部,有一个弹出的终端,用于快速访问 shell。这是一个很好的功能,但坦率地说,在你体验过 Emacs 和 [Kate][10]之后,这感觉很普通。medit 让我惊讶的是它的弹出式 Python 控制台,它从 **Tools** 菜单中启动,并预先导入了 **moo** 和 **gtk** 模块。换句话说,当你启动 medit 的 Python shell 时,你可以查看 medit 自身部分构建的 Python 和 GTK 模块。这是一个很好的功能,也许会给你写插件的灵感(终端弹出的是一个用 Python 编写的插件,所以你也可以通过它的代码来了解一个插件是如何编写的)。
|
||||
在 medit 窗口的底部,有一个弹出的终端,用于快速访问 shell。这是一个很好的功能,但坦率地说,在你体验过 Emacs 和 [Kate][10]之后,这感觉很普通。medit 让我惊讶的是它的弹出式 Python 控制台,它从 **Tools** 菜单中启动,并预先导入了 **moo** 和 **gtk** 模块。换句话说,当你启动 medit 的 Python shell 时,你可以查看 medit 构建自身部分的 Python 和 GTK 模块。这是一个很好的功能,也许会给你写插件的灵感(这个弹出终端的是一个用 Python 编写的插件,所以你也可以通过它的代码来了解一个插件是如何编写的)。
|
||||
|
||||
### 经典编辑
|
||||
|
||||
medit 是一个出色的基于 GTK 的编辑器,它具有所有重要的基本功能和一些诱人的额外功能,可以帮助你扩展应用并使其成为你自己的。因为它接受 C、Python、Lua 和 Bash,所以有几个切入点可以做到这一点。如果你正在为你的写作寻找一个有用的编辑器,无论是代码还是 markdown 或介于两者之间的东西,给 medit 一个机会。
|
||||
medit 是一款出色的基于 GTK 的编辑器,它具有所有重要的基本功能和一些诱人的额外功能,可以帮助你扩展应用并使其成为你自己的。因为它接受 C、Python、Lua 和 Bash,所以你可以将它用于这几种用途。如果你正在为你的写作寻找一个有用的编辑器,无论是代码还是 Markdown 或介于两者之间的东西,给 medit 一个机会。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -51,15 +53,15 @@ via: https://opensource.com/article/20/12/medit
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://opensource.com/article/20/12/xedit
|
||||
[3]: https://opensource.com/article/20/12/gedit
|
||||
[2]: https://linux.cn/article-12930-1.html
|
||||
[3]: https://linux.cn/article-12933-1.html
|
||||
[4]: http://mooedit.sourceforge.net/
|
||||
[5]: https://sourceforge.net/projects/mooedit/files/medit/
|
||||
[6]: https://slackbuilds.org/repository/14.2/development/medit
|
@ -1,20 +1,22 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12942-1.html)
|
||||
[#]: subject: (Why Java developers love the jEdit text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/jedit)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
为什么 Java 开发者喜欢 jEdit 文本编辑器
|
||||
======
|
||||
这款编辑器打包了 Java 的功能,并提供了大量的插件来简化你的工作流程。
|
||||
![Person drinking a hot drink at the computer][1]
|
||||
|
||||
Java 是一门强大的语言。也许因为它经常被看作是一种“工业级”的工具,你可能不会想到它会成为文本编辑器的基础。毕竟,对于如此能力,文本编辑几乎是太容易了。事实上,在大多数现代编程工具包中,接受文本输入的组件是一个预编程的小部件。使用 Java 工具箱,一个简单的文本编辑器可以在 100 行左右的代码中编写出来。那么 [jEdit][2] 能提供什么来证明它的存在呢?
|
||||
> 这款编辑器打包了 Java 的功能,并提供了大量的插件来简化你的工作流程。
|
||||
|
||||
嗯,实际上,它有很多功能!jEdit 应用是一个令人耳目一新的提醒,提醒人们 Java 对于日常桌面应用是多么的实用和有用。它巧妙地展示了它的基础技术的活力,并且永远忠于 Java 的持久承诺,在_所有_的平台上都能使用。
|
||||

|
||||
|
||||
Java 是一门强大的语言。也许因为它经常被看作是一种“工业级”的工具,你可能不会想到它会成为文本编辑器的基础。毕竟,对于如此能力,文本编辑几乎是太容易了。事实上,在大多数现代编程工具包中,接受文本输入的组件是一个预编程的小部件。使用 Java 工具箱,一个简单的文本编辑器可以用 100 行左右的代码编写出来。那么 [jEdit][2] 能提供什么来证明它的存在价值呢?
|
||||
|
||||
嗯,实际上,它有很多功能!jEdit 应用是一个令人耳目一新的提醒,提醒人们 Java 对于日常桌面应用是多么的实用和有用。它巧妙地展示了它的基础技术的活力,并且永远忠于 Java 的永恒承诺,在*所有*的平台上都能运作。
|
||||
|
||||
### 安装 jEdit
|
||||
|
||||
@ -24,9 +26,9 @@ jEdit 是用 Java 编写的,所以它适用于任何平台。[下载][3]通用
|
||||
|
||||
### 使用 jEdit
|
||||
|
||||
在 jEdit 中编辑文本的方式和在任何桌面文本编辑器中编辑文本的方式是一样的。如果你使用过一个编辑器,那么你基本上已经使用了 jEdit。所有常用的键盘快捷键和惯例都适用。也有一些通常针对编码者的功能,如行号、折叠(文本的部分被隐藏,这样你就可以把注意力放在其他部分)和语法高亮。
|
||||
在 jEdit 中编辑文本的方式和在任何桌面文本编辑器中编辑文本的方式是一样的。如果你使用过编辑器,那么你基本上已经会使用 jEdit 了。所有常用的键盘快捷键和惯例都适用。也有一些通常针对开发者的功能,如行号、折叠(该部分文本被隐藏,这样你就可以把注意力放在其他部分)和语法高亮。
|
||||
|
||||
但是,想象一下,从 [Vim 的简单性][6]到 [Emacs 的复杂性][7]的文本编辑器,你会发现 jEdit 与 Emacs 类似。虽然编辑组件和任何典型桌面编辑应用一样,但 jEdit 的附加功能包括插件、可以在编辑会话中实时录制的宏、特定编辑模式的功能、缓冲区选项等。这是一个积极鼓励你把它变成你自己的编辑器。
|
||||
但是,想象一下,从 [简单的 Vim][6] 到 [复杂的 Emacs][7]的各种文本编辑器中,你会发现 jEdit 与 Emacs 类似。虽然编辑组件和任何典型桌面编辑应用一样,但 jEdit 的附加功能包括插件、可以在编辑会话中实时录制的宏、特定于某些编辑模式的功能、缓冲区选项等。这是一个积极鼓励你把它变成你自己的编辑器。
|
||||
|
||||
你可以在三个地方对 jEdit 进行自定义:缓冲区选项、全局选项和插件管理器。
|
||||
|
||||
@ -34,15 +36,15 @@ jEdit 是用 Java 编写的,所以它适用于任何平台。[下载][3]通用
|
||||
|
||||
全局选项(在 “Utilities” 菜单中)提供了数十种首选项,这些首选项被视为 jEdit 的默认值。这包括从外观到自定义快捷方式的所有内容。
|
||||
|
||||
插件扩展了 jEdit 的功能,实际上,它的开发者从未想过要这样。插件提供的工作方式对 jEdit 而言并非“正常”,但可能会将繁琐的任务转变为简单甚至有趣的事情。它以其出色的 XML 解析、可停靠 _Sidekick_ 面板中的 _Outline_ 插件和 XSLT 集成,实际上改变了 XML 工作流程。如果我还没有使用 Netbeans 来编写 Java 代码,我可以想象使用 jEdit 来代替。
|
||||
插件可以扩展出来 jEdit 的开发者从未想过的功能。插件提供的工作方式对 jEdit 而言并非“常规”,但可能会将繁琐的任务转变为简单甚至有趣的事情。它以其出色的 XML 解析、可停靠的 Sidekick 面板中的 Outline 插件和 XSLT 集成,实际上改变了 XML 工作流程。如果我不是已经使用了 Netbeans 来编写 Java 代码,我想我可以使用 jEdit 来代替。
|
||||
|
||||
### 面向程序员的 jEdit
|
||||
|
||||
选择哪种文本编辑器取决于你打算在编辑器中做的事。它称自己为“程序员的文本编辑器”,并且我认为它是认真的 Java 和 XML 工作的有力竞争者。但是,在编辑 Lua 代码和 Bash 脚本时,它的功能不尽相同。例如,与 Emacs 之类相比,jEdit 的代码折叠不那么灵活(我无法在没有附加标记的情况下折叠 Lua 函数)。尽管确实有丰富的插件选择,但我找不到能在 AsciiDoc 和其他非代码格式下工作的特别有说服力的东西。
|
||||
选择哪种文本编辑器取决于你打算在编辑器中做的事。它称自己为“程序员的文本编辑器”,并且我认为它是严肃的 Java 和 XML 开发的有力竞争者。但是,在编辑 Lua 代码和 Bash 脚本时,它的功能不就没有这么强了。例如,与 Emacs 之类相比,jEdit 的代码折叠不那么灵活(我无法在没有附加标记的情况下折叠 Lua 函数)。尽管确实有丰富的插件选择,但我找不到用于 AsciiDoc 和其他非代码格式工作的特别有说服力的东西。
|
||||
|
||||
对我来说,jEdit 最吸引人的特点是它是以 Java 为基础。因为它在 JVM 中运行,所以你可以有信心可以使用它,而无论你使用的平台是什么,也可以不管你是否有权限在自己的主目录之外安装应用。Java 是一种流行且活跃的语言,因此 jEdit 的功能和插件维护得很好。
|
||||
对我来说,jEdit 最吸引人的特点是它是以 Java 为基础。因为它在 JVM 中运行,所以你可以确信能够使用它,而无论你使用的平台是什么,也可以不管你是否有权限在自己的主目录之外安装应用。Java 是一种流行且活跃的语言,因此 jEdit 的功能和插件维护得很好。
|
||||
|
||||
如果你是一贯的忠实拥护者、Java 开发人员,或者只是 XML 极客而拼命试图摆脱 oXygen,那么你应该试试 jEdit。它很容易上手,并且探索起来很有趣。
|
||||
如果你是一致性的忠实拥护者、Java 开发人员,或者只是 XML 极客而拼命试图摆脱 oXygen,那么你应该试试 jEdit。它很容易上手,并且探索起来很有趣。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -51,7 +53,7 @@ via: https://opensource.com/article/20/12/jedit
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -60,7 +62,7 @@ via: https://opensource.com/article/20/12/jedit
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: http://jedit.org
|
||||
[3]: http://www.jedit.org/index.php?page=download
|
||||
[4]: https://opensource.com/article/19/11/install-java-linux
|
||||
[4]: https://linux.cn/article-11614-1.html
|
||||
[5]: http://adoptopenjdk.org
|
||||
[6]: https://opensource.com/article/20/12/vi-text-editor
|
||||
[7]: https://opensource.com/article/20/12/emacs
|
||||
[7]: https://linux.cn/article-12923-1.html
|
@ -1,44 +1,44 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12952-1.html)
|
||||
[#]: subject: (What web developers love about the Brackets text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/brackets)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Web 开发人员喜欢 Brackets 文本编辑器的原因
|
||||
======
|
||||
这个编辑器是面向 Web 开发人员的,它支持多种编程语言,并提供了大量的扩展,使其成为你自己的编辑器。
|
||||
![Text editor on a browser, in blue][1]
|
||||
|
||||
> 这个基础的编辑器是面向 Web 开发人员的,它支持多种编程语言,并提供了大量的扩展,使其成为你自己的编辑器。
|
||||
|
||||

|
||||
|
||||
Brackets 文本编辑器是主要面向 Web 开发人员的编辑器。恰如其分的是,它的“编辑”菜单中充满了对 Web 编程语言用户特别有用的功能,主要是 HTML、CSS 和 Javascript 的经典组合。
|
||||
|
||||
但是,它还支持许多与互联网相关的语言和格式,包括 XML、Markdown、YAML 和 JSON、PHP、Lua、Java 和 Python,以及一些常见的通用语言,例如 C、C ++,甚至是 `diff` 命令的输出。
|
||||
但是,它还支持许多与互联网相关的语言和格式,包括 XML、Markdown、YAML 和 JSON、PHP、Lua、Java 和 Python,以及一些常见的通用语言,例如 C、C++,甚至是 `diff` 命令的输出。
|
||||
|
||||
### 安装 Brackets
|
||||
|
||||
Brackets 可以从 [Brackets 网站][2]安装到 Linux、Windows 和 macOS上。
|
||||
Brackets 可以从 [Brackets 网站][2]安装到 Linux、Windows 和 macOS 上。
|
||||
|
||||
另外,在 Linux 上,你可以从 [flathub.org][3] 将其作为 Flatpak 安装。
|
||||
另外,在 Linux 上,你可以从 [flathub.org][3] 以 Flatpak 安装。
|
||||
|
||||
![Brackets editor][4]
|
||||
|
||||
### 使用 Brackets
|
||||
|
||||
在大多数时候,Brackets 是一个“普通”的文本编辑器,其功能类似于 jEdit 或 Medit。有语法高亮、可配置的 tab 间距、字符编码设置等等。这些都可以在窗口底部的状态栏中找到。
|
||||
在大多数时候,Brackets 是一个“普通”的文本编辑器,其功能类似于 [jEdit][5] 或 [Medit][6]。有语法高亮、可配置的制表符间距、字符编码设置等等。这些都可以在窗口底部的状态栏中找到。
|
||||
|
||||
在“视图”菜单中,有主题设置、行号、自动换行,甚至还有分割窗口的选项,这样你可以在一个窗口中看到两个文件。
|
||||
|
||||
然而,在“编辑”菜单中,有一些编程的特殊功能。以下是我最喜欢的一些功能:
|
||||
|
||||
* 使用 **Ctrl+[** 或 **Ctrl+]** 键盘快捷键来缩进和取消缩进文本块,这不仅对保持 HTML、CSS 和 Javascript 的整洁很有用,而且对 Python 代码也很重要。
|
||||
* 用 **Ctrl+/** 把一行变成注释。Brackets 标记注释的方式取决于你所使用的语言,所以无论你的文档是否使用斜线、破折号、箭头、井号或其他任何类型注释,这个功能都可以使用。
|
||||
* 用 **Shift+Ctrl+Up** 或 **Shift+Ctrl+Down** 在文档中向上或向下移动一行。
|
||||
* 用 **Shift+Ctrl+D** 删除整行。
|
||||
* 用 **Ctrl+D** 复制一行。
|
||||
|
||||
然而,在“编辑”菜单中,有一些的特别用于编程的功能。以下是我最喜欢的一些功能:
|
||||
|
||||
* 使用 `Ctrl+[` 或 `Ctrl+]` 键盘快捷键来缩进和取消缩进文本块,这不仅对保持 HTML、CSS 和 Javascript 的整洁很有用,而且对 Python 代码也很重要。
|
||||
* 用 `Ctrl+/` 把一行变成注释。Brackets 标记注释的方式取决于你所使用的语言,所以无论你的文档是否使用斜线、破折号、箭头、井号或其他任何类型注释,这个功能都可以使用。
|
||||
* 用 `Shift+Ctrl+Up` 或 `Shift+Ctrl+Down` 在文档中将一行向上或向下移动。
|
||||
* 用 `Shift+Ctrl+D` 删除整个一行。
|
||||
* 用 `Ctrl+D` 复制整个一行。
|
||||
|
||||
这些都是看似小众的功能,你可能认为不会经常使用,但一旦你拥有了它们,你就会对它们产生依赖。
|
||||
|
||||
@ -59,7 +59,7 @@ via: https://opensource.com/article/20/12/brackets
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -69,3 +69,5 @@ via: https://opensource.com/article/20/12/brackets
|
||||
[2]: http://brackets.io/
|
||||
[3]: https://flathub.org/apps/details/io.brackets.Brackets
|
||||
[4]: https://opensource.com/sites/default/files/screenshot_2020-12-02_at_16.26.58.png (Brackets editor)
|
||||
[5]: https://linux.cn/article-12942-1.html
|
||||
[6]: https://linux.cn/article-12938-1.html
|
300
published/202012/20201214 Set up an Ansible lab in 20 minutes.md
Normal file
300
published/202012/20201214 Set up an Ansible lab in 20 minutes.md
Normal file
@ -0,0 +1,300 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12970-1.html)
|
||||
[#]: subject: (Set up an Ansible lab in 20 minutes)
|
||||
[#]: via: (https://opensource.com/article/20/12/ansible-lab)
|
||||
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
|
||||
|
||||
20 分钟建立一个 Ansible 实验室
|
||||
======
|
||||
|
||||
> 建立一个支持学习和实验新软件的环境。
|
||||
|
||||

|
||||
|
||||
能够构建和拆解公有云环境是非常有用的,但我们大多数人都不能轻松访问公有云。退而求其次的最好办法就是在本地机器上建立一个实验室,但即使在本地机器上运行也会带来性能、灵活性和其他挑战。大多数时候,本地机器上额外的工作负载会干扰我们日常的工作,它们当然也会影响你提供一个现成的环境来玩耍和实验新软件。
|
||||
|
||||
几年前,当我和我的团队开始学习 [Ansible][2] 时,我们就遇到了这个挑战。我们找不到一个可以单独使用的环境,我们对这种情况的失望导致我们中的一些人停止了实验。我们知道需要找到一个解决方案。
|
||||
|
||||
我们花了很多时间研究各种方案,得出了一套工具,使我们的好奇心能够在我们完全控制的环境中学习。我们可以在本地机器上轮换和拆解实验室环境,而不需要访问内部实验室或公共云。
|
||||
|
||||
本文将解释如何在 20 分钟内以完全自动化的方式在本地机器上部署自己的实验室环境。
|
||||
|
||||
你可以在我的 [GitHub 仓库][3]中找到这个练习的所有代码。
|
||||
|
||||
### 工具和软件
|
||||
|
||||
本方案使用以下工具和软件:
|
||||
|
||||
* [Ansible][4] 是我们选择的自动化工具,因为它易于使用,而且足够灵活,可以满足实验室的要求。
|
||||
* [Vagrant][5] 易于使用,用于构建和维护虚拟机。
|
||||
* [VirtualBox][6] 是一个托管管理程序,可以在 Windows 和 Linux 环境中使用。
|
||||
* [Fedora v30+][7] 是我本地机器上的操作系统。
|
||||
|
||||
你必须进行以下设置才能建立环境:
|
||||
|
||||
* 一个互联网连接
|
||||
* 在 BIOS 中启用虚拟化技术支持(以下是在我的联想笔记本上的[过程][8])
|
||||
* Vagrant v2.2.9
|
||||
* 最新版本的 Ansible
|
||||
* 最新版本的 VirtualBox
|
||||
* Fedora v30+ 宿主机操作系统
|
||||
|
||||
### 这个实验室环境有什么?
|
||||
|
||||
这个项目旨在部署一个带有 Ansible 引擎和多个 Linux 节点的 Ansible 主机,以及一些预加载和预配置的应用程序(httpd 和 MySQL)。它还启用了 [Cockpit][9],这样你就可以在测试过程中监控虚拟机(VM)的状态。使用预部署的应用程序的原因是为了提高效率(所以你不必花时间安装这些组件)。这样你就可以专注于创建角色和剧本,并针对上述工具部署的环境进行测试。
|
||||
|
||||
我们确定,对于我们的用例来说,最好的方案是多机 Vagrant 环境。Vagrant 文件创建了三个 CentOS 虚拟机,以模拟两个目标主机和一个 Ansible 控制机。
|
||||
|
||||
* Host1: 没有图形用户界面(GUI),安装 httpd 和 MySQL
|
||||
* Host2: 没有 GUI,安装了 httpd 和 MySQL
|
||||
* Ansible-host:没有 GUI,安装了 Ansible 引擎
|
||||
|
||||
### 启用多个管理程序
|
||||
|
||||
如果使用了多个管理程序,一些管理程序可能不允许你拉起虚拟机。要解决这个问题,请遵循以下步骤(基于 Vagrant 的[安装][10]说明)。
|
||||
|
||||
首先,找出管理程序的名称:
|
||||
|
||||
```
|
||||
$ lsmod | grep kvm
|
||||
kvm_intel 204800 6
|
||||
kvm 593920 1 kvm_intel
|
||||
irqbypass 16384 1 kvm
|
||||
```
|
||||
|
||||
我感兴趣的是 `kvm_intel`,但你可能需要另一个(比如 `kvm_amd`)。
|
||||
|
||||
以 root 身份运行以下内容,将该管理程序列入黑名单:
|
||||
|
||||
```
|
||||
$ echo 'blacklist kvm-intel' >> /etc/modprobe.d/blacklist.conf
|
||||
```
|
||||
|
||||
重新启动你的机器并尝试再次运行 Vagrant。
|
||||
|
||||
### Vagrant 文件
|
||||
|
||||
```
|
||||
cat Vagrantfile
|
||||
```
|
||||
|
||||
```
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
# Define VMs with static private IP addresses, vcpu, memory and vagrant-box.
|
||||
boxes = [
|
||||
{
|
||||
:name => "web1.demo.com", ⇒ Host1 this is one of the target nodes
|
||||
:box => "centos/8", ⇒ OS version
|
||||
:ram => 1024, ⇒ Allocated memory
|
||||
:vcpu => 1, ⇒ Allocated CPU
|
||||
:ip => "192.168.29.2" ⇒ Allocated IP address of the node
|
||||
},
|
||||
{
|
||||
:name => "web2.demo.com", ⇒ Host2 this is one of the target nodes
|
||||
:box => "centos/8",
|
||||
:ram => 1024,
|
||||
:vcpu => 1,
|
||||
:ip => "192.168.29.3"
|
||||
},
|
||||
{
|
||||
:name => "ansible-host", ⇒ Ansible Host with Ansible Engine
|
||||
:box => "centos/8",
|
||||
:ram => 8048,
|
||||
:vcpu => 1,
|
||||
:ip => "192.168.29.4"
|
||||
}
|
||||
]
|
||||
|
||||
# Provision each of the VMs.
|
||||
boxes.each do |opts|
|
||||
config.vm.define opts[:name] do |config|
|
||||
# Only Enable this if you are connecting to Proxy server
|
||||
# config.proxy.http = "http://usernam:password@x.y:80"⇒ Needed if you have a proxy
|
||||
# config.proxy.https = "http://usernam:password@x.y:80"
|
||||
# config.proxy.no_proxy = "localhost,127.0.0.1"
|
||||
config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
|
||||
config.ssh.insert_key = false
|
||||
config.vm.box = opts[:box]
|
||||
config.vm.hostname = opts[:name]
|
||||
config.vm.provider :virtualbox do |v| ⇒ Defines the vagrant provider
|
||||
v.memory = opts[:ram]
|
||||
v.cpus = opts[:vcpu]
|
||||
end
|
||||
config.vm.network :private_network, ip: opts[:ip]
|
||||
config.vm.provision :file do |file|
|
||||
file.source = './keys/vagrant' ⇒ vagrant keys to allow access to the nodes
|
||||
file.destination = '/tmp/vagrant' ⇒ the location to copy the vagrant key
|
||||
end
|
||||
config.vm.provision :shell, path: "bootstrap-node.sh" ⇒ script that copy hosts entry
|
||||
config.vm.provision :ansible do |ansible| ⇒ declaration to run ansible playbook
|
||||
ansible.verbose = "v"
|
||||
ansible.playbook = "playbook.yml" ⇒ the playbook used to configure the hosts
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
这些是你需要注意的重要文件。
|
||||
|
||||
* `inventory-test.yaml`:连接到节点的清单文件
|
||||
* `playbook.yaml`:Vagrant 供应者调用的用于配置节点的剧本文件
|
||||
* `Vagrantfile':Vagrant 用来部署环境的文件
|
||||
* Vagrant 密钥文件:连接实验室环境中各节点的 Vagrant 密钥
|
||||
|
||||
你可以根据你的需要调整这些文件。Ansible 的灵活性使你有能力根据你的需要声明性地改变你的环境。
|
||||
|
||||
### 部署你的实验室环境
|
||||
|
||||
首先,克隆这个 [GitHub 仓库][11] 中的代码:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/mikecali/ansible-labs-101.git
|
||||
Cloning into 'ansible-labs-101'...
|
||||
remote: Enumerating objects: 15, done.
|
||||
remote: Counting objects: 100% (15/15), done.
|
||||
remote: Compressing objects: 100% (13/13), done.
|
||||
remote: Total 15 (delta 2), reused 10 (delta 0), pack-reused 0
|
||||
Unpacking objects: 100% (15/15), 6.82 KiB | 634.00 KiB/s, done.
|
||||
```
|
||||
|
||||
接下来,将你的目录改为 `vagrant-session-2`,并查看其内容:
|
||||
|
||||
```
|
||||
$ ls
|
||||
Bootstrap-node.sh inventory keys playbook.yml README.md Vagrantfile
|
||||
```
|
||||
|
||||
现在你已经拥有了实验室环境所需的所有工件和配置文件。要部署环境,请运行:
|
||||
|
||||
```
|
||||
$ vagrant up
|
||||
```
|
||||
|
||||
只要有一个像样的网络连接,只需要 20 分钟左右就可以得到一个运行环境:
|
||||
|
||||
```
|
||||
$ vagrant up
|
||||
Bringing machine 'web1.demo.com' up with 'virtualbox' provider...
|
||||
Bringing machine 'web2.demo.com' up with 'virtualbox' provider...
|
||||
Bringing machine 'ansible-host' up with 'virtualbox' provider...
|
||||
==> web1.demo.com: Importing base box 'centos/8'...
|
||||
==> web1.demo.com: Matching MAC address for NAT networking...
|
||||
==> web1.demo.com: Checking if box 'centos/8' version '1905.1' is up to date...
|
||||
==> web1.demo.com: Setting the name of the VM: ansible-labs_web1democom_1606434176593_70913
|
||||
==> web1.demo.com: Clearing any previously set network interfaces...
|
||||
==> web1.demo.com: Preparing network interfaces based on configuration...
|
||||
web1.demo.com: Adapter 1: nat
|
||||
web1.demo.com: Adapter 2: hostonly
|
||||
==> web1.demo.com: Forwarding ports...
|
||||
web1.demo.com: 22 (guest) => 2222 (host) (adapter 1)
|
||||
==> web1.demo.com: Running 'pre-boot' VM customizations...
|
||||
==> web1.demo.com: Booting VM...
|
||||
==> web1.demo.com: Waiting for machine to boot. This may take a few minutes...
|
||||
web1.demo.com: SSH address: 127.0.0.1:2222
|
||||
web1.demo.com: SSH username: vagrant
|
||||
web1.demo.com: SSH auth method: private key
|
||||
[...]
|
||||
```
|
||||
|
||||
一旦该剧本执行完成,你会看到这样的输出:
|
||||
|
||||
```
|
||||
PLAY RECAP *********************************
|
||||
Ansible-host : ok=20 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=3
|
||||
|
||||
Real 18m14.288s
|
||||
User 2m26.978s
|
||||
Sys 0m26.849s
|
||||
```
|
||||
|
||||
确认所有虚拟机都在运行:
|
||||
|
||||
```
|
||||
$ vagrant status
|
||||
Current machine states:
|
||||
|
||||
Web1.demo.com running (virtualbox)
|
||||
Web2.demo.com running (virtualbox)
|
||||
ansible-host running (virtualbox)
|
||||
[...]
|
||||
```
|
||||
|
||||
你可以通过登录其中一个虚拟机进一步调查。访问 `ansible-host`:
|
||||
|
||||
```
|
||||
> vagrant ssh ansible-host
|
||||
Activate the web console with: systemctl enable --now cockpit.socket
|
||||
|
||||
Last login: Thu Nov 26 12:21:23 2020 from 10.0.2.2
|
||||
[vagrant@ansible-host ~] uptime
|
||||
16:46:42 up 1:24, 1 user, load average: 0.00, 0.01, 0.04
|
||||
```
|
||||
|
||||
最后,你可以使用 Ansible 模块来 ping 你创建的其他节点:
|
||||
|
||||
```
|
||||
[vagrant@ansible-host]$ ansible -i inventory-test.yaml \
|
||||
webservers -m ping -u vagrant
|
||||
192.168.29.2 | SUCCESS => {
|
||||
"Ansible-facts": {
|
||||
"Discovered_interpreter_python": "/usr/libexec/platform-python"
|
||||
},
|
||||
"Changed": false;
|
||||
"Ping": "pong"
|
||||
}
|
||||
[...]
|
||||
```
|
||||
|
||||
### 清理
|
||||
|
||||
运行如下命令来清理环境:
|
||||
|
||||
```
|
||||
$ vagrant destroy [vagrant machine name]
|
||||
```
|
||||
|
||||
你的输出会像这样:
|
||||
|
||||
![Output from cleaning up environment][12]
|
||||
|
||||
### 有创意的学习
|
||||
|
||||
在自己的实验室里利用自己的时间学习 Ansible 这样的软件是一个好习惯,但由于受到无法控制的限制,可能会很困难。
|
||||
|
||||
有时候,你需要发挥创意,找到另一种方法。在开源社区中,你可以选择很多方案;我们选择这些工具的主要原因之一是,它们是许多人常用和熟悉的。
|
||||
|
||||
另外,请注意,这些剧本并没有按照我的要求进行优化。请随时改进它们,并在评论中分享你的工作。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/ansible-lab
|
||||
|
||||
作者:[Mike Calizo][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mcalizo
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/science_experiment_beaker_lab.png?itok=plKWRhlU (Science lab with beakers)
|
||||
[2]: https://opensource.com/resources/what-ansible
|
||||
[3]: https://github.com/mikecali/ansible-labs-101
|
||||
[4]: https://www.ansible.com/
|
||||
[5]: https://www.vagrantup.com/
|
||||
[6]: https://www.virtualbox.org/
|
||||
[7]: https://getfedora.org/
|
||||
[8]: https://support.lenovo.com/pt/en/solutions/ht500006
|
||||
[9]: https://opensource.com/article/20/11/cockpit-server-management
|
||||
[10]: https://www.vagrantup.com/docs/installation
|
||||
[11]: https://github.com/mikecali/ansible-labs-101.git
|
||||
[12]: https://opensource.com/sites/default/files/uploads/cleanup.png (Output from cleaning up environment)
|
||||
[13]: https://creativecommons.org/licenses/by-sa/4.0/
|
@ -0,0 +1,167 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12959-1.html)
|
||||
[#]: subject: (9 things to do in your first 10 minutes on a Linux server)
|
||||
[#]: via: (https://opensource.com/article/20/12/linux-server)
|
||||
[#]: author: (Gaurav Kamathe https://opensource.com/users/gkamathe)
|
||||
|
||||
初次登录 Linux 服务器马上要做的 9 件事
|
||||
======
|
||||
|
||||
> 在将新配置的服务器投入工作之前,请确保你知道你正在使用什么。
|
||||
|
||||

|
||||
|
||||
当我在 Linux 上测试软件时(这是我工作中的一个常规部分),我需要使用多台运行 Linux 的不同架构的服务器。我整备机器,安装所需的软件包,运行我的测试,收集结果,并将机器返回到仓库中,以便其他人可以使用它进行测试。
|
||||
|
||||
由于我经常这样做(甚至一天多次),我初次登录 Linux 服务器的前 10 分钟内的工作已经成为每天的仪式。当我初次登录 Linux 服务器时,我会使用命令来收集我需要的信息来寻找某些东西。我将在本文中介绍我的过程,但请注意,在大多数情况下,我只给出命令名称,所以你需要确定这些命令的具体选项,以获得你需要的信息。阅读命令的手册页是一个很好的起点。
|
||||
|
||||
### 1、第一次接触
|
||||
|
||||
当我登录到一台服务器时,我做的第一件事就是检查它是否拥有我将要运行的测试所需的操作系统、内核和硬件架构。我经常会检查一台服务器已经运行了多久。虽然这对测试系统来说并不重要,因为它会被多次重启,但我还是发现这些信息很有帮助。
|
||||
|
||||
使用下面的命令来获取这些信息。我主要使用 Red Hat Linux 进行测试,所以如果你使用其他 Linux 发行版,请在文件名中使用 `*-release` 而不是 `redhat-release`:
|
||||
|
||||
```
|
||||
cat /etc/redhat-release
|
||||
uname -a
|
||||
hostnamectl
|
||||
uptime
|
||||
```
|
||||
|
||||
### 2、有人登录在上面吗?
|
||||
|
||||
一旦我知道这台机器符合我的测试需求,我需要确保没有其他人同时登录该系统运行他们自己的测试。虽然考虑到整备系统会帮我处理好这个问题,这种可能性很小,但偶尔检查一下还是有好处的 —— 尤其是当我第一次登录服务器的时候。我还会检查是否有其他用户(除了 root)可以访问系统。
|
||||
|
||||
使用下面的命令来查找这些信息。最后一条命令是查找 `/etc/passwd` 文件中具有 shell 访问权限的用户;它会跳过文件中没有 shell 访问权限或 shell 设置为 `nologin` 的其他服务:
|
||||
|
||||
```
|
||||
who
|
||||
who -Hu
|
||||
grep sh$ /etc/passwd
|
||||
```
|
||||
|
||||
### 3、物理机还是虚拟机
|
||||
|
||||
现在我有了属于自己的机器,我需要确定它是一台物理机还是一台虚拟机(VM)。如果是我自己整备的这台机器,我可以确定这是我要求的东西。但是,如果你使用的是一台不是你自己整备的机器,你应该检查该机器是物理机还是虚拟机。
|
||||
|
||||
使用以下命令来识别这些信息。如果是物理系统,你会看到供应商的名称(如 HP、IBM 等)以及服务器的品牌和型号;而在虚拟机中,你应该看到 KVM、VirtualBox 等,这取决于创建虚拟机时使用了什么虚拟化软件:
|
||||
|
||||
```
|
||||
dmidecode -s system-manufacturer
|
||||
dmidecode -s system-product-name
|
||||
lshw -c system | grep product | head -1
|
||||
cat /sys/class/dmi/id/product_name
|
||||
cat /sys/class/dmi/id/sys_vendor
|
||||
```
|
||||
|
||||
### 4、硬件
|
||||
|
||||
因为我经常测试连接到 Linux 机器的硬件,所以我通常使用物理服务器,而不是虚拟机。在物理机器上,我的下一步是确定服务器的硬件能力 —— 例如,运行的是什么类型的 CPU,它有多少个核心,启用了哪些标志,以及有多少内存可用于运行测试。如果我正在运行网络测试,我会检查连接到服务器的以太网或其他网络设备的类型和容量。
|
||||
|
||||
使用以下命令来显示连接到 Linux 服务器的硬件。其中一些命令在新的操作系统版本中可能会被废弃,但你仍然可以从 yum 存储库中安装它们或切换到它们的等效新命令:
|
||||
|
||||
```
|
||||
lscpu or cat /proc/cpuinfo
|
||||
lsmem or cat /proc/meminfo
|
||||
ifconfig -a
|
||||
ethtool <devname>
|
||||
lshw
|
||||
lspci
|
||||
dmidecode
|
||||
```
|
||||
|
||||
### 5、已安装的软件
|
||||
|
||||
测试软件总是需要安装额外的依赖包、库等。然而,在安装任何东西之前,我都会检查已经安装了什么(包括是什么版本),以及配置了哪些存储库,这样我就知道软件来自哪里,并可以调试任何软件包安装问题。
|
||||
|
||||
使用下面的命令来确定安装了什么软件:
|
||||
|
||||
```
|
||||
rpm -qa
|
||||
rpm -qa | grep <pkgname>
|
||||
rpm -qi <pkgname>
|
||||
yum repolist
|
||||
yum repoinfo
|
||||
yum install <pkgname>
|
||||
ls -l /etc/yum.repos.d/
|
||||
```
|
||||
|
||||
### 6、运行的进程和服务
|
||||
|
||||
检查了安装的软件之后,自然就会检查系统上有哪些进程在运行。当在系统上运行性能测试时,这一点至关重要 —— 如果一个正在运行的进程、守护进程、测试软件等占用了大部分 CPU/RAM,那么在运行测试之前停止该进程是有意义的。这也可以检查测试所需的进程或守护进程是否已经启动并运行。例如,如果测试需要 `httpd` 运行,那么即使安装了软件包,启动守护进程的服务也可能没有运行。
|
||||
|
||||
使用以下命令来识别系统上正在运行的进程和已启用的服务:
|
||||
|
||||
```
|
||||
pstree -pa 1
|
||||
ps -ef
|
||||
ps auxf
|
||||
systemctl
|
||||
```
|
||||
|
||||
### 7、网络连接
|
||||
|
||||
如今的机器网络化程度很高,它们需要与网络上的其他机器或服务进行通信。我会识别服务器上哪些端口是开放的,是否有到测试机器的任何网络连接,是否启用了防火墙,如果启用了,是否屏蔽了任何端口,以及机器与哪些 DNS 服务器对话。
|
||||
|
||||
使用以下命令来识别网络服务相关信息。如果一个过时的命令不可用,请从 yum 存储库中安装它或使用等效的新命令:
|
||||
|
||||
```
|
||||
netstat -tulpn
|
||||
netstat -anp
|
||||
lsof -i
|
||||
ss
|
||||
iptables -L -n
|
||||
cat /etc/resolv.conf
|
||||
```
|
||||
|
||||
### 8、内核
|
||||
|
||||
在进行系统测试时,我发现了解内核相关的信息是很有帮助的,比如内核版本和加载了哪些内核模块。我还会列出任何[可调整的内核参数][2]以及它们的设置,并检查启动运行中的内核时使用的选项。
|
||||
|
||||
使用以下命令来识别这些信息:
|
||||
|
||||
```
|
||||
uname -r
|
||||
cat /proc/cmdline
|
||||
lsmod
|
||||
modinfo <module>
|
||||
sysctl -a
|
||||
cat /boot/grub2/grub.cfg
|
||||
```
|
||||
|
||||
### 9、日志
|
||||
|
||||
现在,我已经对服务器有了很好的了解,包括安装了哪些软件,运行了哪些进程。还有一件事我无法逃避,那就是日志文件 —— 我需要知道在哪里可以查看不断更新的信息。
|
||||
|
||||
使用以下命令查看系统的日志:
|
||||
|
||||
```
|
||||
dmesg
|
||||
tail -f /var/log/messages
|
||||
journalctl
|
||||
```
|
||||
|
||||
### 接下来的步骤
|
||||
|
||||
虽然命令和实用程序会发生变化,但它们所显示的基本信息大致不变。在你专注于掌握哪些命令之前,你需要对你要寻找的信息以及它属于什么类别有一个宏观的看法。
|
||||
|
||||
由于 Linux 将大部分信息保存在文件中,这些命令基本上是从文件中读取信息,并以一种易于理解的方式呈现出来。下一步的好做法是找出每个命令用来获取信息显示的文件。一个提示:寻找这些信息的方法是 `strace` 命令。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/linux-server
|
||||
|
||||
作者:[Gaurav Kamathe][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/gkamathe
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_modules_networking_hardware_parts.png?itok=rPpVj92- (Parts, modules, containers for software)
|
||||
[2]: https://www.oreilly.com/library/view/red-hat-enterprise/9781785283550/ch10s05.html
|
@ -0,0 +1,169 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12948-1.html)
|
||||
[#]: subject: (How to View Images from the Linux Terminal)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-view-display-images-from-linux-terminal/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
如何在 Linux 终端查看图像
|
||||
======
|
||||
|
||||

|
||||
|
||||
Linux 有很多用于查看图像的 GUI 应用。但我从来没有尝试过用任何命令行应用来查看它。
|
||||
|
||||
幸运的是,在使用 [ImageMagick 工具][1]时,我得到了一个从终端查看图像的命令。命令名是 `“display`,它是 ImageMagick 工具的一部分。这是一个很好的工具,允许类 UNIX 用户从终端查看图像。
|
||||
|
||||
此外,我还为此用途得到了另一个很好的工具,叫做 FIM。
|
||||
|
||||
我们将向你展示如何安装并使用它从 Linux 终端查看图像。这些命令使用系统的<ruby>帧缓冲<rt>framebuffer</rt></ruby>直接从命令行显示图像。
|
||||
|
||||
### 如何使用 display 命令从终端查看图像
|
||||
|
||||
[ImageMagick][2] 是一个自由开源、功能丰富、基于命令行的图像处理工具。它用于创建、编辑、合成或转换位图图像。它可以读取和写入各种格式(超过 200 种)的图像,包括 PNG、JPEG、GIF、PDF、SVG 等。它可以调整图像的大小、镜像、旋转、转换图像、调整图像颜色、应用各种特殊效果等。它支持批处理,允许你一次处理所有图像。
|
||||
|
||||
### 如何安装 ImageMagick?
|
||||
|
||||
ImageMagick 软件包包含在大多数 Linux 发行版的官方仓库中。使用发行版软件包管理器来安装它。
|
||||
|
||||
**需要注意的是:**确保你的 Linux 系统上已经安装了 “[Development Tools][3]” 包,这是安装的前提条件。
|
||||
|
||||
对于 RHEL/CentOS 6/7 系统,请使用 [yum 命令][4] 安装 ImageMagick:
|
||||
|
||||
```
|
||||
$ sudo yum install -y ImageMagick ImageMagick-devel
|
||||
```
|
||||
|
||||
在 RHEL/CentOS 8 和 Fedora 系统,使用 [dnf 命令][5] 安装 ImageMagick:
|
||||
|
||||
```
|
||||
$ sudo dnf install -y ImageMagick ImageMagick-devel
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [apt 命令][6] 或 [apt-get 命令][7] 安装 ImageMagick:
|
||||
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install imagemagick
|
||||
```
|
||||
|
||||
对于 openSUSE 系统,使用 [zypper 命令][8] 安装 ImageMagick:
|
||||
|
||||
```
|
||||
$ sudo zypper install -y ImageMagick
|
||||
```
|
||||
|
||||
要查看任何图像文件,请运行 `display` 命令,如下所示。你可以按下 `Esc`/`q` 按钮关闭图像:
|
||||
|
||||
```
|
||||
$ display bird.jpg
|
||||
```
|
||||
|
||||

|
||||
|
||||
如果你想用指定的窗口大小打开图像,请使用 `-geometry` 标志:
|
||||
|
||||
```
|
||||
$ display -geometry 1000x600 ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
你也可以通过 `display` 命令输入图像的位置信息。下面的命令可以从桌面的距顶部 800 像素和据左上角 800 像素处打开图像:
|
||||
|
||||
```
|
||||
$ display -geometry 1000x600+800+800 ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
如果你想用 `display` 命令调整图像的大小,请使用以下格式:
|
||||
|
||||
```
|
||||
$ display -resize 600x400 ~/Downloads/bird.jp
|
||||
```
|
||||
|
||||
另外,你也可以使用百分比来调整图片的大小:
|
||||
|
||||
```
|
||||
$ display -resize 50% ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
### 如何使用 fim 命令从终端查看图像
|
||||
|
||||
[FIM][10] 是一个专门为 Linux 设计的轻量级全局图像查看器。但它并不局限于 Linux,它也可配置在其他操作系统上运行,如 MS-Windows。
|
||||
|
||||
对于熟悉 VIM 文本编辑器等软件的用户来说,它是高度可定制和可脚本化的图像查看器。它可以全屏显示图像,并且可以使用键盘快捷键轻松控制。它是一款非常轻量级的工具,因为它只依赖于某些库。
|
||||
|
||||
它可以打开许多文件格式,它可以在以下视频模式下显示图像:
|
||||
|
||||
* 使用 Linux 帧缓冲设备图形化。
|
||||
* 在 X/Xorg 下,使用 SDL 库图形化
|
||||
* 在 X/Xorg 下,使用 Imlib2 库图形化。
|
||||
* 使用 AAlib 库,在任意文本控制台中以 ASCII 艺术形式呈现。
|
||||
|
||||
运行时自动检测或选择正确的视频模式,如果需要,可以在构建前配置时选择加入或去除。
|
||||
|
||||
FIM 是 “Fbi IMproved” 的缩写,是 Fbi Image Viewer 的复刻版本。
|
||||
|
||||
FIM 可以很容易地安装在基于 Debian/Ubuntu 的系统上,因为该软件包在发行版的官方仓库中是可用的。对于其他发行版,你可能需要从源码编译它:
|
||||
|
||||
```
|
||||
$ sudo apt install fim
|
||||
```
|
||||
|
||||
安装完毕后,你可以使用以下命令显示图像:
|
||||
|
||||
```
|
||||
$ fim bird.jpg
|
||||
```
|
||||
|
||||
你可以使用 `-a` 选项自动缩放图像:
|
||||
|
||||
```
|
||||
$ fim -a bird.jpg
|
||||
```
|
||||
|
||||

|
||||
|
||||
如果你要打开当前目录中的多个图像文件,请使用通配符将它们全部打开。使用 `PageUp`/`PageDown` 键盘快捷键移动到下一张或上一张图像:
|
||||
|
||||
```
|
||||
$ fim -a *.jpg
|
||||
```
|
||||
|
||||
要以 ASCII 格式查看图像,可以使用 `-t` 标志:
|
||||
|
||||
```
|
||||
$ fim -t bird.jpg
|
||||
```
|
||||
|
||||
下面的键盘快捷键可以让你控制图像:
|
||||
|
||||
* `PageUp`/`PageDown`:上一张/下一张图片。
|
||||
* `+`/`-`:放大/缩小
|
||||
* `a`:自动缩放
|
||||
* `w`:适应宽度
|
||||
* `ESC`/`q`:退出
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-view-display-images-from-linux-terminal/
|
||||
|
||||
作者:[Magesh Maruthamuthu][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://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/resize-convert-images-from-linux-command-line/
|
||||
[2]: https://imagemagick.org/
|
||||
[3]: https://www.2daygeek.com/install-development-tools-on-ubuntu-debian-arch-linux-mint-fedora-centos-rhel-opensuse/
|
||||
[4]: https://www.2daygeek.com/linux-yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[5]: https://www.2daygeek.com/linux-dnf-command-examples-manage-packages-fedora-centos-rhel-systems/
|
||||
[6]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[7]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[8]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.nongnu.org/fbi-improved/#docs
|
@ -0,0 +1,108 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12955-1.html)
|
||||
[#]: subject: (Why Vim users will love the Kakoune text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/kakoune)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
为什么 Vim 用户会喜欢 Kakoune 文本编辑器?
|
||||
======
|
||||
|
||||
> 这个编辑器可能会让人联想到 Vim,但它也提供了很多自己独特的功能和特性。
|
||||
|
||||

|
||||
|
||||
[Kakoune][2] 文本编辑器的灵感来源于 Vi。它拥有简约的界面、简短的键盘快捷键以及独立的编辑和插入模式,乍一看确实[看起来和感觉很像 Vi][3]。然而,Kakoune 编辑器在设计和功能上都有自己独特的风格,与其说是另一个 Vim,不如说是它是它自己。
|
||||
|
||||
### 安装
|
||||
|
||||
在 Linux 和 BSD 上,你可以从你的发行版的软件仓库或 port 树上安装 Kakoune。例如,在 Fedora、CentOS 或 RHEL 上:
|
||||
|
||||
```
|
||||
$ sudo dnf install kakoune
|
||||
```
|
||||
|
||||
在 Debian、Ubuntu 或类似的系统上:
|
||||
|
||||
```
|
||||
$ sudo apt install kakoune
|
||||
```
|
||||
|
||||
在 macOS 上,你可以使用 Homebrew:
|
||||
|
||||
```
|
||||
$ brew install kakoune
|
||||
```
|
||||
|
||||
或者,你也可以[从源码构建][4]。
|
||||
|
||||
启动 Kakoune 的命令是 `kak`。你可以启动 Kakoune 打开空文件,也可以在启动时包含文件名让它打开:
|
||||
|
||||
```
|
||||
$ kak example.txt
|
||||
```
|
||||
|
||||
### 使用 Kakoune
|
||||
|
||||
当你启动 Kakoune(不带文件名)时,除了在窗口底部有一个小的状态栏外,它在你的终端中打开的大部分是空的缓冲区。像 Vim 一样,Kakoune 以“正常”模式启动,它把按键作为命令,不向缓冲区输入文本。要进入*插入模式*,你必须按 `i`(代表<ruby>插入<rt>Insert</rt></ruby>)或 `a`(代表<ruby>追加<rt>Append</rt></ruby>)。
|
||||
|
||||
在插入模式下,Kakoune 的操作和其他编辑器一样。你在键盘上输入,然后你输入的字符就会显示在缓冲区里。在插入模式下,你可以使用方向键来浏览缓冲区。
|
||||
|
||||
### 正常模式
|
||||
|
||||
在正常模式下,你可以发出导航和文本编辑命令。这是从 Vi 传统中借用的最明显的功能。编辑命令包括复制、剪切(在传统的 Unix 编辑术语中,称为 “<ruby>猛拉<rt>yank</rt></ruby>”)、粘贴单词和行、撤销、转换字符大小写等功能。下面是一些基础:
|
||||
|
||||
* `d`:复制并删除当前选择(现代术语中的“剪切”)
|
||||
* `c`:复制并删除当前选择,并进入插入模式
|
||||
* `Esc+Alt+d`:删除当前选择
|
||||
* `y`:复制选择
|
||||
* `p`:粘贴
|
||||
* `<`:取消所选行的缩进
|
||||
* `u`:撤消
|
||||
* `U`:重做
|
||||
* `:转为小写
|
||||
* `~`:转换为大写
|
||||
|
||||
### 选择
|
||||
|
||||
在 Kakoune 中,你的光标是一个单字符的移动选区。除非你扩展你的选区,否则任何影响选区的命令都只适用当前光标位置。例如,如果你的光标悬停在字母 `n` 上,那么复制命令(正常模式下的 `c`)会将字母 `n` 复制到剪贴板,而粘贴命令(正常模式下的 `p`)则会将字母 `n` 粘贴到缓冲区。
|
||||
|
||||
从单个字符扩展选区的最简单方法是进入正常模式,按下 `Shift` 键,同时用方向键移动光标。然而,有几种方法可以根据某些标准来扩展选区。例如,`Alt+l` 将选区从光标扩展到当前行的末端。
|
||||
|
||||
完整的文档可以在 <https://github.com/mawww/kakoune/blob/master/README.asciidoc> 中找到。
|
||||
|
||||
### 函数
|
||||
|
||||
除了这些基本的交互,你还可以执行命令来调用 Kakoune 的内置功能。要访问 Kakoune 的命令行,在普通模式下输入 `:`。在命令行中,你可以执行命令,包括打开文件的 `edit` 命令,保存缓冲区到文件的 `write` 命令,当然还有退出应用的 `quit`。
|
||||
|
||||
还有更多的函数,包括针对特定编程语言和文件格式的特殊选项、使用 [Ranger 文件浏览器][5]浏览文件系统的选项、改变颜色主题、搜索和替换文本等等。
|
||||
|
||||
![Kakoune][6]
|
||||
|
||||
### 尝试 Kakoune
|
||||
|
||||
如果你是一个有经验的 Vim 用户,或者甚至是一个只是略知一二的人,你可能会发现 Kakoune 一开始会让你感到迷惑。它与 Vim 的相似度足以让你陷入一种虚假的熟悉感。一切都与 Vim 一模一样,直到你发现了完全不同的地方。不过,如果你是一个刚接触 Vim 编辑器的新手,或者你是一个正在寻找新挑战的 Vim 用户,那么 Kakoune 可能是你的理想编辑器。
|
||||
|
||||
你自己试试吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/kakoune
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriterkeys-3.png?itok=NyBwMdK_ (Typewriter keys in multicolor)
|
||||
[2]: https://kakoune.org/
|
||||
[3]: https://linux.cn/article-12947-1.html
|
||||
[4]: https://github.com/mawww/kakoune
|
||||
[5]: https://opensource.com/article/20/3/ranger-file-navigator
|
||||
[6]: https://opensource.com/sites/default/files/kakoune-screenshot.png (Kakoune)
|
@ -0,0 +1,71 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12961-1.html)
|
||||
[#]: subject: (Find out how your text will be read with Norka)
|
||||
[#]: via: (https://opensource.com/article/20/12/norka)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
了解如何使用 Norka 编辑器阅读文本
|
||||
======
|
||||
|
||||
> 这是一个素颜朝天的文本编辑器,旨在让你的写作能被更好地阅读和理解。
|
||||
|
||||

|
||||
|
||||
有些文本编辑器是为编程而设计的,有些是为专门的文本格式而设计的,有些是为文档设计而设计的。Norka 文本编辑器是为阅读而设计的。创建一个为*阅读*而设计的文本编辑器似乎很奇怪,但实际上,如果你仔细想想,这是很有意义的。你的文字已经写了一次或三次,这取决于你个人对迭代的容忍度,但它的目的是为了在未来几年内被阅读。Norka 让你轻松地专注于你的文字如何被阅读。
|
||||
|
||||
### 安装
|
||||
|
||||
Norka 文本编辑器是 MIT 授权的,可以[作为 Flatpak 包安装在 Linux上][2]。它是开源的,所以如果你想尝试在不同的平台上安装它,你可以[克隆它的 Github 仓库][3]。
|
||||
|
||||
### Norka 的界面
|
||||
|
||||
Norka 的界面很简单。一个回到 Norka 文档集的按钮,一个导出按钮和一个偏好菜单。窗口的其余部分是供你写文字的空白空间,在右下角,有一个阅读时间计算器来帮助你了解读者可能需要多长时间才能看完你写的东西。
|
||||
|
||||
![Dark Norka terminal box with green and white text][4]
|
||||
|
||||
这几乎就是 Norka 的全部内容。没有分页符或行号,没有代码折叠或正则搜索。这是一个用于文字书写的编辑器,而不设置文档样式或跟踪复杂的数据模式。
|
||||
|
||||
当然,它还有一些额外的功能。如预期那样,可以使用 `Ctrl+C` 和 `Ctrl+V` 复制和粘贴。你可以用 `Ctrl+Z` 撤销,用 `Ctrl+F` 查找。你甚至可以用 `Ctrl+:` 插入表情符号。
|
||||
|
||||
![Norka terminal box with pop up box of emoji search menu][5]
|
||||
|
||||
#### 样式文本
|
||||
|
||||
虽然 Norka 绝对没有兴趣帮你设计,比如说,一本小册子或传单,但它确实有一些能力来指示你想要的文本样式。它通过 [Markdown][6] 来实现这一点,这是一个简单的纯文本书写的约定,但用特殊的符号来指示文本应该如何在 HTML、EPUB 或 PDF 或任何你的目标格式中呈现。
|
||||
|
||||
在大多数编辑器中,你必须知道 Markdown 才能使用 Markdown,但 Norka 翻译了常见的文字处理器键盘快捷键来为你生成 Markdown。例如,要使一个单词加粗,你可以按 `Ctrl+B`,它会在光标的两边插入四个星号。当你输入下一个单词时,它的两边都会有两个星号,这就是 Markdown 对粗体(默认为粗体)文本的标记。你可以在 Norka 窗口右上角的汉堡样式的菜单中查看所有的 Markdown 快捷方式。
|
||||
|
||||
#### 保存和导出
|
||||
|
||||
你可以把 Norka 想象成一个笔记本。你在 Norka 中打开的所有文档都会保留在 Norka 的内部数据库中,所有的文档都会默认自动保存。要在 Norka 外使用文件,你可以在打开的文件中点击右上角的**共享**按钮。另外,你也可以在 Norka 的文件视图中右击任何文件,选择**导出**。你可以将文档导出(或**共享**,Norka 可互换使用这两个术语)为**文本**、**HTML** 或 **Markdown**。
|
||||
|
||||
### 尝试 Norka
|
||||
|
||||
Norka 便于尝试,也易于使用。它通过保持界面简单,几乎到了受限的程度,帮助你专注于写作。但限制有时也是一种强大的创意工具。
|
||||
|
||||
Norka 可能不是你进行大量修改或文本处理的最佳选择。它没有让人激动的功能,比如大小写转换、集成 `sed` 命令、字符交换等等。它是一个为读者服务的文本编辑器。如果你觉得有用,那么你可能正是 Norka 正在寻找的受众。
|
||||
|
||||
感谢你花 2 分 39 秒阅读本文!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/norka
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/reading_book_selfcare_wfh_learning_education_520.png?itok=H6satV2u (Reading a book, selfcare)
|
||||
[2]: https://flathub.org/apps/details/com.github.tenderowl.norka
|
||||
[3]: https://github.com/TenderOwl/Norka
|
||||
[4]: https://opensource.com/sites/default/files/uploads/norka-31_days-norka-opensource.png (Dark Norka terminal box with green and white text)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/norka_emoji-31_days-norka-opensource.png (Norka terminal box with pop up box of emoji search menu)
|
||||
[6]: https://opensource.com/article/19/9/introduction-markdown
|
@ -1,18 +1,20 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12958-1.html)
|
||||
[#]: subject: (How to Install RPM Files on Fedora Linux [Beginner’s Tutorial])
|
||||
[#]: via: (https://itsfoss.com/install-rpm-files-fedora/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
如何在 Fedora Linux 上安装 RPM 文件 [初学者教程]
|
||||
如何在 Fedora Linux 上安装 RPM 文件
|
||||
======
|
||||
|
||||
_**这篇初学者文章介绍如何在 Fedora 和 Red Hat Linux 上安装 RPM 软件包。它也随后向你展示如何移除这些 RPM 软件包。**_
|
||||

|
||||
|
||||
当你开始使用 Red Hat 系的 Fedora Linux 时,你早晚会偶然发现 .rpm 文件。就像在 Windows 中的 .exe 文件,以及在 Ubuntu 和 Debian 中的 .deb 文件一样,一个 rpm 文件能够使你在 [Fedora][1] 上快速安装一个软件。
|
||||
> 这篇初学者文章介绍如何在 Fedora 和 Red Hat Linux 上安装 RPM 软件包。它也随后向你展示如何移除这些 RPM 软件包。
|
||||
|
||||
当你开始使用 Red Hat 系的 Fedora Linux 时,你早晚会偶然发现 .rpm 文件。就像在 Windows 中的 .exe 文件,以及在 Ubuntu 和 Debian 中的 .deb 文件一样,一个 rpm 文件能够使你在 [Fedora][1] 上快速安装一个软件。
|
||||
|
||||
你可以从软件中心中找到并安装大量的软件,特别是 [如果你在 Fedora 中启用附加的存储库的话][2]。但是有时你会在它们的网站上找到可用的 RPM 格式的软件包。
|
||||
|
||||
@ -22,15 +24,13 @@ _**这篇初学者文章介绍如何在 Fedora 和 Red Hat Linux 上安装 RPM
|
||||
|
||||
我将向你展示安装 RPM 文件的三个方法:
|
||||
|
||||
* [使用软件中心安装 RPM 文件][3] (GUI 方法)
|
||||
* [使用 DNF 命令安装 RPM 文件][4] (CLI 方法)
|
||||
* [使用 Yum 命令安装 RPM 文件][5] (Red Hat 的 CLI 方法)
|
||||
|
||||
|
||||
* [使用软件中心安装 RPM 文件][3](GUI 方法)
|
||||
* [使用 DNF 命令安装 RPM 文件][4](CLI 方法)
|
||||
* [使用 Yum 命令安装 RPM 文件][5](Red Hat 的 CLI 方法)
|
||||
|
||||
#### 方法 1: 使用软件中心
|
||||
|
||||
在 Fedora 中使用默认的软件中心是最简单的方法。它真地很简单。转到你下载的 .rpm 文件的文件夹位置。它通常在 Downloads 文件夹。
|
||||
在 Fedora 中使用默认的软件中心是最简单的方法。它真地很简单。转到你下载的 .rpm 文件的文件夹位置。它通常在 “Downloads” 文件夹。
|
||||
|
||||
只需要 **双击 RPM 文件,它将会在软件中心中打开**。
|
||||
|
||||
@ -38,7 +38,7 @@ _**这篇初学者文章介绍如何在 Fedora 和 Red Hat Linux 上安装 RPM
|
||||
|
||||
![或者双击或者右键并选择软件安装][6]
|
||||
|
||||
当它在软件中心打开时,你应该会看到安装选项。只需要点击安装按钮并在提示时输入你的账号密码。
|
||||
当它在软件中心打开时,你应该会看到“安装”选项。只需要点击“安装”按钮并在提示时输入你的账号密码。
|
||||
|
||||
![通过 Fedora 软件中心安装 RPM][7]
|
||||
|
||||
@ -46,9 +46,9 @@ _**这篇初学者文章介绍如何在 Fedora 和 Red Hat Linux 上安装 RPM
|
||||
|
||||
#### 方法 2: 使用 DNF 命令来安装 RPM 文件
|
||||
|
||||
这是命令行方法。Fedora 使用新的 DNF [软件包管理器][8] ,你也可以使用它来安装下载的 RPM 文件。
|
||||
这是命令行方法。Fedora 使用新的 `dnf` [软件包管理器][8] ,你也可以使用它来安装下载的 RPM 文件。
|
||||
|
||||
打开一个终端并切换到你下载 RPM 文件的目录下。你也可以通过到 RPM 文件的路径。像这样使用 DNF 命令:
|
||||
打开一个终端并切换到你下载 RPM 文件的目录下。你也可以通过到 RPM 文件的路径。像这样使用 `dnf` 命令:
|
||||
|
||||
```
|
||||
sudo dnf install rpm_file_name
|
||||
@ -60,9 +60,9 @@ sudo dnf install rpm_file_name
|
||||
|
||||
#### 方法 3: 在 Red Hat 中使用 Yum 命令安装 RPM 文件
|
||||
|
||||
不像 Fedora ,Red Hat 仍然使用很好的旧式的 Yum 软件包管理器。在这里你还不能找到 DNF 命令。
|
||||
不像 Fedora ,Red Hat 仍然使用很好的旧式的 Yum 软件包管理器。在这里你还不能找到 `dnf` 命令。
|
||||
|
||||
这个过程与 DNF 命令相同。转到 RPM 文件所在的目录或提供它的路径。
|
||||
这个过程与 `dnf` 命令相同。转到 RPM 文件所在的目录或提供它的路径。
|
||||
|
||||
```
|
||||
sudo yum install path_to_RPM_file
|
||||
@ -78,21 +78,21 @@ sudo yum install path_to_RPM_file
|
||||
|
||||
![移除 RPM 软件包][11]
|
||||
|
||||
或者,你可以使用带有 `remove` 选项的 DNF 或 YUM 命令。
|
||||
或者,你可以使用带有 `remove` 选项的 `dnf` 或 `yum` 命令。
|
||||
|
||||
使用 DNF ,使用这个命令:
|
||||
使用 `dnf` ,使用这个命令:
|
||||
|
||||
```
|
||||
sudo dnf remove rpm_package_name
|
||||
```
|
||||
|
||||
使用 Yum ,使用这个命令:
|
||||
使用 `yum` ,使用这个命令:
|
||||
|
||||
```
|
||||
sudo yum remove rpm_package_name
|
||||
```
|
||||
|
||||
你可能不记得准确的软件包名称,没有关系。你可以做的是输入软件包的前几个字母,然后敲击 tab 按键。这是假设你已经启用 tab 按键补全,通常是这样的。
|
||||
你可能不记得准确的软件包名称,没有关系。你可以做的是输入软件包的前几个字母,然后敲击 `tab` 按键。这是假设你已经启用 `tab` 按键补全,通常是这样的。
|
||||
|
||||
这就是你需要做的全部。相当简单,对吧?作为一个初学者,你可能会为这样一个简单的任务而挣扎,我希望像这样的快速教程会让你对 Fedora 更自信一些。
|
||||
|
||||
@ -103,7 +103,7 @@ via: https://itsfoss.com/install-rpm-files-fedora/
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,72 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12964-1.html)
|
||||
[#]: subject: (How to use this KDE Plasma text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/kwrite-kde-plasma)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何使用这个 KDE Plasma 文本编辑器?
|
||||
======
|
||||
|
||||
> 作为流行的 KDE Plasma 桌面的一部分,KWrite 在一个简单易用的界面中隐藏了大量有用的功能。
|
||||
|
||||

|
||||
|
||||
KWrite 是一款适用于 KDE Plasma 桌面的文本编辑器。它的目的是成为一个通用的应用,任何人都可以在他们需要快速做笔记、写一篇学校论文、做一些编程,和/或任何其他你能想到的文本编辑器能做的事时用上它。它使用 [Kate 编辑器][2]的组件来创建一个简单的界面,但它利用这些相同的组件来提供了大量有用的功能。
|
||||
|
||||
### 安装
|
||||
|
||||
KWrite 不可用于所有环境,它是 [KDE Plasma 桌面][3]的一个组件,所以如果你正在运行 Plasma,那么你已经有了 KWrite。
|
||||
|
||||
如果你没有运行 Plasma,那么你可以安装 Plasma,这样你可以将它和 KWrite 一起开始使用,或者根据需要使用 KWrite。然而,它是作为 Plasma 桌面的默认文本编辑器,所以如果你真的想把它作为一个独立应用使用,那么安装 Kate 可能更容易。
|
||||
|
||||
### 使用 KWrite
|
||||
|
||||
当你启动 KWrite 时,你会看到期望的编辑器的样子:一大块用于输入的区域,顶部有一个菜单栏和工具栏,底部有一个状态栏。这就是你在开始之前需要了解的全部内容。KWrite 是一个直观的应用,工具栏按钮用于重要的动作,如打开和保存文件,简单的菜单系统用于更高级的编辑任务。
|
||||
|
||||
![Kwrite terminal containing dark gray html code on white background][4]
|
||||
|
||||
KWrite 的许多功能都是潜在的,不需要你自己去激活它们就会发生。例如,如果你打开一个用 HTML 编写的文件,那么 KWrite 会高亮显示关键字(如 `class` 和 `id`)和识别代码标签(如 `<p>` 或 `<div>`),并将它们与自然语言的单词区别对待。当你加载一个用 Python 编写的文件时,也会发生同样的情况,而对于主要用自然语言编写的文件,则不会发生任何事情。
|
||||
|
||||
当然,你不必只选择 HTML、Python 和你的母语。KWrite 支持很多语言和格式(对于很多语言和格式,它甚至有自动完成选项)。
|
||||
|
||||
对于那些想要除了自动加载功能之外更多功能的用户,在编辑、视图和工具菜单中都有一些选项。例如,你可以激活动态的拼写检查、运行脚本、调出命令行、注释或取消注释一行、调整缩进、显示行号等等。
|
||||
|
||||
当从终端启动 KWrite 时,也有一些有趣的选项。例如,如果你知道要到文件中的哪一行,你可以用行号参数启动 KWrite:
|
||||
|
||||
```
|
||||
$ kwrite --line 101 example.txt
|
||||
```
|
||||
|
||||
你也可以使用 `--stdin` (或简写 `-i`)选项方便地将命令的输出通过管道到 KWrite。例如,这个命令下载 [example.com][5] 的首页,并在一个新的 KWrite 窗口中显示 HTML:
|
||||
|
||||
```
|
||||
$ curl http://example.com | kwrite --stdin
|
||||
```
|
||||
|
||||
### 尝试 KWrite
|
||||
|
||||
我一直觉得 KDE 的优势之一就是它的复杂性很灵活。如果你想要一个简单的桌面,你基本上可以选择忽略任何你不想要的功能。KWrite 就是这种灵活性也适用于开发人员的一个例子。由于 Kate 具有许多功能,所以开发者有能够重用这些功能的一个子集来创建一个更干净、更专注的应用版本。
|
||||
|
||||
KWrite 是一个单文档编辑器。它没有标签,也没有任何“项目”的意识。它的目的是为那些想一次只处理一个文档的人准备的,他们希望基本的功能在默认情况下是激活的,在需要的时候可以选择强大的编辑工具。安装优秀的 Plasma 桌面,今天就来试试吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/kwrite-kde-plasma
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer)
|
||||
[2]: https://opensource.com/article/20/12/kate-text-editor
|
||||
[3]: https://opensource.com/article/19/12/linux-kde-plasma
|
||||
[4]: https://opensource.com/sites/default/files/uploads/kwrite-31_days_kwrite-opensource.png (Kwrite terminal containing dark gray html code on white background)
|
||||
[5]: http://example.com
|
@ -0,0 +1,118 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12971-1.html)
|
||||
[#]: subject: (4 cool new projects to try in COPR from December 2020)
|
||||
[#]: via: (https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-from-december/)
|
||||
[#]: author: (Jakub Kadlčík https://fedoramagazine.org/author/frostyx/)
|
||||
|
||||
COPR 仓库中 4 个很酷的新项目(2020.12)
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
COPR 是个人软件仓库[集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
|
||||
本文介绍了 COPR 中一些有趣的新项目。如果你第一次使用 COPR,请参阅 [COPR 用户文档][3]。
|
||||
|
||||
### Blanket
|
||||
|
||||
[Blanket][5] 是一款播放背景声音的应用,它可能会提高你的注意力,提高你的工作效率。另外,它还可以帮助你在嘈杂的环境中放松和入睡。无论何时何地,Blanket 都可以让你在鸟鸣中醒来,在咖啡店聊天声或远离城市交通喧嚣的友好氛围下工作,然后在外面淅淅沥沥的雨声中像木头一样沉睡在壁炉旁边。还有其他流行的背景音选择,如粉色和白色噪音。
|
||||
|
||||
![][6]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
目前[仓库][8]为 Fedora 32 和 33 提供了 Blanket。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable tuxino/blanket
|
||||
sudo dnf install blanket
|
||||
```
|
||||
|
||||
### k9s
|
||||
|
||||
[k9s][10] 是一个管理 Kubernetes 集群的命令行工具。它可以让你列出正在运行的 pod 并与之交互,读取它们的日志,挖掘已使用的资源,并总体上使操作 Kubernetes 更轻松。通过插件和可定制的用户界面的可扩展性,k9s 受到有经验用户的欢迎。
|
||||
|
||||
|
||||
![][11]
|
||||
|
||||
有关[更多预览截图][12],请参见[项目页面][10]。
|
||||
|
||||
#### 安装说明
|
||||
|
||||
目前[仓库][14]为 Fedora 32、33、Fedora Rawhide 以及 EPEL 7、8、Centos Stream 等提供 k9s。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable luminoso/k9s
|
||||
sudo dnf install k9s
|
||||
```
|
||||
|
||||
### rhbzquery
|
||||
|
||||
[rhbzquery][16] 是一个简单的查询 Fedora Bugzilla 的工具。它提供了一个指定搜索查询的界面,但它并不在命令行中列出结果,而是由 rhbzquery 生成 Bugzilla 的 URL,并在浏览器中打开。
|
||||
|
||||
![][17]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
目前[仓库][19]为 Fedora 32、33 和 Fedora Rawhide 提供 rhbzquery。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable petersen/rhbzquery
|
||||
sudo dnf install rhbzquery
|
||||
```
|
||||
|
||||
### gping
|
||||
|
||||
[gping][21] 是一个比标准的 `ping` 命令更有视觉吸引力的选择,因为它以图表的形式显示结果。也可以同时 ping 多个主机,以方便比较它们的响应时间。
|
||||
|
||||
![][22]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
目前[仓库][24]为 Fedora 32、33、Fedora Rawhide 以及 EPEL 7 和 8 提供了 gping。要安装它,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable atim/gping
|
||||
sudo dnf install gping
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-from-december/
|
||||
|
||||
作者:[Jakub Kadlčík][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/frostyx/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg
|
||||
[2]: https://copr.fedorainfracloud.org/
|
||||
[3]: https://docs.pagure.org/copr.copr/user_documentation.html
|
||||
[4]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#blanket
|
||||
[5]: https://github.com/rafaelmardojai/blanket
|
||||
[6]: https://github.com/FrostyX/fedora-magazine/raw/main/img/blanket.png
|
||||
[7]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#installation-instructions
|
||||
[8]: https://copr.fedorainfracloud.org/coprs/tuxino/blanket/
|
||||
[9]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#k9s
|
||||
[10]: https://k9scli.io/
|
||||
[11]: https://github.com/FrostyX/fedora-magazine/raw/main/img/k9s.png
|
||||
[12]: https://k9scli.io/#-previews
|
||||
[13]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#installation-instructions-1
|
||||
[14]: https://copr.fedorainfracloud.org/coprs/luminoso/k9s/
|
||||
[15]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#rhbzquery
|
||||
[16]: https://github.com/juhp/rhbzquery
|
||||
[17]: https://github.com/FrostyX/fedora-magazine/raw/main/img/rhbzquery.png
|
||||
[18]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#installation-instructions-2
|
||||
[19]: https://copr.fedorainfracloud.org/coprs/petersen/rhbzquery/
|
||||
[20]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#gping
|
||||
[21]: https://github.com/orf/gping
|
||||
[22]: https://github.com/FrostyX/fedora-magazine/raw/main/img/gping.png
|
||||
[23]: https://github.com/FrostyX/fedora-magazine/blob/main/2020-december.md#installation-instructions-4
|
||||
[24]: https://copr.fedorainfracloud.org/coprs/atim/gping
|
@ -0,0 +1,54 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12967-1.html)
|
||||
[#]: subject: (4 reasons businesses adopted open source in 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/open-source-survey)
|
||||
[#]: author: (Chris Grams https://opensource.com/users/cgrams)
|
||||
|
||||
2020 年企业采用开源的 4 个原因
|
||||
======
|
||||
|
||||
> 根据 Tidelift 的第三次开源管理调查,根据公司规模,出现了差异。
|
||||
|
||||

|
||||
|
||||
Tidelift 的[第三次开源管理调查][2]发现,企业在大流行期间正在转向开源,44% 的组织报告他们将增加使用开源进行应用开发。
|
||||
|
||||
我们以前见过类似现象。在以前的经济衰退中,组织转向开源[以节省成本][3],并因[其它一些转型收益][4]而留下来。我们想了解哪些长期收益对不同规模的组织最有帮助。以下是我们发现的摘要。
|
||||
|
||||
**开源正在推动成本和时间的节约,同时提高效率。** 68% 的组织提到的一个关键驱动力是节约资金和开发时间,因为使用开源减少了开发人员从头开始编写新代码的时间。近半数(48%)报告称,它提高了应用开发和维护效率。拥有超过 1000 名员工的组织更有可能将此作为鼓励使用更多开源的原因(61%,而少于 1000 人的组织为 41%)。
|
||||
|
||||
![Graph showing reasons for using open source][5]
|
||||
|
||||
*(Tidelift ©2020)*
|
||||
|
||||
**在组织使用更多的开源的原因中,消除供应商锁定是一个重要原因。** 我们发现 40% 的受访者将这视为主要原因。用开源软件取代昂贵的专有软件,可以确保组织更加灵活,避免对供应商的依赖。同样,规模较大的组织也倾向于这个原因。在拥有 1000 名以上员工的组织中,有 50% 的组织将此作为主要优势。
|
||||
|
||||
**增加开发人员的满意度是使用更多开源的另一个原因,有 31% 的组织提到了这一点。** 随着企业对人才的激烈竞争,他们了解确保开发人员在工作中和使用的工具中感到快乐的价值。调查发现,开发人员使用的前三种语言是 JavaScript(78%)、Python(52%)和 Java(41%)。
|
||||
|
||||
**此外,随着开源使用量的增加,83% 的组织继续对其贡献,近一半的组织制定了管理贡献的政策。** 这些政策包括:在工作时间对组织使用但不赞助或管理的项目的贡献、对他们赞助或管理的项目的贡献、在个人时间对与工作无关的(个人)项目的贡献、以及在工作时间对与工作无关的(个人)项目的贡献。
|
||||
|
||||
虽然向开源的长期迁移仍在继续,但很明显,COVID-19 的影响可能正在加速这一进程,组织继续从使用和贡献中获得更深层次的价值。
|
||||
|
||||
更多信息,请查看 [2020 年开源管理调查][2]的所有调查结果。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/open-source-survey
|
||||
|
||||
作者:[Chris Grams][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/cgrams
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_graph_stats_blue.png?itok=OKCc_60D (Metrics and a graph illustration)
|
||||
[2]: https://www.tidelift.com/subscription/2020-managed-open-source-survey
|
||||
[3]: https://blog.tidelift.com/the-third-wave-of-open-source-migration?utm_source=opensource&utm_medium=referral&utm_campaign=2020-survey
|
||||
[4]: https://blog.tidelift.com/theres-one-thing-stopping-developers-from-using-open-source-even-more?utm_source=opensource&utm_medium=referral&utm_campaign=2020-survey
|
||||
[5]: https://opensource.com/sites/default/files/uploads/tidelift_reasons-for-using-open-source.png (Graph showing reasons for using open source)
|
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12968-1.html)
|
||||
[#]: subject: (Font Manager: A Simple Open-Source App for GTK+ Desktop)
|
||||
[#]: via: (https://itsfoss.com/font-manager/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Font Manager:一个简单的 GTK+ 桌面的开源应用
|
||||
======
|
||||
|
||||

|
||||
|
||||
> 一个非常简单的字体管理器应用,让你专注于调整 Linux 系统上的字体。
|
||||
|
||||
如果你是一个有经验的 Linux 用户,你可能会利用终端或 [调整工具][1]来管理你的 Linux 系统的字体。
|
||||
|
||||
老实说,不管 GNOME 调整工具有多有用,但是用来管理字体可能会不太够用。因此,一个单独的应用可以很好地帮助你管理字体。
|
||||
|
||||
### Font Manager:一个帮助管理字体的开源应用
|
||||
|
||||
![][2]
|
||||
|
||||
Font Manager(这就是应用的字面名称)是一个专门帮助你管理字体的应用。
|
||||
|
||||
你可以获得字体族的详细信息、可用的变体,以及根据字体的高度、宽度、间距等进行过滤和调整的功能。考虑到它是一个简单的应用,因此你找不到很多功能,但是我将在下面简要介绍一些功能。
|
||||
|
||||
### Font Manager 的功能
|
||||
|
||||
![][3]
|
||||
|
||||
* 可以添加字体
|
||||
* 可以删除字体
|
||||
* 根据字体族、供应商、间距、高度等因素轻松筛选字体
|
||||
* 调整字体的缩放系数
|
||||
* 调整字体的抗锯齿(软度/锐度)
|
||||
* 添加字体源,以便在安装前进行预览
|
||||
* 提供快速管理的键盘快捷键
|
||||
* 开箱即用的谷歌字体集成
|
||||
* 获取关于字体族中可用字符的详细信息、许可证、字体大小、供应商、文件类型、间距、宽度和样式
|
||||
|
||||
![][4]
|
||||
|
||||
总的来说,你可以轻松安装或删除字体。但是,当你管理字体时,你会得到很多帮助,如上面的截图所示。
|
||||
|
||||
### 在 Linux 上安装 Font Manager
|
||||
|
||||
你有多种选择(取决于你使用的 Linux 发行版)进行安装。
|
||||
|
||||
如果你使用的是基于 Ubuntu 的发行版,你可以通过下面的命令轻松添加 PPA 来安装 Font Manager:
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:font-manager/staging
|
||||
sudo apt update
|
||||
sudo apt install font-manager
|
||||
```
|
||||
|
||||
如果你不喜欢 [PPA][5](我更喜欢这样安装),你也可以在任何 Linux 发行版上安装一个[可用的 Flatpak 包][6]。
|
||||
|
||||
你只需要在你的 Linux 系统上启用 Flatpak,然后在你的软件中心搜索它(如果它支持 Flatpak 集成的话),或者直接输入下面的命令安装它:
|
||||
|
||||
```
|
||||
flatpak install flathub org.gnome.FontManager
|
||||
```
|
||||
|
||||
如果你是 Arch 用户,你可以在 [AUR][8] 中找到[包][7]。
|
||||
|
||||
|
||||
更多的安装说明,你可以参考它的[官网][9]和 [GitHub 页面][10]。
|
||||
|
||||
- [下载 Font Manager][9]
|
||||
|
||||
### 总结
|
||||
|
||||
Font Manager 是一个简单的解决方案,适用于任何基于 GTK+ 的桌面环境。主要用于 GNOME,但你在其他桌面环境使用它。
|
||||
|
||||
你可以得到很多有用的信息,同时可以添加或删除字体,我想这显然是一个真正的字体管理器。
|
||||
|
||||
你对 Font Manager 有什么看法?在下面的评论中告诉我你的想法吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/font-manager/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/gnome-tweak-tool/
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/12/font-manager.png?resize=800%2C565&ssl=1
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/12/font-manager-settings.jpg?resize=800%2C569&ssl=1
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/12/font-manager-showcase.png?resize=800%2C571&ssl=1
|
||||
[5]: https://itsfoss.com/ppa-guide/
|
||||
[6]: https://flathub.org/apps/details/org.gnome.FontManager
|
||||
[7]: https://aur.archlinux.org/packages/font-manager/
|
||||
[8]: https://itsfoss.com/aur-arch-linux/
|
||||
[9]: https://fontmanager.github.io/
|
||||
[10]: https://github.com/FontManager/font-manager
|
186
published/20201222 Learn Rust by writing a simple game.md
Normal file
186
published/20201222 Learn Rust by writing a simple game.md
Normal file
@ -0,0 +1,186 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12979-1.html)
|
||||
[#]: subject: (Learn Rust by writing a simple game)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-rust)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
通过编写一个简单的游戏来学习 Rust
|
||||
======
|
||||
|
||||
> 你可以尝试以多种语言编程一个简单的游戏来开始编程之路。
|
||||
|
||||
![海底的螃蟹 Ferris,Rust 编程语言的非官方标志][1]
|
||||
|
||||
当你想学习一门新的编程语言时,不妨关注一下编程语言的共同点。
|
||||
|
||||
* 变量
|
||||
* 表达式
|
||||
* 语句
|
||||
|
||||
这些概念是大多数编程语言的基础。一旦你理解了它们,你就可以开始弄清楚其余的东西。
|
||||
|
||||
因为编程语言通常具有相似性,一旦你懂了一种语言,你就可以通过理解其差异来学习另一种语言的基础知识。
|
||||
|
||||
学习新语言的一个好方法是使用一个你可以用来练习的标准程序。这可以让你专注于语言,而不是程序的逻辑。我在这一系列文章中使用了一个“猜数字”的程序,在这个程序中,电脑会在 1 到 100 之间选一个数字让你猜。程序一直循环,直到你猜对数字为止。
|
||||
|
||||
这个程序锻炼了编程语言的几个概念:
|
||||
|
||||
* 变量
|
||||
* 输入
|
||||
* 输出
|
||||
* 条件评估
|
||||
* 循环
|
||||
|
||||
这是学习一门新编程语言的很好的实践实验。
|
||||
|
||||
### 安装 Rust
|
||||
|
||||
你可以[使用 Rustup 安装一个 Rust 工具链][2],或者你可以[在线尝试 Rust][3] 而不在本地安装它。
|
||||
|
||||
如果你在本地安装,你应该定期用 `rustup update` 来更新它,以保持你的工具链的新鲜,并使用 `cargo update` 来保持你的库的最新版本。
|
||||
|
||||
### Rust 语言版本的猜数字
|
||||
|
||||
[Rust][4] 是一门赋予任何人构建可靠和高效的软件能力的语言。你可以通过编写一个 Rust 版本的“猜数字”游戏来探索 Rust。
|
||||
|
||||
第一步是编写一个 `Cargo.toml` 文件。你可以使用 `cargo new` 命令生成一个骨架 `Cargo.toml`。这几乎是开始一个 Rust 项目的最佳方式。
|
||||
|
||||
```
|
||||
$ cargo new guess
|
||||
$ cd guess
|
||||
$ ls -1
|
||||
Cargo.toml
|
||||
src/
|
||||
```
|
||||
|
||||
`Cargo.toml` 文件为你的包命名,并给它一些元数据,最重要的是,指明了它依赖于 `rand` [crate][5]。
|
||||
|
||||
```
|
||||
[package]
|
||||
name = "guess"
|
||||
version = "2020.11.0"
|
||||
authors = ["Moshe Zadka <moshez@opensource.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rand = "*"
|
||||
```
|
||||
|
||||
Rust 中的许多东西不是由语言或标准库提供的。取而代之的是,你可以从某个外部 crate 得到它们,这些 crate 可以做许多事情。
|
||||
|
||||
程序逻辑在 `src/main.rs` 中:
|
||||
|
||||
```
|
||||
use rand::Rng;
|
||||
use std::io::BufRead;
|
||||
|
||||
fn main() {
|
||||
let mut rng = rand::thread_rng();
|
||||
let random = rng.gen_range(1..101);
|
||||
println!("Guess a number between 1 and 100");
|
||||
for line in std::io::stdin().lock().lines() {
|
||||
let parsed = line.ok().as_deref().map(str::parse::<i64>);
|
||||
if let Some(Ok(guess)) = parsed {
|
||||
match guess {
|
||||
_ if guess < random => println!("Too low"),
|
||||
_ if guess > random => println!("Too high"),
|
||||
_ => {
|
||||
println!("That's right");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
代码的前两行声明你要做什么。在本例中,`rand::Rng` 生成一个猜测值,而 [trait][7] `std::io::BufRead` 使得可以从标准输入中读取。
|
||||
|
||||
Rust 代码的入口在 `main()` 函数中,所以下一步就是定义 `main()`。
|
||||
|
||||
要给一个变量赋值,先放 `let`,再放变量的名字,后面放 `=` 号。这样就创建了一个[不可变][8]变量。
|
||||
|
||||
Rust 中大多数变量都是不可变的,但是 `rng` 对象必须是可变的(`mut`)。例如,语句 `let random = 0` 给`random` 变量分配一个零值。
|
||||
|
||||
函数的第一行创建了一个线程安全的 `Rng` 对象,并将其分配给变量 `rng`。Rust 是建立在线程和内存安全的基础上的,所以你必须在开始写代码时就考虑到这些事情。
|
||||
|
||||
程序的下一行读取函数 `gen_range()` 的结果,并将其分配给名为 `random` 的变量。该函数取一个最小值(包含)和一个上界(不包含)。为了也包含上界,你可以用一个等号来标记较大的数字(例如,`1...=100`),或者你也可以像我在代码中做的那样,将上界设置为比你的预期最大值大 1。在这种情况下,该范围是 `1` 到 `100`,使得游戏刚好有足够的挑战性。
|
||||
|
||||
中央循环在 `std::io::stdin()` 中迭代行。由于有各种可能导致行不能读取的例外情况,Rust 要求你用一个 `Result` 来包裹一行。有时候可能无法将一行解析为一个整数。
|
||||
|
||||
这段代码使用条件模式匹配来忽略所有会导致错误的行:
|
||||
|
||||
```
|
||||
let parsed = line.ok().as_deref().map(str::parse::<i64>);
|
||||
if let Some(Ok(guess)) = parsed {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
第一行创建了一个 `Result<Option<i64>, ...>` 对象,因为它可能在读取或解析步骤中失败。由于下一行只在 `Some(Ok(guess))` 上匹配,每当一行的结果是一个不匹配的值时,它就会跳过 `if` 语句。这是一种强大的忽略错误的方法。
|
||||
|
||||
Rust 支持条件表达式和流程控制,比如循环。在“猜数字”游戏中,只要猜中的值不等于 `random`,Rust 就会继续循环。
|
||||
|
||||
`if` 语句的主体包含一个 Rust 的 `match` 语句的三向分支。虽然 `match` 最常用于模式匹配,但它也可以检查任意条件。在这种情况下是打印一个适当的信息,如果猜测是正确的,则中断(`break`)循环。
|
||||
|
||||
### 示例输出
|
||||
|
||||
现在你已经写好了你的 Rust 程序,你可以运行它来玩“猜数字”游戏。每次运行程序时,Rust 都会选择一个不同的随机数,所以继续猜,直到找到正确的数字。
|
||||
|
||||
```
|
||||
$ cargo run
|
||||
Compiling guess v2020.11.0 (/Users/mzadka/src/guess)
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 0.70s
|
||||
Running `target/debug/guess`
|
||||
Guess a number between 1 and 100
|
||||
50
|
||||
Too high
|
||||
25
|
||||
Too high
|
||||
12
|
||||
Too low
|
||||
18
|
||||
Too high
|
||||
15
|
||||
Too high
|
||||
13
|
||||
Too low
|
||||
14
|
||||
That's right
|
||||
```
|
||||
|
||||
典型的做法是用 `cargo run` 来测试程序。最终,你可能会使用 `cargo build` 分成两个独立的步骤[构建一个可执行文件并运行它][9]。
|
||||
|
||||
### 学习 Rust
|
||||
|
||||
这个“猜数字”游戏是学习一门新的编程语言的一个很好的入门程序,因为它以一种相当直接的方式锻炼了几个常见的编程概念。通过在不同的编程语言中实现这个简单的游戏,你可以展示语言的一些核心概念,并比较它们的细节。
|
||||
|
||||
你有喜欢的编程语言吗?你会如何用它来写“猜数字”游戏呢?请关注本系列文章,看看你可能感兴趣的其他编程语言的例子吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-rust
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rust_programming_crab_sea.png?itok=2eWLz8A5 (Ferris the crab under the sea, unofficial logo for Rust programming language)
|
||||
[2]: https://www.rust-lang.org/learn/get-started
|
||||
[3]: https://play.rust-lang.org/
|
||||
[4]: https://www.rust-lang.org/
|
||||
[5]: https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html
|
||||
[6]: mailto:moshez@opensource.com
|
||||
[7]: https://doc.rust-lang.org/rust-by-example/trait.html
|
||||
[8]: https://en.wikipedia.org/wiki/Immutable_object
|
||||
[9]: https://opensource.com/article/20/3/rust-cargo
|
128
published/20201225 How to use heredoc as a text editor.md
Normal file
128
published/20201225 How to use heredoc as a text editor.md
Normal file
@ -0,0 +1,128 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12978-1.html)
|
||||
[#]: subject: (How to use heredoc as a text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/heredoc)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何使用 heredoc 作为一个文本编辑器
|
||||
======
|
||||
|
||||
> 这个不起眼的终端功能在紧要关头提供一个文本编辑器。
|
||||
|
||||

|
||||
|
||||
在 Linux 和 Unix 的 shell 中有一个不为人知的功能,它能让你用 [cat][2] 命令打开一个 do-while 循环。它被称为 heredoc,无论你使用什么 shell,它都能让你或多或少地拥有一个文本编辑器。它的语法是:
|
||||
|
||||
```
|
||||
$ cat << EOF >> example.txt
|
||||
```
|
||||
|
||||
中间的字符串(`EOF`),本质上是一个停止循环的条件。也就是说,如果你在一行中单独输入它,循环就会结束。在循环过程中,无论你在终端中输入什么,都会被管道传送到目标文件中(在本例中)。
|
||||
|
||||
### 安装
|
||||
|
||||
只要你有一个终端,你就能够启动 heredoc。我在 [Bash][3]、[tsh][4] 和 Korn shell 中使用过这个语法技巧。
|
||||
|
||||
### 使用 heredoc
|
||||
|
||||
要打开一个 heredoc “会话”,你可以使用带重定向的 `cat` 命令。首先用终止字符串(常见约定是 `EOF`,代表 “End Of File”,但它实际上可以是任何字符串)指向 `cat` 命令。在终止字符串之后,将输出重定向到一个目标文件。然后,你就可以直接在终端中输入了,可以使用最常见的 shell 键盘快捷键来处理你的工作。当你在一行上输入你指定的终止字符串时,你的会话就结束了。你可以通过唯一的提示符(通常是 `>`)知道你是在一个 heredoc 循环中。
|
||||
|
||||
```
|
||||
$ cat << EOF >> example.txt
|
||||
> Everything you type here will be placed into example.txt when I type EOF on a line by itself. Until then, you can type...
|
||||
>
|
||||
> whatever...
|
||||
>
|
||||
> you want to type.
|
||||
>
|
||||
> EOF
|
||||
$
|
||||
```
|
||||
|
||||
在终端等待 `EOF` 时,你输入的所有内容都会被放入目标文件中,提示符被忽略,`EOF` 本身也不是文件的一部分。
|
||||
|
||||
```
|
||||
Everything you type here will be placed into example.txt when I type EOF on a line by itself. Until then, you can type...
|
||||
|
||||
whatever...
|
||||
|
||||
you want to type.
|
||||
```
|
||||
|
||||
在现实中,你可能不会用 heredoc 语法来代替一个正常的文本编辑器。它是一个很好的快速处理方式,可以输入多行,但超过 10 行左右就开始限制它的作用了。例如,如果不触发你 shell 的 [history][5] 功能,你就不能编辑以前的行。根据你的 shell 和配置,你可能需要先按向上键,然后按向下键来找回你的文本,然后用 `Ctrl+B` 来后退。
|
||||
|
||||
你的 shell 的大部分功能都能正常工作,但可能没有撤销功能,也没有什么错误恢复功能。
|
||||
|
||||
此外,即使是最简安装的系统,可能也至少安装了 [Vi][6] 或 [ed][7]。
|
||||
|
||||
然而 heredoc 还是很有用的!它比 `echo` 更灵活,当你在编写 shell 脚本时,它是不可缺少的。例如,想象一下你正在编写一个安装脚本,以便你可以自动安装一组自定义应用。其中一个应用没有生成 `.dekstop` 文件,所以它不会出现在你的应用菜单中。为了解决这个问题,你决定在安装时生成一个 `.desktop` 文件。
|
||||
|
||||
与其编写一个 `.desktop` 文件,然后作为安装脚本的外部依赖,不如在安装脚本中使用 heredoc:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
VERSION=${VERSION:-x.y.z}
|
||||
PKGNAM=${VERSION:-example}
|
||||
PKG="${PKGNAM}"-"${VERSION}"-`arch`.tgz
|
||||
|
||||
# download package
|
||||
wget "${PKG}"
|
||||
tar txvf "${PKG}"
|
||||
|
||||
# use here doc to create missing .desktop file
|
||||
cat << EOF >> $HOME/.local/share/applications/example.desktop
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name="${PKGNAM}"
|
||||
Comment="${PKGNAM}"
|
||||
Exec="${PKGNAM}" %F
|
||||
EOF
|
||||
|
||||
# insert the rest of an install script...
|
||||
```
|
||||
|
||||
你自动地将文本输入到了一个文件中,而不需要文本编辑器(当然,除了你用来写脚本的那个)。下面是生成的 `.desktop` 文件的样子:
|
||||
|
||||
```
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=example
|
||||
Comment=example
|
||||
Exec=example %F
|
||||
```
|
||||
|
||||
正如你所看到的,你可以在 heredoc 中使用变量,而且它们得到了正确的解析。`EOF` 字符串并没有出现在文件中,它只是标志着 heredoc 的结束。
|
||||
|
||||
### 比 echo 更好
|
||||
|
||||
heredoc 技术通常被认为比 `echo` 或 [printf][8] 更容易,因为一旦你“进入”了文档,你就可以自由地做任何你想做的事情。从这个意义上说,它是自由的,但与合适的文本编辑器相比,它是有限的。
|
||||
|
||||
使用 heredoc 来做快速笔记和 shell 脚本,再也不用为如何动态生成配置文件而烦恼了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/heredoc
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-window-focus.png?itok=g0xPm2kD (young woman working on a laptop)
|
||||
[2]: https://opensource.com/article/19/2/getting-started-cat-command
|
||||
[3]: https://opensource.com/article/20/4/bash-sysadmins-ebook
|
||||
[4]: https://opensource.com/article/20/8/tcsh
|
||||
[5]: https://opensource.com/article/20/6/bash-history-commands
|
||||
[6]: https://opensource.com/article/19/3/getting-started-vim
|
||||
[7]: https://opensource.com/article/20/12/gnu-ed
|
||||
[8]: https://opensource.com/article/20/8/printf
|
111
published/20201228 Learn Python by coding a simple game.md
Normal file
111
published/20201228 Learn Python by coding a simple game.md
Normal file
@ -0,0 +1,111 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12973-1.html)
|
||||
[#]: subject: (Learn Python by coding a simple game)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-python)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
编写一个简单的游戏来学习 Python
|
||||
======
|
||||
|
||||
> 通过编写一个“猜数字”游戏来探索 Python(和其他编程语言)。
|
||||
|
||||

|
||||
|
||||
在这个系列中,我们要用不同的编程语言编写相同的应用,以比较各种语言是如何工作的,并说明使用标准测试程序是学习新编程好方法。
|
||||
|
||||
当你学习一门新的编程语言时,关注它们的共同点是件好事。变量、表达式和语句是大多数编程语言的基础。一旦你理解了这些概念,你就可以开始弄清楚其余的东西。
|
||||
|
||||
因为编程语言有许多相似之处,一旦你知道一种语言,你通常可以通过观察它与你所知道的语言的不同之处来学习另一种语言的基础知识。使用你用其他语言编写的标准测试程序,可以让你专注于语言,而不是程序的逻辑。
|
||||
|
||||
为了证明这点,我们正在测试如何用多种语言编写一个“猜数字”程序。计算机选择一个 1 到 100 之间的数字,然后让你猜。程序循环,直到你猜出正确答案。
|
||||
|
||||
“猜数字”程序练习了编程语言的几个概念:
|
||||
|
||||
* 变量
|
||||
* 输入
|
||||
* 输出
|
||||
* 条件判断
|
||||
* 循环
|
||||
|
||||
这是一个很好的学习新编程语言的实践实验。
|
||||
|
||||
### 用 Python 猜数字
|
||||
|
||||
用 [Python 软件基金会][2]的话来说。“Python 是一种解释性的、交互式的、面向对象的程序设计语言,它包含了模块、异常、动态类型、非常高层的动态数据类型和类。”它是一种很好的通用编程语言,从简单的脚本到复杂的 GUI 应用都很适用。
|
||||
|
||||
你可以通过编写一个版本的“猜数字”游戏来探索 Python。这是我的实现:
|
||||
|
||||
```
|
||||
import random as randomlib
|
||||
random = randomlib.randint(1, 100)
|
||||
print("Guess a number between 1 and 100")
|
||||
while True:
|
||||
guess = int(input())
|
||||
if guess < random:
|
||||
print("Too low")
|
||||
elif guess > random:
|
||||
print("Too high")
|
||||
else:
|
||||
print("That's right!")
|
||||
break
|
||||
```
|
||||
|
||||
要给一个变量赋值,请列出变量的名称,然后是 `=` 号。例如,语句 `random = 0` 给 `random` 变量分配了一个零值。
|
||||
|
||||
脚本的第一行就导入了 `random` 模块。由于本系列中的所有程序都使用 `random` 作为变量的名称,你可以使用 `import random as randomlib` 以别名导入它,以避免命名冲突。
|
||||
|
||||
很少有函数被内置到 Python 中,大多数函数必须从标准库中显式导入。`random` 标准库模块有生成各种随机值的功能。
|
||||
|
||||
脚本的第二行读取函数 `randint()` 的结果,并将其赋值给名为 `random` 的变量。函数需要两个参数:一个最小值和一个最大值。在本例中,范围是 `1` 到 `100`,以使游戏具有足够的挑战性。
|
||||
|
||||
你可以使用 `input()` 函数提示用户输入一个值。如果你写 `guess = int(input())`,Python 会等待用户输入一些文本,将其转换为一个整数,然后将值存储在 `guess` 变量中。
|
||||
|
||||
Python 支持条件表达式和循环等流程控制。在“猜数字”游戏中,只要 `guess` 中的值不等于 `random`,Python 就会继续循环。
|
||||
|
||||
如果猜测值小于随机数,Python 会打印 `Too low`,如果猜测值大于这个数字,Python 会打印 `Too high`。
|
||||
|
||||
### 示例输出
|
||||
|
||||
现在你已经写好了 Python 程序,运行它来玩“猜数字”游戏。每次运行程序,Python 都会随机选取一个不同的数字。为了完成这个游戏,你需要猜测,直到找到正确的数字:
|
||||
|
||||
```
|
||||
$ python guess.py
|
||||
Guess a number between 1 and 100
|
||||
50
|
||||
Too high
|
||||
25
|
||||
Too high
|
||||
12
|
||||
Too high
|
||||
7
|
||||
Too high
|
||||
3
|
||||
Too low
|
||||
5
|
||||
Too low
|
||||
6
|
||||
That's right!
|
||||
```
|
||||
|
||||
在学习一门新的编程语言时,这个“猜数字”游戏是一个很好的入门程序,因为它以一种相当直接的方式练习了几个常见的编程概念。通过在不同的编程语言中实现这个简单的游戏,你可以展示不同编程语言的一些核心概念,并比较每种语言的细节。
|
||||
|
||||
你有喜欢的编程语言吗?你会如何编写“猜数字”游戏?请关注本系列文章,看看你可能感兴趣的其他编程语言的例子吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-python
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python_programming_question.png?itok=cOeJW-8r (Python programming language logo with question marks)
|
||||
[2]: https://docs.python.org/3/faq/general.html#general-information
|
@ -0,0 +1,166 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12976-1.html)
|
||||
[#]: subject: (Bring an old MacBook back to life with Linux)
|
||||
[#]: via: (https://opensource.com/article/20/12/linux-macbook)
|
||||
[#]: author: (Eric D. Schabell https://opensource.com/users/eschabell)
|
||||
|
||||
用 Linux 让旧 MacBook 重获新生
|
||||
======
|
||||
|
||||
> 花上一小时,用 Fedora 让一台过时的 Mac 重新有用。
|
||||
|
||||

|
||||
|
||||
最近,我偶然找到了一台 2011 年底的老款 13 英寸 MacBook Pro,有 125GB SSD 和 8GB 内存。我曾带着这台机器去世界各地旅行,当年,我开了很多场会议、研讨会或演示,分享 JBoss 技术带来的各种 AppDev 优势。
|
||||
|
||||
在验证了它的电池能用,充了电,重新安装了一个新的 OS X 之后,我发现 Safari 浏览器的版本受限于旧的安全规范,这意味着它现在无法连接到很多 HTTPS 网站。这就使得这个解决方案失效了。
|
||||
|
||||
这个老伙计该怎么处理呢?
|
||||
|
||||
自从我作为开发人员专门在 Linux 工作站上工作以来已经有几年了。我只使用 Fedora,所以我决定尝试在这台 MacBook Pro 上安装它的最新版本。
|
||||
|
||||
我只花了一个多小时就用下面的步骤让 [Fedora 33][2] 在这台笔记本上工作了。
|
||||
|
||||
### 下载 Fedora 33 并创建一个临场 USB
|
||||
|
||||
第一步是找到正确的安装 Fedora 的方法。这台机器有一个 CD 插槽,所以可以刻录一个 ISO 并从它启动,但我选择直接使用可启动的 USB 方式。
|
||||
|
||||
我登上了另一台 MacBook,访问了 [Fedora Workstation 网站][3],它有 Fedora Media Writer 的链接。点击你的机器类型的图标(在我的例子中是苹果标志),你会得到一个安装包。
|
||||
|
||||
![Fedora Media Writer 下载界面][4]
|
||||
|
||||
开始安装,可以看到一个引导你完成安装过程的图形用户界面(GUI)。选择 Fedora Workstation 33 选项。
|
||||
|
||||
![在 Fedora Media Writer 中下载 Fedora Workstation][6]
|
||||
|
||||
接下来,选择右上角的“Create Live USB”选项。
|
||||
|
||||
![创建 Live USB 的按钮][7]
|
||||
|
||||
镜像将开始下载,你将看到一个下拉菜单来选择安装位置。
|
||||
|
||||
![下载 Fedora Workstation][8]
|
||||
|
||||
插入一个有足够空间的 U 盘,下载完成后,就可以选择它并在上面安装镜像。完成后,关闭 GUI,取出 U 盘。
|
||||
|
||||
### 安装 Linux
|
||||
|
||||
将你创建的 U 盘插入 MacBook Pro 左侧的端口,并按住 `Cmd` 键左侧的 `Option`(或 `Alt`)键的同时重新启动。这将打开一个启动机器的选项菜单:使用 EFI 选项,因为那是 USB 镜像。
|
||||
|
||||
笔记本电脑将从 USB 设备启动,你可以按照[正常的 Fedora 安装][9]过程进行。如果你能将 MacBook Pro 插入网线连接,会有帮助,因为它的 Broadcom WiFi 设备无法开箱即用。
|
||||
|
||||
![MacBook Pro][10]
|
||||
|
||||
你现在也可以将 Fedora 安装到你的硬盘上,并将它永久地放在你的机器上。
|
||||
|
||||
![在 MacBook Pro 上安装 Fedora][11]
|
||||
|
||||
一旦安装程序完成,重新启动机器,Fedora 33 现在应该是启动选项。
|
||||
|
||||
![MacBook Pro 启动到 Fedora][12]
|
||||
|
||||
唯一缺少的就是 WiFi 驱动,所以要保持网线连接,安装你正在运行的内核的开发包,并为该内核构建 `broadcom-wl` 驱动。
|
||||
|
||||
验证你需要用于 WiFi 的卡。
|
||||
|
||||
```
|
||||
$ lspci -vnn -d 14e4:
|
||||
```
|
||||
|
||||
在输出中会有几项,包括如下内容:
|
||||
|
||||
```
|
||||
Network controller [0280]: Broadcom Inc. and subsidiaries....
|
||||
|
||||
Subsystem: Apple Inc. AirPort Extreme...
|
||||
```
|
||||
|
||||
安装一个仓库来拉取 Broadcom 相关的部分:
|
||||
|
||||
```
|
||||
$ su -c 'dnf install -y http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm'
|
||||
```
|
||||
|
||||
接下来的部分很有趣:如果你查看正在运行的内核时,你会看到 `v5.9.8-200.fc33`,但是你要使用开发内核包来构建你的 Broadcom 无线驱动。所以,你需要安装 `v5.8.15-301.fc33`(在写这篇文章的时候可用)。使用 `uname -r` 检查它们,并使用 `sudo dnf list kernel` 列出已安装的内核包:
|
||||
|
||||
```
|
||||
$ sudo dnf list kernel
|
||||
kernel.x86_64 5.8.15-301.fc33
|
||||
kernel.x86_64 5.9.8-200.fc33
|
||||
```
|
||||
|
||||
安装开发包:
|
||||
|
||||
```
|
||||
$ sudo dnf install -y akmods kernel-devel-5.8.15-301.fc33
|
||||
```
|
||||
|
||||
![安装开发包][13]
|
||||
|
||||
安装 Broadcom 无线软件包:
|
||||
|
||||
```
|
||||
$ sudo dnf install -y broadcom-wl
|
||||
```
|
||||
|
||||
构建内核模块:
|
||||
|
||||
```
|
||||
$ sudo akmods
|
||||
```
|
||||
|
||||
![构建内核模块][14]
|
||||
|
||||
重新启动你的机器,你应该可以看到无线驱动(`wl`)。
|
||||
|
||||
```
|
||||
$ lsmod | grep wl
|
||||
```
|
||||
|
||||
在 Fedora 中设置你的无线连接:
|
||||
|
||||
![设置无线连接][15]
|
||||
|
||||
这篇文章对我来说有些出乎意料,但我希望它能帮助别人在周末享受一些老硬件的乐趣!
|
||||
|
||||
> 现在要走不寻常路了……在 2011 年的 Macbook Pro 上安装 [#Fedora][16]。祝我好运! [pic.twitter.com/zlsESnq2Px][17]。
|
||||
>
|
||||
> - Eric D. Schabell (@ericschabell) [2020 年 11 月 22 日][18]
|
||||
|
||||
*此文原载于 [Schabell.org][19],经许可转载。*
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/linux-macbook
|
||||
|
||||
作者:[Eric D. Schabell][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/eschabell
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_desk_home_laptop_browser.png?itok=Y3UVpY0l (Digital images of a computer desktop)
|
||||
[2]: https://getfedora.org/en/
|
||||
[3]: https://getfedora.org/en/workstation/download/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/fedoramediawriter.png (Fedora Media Writer download screen)
|
||||
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/fedoraworkstation33-installation.png (Fedora Workstation download in Fedora Media Writer)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/create-live-usb.png (Create Live USB button)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/download_fedora-workstation.png (Downloading Fedora Workstation)
|
||||
[9]: https://docs.fedoraproject.org/en-US/fedora/f33/install-guide/install/Booting_the_Installation/
|
||||
[10]: https://opensource.com/sites/default/files/uploads/macbook.jpeg (MacBook Pro)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/macbook_install-fedora.jpeg (Installing Fedora on MacBook Pro)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/macbook_fedora-boot.jpeg (MacBook Pro booting into Fedora)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/install-development-packages.jpeg (Installing development packages)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/build-kernel-module.jpeg (Building the kernel module)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/wireless-setup.jpeg (Set up wireless connection)
|
||||
[16]: https://twitter.com/hashtag/Fedora?src=hash&ref_src=twsrc%5Etfw
|
||||
[17]: https://t.co/zlsESnq2Px
|
||||
[18]: https://twitter.com/ericschabell/status/1330434517883121665?ref_src=twsrc%5Etfw
|
||||
[19]: https://www.schabell.org/2020/11/installing-fedora33-on-macbook-pro-13inch-late-2011.html
|
@ -0,0 +1,79 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (9 stories about switching to an open source alternative in 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/open-source-alternatives)
|
||||
[#]: author: (Jason Blais https://opensource.com/users/jasonblais)
|
||||
|
||||
9 stories about switching to an open source alternative in 2020
|
||||
======
|
||||
Ditch your proprietary software for open source solutions.
|
||||
![Working from home at a laptop][1]
|
||||
|
||||
In 2020, as every year, new open source projects launched as alternatives to proprietary solutions. Here is a roundup of the top nine articles about open source alternatives that made the headlines in 2020 on Opensource.com.
|
||||
|
||||
### 7 alternatives to VS Code
|
||||
|
||||
Seth Kenlon gives an overview of [_7 open source alternatives to VS Code_][2], a code editor from Microsoft for Linux, Windows, and macOS. While Microsoft publishes VS Code's source code under the MIT License, "the version you download from Microsoft is not open source," Seth warns. If you prefer open source alternatives, make sure to check out Seth's article for his recommended alternatives, including VSCodium and Atom.
|
||||
|
||||
### Nextcloud instead of Google Suite
|
||||
|
||||
In [_Build your own open source alternative to Google Suite with Nextcloud_][3], Correspondent Don Watkins explains how Nextcloud has matured in recent years to become a true alternative to Google Drive and Microsoft 365. Don begins by reviewing how to get started with Nextcloud, then he outlines its key features, including the ability to "sync, share, and collaboratively view and edit files, as well as [share] calendars, contacts, email, chats, video calls, project management, [and] notes."
|
||||
|
||||
### 6 alternatives to Wunderlist
|
||||
|
||||
Wunderlist was a popular tool to track to-do lists, but when Microsoft announced it was shutting it down, many people began looking for alternatives. Jen Wike Huger does an excellent job summarizing [_6 open source alternatives to Wunderlist_][4], including OwnCloud, OpenTasks, and more. If you're still looking for a Wunderlist replacement or are just curious to know what is out there for tracking your to-do's, make sure to read Jen's article.
|
||||
|
||||
### Plausible Analytics instead of Google Analytics
|
||||
|
||||
In [_Transparent, open source alternative to Google Analytics_][5], Marko Saric describes Plausible Analytics as a "leaner, more transparent option [to Google Analytics], with the essential data you need but without all the privacy baggage." By "baggage," Marko means privacy policies, GDPR-consent prompts, and other things that come with Google Analytics. With Plausible Analytics, you don't need to worry about such privacy restrictions; the tool doesn't collect any personal data or use cookies and still provides accurate visitor statistics for your website.
|
||||
|
||||
### Mycroft instead of Alexa
|
||||
|
||||
Many people are wary about the private conversations their Apple, Google, and Amazon voice assistants may have access to. Those looking for a private option may want to explore Mycroft, [_A secure and private open source alternative to Alexa_][6]. Correspondent Steve Ovens describes Mycroft as the "open source alternative … [that] puts privacy at the forefront."
|
||||
|
||||
### HomeBank instead of Quicken
|
||||
|
||||
Quicken is a proprietary personal financial management tool—and you guessed it, there is an open source alternative for it. In [_How to use HomeBank for your open source alternative to Quicken_][7], Correspondent Jessica Cherry provides an overview of HomeBank and walks through how to install the software, create an account, and analyze your finances with the tool. If you're looking for an open source option to help manage your spending habits, make sure to read Jess' article about HomeBank.
|
||||
|
||||
### GoDBLedger instead of proprietary accounting software
|
||||
|
||||
Sean Darcy, an accountant frustrated by outdated accounting software solutions, decided to spend six months building GoDBLedger, an open source option to improve accountants' productivity. In [_Open source accounting software developed by accountants_][8], he outlines the challenges he faced with previous tools due to poor usability, unintuitive user experiences, and slow compilation that "involves a lot of human labor to achieve." He then demonstrates how GoDBLedger solves each of these challenges.
|
||||
|
||||
### 4 alternatives to Grammarly
|
||||
|
||||
Grammarly is one of the most popular tools to "check your writing for spelling, grammar, plagiarism, and style errors," writes Seth Kenlon. But instead of Grammarly, Seth uses open source options for each of these use cases. In [_Open source alternatives to Grammarly for word processing_][9], he describes the tool that works best for each of Grammarly's functionalities, such as Flyspell, a lightweight open source spell checker.
|
||||
|
||||
### 7 alternatives to StackOverflow or Quora
|
||||
|
||||
Instead of using StackOverflow or Quora as your knowledge-base Q&A site, why not switch to an open source alternative? Correspondent Bryant Son walks through [_7 open source Q&A platforms_][10], including Discourse, Vanilla, AskBot, and more. If you are looking for a new Q&A platform, make sure to check out Bryant's article!
|
||||
|
||||
### Top open source alternatives in 2021?
|
||||
|
||||
Which open source alternatives do you think will make the headlines in 2021? Let us know in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/open-source-alternatives
|
||||
|
||||
作者:[Jason Blais][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jasonblais
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||
[2]: https://opensource.com/article/20/6/open-source-alternatives-vs-code
|
||||
[3]: https://opensource.com/article/20/7/nextcloud
|
||||
[4]: https://opensource.com/article/20/5/alternatives-list
|
||||
[5]: https://opensource.com/article/20/5/plausible-analytics
|
||||
[6]: https://opensource.com/article/20/6/open-source-voice-assistant
|
||||
[7]: https://opensource.com/article/20/2/open-source-homebank
|
||||
[8]: https://opensource.com/article/20/7/godbledger
|
||||
[9]: https://opensource.com/article/20/3/open-source-writing-tools
|
||||
[10]: https://opensource.com/article/20/2/open-source-qa
|
@ -0,0 +1,153 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Why I rewrote my open source virtual reality server)
|
||||
[#]: via: (https://opensource.com/article/20/12/virtual-reality-server)
|
||||
[#]: author: (Josip Almasi https://opensource.com/users/jalmasi)
|
||||
|
||||
Why I rewrote my open source virtual reality server
|
||||
======
|
||||
With VRSpace, you can play group VR games across platforms without
|
||||
sacrificing your privacy.
|
||||
![new techie gadgets representing innovation][1]
|
||||
|
||||
Look! I wrote a virtual reality (VR) server and [published it on GitHub][2]! But _why_?
|
||||
|
||||
Well, I'm your typical introverted hacker. I like to play with technology. Whenever something new comes out, I have to lay my hands on it and get them dirty. So, when I gifted myself Oculus Quest last year, I played a few games before I wanted to code something myself. And guess what? _Everything is_ _proprietary!_
|
||||
|
||||
Alright, this may be a bit of an overstatement. But my overall impression of the VR industry is exactly that—it's all proprietary! Hardware and software vendors are trying to lock developers in to sell more devices and development tools than their competitors—deja vu, like the Unix wars in the last century.
|
||||
|
||||
![VRSpace.org][3]
|
||||
|
||||
Choosing an avatar and portals to virtual spaces. ([Gileon][4], [hong227][5], [Jasna Almasi][6], [CC BY-SA 4.0][7])
|
||||
|
||||
But welcome to the 21st century; we live in clouds now! Clouds take all our data and store it somewhere safe at the cloud owner's mercy. Take Oculus Quest 2, for instance. You can't even use it without a Facebook account. But once you do, all your data goes to Facebook.
|
||||
|
||||
What kind of data? _Biometric_ _data_.
|
||||
|
||||
VR devices track our movements, know our real-world height, and more. GDPR and other privacy laws include this type of biometric data in the highest security categories. Rightfully so, as this data enables the worst kind of privacy invasions. Imagine, for instance, a deepfake that mimics your every movement.
|
||||
|
||||
I'm using Facebook as an example, but the risks are the same with any private organization whose code cannot be scrutinized.
|
||||
|
||||
### Building an open, interoperable VR server
|
||||
|
||||
Privacy is but one of my motivations for writing a VR server; the other is my family.
|
||||
|
||||
My kids play together in real life, and they also want to play together in VR. I have another VR headset, an Acer OJO, but that exists in a different world of Windows Mixed Reality from an Oculus. Once again, vendor lock-in gets in the way. For my kids to play VR together, we'd need two Microsoft or two Facebook headsets.
|
||||
|
||||
But there's a way out.
|
||||
|
||||
Enter the [WebXR][8] Device API. This [open source][9] specification "describes support for accessing virtual reality (VR) and augmented reality (AR) devices, including sensors and head-mounted displays, on the web." It's VR and AR (summarized by _X_) that works on every device, just as the web has to work on any device—including mobile devices.
|
||||
|
||||
WebXR includes a [WebGL layer][10], and there are a number of JavaScript libraries (such as Three.js) to help developers working with WebGL and a full-featured open source game engine, BabylonJS. (Three.js fans might want to try [CS1 Game Engine][11], a promising yet unfinished library with performance and developer experience as top priorities.)
|
||||
|
||||
The tools also interoperate with popular web development frameworks like Angular and React. There's also [glTF][12], an open standard for 3D models that pretty much every relevant tool reads and writes, as well as an incredible number of open source 3D models that are mostly published under Creative Commons Attribution licenses.
|
||||
|
||||
The only thing missing was a server. One that would deliver content (models) and presentation logic (JavaScript), collect and distribute user events, and implement business (game) logic, but _would not store any sensitive data_.
|
||||
|
||||
It just happens that 20 years ago, I wrote an open source VR server named [VRSpace][13]. Unfortunately, it was way too early for its own good, and the project died along with the client technology ([VRML][14]). But I knew exactly what I needed to do for today's VR, so I wrote it again. And luckily, it's much easier to do with modern technologies.
|
||||
|
||||
![Old VRSpace][15]
|
||||
|
||||
Twenty years ago, VRSpace.org was a chat with a chatbot. ([Arni Barisic][16], Slaven Katic, Josip Almasi, [CC BY-SA 4.0][7])
|
||||
|
||||
Rather than reflecting on the good ol' times and 20 years of technology gap, I'll talk about some of the design choices I made and the open source tools I used.
|
||||
|
||||
### Two decades later: Java and JavaScript
|
||||
|
||||
I chose Java and [Spring Boot][17] simply because I use them daily. But truth be told, Node.js might be a better tool for this job, as it is easier to develop and maintain software written in one language than two. For the client side, I chose [BabylonJS][18], because it's a full-featured WebXR game engine and plain JavaScript, and I didn't want the client to depend on a user interface (UI) framework.
|
||||
|
||||
BabylonJS is written in TypeScript, so if I wanted to make a monolithic product, I'd go with TypeScript. On the other hand, I don't want to enforce any specific technology on the client side. Web browsers are not the only kind of client that will want to interact in VR, and native apps usually give the best performance.
|
||||
|
||||
The communication layer doesn't depend on anything else, which may be relevant if you want to implement your own VR client or a headless client like a chatbot.
|
||||
|
||||
To store the data, I chose the [Neo4J][19] database, which turned out to be as good as it gets. It can be embedded into my server and store all of my objects. Except for sensitive ones, of course, so I took special care to mark every sensitive field as transient. If I didn't care about this, you couldn't trust my server to protect your private data against nosy government institutions or criminals looking to steal valuable biometric data.
|
||||
|
||||
Communication happens with JSON over WebSockets—because it just works. Protocol-wise, it's far from the best choice. The sheer number of events emitted from VR device sensors is much higher than your usual first-person shooter; VR gear tracks your arms and head, various buttons and joysticks, possibly even eye movements, and every finger. Rate limiting is a must-have no matter what.
|
||||
|
||||
But what about chat? VR devices don't have keyboards, nor do mobile devices once they're head-mounted as VR gear. Virtual keyboards inside VR are not very useful, and they're certainly useless for chat. So voice chat seems the only option. Luckily, there's an open source chat server called [OpenVidu][20]. I made my server talk to that server so that people can chat with each other.
|
||||
|
||||
Last but not least, security. Embedding a script into a JSON string is trivial, and to prevent cross-site scripting attacks, the server must, at a minimum, sanitize each and every incoming request.
|
||||
|
||||
![VRSpace architecture][21]
|
||||
|
||||
(Josip Almasi, [CC BY-SA 4.0][7])
|
||||
|
||||
### Wide-open virtual spaces
|
||||
|
||||
People need open spaces every once in a while, just to keep their sanity. Prisoners get at least an hour outside every day. NASA expects astronauts to be able to endure long periods of confinement. But ordinary people just can't stand being inside all the time.
|
||||
|
||||
I've been rather confined for months now, but VR to the rescue! Making a virtual space requires spending endless hours trying out different models and backgrounds and doing much more testing. For physical and mental health, it's not as good as the real stuff, but it's good enough to keep people sane.
|
||||
|
||||
![VRSpace.org virtual worlds][22]
|
||||
|
||||
VRSpace.org virtual worlds created by [farhad.Guli][23], [anthwolf][24], [fenixman12][25], [ShadowTan][26], [Binkley-Spacetrucker][27], and [exima113][28] (Josip Almasi, [CC BY-SA 4.0][7])
|
||||
|
||||
Now that I've written the server, my kids can finally play hide and seek together in any virtual world they choose, with my wife and me alongside them—two VR headsets, a PC, and a mobile, all playing together. So far, we can only play hide and seek because there are not any other games yet. We started playing a "make a game" game; so far, we have a game map, the first level, and of course, zombies.
|
||||
|
||||
But what's the point of having software that nobody uses? My first VR server was not widely used, but it was used by people all over the world. I remember some students in Korea and a girl in Uruguay sitting on her daddy's lap, enchanted by dolphins flying through a virtual replica of a far-away city.
|
||||
|
||||
But my best memory is being told, "programmers like you are benefactors of humanity." This is what open source is all about: benefiting humanity. Not just me, not just my family, not just paying customers, not just my company, but anybody, anywhere and possibly everybody, everywhere.
|
||||
|
||||
And that is why I wrote that VR server again and [published it on GitHub][2].
|
||||
|
||||
### Get involved
|
||||
|
||||
I'm running a [demo server][29] of the current code, available to anyone anonymously. I installed a [Redmine][30] server on it; it has a wiki, forums, bug reports, and everything, so if you want to collaborate or just get in touch, see you [there][31] and on [GitHub][2]!
|
||||
|
||||
I also made a [YouTube channel][32] for demos and tutorials and made a few movies (with another open source tool called [Shotcut][33]). [This video][34] explains all of the project's features at a glance. And I made a [Facebook page][35] because literally everybody knows about Facebook.
|
||||
|
||||
I hope to see you in the virtual worlds, so stay safe and have fun!
|
||||
|
||||
Mozilla's MozVR is a new technology that combines the open web and virtual reality, enabling...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/virtual-reality-server
|
||||
|
||||
作者:[Josip Almasi][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/jalmasi
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/innovation_virtual_gadgets_device_drone.png?itok=JTAgRb-1 (new techie gadgets representing innovation)
|
||||
[2]: https://github.com/jalmasi/vrspace
|
||||
[3]: https://opensource.com/sites/default/files/uploads/vrspace.png (VRSpace.org)
|
||||
[4]: https://sketchfab.com/gileon
|
||||
[5]: https://sketchfab.com/hong227
|
||||
[6]: https://www.linkedin.com/in/jasna-almasi/
|
||||
[7]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[8]: https://www.w3.org/TR/webxr/
|
||||
[9]: https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
||||
[10]: https://www.w3.org/TR/webxr/#xrwebgllayer-interface
|
||||
[11]: https://github.com/EricEisaman/cs1-engine
|
||||
[12]: https://en.wikipedia.org/wiki/GlTF
|
||||
[13]: http://old.vrspace.org/
|
||||
[14]: https://en.wikipedia.org/wiki/VRML
|
||||
[15]: https://opensource.com/sites/default/files/uploads/vrspace_old.jpg (Old VRSpace)
|
||||
[16]: https://www.facebook.com/arni.barisic
|
||||
[17]: https://spring.io/projects/spring-boot
|
||||
[18]: https://www.babylonjs.com/
|
||||
[19]: https://neo4j.com/
|
||||
[20]: https://openvidu.io/
|
||||
[21]: https://opensource.com/sites/default/files/uploads/vrspace_architecture.png (VRSpace architecture)
|
||||
[22]: https://opensource.com/sites/default/files/uploads/virtualworlds.png (VRSpace.org virtual worlds)
|
||||
[23]: https://sketchfab.com/farhad.Guli
|
||||
[24]: https://sketchfab.com/anthmurphy
|
||||
[25]: https://sketchfab.com/fenixman12
|
||||
[26]: https://sketchfab.com/ShadowTan
|
||||
[27]: https://sketchfab.com/Binkley-Piratepants
|
||||
[28]: https://sketchfab.com/Exima113
|
||||
[29]: http://www.vrspace.org/
|
||||
[30]: https://redmine.org/
|
||||
[31]: https://redmine.vrspace.org/
|
||||
[32]: https://www.youtube.com/channel/UCLdSg22i9MZ3u7ityj_PBxw
|
||||
[33]: https://shotcut.org/
|
||||
[34]: https://vrdays.co/videos/vrspace-org-diy-multiuser-vr-for-the-web/
|
||||
[35]: https://www.facebook.com/vrspace.org
|
@ -0,0 +1,96 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (9 insights from pivoting to remote work in 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/remote-work)
|
||||
[#]: author: (Dawn Parzych https://opensource.com/users/dawnparzych)
|
||||
|
||||
9 insights from pivoting to remote work in 2020
|
||||
======
|
||||
Remote work is now standard for many companies and workers. Here is a
|
||||
roundup from this year's lessons learned in remote work.
|
||||
![Selfcare, calm routine][1]
|
||||
|
||||
2020 was the year remote work became the norm. Due to the COVID-19 pandemic, people and companies shifted to "temporary" remote work, though many have now extended it indefinitely. As remote work will be the norm for the foreseeable future, here’s a review of some of the many articles published on Opensource.com regarding remote work practices, tools, and activities to manage this new normal.
|
||||
|
||||
### Tools
|
||||
|
||||
When shifting the way we work, we also need to look at the tools we use. Tools that work in person may not be as effective in a remote world. We need to look for new and different ways of sharing information. The articles below highlight some of the tools that come in handy for remote work.
|
||||
|
||||
#### [Top 10 open source tools for working from home][2]
|
||||
|
||||
We rely on tools on a daily basis. Working remotely requires adding new tools to our belt. Here, Seth shares his top 10 communication and collaboration tools. If you’re looking to up your collaboration game, check out this article for suggestions on:
|
||||
|
||||
* Video conferencing and chat
|
||||
* Virtual whiteboards
|
||||
* Virtual notebooks
|
||||
* Shared documents, spreadsheets, and storage
|
||||
|
||||
|
||||
|
||||
#### [Is it possible to run a conference using only free software?][3]
|
||||
|
||||
Not only did employers and employees have to figure out how to support a remote workforce, but industry conferences and tradeshows had to be reimagined for the virtual world. The value in a conference isn’t only the talks; it’s also in the interaction with others, open spaces, and the hallway track. Zoe shares how the [Free Software Foundation][4] took LibrePlanet fully virtual using open source software and what they would improve upon for future events.
|
||||
|
||||
#### [How to set up a remote school environment for kids with Linux][5]
|
||||
|
||||
For those of you who have kids returning to remote learning from in-person learning, this one is for you. Alan shares how he took an unused computer to create a system suitable for full-time remote school. You don’t need the latest and greatest hardware due to the efficiency of the Linux operating system; even a 10-year-old laptop can get the job done.
|
||||
|
||||
### Activities
|
||||
|
||||
Whether you’re looking for a side project or something to do outside of work, the articles highlighted below may help motivate you to try something new.
|
||||
|
||||
#### [6 open source teaching tools for virtual classrooms][6]
|
||||
|
||||
The tools Mathias mentions aren’t just for virtual classrooms. Want to start a podcast? Create YouTube videos? How about live stream your coding adventures? These tools can help you get started—topics range from how to record with Open Broadcaster Studio to audio and video editing. If you’re looking for a new activity, check out the tools in this article for inspiration.
|
||||
|
||||
#### [5 open source activities while you work from home][7]
|
||||
|
||||
We all need a break from our computers. I’ve heard a lot of people talk about Zoom fatigue as they stare at a screen all day and then into the evenings for social gatherings, community events, or virtual classes. Seth’s article highlights several things you can do to take a break from the computer.
|
||||
|
||||
#### [Create web tutorials with Reveal.js and Git][8]
|
||||
|
||||
You might be thinking, "what does creating a web tutorial have to do with remote work?" Many in-person workshops, customer training, and internal trainings have also shifted online. With people working asynchronously, it can be impossible to find a single time convenient for everybody to participate. Creating a self-paced tutorial or workshop may be the answer. Here, Eric shares the process and tools he uses to create online self-paced workshops, including examples.
|
||||
|
||||
### Practices
|
||||
|
||||
We should always be looking for new ways of doing things. These articles share insights into how you can improve your teams’ operations. Sometimes a fresh idea or insight can break us out of a rut. What "new-to-you" suggestion can you incorporate into your daily work?
|
||||
|
||||
#### [7 ways not to manage your remote team][9]
|
||||
|
||||
Many of these articles focus on what an individual can do, which is good, but good remote practices start at the top. This article covers how NOT to manage a remote team. Matt’s insight is a must-read for anybody who is currently a manager or looking to move into a management role in 2021.
|
||||
|
||||
#### [Love or hate chat? 4 best practices for remote teams][10]
|
||||
|
||||
Every company (and every person, for that matter) has its own preference when it comes to chat. Chat doesn’t have to be synchronous; it can be effectively asynchronous, as long as everybody is aware of the expectations and norms. Jen discusses four areas where teams should define the rules of chat to ensure everybody’s needs surrounding chat-based communication are met.
|
||||
|
||||
#### [5 tips for working from home from a veteran remotee][11]
|
||||
|
||||
You may think that you're an expert after months of working remotely, but there is always still room to learn. And maybe some of the habits you initially put in place have now taken a back seat several months later. It’s time to look again at ways to improve your day-to-day. I’ve worked remotely for years, and I still found valuable tips in Birthe’s article on working remotely. The structure for the daily and weekly meetings is a great way to keep meetings focused and on track.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/remote-work
|
||||
|
||||
作者:[Dawn Parzych][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/dawnparzych
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/meditate_zen_wfh_outside_family_selfcare_520.png?itok=qoSXLqRw (Selfcare, calm routine)
|
||||
[2]: https://opensource.com/article/20/3/open-source-working-home
|
||||
[3]: https://opensource.com/article/20/5/conference-free-software
|
||||
[4]: https://www.fsf.org/
|
||||
[5]: https://opensource.com/article/20/4/school-home-linux
|
||||
[6]: https://opensource.com/article/20/4/open-source-remote-teaching-tools
|
||||
[7]: https://opensource.com/article/20/4/open-source-activities
|
||||
[8]: https://opensource.com/article/20/4/create-web-tutorial-git
|
||||
[9]: https://opensource.com/article/20/1/ways-not-manage-remote-team
|
||||
[10]: https://opensource.com/article/20/4/chat-tools-best-practices
|
||||
[11]: https://opensource.com/article/20/4/home-office-tips
|
@ -1,443 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (gxlct008)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Go channels are bad and you should feel bad)
|
||||
[#]: via: (https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-should-feel-bad)
|
||||
[#]: author: (jtolio.com https://www.jtolio.com/)
|
||||
|
||||
Go channels are bad and you should feel bad
|
||||
======
|
||||
|
||||
_Update: If you’re coming to this blog post from a compendium titled “Go is not good,” I want to make it clear that I am ashamed to be on such a list. Go is absolutely the least worst programming language I’ve ever used. At the time I wrote this, I wanted to curb a trend I was seeing, namely, overuse of one of the more warty parts of Go. I still think channels could be much better, but overall, Go is wonderful. It’s like if your favorite toolbox had [this][1] in it; the tool can have uses (even if it could have had more uses), and it can still be your favorite toolbox!_
|
||||
|
||||
_Update 2: I would be remiss if I didn’t point out this excellent survey of real issues: [Understanding Real-World Concurrency Bugs In Go][2]. A significant finding of this survey is that… Go channels cause lots of bugs._
|
||||
|
||||
I’ve been using Google’s [Go programming language][3] on and off since mid-to-late 2010, and I’ve had legitimate product code written in Go for [Space Monkey][4] since January 2012 (before Go 1.0!). My initial experience with Go was back when I was researching Hoare’s [Communicating Sequential Processes][5] model of concurrency and the [π-calculus][6] under [Matt Might][7]’s [UCombinator research group][8] as part of my ([now redirected][9]) PhD work to better enable multicore development. Go was announced right then (how serendipitous!) and I immediately started kicking tires.
|
||||
|
||||
It quickly became a core part of Space Monkey development. Our production systems at Space Monkey currently account for over 425k lines of pure Go (_not_ counting all of our vendored libraries, which would make it just shy of 1.5 million lines), so not the most Go you’ll ever see, but for the relatively young language we’re heavy users. We’ve [written about our Go usage][10] before. We’ve open-sourced some fairly heavily used libraries; many people seem to be fans of our [OpenSSL bindings][11] (which are faster than [crypto/tls][12], but please keep openssl itself up-to-date!), our [error handling library][13], [logging library][14], and [metric collection library/zipkin client][15]. We use Go, we love Go, we think it’s the least bad programming language for our needs we’ve used so far.
|
||||
|
||||
Although I don’t think I can talk myself out of mentioning my widely avoided [goroutine-local-storage library][16] here either (which even though it’s a hack that you shouldn’t use, it’s a beautiful hack), hopefully my other experience will suffice as valid credentials that I kind of know what I’m talking about before I explain my deliberately inflamatory post title.
|
||||
|
||||
![][17]
|
||||
|
||||
### Wait, what?
|
||||
|
||||
If you ask the proverbial programmer on the street what’s so special about Go, she’ll most likely tell you that Go is most known for channels and goroutines. Go’s theoretical underpinnings are heavily based in Hoare’s CSP model, which is itself incredibly fascinating and interesting and I firmly believe has much more to yield than we’ve appropriated so far.
|
||||
|
||||
CSP (and the π-calculus) both use communication as the core synchronization primitive, so it makes sense Go would have channels. Rob Pike has been fascinated with CSP (with good reason) for a [considerable][18] [while][19] [now][20].
|
||||
|
||||
But from a pragmatic perspective (which Go prides itself on), Go got channels wrong. Channels as implemented are pretty much a solid anti-pattern in my book at this point. Why? Dear reader, let me count the ways.
|
||||
|
||||
#### You probably won’t end up using just channels.
|
||||
|
||||
Hoare’s Communicating Sequential Processes is a computational model where essentially the only synchronization primitive is sending or receiving on a channel. As soon as you use a mutex, semaphore, or condition variable, bam, you’re no longer in pure CSP land. Go programmers often tout this model and philosophy through the chanting of the [cached thought][21] “[share memory by communicating][22].”
|
||||
|
||||
So let’s try and write a small program using just CSP in Go! Let’s make a high score receiver. All we will do is keep track of the largest high score value we’ve seen. That’s it.
|
||||
|
||||
First, we’ll make a `Game` struct.
|
||||
|
||||
```
|
||||
type Game struct {
|
||||
bestScore int
|
||||
scores chan int
|
||||
}
|
||||
```
|
||||
|
||||
`bestScore` isn’t going to be protected by a mutex! That’s fine, because we’ll simply have one goroutine manage its state and receive new scores over a channel.
|
||||
|
||||
```
|
||||
func (g *Game) run() {
|
||||
for score := range g.scores {
|
||||
if g.bestScore < score {
|
||||
g.bestScore = score
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Okay, now we’ll make a helpful constructor to start a game.
|
||||
|
||||
```
|
||||
func NewGame() (g *Game) {
|
||||
g = &Game{
|
||||
bestScore: 0,
|
||||
scores: make(chan int),
|
||||
}
|
||||
go g.run()
|
||||
return g
|
||||
}
|
||||
```
|
||||
|
||||
Next, let’s assume someone has given us a `Player` that can return scores. It might also return an error, cause hey maybe the incoming TCP stream can die or something, or the player quits.
|
||||
|
||||
```
|
||||
type Player interface {
|
||||
NextScore() (score int, err error)
|
||||
}
|
||||
```
|
||||
|
||||
To handle the player, we’ll assume all errors are fatal and pass received scores down the channel.
|
||||
|
||||
```
|
||||
func (g *Game) HandlePlayer(p Player) error {
|
||||
for {
|
||||
score, err := p.NextScore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.scores <- score
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Yay! Okay, we have a `Game` type that can keep track of the highest score a `Player` receives in a thread-safe way.
|
||||
|
||||
You wrap up your development and you’re on your way to having customers. You make this game server public and you’re incredibly successful! Lots of games are being created with your game server.
|
||||
|
||||
Soon, you discover people sometimes leave your game. Lots of games no longer have any players playing, but nothing stopped the game loop. You are getting overwhelmed by dead `(*Game).run` goroutines.
|
||||
|
||||
**Challenge:** fix the goroutine leak above without mutexes or panics. For real, scroll up to the above code and come up with a plan for fixing this problem using just channels.
|
||||
|
||||
I’ll wait.
|
||||
|
||||
For what it’s worth, it totally can be done with channels only, but observe the simplicity of the following solution which doesn’t even have this problem:
|
||||
|
||||
```
|
||||
type Game struct {
|
||||
mtx sync.Mutex
|
||||
bestScore int
|
||||
}
|
||||
|
||||
func NewGame() *Game {
|
||||
return &Game{}
|
||||
}
|
||||
|
||||
func (g *Game) HandlePlayer(p Player) error {
|
||||
for {
|
||||
score, err := p.NextScore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.mtx.Lock()
|
||||
if g.bestScore < score {
|
||||
g.bestScore = score
|
||||
}
|
||||
g.mtx.Unlock()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Which one would you rather work on? Don’t be deceived into thinking that the channel solution somehow makes this more readable and understandable in more complex cases. Teardown is very hard. This sort of teardown is just a piece of cake with a mutex, but the hardest thing to work out with Go-specific channels only. Also, if anyone replies that channels sending channels is easier to reason about here it will cause me an immediate head-to-desk motion.
|
||||
|
||||
Importantly, this particular case might actually be _easily_ solved _with channels_ with some runtime assistance Go doesn’t provide! Unfortunately, as it stands, there are simply a surprising amount of problems that are solved better with traditional synchronization primitives than with Go’s version of CSP. We’ll talk about what Go could have done to make this case easier later.
|
||||
|
||||
**Exercise:** Still skeptical? Try making both solutions above (channel-only vs. mutex-only) stop asking for scores from `Players` once `bestScore` is 100 or greater. Go ahead and open your text editor. This is a small, toy problem.
|
||||
|
||||
The summary here is that you will be using traditional synchronization primitives in addition to channels if you want to do anything real.
|
||||
|
||||
#### Channels are slower than implementing it yourself
|
||||
|
||||
One of the things I assumed about Go being so heavily based in CSP theory is that there should be some pretty killer scheduler optimizations the runtime can make with channels. Perhaps channels aren’t always the most straightforward primitive, but surely they’re efficient and fast, right?
|
||||
|
||||
![][23]
|
||||
|
||||
As [Dustin Hiatt][24] points out on [Tyler Treat’s post about Go][25],
|
||||
|
||||
> Behind the scenes, channels are using locks to serialize access and provide threadsafety. So by using channels to synchronize access to memory, you are, in fact, using locks; locks wrapped in a threadsafe queue. So how do Go’s fancy locks compare to just using mutex’s from their standard library `sync` package? The following numbers were obtained by using Go’s builtin benchmarking functionality to serially call Put on a single set of their respective types.
|
||||
|
||||
```
|
||||
> BenchmarkSimpleSet-8 3000000 391 ns/op
|
||||
> BenchmarkSimpleChannelSet-8 1000000 1699 ns/o
|
||||
>
|
||||
```
|
||||
|
||||
It’s a similar story with unbuffered channels, or even the same test under contention instead of run serially.
|
||||
|
||||
Perhaps the Go scheduler will improve, but in the meantime, good old mutexes and condition variables are very good, efficient, and fast. If you want performance, you use the tried and true methods.
|
||||
|
||||
#### Channels don’t compose well with other concurrency primitives
|
||||
|
||||
Alright, so hopefully I have convinced you that you’ll at least be interacting with primitives besides channels sometimes. The standard library certainly seems to prefer traditional synchronization primitives over channels.
|
||||
|
||||
Well guess what, it’s actually somewhat challenging to use channels alongside mutexes and condition variables correctly!
|
||||
|
||||
One of the interesting things about channels that makes a lot of sense coming from CSP is that channel sends are synchronous. A channel send and channel receive are intended to be synchronization barriers, and the send and receive should happen at the same virtual time. That’s wonderful if you’re in well-executed CSP-land.
|
||||
|
||||
![][26]
|
||||
|
||||
Pragmatically, Go channels also come in a buffered variety. You can allocate a fixed amount of space to account for possible buffering so that sends and receives are disparate events, but the buffer size is capped. Go doesn’t provide a way to have arbitrarily sized buffers - you have to allocate the buffer size in advance. _This is fine_, I’ve seen people argue on the mailing list, _because memory is bounded anyway._
|
||||
|
||||
Wat.
|
||||
|
||||
This is a bad answer. There’s all sorts of reasons to use an arbitrarily buffered channel. If we knew everything up front, why even have `malloc`?
|
||||
|
||||
Not having arbitrarily buffered channels means that a naive send on _any_ channel could block at any time. You want to send on a channel and update some other bookkeeping under a mutex? Careful! Your channel send might block!
|
||||
|
||||
```
|
||||
// ...
|
||||
s.mtx.Lock()
|
||||
// ...
|
||||
s.ch <- val // might block!
|
||||
s.mtx.Unlock()
|
||||
// ...
|
||||
```
|
||||
|
||||
This is a recipe for dining philosopher dinner fights. If you take a lock, you should quickly update state and release it and not do anything blocking under the lock if possible.
|
||||
|
||||
There is a way to do a non-blocking send on a channel in Go, but it’s not the default behavior. Assume we have a channel `ch := make(chan int)` and we want to send the value `1` on it without blocking. Here is the minimum amount of typing you have to do to send without blocking:
|
||||
|
||||
```
|
||||
select {
|
||||
case ch <- 1: // it sent
|
||||
default: // it didn't
|
||||
}
|
||||
```
|
||||
|
||||
This isn’t what naturally leaps to mind for beginning Go programmers.
|
||||
|
||||
The summary is that because many operations on channels block, it takes careful reasoning about philosophers and their dining to successfully use channel operations alongside and under mutex protection, without causing deadlocks.
|
||||
|
||||
#### Callbacks are strictly more powerful and don’t require unnecessary goroutines.
|
||||
|
||||
![][27]
|
||||
|
||||
Whenever an API uses a channel, or whenever I point out that a channel makes something hard, someone invariably points out that I should just spin up a goroutine to read off the channel and make whatever translation or fix I need as it reads of the channel.
|
||||
|
||||
Um, no. What if my code is in a hotpath? There’s very few instances that require a channel, and if your API could have been designed with mutexes, semaphores, and callbacks and no additional goroutines (because all event edges are triggered by API events), then using a channel forces me to add another stack of memory allocation to my resource usage. Goroutines are much lighter weight than threads, yes, but lighter weight doesn’t mean the lightest weight possible.
|
||||
|
||||
As I’ve formerly [argued in the comments on an article about using channels][28] (lol the internet), your API can _always_ be more general, _always_ more flexible, and take drastically less resources if you use callbacks instead of channels. “Always” is a scary word, but I mean it here. There’s proof-level stuff going on.
|
||||
|
||||
If someone provides a callback-based API to you and you need a channel, you can provide a callback that sends on a channel with little overhead and full flexibility.
|
||||
|
||||
If, on the other hand, someone provides a channel-based API to you and you need a callback, you have to spin up a goroutine to read off the channel _and_ you have to hope that no one tries to send more on the channel when you’re done reading so you cause blocked goroutine leaks.
|
||||
|
||||
For a super simple real-world example, check out the [context interface][29] (which incidentally is an incredibly useful package and what you should be using instead of [goroutine-local storage][16]):
|
||||
|
||||
```
|
||||
type Context interface {
|
||||
...
|
||||
// Done returns a channel that closes when this work unit should be canceled.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err returns a non-nil error when the Done channel is closed
|
||||
Err() error
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Imagine all you want to do is log the corresponding error when the `Done()` channel fires. What do you have to do? If you don’t have a good place you’re already selecting on a channel, you have to spin up a goroutine to deal with it:
|
||||
|
||||
```
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
logger.Errorf("canceled: %v", ctx.Err())
|
||||
}()
|
||||
```
|
||||
|
||||
What if `ctx` gets garbage collected without closing the channel `Done()` returned? Whoops! Just leaked a goroutine!
|
||||
|
||||
Now imagine we changed `Done`’s signature:
|
||||
|
||||
```
|
||||
// Done calls cb when this work unit should be canceled.
|
||||
Done(cb func())
|
||||
```
|
||||
|
||||
First off, logging is so easy now. Check it out: `ctx.Done(func() { log.Errorf("canceled: %v", ctx.Err()) })`. But lets say you really do need some select behavior. You can just call it like this:
|
||||
|
||||
```
|
||||
ch := make(chan struct{})
|
||||
ctx.Done(func() { close(ch) })
|
||||
```
|
||||
|
||||
Voila! No expressiveness lost by using a callback instead. `ch` works like the channel `Done()` used to return, and in the logging case we didn’t need to spin up a whole new stack. I got to keep my stack traces (if our log package is inclined to use them); I got to avoid another stack allocation and another goroutine to give to the scheduler.
|
||||
|
||||
Next time you use a channel, ask yourself if there’s some goroutines you could eliminate if you used mutexes and condition variables instead. If the answer is yes, your code will be more efficient if you change it. And if you’re trying to use channels just to be able to use the `range` keyword over a collection, I’m going to have to ask you to put your keyboard away or just go back to writing Python books.
|
||||
|
||||
![more like Zooey De-channel, amirite][30]
|
||||
|
||||
#### The channel API is inconsistent and just cray-cray
|
||||
|
||||
Closing or sending on a closed channel panics! Why? If you want to close a channel, you need to either synchronize its closed state externally (with mutexes and so forth that don’t compose well!) so that other writers don’t write to or close a closed channel, or just charge forward and close or write to closed channels and expect you’ll have to recover any raised panics.
|
||||
|
||||
This is such bizarre behavior. Almost every other operation in Go has a way to avoid a panic (type assertions have the `, ok =` pattern, for example), but with channels you just get to deal with it.
|
||||
|
||||
Okay, so when a send will fail, channels panic. I guess that makes some kind of sense. But unlike almost everything else with nil values, sending to a nil channel won’t panic. Instead, it will block forever! That’s pretty counter-intuitive. That might be useful behavior, just like having a can-opener attached to your weed-whacker might be useful (and found in Skymall), but it’s certainly unexpected. Unlike interacting with nil maps (which do implicit pointer dereferences), nil interfaces (implicit pointer dereferences), unchecked type assertions, and all sorts of other things, nil channels exhibit actual channel behavior, as if a brand new channel was just instantiated for this operation.
|
||||
|
||||
Receives are slightly nicer. What happens when you receive on a closed channel? Well, that works - you get a zero value. Okay that makes sense I guess. Bonus! Receives allow you to do a `, ok =`-style check if the channel was open when you received your value. Thank heavens we get `, ok =` here.
|
||||
|
||||
But what happens if you receive from a nil channel? _Also blocks forever!_ Yay! Don’t try and use the fact that your channel is nil to keep track of if you closed it!
|
||||
|
||||
### What are channels good for?
|
||||
|
||||
Of course channels are good for some things (they are a generic container after all), and there are certain things you can only do with them (`select`).
|
||||
|
||||
#### They are another special-cased generic datastructure
|
||||
|
||||
Go programmers are so used to arguments about generics that I can feel the PTSD coming on just by bringing up the word. I’m not here to talk about it so wipe the sweat off your brow and let’s keep moving.
|
||||
|
||||
Whatever your opinion of generics is, Go’s maps, slices, and channels are data structures that support generic element types, because they’ve been special-cased into the language.
|
||||
|
||||
In a language that doesn’t allow you to write your own generic containers, _anything_ that allows you to better manage collections of things is valuable. Here, channels are a thread-safe datastructure that supports arbitrary value types.
|
||||
|
||||
So that’s useful! That can save some boilerplate I suppose.
|
||||
|
||||
I’m having trouble counting this as a win for channels.
|
||||
|
||||
#### Select
|
||||
|
||||
The main thing you can do with channels is the `select` statement. Here you can wait on a fixed number of inputs for events. It’s kind of like epoll, but you have to know upfront how many sockets you’re going to be waiting on.
|
||||
|
||||
This is truly a useful language feature. Channels would be a complete wash if not for `select`. But holy smokes, let me tell you about the first time you decide you might need to select on multiple things but you don’t know how many and you have to use `reflect.Select`.
|
||||
|
||||
### How could channels be better?
|
||||
|
||||
It’s really tough to say what the most tactical thing the Go language team could do for Go 2.0 is (the Go 1.0 compatibility guarantee is good but hand-tying), but that won’t stop me from making some suggestions.
|
||||
|
||||
#### Select on condition variables!
|
||||
|
||||
We could just obviate the need for channels! This is where I propose we get rid of some sacred cows, but let me ask you this, how great would it be if you could select on any custom synchronization primitive? (A: So great.) If we had that, we wouldn’t need channels at all.
|
||||
|
||||
#### GC could help us?
|
||||
|
||||
In the very first example, we could easily solve the high score server cleanup with channels if we were able to use directionally-typed channel garbage collection to help us clean up.
|
||||
|
||||
![][31]
|
||||
|
||||
As you know, Go has directionally-typed channels. You can have a channel type that only supports reading (`<-chan`) and a channel type that only supports writing (`chan<-`). Great!
|
||||
|
||||
Go also has garbage collection. It’s clear that certain kinds of book keeping are just too onerous and we shouldn’t make the programmer deal with them. We clean up unused memory! Garbage collection is useful and neat.
|
||||
|
||||
So why not help clean up unused or deadlocked channel reads? Instead of having `make(chan Whatever)` return one bidirectional channel, have it return two single-direction channels (`chanReader, chanWriter := make(chan Type)`).
|
||||
|
||||
Let’s reconsider the original example:
|
||||
|
||||
```
|
||||
type Game struct {
|
||||
bestScore int
|
||||
scores chan<- int
|
||||
}
|
||||
|
||||
func run(bestScore *int, scores <-chan int) {
|
||||
// we don't keep a reference to a *Game directly because then we'd be holding
|
||||
// onto the send side of the channel.
|
||||
for score := range scores {
|
||||
if *bestScore < score {
|
||||
*bestScore = score
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewGame() (g *Game) {
|
||||
// this make(chan) return style is a proposal!
|
||||
scoreReader, scoreWriter := make(chan int)
|
||||
g = &Game{
|
||||
bestScore: 0,
|
||||
scores: scoreWriter,
|
||||
}
|
||||
go run(&g.bestScore, scoreReader)
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *Game) HandlePlayer(p Player) error {
|
||||
for {
|
||||
score, err := p.NextScore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.scores <- score
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If garbage collection closed a channel when we could prove no more values are ever coming down it, this solution is completely fixed. Yes yes, the comment in `run` is indicative of the existence of a rather large gun aimed at your foot, but at least the problem is easily solveable now, whereas it really wasn’t before. Furthermore, a smart compiler could probably make appropriate proofs to reduce the damage from said foot-gun.
|
||||
|
||||
#### Other smaller issues
|
||||
|
||||
* **Dup channels?** \- If we could use an equivalent of the `dup` syscall on channels, then we could also solve the multiple producer problem quite easily. Each producer could close their own `dup`-ed channel without ruining the other producers.
|
||||
* **Fix the channel API!** \- Close isn’t idempotent? Send on closed channel panics with no way to avoid it? Ugh!
|
||||
* **Arbitrarily buffered channels** \- If we could make buffered channels with no fixed buffer size limit, then we could make channels that don’t block.
|
||||
|
||||
|
||||
|
||||
### What do we tell people about Go then?
|
||||
|
||||
If you haven’t yet, please go take a look at my current favorite programming post: [What Color is Your Function][32]. Without being about Go specifically, this blog post much more eloquently than I could lays out exactly why goroutines are Go’s best feature (and incidentally one of the ways Go is better than Rust for some applications).
|
||||
|
||||
If you’re still writing code in a programming language that forces keywords like `yield` on you to get high performance, concurrency, or an event-driven model, you are living in the past, whether or not you or anyone else knows it. Go is so far one of the best entrants I’ve seen of languages that implement an M:N threading model that’s not 1:1, and dang that’s powerful.
|
||||
|
||||
So, tell folks about goroutines.
|
||||
|
||||
If I had to pick one other leading feature of Go, it’s interfaces. Statically-typed [duck typing][33] makes extending and working with your own or someone else’s project so fun and amazing it’s probably worth me writing an entirely different set of words about it some other time.
|
||||
|
||||
### So…
|
||||
|
||||
I keep seeing people charge in to Go, eager to use channels to their full potential. Here’s my advice to you.
|
||||
|
||||
**JUST STAHP IT**
|
||||
|
||||
When you’re writing APIs and interfaces, as bad as the advice “never” can be, I’m pretty sure there’s never a time where channels are better, and every Go API I’ve used that used channels I’ve ended up having to fight. I’ve never thought “oh good, there’s a channel here;” it’s always instead been some variant of _**WHAT FRESH HELL IS THIS?**_
|
||||
|
||||
So, _please, please use channels where appropriate and only where appropriate._
|
||||
|
||||
In all of my Go code I work with, I can count on one hand the number of times channels were really the best choice. Sometimes they are. That’s great! Use them then. But otherwise just stop.
|
||||
|
||||
![][34]
|
||||
|
||||
_Special thanks for the valuable feedback provided by my proof readers Jeff Wendling, [Andrew Harding][35], [George Shank][36], and [Tyler Treat][37]._
|
||||
|
||||
If you want to work on Go with us at Space Monkey, please [hit me up][38]!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-should-feel-bad
|
||||
|
||||
作者:[jtolio.com][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.jtolio.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://blog.codinghorror.com/content/images/uploads/2012/06/6a0120a85dcdae970b017742d249d5970d-800wi.jpg
|
||||
[2]: https://songlh.github.io/paper/go-study.pdf
|
||||
[3]: https://golang.org/
|
||||
[4]: http://www.spacemonkey.com/
|
||||
[5]: https://en.wikipedia.org/wiki/Communicating_sequential_processes
|
||||
[6]: https://en.wikipedia.org/wiki/%CE%A0-calculus
|
||||
[7]: http://matt.might.net
|
||||
[8]: http://www.ucombinator.org/
|
||||
[9]: https://www.jtolio.com/writing/2015/11/research-log-cell-states-and-microarrays/
|
||||
[10]: https://www.jtolio.com/writing/2014/04/go-space-monkey/
|
||||
[11]: https://godoc.org/github.com/spacemonkeygo/openssl
|
||||
[12]: https://golang.org/pkg/crypto/tls/
|
||||
[13]: https://godoc.org/github.com/spacemonkeygo/errors
|
||||
[14]: https://godoc.org/github.com/spacemonkeygo/spacelog
|
||||
[15]: https://godoc.org/gopkg.in/spacemonkeygo/monitor.v1
|
||||
[16]: https://github.com/jtolds/gls
|
||||
[17]: https://www.jtolio.com/images/wat/darth-helmet.jpg
|
||||
[18]: https://en.wikipedia.org/wiki/Newsqueak
|
||||
[19]: https://en.wikipedia.org/wiki/Alef_%28programming_language%29
|
||||
[20]: https://en.wikipedia.org/wiki/Limbo_%28programming_language%29
|
||||
[21]: https://lesswrong.com/lw/k5/cached_thoughts/
|
||||
[22]: https://blog.golang.org/share-memory-by-communicating
|
||||
[23]: https://www.jtolio.com/images/wat/jon-stewart.jpg
|
||||
[24]: https://twitter.com/HiattDustin
|
||||
[25]: http://bravenewgeek.com/go-is-unapologetically-flawed-heres-why-we-use-it/
|
||||
[26]: https://www.jtolio.com/images/wat/obama.jpg
|
||||
[27]: https://www.jtolio.com/images/wat/yael-grobglas.jpg
|
||||
[28]: http://www.informit.com/articles/article.aspx?p=2359758#comment-2061767464
|
||||
[29]: https://godoc.org/golang.org/x/net/context
|
||||
[30]: https://www.jtolio.com/images/wat/zooey-deschanel.jpg
|
||||
[31]: https://www.jtolio.com/images/wat/joel-mchale.jpg
|
||||
[32]: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
|
||||
[33]: https://en.wikipedia.org/wiki/Duck_typing
|
||||
[34]: https://www.jtolio.com/images/wat/michael-cera.jpg
|
||||
[35]: https://github.com/azdagron
|
||||
[36]: https://twitter.com/taterbase
|
||||
[37]: http://bravenewgeek.com
|
||||
[38]: https://www.jtolio.com/contact/
|
@ -1,185 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (3 Ways to Install Deb Files on Ubuntu Linux)
|
||||
[#]: via: (https://itsfoss.com/install-deb-files-ubuntu)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
3 Ways to Install Deb Files on Ubuntu Linux
|
||||
======
|
||||
|
||||
**This beginner article explains how to install deb packages in Ubuntu. It also shows you how to remove those deb packages afterwards.**
|
||||
|
||||
This is another article in the Ubuntu beginner series. If you are absolutely new to Ubuntu, you might wonder about [how to install applications][1].
|
||||
|
||||
The easiest way is to use the Ubuntu Software Center. Search for an application by its name and install it from there.
|
||||
|
||||
Life would be too simple if you could find all the applications in the Software Center. But that does not happen, unfortunately.
|
||||
|
||||
Some software are available via DEB packages. These are archived files that end with .deb extension.
|
||||
|
||||
You can think of .deb files as the .exe files in Windows. You double click on the .exe file and it starts the installation procedure in Windows. DEB packages are pretty much the same.
|
||||
|
||||
You can find these DEB packages from the download section of the software provider’s website. For example, if you want to [install Google Chrome on Ubuntu][2], you can download the DEB package of Chrome from its website.
|
||||
|
||||
Now the question arises, how do you install deb files? There are multiple ways of installing DEB packages in Ubuntu. I’ll show them to you one by one in this tutorial.
|
||||
|
||||
![Install deb files in Ubuntu][3]
|
||||
|
||||
### Installing .deb files in Ubuntu and Debian-based Linux Distributions
|
||||
|
||||
You can choose a GUI tool or a command line tool for installing a deb package. The choice is yours.
|
||||
|
||||
Let’s go on and see how to install deb files.
|
||||
|
||||
#### Method 1: Use the default Software Center
|
||||
|
||||
The simplest method is to use the default software center in Ubuntu. You have to do nothing special here. Simply go to the folder where you have downloaded the .deb file (it should be the Downloads folder) and double click on this file.
|
||||
|
||||
![Google Chrome deb file on Ubuntu][4]Double click on the downloaded .deb file to start installation
|
||||
|
||||
It will open the software center and you should see the option to install the software. All you have to do is to hit the install button and enter your login password.
|
||||
|
||||
![Install Google Chrome in Ubuntu Software Center][5]The installation of deb file will be carried out via Software Center
|
||||
|
||||
See, it’s even simple than installing from a .exe files on Windows, isn’t it?
|
||||
|
||||
#### Method 2: Use Gdebi application for installing deb packages with dependencies
|
||||
|
||||
Again, life would be a lot simpler if things always go smooth. But that’s not life as we know it.
|
||||
|
||||
Now that you know that .deb files can be easily installed via Software Center, let me tell you about the dependency error that you may encounter with some packages.
|
||||
|
||||
What happens is that a program may be dependent on another piece of software (libraries). When the developer is preparing the DEB package for you, he/she may assume that your system already has that piece of software on your system.
|
||||
|
||||
But if that’s not the case and your system doesn’t have those required pieces of software, you’ll encounter the infamous ‘dependency error’.
|
||||
|
||||
The Software Center cannot handle such errors on its own so you have to use another tool called [gdebi][6].
|
||||
|
||||
gdebi is a lightweight GUI application that has the sole purpose of installing deb packages.
|
||||
|
||||
It identifies the dependencies and tries to install these dependencies along with installing the .deb files.
|
||||
|
||||
![gdebi handling dependency while installing deb package][7]Image Credit: [Xmodulo][8]
|
||||
|
||||
Personally, I prefer gdebi over software center for installing deb files. It is a lightweight application so the installation seems quicker. You can read in detail about [using gDebi and making it the default for installing DEB packages][6].
|
||||
|
||||
You can install gdebi from the software center or using the command below:
|
||||
|
||||
```
|
||||
sudo apt install gdebi
|
||||
```
|
||||
|
||||
#### Method 3: Install .deb files in command line using dpkg
|
||||
|
||||
If you want to install deb packages in command lime, you can use either apt command or dpkg command. Apt command actually uses [dpkg command][9] underneath it but apt is more popular and easy to use.
|
||||
|
||||
If you want to use the apt command for deb files, use it like this:
|
||||
|
||||
```
|
||||
sudo apt install path_to_deb_file
|
||||
```
|
||||
|
||||
If you want to use dpkg command for installing deb packages, here’s how to do it:
|
||||
|
||||
```
|
||||
sudo dpkg -i path_to_deb_file
|
||||
```
|
||||
|
||||
In both commands, you should replace the path_to_deb_file with the path and name of the deb file you have downloaded.
|
||||
|
||||
![Install deb files using dpkg command in Ubuntu][10]Installing deb files using dpkg command in Ubuntu
|
||||
|
||||
If you get a dependency error while installing the deb packages, you may use the following command to fix the dependency issues:
|
||||
|
||||
```
|
||||
sudo apt install -f
|
||||
```
|
||||
|
||||
### How to remove deb packages
|
||||
|
||||
Removing a deb package is not a big deal as well. And no, you don’t need the original deb file that you had used for installing the program.
|
||||
|
||||
#### Method 1: Remove deb packages using apt commands
|
||||
|
||||
All you need is the name of the program that you have installed and then you can use apt or dpkg to remove that program.
|
||||
|
||||
```
|
||||
sudo apt remove program_name
|
||||
```
|
||||
|
||||
Now the question comes, how do you find the exact program name that you need to use in the remove command? The apt command has a solution for that as well.
|
||||
|
||||
You can find the list of all installed files with apt command but manually going through this will be a pain. So you can use the grep command to search for your package.
|
||||
|
||||
For example, I installed AppGrid application in the previous section but if I want to know the exact program name, I can use something like this:
|
||||
|
||||
```
|
||||
sudo apt list --installed | grep grid
|
||||
```
|
||||
|
||||
This will give me all the packages that have grid in their name and from there, I can get the exact program name.
|
||||
|
||||
```
|
||||
apt list --installed | grep grid
|
||||
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
|
||||
appgrid/now 0.298 all [installed,local]
|
||||
```
|
||||
|
||||
As you can see, a program called appgrid has been installed. Now you can use this program name with the apt remove command.
|
||||
|
||||
#### Method 2: Remove deb packages using dpkg commands
|
||||
|
||||
You can use dpkg to find the installed program’s name:
|
||||
|
||||
```
|
||||
dpkg -l | grep grid
|
||||
```
|
||||
|
||||
The output will give all the packages installed that has grid in its name.
|
||||
|
||||
```
|
||||
dpkg -l | grep grid
|
||||
|
||||
ii appgrid 0.298 all Discover and install apps for Ubuntu
|
||||
```
|
||||
|
||||
ii in the above command output means package has been correctly installed.
|
||||
|
||||
Now that you have the program name, you can use dpkg command to remove it:
|
||||
|
||||
```
|
||||
dpkg -r program_name
|
||||
```
|
||||
|
||||
**Tip: Updating deb packages**
|
||||
Some deb packages (like Chrome) provide updates through system updates but for most other programs, you’ll have to remove the existing program and install the newer version.
|
||||
|
||||
I hope this beginner guide helped you to install deb packages on Ubuntu. I added the remove part so that you’ll have better control over the programs you installed.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-deb-files-ubuntu
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/remove-install-software-ubuntu/
|
||||
[2]: https://itsfoss.com/install-chrome-ubuntu/
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/deb-packages-ubuntu.png?resize=800%2C450&ssl=1
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/install-google-chrome-ubuntu-4.jpeg?resize=800%2C347&ssl=1
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/install-google-chrome-ubuntu-5.jpeg?resize=800%2C516&ssl=1
|
||||
[6]: https://itsfoss.com/gdebi-default-ubuntu-software-center/
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/gdebi-handling-dependency.jpg?ssl=1
|
||||
[8]: http://xmodulo.com
|
||||
[9]: https://help.ubuntu.com/lts/serverguide/dpkg.html.en
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/install-deb-file-with-dpkg.png?ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/deb-packages-ubuntu.png?fit=800%2C450&ssl=1
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (zhangxiangping)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
@ -241,7 +241,7 @@ via: https://fedoramagazine.org/latex-typesetting-part-1/
|
||||
|
||||
作者:[Earl Ramirez][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[zhangxiangping](https://github.com/zxp93)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,113 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ()
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How the Linux kernel handles interrupts)
|
||||
[#]: via: (https://opensource.com/article/20/10/linux-kernel-interrupts)
|
||||
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
|
||||
|
||||
How the Linux kernel handles interrupts
|
||||
======
|
||||
Interrupts are a crucial part of how computers process data.
|
||||
![Penguin driving a car with a yellow background][1]
|
||||
|
||||
Interrupts are an essential part of how modern CPUs work. For example, every time you press a key on the keyboard, the CPU is interrupted so that the PC can read user input from the keyboard. This happens so quickly that you don't notice any change or impairment in user experience.
|
||||
|
||||
Moreover, the keyboard is not the only component that can cause interrupts. In general, there are three types of events that can cause the CPU to interrupt: _Hardware interrupts_, _software interrupts_, and _exceptions_. Before getting into the different types of interrupts, I'll define some terms.
|
||||
|
||||
### Definitions
|
||||
|
||||
An interrupt request (**IRQ**) is requested by the programmable interrupt controller (**PIC**) with the aim of interrupting the CPU and executing the interrupt service routine (**ISR**). The ISR is a small program that processes certain data depending on the cause of the IRQ. Normal processing is interrupted until the ISR finishes.
|
||||
|
||||
In the past, IRQs were handled by a separate microchip—the PIC—and I/O devices were wired directly to the PIC. The PIC managed the various hardware IRQs and could talk directly to the CPU. When an IRQ occurred, the PIC wrote the data to the CPU and raised the interrupt request (**INTR**) pin.
|
||||
|
||||
Nowadays, IRQs are handled by an advanced programmable interrupt controller (**APIC**), which is part of the CPU. Each core has its own APIC.
|
||||
|
||||
### Types of interrupts
|
||||
|
||||
As I mentioned, interrupts can be separated into three types depending on their source:
|
||||
|
||||
#### Hardware interrupts
|
||||
|
||||
When a hardware device wants to tell the CPU that certain data is ready to process (e.g., a keyboard entry or when a packet arrives at the network interface), it sends an IRQ to signal the CPU that the data is available. This invokes a specific ISR that was registered by the device driver during the kernel's start.
|
||||
|
||||
#### Software interrupts
|
||||
|
||||
When you're playing a video, it is essential to synchronize the music and video playback so that the music's speed doesn't vary. This is accomplished through a software interrupt that is repetitively fired by a precise timer system (known as [jiffies][2]). This timer enables your music player to synchronize. A software interrupt can also be invoked by a special instruction to read or write data to a hardware device.
|
||||
|
||||
Software interrupts are also crucial when real-time capability is required (such as in industrial applications). You can find more information about this in the Linux Foundation's article _[Intro to real-time Linux for embedded developers][3]_.
|
||||
|
||||
#### Exceptions
|
||||
|
||||
Exceptions are the type of interrupt that you probably know about. When the CPU executes a command that would result in division by zero or a page fault, any additional execution is interrupted. In such a case, you will be informed about it by a pop-up window or by seeing **segmentation fault (core dumped)** in the console output. But not every exception is caused by a faulty instruction.
|
||||
|
||||
Exceptions can be further divided into _Faults_, _Traps_, and _Aborts_.
|
||||
|
||||
* **Faults:** Faults are an exception that the system can correct, e.g., when a process tries to access data from a memory page that was swapped to the hard drive. The requested address is within the process address space, and the access rights are correct. If the page is not present in RAM, an IRQ is raised and it starts the **page fault exception handler** to load the desired memory page into RAM. If the operation is successful, execution will continue.
|
||||
* **Traps:** Traps are mainly used for debugging. If you set a breakpoint in a program, you insert a special instruction that causes it to trigger a trap. A trap can trigger a context switch that allows your debugger to read and display values of local variables. Execution can continue afterward. Traps are also the default way to execute system calls (like killing a process).
|
||||
* **Aborts:** Aborts are caused by hardware failure or inconsistent values in system tables. An abort does not report the location of the instruction that causes the exception. These are the most critical interrupts. An abort invokes the system's **abort exception handler**, which terminates the process that caused it.
|
||||
|
||||
|
||||
|
||||
### Get hands-on
|
||||
|
||||
IRQs are ordered by priority in a vector on the APIC (0=highest priority). The first 32 interrupts (0–31) have a fixed sequence that is specified by the CPU. You can find an overview of them on [OsDev's Exceptions][4] page. Subsequent IRQs can be assigned differently. The interrupt descriptor table (**IDT**) contains the assignment between IRQ and ISR. Linux defines an IRQ vector from 0 to 256 for the assignment.
|
||||
|
||||
To print a list of registered interrupts on your system, open a console and type:
|
||||
|
||||
|
||||
```
|
||||
`cat /proc/interrupts`
|
||||
```
|
||||
|
||||
You should see something like this:
|
||||
|
||||
![Registered interrupts list][5]
|
||||
|
||||
Registered interrupts in kernel version 5.6.6 (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
From left to right, the columns are: IRQ vector, interrupt count per CPU (`0 .. n`), the hardware source, the hardware source's channel information, and the name of the device that caused the IRQ.
|
||||
|
||||
On the bottom of the table, there are some non-numeric interrupts. They are the architecture-specific interrupts, like the local timer interrupt (**LOC**) on IRQ 236. Some of them are specified in the [Linux IRQ vector layout][7] in the Linux kernel source tree.
|
||||
|
||||
![Architecture-specific interrupts][8]
|
||||
|
||||
Architecture-specific interrupts (Stephan Avenwedde, [CC BY-SA 4.0][6])
|
||||
|
||||
To get a live view of this table, run:
|
||||
|
||||
|
||||
```
|
||||
`watch -n1 "cat /proc/interrupts"`
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
Proper IRQ handling is essential for the proper interaction of hardware, drivers, and software. Luckily, the Linux kernel does a really good job, and a normal PC user will hardly notice anything about the kernel's entire interrupt handling.
|
||||
|
||||
This can get very complicated, and this article gives only a brief overview of the topic. Good sources of information for a deeper dive into the subject are the _[Linux Inside][9]_ eBook (CC BY-NC-SA 4.0) and the [Linux Kernel Teaching][10] repository.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/10/linux-kernel-interrupts
|
||||
|
||||
作者:[Stephan Avenwedde][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/hansic99
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
|
||||
[2]: https://elinux.org/Kernel_Timer_Systems
|
||||
[3]: https://www.linuxfoundation.org/blog/2013/03/intro-to-real-time-linux-for-embedded-developers/
|
||||
[4]: https://wiki.osdev.org/Exceptions
|
||||
[5]: https://opensource.com/sites/default/files/uploads/proc_interrupts_1.png (Registered interrupts list)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/irq_vectors.h
|
||||
[8]: https://opensource.com/sites/default/files/uploads/proc_interrupts_2.png (Architecture-specific interrupts)
|
||||
[9]: https://0xax.gitbooks.io/linux-insides/content/Interrupts/
|
||||
[10]: https://linux-kernel-labs.github.io/refs/heads/master/lectures/interrupts.html#
|
@ -1,98 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get the most out of the Vi text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/vi-text-editor)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Get the most out of the Vi text editor
|
||||
======
|
||||
Vi is the quintessential Unix text editor. Get to know it—or any of its
|
||||
incarnations, Vim, Neovim, gVim, nvi, or Elvis, for Linux, macOS,
|
||||
Windows, or BSD.
|
||||
![Business woman on laptop sitting in front of window][1]
|
||||
|
||||
Whether you know it as Vim, Neovim, gVim, nvi, or even Elvis, the quintessential Unix editor is easily Vi. Included in probably every Linux and BSD distribution, Vi is a lightweight and minimalist text editor that many users love for its simple and succinct keyboard shortcuts and dual-mode design.
|
||||
|
||||
The original Vi editor was an application written by Bill Joy, creator of the [C shell][2]. Modern incarnations of Vi have [added many features][3], including multiple levels of undo, better navigation while in insert mode, line folding, syntax highlighting, plugin support, and much more. Vim is regarded as the most popular modern implementation, and most people actually mean Vim when they refer to Vi.
|
||||
|
||||
All incarnations hearken back to the same goal, though, so this article looks at Vi in a generic sense. The implementation on your computer may differ slightly, but you can still benefit from editing text the Vi way.
|
||||
|
||||
### Install Vi
|
||||
|
||||
If you're running Linux, macOS, or BSD, then you already have the `vi` command installed. If you're on Windows, you can [download Vim and gVim][4].
|
||||
|
||||
![gVim][5]
|
||||
|
||||
(Seth Kenlon, [CC BY-SA 4.0][6])
|
||||
|
||||
On [NetBSD][7], nvi is a common alternative to Vi, while Slackware provides [Elvis][8] (and Vim), and the popular [Neovim][9] fork aims to help users extend Vim with [Lua][10].
|
||||
|
||||
### Launch Vi
|
||||
|
||||
Start Vi or Vim with the `vi` command in a terminal. If a `.vimrc` file is not found on your system, then Vim starts in Vi-compatibility mode (this can also be forced with the `-C` option). If you want to use gVim to have a graphical user interface (GUI), you can start it from your desktop's application menu.
|
||||
|
||||
If you're a new user just learning Vi, using a graphical user interface can be a nice way to provide yourself a buffer between how you might _expect_ a text editor to behave and how Vi was designed to behave. The GUI version has a menu bar, some mouse integration, a toolbar, and other features to help you find the basic functions you probably take for granted in a typical text editor but don't know how to do in Vi yet.
|
||||
|
||||
### How to use Vi
|
||||
|
||||
Probably the easiest way to learn Vi is with `vimtutor`, an interactive tutorial packaged with Vim. To start the tutorial, launch `vimtutor` and read through the instructions, trying each exercise. As the tutorial says, getting good with Vi is less about memorizing what key does what and more about establishing muscle memory to invoke common actions as you type.
|
||||
|
||||
#### Escape
|
||||
|
||||
One of the first things you learn about Vi is the importance of the **Esc** key. **Esc** is what activates _command mode_, and it doesn't take long to learn that whenever you're in doubt in Vi, just press **Esc**. Any key you press while in command mode is not entered into the text document you're working on; instead, it is interpreted by Vi as a command. For instance, to move your cursor left, you press the **H** key on your keyboard. If you're in _insert_ mode, then pressing **H** types the letter H, just as you'd expect. But in _command_ mode, pressing **H** moves left, **L** moves right, **J** moves down, and **K** moves up.
|
||||
|
||||
The separation between command mode and insert mode is a sharp contrast to the way any other text editor works, and for that reason, it's probably Vi's most significant differentiator. Interestingly, though, it's theoretically not so different from the way you probably already work. After all, when you take your hands off the keyboard to select text with a mouse, you're essentially placing yourself into a kind of command mode. With Vi, instead of moving your hands off the keyboard to move the mouse and press function keys or Ctrl, you put the _editor_ into a special mode of operation, such that it reassigns your key presses to commands instead of text input.
|
||||
|
||||
#### Extend Vi
|
||||
|
||||
Before Vim version 8.0, Vi was very much "just" a text editor. There were plugins for it, but installing them was a manual process that many users never thought to do. Luckily, Vim version 8 and higher offer support for plugin management, making it trivial to install and load plugins.
|
||||
|
||||
Installing plugins for Vim can be done with the `vim-plug` function. For instance, to install the Vi file browser [NERDTree][11]:
|
||||
|
||||
|
||||
```
|
||||
`:PlugInstall NERDTree`
|
||||
```
|
||||
|
||||
You can also update plugins:
|
||||
|
||||
|
||||
```
|
||||
`:PlugUpdate NERDTree`
|
||||
```
|
||||
|
||||
For more information on installing plugins and themes, both with `vim-plug` and manually, read my article [_How to install Vim plugins_][12].
|
||||
|
||||
### Vi as default
|
||||
|
||||
Vi isn't just popular; it's a [POSIX][13] standard. It's an application every sysadmin should know how to use, even if they don't intend to use it on an everyday basis. It's also a fast and simple editor, so once you get good at it, it may be the editor you've long been searching for.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/vi-text-editor
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||
[2]: https://opensource.com/article/20/8/tcsh
|
||||
[3]: https://vimhelp.org/vi_diff.txt.html#vi-differences
|
||||
[4]: https://www.vim.org/download.php
|
||||
[5]: https://opensource.com/sites/default/files/uploads/gvim.jpg (gVim)
|
||||
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[7]: https://opensource.com/article/19/3/netbsd-raspberry-pi
|
||||
[8]: https://github.com/mbert/elvis
|
||||
[9]: http://neovim.io
|
||||
[10]: https://opensource.com/article/20/2/lua-cheat-sheet
|
||||
[11]: https://www.vim.org/scripts/script.php?script_id=1658
|
||||
[12]: https://opensource.com/article/20/2/how-install-vim-plugins
|
||||
[13]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
@ -1,126 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn Bash by writing an interactive game)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-bash)
|
||||
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||
|
||||
Learn Bash by writing an interactive game
|
||||
======
|
||||
Programming a simple game is a great way to practice a new language and
|
||||
compare it against others you know.
|
||||
![bash logo on green background][1]
|
||||
|
||||
Learning a new programming language can be fun. Whenever I try to learn a new one, I focus on defining variables, writing a statement, and evaluating expressions. Once I have a general understanding of those concepts, I can usually figure out the rest on my own. Most programming languages have some similarities, so once you know one programming language, learning the next one is a matter of figuring out the unique details and recognizing the differences in it.
|
||||
|
||||
To help me practice a new programming language, I like to write a few test programs. One sample program I often write is a simple "guess the number" program, where the computer picks a number between one and 100 and asks me to guess the number. The program loops until I guess correctly.
|
||||
|
||||
The "guess the number" program exercises several concepts in programming languages: how to assign values to variables, how to write statements, and how to perform conditional evaluation and loops. It's a great practical experiment for learning a new programming language.
|
||||
|
||||
### Guess the number in Bash
|
||||
|
||||
[Bash][2] is the standard shell for most Linux systems. Aside from providing a rich command-line user interface, Bash also supports a complete programming language in the form of _scripts_.
|
||||
|
||||
If you're not familiar with Bash, I recommend these introductions:
|
||||
|
||||
* [What is Bash?][3]
|
||||
* [Get started with Bash programming][4]
|
||||
* [Get started with Bash scripting for sysadmins][5]
|
||||
* [How to write functions in Bash][6]
|
||||
* [Read more about Bash][7]
|
||||
|
||||
|
||||
|
||||
You can explore Bash by writing a version of the "guess the number" game. Here is my implementation:
|
||||
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
number=$(( $RANDOM % 100 + 1 ))
|
||||
|
||||
echo "Guess a number between 1 and 100"
|
||||
|
||||
guess=0
|
||||
|
||||
while [ "0$guess" -ne $number ] ; do
|
||||
read guess
|
||||
[ "0$guess" -lt $number ] && echo "Too low"
|
||||
[ "0$guess" -gt $number ] && echo "Too high"
|
||||
done
|
||||
|
||||
echo "That's right!"
|
||||
exit 0
|
||||
```
|
||||
|
||||
### Breaking down the script
|
||||
|
||||
The first line in the script, `#!/bin/bash` tells Linux to run this script using the Bash shell. Every script starts with the `#!` character pair, which indicates this is a shell script. What immediately follows `#!` is the shell to run. In this case, `/bin/bash` is the Bash shell.
|
||||
|
||||
To assign a value to a variable, list the variable's name followed by the `=` sign. For example, the statement `guess=0` assigns a zero value to the `guess` variable.
|
||||
|
||||
You can also prompt the user to enter a value using the `read` statement. If you write `read guess`, Bash waits for the user to enter some text then stores that value in the `guess` variable.
|
||||
|
||||
To reference the value of a variable, use `$` before the variable name. So, having stored a value in the `guess` variable, you can retrieve it using `$guess`.
|
||||
|
||||
You can use whatever names you like for variables, but Bash reserves a few special variable names for itself. One special variable is `RANDOM`, which generates a very large random number every time you reference it.
|
||||
|
||||
If you want to perform an operation at the same time you store a value, you need to enclose the statement in special brackets. This tells Bash to execute that statement first, and the `=` stores the resulting value in the variable. To evaluate a mathematical expression, use `$(( ))` around your statement. The double parentheses indicate an _arithmetic expression_. In my example, `number=$(( $RANDOM % 100 + 1 ))` evaluates the expression `$RANDOM % 100 + 1` and then stores the value in the `number` variable.
|
||||
|
||||
Standard arithmetic operators such as `+` (plus), `-` (minus), `*` (multiply), `/` (divide), and `%` (modulo) apply.
|
||||
|
||||
That means the statement `number=$(( $RANDOM % 100 + 1 ))` generates a random number between one and 100. The modulo operator (`%`) returns the _remainder_ after dividing two numbers. In this case, Bash divides a random number by 100, leaving a remainder in the range zero to 99. By adding one to that value, you get a random number between one and 100.
|
||||
|
||||
Bash supports _conditional expressions_ and _flow control_ like loops. In the "guess the number" game, Bash continues looping as long as the value in `guess` is not equal to `number`. If the guess is less than the random number, Bash prints "Too low," and if the guess is greater than the number, Bash prints "Too high."
|
||||
|
||||
### How it works
|
||||
|
||||
Now that you've written your Bash script, you can run it to play the "guess the number" game. Continue guessing until you find the correct number:
|
||||
|
||||
|
||||
```
|
||||
Guess a number between 1 and 100
|
||||
50
|
||||
Too high
|
||||
30
|
||||
Too high
|
||||
20
|
||||
Too high
|
||||
10
|
||||
Too low
|
||||
15
|
||||
Too high
|
||||
13
|
||||
Too low
|
||||
14
|
||||
That's right!
|
||||
```
|
||||
|
||||
Every time you run the script, Bash will pick a different random number.
|
||||
|
||||
This "guess the number" game is a great introductory program when learning a new programming language because it exercises several common programming concepts in a pretty straightforward way. By implementing this simple game in different programming languages, you can demonstrate some core concepts and compare details in each language.
|
||||
|
||||
Do you have a favorite programming language? How would you write the "guess the number" game in it? Follow this article series to see examples of other programming languages that might interest you.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-bash
|
||||
|
||||
作者:[Jim Hall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jim-hall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bash_command_line.png?itok=k4z94W2U (bash logo on green background)
|
||||
[2]: https://en.wikipedia.org/wiki/Bash_(Unix_shell)
|
||||
[3]: https://opensource.com/resources/what-bash
|
||||
[4]: https://opensource.com/article/20/4/bash-programming-guide
|
||||
[5]: https://opensource.com/article/20/4/bash-sysadmins-ebook
|
||||
[6]: https://opensource.com/article/20/6/bash-functions
|
||||
[7]: https://opensource.com/tags/bash
|
@ -1,318 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Set up an Ansible lab in 20 minutes)
|
||||
[#]: via: (https://opensource.com/article/20/12/ansible-lab)
|
||||
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
|
||||
|
||||
Set up an Ansible lab in 20 minutes
|
||||
======
|
||||
Build an environment to support learning and experimenting with new
|
||||
software.
|
||||
![Science lab with beakers][1]
|
||||
|
||||
Being able to build and tear down a public cloud environment is very useful, but most of us don’t have easy access to a public cloud. The next best thing would be to have a lab on your local machine, but even running on a local machine brings performance, flexibility, and other challenges. Most of the time, the additional workloads on our local machines interfere with doing our daily job, and they certainly prevent having a readily available environment to play and experiment with new software.
|
||||
|
||||
My team and I encountered this challenge a few years ago when we were starting to learn [Ansible][2]. We couldn’t find an environment that we could use individually, and our frustration with the situation caused some of us to stop experimenting. We knew we needed to find a solution.
|
||||
|
||||
We spent a lot of time researching the options and came up with a set of tools that enable our curiosity to learn in an environment we fully control. We can spin up and tear down the lab environment on our local machines without needing access to on-premises labs or public clouds.
|
||||
|
||||
This article will explain how to deploy your own lab environment on your local machine in as little as 20 minutes in a fully automated way.
|
||||
|
||||
You can find all the code for this exercise in my [GitHub repository][3].
|
||||
|
||||
### Tools and software
|
||||
|
||||
This solution uses the following tools and software:
|
||||
|
||||
* [Ansible][4] is our automation tool of choice because it’s easy to use and flexible enough to handle the lab requirements.
|
||||
* [Vagrant][5] is easy to use for building and maintaining virtual machines.
|
||||
* [VirtualBox][6] is a hosted hypervisor that works in Windows and Linux environments.
|
||||
* [Fedora v30+][7] is the operating system on my local machine.
|
||||
|
||||
|
||||
|
||||
You must have the following set up to build the environment:
|
||||
|
||||
* An internet connection
|
||||
* Virtualization Technology support enabled in your BIOS (here is the [procedure][8] for my Lenovo laptop)
|
||||
* Vagrant v2.2.9
|
||||
* The latest version of Ansible
|
||||
* The latest version of VirtualBox
|
||||
* Fedora v30+ host operating system
|
||||
|
||||
|
||||
|
||||
### What’s in the lab environment?
|
||||
|
||||
This project aims to deploy an Ansible host with an Ansible engine and multiple Linux nodes along with some pre-loaded and pre-configured applications (httpd and MySQL). It also enables [Cockpit][9] so that you can monitor the status of the virtual machines (VMs) during testing. The reason to use a pre-deployed application is for efficiency (so you don’t have to spend time installing those components). This allows you to focus on creating roles and playbooks and testing against the environments deployed by the tools listed above.
|
||||
|
||||
We determined that the best scenario for our use case was a multi-machine Vagrant environment. The Vagrantfile creates three CentOS VMs to simulate two target hosts and an Ansible control machine:
|
||||
|
||||
* Host1: No graphical user interface (GUI), with httpd and MySQL installed
|
||||
* Host2: No GUI, with httpd and MySQL installed
|
||||
* Ansible-host: No GUI, with Ansible engine installed
|
||||
|
||||
|
||||
|
||||
### Enable multiple hypervisors
|
||||
|
||||
Some hypervisors may not allow you to bring up VMs if more than one hypervisor is in use. To fix this problem, follow these steps (based on Vagrant’s [installation][10] instructions).
|
||||
|
||||
First, find out the name of the hypervisor:
|
||||
|
||||
|
||||
```
|
||||
$ lsmod | grep kvm
|
||||
kvm_intel 204800 6
|
||||
kvm 593920 1 kvm_intel
|
||||
irqbypass 16384 1 kvm
|
||||
```
|
||||
|
||||
The one I’m interested in is `kvm_intel`, but you might want another (such as `kvm_amd`).
|
||||
|
||||
Run the following as root to blacklist the hypervisor:
|
||||
|
||||
|
||||
```
|
||||
`$ echo 'blacklist kvm-intel' >> /etc/modprobe.d/blacklist.conf`
|
||||
```
|
||||
|
||||
Restart your machine and try running Vagrant again.
|
||||
|
||||
### The Vagrant file
|
||||
|
||||
|
||||
```
|
||||
cat Vagrantfile
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
# Define VMs with static private IP addresses, vcpu, memory and vagrant-box.
|
||||
boxes = [
|
||||
{
|
||||
:name => "web1.demo.com", ⇒ Host1 this is one of the target nodes
|
||||
:box => "centos/8", ⇒ OS version
|
||||
:ram => 1024, ⇒ Allocated memory
|
||||
:vcpu => 1, ⇒ Allocated CPU
|
||||
:ip => "192.168.29.2" ⇒ Allocated IP address of the node
|
||||
},
|
||||
{
|
||||
:name => "web2.demo.com", ⇒ Host2 this is one of the target nodes
|
||||
:box => "centos/8",
|
||||
:ram => 1024,
|
||||
:vcpu => 1,
|
||||
:ip => "192.168.29.3"
|
||||
},
|
||||
{
|
||||
:name => "ansible-host", ⇒ Ansible Host with Ansible Engine
|
||||
:box => "centos/8",
|
||||
:ram => 8048,
|
||||
:vcpu => 1,
|
||||
:ip => "192.168.29.4"
|
||||
}
|
||||
]
|
||||
|
||||
# Provision each of the VMs.
|
||||
boxes.each do |opts|
|
||||
config.vm.define opts[:name] do |config|
|
||||
# Only Enable this if you are connecting to Proxy server
|
||||
# config.proxy.http = "<http://usernam:password@x.y:80"⇒> Needed if you have a proxy
|
||||
# config.proxy.https = "<http://usernam:password@x.y:80>"
|
||||
# config.proxy.no_proxy = "localhost,127.0.0.1"
|
||||
config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
|
||||
config.ssh.insert_key = false
|
||||
config.vm.box = opts[:box]
|
||||
config.vm.hostname = opts[:name]
|
||||
config.vm.provider :virtualbox do |v| ⇒ Defines the vagrant provider
|
||||
v.memory = opts[:ram]
|
||||
v.cpus = opts[:vcpu]
|
||||
end
|
||||
config.vm.network :private_network, ip: opts[:ip]
|
||||
config.vm.provision :file do |file|
|
||||
file.source = './keys/vagrant' ⇒ vagrant keys to allow access to the nodes
|
||||
file.destination = '/tmp/vagrant' ⇒ the location to copy the vagrant key
|
||||
end
|
||||
config.vm.provision :shell, path: "bootstrap-node.sh" ⇒ script that copy hosts entry
|
||||
config.vm.provision :ansible do |ansible| ⇒ declaration to run ansible playbook
|
||||
ansible.verbose = "v"
|
||||
ansible.playbook = "playbook.yml" ⇒ the playbook used to configure the hosts
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
These are the important files that you need to pay attention to:
|
||||
|
||||
* `inventory-test.yaml`: The inventory file to connect to the nodes
|
||||
* `playbook.yaml`: The playbook file that Vagrant provisioner calls to configure the nodes
|
||||
* `Vagrantfile`: The file that Vagrant uses to deploy the environment
|
||||
* `vagrant keys`: The Vagrant keys for connecting to the nodes in your lab environment
|
||||
|
||||
|
||||
|
||||
You can adjust these files based on your needs. Ansible’s flexibility gives you the power to declaratively change your environment as you require.
|
||||
|
||||
### Deploy your lab environment
|
||||
|
||||
First, clone the code from the [GitHub repo][11]:
|
||||
|
||||
|
||||
```
|
||||
$ git clone <https://github.com/mikecali/ansible-labs-101.git>
|
||||
Cloning into 'ansible-labs-101'...
|
||||
remote: Enumerating objects: 15, done.
|
||||
remote: Counting objects: 100% (15/15), done.
|
||||
remote: Compressing objects: 100% (13/13), done.
|
||||
remote: Total 15 (delta 2), reused 10 (delta 0), pack-reused 0
|
||||
Unpacking objects: 100% (15/15), 6.82 KiB | 634.00 KiB/s, done.
|
||||
```
|
||||
|
||||
Next, change your directory to `vagrant-session-2`, and view its contents:
|
||||
|
||||
|
||||
```
|
||||
$ ls
|
||||
Bootstrap-node.sh inventory keys playbook.yml README.md Vagrantfile
|
||||
```
|
||||
|
||||
You now have all the artifacts and configuration files you need for your lab environment. To deploy your environment, run:
|
||||
|
||||
|
||||
```
|
||||
`$ vagrant up`
|
||||
```
|
||||
|
||||
With a decent internet connection, it takes only about 20 minutes to get a running environment:
|
||||
|
||||
|
||||
```
|
||||
$ vagrant up
|
||||
Bringing machine 'web1.demo.com' up with 'virtualbox' provider...
|
||||
Bringing machine 'web2.demo.com' up with 'virtualbox' provider...
|
||||
Bringing machine 'ansible-host' up with 'virtualbox' provider...
|
||||
==> web1.demo.com: Importing base box 'centos/8'...
|
||||
==> web1.demo.com: Matching MAC address for NAT networking...
|
||||
==> web1.demo.com: Checking if box 'centos/8' version '1905.1' is up to date...
|
||||
==> web1.demo.com: Setting the name of the VM: ansible-labs_web1democom_1606434176593_70913
|
||||
==> web1.demo.com: Clearing any previously set network interfaces...
|
||||
==> web1.demo.com: Preparing network interfaces based on configuration...
|
||||
web1.demo.com: Adapter 1: nat
|
||||
web1.demo.com: Adapter 2: hostonly
|
||||
==> web1.demo.com: Forwarding ports...
|
||||
web1.demo.com: 22 (guest) => 2222 (host) (adapter 1)
|
||||
==> web1.demo.com: Running 'pre-boot' VM customizations...
|
||||
==> web1.demo.com: Booting VM...
|
||||
==> web1.demo.com: Waiting for machine to boot. This may take a few minutes...
|
||||
web1.demo.com: SSH address: 127.0.0.1:2222
|
||||
web1.demo.com: SSH username: vagrant
|
||||
web1.demo.com: SSH auth method: private key
|
||||
[...]
|
||||
```
|
||||
|
||||
Once the playbook execution completes, you will see output like this:
|
||||
|
||||
|
||||
```
|
||||
PLAY RECAP *********************************
|
||||
Ansible-host : ok=20 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=3
|
||||
|
||||
Real 18m14.288s
|
||||
User 2m26.978s
|
||||
Sys 0m26.849s
|
||||
```
|
||||
|
||||
Verify that all VMs are running:
|
||||
|
||||
|
||||
```
|
||||
$ vagrant status
|
||||
Current machine states:
|
||||
|
||||
Web1.demo.com running (virtualbox)
|
||||
Web2.demo.com running (virtualbox)
|
||||
ansible-host running (virtualbox)
|
||||
[...]
|
||||
```
|
||||
|
||||
You can investigate further by logging into one of the VMs. Access the ansible-host:
|
||||
|
||||
|
||||
```
|
||||
> vagrant ssh ansible-host
|
||||
Activate the web console with: systemctl enable --now cockpit.socket
|
||||
|
||||
Last login: Thu Nov 26 12:21:23 2020 from 10.0.2.2
|
||||
[vagrant@ansible-host ~] uptime
|
||||
16:46:42 up 1:24, 1 user, load average: 0.00, 0.01, 0.04
|
||||
```
|
||||
|
||||
Finally, you can use the Ansible module to ping the other nodes you created:
|
||||
|
||||
|
||||
```
|
||||
[vagrant@ansible-host]$ ansible -i inventory-test.yaml \
|
||||
webservers -m ping -u vagrant
|
||||
192.168.29.2 | SUCCESS => {
|
||||
"Ansible-facts": {
|
||||
"Discovered_interpreter_python": "/usr/libexec/platform-python"
|
||||
},
|
||||
"Changed": false;
|
||||
"Ping": "pong"
|
||||
}
|
||||
[...]
|
||||
```
|
||||
|
||||
### Clean up
|
||||
|
||||
Clean up your environment by running:
|
||||
|
||||
|
||||
```
|
||||
`$ vagrant destroy [vagrant machine name]`
|
||||
```
|
||||
|
||||
Your output will look like this:
|
||||
|
||||
![Output from cleaning up environment][12]
|
||||
|
||||
(Michael Calizo, [CC BY-SA 4.0][13])
|
||||
|
||||
### Get creative to learn
|
||||
|
||||
Learning software like Ansible on your own time in your own lab is a good habit, but it can be difficult because of constraints that are out of your control.
|
||||
|
||||
Sometimes, you need to get creative and find another way. There are many options in the open source community you can choose from; one of the main reasons we picked these tools is because they are commonly used and familiar to many people.
|
||||
|
||||
Also, please note that these playbooks are not as optimized as I want. Please feel free to improve them and share your work in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/ansible-lab
|
||||
|
||||
作者:[Mike Calizo][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/mcalizo
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/science_experiment_beaker_lab.png?itok=plKWRhlU (Science lab with beakers)
|
||||
[2]: https://opensource.com/resources/what-ansible
|
||||
[3]: https://github.com/mikecali/ansible-labs-101
|
||||
[4]: https://www.ansible.com/
|
||||
[5]: https://www.vagrantup.com/
|
||||
[6]: https://www.virtualbox.org/
|
||||
[7]: https://getfedora.org/
|
||||
[8]: https://support.lenovo.com/pt/en/solutions/ht500006
|
||||
[9]: https://opensource.com/article/20/11/cockpit-server-management
|
||||
[10]: https://www.vagrantup.com/docs/installation
|
||||
[11]: https://github.com/mikecali/ansible-labs-101.git
|
||||
[12]: https://opensource.com/sites/default/files/uploads/cleanup.png (Output from cleaning up environment)
|
||||
[13]: https://creativecommons.org/licenses/by-sa/4.0/
|
@ -1,175 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (9 things to do in your first 10 minutes on a Linux server)
|
||||
[#]: via: (https://opensource.com/article/20/12/linux-server)
|
||||
[#]: author: (Gaurav Kamathe https://opensource.com/users/gkamathe)
|
||||
|
||||
9 things to do in your first 10 minutes on a Linux server
|
||||
======
|
||||
Before putting a newly provisioned server to work, make sure you know
|
||||
what you're working with.
|
||||
![Parts, modules, containers for software][1]
|
||||
|
||||
When I test software on Linux (a regular part of my job), I need to use multiple servers with various architectures running Linux. I provision the machines, install the required software packages, run my tests, gather the results, and return the machine to the pool so that others can use it for their tests.
|
||||
|
||||
Since I do this so often (even multiple times a day), my first 10 minutes on a Linux server have become a daily ritual. When I first log into a Linux server, I look for certain things using commands to gather the information I need. I'll go through my process in this article, but please note that, in most cases, I'll just give the command name, so you will need to identify the specific flags for those commands to get the information that you need. Reading man pages for the commands is a good starting point.
|
||||
|
||||
### 1\. First contact
|
||||
|
||||
As soon as I log into a server, the first thing I do is check whether it has the operating system, kernel, and hardware architecture needed for the tests I will be running. I often check how long a server has been up and running. While this does not matter very much for a test system because it will be rebooted multiple times, I still find this information helpful.
|
||||
|
||||
Use the following commands to get this information. I mostly use Red Hat Linux for testing, so if you are using another Linux distro, use `*-release` in the filename instead of `redhat-release`:
|
||||
|
||||
|
||||
```
|
||||
cat /etc/redhat-release
|
||||
uname -a
|
||||
hostnamectl
|
||||
uptime
|
||||
```
|
||||
|
||||
### 2\. Is anyone else on board?
|
||||
|
||||
Once I know that the machine meets my test needs, I need to ensure no one else is logged into the system at the same time running their own tests. Although it is highly unlikely, given that the provisioning system takes care of this for me, it's still good to check once in a while—especially if it's my first time logging into a server. I also check whether there are other users (other than root) who can access the system.
|
||||
|
||||
Use the following commands to find this information. The last command looks for users in the `/etc/passwd` file who have shell access; it skips other services in the file that do not have shell access or have a shell set to `nologin`:
|
||||
|
||||
|
||||
```
|
||||
who
|
||||
who -Hu
|
||||
grep sh$ /etc/passwd
|
||||
```
|
||||
|
||||
### 3\. Physical or virtual machine
|
||||
|
||||
Now that I know I have the machine to myself, I need to identify whether it's a physical machine or a virtual machine (VM). If I provisioned the machine myself, I could be sure that I have what I asked for. However, if you are using a machine that you did not provision, you should check whether the machine is physical or virtual.
|
||||
|
||||
Use the following commands to identify this information. If it's a physical system, you will see the vendor's name (e.g., HP, IBM, etc.) and the make and model of the server; whereas, in a virtual machine, you should see KVM, VirtualBox, etc., depending on what virtualization software was used to create the VM:
|
||||
|
||||
|
||||
```
|
||||
dmidecode -s system-manufacturer
|
||||
dmidecode -s system-product-name
|
||||
lshw -c system | grep product | head -1
|
||||
cat /sys/class/dmi/id/product_name
|
||||
cat /sys/class/dmi/id/sys_vendor
|
||||
```
|
||||
|
||||
### 4\. Hardware
|
||||
|
||||
Because I often test hardware connected to the Linux machine, I usually work with physical servers, not VMs. On a physical machine, my next step is to identify the server's hardware capabilities—for example, what kind of CPU is running, how many cores does it have, which flags are enabled, and how much memory is available for running tests. If I am running network tests, I check the type and capacity of the Ethernet or other network devices connected to the server.
|
||||
|
||||
Use the following commands to display the hardware connected to a Linux server. Some of the commands might be deprecated in newer operating system versions, but you can still install them from yum repos or switch to their equivalent new commands:
|
||||
|
||||
|
||||
```
|
||||
lscpu or cat /proc/cpuinfo
|
||||
lsmem or cat /proc/meminfo
|
||||
ifconfig -a
|
||||
ethtool <devname>
|
||||
lshw
|
||||
lspci
|
||||
dmidecode
|
||||
```
|
||||
|
||||
### 5\. Installed software
|
||||
|
||||
Testing software always requires installing additional dependent packages, libraries, etc. However, before I install anything, I check what is already installed (including what version it is), as well as which repos are configured, so I know where the software comes from, and I can debug any package installation issues.
|
||||
|
||||
Use the following commands to identify what software is installed:
|
||||
|
||||
|
||||
```
|
||||
rpm -qa
|
||||
rpm -qa | grep <pkgname>
|
||||
rpm -qi <pkgname>
|
||||
yum repolist
|
||||
yum repoinfo
|
||||
yum install <pkgname>
|
||||
ls -l /etc/yum.repos.d/
|
||||
```
|
||||
|
||||
### 6\. Running processes and services
|
||||
|
||||
Once I check the installed software, it's natural to check what processes are running on the system. This is crucial when running a performance test on a system—if a running process, daemon, test software, etc. is eating up most of the CPU/RAM, it makes sense to stop that process before running the tests. This also checks that the processes or daemons the test requires are up and running. For example, if the tests require httpd to be running, the service to start the daemon might not have run even if the package is installed.
|
||||
|
||||
Use the following commands to identify running processes and enabled services on your system:
|
||||
|
||||
|
||||
```
|
||||
pstree -pa 1
|
||||
ps -ef
|
||||
ps auxf
|
||||
systemctl
|
||||
```
|
||||
|
||||
### 7\. Network connections
|
||||
|
||||
Today's machines are heavily networked, and they need to communicate with other machines or services on the network. I identify which ports are open on the server, if there are any connections from the network to the test machine, if a firewall is enabled, and if so, is it blocking any ports, and which DNS servers the machine talks to.
|
||||
|
||||
Use the following commands to identify network services-related information. If a deprecated command is not available, install it from a yum repo or use the equivalent newer command:
|
||||
|
||||
|
||||
```
|
||||
netstat -tulpn
|
||||
netstat -anp
|
||||
lsof -i
|
||||
ss
|
||||
iptables -L -n
|
||||
cat /etc/resolv.conf
|
||||
```
|
||||
|
||||
### 8\. Kernel
|
||||
|
||||
When doing systems testing, I find it helpful to know kernel-related information, such as the kernel version and which kernel modules are loaded. I also list any [tunable kernel parameters][2] and what they are set to and check the options used when booting the running kernel.
|
||||
|
||||
Use the following commands to identify this information:
|
||||
|
||||
|
||||
```
|
||||
uname -r
|
||||
cat /proc/cmdline
|
||||
lsmod
|
||||
modinfo <module>
|
||||
sysctl -a
|
||||
cat /boot/grub2/grub.cfg
|
||||
```
|
||||
|
||||
### 9\. Logs
|
||||
|
||||
By now, I have a good idea about the server, including what software is installed and what processes are running. One other thing I cannot escape is log files—I need to know where to check the information that is continuously being updated.
|
||||
|
||||
Use the following commands to see your system's logs:
|
||||
|
||||
|
||||
```
|
||||
dmesg
|
||||
tail -f /var/log/messages
|
||||
journalctl
|
||||
```
|
||||
|
||||
### Next steps
|
||||
|
||||
While commands and utilities will change, the underlying information they show remains more or less the same. You need a high-level view of the information you are looking for and what category it falls into before you can focus on which commands to master.
|
||||
|
||||
Since Linux saves most information in files, these commands basically read information from the files and present them in an easy-to-understand way. A good next step is to identify the files each command uses to get the information to display. A hint for finding that information is the `strace` command.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/linux-server
|
||||
|
||||
作者:[Gaurav Kamathe][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/gkamathe
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_modules_networking_hardware_parts.png?itok=rPpVj92- (Parts, modules, containers for software)
|
||||
[2]: https://www.oreilly.com/library/view/red-hat-enterprise/9781785283550/ch10s05.html
|
@ -1,193 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to View Images from the Linux Terminal)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-view-display-images-from-linux-terminal/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How to View Images from the Linux Terminal
|
||||
======
|
||||
|
||||
Linux has many GUI applications for viewing images.
|
||||
|
||||
But I have never tried any CLI applications to see it.
|
||||
|
||||
Fortunately while working with the **[ImageMagick tool][1]** I got a command to view an image from the terminal.
|
||||
|
||||
The command name is **“display”**, which is part of the ImageMagick tool.
|
||||
|
||||
This is a great tool that allows NIX users to view images from the terminal.
|
||||
|
||||
Also, I got another great tool called FIM for this purpose.
|
||||
|
||||
We will show you how to install and use it to view images from the Linux terminal.
|
||||
|
||||
These commands use the system’s framebuffer to display images directly from the command line.
|
||||
|
||||
### How to View Images from Terminal Using display Command
|
||||
|
||||
[ImageMagick][2] is a free and open source, feature-rich, command-line based image manipulation tool.
|
||||
|
||||
It used to create, edit, compose, or convert bitmap images.
|
||||
|
||||
It can read and write images in a variety of formats (over 200) including PNG, JPEG, GIF, PDF, SVG and etc,.
|
||||
|
||||
It can resize, mirror, rotate, transform images, adjust image colors, apply various special effects, etc,.
|
||||
|
||||
It supports batch process, which allow you to processes all images at once.
|
||||
|
||||
### How to Install ImageMagick?
|
||||
|
||||
The ImageMagick package is included in the official repository of most Linux distributions. Use the distribution package manager to install it.
|
||||
|
||||
**Make a note:** Make sure you already have “**[Development Tools][3]**” installed on your Linux system as a prerequisite for this.
|
||||
|
||||
For **RHEL/CentOS 6/7** systems, use the **[yum command][4]** to install ImageMagick.
|
||||
|
||||
```
|
||||
$ sudo yum install -y ImageMagick ImageMagick-devel
|
||||
```
|
||||
|
||||
For **RHEL/CentOS 8** and **Fedora** systems, use the **[dnf command][5]** to install ImageMagick.
|
||||
|
||||
```
|
||||
$ sudo dnf install -y ImageMagick ImageMagick-devel
|
||||
```
|
||||
|
||||
For **Debian/Ubuntu** systems, use the **[apt command][6]** or **[apt-get command][7]** to install ImageMagick.
|
||||
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install imagemagick
|
||||
```
|
||||
|
||||
For **openSUSE** systems, use the **[zypper command][8]** to install ImageMagick
|
||||
|
||||
```
|
||||
$ sudo zypper install -y ImageMagick
|
||||
```
|
||||
|
||||
To view any image file, run display command as follows. You can close the image by pressing the **“Esc/q”** button.
|
||||
|
||||
```
|
||||
$ display bird.jpg
|
||||
```
|
||||
|
||||
![][9]
|
||||
|
||||
If you want to open the image with the specified size of the window, use the **“-geometry”** flag.
|
||||
|
||||
```
|
||||
$ display -geometry 1000x600 ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
You can also input position information of the image with display command. The below command open your image 800 pixels from the top and 800 pixels from the top left corner of your desktop.
|
||||
|
||||
```
|
||||
$ display -geometry 1000x600+800+800 ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
If you want to resize the image with the display command, use the following format.
|
||||
|
||||
```
|
||||
$ display -resize 600x400 ~/Downloads/bird.jp
|
||||
```
|
||||
|
||||
Alternatively, you can use percentage to resize the image.
|
||||
|
||||
```
|
||||
$ display -resize 50% ~/Downloads/bird.jpg
|
||||
```
|
||||
|
||||
### How to View Images from the Terminal Using fim Command
|
||||
|
||||
[FIM][10] is a lightweight global image viewer designed specifically for Linux.
|
||||
|
||||
But it is not limited to Linux and can be configured to run on other OS such as MS-Windows.
|
||||
|
||||
It’s highly customizable and scriptable image viewer for users who are familiar with software like the VIM text editor.
|
||||
|
||||
It displays the image in full screen and can be easily controlled using the keyboard shortcuts.
|
||||
|
||||
It is very lightweight tool because it only depends on certain libraries.
|
||||
|
||||
It can open many file formats and it can display images in the following video modes.
|
||||
|
||||
* Graphically, with the Linux framebuffer device
|
||||
* Graphically, under X/Xorg, using the SDL library
|
||||
* Graphically, under X/Xorg, using the Imlib2 library
|
||||
* Rendered as ASCII Art in any textual console, using the AAlib library
|
||||
|
||||
|
||||
|
||||
The right video mode gets auto-detected or selected at runtime, and may be opted in/out before build at configure time, if desired.
|
||||
|
||||
FIM stands for Fbi IMproved, which is the fork of the Fbi Image viewer.
|
||||
|
||||
FIM can be easily installed on Debian/Ubuntu based systems as the package is available in the distribution official repository. For other distributions, you may need to compile it from the source.
|
||||
|
||||
```
|
||||
$ sudo apt install fim
|
||||
```
|
||||
|
||||
Once installed, you can display an image using the following command.
|
||||
|
||||
```
|
||||
$ fim bird.jpg
|
||||
```
|
||||
|
||||
You can automatically zoom an image using the **“-a”** option.
|
||||
|
||||
```
|
||||
$ fim -a bird.jpg
|
||||
```
|
||||
|
||||
![][9]
|
||||
|
||||
If you want to open multiple image files in the current directory, use the wildcard to open them all. Use the **“Pageup/Down”** keyboard shortcuts to move to the next or previous image.
|
||||
|
||||
```
|
||||
$ fim -a *.jpg
|
||||
```
|
||||
|
||||
To view the image in ASCII format, you can use the **“-t”** flag.
|
||||
|
||||
```
|
||||
$ fim -t bird.jpg
|
||||
```
|
||||
|
||||
The below keyboard shortcuts allow you to control the images.
|
||||
|
||||
* PageUp/Down : Prev/Next image
|
||||
* +/- : Zoom in/out
|
||||
* a : Autoscale
|
||||
* w : Fit to width
|
||||
* ESC/q : Quit
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-view-display-images-from-linux-terminal/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/resize-convert-images-from-linux-command-line/
|
||||
[2]: https://imagemagick.org/
|
||||
[3]: https://www.2daygeek.com/install-development-tools-on-ubuntu-debian-arch-linux-mint-fedora-centos-rhel-opensuse/
|
||||
[4]: https://www.2daygeek.com/linux-yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[5]: https://www.2daygeek.com/linux-dnf-command-examples-manage-packages-fedora-centos-rhel-systems/
|
||||
[6]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[7]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[8]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.nongnu.org/fbi-improved/#docs
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: ()
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
@ -232,7 +232,7 @@ via: https://opensource.com/article/20/12/52-bit-arm64-kernel
|
||||
|
||||
作者:[Bhupesh Sharma][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,115 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Why Vim users will love the Kakoune text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/kakoune)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Why Vim users will love the Kakoune text editor
|
||||
======
|
||||
This editor may be reminiscent of Vim, but it offers plenty of its own
|
||||
unique functions and features.
|
||||
![Typewriter keys in multicolor][1]
|
||||
|
||||
The [Kakoune][2] text editor takes inspiration from Vi. With a minimalistic interface, short keyboard shortcuts, and separate editing and insert modes, it does [look and feel a lot like Vi][3] at first. However, the Kakoune editor has its own unique style both in design and function and is better considered its own editor rather than yet another Vim.
|
||||
|
||||
### Install
|
||||
|
||||
On Linux and BSD, you can install Kakoune from your distribution’s software repository or ports tree. For example, on Fedora, CentOS, or RHEL:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dnf install kakoune`
|
||||
```
|
||||
|
||||
On Debian, Ubuntu, or similar:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo apt install kakoune`
|
||||
```
|
||||
|
||||
On macOS, you can use Homebrew:
|
||||
|
||||
|
||||
```
|
||||
`$ brew install kakoune`
|
||||
```
|
||||
|
||||
Alternatively, you can [build it from source code][4].
|
||||
|
||||
The command to start Kakoune is `kak`. You can start Kakoune empty, or you can include a file name for it to open upon launch:
|
||||
|
||||
|
||||
```
|
||||
`$ kak example.txt`
|
||||
```
|
||||
|
||||
### Using Kakoune
|
||||
|
||||
When you launch Kakoune (without a file name), it opens a mostly empty buffer in your terminal, except for a small status bar at the bottom of the windows. Like Vim, Kakoune starts in "normal" mode, which accepts key presses as commands and does not enter text into the buffer. To enter _insert_ mode, you must press either **i** (for **insert**) or **a** (for **append**).
|
||||
|
||||
While in insert mode, Kakoune acts mostly like any other editor. You type on your keyboard, and the characters you type show up in the buffer. While in insert mode, you can use the arrow keys to navigate through the buffer.
|
||||
|
||||
### Normal mode
|
||||
|
||||
In normal mode, you can issue navigation and text editing commands. This is the most obvious borrowed feature from the Vi tradition. Editing commands include functions to copy, cut (or "yank," in traditional Unix editing vernacular), and paste words and lines, undo, transform characters to upper or lower case, and so on. Here are some of the basics:
|
||||
|
||||
* **d**: yank and delete current selection ("cut" in modern terminology)
|
||||
* **c**: yank and delete current selection and enter insert mode
|
||||
* **Esc+Alt+d**: delete current selection
|
||||
* **y**: yank selection
|
||||
* **p**: paste
|
||||
* **<**: unindent selected lines
|
||||
* **u**: undo
|
||||
* **U**: redo
|
||||
* **`**: transform to lower case
|
||||
* **~**: transform to upper case
|
||||
|
||||
|
||||
|
||||
### Selection
|
||||
|
||||
In Kakoune, your cursor is a single-character mobile selection. Unless you extend your selection, any commands affecting a selection apply to just your cursor. For instance, if your cursor is hovering over the letter **n**, then the yank command (**c** in normal mode) copies the letter **n** to your clipboard, and the paste command (**p** in normal mode) pastes the letter **n** into the buffer.
|
||||
|
||||
The easiest way to extend a selection from a single character is to enter normal mode and press the **Shift** key while moving your cursor with the arrow keys. There are, however, several methods of extending a selection based on certain criteria. For instance, **Alt+l** extends a selection region from your cursor to the end of the current line.
|
||||
|
||||
Full documentation is available at <https://github.com/mawww/kakoune/blob/master/README.asciidoc>.
|
||||
|
||||
### Functions
|
||||
|
||||
In addition to these basic interactions, you can also issue commands to invoke the built-in functions of Kakoune. To access the Kakoune’s command line, type `:` in normal mode. From the command line, you can issue commands, including the essential **edit** command to open a file, the **write** command to save your buffer to a file, and of course, **quit** to exit the application.
|
||||
|
||||
There are many more functions, including special options for specific programming languages and file formats, an option to use the [Ranger file navigator][5] to browse your file system, change your color theme, search and replace text, and much more.
|
||||
|
||||
![Kakoune][6]
|
||||
|
||||
### Try Kakoune
|
||||
|
||||
If you’re an experienced Vim user or even someone with just a passing competency, you might find Kakoune disorienting at first. It’s just similar enough to Vim to lull you into a false sense of familiarity—everything works exactly like Vim until it’s drastically different. However, if you’re new to Vim-like editors, or you’re a Vim user looking for a new challenge, then Kakoune could be an ideal editor for you.
|
||||
|
||||
Try it for yourself!
|
||||
|
||||
When I started using the vi text editor, I hated it. Now I've been using vi for more than 17 years...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/kakoune
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriterkeys-3.png?itok=NyBwMdK_ (Typewriter keys in multicolor)
|
||||
[2]: https://kakoune.org/
|
||||
[3]: https://opensource.com/article/20/12/vi-text-editor
|
||||
[4]: https://github.com/mawww/kakoune
|
||||
[5]: https://opensource.com/article/20/3/ranger-file-navigator
|
||||
[6]: https://opensource.com/sites/default/files/kakoune-screenshot.png (Kakoune)
|
@ -1,70 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Find out how your text will be read with Norka)
|
||||
[#]: via: (https://opensource.com/article/20/12/norka)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Find out how your text will be read with Norka
|
||||
======
|
||||
This is a no-frills text editor designed to provide insight into how
|
||||
your writing will be read and understood.
|
||||
![Reading a book, selfcare][1]
|
||||
|
||||
Some text editors are designed for programming, others for specialized text formats, others for document design. The Norka text editor is designed for reading. It might seem strange to create a text editor designed for _reading_, but actually, it makes a lot of sense if you think about it. Your text is written once or thrice, depending on your personal tolerance for iteration, but it’s meant to be read for years to come. Norka makes it easy for you to focus on how your writing is going to get read.
|
||||
|
||||
### Installing
|
||||
|
||||
The Norka text editor is licensed with an MIT license and can be [installed as a Flatpak on Linux][2]. It is open source, so if you want to try your hand at installing it on a different platform, you may [clone its Github repository][3].
|
||||
|
||||
### Norka interface
|
||||
|
||||
The Norka interface is simple—a button back to your Norka document collection, an export button, and a preference menu. The rest of the window is blank space for you to write text into, and in the bottom right corner, there’s a read time calculator to help you understand how long it might take for readers to get through what you’ve written.
|
||||
|
||||
![Dark Norka terminal box with green and white text][4]
|
||||
|
||||
That’s nearly all there is to Norka. There are no page breaks or line numbers, no code-folding or regex searches. This is an editor meant for text writing words, not styling documents or keeping track of a complex data schema.
|
||||
|
||||
There are, of course, some extra features. Copy and paste work as expected with **Ctrl+C** and **Ctrl+V**. You can undo with **Ctrl+Z** and find with **Ctrl+F**. You can even insert emoji with **Ctrl+:**.
|
||||
|
||||
![Norka terminal box with pop up box of emoji search menu][5]
|
||||
|
||||
#### Styling text
|
||||
|
||||
While Norka definitely has no interest in helping you design, say, a brochure or flyer, it does have some ability to indicate how you want your text styled. It does this through [Markdown][6], a simple convention for writing in plain text but with special notation to indicate how the text should be rendered later in HTML or EPUB or PDF or whatever your destination may be.
|
||||
|
||||
In most editors, you have to know Markdown to use Markdown, but Norka translates common word processor keyboard shortcuts to produce Markdown for you. For instance, to make a word bold, you can press **Ctrl+B**, which inserts four asterisks on either side of your cursor. When you type the next word, it’s surrounded on either side with two asterisks, which is the Markdown notation for strong (rendered in boldface by default) text. You can view all Markdown shortcuts in the hamburger menu in the upper-right corner of the Norka window.
|
||||
|
||||
#### Saving and exporting
|
||||
|
||||
You can think of Norka like a notebook. All of the documents you start in Norka remain in Norka’s internal database, and everything is saved automatically by default. To work with a file outside of Norka, you use the **Share** button in the top right corner of your open document. Alternately, you can right-click on any document from Norka's file view and select **Export**. You can export (or _share_—Norka uses both terms interchangeably) a document to **Text**, **HTML**, or **Markdown**.
|
||||
|
||||
### Try Norka
|
||||
|
||||
Norka is easy to try and easy to use. It helps you focus on writing by keeping its interface simple, almost to the point of restriction. But restrictions can be a powerful creative tool, sometimes.
|
||||
|
||||
Norka might not be your best choice for heavy revisions or text processing. It doesn’t have exciting features like case conversion, integrated **sed** commands, character swapping, and so on. It’s a text writer for readers. If that makes sense to you, then you may be just the audience Norka is seeking.
|
||||
|
||||
Thanks for spending two minutes and 39 seconds reading this article!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/norka
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/reading_book_selfcare_wfh_learning_education_520.png?itok=H6satV2u (Reading a book, selfcare)
|
||||
[2]: https://flathub.org/apps/details/com.github.tenderowl.norka
|
||||
[3]: https://github.com/TenderOwl/Norka
|
||||
[4]: https://opensource.com/sites/default/files/uploads/norka-31_days-norka-opensource.png (Dark Norka terminal box with green and white text)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/norka_emoji-31_days-norka-opensource.png (Norka terminal box with pop up box of emoji search menu)
|
||||
[6]: https://opensource.com/article/19/9/introduction-markdown
|
@ -0,0 +1,84 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (6 ways this fullscreen text editor improves focus)
|
||||
[#]: via: (https://opensource.com/article/20/12/focuswriter)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
6 ways this fullscreen text editor improves focus
|
||||
======
|
||||
This fullscreen editor helps you set your writing goals and keeps
|
||||
distractions to a minimum so you can achieve them.
|
||||
![Typewriter with hands][1]
|
||||
|
||||
The great thing about computers is that they’re really good at multi-tasking.
|
||||
|
||||
The bad thing about computers is that they’re really good at multi-tasking.
|
||||
|
||||
Whether you consider yourself, as a human, good or bad at multi-tasking, sometimes you need a little help focusing. One of those times is when you’re trying to compose clear and concise communication. And that’s exactly why Focuswriter was developed.
|
||||
|
||||
### Install
|
||||
|
||||
On Linux, you can install Focuswriter as a Flatpak from [Flathub][2].
|
||||
|
||||
On Windows or Linux (if you don’t use Flatpak), you can [install Focuswriter from its website][3]. You can also install from source code, also available from the Focuswriter webpage.
|
||||
|
||||
### Using Focuswriter
|
||||
|
||||
Focuswriter is, admittedly, actually a cross between a text editor and a word processor. Its default format is the Open Document Text (.odt) format, so it allows you to style and align text, mark headers, and toggle smart quotes on and off. But that’s where its word processor features end because Focuswriter does mostly focus on _writing_, not on styling what you’ve written.
|
||||
|
||||
Focuswriter encourages focus in a few different ways.
|
||||
|
||||
#### Attractiveness
|
||||
|
||||
Focuswriter doesn’t look like your usual computer application, much less your usual text editor. When it launches, it loads a theme behind your document. The theme is generally benign—a writing desk is the default, but there’s also a starry sky, a faraway landscape, and so on. You’re not meant to become preoccupied with the theme, of course, but it does help you from getting distracted by some other application window or your computer desktop lingering behind your editor. Because it’s easy to customize, there’s little chance of you being left without a theme you like.
|
||||
|
||||
![Focuswriter white box with gray wording on wooden writing desk background theme][4]
|
||||
|
||||
#### Sound effects
|
||||
|
||||
Focuswriter is actually fun to use. Aside from its visual theme, it also has an _optional_ typewriter audio theme. Once enabled, every keypress makes the sound of a mechanical typewriter key. When you press **Return**, the satisfying sound of a carriage return is your reward for completing a paragraph (or a line, if you write one sentence per line to improve version control).
|
||||
|
||||
This audio theme is entirely opt-in, and it’s not on by default. You may doubt its efficacy, but you shouldn’t underestimate the satisfaction of making those sounds of productivity while also wielding the powers of modern text editing.
|
||||
|
||||
#### Fullscreen display
|
||||
|
||||
Focuswriter not only launches fullscreen by default, but it also hides its menus and other widgets from view. To access the main menu bar, you place your cursor to the top of your screen until it appears. There’s a scroll bar hidden on the right, a document switcher widget on the left, and a status bar at the bottom.
|
||||
|
||||
#### Minimalism
|
||||
|
||||
There isn’t much to Focuswriter’s editing capabilities. It doesn’t have advanced search options or specialized options for code formatting or syntax highlighting. It lets you write text, and little else, into a document, by design. Even the contextual right-click menu only offers basic editing functions (copy, cut, paste, and so on) or spell-checking options.
|
||||
|
||||
#### Line focus
|
||||
|
||||
Another optional feature of Focuswriter is its ability to "grey out" all lines of text but your current one. This helps your eyes lazily locate your current line of text, which can be especially helpful if you’re not a touch-typist or if you’re transcribing something you’ve handwritten on physical paper and must look away from the screen often.
|
||||
|
||||
#### Goal tracker
|
||||
|
||||
You can set a daily word count goal or a timed goal for yourself in Focuswriter’s preferences. Your progress is tracked as you work and displayed in the status bar at the bottom of the screen. It’s hidden from your view unless you hover your cursor over it, so you’re not compelled to obsess over it, but it’s convenient enough to help you stay on track.
|
||||
|
||||
### Try Focuswriter (even if you think it’s silly)
|
||||
|
||||
I’ve heard about fullscreen text editors before, and I’ve never felt it was important for me to try one. After all, nearly any application can be made fullscreen, and I don’t personally have trouble focusing anyway.
|
||||
|
||||
Having tried Focuswriter, though, I understand the appeal of a good fullscreen "focus first" text editor. It may not be necessary, but then again, open source is thriving. We have the luxury of redundant sets of applications that have minor differences in function but major differences in implementation. Focuswriter makes writing fun; it makes the work enjoyable. Download it, set a goal, and get writing!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/focuswriter
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/typewriter-hands.jpg?itok=oPugBzgv (Typewriter with hands)
|
||||
[2]: https://flathub.org/apps/details/org.gottcode.FocusWriter
|
||||
[3]: https://gottcode.org/focuswriter/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/focuswriter-31_days_focuswriter-opensource.png (Focuswriter white box with gray wording on wooden writing desk background theme)
|
@ -0,0 +1,242 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn a new old language by programming a game in Algol 68)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-algol-68)
|
||||
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
|
||||
|
||||
Learn a new old language by programming a game in Algol 68
|
||||
======
|
||||
Even "dead languages" can teach you a lot about programming today.
|
||||
![Old UNIX computer][1]
|
||||
|
||||
In this article series, Opensource.com [Correspondents][2] and others have been writing the same "guess the number" game in various programming languages. This exercise shows how the basic concepts you'll find in most programming languages—variables, expressions, and statements—can be applied to learn new languages.
|
||||
|
||||
Most languages have a "way of doing things" that's supported by their design, and those ways can be quite different from one program to another. These ways include modularity (grouping related functionality together), declarative vs. imperative, object-orientation, low- vs. high-level syntactic features, and so on.
|
||||
|
||||
In the "guess the number" program, the computer picks a number between one and 100 and asks you to guess the number. The program loops until you guess the right answer.
|
||||
|
||||
In this article, I'll show you how to write this application in Algol 68. I'll also try to exercise the following concepts you'll find in any programming language:
|
||||
|
||||
* Variables
|
||||
* Input
|
||||
* Output
|
||||
* Conditional evaluation
|
||||
* Loops
|
||||
|
||||
|
||||
|
||||
### Guess the number in Algol 68
|
||||
|
||||
This example uses the [Algol 68][3] Genie compiler, available in many Linux distros, created by [Marcel Van Der Veer][4].
|
||||
|
||||
OK, I can hear some of you out there moaning, "oh no, why Algol 68? That language is so old and has been irrelevant since before there were implementations." And I respect your opinions, I really do. Really. But I believe many cool things exist in today's programming languages that come from the hard thinking done by the designers of Algol 68, which justifies learning a bit about the language.
|
||||
|
||||
Algol 68 is statically typed and not particularly verbose. Algol 68 Genie compiles and executes in one go, so Algol 68 can feel a bit like a scripting language. The Genie implementation offers many useful hooks into our favorite operating system, which keeps it from feeling horribly dated and means a fair bit of useful work can be done with it.
|
||||
|
||||
Some points worth mentioning at the outset:
|
||||
|
||||
* One of Algol 68's design principles is letting anything that could reasonably be thought of as an expression (a construct that delivers a value) be legal code.
|
||||
* Algol 68 "reserved words" are typically expressed as boldface symbols in the program source, which is kind of hard to do with text files, so most compilers have a way of indicating that a token is a reserved word. In Algol 68 Genie, the default is to use all upper case letters; for example, `BEGIN`, `IF`, `THEN`, etc.
|
||||
* Speaking of things like `BEGIN … END`, `IF … THEN … ELSE`, Algol 68 has a "closed syntax." A `BEGIN` must have a corresponding `END`, similar to `{ }` in C or Java; an `IF` must have a `FI`, and a `DO` must have an `OD`.
|
||||
* Algol 68 generally treats whitespace as irrelevant—even within numbers or variable names. Therefore, `myvariablename` and `my variable name` (and even `myvar iablename`) all refer to the same variable.
|
||||
* Algol 68 requires "go on symbols"—semicolons—between (but not following) statements in a sequence to be evaluated statement-by-statement.
|
||||
* Algol 68 incorporates a "string" type but does not provide a rich set of string processing primitives, which can be a bit frustrating.
|
||||
* Algol 68 is imperative rather than declarative and not object-oriented.
|
||||
|
||||
|
||||
|
||||
With that preamble, here is my "guess the number" implementation (with line numbers to make it easier to review some of the specific features):
|
||||
|
||||
|
||||
```
|
||||
1 on logical file end (stand in,
|
||||
2 (REF FILE f) BOOL: (print(("Goodbye!",new line));stop));
|
||||
|
||||
3 first random(42);
|
||||
4 INT random number = ENTIER (next random * 100.0) + 1;
|
||||
|
||||
5 print(("the secret number is",random number,new line));
|
||||
|
||||
6 print("guess a number: ");
|
||||
7 WHILE
|
||||
8 INT guess = read int;
|
||||
9 IF guess < random number THEN
|
||||
10 print("too low, try again: ");
|
||||
11 TRUE
|
||||
12 ELIF guess > random number THEN
|
||||
13 print("too high, try again: ");
|
||||
14 TRUE
|
||||
15 ELSE
|
||||
16 print(("that's right",new line));
|
||||
17 FALSE
|
||||
18 FI
|
||||
19 DO SKIP OD
|
||||
```
|
||||
|
||||
### Breaking it down
|
||||
|
||||
Jumping right in: lines 1 and 2 define what happens when an end of file is detected on the input coming from the console.
|
||||
|
||||
This situation is managed by calling the procedure `on logical file end` and passing two arguments: a file to be monitored and a procedure to be called when the end of file is detected. The file you want to monitor is the standard input, `stand in`. Line 2 is the definition of the procedure; this is an expression that yields a procedure. It has one parameter, which is a pointer to a file named "f" that is written as `REF FILE f`. It returns a boolean value, indicated by `BOOL`.
|
||||
|
||||
The text after the `:` is the procedure body, which:
|
||||
|
||||
* Starts with a brief begin symbol, `(`
|
||||
* Is followed by a call to the `print` procedure with a list of two arguments, the string `"Goodbye!"` and the `new line` procedure that will emit a newline in the output stream
|
||||
* Is followed by a "go on symbol"—the semicolon
|
||||
* Is followed by a call to the procedure `stop`
|
||||
* Is followed by the brief end symbol, `)`
|
||||
* Is followed by the parenthesis closing the list of arguments to the "on logical file end "call
|
||||
* Is followed by the "go on symbol," `;`
|
||||
|
||||
|
||||
|
||||
More verbosely, I could have written this procedure definition as:
|
||||
|
||||
|
||||
```
|
||||
(REF FILE f) BOOL: BEGIN
|
||||
print(("Goodbye!",new line));
|
||||
stop
|
||||
END
|
||||
```
|
||||
|
||||
It's probably worth mentioning that Algol 68 makes a very strong distinction between values and references to values. An Algol 68 value is conceptually similar to a constant or immutable or final value seen in many of today's popular programming languages. A value cannot be changed. A reference to a value, on the other hand, essentially defines a location where a value can be stored and the contents of that location can be changed. This corresponds to a variable, or mutable, or non-final value.
|
||||
|
||||
By way of concrete examples:
|
||||
|
||||
|
||||
```
|
||||
`INT forty two = 42`
|
||||
```
|
||||
|
||||
defines an "integer value" named `forty two`, which evaluates to the number `42`.
|
||||
|
||||
And:
|
||||
|
||||
|
||||
```
|
||||
`INT fink := 42`
|
||||
```
|
||||
|
||||
defines an integral variable `fink` and uses `:=` to assign the value `42` to it. This expression is actually shorthand for:
|
||||
|
||||
|
||||
```
|
||||
REF INT fink = LOC INT;
|
||||
fink := 42
|
||||
```
|
||||
|
||||
This makes the correspondence between values (`INT forty two`) and variables (`REF INT fink`) clearer at the expense of some verbosity. The `LOC INT` thing is a "local generator"—space for an integer value is allocated on the stack. There is also a "heap generator" useful for building structures that persist across procedure calls.
|
||||
|
||||
Phew! Back to the code.
|
||||
|
||||
Lines 3 and 4 initialize the system random number generator by calling the "setup" procedure first random() with an integer "seed" argument (which kinda hasta be 42, right?), then calling the procedure next random—which takes no arguments and therefore doesn't require parentheses with nothing between—and multiplies that by 100 to give a result between 0.0 and 99.9999…, truncating the result created using the unary operator ENTIER to give a result between 0 and 99, and finally adding 1 to give a result between 1 and 100.
|
||||
|
||||
Worth mentioning at this point is that Algol 68 seems to be the first language to support the definition of unary and binary operators, which are distinct from procedures. You must put parentheses around the expression:
|
||||
|
||||
|
||||
```
|
||||
`next random * 100.0`
|
||||
```
|
||||
|
||||
because otherwise `ENTIER` would bind to the next random, giving the number 0, rather than to the whole expression.
|
||||
|
||||
On line 5 is a call to the `print` procedure, which is used here as a debugging thing. Notice the nested parentheses; `print` takes an argument that is either a printable value or expression or a list of printable values or expressions. When it's a list, you use a "denotation," which opens and closes with parentheses.
|
||||
|
||||
Line 6 uses `print` again to offer the single string `guess a number:`.
|
||||
|
||||
Lines 7 through 20 are a `WHILE … DO … OD` loop. A few interesting things here: First, all the work is done as a part of the logical expression evaluated by the `WHILE`, so the body of the loop contains only the reserved word `SKIP`, which means "do nothing."
|
||||
|
||||
Lines 8 through 17 are a sequence of two statements: the definition of the integer value `guess`, which is obtained by calling the procedure `read int` to get an integer from the input, followed by the `IF … THEN … ELIF … ELSE … FI` statement. Note that each of the `THEN`, `ELIF`, and `ELSE` parts end with a boolean value `TRUE` or `FALSE`. This causes the whole `IF… FI` statement to return either `TRUE` or `FALSE`, which, being the last statement in the sequence of statements, is the value "delivered" to `WHILE` to determine whether to loop around again or not.
|
||||
|
||||
A more typical language might have a structure similar to:
|
||||
|
||||
|
||||
```
|
||||
boolean doAgain = true;
|
||||
while (doAgain) {
|
||||
if less then
|
||||
doAgain = true
|
||||
else if more then
|
||||
doAgain = true
|
||||
else
|
||||
doAgain = false
|
||||
}
|
||||
```
|
||||
|
||||
Because Algol 68 is expression-oriented, you don't need to declare that variable `doAgain`; you just incorporate the values to be generated into the expression being evaluated by the `WHILE` part.
|
||||
|
||||
What's cool about this is you can do things like the ternary operator in C—except much more broadly and better—with the standard `IF...FI`:
|
||||
|
||||
|
||||
```
|
||||
`do again := IF guess < random number THEN print("something"); TRUE ELIF guess > random number THEN print("something else"); TRUE ELSE print("another thing"); FALSE FI`
|
||||
```
|
||||
|
||||
Note that I also took care not to declare anything as a mutable value when unnecessary. Since the value `guess` only has the scope of the `WHILE` loop, it just defines a new value each time.
|
||||
|
||||
One nagging little problem I didn't handle stems from the use of `read int`; if the frustrated user types in a value that is not convertible to an integer, the program will stop with an error condition. You could manage this problem by calling the procedure `on value error`, which is similar to the `on logical file end` procedure. I'll leave that for you to figure out. You didn't think you'd get away from this without an exercise, did you?
|
||||
|
||||
### What we learned
|
||||
|
||||
In the introduction, I listed the programming concepts this exercise should explore. How did I do?
|
||||
|
||||
* **Variables:** This shows that Algol 68 thinks of variables as named locations and supports named (immutable) values.
|
||||
* **Input:** It used `stand in` as predefined console input and handled end-of-file conditions.
|
||||
* **Output:** It used `print` to print messages on the console.
|
||||
* **Conditional evaluation:** It used Algol 68 `if-then-else-fi` and `if` statements as expressions.
|
||||
* **Loops:** It used Algol 68's `while` loop, including using a sequence of statements to calculate the value to be tested.
|
||||
|
||||
|
||||
|
||||
It also used some Algol 68 standard library (which Algol 68 calls "standard prelude") functionality, including the random number generator and I/O exception testing.
|
||||
|
||||
Run the program:
|
||||
|
||||
|
||||
```
|
||||
$ a68g guess.a68
|
||||
the secret number is +26
|
||||
guess a number: 50
|
||||
too high, try again: 25
|
||||
too low, try again: 37
|
||||
too high, try again: 31
|
||||
too high, try again: 28
|
||||
too high, try again: 26
|
||||
that's right
|
||||
$
|
||||
```
|
||||
|
||||
One thing I didn't cover is comments. In Algol 68 Genie, comments can begin and end with the symbol `COMMENT`, or `CO`, or `#`, as in:
|
||||
|
||||
|
||||
```
|
||||
`# this is a comment #`
|
||||
```
|
||||
|
||||
If you're interested in exploring Algol 68, take a look at [Marcel's site][4] or the many contributed solutions in Algol 68 on [Rosetta Code][5].
|
||||
|
||||
In closing, back to the "dead languages" thing. Yes, it's a bit of an esoteric pursuit. But learning obscure languages is a great way to appreciate how far we've come (or, in some cases, not) and to give a more rounded perspective on language features we take for granted.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-algol-68
|
||||
|
||||
作者:[Chris Hermansen][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/clhermansen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/retro_old_unix_computer.png?itok=SYAb2xoW (Old UNIX computer)
|
||||
[2]: https://opensource.com/correspondent-program
|
||||
[3]: http://www.algol68.org/
|
||||
[4]: https://jmvdveer.home.xs4all.nl/en.algol-68-genie.html
|
||||
[5]: http://www.rosettacode.org/wiki/Rosetta_Code
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 open source security practices from 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/security)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
5 open source security practices from 2020
|
||||
======
|
||||
Here are manageable ways to keep your systems and data safe and secure.
|
||||
![Lock][1]
|
||||
|
||||
Few of us really want to read articles about security. They're usually uncomfortable (and overwhelming) reminders of the things we aren't doing to keep our data safe and secure. Luckily for us, this year, Opensource.com authors specifically focused on writing about manageable security tasks. Some are afternoon projects, while others are small steps you can take to improve your default security settings.
|
||||
|
||||
Here are 13 of our favorites.
|
||||
|
||||
### Encryption
|
||||
|
||||
How often have you watched a talk or read something about cryptography that is either so theoretical that it is hard to understand or so high-level that you don't have a concrete example to build on its themes? In _[Never forget your password with this Python encryption algorithm][2],_ Moshe Zadka gives us the best of both worlds: theory and application. Check it out!
|
||||
|
||||
We live in an increasingly complex world where we often need to manage several calendars at once. We have our work calendar, our kids' school and activity calendars, our personal appointments, sports and TV schedules… and, if you're using CalDAV, managing all of those calendars could put your security and privacy at risk. Ivan Kupalov explains how to avoid these risks in [_How to replace CalDAV with a secure calendar protocol_][3].
|
||||
|
||||
Mike Bursell introduces Enarx, a new "application deployment system enabling applications to run within Trusted Execution Environments (TEEs) without rewriting for particular platforms or SDKs." In [_Why we open sourced our security project_][4], Mike explains why he and his co-developer decided to make the project open source.
|
||||
|
||||
### Email infrastructure
|
||||
|
||||
Here's a bargain for you—two articles for the price of one: Free! Victor Lopes and Marc Skinner explain how SSL can help secure your email solutions. Victor's [_Eliminate spam using SSL with an open source certification authority_][5] introduces MailCleaner as an open source anti-spam solution for your email infrastructure, and Marc's [_How to secure your Linux email services with SSL/TLS_][6] walks through enabling SSL/TLS between email endpoints.
|
||||
|
||||
You may not have needed to manage SSL certificates before, but you've surely been affected by them. As a user, you've probably gotten an error message on your browser or experienced an outage on a favorite online service. As a system administrator, it's your responsibility to minimize or eliminate these experiences for customers. In [_Manage your SSL certificates with the ssl-on-demand script_][7], Abhishek Tamrakar offers some ideas on managing these certs and avoiding guaranteed headaches if you ignore them.
|
||||
|
||||
### Firewalls
|
||||
|
||||
If firewalls are one of your responsibilities (and they probably are), Seth Kenlon has you covered. First, he introduces _[Getting started with Linux firewalls][8],_ and then he takes a deeper dive into more advanced capabilities of firewalld in _[Open ports and route traffic through your firewall][9]._
|
||||
|
||||
### Vulnerability management
|
||||
|
||||
WordPress is by far the [most popular][10] web content management system, making it a popular target for cyber threats. Therefore, it is imperative that system administrators keep WordPress installations secure, and Lucy Carney offers [_6 tips for securing your WordPress website_][11] to help you do so.
|
||||
|
||||
Two words you often hear in security are hardening and compliance. In fact, the process of securing your system can also be called "hardening," and depending on your industry, internal or external parties (e.g., your infosec team or a government regulatory agency) may require you to "harden" your system to a minimum security level. Lynis is a tool that will help you achieve that level and audit its capabilities. Gaurav Kamathe's [_Scan your Linux security with Lynis_][12] will help you get started with it.
|
||||
|
||||
After you read Gaurav's article, Ari Noman's [_Use this command-line tool to find security flaws in your code_][13] will help you take the principles of hardening to the code level by using the Graudit tool to uncover programming flaws and code vulnerabilities.
|
||||
|
||||
### Identity management
|
||||
|
||||
Will you do me a favor? Before you continue reading, turn on two-factor authentication (2FA) in all of your accounts. Everywhere! And if your organization is looking for an open source solution to produce multi-factor authentication (MFA) in your services, look no further than privacyIDEA. Find out more in Cornelius Kölbel's [_Open source alternative for multi-factor authentication: privacyIDEA_][14].
|
||||
|
||||
In _[Protect your network with open source tools][15],_ Chantale Benoit introduces a couple of open source security tools under the Apache Foundation umbrella. They are Syncope, "an open source system for managing digital identities in an enterprise environment," and Metron, an "advanced security analytics framework that detects cyber anomalies, such as phishing activity and malware infections."
|
||||
|
||||
### Living a security lifestyle
|
||||
|
||||
Security is an ongoing practice. As these articles demonstrate, good security is something you integrate into your life and into your code. Give them all a read, and see what you can do to improve your digital security over the coming year.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/security
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum (Lock)
|
||||
[2]: https://opensource.com/article/20/6/python-passwords
|
||||
[3]: https://opensource.com/article/20/3/caldav-security
|
||||
[4]: https://opensource.com/article/20/8/why-open-source
|
||||
[5]: https://opensource.com/article/20/6/secure-open-source-antispam
|
||||
[6]: https://opensource.com/article/20/4/securing-linux-email
|
||||
[7]: https://opensource.com/article/20/2/ssl-demand
|
||||
[8]: https://opensource.com/article/20/2/firewall-cheat-sheet
|
||||
[9]: https://opensource.com/article/20/9/firewall
|
||||
[10]: https://w3techs.com/technologies/overview/content_management
|
||||
[11]: https://opensource.com/article/20/4/wordpress-security
|
||||
[12]: https://opensource.com/article/20/5/linux-security-lynis
|
||||
[13]: https://opensource.com/article/20/8/static-code-security-analysis
|
||||
[14]: https://opensource.com/article/20/3/open-source-multi-factor-authentication
|
||||
[15]: https://opensource.com/article/20/10/apache-security-tools
|
@ -0,0 +1,97 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Try a text editor inspired by Notepad++)
|
||||
[#]: via: (https://opensource.com/article/20/12/notepad-text-editor)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Try a text editor inspired by Notepad++
|
||||
======
|
||||
Classic notepads are reliable and familiar, and the new, improved
|
||||
versions offer endless plugins to customize your experience.
|
||||
![Writing Hand][1]
|
||||
|
||||
If you look online for great open source text editors, you’re bound to come across [Notepad++][2]. An enduring and popular editor, Notepad++ is built only for Windows. I use the open source operating system [Linux][3] but was nevertheless curious to experience Notepad++. Fortunately for me, I discovered one way to try Notepad++ (yes, it’s WINE) and one way to approximate it.
|
||||
|
||||
### Running Notepad++ in WINE
|
||||
|
||||
It seemed like a crazy idea at one time, but long ago, a group of developers wondered whether they could reverse engineer the system-level libraries that made Windows work and then release them as open source software. That’s what WINE is—a rewrite of the core components of Windows, allowing many Windows applications to run on Linux.
|
||||
|
||||
It’s a staggering achievement and one that has, among other things, helped the ReactOS project launch a Windows-like open source operating system, Valve Software to create Steam Play for running Windows games on Linux, and people who are over-curious about text editors to try Notepad++.
|
||||
|
||||
There are two steps involved in this process:
|
||||
|
||||
1. Install WINE on Linux from your software repository.
|
||||
2. Download the [Notepad++ EXE installer][4]. With WINE, you can launch it like a native application, and install Notepad++ to your system.
|
||||
|
||||
|
||||
|
||||
### Winetricks
|
||||
|
||||
Alternatively, you can use Winetricks to install applications, Notepad++ included. Winetricks is a shell script with tried-and-tested build scripts for dozens upon dozens of applications, games, fonts, and more. You can probably install Winetricks from your distribution's software repository. If it's not available, then you can download it yourself:
|
||||
|
||||
|
||||
```
|
||||
$ mkdir ~/bin
|
||||
$ cd ~/bin
|
||||
$ wget <https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks>
|
||||
$ chmod +x winetricks
|
||||
$ ./winetricks
|
||||
```
|
||||
|
||||
Winetricks is a simple menu-driven application. Find **npp** ("Notepad plus plus") in the **Install applications** menu selection.
|
||||
|
||||
![Winetricks][5]
|
||||
|
||||
There are a few things to get used to when using applications on Linux that believe they’re running on Windows, but nothing serious. You have to get used to the idea of hard drive locations designated by letters, and you might want to download and install some Windows themes to help your WINE environment feel better integrated with the rest of your system. Once you’ve used Notepad++ running on WINE, you quickly forget WINE is involved at all.
|
||||
|
||||
![Notepad++ running in WINE on Linux][6]
|
||||
|
||||
### Running Notepadqq
|
||||
|
||||
There’s no affiliation between Notepadqq and Notepad++, except that the former takes inspiration from the latter. They’re not identical applications, but if you’re a casual fan of the original, then you might find Notepadqq a suitable native replacement.
|
||||
|
||||
Notepadqq is easy to [install as a Flatpak][7] on Linux or a Chromebook. Alternately, you can [download and compile it from its source code][8]. Some support is provided for [compiling on MacOS][9], too.
|
||||
|
||||
![screenshot of black notepad terminal with white lettering][10]
|
||||
|
||||
### Notepad (improved)
|
||||
|
||||
Regardless of how you satiate your Notepad improved hunger, you’ll be pleased to find you have a responsive, customizable, and extensible editor. Both applications provide syntax highlighting for around 80 programming languages and text formats, including C, C++, Java, Python, Javascript, Lua, [Markdown][11], RPM spec files, and [YAML][12].
|
||||
|
||||
They also both use the concept of a session, or sets of files opened in your Notepad editor, which you can save and reload as needed. Using sessions helps you organize your work into projects.
|
||||
|
||||
Both Notepad applications can be extended through plugins. Notepad++ features a Plugins Admin panel, where you can browse through available plugins. Notepadqq doesn’t have the years of development that Notepad++ has had, and accordingly, doesn’t seem to have the abundance of available extensions. However, you can [develop your own using Node.js][13].
|
||||
|
||||
### Try a Notepad (improved)
|
||||
|
||||
Whether you stick with the classic Notepad++ or venture into the newer Notepadqq, you’re bound to find satisfaction with these reliable editors. They give you the features you expect for efficient text editing and the access you need so you can hack together your own extensions. These are both fun, reliable, and dependable projects, so give one (or both) a try today!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/notepad-text-editor
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/write-hand_0.jpg?itok=Uw5RJD03 (Writing Hand)
|
||||
[2]: https://notepad-plus-plus.org
|
||||
[3]: http://opensource.com/resources/what-linux
|
||||
[4]: https://notepad-plus-plus.org/downloads/
|
||||
[5]: https://opensource.com/sites/default/files/winetricks.png (Winetricks)
|
||||
[6]: https://opensource.com/sites/default/files/npp.png (Notepad++ running in WINE on Linux)
|
||||
[7]: https://flathub.org/apps/details/com.notepadqq.Notepadqq
|
||||
[8]: https://github.com/notepadqq/notepadqq
|
||||
[9]: https://github.com/notepadqq/notepadqq/wiki/Compiling-Notepadqq-on-macOS
|
||||
[10]: https://opensource.com/sites/default/files/uploads/notepad-31_days-notepad-opensource.png (screenshot of black notepad terminal with white lettering)
|
||||
[11]: https://opensource.com/article/19/9/introduction-markdown
|
||||
[12]: https://www.redhat.com/sysadmin/yaml-beginners
|
||||
[13]: https://github.com/notepadqq/notepadqq/wiki/How-to-write-an-extension-with-Node.js
|
@ -0,0 +1,59 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (10 lessons from sysadmins adapting to change in 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/sysadmin)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss)
|
||||
|
||||
10 lessons from sysadmins adapting to change in 2020
|
||||
======
|
||||
Adapting to change was a major theme in 2020, and throughout all the
|
||||
turmoil, we could count on sysadmins to keep us up and running.
|
||||
![Tips and gears turning][1]
|
||||
|
||||
While 2020 will certainly be remembered for elections, protests, and most of all, the COVID-19 pandemic, a lot of other things changed in 2020, including a whole lot of cool changes in technology. Through it all, we could count on system administrators to do what they do best. Perhaps more so than ever, as we all moved from physical offices to working from home. We generated more load than ever on our infrastructure as more users relied on virtual private networks and videoconference tools to get their daily work done.
|
||||
|
||||
Every year, we publish many articles to help systems administrators do their jobs better. Of the many articles we published this year, we believe these 10 offer the best insights for sysadmins in 2020. Several provide good examples of the importance of keeping up with change—which, after all, is the only thing we could count on this year.
|
||||
|
||||
1. [Manage network connections from the Linux command line with nmcli][2]: Dave McKay gives an overview of NetworkManager's `nmcli` command for network management in Linux. Using `nmcli` in place of `ifconfig` is strongly recommended in the latest versions of Linux.
|
||||
2. [5 new sudo features you need to know in 2020][3]: Following the theme of keeping up with change, Peter Czanik shows five new features of the `sudo` command. This crucial sysadmin tool gains power with recording and auditing capabilities and support for Python.
|
||||
3. [Start using systemd as a troubleshooting tool][4]: It's clear that systemd is here to stay. Correspondent David Both invites us on his journey from SystemV to systemd in yet another example of how system administrators need to adapt. In this article (part of an ongoing series), David demonstrates how to troubleshoot a problematic Apache HTTP service using systemd logs and status output.
|
||||
4. [5 ops hacks for sysadmins][5]: Server counts continue to rise alongside the demands on system administrators managing bare-metal hosts, containers, or virtual machines. As Stephen Bancroft starts this article: "As a sysadmin, every day I am faced with problems I need to solve quickly because there are users and managers who expect things to run smoothly." He discusses five tools, some "oldies but goodies," that remain extremely useful in 2020.
|
||||
5. [Load balance network traffic with HAProxy][6]: Load balancers are an important component of a high-availability infrastructure. They can be deployed for anything from large distributed enterprise applications down to your home lab. A great option for the latter is HAProxy, and Jim O'Connell shows how to set it up.
|
||||
6. [An SRE's guide to Memcached for building scalable applications][7]: After reading about load balancers, check out this article by Correspondent Moshe Zadka, as he takes you deeper into the application stack with an overview of Memcached. Moshe, a site reliability engineer, explains Memcached's value for high-performance systems that must respond to repeated requests under heavy load.
|
||||
7. [Why making mistakes makes me a better sysadmin][8]: Ben Cotton, the Fedora Linux Project's program manager, reminds us that we can learn from our mistakes. He explains that we can learn to avoid repeating mistakes through practice and testing. Now if only 2020 had a dry-run option!
|
||||
8. [10 Ansible modules for Linux system automation][9]: Automation is a great way to avoid those mistakes Ben writes about. Ricardo Gerardi specializes in automation, and in this article, he shows how to use Ansible to automate daily Linux system administration tasks, such as package installation and user creation, that are repetitive and, therefore, error-prone.
|
||||
9. [How I use Cockpit for my home's Linux server management][10]: Cockpit is a fairly new graphical tool for Linux system management. It is browser-based and handles local and remote management equally well. After using similar tools over the years, I wrote this article because I am impressed at how quickly Cockpit can be put to use. Installation is simple, and it is easy for any busy system administrator to learn.
|
||||
10. [4 ways I contribute to open source as a Linux systems administrator][11]: Open source projects and the communities that support them have taken a prominent role in 2020. In this article, Elizabeth Joseph shares some ways to get involved. She encourages system administrators and other open source users to join and contribute to projects. So, get involved and help make 2021 an even better year!
|
||||
|
||||
|
||||
|
||||
What sysadmin topics would you like to learn about on Opensource.com? Please share your ideas in the comments. We're always looking for new contributors, so please check out our [Contributor guidelines][12] if you want to write an article you think our readers would enjoy.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/sysadmin
|
||||
|
||||
作者:[Alan Formy-Duval][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/alanfdoss
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/gears_devops_learn_troubleshooting_lightbulb_tips_520.png?itok=HcN38NOk (Tips and gears turning)
|
||||
[2]: https://opensource.com/article/20/7/nmcli
|
||||
[3]: https://opensource.com/article/20/10/sudo-19
|
||||
[4]: https://opensource.com/article/20/5/systemd-troubleshooting-tool
|
||||
[5]: https://opensource.com/article/20/1/ops-hacks-sysadmins
|
||||
[6]: https://opensource.com/article/20/11/load-balancing-haproxy
|
||||
[7]: https://opensource.com/article/20/3/sre-memcached
|
||||
[8]: https://opensource.com/article/20/8/sysadmin-mistakes
|
||||
[9]: https://opensource.com/article/20/10/ansible-modules-linux
|
||||
[10]: https://opensource.com/article/20/11/cockpit-server-management
|
||||
[11]: https://opensource.com/article/20/7/open-source-sysadmin
|
||||
[12]: https://opensource.com/how-submit-article
|
@ -0,0 +1,150 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to Automatically Accept SSH Key Fingerprint?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-automatically-accept-ssh-key-fingerprint/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How to Automatically Accept SSH Key Fingerprint?
|
||||
======
|
||||
|
||||
**[SSH Secure Shell][1]** is an encryption network protocol that provides secure encrypted communications between two hosts.
|
||||
|
||||
It allows you to connect to a remote machine securely over an insecure network.
|
||||
|
||||
When you connect to a Linux system for the first time, SSH prompts you to accept the fingerprint of the machines to successfully establish the connection, since you do not have a fingerprint in your **“known_hosts”** file.
|
||||
|
||||
Fingerprint is a shortened version of the system’s public key.
|
||||
|
||||
To protect yourself from Man-in-the-Middle Attack (MITM), the ssh program verifies the fingerprint of the remote system ssh with the fingerprint stored since it was last connected.
|
||||
|
||||
If the fingerprint has changed you will be alerted and asked if you would like to proceed. Otherwise, you will be allowed to log in directly.
|
||||
|
||||
But sometimes you may need to accept SSH fingerprint automatically.
|
||||
|
||||
For instance, if you created a **[shell script][2]** to run against multiple machines to pull a report.
|
||||
|
||||
**Make a Note:** You are effectively bypassing SSH intended security through the methods below. It is less dangerous when using it on the internal network, but it is not advisable to use it on the public Internet or other untrusted networks.
|
||||
|
||||
This can be done using the following two methods.
|
||||
|
||||
* Automatically accept an ssh fingerprint using the “StrictHostKeyChecking=no” option with the ssh command
|
||||
* Auto accepts an ssh fingerprint using the ssk-keycan command
|
||||
|
||||
|
||||
|
||||
When you connect to a remote computer for the first time, you will be warned that the authenticity of the host cannot be established and presented with a key fingerprint to verify.
|
||||
|
||||
```
|
||||
$ ssh [email protected]
|
||||
The authenticity of host '192.168.1.4 (192.168.1.4)' can't be established.
|
||||
ECDSA key fingerprint is 6a:75:e3:ac:5d:f8:cc:04:01:7b:ef:4d:42:ad:b9:83.
|
||||
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
|
||||
Warning: Permanently added '192.168.1.4' (ECDSA) to the list of known hosts.
|
||||
[email protected]'s password:
|
||||
Last login: Mon Dec 14 14:16:51 2020 from 192.168.1.6
|
||||
```
|
||||
|
||||
Once you accept the fingerprint, it will be saved in the “known_hosts” file.
|
||||
|
||||
When reconnecting to the same remote host, SSH checks the fingerprint against the known_host file to verify its identity.
|
||||
|
||||
If this matches, you will be allowed direct access to the system as long as the key remains intact.
|
||||
|
||||
You will see the following warning if the fingerprint does not match the known_hosts. This happens if the host public key changes for some reason.
|
||||
|
||||
If you see the warning below, double-check that you are actually connecting with the right host on a secure connection. Although most of the time it is harmless, it can be an indication of a potential issue.
|
||||
|
||||
```
|
||||
$ ssh [email protected]
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
||||
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
|
||||
It is also possible that the RSA host key has just been changed.
|
||||
The fingerprint for the RSA key sent by the remote host is
|
||||
6a:75:e3:ac:5d:f8:cc:04:01:7b:ef:4d:42:ad:b9:83.
|
||||
Please contact your system administrator.
|
||||
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
|
||||
Offending key in /root/.ssh/known_hosts:1
|
||||
Password authentication is disabled to avoid man-in-the-middle attacks.
|
||||
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
|
||||
********************************************************
|
||||
Permission denied (publickey,password,keyboard-interactive).
|
||||
```
|
||||
|
||||
### 1) How to Automatically Accept SSH Key Fingerprint Using SSH Option?
|
||||
|
||||
This method is simple and straight forward, to achieve this only need to add an option with SSH command.
|
||||
|
||||
When you use this option, ssh will automatically add a new host key to the user known_host file and allow it to host connections with modified hostkeys to connect to the remote system.
|
||||
|
||||
```
|
||||
$ ssh -o "StrictHostKeyChecking no" 192.168.1.5
|
||||
Warning: Permanently added 'centos7,192.168.1.5' (ECDSA) to the list of known hosts.
|
||||
ok
|
||||
```
|
||||
|
||||
However, the above warning shows that it has added a key to the known_host file.
|
||||
|
||||
### 2) How to Automatically Accept SSH Key Fingerprint Using ssk-keyscan Command?
|
||||
|
||||
This is another method, it is very simple. The ssh-keycan tool allows you to append the ssh key fingerprint to the user-known_host file on the remote server.
|
||||
|
||||
This tool is very useful when you want to add bulk.
|
||||
|
||||
This command must be inserted into the shell script before calling the actual command in the script.
|
||||
|
||||
Use the following format to add the ssh key fingerprint to a remote host.
|
||||
|
||||
```
|
||||
$ ssh-keyscan -H 192.168.1.4 >> ~/.ssh/known_hosts
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
```
|
||||
|
||||
Use the following format to add the ssh key fingerprint to multiple hosts.
|
||||
|
||||
To do so, you must add the remote hosts details to a file and call it with the ssh-keycan command as follows. For example, I added five hosts to the **“remote-hosts.txt”** file.
|
||||
|
||||
You can use any text editor to add entries. I recommend you to use **[vim editor][3]**, the most flexible and powerful text editor widely used by Linux administrators and developers.
|
||||
|
||||
```
|
||||
# vi remote-hosts.txt
|
||||
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
```
|
||||
|
||||
If yes, the ssh-keyscan command would be as follows.
|
||||
|
||||
```
|
||||
$ ssh-keyscan -f /tmp/remote-hosts.txt >> ~/.ssh/known_hosts
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
#centos:22 SSH-2.0-OpenSSH_7.4
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-automatically-accept-ssh-key-fingerprint/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/category/ssh-tutorials/
|
||||
[2]: https://www.2daygeek.com/category/shell-scripts/
|
||||
[3]: https://www.2daygeek.com/basic-vim-commands-cheat-sheet-quick-start-guide/
|
290
sources/tech/20201222 Learn to use the Sed text editor.md
Normal file
290
sources/tech/20201222 Learn to use the Sed text editor.md
Normal file
@ -0,0 +1,290 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn to use the Sed text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/sed)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Learn to use the Sed text editor
|
||||
======
|
||||
Sed lacks the usual text boxes and instead writes directly on a file,
|
||||
directed by user commands.
|
||||
![Command line prompt][1]
|
||||
|
||||
Created for version 7 of AT&T’s original Unix operating system, the `sed` command has been included with probably every Unix and Linux OS since. The `sed` application is a _stream editor_, and unlike a text editor it doesn’t open a visual buffer into which a file’s data is loaded for processing. Instead, it operates on a file, line by line, according to either a command typed into a terminal or a series of commands in a script.
|
||||
|
||||
### Installing
|
||||
|
||||
If you’re using Linux, BSD, or macOS, then you already have GNU or BSD `sed` installed. These are two unique reimplementations of the original `sed` command, and while they’re similar, there can be minor differences. GNU `sed` is generally regarded to be the most feature-rich `sed` out there, and it’s widely available on any of these platforms.
|
||||
|
||||
If you can’t find GNU `sed` (often called `gsed` on non-Linux systems), then you can [download its source code from the GNU website][2]. The nice thing about having GNU `sed` installed is that it can be used for its extra functions, but it can also be constrained to conform to just the [POSIX][3] specifications of `sed`, should you require portability.
|
||||
|
||||
On Windows, you can [install][4] GNU `sed` with [Chocolatey][5].
|
||||
|
||||
### How Sed works
|
||||
|
||||
The `sed` application works on one line at a time. Because it has no visual display, it creates a pattern space—a space in memory containing the current line from the input stream (with any trailing newline character removed). Once the pattern space is populated, your instructions to `sed` are executed. Sometimes your commands are conditional, and other times they are absolute, so the results of these commands depend on how you’re using `sed`.
|
||||
|
||||
When the end of commands is reached, `sed` prints the contents of the pattern space to the output stream. The default output stream is **stdout**, but it can be redirected to a file or even back into the same file using the `--in-place=.bak` option.
|
||||
|
||||
Then the cycle begins again with the next input line.
|
||||
|
||||
The syntax for the `sed` command is:
|
||||
|
||||
|
||||
```
|
||||
`$ sed --options [optional SCRIPT] [INPUT FILE or STREAM]`
|
||||
```
|
||||
|
||||
#### Finding what you want to edit
|
||||
|
||||
In a visual editor, you usually locate what you want to change in a text file without thinking much about it. Your eye (or screen reader) scans the text, finds the word you want to change or the place you want to insert or remove text, and then you just start typing. There is no interactive mode for `sed`, though, so you must tell it what conditions must be met for it to run specific commands.
|
||||
|
||||
For these examples, assume that a file called `example.txt` contains this text:
|
||||
|
||||
|
||||
```
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
#### Line number
|
||||
|
||||
Specifying a line number tells `sed` to operate only on that specific line in the file.
|
||||
|
||||
For instance, this command selects line 1 of a file and prints it. Because `sed`’s default action after processing is also to print a line to **stdout**, this has the effect of duplicating the first line:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘1p’ example.txt
|
||||
hello
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
You can specify line numbers in steps, too. For instance, `1~2` indicates that every 2 lines are selected ("select every second line starting with the first"). The instruction `1~3` means to select every third line after the first:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘1p’ example.txt
|
||||
hello
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
#### Line position
|
||||
|
||||
You can operate only on the last line of a file by using `$` as a selector:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘$p’ example.txt
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
In GNU `sed`, you can select more than one line (`sed '1,$p'` prints the first and final line, for example).
|
||||
|
||||
#### Negation
|
||||
|
||||
Any selection by number or position, you can invert with the exclamation mark (`!`) character. This selects all lines _except_ the first line:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘1!p’ example.txt
|
||||
hello
|
||||
world
|
||||
world
|
||||
This is line three.
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
#### Pattern matching
|
||||
|
||||
You can think of a pattern match as a **find** operation in a word processor or a browser. You provide a word (a _pattern_), and the results are selected. The syntax for a pattern match is `/pattern/`.
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘/hello/p’ example.txt
|
||||
hello
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
$ sed ‘/line/p’ example.txt
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
### Editing with Sed
|
||||
|
||||
Once you’ve found what you want to edit, you can perform whatever action you want. You perform edits with `sed` with commands. Commands in `sed` are different from the `sed` command itself. If it helps, think of them as "actions" or "verbs" or "instructions."
|
||||
|
||||
Commands in `sed` are single letters, such as the `p` for **print** command used in previous examples. They can be difficult to recall at first, but as with everything, you get to know them with practice.
|
||||
|
||||
#### p for print
|
||||
|
||||
The `p` instruction prints whatever is currently held in pattern space.
|
||||
|
||||
#### d for delete
|
||||
|
||||
The `d` instruction deletes the pattern space.
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘$d’ example.txt
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
$ sed ‘1d’ example.txt
|
||||
world
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
#### s for search and replace
|
||||
|
||||
The `s` command searches for a pattern and replaces it with something else. This is probably the most popular and casual use for `sed`, and it’s often the first (and sometimes the only) `sed` command a user learns. It’s almost certainly the most useful command for text editing.
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/world/opensource.com/’
|
||||
hello
|
||||
opensource.com
|
||||
This is line three.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
There are special functions you can use in your replacement text, too. For instance, `\L` transforms the replacement text to lowercase and `\l` does the same for just the next character. There are others, which are listed in the `sed` documentation (you can view that with the `info sed` command).
|
||||
|
||||
The special character `&` in the replacement clause refers to the matched pattern:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/is/\U&/’ example.txt
|
||||
hello
|
||||
world
|
||||
ThIS is line three.
|
||||
Here IS the final line.
|
||||
```
|
||||
|
||||
You can also pass special flags to affect how `s` processes what it finds. The `g` (for _global_, presumably) flag tells `s` to apply the replacement to all matches found on the line and not just the first match:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/is/\U&/g’ example.txt
|
||||
hello
|
||||
world
|
||||
ThIS IS line three.
|
||||
Here IS the final line.
|
||||
```
|
||||
|
||||
Other important flags include a number to indicate which occurrence of a matched pattern to affect:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/is/\U&/2’ example.txt
|
||||
hello
|
||||
world
|
||||
This IS line three.
|
||||
Here is the final line.
|
||||
```
|
||||
|
||||
The `w` flag, followed by a filename, writes a matched line to a file _only if_ a change is made:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/is/\U&/w sed.log’ example.txt
|
||||
hello
|
||||
world
|
||||
ThIS is line three.
|
||||
Here IS the final line.
|
||||
$ cat sed.log
|
||||
ThIS is line three.
|
||||
Here IS the final line.
|
||||
```
|
||||
|
||||
Flags can be combined:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘s/is/\U&/2w sed.log’ example.txt
|
||||
hello
|
||||
world
|
||||
This IS line three.
|
||||
Here is the final line.
|
||||
$ cat sed.log
|
||||
This IS line three.
|
||||
```
|
||||
|
||||
### Scripts
|
||||
|
||||
There are lots of great sites out there with `sed` "one-liners." They give you task-oriented `sed` commands to solve common problems. However, learning `sed` for yourself enables you to write your own one-liners, and those can be tailored to your specific needs.
|
||||
|
||||
Scripts for `sed` can be written as lines in a terminal, or they can be saved to a file and executed with `sed` itself. I tend to write small scripts all as one command because I find myself rarely re-using `sed` commands in real life. When I write a `sed` script, it’s usually very specific to one file. For example, after writing the initial draft of this very article, I used `sed` to standardize the capitalization of "sed", and that’s a task I’ll probably never have to do again.
|
||||
|
||||
You can issue a series of distinct commands to `sed` separated by a semicolon (`;`).
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘3t ; s/line/\U&/’ example.txt
|
||||
hello
|
||||
world
|
||||
This is LINE three.
|
||||
This is the final line.
|
||||
```
|
||||
|
||||
### Scope changes with braces
|
||||
|
||||
You can also limit which results are affected with braces (`{}`). When you enclose `sed` commands in braces, they apply only to a specific selection. For example, the word "line" appears in two lines of the sample text. You can force `sed` to affect only the final line by declaring the required match condition (`$` to indicate the final line) and placing the `s` command you want to be performed in braces immediately thereafter:
|
||||
|
||||
|
||||
```
|
||||
$ sed ‘$ {s/line/\U&/}’ example.txt
|
||||
hello
|
||||
world
|
||||
This is line three.
|
||||
This is the final LINE.
|
||||
```
|
||||
|
||||
### Learn Sed
|
||||
|
||||
You can do a lot more with `sed` than what’s explained in this article. I haven’t even gotten to branching (`b`), tests (`t`), the _hold_ space (`H`), and many other features. Like [`ed`][6], `sed` probably isn’t the text editor you’re going to use for document creation or even for every scripted task you need doing, but it is a powerful option you have as a POSIX user. Learning how `sed` commands are structured and how to write short scripts can make for quick changes to massive amounts of text. Read through the `info` pages of GNU `sed`, or the man pages of BSD `sed`, and find out what `sed` can do for you.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/sed
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
|
||||
[2]: http://www.gnu.org/software/sed/
|
||||
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[4]: https://chocolatey.org/packages/sed
|
||||
[5]: https://opensource.com/article/20/3/chocolatey
|
||||
[6]: https://opensource.com/article/20/12/gnu-ed
|
@ -0,0 +1,88 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (10 Raspberry Pi project ideas from 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/raspberry-pi)
|
||||
[#]: author: (Joshua Allen Holm https://opensource.com/users/holmja)
|
||||
|
||||
10 Raspberry Pi project ideas from 2020
|
||||
======
|
||||
Find some great new projects for your Raspberry Pi from the year's top
|
||||
articles.
|
||||
![Vector, generic Raspberry Pi board][1]
|
||||
|
||||
The Raspberry Pi is the small, low-cost, single-board PC that took the world by storm when it was released in 2012. Since then, educators, students, makers, and tinkerers have used the various Raspberry Pi models for many, many unique and interesting projects. The possibilities are nearly endless.
|
||||
|
||||
Over the course of 2020, Opensource.com published many great articles about Raspberry Pi projects; below, I explore the top 10. I hope these articles educate, entertain, and inspire you.
|
||||
|
||||
### How I migrated from a Mac Mini to a Raspberry Pi
|
||||
|
||||
A Raspberry Pi as a main desktop computer? Absolutely. Peter Garner shares how he [switched from a Mac Mini to a Raspberry Pi][2]. When Garner's Mac Mini needed to be replaced, he turned to a Raspberry Pi Model 2. This article explains the hardware and software choices Garner made to turn a humble Raspberry Pi into a functional desktop computer. His software choices range from the operating system (Arch Linux) and desktop environment (LXDE) to various applications for web browsing, messaging, email, audio, video, image processing, and more.
|
||||
|
||||
### 6 Raspberry Pi tutorials to try out
|
||||
|
||||
Opensource.com editor Lauren Pritchett shares [_6 Raspberry Pi tutorials to try out_][3]. This roundup of Raspberry Pi projects highlights some of the many different ways the Raspberry Pi can be used. The projects include setting up a VPN server, creating an object-tracking camera, displaying your favorite photos in a slideshow, playing retro video games, building a clock, and managing a home-brewed beer operation.
|
||||
|
||||
### Build a Kubernetes cluster with the Raspberry Pi
|
||||
|
||||
Chris Collins explains [how to install a Kubernetes cluster][4] on three or more Raspberry Pi 4s running Ubuntu 20.04. From configuring the host system through creating a Kubernetes cluster, the instructions Collins provides will walk you though through everything you need to create "your own 'private cloud at home' container service."
|
||||
|
||||
### 5 reasons to run Kubernetes on your Raspberry Pi homelab
|
||||
|
||||
Opensource.com editor Seth Kenlon shares [_5 reasons to run Kubernetes on your Raspberry Pi homelab_][5]. Kenlon begins by introducing Opensource.com's Kubernetes eBook by Chris Collins. He then answers the question, "What do you need Kubernetes for, anyway?" His reasons include that you can create a network-attached storage for your home, it is a good educational and upskilling experience, and it provides benefits for working with containers, web development, and web servers.
|
||||
|
||||
### How to manage a big hotel with a little Raspberry Pi
|
||||
|
||||
This tutorial by Giuseppe Cassibba explains how to manage a [hotel reservation system with a Raspberry Pi][6]. He shows how to install QloApps, a web-based software package designed for hotels, on a Raspberry Pi 3. Cassibba begins his tutorial by walking through the steps to install and configure a LAMP stack on Raspbian, and then covers the specifics of installing and setting up QloApps. Once the tutorial is complete, the Raspberry Pi will be configured to function as a hotel management system with customer and administrator web-based user interfaces.
|
||||
|
||||
### Set up a Tor proxy with Raspberry Pi to control internet traffic
|
||||
|
||||
In another article, Giuseppe Cassibba explains how to control internet traffic by setting up a [Tor proxy with Raspberry Pi][7]. The article begins with a brief introduction to Tor, then asks a few questions to determine if you need a Tor proxy or can use the Tor browser. The rest of the article provides detailed instructions on how to configure a Raspberry Pi Zero W as a Tor proxy and how to configure a web browser to connect to that proxy.
|
||||
|
||||
### How to set up the Raspberry Pi Zero for travel
|
||||
|
||||
Peter Garner provides tips on how to [set up a Raspberry Pi for remote work][8]. Taking a work laptop on a business trip means dealing with company and airport security policies, which can be a pain. As an alternative, Garner configured a super-small, ultra-portable Raspberry Pi Zero to function as a computer to take on trips. This article explains how he configured his Pi Zero to suit his needs. Garner gives in-depth explanations for his hardware and software choices to create a computer that meets his needs. This article should inspire anyone seeking to create a similar device.
|
||||
|
||||
### How many Raspberry Pis do you own?
|
||||
|
||||
This Opensource.com poll asked readers to [count their Raspberry Pi collection][9]. This simple question could have resulted in readers providing nothing more than the number of Raspberry Pis they own, but many commenters provided interesting anecdotes about what they are doing with their Pis. The article is not extremely deep, but it was the catalyst for a very interesting selection of comments.
|
||||
|
||||
### Run Kubernetes on a Raspberry Pi with k3s
|
||||
|
||||
Lee Carpenter demonstrates how to [run a Kubernetes on a Raspberry Pi][10]. This tutorial explains how to use k3s, a lightweight Kubernetes for use in resource-constrained environments, on three Raspberry Pis. The instructions explain how to set up a master node with two worker nodes and to connect to this cluster from a PC.
|
||||
|
||||
### Customize your Raspberry Pi operating system for everyday use
|
||||
|
||||
Patrick H. Mullins shows how you can [customize Raspberry Pi OS for your needs][11]. Instead of using the full Raspberry Pi OS, Mullins recommends using Rasberry Pi OS Lite and modifying it for your preferences. This article shows how to add software to Raspberry Pi OS Lite to turn it into a custom desktop operating system. Instructions are provided for installing X Windows, the XFCE desktop environment, a small selection of essential applications, and some "optional goodies."
|
||||
|
||||
* * *
|
||||
|
||||
What do you want to learn about Raspberry Pi in 2021? Please share your ideas in the comments, and if you have knowledge to share, please [consider writing about it for Opensource.com][12].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/raspberry-pi
|
||||
|
||||
作者:[Joshua Allen Holm][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/holmja
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberrypi_board_vector_red.png?itok=yaqYjYqI (Vector, generic Raspberry Pi board)
|
||||
[2]: https://opensource.com/article/20/3/mac-raspberry-pi
|
||||
[3]: https://opensource.com/article/20/3/raspberry-pi-tutorials
|
||||
[4]: https://opensource.com/article/20/6/kubernetes-raspberry-pi
|
||||
[5]: https://opensource.com/article/20/8/kubernetes-raspberry-pi
|
||||
[6]: https://opensource.com/article/20/4/qloapps-raspberry-pi
|
||||
[7]: https://opensource.com/article/20/4/tor-proxy-raspberry-pi
|
||||
[8]: https://opensource.com/article/20/3/raspberry-pi-zero
|
||||
[9]: https://opensource.com/article/20/3/raspberry-pi-poll
|
||||
[10]: https://opensource.com/article/20/3/kubernetes-raspberry-pi-k3s
|
||||
[11]: https://opensource.com/article/20/6/custom-raspberry-pi
|
||||
[12]: https://opensource.com/how-submit-article
|
@ -0,0 +1,388 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Deploy Fedora CoreOS servers with Terraform)
|
||||
[#]: via: (https://fedoramagazine.org/deploy-fedora-coreos-with-terraform/)
|
||||
[#]: author: (Nathan Smith https://fedoramagazine.org/author/nfsmith/)
|
||||
|
||||
Deploy Fedora CoreOS servers with Terraform
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Photo by [Jasper Boer][2] on [Unsplash][3]
|
||||
|
||||
Fedora CoreOS is a lightweight, secure operating system optimized for running containerized workloads. A YAML document is all you need to describe the workload you’d like to run on a Fedora CoreOS server.
|
||||
|
||||
This is wonderful for a single server, but how would you describe a fleet of cooperating Fedora CoreOS servers? For example, what if you wanted a set of servers running load balancers, others running a database cluster and others running a web application? How can you get them all configured and provisioned? How can you configure them to communicate with each other? This article looks at how Terraform solves this problem.
|
||||
|
||||
### Getting started
|
||||
|
||||
Before you start, decide whether you need to review the basics of Fedora CoreOS. Check out this [previous article][4] on the Fedora Magazine:
|
||||
|
||||
> [Getting started with Fedora CoreOS][4]
|
||||
|
||||
**Terraform** is an open source tool for defining and provisioning infrastructure. Terraform defines infrastructure as code in files. It provisions infrastructure by calculating the difference between the desired state in code and observed state and applying changes to remove the difference.
|
||||
|
||||
HashiCorp, the company that created and maintains Terraform, offers an RPM repository to install Terraform.
|
||||
|
||||
```
|
||||
sudo dnf config-manager --add-repo \
|
||||
https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
|
||||
sudo dnf install terraform
|
||||
```
|
||||
|
||||
To get yourself familiar with the tools, start with a simple example. You’re going to create a single Fedora CoreOS server in AWS. To follow along, you need to install _awscli_ and have an AWS account. _awscli_ can be installed from the Fedora repositories and configured using the _aws configure_ command
|
||||
|
||||
```
|
||||
sudo dnf install -y awscli
|
||||
aws configure
|
||||
```
|
||||
|
||||
_**Please note,** AWS is a paid service. If executed correctly, participants should expect less than $1 USD in charges, but mistakes may lead to unexpected charges_.
|
||||
|
||||
### Configuring Terraform
|
||||
|
||||
In a new directory, create a file named _config.yaml_. This file will hold the contents of your Fedore CoreOS configuration. The configuration simply adds an SSH key for the _core_ user. Modify the ******_authorized_ssh_key_ section to use your own.
|
||||
|
||||
```
|
||||
variant: fcos
|
||||
version: 1.2.0
|
||||
passwd:
|
||||
users:
|
||||
- name: core
|
||||
authorized_ssh_keys:
|
||||
- "ssh-ed25519 AAAAC3....... user@hostname"
|
||||
```
|
||||
|
||||
Next, create a file _main.tf_ to contain your Terraform specification. Take a look at the contents section by section. It begins with a block to specify the versions of your providers.
|
||||
|
||||
```
|
||||
terraform {
|
||||
required_providers {
|
||||
ct = {
|
||||
source = "poseidon/ct"
|
||||
version = "0.7.1"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Terraform uses providers to control infrastructure. Here it uses the AWS provider to provision EC2 servers, but it can provision any kind of AWS infrastructure. The [ct provider][5] from [Poseidon Labs][6] stands for _config transpiler_. This provider will [transpile][7] Fedora CoreOS configurations into Ignition configurations. As a result, you do not need to use _[fcct][8]_ to transpile your configurations. Now that your provider versions are specified, initialize them.
|
||||
|
||||
```
|
||||
provider "aws" {
|
||||
region = "us-west-2"
|
||||
}
|
||||
|
||||
provider "ct" {}
|
||||
```
|
||||
|
||||
The AWS region is set to _us-west-2_ and the _ct_ provider requires no configuration. With the providers configured, you’re ready to define some infrastructure. Use a _[data source][9]_ block to read the configuration.
|
||||
|
||||
```
|
||||
data "ct_config" "config" {
|
||||
content = file("config.yaml")
|
||||
strict = true
|
||||
}
|
||||
```
|
||||
|
||||
With this data block defined, you can now access the transpiled Ignition output as _data.ct_config.config.rendered_. To create an EC2 server, use a [resource][10] block, and pass the Ignition output as the _user_data_ attribute.
|
||||
|
||||
```
|
||||
resource "aws_instance" "server" {
|
||||
ami = "ami-0699a4456969d8650"
|
||||
instance_type = "t3.micro"
|
||||
user_data = data.ct_config.config.rendered
|
||||
}
|
||||
```
|
||||
|
||||
This configuration hard-codes the virtual machine image (AMI) to the latest _stable_ image of Fedora CoreOS in the _us-west-2_ region at time of writing. If you would like to use a different region or stream, you can discover the correct AMI on the [Fedora CoreOS downloads page][11].
|
||||
|
||||
Finally, you’d like to know the public IP address of the server once it’s created. Use an _[output][12]_ block to define the outputs to be displayed once Terraform completes its provisioning.
|
||||
|
||||
```
|
||||
output "instance_ip_addr" {
|
||||
value = aws_instance.server.public_ip
|
||||
}
|
||||
```
|
||||
|
||||
Alright! You’re ready to create some infrastructure. To deploy the server simply run:
|
||||
|
||||
```
|
||||
terraform init # Installs the provider dependencies
|
||||
terraform apply # Displays the proposed changes and applies them
|
||||
```
|
||||
|
||||
Once **completed, Terraform prints the public IP address of the server, and you can SSH to the server by running _ssh core@{public ip here}_. Congratulations — you’ve provisioned your first Fedora CoreOS server using Terraform!
|
||||
|
||||
### Updates and immutability
|
||||
|
||||
At this point you can modify the configuration in _config.yaml_ however you like. To deploy your change simply run _terraform apply_ again. Notice that each time you change the configuration, when you run _terraform apply_ it destroys the server and creates a new one. This aligns well with the Fedora CoreOS philosophy: Configuration can only happen once. Want to change that configuration? Create a new server. This can feel pretty alien if you’re accustomed to provisioning your servers once and continuously re-configuring them with tools like [Ansible][13], [Puppet][14] or [Chef][15].
|
||||
|
||||
The benefit of always creating new servers is that it is significantly easier to test that newly provisioned servers will act as expected. It can be much more difficult to account for all of the possible ways in which updating a system in place may break. Tooling that adheres to this philosophy typically falls under the heading of _Immutable Infrastructure_. This approach to infrastructure has some of the same benefits seen in functional programming techniques, namely that mutable state is often a source of error.
|
||||
|
||||
### Using variables
|
||||
|
||||
You can use Terraform [input variables][16] to parameterize your infrastructure. In the previous example, you might like to parameterize the AWS region or instance type. This would let you deploy several instances of the same configuration with differing parameters. What if you want to parameterize the Fedora CoreOS configuration? Do so using the [_templatefile_][17] function.
|
||||
|
||||
As an example, try parameterizing the username of your user. To do this, add a _username_ variable to the _main.tf_ file:
|
||||
|
||||
```
|
||||
variable "username" {
|
||||
type = string
|
||||
description = "Fedora CoreOS user"
|
||||
default = "core"
|
||||
}
|
||||
```
|
||||
|
||||
Next, modify the _config.yaml_ file to turn it into a template. When rendered, the _${username}_ will be replaced.
|
||||
|
||||
```
|
||||
variant: fcos
|
||||
version: 1.2.0
|
||||
passwd:
|
||||
users:
|
||||
- name: ${username}
|
||||
authorized_ssh_keys:
|
||||
- "ssh-ed25519 AAAAC3....... user@hostname"
|
||||
```
|
||||
|
||||
Finally, modify the data block to render the template using the _templatefile_ function.
|
||||
|
||||
```
|
||||
data "ct_config" "config" {
|
||||
content = templatefile(
|
||||
"config.yaml",
|
||||
{ username = var.username }
|
||||
)
|
||||
strict = true
|
||||
}
|
||||
```
|
||||
|
||||
To deploy with _username_ set to _jane_, run _terraform apply -var=”username=jane”_. To verify, try to SSH into the server with _ssh jane@{public ip address}_.
|
||||
|
||||
### Leveraging the dependency graph
|
||||
|
||||
Passing variables from Terraform into Fedora CoreOS configuration is quite useful. But you can go one step further and pass infrastructure data into the server configuration. This is where Terraform and Fedora CoreOS start to really shine.
|
||||
|
||||
Terraform creates a [dependency graph][18] to model the state of infrastructure and to plan updates. If the output of one resource (e.g the public IP address of a server) is passed as the input of another service (e.g the destination in a firewall rule), Terraform understands that changes in the former require recreating or modifying the later. If you pass infrastructure data into a Fedora CoreOS configuration, it will participate in the dependency graph. Updates to the inputs will trigger creation of a new server with the new configuration.
|
||||
|
||||
Consider a system of one load balancer and three web servers as an example.
|
||||
|
||||
![][19]
|
||||
|
||||
The goal is to configure the load balancer with the IP address of each web server so that it can forward traffic to them.
|
||||
|
||||
### Web server configuration
|
||||
|
||||
First, create a file _web.yaml_ and add a simple Nginx configuration with a templated message.
|
||||
|
||||
```
|
||||
variant: fcos
|
||||
version: 1.2.0
|
||||
systemd:
|
||||
units:
|
||||
- name: nginx.service
|
||||
enabled: true
|
||||
contents: |
|
||||
[Unit]
|
||||
Description=Nginx Web Server
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
[Service]
|
||||
ExecStartPre=-/bin/podman kill nginx
|
||||
ExecStartPre=-/bin/podman rm nginx
|
||||
ExecStartPre=/bin/podman pull nginx
|
||||
ExecStart=/bin/podman run --name nginx -p 80:80 -v /etc/nginx/index.html:/usr/share/nginx/html/index.html:z nginx
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
storage:
|
||||
directories:
|
||||
- path: /etc/nginx
|
||||
files:
|
||||
- path: /etc/nginx/index.html
|
||||
mode: 0444
|
||||
contents:
|
||||
inline: |
|
||||
<html>
|
||||
<h1>Hello from Server ${count}</h1>
|
||||
</html>
|
||||
```
|
||||
|
||||
In _main.tf_, you can create three web servers using this template with the following blocks:
|
||||
|
||||
```
|
||||
data "ct_config" "web" {
|
||||
count = 3
|
||||
content = templatefile(
|
||||
"web.yaml",
|
||||
{ count = count.index }
|
||||
)
|
||||
strict = true
|
||||
}
|
||||
|
||||
resource "aws_instance" "web" {
|
||||
count = 3
|
||||
ami = "ami-0699a4456969d8650"
|
||||
instance_type = "t3.micro"
|
||||
user_data = data.ct_config.web[count.index].rendered
|
||||
}
|
||||
```
|
||||
|
||||
Notice the use of _count = 3_ and the _count.index_ variable. You can use [count][20] to make many copies of a resource. Here, it creates three configurations and three web servers. The _count.index_ variable is used to pass the first configuration to the first web server and so on.
|
||||
|
||||
### Load balancer configuration
|
||||
|
||||
The load balancer will be a basic [HAProxy load balancer][21] that forwards to each server. Place the configuration in a file named _lb.yaml_:
|
||||
|
||||
```
|
||||
variant: fcos
|
||||
version: 1.2.0
|
||||
systemd:
|
||||
units:
|
||||
- name: haproxy.service
|
||||
enabled: true
|
||||
contents: |
|
||||
[Unit]
|
||||
Description=Haproxy Load Balancer
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
[Service]
|
||||
ExecStartPre=-/bin/podman kill haproxy
|
||||
ExecStartPre=-/bin/podman rm haproxy
|
||||
ExecStartPre=/bin/podman pull haproxy
|
||||
ExecStart=/bin/podman run --name haproxy -p 80:8080 -v /etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
storage:
|
||||
directories:
|
||||
- path: /etc/haproxy
|
||||
files:
|
||||
- path: /etc/haproxy/haproxy.cfg
|
||||
mode: 0444
|
||||
contents:
|
||||
inline: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
defaults
|
||||
mode tcp
|
||||
log global
|
||||
option tcplog
|
||||
frontend http
|
||||
bind *:8080
|
||||
default_backend http
|
||||
backend http
|
||||
balance roundrobin
|
||||
%{ for name, addr in servers ~}
|
||||
server ${name} ${addr}:80 check
|
||||
%{ endfor ~}
|
||||
```
|
||||
|
||||
The template expects a [map][22] with server names as keys and IP addresses as values. You can create that using the [_zipmap_][23] function. Use the ID of the web servers as keys and the public IP addresses as values.
|
||||
|
||||
```
|
||||
data "ct_config" "lb" {
|
||||
content = templatefile(
|
||||
"lb.yaml",
|
||||
{
|
||||
servers = zipmap(
|
||||
aws_instance.web.*.id,
|
||||
aws_instance.web.*.public_ip
|
||||
)
|
||||
}
|
||||
)
|
||||
strict = true
|
||||
}
|
||||
|
||||
resource "aws_instance" "lb" {
|
||||
ami = "ami-0699a4456969d8650"
|
||||
instance_type = "t3.micro
|
||||
user_data = data.ct_config.lb.rendered
|
||||
}
|
||||
```
|
||||
|
||||
Finally, add an output block to display the IP address of the load balancer.
|
||||
|
||||
```
|
||||
output "load_balancer_ip" {
|
||||
value = aws_instance.lb.public_ip
|
||||
}
|
||||
```
|
||||
|
||||
All right! Run _terraform apply_ and the IP address of the load balancer displays on completion. You should be able to make requests to the load balancer and get responses from each web server.
|
||||
|
||||
```
|
||||
$ export LB={{load balancer IP here}}
|
||||
$ curl $LB
|
||||
<html>
|
||||
<h1>Hello from Server 0</h1>
|
||||
</html>
|
||||
$ curl $LB
|
||||
<html>
|
||||
<h1>Hello from Server 1</h1>
|
||||
</html>
|
||||
$ curl $LB
|
||||
<html>
|
||||
<h1>Hello from Server 2</h1>
|
||||
</html>
|
||||
```
|
||||
|
||||
Now you can modify the configuration of the web servers or load balancer. Any changes can be realized by running _terraform apply_ once again. Note in particular that any change to the web server IP addresses will cause Terraform to recreate the load balancer (changing the count from 3 to 4 is a simple test). Hopefully this emphasizes that the load balancer configuration is indeed a part of the Terraform dependency graph.
|
||||
|
||||
### Clean up
|
||||
|
||||
You can destroy all the infrastructure using the _terraform destroy_ command. Simply navigate to the folder where you created _main.tf_ and run _terraform destroy_.
|
||||
|
||||
### Where next?
|
||||
|
||||
Code for this tutorial can be found at [this GitHub repository][24]. Feel free to play with examples and contribute more if you find something you’d love to share with the world. To learn more about all the amazing things Fedora CoreOS can do, dive into [the docs][25] or come chat with [the community][26]. To learn more about Terraform, you can rummage through [the docs][27], checkout #terraform on [freenode][28], or contribute on [GitHub][29].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/deploy-fedora-coreos-with-terraform/
|
||||
|
||||
作者:[Nathan Smith][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/nfsmith/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/12/terraform-816x345.jpg
|
||||
[2]: https://unsplash.com/@jasperboer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/s/photos/landscape?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/getting-started-with-fedora-coreos/
|
||||
[5]: https://github.com/poseidon/terraform-provider-ct
|
||||
[6]: https://www.psdn.io/
|
||||
[7]: https://en.wikipedia.org/wiki/Source-to-source_compiler
|
||||
[8]: https://docs.fedoraproject.org/en-US/fedora-coreos/using-fcct/
|
||||
[9]: https://www.terraform.io/docs/configuration/data-sources.html
|
||||
[10]: https://www.terraform.io/docs/configuration/blocks/resources/syntax.html
|
||||
[11]: https://getfedora.org/en/coreos/download?tab=cloud_launchable&stream=stable
|
||||
[12]: https://www.terraform.io/docs/configuration/outputs.html
|
||||
[13]: https://www.ansible.com/
|
||||
[14]: https://puppet.com/
|
||||
[15]: https://www.chef.io/
|
||||
[16]: https://www.terraform.io/docs/configuration/variables.html
|
||||
[17]: https://www.terraform.io/docs/configuration/functions/templatefile.html
|
||||
[18]: https://www.terraform.io/docs/internals/graph.html
|
||||
[19]: https://fedoramagazine.org/wp-content/uploads/2020/12/diagram.png
|
||||
[20]: https://www.terraform.io/docs/configuration/meta-arguments/count.html
|
||||
[21]: https://www.haproxy.org/
|
||||
[22]: https://www.terraform.io/docs/configuration/expressions/types.html#maps-objects
|
||||
[23]: https://www.terraform.io/docs/configuration/functions/zipmap.html
|
||||
[24]: https://github.com/nsmith5/fcos-terraform-tutorial
|
||||
[25]: https://docs.fedoraproject.org/en-US/fedora-coreos/getting-started/
|
||||
[26]: https://discussion.fedoraproject.org/c/server/coreos/5
|
||||
[27]: https://www.terraform.io/docs/index.html
|
||||
[28]: https://freenode.net/
|
||||
[29]: https://github.com/hashicorp/terraform
|
@ -0,0 +1,79 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use the Eclipse IDE as your text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/eclipse)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
How to use the Eclipse IDE as your text editor
|
||||
======
|
||||
Though technically an IDE, Eclipse offers a robust editing suite with
|
||||
lots of extensions to give you the tools you need.
|
||||
![Women in computing and open source v5][1]
|
||||
|
||||
Eclipse is an IDE (integrated development environment). It’s definitely not a text editor. Then again, an IDE is really just a text editor with a lot of extra features for specific kinds of text. Furthermore, an IDE is often _home_ to a developer. Developers have their IDE of choice open all day long, so it’s natural to stay in that IDE when it’s time to write a project README file, or to jot down a quick note, or to just make a grocery list. So sometimes, an IDE is just a text editor, after all.
|
||||
|
||||
### Installing
|
||||
|
||||
One of Eclipse’s advantages as a platform is that it’s wildly popular. It’s the default Java IDE in many a classroom and business, and it’s easy to obtain regardless of your operating system.
|
||||
|
||||
On Linux, you can install Eclipse from your software repository.
|
||||
|
||||
On Mac or Windows, download an installer from [eclipse.org][2].
|
||||
|
||||
Eclipse is a big project, so if you have a favorite programming language, you can download a version of Eclipse tuned specifically for that language. However, you can’t go wrong by just downloading the Java one and adding extensions to it for further development options.
|
||||
|
||||
### Launching Eclipse
|
||||
|
||||
When you first launch Eclipse, you’re prompted to establish a workspace. This is a useful convention of many IDEs, designed to ensure that all of your active development libraries and projects are centrally located on your computer. This way, you don’t throw out a directory of libraries and headers you’ve forgotten your project relies upon, and you’re less likely to bundle in libraries from your base system, forgetting that your users will need to install them separately before running your code. The default location for Eclipse’s workspace is `~/eclipse-workspace`.
|
||||
|
||||
![eclipse workspace with white text on grey background][3]
|
||||
|
||||
### Eclipse projects
|
||||
|
||||
Eclipse is designed for formal _projects_. It assumes that you’re building an application or command or library consisting of many related files. Even when you create a text file, Eclipse assumes that it’s probably a `README` or a configuration file for your project. If you want to use Eclipse to create arbitrary text files that are not associated with a code project, then you can create a project file just for your text files.
|
||||
|
||||
To create a new project, navigate to the **File** menu and select **New Project**. From the list of project templates, select **General**. Once you have a project created, you can use it to store arbitrary text files created and maintained within Eclipse.
|
||||
|
||||
### Extensions
|
||||
|
||||
By default, Eclipse is adept with XML and can handle plain text adequately. [I write in XML whenever I get the chance][4], and Eclipse makes for an excellent XML workbench. If you don’t write in XML for fun, though, you might prefer to have syntax highlighting for your favorite syntax, too. Eclipse is extensible, so you can install plugins to add to its features.
|
||||
|
||||
One of my favorite plugins is [LiClipseText][5], a configurable syntax highlighter for several text formats. To install it (or any Eclipse extension), navigate to the **Help** menu and select **Eclipse Marketplace**. Search the Marketplace for LiClipse, and then click the **Install** button on the result. Depending on the speed of your Internet and computer, wait for the extension to install, and then allow Eclipse to restart so it can load the extension into your environment.
|
||||
|
||||
![Eclipse marketplace showing available editors ][6]
|
||||
|
||||
In my experience, most document format plugins are activated according to file extension association. In other words, when I open a file with a name ending in .md or .mdown, LiClipseText is enabled in the text editing window.
|
||||
You can adjust file associations in Eclipse’s preferences in case you want to override defaults loaded by an extension or by Eclipse itself.
|
||||
|
||||
### Eclipse for text editing
|
||||
|
||||
Writing in Eclipse feels very natural. After all, Eclipse primarily operates upon text anyway, so it’s well equipped whether your text contains code or natural language. In fact, I’ve found that there are some small bonuses to using a code editor like Eclipse for natural language processing. For instance, the occurrence marker in Eclipse highlights all occurrences of a specific term. When programming, this is useful so you can visualize where variables and functions are being used. When you’re writing, you can activate the same feature, and I’ve found that it helps me keep the terms I’m using consistent, and by contrast, it helps me detect overuse of any given phrase.
|
||||
|
||||
Eclipse can also handle diffs and patches with ease, and it’s got version control integration, so synchronizing work between computers is trivial.
|
||||
|
||||
Whether you use Eclipse as your primary text editor or just for required text files you’re bundling along with applications you develop, it’s a great platform for writing.
|
||||
|
||||
How to set up your Eclipse environment with Python and EASE, and a few ideas to supercharge your...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/eclipse
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss (Women in computing and open source v5)
|
||||
[2]: https://www.eclipse.org/downloads/packages/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/eclipse-31_days-eclipse-opensource.png (eclipse workspace with white text on grey background)
|
||||
[4]: https://opensource.com/article/17/9/docbook
|
||||
[5]: https://marketplace.eclipse.org/content/liclipsetext
|
||||
[6]: https://opensource.com/sites/default/files/uploads/eclipse-marketplace-31_days-eclipse-opensource.jpg (Eclipse marketplace showing available editors )
|
123
sources/tech/20201224 5 reasons to use the Atom text editor.md
Normal file
123
sources/tech/20201224 5 reasons to use the Atom text editor.md
Normal file
@ -0,0 +1,123 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 reasons to use the Atom text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/atom)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
5 reasons to use the Atom text editor
|
||||
======
|
||||
Atom is a comprehensive environment that can accomplish tasks from basic
|
||||
to complex, for users from beginners to veterans.
|
||||
![Science lab with beakers][1]
|
||||
|
||||
Beautiful open source text editors are pretty common these days, between Adobe’s [Brackets][2], Microsoft’s [VSCode][3], and GitHub’s [Atom][4]. Each of these seem to offer similar experiences: a modern interface, easily installable plugins, and a big brand-name sponsor. And they’re all actually really good. So what sets Atom apart from any other hyper-modern text editor? Or from a classic old editor like [Vim][5] or [Emacs][6]?
|
||||
|
||||
![Atom terminal with white text on dark grey background][7]
|
||||
|
||||
I’ve used lots of text editors, and upon reflection, I have to admit that once you’ve seen one text editor, you’ve basically seen them all. When judging an editor’s efficacy, 80% of the requirements are satisfied as long as it does one thing: edit text. The other 20% are bonus conveniences, extra gizmos, and fanciful features. They’re nice to have but hardly essential.
|
||||
|
||||
I often come back to Atom, though, because, as a user of open source, I have the luxury of using an application just because I can. Here’s what I like about Atom.
|
||||
|
||||
### Beginner-friendly
|
||||
|
||||
One of my favorite things about Atom is that it feels pretty "normal." I can install Atom on anyone’s computer and they’re off and typing in no time. No new keyboard shortcuts to learn, no serious deviations from user interface conventions. If I take a few minutes to show them a few power features of the application, then they're quickly empowered to install new plugins and discover useful features they enjoy.
|
||||
|
||||
It’s just different enough to feel unique but "safe" enough to trick people into believing (and rightly so) they can use it. That’s a hard line to walk, but Atom manages it, and I appreciate it for that.
|
||||
|
||||
### Great extensions
|
||||
|
||||
When most requirements have been filled as soon as you launch the application, a major factor in "selling" an open source text editor is its extensions. My habitual editor is [GNU Emacs][8], which has a mind-boggling array of extensions so versatile that they can provide everything from an email client to a video game. That’s a hard act to top, and to be honest, I’ve yet to see the editor that can. It shows how important extensions can be, though, and Atom has a nice set of plugins.
|
||||
|
||||
There are extensions to add syntax highlighting for languages and formats, to add dynamic linting, and to integrate debuggers, runtime environments, video and music player controls, and much more.
|
||||
You can practically make Atom the control hub for your desktop, so you rarely have to leave it.
|
||||
|
||||
### Language and syntax support
|
||||
|
||||
I’m a documented fan of [Docbook][9]. By extension, I’m a fan of its simplified front-end, Asciidoc. When I evaluate an editor, Docbook schema and Asciidoc support are two of my primary metrics. While XML support is relatively common, integration with a specific schema can be a tall order, and Asciidoc is still relatively obscure. Atom's community provides great support for my favorite formats.
|
||||
|
||||
Of course, I’ve already mentioned that Atom has great extensions in general, but syntax highlighting is an important feature regardless of what language you're typing. Once again, thanks to a vibrant community, the variety of syntax highlighter options in Atom’s package repository is one of the best.
|
||||
|
||||
### Easy theming
|
||||
|
||||
Atom makes generating your own style as easy as styling a website, so if you’re competent with CSS, you can make your own Atom theme. To create your own theme, navigate to the **Package** menu. If you don’t see a **Package** menu, press the **Alt** key first to reveal the top menu bar. In the **Package** menu, hover over **Package Generator** and then select **Generate Atom Syntax Theme**. This opens a new project called _my-theme-syntax_ by default. You can name it whatever you want, but it should end in `-syntax` according to Atom convention.
|
||||
|
||||
In your new theme project, locate these files: `base.less`, `colors.less`, and `syntax-variables.less`. These define how special keywords, and even background and foreground colors, are themed when your syntax is active. Because they all inherit values from a common template, it’s pretty easy to hack on. For example:
|
||||
|
||||
|
||||
```
|
||||
// Syntax styles
|
||||
|
||||
.syntax--comment {
|
||||
color: @light-gray;
|
||||
}
|
||||
|
||||
.syntax--keyword {
|
||||
color: @purple;
|
||||
|
||||
&.syntax--control {
|
||||
color: @purple;
|
||||
}
|
||||
|
||||
&.syntax--operator {
|
||||
color: @syntax-text-color;
|
||||
}
|
||||
|
||||
&.syntax--other.syntax--special-method {
|
||||
color: @blue;
|
||||
}
|
||||
|
||||
&.syntax--other.syntax--unit {
|
||||
color: @orange;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The values ending with two dashes, such as `.syntax--keyword`, are objects recognized by a syntax highlighting engine. If you want to develop your customizations further, of course, you can even create your own syntax definitions (although that’s more work than CSS theming). Read all about the ways to hack Atom at [flight-manual.atom.io][10].
|
||||
|
||||
### Flexible workflow
|
||||
|
||||
Atom has lots of features, and only a subset of them are activated by default. This means you get to decide how you prefer to work, whether you activate new extensions and use them to change Atom on a fundamental level, or you just open up Atom’s preferences and make small adjustments. You can use Atom for writing a fiction book or for writing Python code or technical documentation or anything else.
|
||||
|
||||
Even its Git integration doesn’t insist on what you might imagine would be the obvious repository (Github sponsors Atom). It doesn’t have an agenda, and it’s equally useful to everyone, regardless of audience.
|
||||
|
||||
## Installing
|
||||
|
||||
On Linux, Windows, and macOS, you can [install Atom from its website][11].
|
||||
|
||||
Alternately, on Linux, you can install Atom as a Flatpak from [Flathub][12].
|
||||
|
||||
If you want to build Atom yourself, you can also [compile it from its source code on Github][13].
|
||||
|
||||
## Try Atom
|
||||
|
||||
Atom could be your next text editor, notepad, and IDE. It’s easy to use, easy to configure, easy to extend, and it offers a great user experience. Download Atom today, and give it a try.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/atom
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/science_experiment_beaker_lab.png?itok=plKWRhlU (Science lab with beakers)
|
||||
[2]: https://opensource.com/article/20/12/brackets
|
||||
[3]: https://opensource.com/article/20/12/%C2%A0https://opensource.com/article/20/6/open-source-alternatives-vs-code
|
||||
[4]: https://opensource.com/article/17/5/atom-text-editor-packages-writers
|
||||
[5]: https://opensource.com/article/20/12/vi-text-editor
|
||||
[6]: https://opensource.com/article/20/12/emacs
|
||||
[7]: https://opensource.com/sites/default/files/uploads/atom-31_days-atom-opensource.png (Atom terminal with white text on dark grey background)
|
||||
[8]: https://opensource.com/article/20/2/who-cares-about-emacs
|
||||
[9]: https://opensource.com/article/17/9/docbook
|
||||
[10]: https://flight-manual.atom.io/
|
||||
[11]: https://atom.io
|
||||
[12]: https://flathub.org/apps/details/io.atom.Atom
|
||||
[13]: https://github.com/atom
|
@ -0,0 +1,80 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (3 critical DevOps concepts we explored in 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/devops)
|
||||
[#]: author: (Dawn Parzych https://opensource.com/users/dawnparzych)
|
||||
|
||||
3 critical DevOps concepts we explored in 2020
|
||||
======
|
||||
In 2020, Opensource.com's top DevOps articles focused on testing,
|
||||
software methodologies, and the most important part: the people
|
||||
![Looking at a map][1]
|
||||
|
||||
Looking back through Opensource.com's articles about [DevOps][2] in 2020, there was a bit of something for everyone—from people starting the DevOps journey to seasoned DevOps veterans. The articles focused on testing, software methodologies, and DevOps' most important part: the people. Here are the top 10 DevOps articles of 2020.
|
||||
|
||||
### Test-driven development
|
||||
|
||||
Alex Bunardzic shared [many articles about testing][3] this year, and I narrowed the list down to the top three. If you are interested in testing (and I would argue that anybody involved in writing or supporting software should have at least a passing interest in testing), check out these articles.
|
||||
|
||||
In _[How to get started with test-driven development][4]_, Alex uses an analogy to describe the fundamentals of test-driven development (TDD) and explain dependencies and how to eliminate them for testing purposes.
|
||||
|
||||
If you're going to practice TDD, you need to understand how and when to write a unit test. Alex shares his best practices in [_Writing unit test after writing code considered harmful in test-driven development_][5].
|
||||
|
||||
Testing is about determining if code is working as designed, and [_What does it mean for code to "work"?_][6] explores how to define what working code looks like from the perspective of observable behavior.
|
||||
|
||||
### Software methodologies
|
||||
|
||||
People sometimes ask, "How does 'concept x' relate to DevOps?" Both [_DevOps vs. Agile: What's the difference?_][7] by Tonya Brown and [_How does kanban relate to DevOps_][8]_?_ by Willy-Peter Schaub address these questions head-on. Willy explains the four pivotal kanban practices then dives into how they are similar to DevOps. Tonya highlights similarities and differences between DevOps and agile. If you're starting out on your DevOps journey, these articles will help you understand how DevOps is similar to and different from your current practices.
|
||||
|
||||
And speaking of starting out, Sameer S Paradkar's article [_A beginner's guide to everything DevOps_][9] should be bookmarked and shared with anyone new to the practice. He covers everything from how DevOps addresses development and operations challenges, to the differences between traditional IT processes and DevOps, to understanding the DevOps lifecycle. To top it off, Sameer ends with a handy cheat sheet to open source DevOps tools.
|
||||
|
||||
### People
|
||||
|
||||
The people are the most important part of DevOps. They are the ones writing the software, supporting it, building automation, and so much more. Finding the right people is more important than implementing the right tools.
|
||||
|
||||
The right mindset is required to navigate DevOps. In [_10 tips for maintaining a DevOps mindset for distributed teams_][10], Willy-Peter Shaub shares how that mindset helps in the new era of remote work:
|
||||
|
||||
> "A healthy DevOps mindset navigates through different paths of continuous improvement wherein disruption, discipline, and guardrails are the norm. What no one anticipated is the radical disruption we are all experiencing due to the pandemic, and the impact it has on our DevOps and personal mindset, our workflows, and the ceremonies of kanban and agile teams."
|
||||
|
||||
This mindset is crucial as teams evolve how we collaborate, communicate, and deliver software for the remote world.
|
||||
|
||||
Yet, it's not the only thing you need to be successful in DevOps. Josh Atwell shared his list of key skills for DevOps success in [_How to be the right person for DevOps_][11]. It may come as a surprise, but none of the skills are related to programming languages or tools. Being the right person for DevOps requires communication, selflessness, and self-care, Josh says.
|
||||
|
||||
Even the right mindset and attitude won't make everything perfect; there will still be challenges. One of the challenges people face today is burnout. People are getting tired of being remote, and they are looking for things to return to "normal." In [_DevOps is a solution to burnout worth investing in_][12], I discuss how changing underlying processes and cultures can help reduce or prevent burnout.
|
||||
|
||||
Finally, if you're looking for a career change in 2021, consider the role of scrum master. Tonya Brown outlined a day in the life of a scrum master in [_What does a scrum master do?_][13] If you like removing impediments and coaching people on solving problems, this may be a role for you.
|
||||
|
||||
* * *
|
||||
|
||||
What DevOps topics are you interested in reading about? Please share your ideas in the comments, and if you have knowledge to share, please [consider writing about it for Opensource.com][14].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/devops
|
||||
|
||||
作者:[Dawn Parzych][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/dawnparzych
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tips_map_guide_ebook_help_troubleshooting_lightbulb_520.png?itok=L0BQHgjr (Looking at a map)
|
||||
[2]: https://opensource.com/resources/devops
|
||||
[3]: https://opensource.com/users/alex-bunardzic
|
||||
[4]: https://opensource.com/article/20/1/test-driven-development
|
||||
[5]: https://opensource.com/article/20/2/automate-unit-tests
|
||||
[6]: https://opensource.com/article/20/7/code-tdd
|
||||
[7]: https://opensource.com/article/20/2/devops-vs-agile
|
||||
[8]: https://opensource.com/article/20/4/kanban-devops
|
||||
[9]: https://opensource.com/article/20/2/devops-beginners
|
||||
[10]: https://opensource.com/article/20/6/devops-mindset
|
||||
[11]: https://opensource.com/article/20/3/devops-relationships
|
||||
[12]: https://opensource.com/article/20/1/devops-burnout-solution
|
||||
[13]: https://opensource.com/article/20/7/scrum-master
|
||||
[14]: https://opensource.com/how-submit-article
|
@ -0,0 +1,92 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (10 open source news headlines of 2020)
|
||||
[#]: via: (https://opensource.com/article/20/12/open-source-news)
|
||||
[#]: author: (Jason Blais https://opensource.com/users/jasonblais)
|
||||
|
||||
10 open source news headlines of 2020
|
||||
======
|
||||
Take a look back at the open source news that made headlines in 2020.
|
||||
![Digital creative of a browser on the internet][1]
|
||||
|
||||
Throughout this past year, we've shared [top open source news][2] to keep everyone updated on what's happening in the world of open source. In case you missed any of the headlines, catch up on 10 of the open source news events that grabbed our readers' attention in 2020.
|
||||
|
||||
### Conferences successfully move to the virtual world
|
||||
|
||||
When COVID-19 was declared a pandemic in March, in-person conferences and events around the world came to a halt. Although many were canceled or postponed, others moved to [virtual formats with massive early success][3], reports Correspondent Alan Formy-Duval in his May news roundup. More than 80,000 people attended [Red Hat Summit][4] 2020 online in April, and [GitHub Satellite][5] saw 40,000 tune in from 178 countries. These were some of the biggest virtual conferences anywhere in 2020.
|
||||
|
||||
### Open source in the battle against COVID-19
|
||||
|
||||
As the world focused on controlling the spread of COVID-19, it is no surprise that open source technologies were critical in the effort. Scott Nesbitt shares how open data was used to "[create tracking dashboards and apps, [design] ventilators, and [develop] protective gear][6]." COVID tools, datasets, and research findings were also shared openly on GitHub for others to use and collaborate on.
|
||||
|
||||
### Java celebrates its 25th anniversary
|
||||
|
||||
In February, Tim Hildred helped us celebrate the exciting news about [Java's 25th anniversary][7]. Java was initially designed for interactive televisions with applets embedded in HTML pages, and it has since become the primary programming language for many enterprise applications, especially in financial services. Congratulations to the beloved Java language on reaching the quarter-century mark!
|
||||
|
||||
### GNOME launches a new contributor program
|
||||
|
||||
The GNOME Foundation and Endless partnered to launch a new [Community Engagement Challenge][8]. The objective was to bring "beginners into open source and [encourage] ongoing participation in open source communities," writes Ben Cotton. Of the applications submitted by the July deadline, 20 projects were [selected to continue][9] to the challenge's second phase. Five were invited to participate in the third phase, with the winner to be announced in April 2021.
|
||||
|
||||
### CERN uses open source platform Ceph for storage
|
||||
|
||||
Ceph is an open source software-defined storage platform. It implements object storage on a single distributed computer cluster and powers several research centers' projects, including [CERN's particle physics research][10], Tim Hildred reports. This continues CERN's push, which [began in 2019][11], to use open source software.
|
||||
|
||||
### CNCF takes charge of Red Hat's Operator Framework
|
||||
|
||||
The Cloud Native Computing Foundation (CNCF) hosts various projects, including Kubernetes, to advance container technology, and it runs the world's largest open source developer conferences. In 2020, [CNCF took on Red Hat's Operator Framework][12], an open source toolkit for managing Kubernetes-native applications in an automated and scalable way. "The increasing number of projects and code in the stewardship of neutral foundations like the CNCF is a testament to the power of collaboration," writes Tim Hildred.
|
||||
|
||||
### Two German states roll out Element for their education system
|
||||
|
||||
Correspondent Lauren Maffeo writes that the German states of Schleswig-Holstein and Hamburg [deployed Element][13], an open source messaging platform, to their education system with 500,000 users. It was an exciting leap for open source in the collaboration software market, which has been led by closed source applications like Slack, Zoom, and Microsoft Teams. Several open source collaboration projects, including [Element][14], [Mattermost][15], and [Jitsi][16], took big strides during the COVID-19 pandemic.
|
||||
|
||||
### Strapi announces general availability
|
||||
|
||||
Strapi, an open source, headless CMS for building powerful APIs, [announced general availability][17] five years after its first commit, hundreds of contributors participating, and more than a million downloads, shares Jeff Macharyas. Used by organizations from small businesses to Global 500 companies, Strapi is a testament to the staying power of open source projects backed by a community of users and contributors.
|
||||
|
||||
### Wireguard merged into the Linux Kernel
|
||||
|
||||
Wireguard, the open source communication protocol for virtual private networks (VPNs), was [merged into the Linux Kernel codebase][18] in January, says Correspondent Don Watkins. While the full effects are yet to be seen, this move has the potential to change the landscape of VPNs powered by open source.
|
||||
|
||||
### Mozilla Foundation creates a new subsidiary to host Thunderbird
|
||||
|
||||
Scott Nesbitt reports on a new Mozilla Foundation subsidiary, MZLA Technologies, which will be "the [new home of the Thunderbird project][19]." MZLA Technologies will help Mozilla offer products and services that would not be possible otherwise. Time will tell if Mozilla transfers other products to the new subsidiary.
|
||||
|
||||
### Top headlines in 2021?
|
||||
|
||||
What news do you anticipate open source software will make in 2021? Which companies, projects, or communities will we hear from the most? Let us know in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/open-source-news
|
||||
|
||||
作者:[Jason Blais][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jasonblais
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_web_internet_website.png?itok=g5B_Bw62 (Digital creative of a browser on the internet)
|
||||
[2]: https://opensource.com/tags/news
|
||||
[3]: https://opensource.com/article/20/5/news-may-9
|
||||
[4]: https://www.redhat.com/en/summit/about
|
||||
[5]: https://githubsatellite.com/
|
||||
[6]: https://opensource.com/article/20/3/news-march-28
|
||||
[7]: https://opensource.com/article/20/2/linux-java-and-other-industry-news
|
||||
[8]: https://opensource.com/article/20/4/news-april-11
|
||||
[9]: https://www.gnome.org/challenge/winners/
|
||||
[10]: https://opensource.com/article/20/2/linux-desktop-cern-more-industry-trends
|
||||
[11]: https://www.zdnet.com/article/cern-leaves-microsoft-programs-behind-for-open-source-software/
|
||||
[12]: https://opensource.com/article/20/8/standardizing-kube-and-more-industry-trends
|
||||
[13]: https://opensource.com/article/20/8/news-aug-8
|
||||
[14]: https://element.io/
|
||||
[15]: https://mattermost.com/
|
||||
[16]: http://jitsi.org/
|
||||
[17]: https://opensource.com/article/20/6/news-june-8
|
||||
[18]: https://opensource.com/article/20/2/new-feb-15
|
||||
[19]: https://opensource.com/article/20/2/news-february-1
|
@ -0,0 +1,74 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Jot down your ideas in a digital notebook)
|
||||
[#]: via: (https://opensource.com/article/20/12/kjots)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Jot down your ideas in a digital notebook
|
||||
======
|
||||
If you have an analog soul but need a convenient digital version of your
|
||||
beloved paper notebooks, KJots is the editor for you.
|
||||
![Writing in a notebook][1]
|
||||
|
||||
I love a good notebook. I usually get one or two blank notebooks from technical conferences each year, and I spend the journey home deciding what I’ll fill the empty pages with. Sometimes, it’s notes about some new open source technology; other times, it’s ideas for new games, or a collection of dungeons for my D&D groups, or ideas for a fictional world or story. The ideas tend to flow freely when I have a blank notebook in front of me, because it’s _empty_, and nature abhors a vacuum.
|
||||
|
||||
A digital version of this is the KJots application, a sort of personal wiki distributed with the KDE Plasma desktop. KJots allows you to create text files to be kept in a database so that all of the "pages" of text you create form one or more "notebooks."
|
||||
|
||||
### Install
|
||||
|
||||
KJots is the default personal wiki of KDE’s Plasma desktop. If you’re running the Plasma desktop on Linux or BSD, you already have KJots, and you can launch it either as a self-standing application or from the Kontact Personal Information Manager (PIM) application.
|
||||
|
||||
### Using KJots
|
||||
|
||||
KJots behaves a lot like a text editor, except that your files are stored in a database, so you never have to manually save them out to a place on your hard drive. KJots is designed to encourage you to think of your notes like pages in a notebook. It has a side panel displaying each note in a book structure of your choosing. You can create a new book at any time, and of course, you can move notes in and out of books according to how you want to keep your data organized. The application is intuitive as a text editor; there’s a text editing field on the right and a tree view of your collection of notes on the left.
|
||||
|
||||
![black KJots terminal with white text and separate left-side tree menu][2]
|
||||
|
||||
#### Editing
|
||||
|
||||
Editing text in KJots is a lot like editing text in KWrite or [medit][3]. There’s a button or menu for whatever you need to do, including styling your text as bold or italics or color, changing the font, adding arbitrary bookmarks (in KJots), creating lists, and so on. It’s not as flexible as [Kate][4], but it’s got all the basics you need for general-purpose composition.
|
||||
|
||||
#### Linking
|
||||
|
||||
One thing that’s difficult to simulate in the digital world is the ease of flipping back and forth between pages in a physical book. I don’t know that anyone’s solved this problem yet, but as consolation, KJots allows you to link between notes. In a way, you’re anticipating your future desire to flip back to a previous note by including an easy-to-follow hyperlink straight to the page you want yourself to refer to later. Technically, it’s more efficient than the physical equivalent (although it does require you to think of it beforehand, or else you’re back to scrolling through notes or using **Ctrl+F** to find a keyword).
|
||||
|
||||
To link from one note to another, select the word or phrase you want to make a hyperlink. Click the **Format** menu, and select the **Link** option. You can choose to create an external link (to a website, for instance) or an internal link to another note, even if the note is filed in a separate book.
|
||||
|
||||
![Kjots terminal with pop-up box titled link management][5]
|
||||
|
||||
#### Exporting
|
||||
|
||||
KJots exports its files to plain text, HTML, or book files. A book file is useful to transfer notes between KJots instances and can be a good means of performing a manual backup. To export a note, select the note you want to save and choose **Export** from the **File** menu. Save the file somewhere on your hard drive.
|
||||
|
||||
I use this function to export notes that started as a small idea and then got developed to the point that I feel it deserves to be its own file. This is especially useful to me because I don’t use internal KJots styling options and instead write in Asciidoc or Markdown in KJots, and then export as plain text so I can process the markdown with [Pandoc][6] or similar.
|
||||
|
||||
### Try KJots
|
||||
|
||||
I’ve used Kjots off and on again since discovering it in the Kontact suite of applications on Plasma desktop 4. It’s one of my favorite digital notebooks because, of the ones I’ve used, it’s the one that "feels" the most like a notebook, and also because it’s the one that comes with my desktop. It may or may not be suitable as your primary editor, but it is a nice editor if you sometimes think in collections of ideas, and you want to keep related thoughts closely associated but not in the same document.
|
||||
|
||||
If you love a good notebook, try KJots!
|
||||
|
||||
KDE originally stood for Kool Desktop Environment, but is now known by many as the K Desktop...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/kjots
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/notebook-writing-pen.jpg?itok=uA3dCfu_ (Writing in a notebook)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/kjots-31_days-kjots-opensource.png (black KJots terminal with white text and separate left-side tree menu)
|
||||
[3]: https://opensource.com/article/20/12/medit
|
||||
[4]: https://opensource.com/article/20/12/kate-text-editor
|
||||
[5]: https://opensource.com/sites/default/files/uploads/kjots-link-31_days-kjots-opensource.png (Kjots terminal with pop-up box titled link management)
|
||||
[6]: https://opensource.com/article/20/5/pandoc-cheat-sheet
|
@ -0,0 +1,76 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn to use the JOE text editor on Linux)
|
||||
[#]: via: (https://opensource.com/article/20/12/joe)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Learn to use the JOE text editor on Linux
|
||||
======
|
||||
Joe's Own Editor (JOE) is a general text editor that is easy to learn
|
||||
and use.
|
||||
![Person programming on a laptop on a building][1]
|
||||
|
||||
I’m a fan of text editors that make it easy for you to learn how to use them. GNU nano is my favorite example of this: you launch nano, and you see a list of the most common commands along the bottom of the window throughout your entire session. Joe’s Own Editor (that’s `joe` for short) is another great example.
|
||||
|
||||
The `joe` editor uses a terminal-based interface, providing simple text editing capabilities and an easily accessible help screen. It’s written in C, it’s small with a hard dependency only on libc (ncurses is optional), and it’s licensed under the GPL.
|
||||
|
||||
### Installing
|
||||
|
||||
On Linux, you may be able to find JOE in your distribution’s software repository. It’s a little obscure, though, so not all distributions have packaged it. If that’s the case, you can download the source code from [SourceForge][2] and compile it yourself. It’s an easy process:
|
||||
|
||||
|
||||
```
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
### Using JOE
|
||||
|
||||
According to its author, JOE takes inspiration from an application called WordStar and from [GNU Emacs][3]. Most of its basic editing keys are the same as WordStar shortcuts, and the editor itself strives to approximate WordStar. JOE also has some of the key bindings and features of GNU Emacs. This mix of two sources of inspiration can sometimes be disorienting, but then again, weaning yourself off Emacs (or your usual text editor of choice) under any circumstance can be disorienting. The important thing is that JOE offers help, and it’s easy to reach.
|
||||
|
||||
In the top right corner of JOE’s interface, there’s a persistent reminder that you can press **Ctrl+K** followed immediately by **H** to view a help screen. This is a toggle, so once you activate it, the help screen remains displayed at the top of your editor window until dismissed with the same key combo (**^KH** in JOE’s keyboard notation).
|
||||
|
||||
### Keyboard shortcuts
|
||||
|
||||
For all the pride JOE’s author takes in simulating a WordStar user experience, I have to admit it’s lost on me. I’d never heard of WordStar until I read about it in JOE’s documentation, and to me, it seemed to have a completely arbitrary keyboard shortcut scheme. Some are prefixed with **Ctrl+K** as an escape sequence, while others use **Esc** as the prefix, and still others require no escape sequence at all. I couldn’t determine the logic. Editing operations were just as likely as application options to require an escape sequence or not, and few of the letter associations made sense to me (**Ctrl+K** **D** for **save as**, for instance).
|
||||
|
||||
Luckily, JOE lets you cheat on keyboard shortcuts. Upon installation, JOE quietly creates a few symlinks for the `joe` executable. Included are:
|
||||
|
||||
* `jmacs` JOE with Emacs key bindings
|
||||
* `jpico` JOE with Pico (or GNU nano) key bindings
|
||||
* `rjoe` JOE with editing restricted only to the file passed to JOE at launch
|
||||
* `jstar` JOE with WordStar key bindings
|
||||
|
||||
|
||||
|
||||
![Black terminal with white text showing WordStar key bindings][4]
|
||||
|
||||
The persistent help menu remains, so if you’re ever unclear as to what functions you have available to you, refer to them with the help prompt at the top right of the screen. Of course, in Pico/nano mode, the main commands are always visible.
|
||||
|
||||
### Try JOE
|
||||
|
||||
JOE isn’t intended as a text editor you’ll never leave. It won’t become your IDE, email client, web browser, and file manager. In fact, it may not even be your main text editor for all tasks. It focuses on being good at one thing, and that’s general text editing.
|
||||
|
||||
JOE has all of the essential functions you need, like the ability to navigate your text quickly, the ability to select text, copy and paste, and so on. Give JOE a try, using your preferred symlink.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/joe
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_code_programming_laptop.jpg?itok=ormv35tV (Person programming on a laptop on a building)
|
||||
[2]: https://joe-editor.sourceforge.io/
|
||||
[3]: https://opensource.com/article/20/12/emacs
|
||||
[4]: https://opensource.com/sites/default/files/uploads/joe-jstar-31_days-joe-opensource.png (Black terminal with white text showing WordStar key bindings)
|
@ -0,0 +1,175 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Practice programming in C++ by writing a simple game)
|
||||
[#]: via: (https://opensource.com/article/20/12/learn-c-game)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Practice programming in C++ by writing a simple game
|
||||
======
|
||||
The C++ language is complex, but it can teach you a lot about data
|
||||
types, memory management, and code linking.
|
||||
![A bunch of question marks][1]
|
||||
|
||||
There are a couple of ways to learn a programming language. If you're new to coding, you usually learn some basic computer coding concepts and try to apply them. If you already know how to code in another language, you relearn how coding concepts are expressed in the new language.
|
||||
|
||||
In either case, a convenient way to learn these new principles is to create a simple guessing game. This forces you to understand how a language receives input and sends output, how it compares data, how to control a program's flow, and how to leverage conditionals to affect an outcome. It also ensures that you know how a language structures its code; for instance, Lua or [Bash][2] can easily run as a script, while [Java][3] requires you to create a class.
|
||||
|
||||
In this article, I'll demonstrate how to implement a guessing game for the terminal in [C++][4].
|
||||
|
||||
### Install dependencies
|
||||
|
||||
To follow along with this article, you need C++ and a compiler.
|
||||
|
||||
You can get everything you need on Linux by installing the Qt Creator IDE from your distribution's software repository.
|
||||
|
||||
On Fedora, CentOS, or RHEL:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo dnf install qt-creator`
|
||||
```
|
||||
|
||||
On Debian, Ubuntu, Chromebook, or similar:
|
||||
|
||||
|
||||
```
|
||||
`$ sudo apt install qtcreator`
|
||||
```
|
||||
|
||||
This article doesn't utilize the Qt Creator IDE, but it's an easy way to get everything you need installed, and for complex C++ projects (including those with a GUI), it's an essential tool to have. On macOS or Windows, follow the [installation instructions][5] on Qt's website.
|
||||
|
||||
### Set up includes and namespace
|
||||
|
||||
C++'s core language is minimal. Even a simple application requires the use of additional libraries. This application uses [iostream][6] to gain access to the `cout` and `cin` keywords.
|
||||
|
||||
Also, ensure that the program uses the `std` namespace:
|
||||
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
```
|
||||
|
||||
This isn't strictly necessary, but without setting the namespace to `std`, all keywords from the iostream library require a namespace prefix. For instance, instead of writing `cout`, I would have to write `std::cout`.
|
||||
|
||||
Statements in C++ terminate with a semicolon.
|
||||
|
||||
### Create a function
|
||||
|
||||
Every C++ application requires at least one function. The primary function of a C++ application must be called `main`, and it must return an integer (`int`), which corresponds to the [POSIX][7] expectation that a process returns 0 upon success and something else upon failure. You create a new function by providing its return type and then its name:
|
||||
|
||||
|
||||
```
|
||||
int main() {
|
||||
// code goes here
|
||||
}
|
||||
```
|
||||
|
||||
### Implement program logic
|
||||
|
||||
The game code must first produce a random number for the player to guess. You do this in C++ by establishing a _seed_ for pseudo-random number generation. A simple seed is the current time. Once the seed starts, you retrieve a number between 1 and 100 by calling the `rand` function with an upper constraint of 100. This generates a random number from 0 to 99, so add 1 to whatever number is chosen and assign the result to a variable called `number`. You must also declare a variable to hold the player's guess. For clarity, I'm calling this variable `guess`.
|
||||
|
||||
This sample code also includes a debug statement that tells you exactly what the random number is. This isn't very good for a guessing game, but it makes testing a lot faster. Later, you can remove the line or just comment it out by prefacing it with `//`:
|
||||
|
||||
|
||||
```
|
||||
srand (time(NULL));
|
||||
int number = rand() % 100+1;
|
||||
int guess = 0;
|
||||
|
||||
cout << number << endl; //debug
|
||||
```
|
||||
|
||||
### Add do-while and if statements
|
||||
|
||||
A `do-while` statement in C++ starts with the keyword `do` and encloses everything that you want C++ to do in braces. Close the statement with the `while` keyword followed by the condition that must be met (in parentheses):
|
||||
|
||||
|
||||
```
|
||||
do {
|
||||
// code here
|
||||
} while ( number != guess );
|
||||
```
|
||||
|
||||
The game code occurs within an `if` statement with an `else if` and `else` statements to provide the player with hints.
|
||||
|
||||
First, prompt the player for a guess with a `cout` statement. The `cout` function prints output onto `stdout`. Because the `cout` statement isn't appended with the `endl` (endline) function, no linebreak occurs. Immediately following this `cout` statement, tell C++ to wait for input by using the `cin` function. As you might surmise, `cin` waits for input from `stdin`.
|
||||
|
||||
Next, the program enters the `if` control statement. If the player's guess is greater than the pseudo-random number contained in the `number` variable, then the program prints out a hint followed by a newline character. This breaks the `if` statement, but C++ is still trapped within the `do-while` loop because its condition (the `number` variable being equal to `guess`) has not yet been met.
|
||||
|
||||
If the player's guess is less than the pseudo-random number contained in the `number` variable, then the program prints out a hint followed by a newline character. This again breaks the `if` statement, but the program remains trapped within the `do-while` loop.
|
||||
|
||||
When `guess` is equal to `number`, the key condition is finally met, the `else` statement is triggered, the `do-while` loop ends, and the application ends:
|
||||
|
||||
|
||||
```
|
||||
do {
|
||||
cout << "Guess a number between 1 and 100: ";
|
||||
cin >> guess;
|
||||
|
||||
if ( guess > number) { cout << "Too high.\n" << endl; }
|
||||
else if ( guess < number ) { cout << "Too low.\n" << endl; }
|
||||
else {
|
||||
cout << "That's right!\n" << endl;
|
||||
exit(0);
|
||||
} // fi
|
||||
} while ( number != guess );
|
||||
return 0;
|
||||
} // main
|
||||
```
|
||||
|
||||
### Building the code and playing the game
|
||||
|
||||
You can build your application with GCC:
|
||||
|
||||
|
||||
```
|
||||
`$ g++ -o guess.bin guess.cpp`
|
||||
```
|
||||
|
||||
Run the binary to try it out:
|
||||
|
||||
|
||||
```
|
||||
$ ./guess.bin
|
||||
74
|
||||
Guess a number between 1 and 100: 76
|
||||
Too high.
|
||||
|
||||
Guess a number between 1 and 100: 1
|
||||
Too low.
|
||||
|
||||
Guess a number between 1 and 100: 74
|
||||
That's right!
|
||||
```
|
||||
|
||||
Success!
|
||||
|
||||
### Give C++ a try
|
||||
|
||||
The C++ language is complex. Writing C++ applications for terminals can teach you a lot about data types, memory management, and code linking. Try writing a useful utility in C++ and see what you can discover!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/learn-c-game
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_question_B.png?itok=f88cyt00 (A bunch of question marks)
|
||||
[2]: https://opensource.com/article/20/12/learn-bash
|
||||
[3]: https://opensource.com/article/20/12/learn-java-writing-guess-number-game
|
||||
[4]: https://www.cplusplus.com/
|
||||
[5]: https://www.qt.io/product/development-tools
|
||||
[6]: http://www.cplusplus.com/reference/iostream/
|
||||
[7]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
@ -0,0 +1,79 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Experience alternate computing with the Pe text editor)
|
||||
[#]: via: (https://opensource.com/article/20/12/pe)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Experience alternate computing with the Pe text editor
|
||||
======
|
||||
With elements of legacy systems, Pe is refreshingly simple with plenty
|
||||
of additional features.
|
||||
![Programming keyboard.][1]
|
||||
|
||||
The Haiku operating system is a bold but successful attempt at reviving an old OS called BeOS. In the 1990s, BeOS was positioned to become the foundation for the next evolution of the Apple Mac line of computers. Back in the 1990s, Apple Inc. was poised to acquire BeOS as its next generation operating system. At the last minute, however, Apple decided the price was too steep and acquired the UNIX-based NeXT operating system instead (and so Mac OS X was born). BeOS, however, had [made some remarkable progress][2] in multi-threading, file systems and attributes, and interface design. When the company finally folded, its userbase persisted.
|
||||
|
||||
I like to check in on Haiku every now and again, and while it still lists itself as beta software, it’s a striking achievement. Haiku is not Linux or UNIX, although it is POSIX-compliant. It stays true and compatible with BeOS, while making lots of improvements so that it largely feels like an OS that was developed today and not 30 years ago.
|
||||
|
||||
Between BeOS and Haiku, there have been lots of text editors on this platform, including **ne**, **pad**, **TextEdit**, **YATE**, and many more ([JOVE][3], [Emacs][4], and [Vim][5] have all been ported to it, too). For this article, however, I decided to try one of the default text editors included with Haiku: [the Pe editor][6] or _programmer’s editor_.
|
||||
|
||||
![Blue HAIKU desktop with Pe editor buffer, a white box with gray text][7]
|
||||
|
||||
### Install
|
||||
|
||||
Pe is written for Haiku OS and is released under a BSD license. To run it, you must have [Haiku installed][8]. Haiku is an operating system, so in theory, you could install it on a spare computer, but it also runs well in a virtual machine, such as [GNOME Boxes][9]. With Haiku installed on hardware or in a virtual machine, you have Pe by default.
|
||||
|
||||
### Launching
|
||||
|
||||
If you’re new to BeOS or Haiku, then the easiest way to launch Pe is from the Deskbar. The Deskbar is a precursor to the modern Dock (like the one in macOS). Click the Haiku feather icon in the top-right corner of the desktop and select **Applications**. In the **Applications** submenu, click on **Pe** to launch the text editor.
|
||||
|
||||
Alternately, you can double-click the hard drive icon on the desktop and navigate to your home directory. Once there, right-click and create a new text file. Right-click on the text file and open it with Pe.
|
||||
|
||||
### Using Pe
|
||||
|
||||
When Pe first launches, it opens an empty buffer for text entry, with a menu and a toolbar at the top of the window. Once you’re using Pe, the relative unfamiliarity of the OS fades away because Pe works largely like every other text editor you’ve ever used. You type text, and it appears on the screen. It’s refreshingly simple, but there are lots of exciting features for you to discover.
|
||||
|
||||
#### Syntax highlighting
|
||||
|
||||
I tried writing in Asciidoc, Docbook XML, Markdown, Python, and C++. Both XML and C++ were recognized by Pe, and it automatically themed the keywords and elements. The color scheme only activated when a text file was saved with the appropriate file extension, so it’s not a bad idea to create your file on the desktop first and then open it with Pe to ensure that the correct syntax definition is loaded. Languages included in Pe are stored in **/system/apps/Pe/Languages**. The color themes followed the general visual design of Haiku itself: soft and calming shades, mostly earth tones, but easy to see. I usually use a dark theme on my desktop, but I found Haiku’s theme pleasing enough that I didn’t feel a special urge to change it (which is convenient because I couldn’t find a built-in dark theme that didn’t involve me redefining every system color myself).
|
||||
|
||||
#### Text modifiers
|
||||
|
||||
Text editors ideally make editing text easy, and that’s exactly the aim of the **Text** menu. This menu contains lots of convenience functions that most people writing text probably don’t ever think about but that programmers seem to use all the time. There’s **twiddle** to swap characters (a quick way to change "hte" to "the" or "cmo" to "com," and so on), **change case** to alter capitalization of words and sentences, **shift left** and **shift right** to adjust indentation, **comment** and **uncomment** to transform a line into a comment, and much more. This menu, along with its robust **Preferences,** is where Pe really excels. It’s a sign of developers who include what they, and other people serious about computing, want.
|
||||
|
||||
#### Saving
|
||||
|
||||
Saving and opening files are essentially the same in Pe as with most editors. You go to the **File** menu and select the action you want. However, Pe provides some extra services, too. You can open files from a server, save them directly to a server, save just one file, or save several files in a group.
|
||||
|
||||
#### Keyboard shortcuts
|
||||
|
||||
Most keyboard shortcuts in Haiku are based around the **Alt** key instead of the **Ctrl** key. I find this somewhat refreshing because I’ve often felt that the **Ctrl** (or **Command** on macOS) is overloaded. Pe, being a native Haiku application, inherits this preference, although the keyboard shortcuts can be changed in its **Preferences**. Unfortunately, I think the **Alt** key ends up being overloaded in Haiku, so the change from one modifier key to another doesn’t actually help relieve that issue (I still have no idea how a user is meant to know a global action from a local action), but it’s an interesting experiment. I find the **Alt** key is easier to press for common actions; it’s right next to the spacebar, after all, and in the future, I may swap **Ctrl** and **Alt** on Linux.
|
||||
|
||||
### Alternate computing
|
||||
|
||||
Haiku, and BeOS before it, are interesting if only because they let you peek into an alternate reality in which Apple didn’t join in with the UNIX crowd. It’s a fun diversion to look into an OS based on a unique system design, and it’s interesting to see what Apple has borrowed from BeOS, what Haiku has borrowed from UNIX, and how a little variety can help inform each of us about different perspectives and new ideas for interfacing with the tools we use every day of our lives. Whether you’re looking at the OS or the text editor, take an afternoon to get some perspective with Pe.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/pe
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_keyboard_coding.png?itok=E0Vvam7A (Programming keyboard.)
|
||||
[2]: http://birdhouse.org/beos/bible
|
||||
[3]: https://opensource.com/article/20/12/jove-emacs
|
||||
[4]: https://opensource.com/article/20/12/emacs
|
||||
[5]: https://opensource.com/article/20/12/vi-text-editor
|
||||
[6]: http://github.com/olta/pe
|
||||
[7]: https://opensource.com/sites/default/files/uploads/haiku-31_days-pe-opensource.jpg (Blue HAIKU desktop with Pe editor buffer, a white box with gray text)
|
||||
[8]: http://haiku-os.org
|
||||
[9]: https://opensource.com/article/19/5/getting-started-gnome-boxes-virtualization
|
@ -0,0 +1,119 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Rocket.Chat: An Amazing Open-Source Alternative to Slack That You Can Self-host)
|
||||
[#]: via: (https://itsfoss.com/rocket-chat/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Rocket.Chat: An Amazing Open-Source Alternative to Slack That You Can Self-host
|
||||
======
|
||||
|
||||
_**Brief: Rocket.Chat is an open-source team communication application with features and looks similar to Slack. You are free to self-host it or opt for their managed service for a fee.**_
|
||||
|
||||
Slack is a useful and popular team communication app that potentially replaces emails for work. A lot of big and small teams use it, even we at It’s FOSS relied on Slack initially.
|
||||
|
||||
However, we needed a good open-source alternative to Slack and that’s when we came across Rocket.Chat. Sure, there are several other [open-source slack alternatives][1], but we opted for Rocket.Chat for its similarity with Slack and ease of deployment.
|
||||
|
||||
### Rocket.Chat: An Open Source Communication Platform
|
||||
|
||||
![][2]
|
||||
|
||||
Rocket.Chat is an open-source communication platform for team collaboration.
|
||||
|
||||
You get all the essential features to facilitate proper communication along with the option to get started for free, opt for hosted service by the Rocket.Chat team or deploy it on your server.
|
||||
|
||||
You can totally customize as per your requirements when deploying it on your server. No matter what you choose to do, the feature-set is impressive.
|
||||
|
||||
Let us take a look at what it offers.
|
||||
|
||||
### Features of Rocket.Chat
|
||||
|
||||
![][3]
|
||||
|
||||
Rocket.Chat is a powerful and flexible team communication tool. Here’s what you can expect from it:
|
||||
|
||||
* Easy file sharing (drag and drop support)
|
||||
* Audio file sharing support
|
||||
* Video conferencing with [Jitsi Meet][4] integration
|
||||
* Separate channels (private and public options)
|
||||
* End-to-End encryption support
|
||||
* Customize the theme of the service (including the ability to customize it)
|
||||
* Guest access support
|
||||
* Unlimited message history (depending on the storage of your server for self-managed setup)
|
||||
* Broadcast channel support
|
||||
* RSS Integration
|
||||
* Several 3rd party app integration support
|
||||
* White label (optional if you want a custom branding)
|
||||
* Read receipt (Enterprise plan)
|
||||
* Push notifications support
|
||||
* Customizable user permission
|
||||
* 24 x 7 Support (depending on the pricing plan)
|
||||
* LiveChat integration support which you can add on your website
|
||||
* Real-time translation
|
||||
* Self-host support
|
||||
* Cross-platform support (Windows, macOS, Android, iOS, and Linux)
|
||||
|
||||
|
||||
|
||||
In addition to all the key points mentioned above, there are a lot of little nifty features that should come in useful in Rocket.Chat.
|
||||
|
||||
### Installing Rocket.Chat client on Linux
|
||||
|
||||
If you have a Rocket.Chat instance deployed or hosted by Rocket Chat itself, you can access it through web browser, desktop clients and mobile apps.
|
||||
|
||||
Can’t self-host Rocket.Chat? Let us help you
|
||||
|
||||
Deploying open source applications and managing Linux servers takes some expertise and time. If you lack either but still want to have your own instance of open source software, we can help you out.
|
||||
With our new project, [High on Cloud][5], you can leave the deployment and server management part to us while you focus on your work.
|
||||
|
||||
On Linux, Rocket.Chat is available as a [snap][6] and a [Flatpak package][7]. You can go through our guides on [using snap][6] or [Flatpak on Linux][8] to get started.
|
||||
|
||||
I would recommend installing it as a Flatpak (that’s how I use it) to get the latest version. Of course, if you prefer to use it as a snap package, you can go with that as well.
|
||||
|
||||
In either case, you can explore the source code on their [GitHub page][9] if you need.
|
||||
|
||||
[Rocket.Chat][10]
|
||||
|
||||
### My Thoughts on Using Rocket.Chat
|
||||
|
||||
![][11]
|
||||
|
||||
I’ve been using Rocket.Chat for quite a while now (for our internal communication at It’s FOSS). Even though I was not the one who deployed it on our server, the [documentation][12] hints at a swift process to set it up on your server.
|
||||
|
||||
It supports automation tools like [Ansible][13], [Kubernetes][14], etc and also gives you the option to deploy it as a docker container directly.
|
||||
|
||||
You will find plenty of administrative options to tweak the experience on your instance of Rocket.Chat. It is easy to customize many things even if you are not an expert at self-managed projects.
|
||||
|
||||
Personally, I appreciate the ability to customize the theme (it is easy to add a dark mode toggle as well). You get all the essential options available on smartphone as well. Overall, it is indeed an exciting switch from Slack and it should be a similar experience for most of you.
|
||||
|
||||
_What do you think about Rocket.Chat? Do you prefer something else over Rocket.Chat? Let me know your thoughts in the comments below._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/rocket-chat/
|
||||
|
||||
作者:[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/open-source-slack-alternative/
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/12/rocket-chat-feat.png?resize=768%2C433&ssl=1
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/12/rocket-chat-itsfoss-1.resized.jpg?resize=800%2C509&ssl=1
|
||||
[4]: https://itsfoss.com/jitsi-meet/
|
||||
[5]: https://highoncloud.com/
|
||||
[6]: https://itsfoss.com/use-snap-packages-ubuntu-16-04/
|
||||
[7]: https://itsfoss.com/what-is-flatpak/
|
||||
[8]: https://itsfoss.com/flatpak-guide/
|
||||
[9]: https://github.com/RocketChat/Rocket.Chat
|
||||
[10]: https://rocket.chat/
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/12/rocket-chat-itsfoss.png?resize=800%2C504&ssl=1
|
||||
[12]: https://docs.rocket.chat/
|
||||
[13]: https://www.ansible.com/
|
||||
[14]: https://kubernetes.io/
|
@ -0,0 +1,159 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Show progress in your Python apps with tqdm)
|
||||
[#]: via: (https://opensource.com/article/20/12/tqdm-python)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
Show progress in your Python apps with tqdm
|
||||
======
|
||||
If your program takes a while to show results, avoid frustrating users
|
||||
by showing the progress it's making.
|
||||
![arrows cycle symbol for failing faster][1]
|
||||
|
||||
The Semitic root _q-d-m_ in Aramaic, Hebrew, and Arabic is usually associated with moving forward or making progress. The Arabic word _taqaddum_ (تقدّم) means "progress." Progress is important. As every feel-good movie will tell you, the journey is as important as the destination.
|
||||
|
||||
Most programs have a clear goal, a desired end state. Sometimes, calculating that end state can take a long time. While computers don't care, not having feelings, people do. Humans are not happy sitting around waiting without any visible sign of progress. Doubt creeps in. Has the program crashed? Is the disk thrashing? Did the operating system allocate all its computing resources to other tasks?
|
||||
|
||||
Like justice, progress must be seen, not merely done. The [tqdm][2] Python library helps make progress explicit.
|
||||
|
||||
The tqdm module works with the console, but it also has special support for one of my favorite environments: Jupyter. To use tqdm in Jupyter, you need to import the `notebook` submodule and have [ipywidgets][3] installed. The `notebook` submodule is interface-compatible with tqdm.
|
||||
|
||||
This means you can do some import-time shenanigans to import the correct module while keeping tqdm usage the same. The trick is to check if the `__main__` module has the global variable `get_ipython`. While this is a heuristic, it is a reasonably accurate one:
|
||||
|
||||
|
||||
```
|
||||
import sys
|
||||
if hasattr(sys.modules["__main__"], "get_ipython"):
|
||||
from tqdm import notebook as tqdm
|
||||
else:
|
||||
import tqdm
|
||||
```
|
||||
|
||||
The simplest case is when something needs to run for a certain number of iterations (known in advance), and each of those iterations takes about the same amount of time. For example, there is an algorithm to calculate the square root of any number by starting with 1 as a guess and then calculating an improved guess:
|
||||
|
||||
|
||||
```
|
||||
def improve_guess(rt, n):
|
||||
return (rt + n/rt) / 2
|
||||
```
|
||||
|
||||
A small number of improvements gets you pretty close. For example, you can calculate the square root of two:
|
||||
|
||||
|
||||
```
|
||||
guess = 1
|
||||
target = 2
|
||||
for i in tqdm.trange(10):
|
||||
guess = improve_guess(guess, target)
|
||||
```
|
||||
|
||||
![tqdm output][4]
|
||||
|
||||
(Moshe Zadke, [CC BY-SA 4.0][5])
|
||||
|
||||
It's correct to 10 decimal places!
|
||||
|
||||
|
||||
```
|
||||
`round(2 - guess*guess, 10)`[/code] [code]`0.0`
|
||||
```
|
||||
|
||||
A slightly more complicated example is when the number of elements is known, and processing each element takes a similar amount of time. As an example, you can calculate the product of some numbers. For that, you'll want some random numbers:
|
||||
|
||||
|
||||
```
|
||||
import random
|
||||
numbers = [random.uniform(0, 2.8) for i in range(100)]
|
||||
numbers[:5]
|
||||
|
||||
[/code] [code]
|
||||
|
||||
[2.6575636572230916,
|
||||
0.1286674965830302,
|
||||
1.0634250104041332,
|
||||
1.1760969844376505,
|
||||
0.45192978568125486]
|
||||
```
|
||||
|
||||
Now that the numbers are in, it's time to multiply them. The easiest way to use tqdm is by wrapping a Python iterable. The values will be the same, but tqdm will also display a progress bar:
|
||||
|
||||
|
||||
```
|
||||
result = 1
|
||||
for num in tqdm.tqdm(numbers):
|
||||
result *= num
|
||||
result
|
||||
|
||||
[/code] [code]`2.4081854901728303`
|
||||
```
|
||||
|
||||
![tqdm output][6]
|
||||
|
||||
(Moshe Zadke, [CC BY-SA 4.0][5])
|
||||
|
||||
However, not all things are predictable. One of the least predictable things is network speed. When you download a big file, the only way to measure progress is to explicitly check how much has been downloaded:
|
||||
|
||||
|
||||
```
|
||||
url = "<https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz>"
|
||||
import httpx
|
||||
with httpx.stream("GET", url) as response:
|
||||
total = int(response.headers["Content-Length"])
|
||||
with tqdm.tqdm(total=total) as progress:
|
||||
for chunk in response.iter_bytes():
|
||||
progress.update(len(chunk))
|
||||
```
|
||||
|
||||
![tqdm output][7]
|
||||
|
||||
(Moshe Zadke, [CC BY-SA 4.0][5])
|
||||
|
||||
Sometimes, it makes sense to "nest" progress bars. For example, if you are downloading a directory, you'll want a progress bar tracking the files and a progress bar per file.
|
||||
|
||||
Here is an example (but without actually downloading a directory):
|
||||
|
||||
|
||||
```
|
||||
files = [f"vid-{i}.mp4" for i in range(4)]
|
||||
for fname in tqdm.tqdm(files, desc="files"):
|
||||
total = random.randrange(10**9, 2 * 10**9)
|
||||
with tqdm.tqdm(total=total, desc=fname) as progress:
|
||||
current = 0
|
||||
while current < total:
|
||||
chunk_size = min(random.randrange(10**3, 10**5), total - current)
|
||||
current += chunk_size
|
||||
if random.uniform(0, 1) < 0.01:
|
||||
time.sleep(0.1)
|
||||
progress.update(chunk_size)
|
||||
```
|
||||
|
||||
![tqdm output][8]
|
||||
|
||||
(Moshe Zadke, [CC BY-SA 4.0][5])
|
||||
|
||||
So, if your program takes a while to show final results, avoid frustrating your users: Show the progress it's making!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/tqdm-python
|
||||
|
||||
作者:[Moshe Zadka][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/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh (arrows cycle symbol for failing faster)
|
||||
[2]: https://pypi.org/project/tqdm/
|
||||
[3]: https://opensource.com/article/20/11/daily-journal-jupyter
|
||||
[4]: https://opensource.com/sites/default/files/uploads/output_8_0.png (tqdm output)
|
||||
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/output_15_0.png (tqdm output)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/output_18_0.png (tqdm output)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/output_21_0.png (tqdm output)
|
150
sources/tech/20201230 Choose between Btrfs and LVM-ext4.md
Normal file
150
sources/tech/20201230 Choose between Btrfs and LVM-ext4.md
Normal file
@ -0,0 +1,150 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Choose between Btrfs and LVM-ext4)
|
||||
[#]: via: (https://fedoramagazine.org/choose-between-btrfs-and-lvm-ext4/)
|
||||
[#]: author: (Troy Curtis Jr https://fedoramagazine.org/author/troycurtisjr/)
|
||||
|
||||
Choose between Btrfs and LVM-ext4
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Photo by [Raul Petri][2] on [Unsplash][3]
|
||||
|
||||
[Fedora 33][4] introduced a new default filesystem in desktop variants, [Btrfs][5]. After years of Fedora using [ext4][6] on top of [Logical Volume Manager (LVM)][7] volumes, this is a big shift. Changing the default file system requires [compelling reasons][8]. While Btrfs is an exciting next-generation file system, ext4 on LVM is well established and stable. This guide aims to explore the high-level features of each and make it easier to choose between Btrfs and LVM-ext4.
|
||||
|
||||
### In summary
|
||||
|
||||
The simplest advice is to stick with the defaults. A fresh Fedora 33 install defaults to Btrfs and upgrading a previous Fedora release continues to use whatever was initially installed, typically LVM-ext4. For an existing Fedora user, the cleanest way to get Btrfs is with a fresh install. However, a fresh install is much more disruptive than a simple upgrade. Unless there is a specific need, this disruption could be unnecessary. The Fedora development team carefully considered both defaults, so be confident with either choice.
|
||||
|
||||
### What about all the other file systems?
|
||||
|
||||
There are a [large number of file systems for Linux systems][9]. The number explodes after adding in combinations of volume managers, encryption methods, and storage mechanisms . So why focus on Btrfs and LVM-ext4? For the Fedora audience these two setups are likely to be the most common. Ext4 on top of LVM became the default disk layout in Fedora 11, and ext3 on top of LVM came before that.
|
||||
|
||||
Now that Btrfs is the default for Fedora 33, the vast majority of existing users will be looking at whether they should stay where they are or make the jump forward. Faced with a fresh Fedora 33 install, experienced Linux users may wonder whether to use this new file system or fall back to what they are familiar with. So out of the wide field of possible storage options, many Fedora users will wonder how to choose between Btrfs and LVM-ext4.
|
||||
|
||||
### Commonalities
|
||||
|
||||
Despite core differences between the two setups, Btrfs and LVM-ext4 actually have a lot in common. Both are mature and well-tested storage technologies. LVM has been in continuous use since the early days of Fedora Core and ext4 became the [default in 2009 with Fedora 11][10]. Btrfs merged into the mainline Linux kernel in 2009 and [Facebook uses it widely][11]. SUSE Linux Enterprise 12 made it the [default in 2014][12]. So there is plenty of production run time there as well.
|
||||
|
||||
Both systems do a great job preventing file system corruption due to unexpected power outages, even though the way they accomplish it is different. Supported configurations include single drive setups as well as spanning multiple devices, and both are capable of creating nearly instant snapshots. A variety of tools exist to help manage either system, both with the command line and graphical interfaces. Either solution works equally well on home desktops and on high-end servers.
|
||||
|
||||
### Advantages of LVM-ext4
|
||||
|
||||
![Structure of ext4 on LVM][13]
|
||||
|
||||
The [ext4 file system][14] focuses on high-performance and scalability, without a lot of extra frills. It is effective at preventing fragmentation over extended periods of time and provides [nice tools][15] for when it does happen. Ext4 is rock solid because it built on the previous ext3 file system, bringing with it all the years of in-system testing and bug fixes.
|
||||
|
||||
Most of the advanced capabilities in the LVM-ext4 setup come from LVM itself. LVM sits “below” the file system, which means it supports any file system. Logical volumes (LV) are generic block devices so [virtual machines can use them directly.][16] This flexibility allows each logical volume to use the right file system, with the right options, for a variety of situations. This layered approach also honors the Unix philosophy of small tools working together.
|
||||
|
||||
The [volume group][17] (VG) abstraction from the hardware allows LVM to create flexible logical volumes. Each LV pulls from the same storage pool but has its own configuration. Resizing volumes is a lot easier than resizing physical partitions as there are no limitation of ordered placement of the data. LVM [physical volumes][18] (PV) can be any number of partitions and can even move between devices while the system is running.
|
||||
|
||||
LVM supports read-only and read-write [snapshots][19], which make it easy to create consistent backups from active systems. Each snapshot has a defined size, and a change to the source or snapshot volume use space from there. Alternately, logical volumes can also be part of a [thinly provisioned pool][20]. This allows snapshots to automatically use data from a pool instead of consuming fixed sized chunks defined at volume creation.
|
||||
|
||||
#### Multiple devices with LVM
|
||||
|
||||
LVM really shines when there are multiple devices. It has native support for most [RAID levels][21] and each logical volume can have a different RAID level. LVM will automatically choose appropriate physical devices for the RAID configuration or the user can specify it directly. Basic RAID support includes data striping for performance ([RAID0][22]) and mirroring for redundancy ([RAID1][23]). Logical volumes can also use advanced setups like [RAID5][24], [RAID6][25], and [RAID10][26]. LVM RAID support is mature because under the hood LVM uses the same [device-mapper (dm)][27] and [multiple-device (md)][28] kernel support used by [mdadm][29].
|
||||
|
||||
Logical volumes can also be [cached volumes][30] for systems with both fast and slow drives. A classic example is a combination of SSD and spinning-disk drives. Cached volumes use faster drives for more frequently accessed data (or as a write cache), and the slower drive for bulk data.
|
||||
|
||||
The large number of stable features in LVM and the reliable performance of ext4 are a testament to how long they have been in use. Of course, with more features comes complexity. It can be challenging to find the right options for the right feature when configuring LVM. For single drive desktop systems, features of LVM like RAID and cache volumes don’t apply. However, logical volumes are more flexible than physical partitions and snapshots are useful. For normal desktop use, the complexity of LVM can also be a barrier to recovering from issues a typical user might encounter.
|
||||
|
||||
### Advantages of Btrfs
|
||||
|
||||
![Btrfs Structure][31]
|
||||
|
||||
Lessons learned from previous generations guided the features built into [Btrfs][5]. Unlike ext4, it can directly span multiple devices, so it brings along features typically found only in volume managers. It also has features that are unique in the Linux file system space ([ZFS][32] has a similar feature set, but [don’t expect it in the Linux kernel][33]).
|
||||
|
||||
#### Key Btrfs features
|
||||
|
||||
Perhaps the most important feature is the checksumming of all data. Checksumming, along with copy-on-write, provides the [key method][34] of ensuring file system integrity after unexpected power loss. More uniquely, checksumming can detect errors in the data itself. Silent data corruption, sometimes referred to as [bitrot][35], is more common that most people realize. Without active validation, corruption can end up propagating to all available backups. This leaves the user with no valid copies. By transparently checksumming all data, Btrfs is able to immediately detect any such corruption. Enabling the right [dup or raid option][36] allows the file system to transparently fix the corruption as well.
|
||||
|
||||
[Copy-on-write][37] (COW) is also a fundamental feature of Btrfs, as it is critical in providing file system integrity and instant subvolume snapshots. Snapshots automatically share underlying data when created from common subvolumes. Additionally, after-the-fact [deduplication][38] uses the same technology to eliminate identical data blocks. Individual files can use COW features by calling _cp_ with the [reflink option][39]. Reflink copies are especially useful for copying large files, such as virtual machine images, that tend to have mostly identical data over time.
|
||||
|
||||
Btrfs supports spanning multiple devices with no volume manager required. Multiple device support unlocks data mirroring for redundancy and striping for performance. There is also experimental support for more advanced RAID levels, such as [RAID5][24] and [RAID6][25]. Unlike standard RAID setups, the Btrfs _raid1_ option actually allows an odd number of devices. For example, it can use 3 devices, even if they are are different sizes.
|
||||
|
||||
All RAID and dup options are specified at the file system level. As a consequence, individual subvolumes cannot use different options. Note that using the RAID1 option with multiple devices means that all data in the volume is available even if one device fails and the checksum feature maintains the integrity of the data itself. That is beyond what current typical RAID setups can provide.
|
||||
|
||||
#### Additional features
|
||||
|
||||
Btrfs also enables quick and easy remote backups. Subvolume snapshots can be [sent to a remote system][40] for storage. By leveraging the inherent COW meta-data in the file system, these transfers are efficient by only sending incremental changes from previously sent snapshots. User applications such as [snapper][41] make it easy to manage these snapshots.
|
||||
|
||||
Additionally, a Btrfs volume can have [transparent compression][42] and _[chattr +c][43]_ will mark individual files or directories for compression. Not only does compression reduce the space consumed by data, but it helps extend the life of SSDs by reducing the volume of write operations. Compression certainly introduces additional CPU overhead, but a lot of options are available to dial in the right trade-offs.
|
||||
|
||||
The integration of file system and volume manager functions by Btrfs means that overall maintenance is simpler than LVM-ext4. Certainly this integration comes with less flexibility, but for most desktop, and even server, setups it is more than sufficient.
|
||||
|
||||
### Btrfs on LVM
|
||||
|
||||
Btrfs can [convert an ext3/ext4 file system in place][44]. In-place conversion means no data to copy out and then back in. The data blocks themselves are not even modified. As a result, one option for an existing LVM-ext4 systems is to leave LVM in place and simply convert ext4 over to Btrfs. While doable and supported, there are reasons why this isn’t the best option.
|
||||
|
||||
Some of the appeal of Btrfs is the easier management that comes with a file system integrated with a volume manager. By running on top of LVM, there is still some other volume manager in play for any system maintenance. Also, LVM setups typically have multiple fixed sized logical volumes with independent file systems. While Btrfs supports multiple volumes in a given computer, many of the nice features expect a single volume with multiple subvolumes. The user is still stuck manually managing fixed sized LVM volumes if each one has an independent Btrfs volume. Though, the ability to shrink mounted Btrfs filesystems does make working with fixed sized volumes less painful. With online shrink there is no need to boot a [live image][45].
|
||||
|
||||
The physical locations of logical volumes must be carefully considered when using the multiple device support of Btrfs. To Btrfs, each LV is a separate physical device and if that is not actually the case, then certain data availability features might make the wrong decision. For example, using _raid1_ for data typically provides protection if a single drive fails. If the actual logical volumes are on the same physical device, then there is no redundancy.
|
||||
|
||||
If there is a strong need for some particular LVM feature, such as raw block devices or cached logical volumes, then running Btrfs on top of LVM makes sense. In this configuration, Btrfs still provides most of its advantages such as checksumming and easy sending of incremental snapshots. While LVM has some operational overhead when used, it is no more so with Btrfs than with any other file system.
|
||||
|
||||
### Wrap up
|
||||
|
||||
When trying to choose between Btrfs and LVM-ext4 there is no single right answer. Each user has unique requirements, and the same user may have different systems with different needs. Take a look at the feature set of each configuration, and decide if there is something compelling about one over the other. If not, there is nothing wrong with sticking with the defaults. There are excellent reasons to choose either setup.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/choose-between-btrfs-and-lvm-ext4/
|
||||
|
||||
作者:[Troy Curtis Jr][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/troycurtisjr/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/12/btrfs-lvm-ext4-816x345.jpg
|
||||
[2]: https://unsplash.com/@raulpetri?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[4]: https://fedoramagazine.org/announcing-fedora-33/
|
||||
[5]: https://btrfs.wiki.kernel.org/index.php/Main_Page
|
||||
[6]: https://ext4.wiki.kernel.org/index.php/Main_Page
|
||||
[7]: https://man7.org/linux/man-pages/man8/lvm.8.html
|
||||
[8]: https://fedoraproject.org/wiki/Changes/BtrfsByDefault
|
||||
[9]: https://man7.org/linux/man-pages/man5/filesystems.5.html
|
||||
[10]: https://docs.fedoraproject.org/en-US/Fedora/11/html/Release_Notes/index.html#sect-Release_Notes-Fedora_11_Overview
|
||||
[11]: https://facebookmicrosites.github.io/btrfs/docs/btrfs-facebook.html
|
||||
[12]: https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12/#fate-317221
|
||||
[13]: https://fedoramagazine.org/wp-content/uploads/2020/12/ext4-on-LVM.jpg
|
||||
[14]: https://opensource.com/article/18/4/ext4-filesystem
|
||||
[15]: https://man7.org/linux/man-pages/man8/e4defrag.8.html
|
||||
[16]: https://libvirt.org/storage.html#StorageBackendLogical
|
||||
[17]: https://www.redhat.com/sysadmin/create-volume-group
|
||||
[18]: https://www.redhat.com/sysadmin/create-physical-volume
|
||||
[19]: https://tldp.org/HOWTO/LVM-HOWTO/snapshotintro.html
|
||||
[20]: https://man7.org/linux/man-pages/man7/lvmthin.7.html
|
||||
[21]: https://rhea.dev/articles/2018-08/LVM-RAID-on-Fedora
|
||||
[22]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_0
|
||||
[23]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1
|
||||
[24]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_5
|
||||
[25]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_6
|
||||
[26]: https://en.wikipedia.org/wiki/Non-standard_RAID_levels#Linux_MD_RAID_10
|
||||
[27]: https://man7.org/linux/man-pages/man8/dmsetup.8.html
|
||||
[28]: https://man7.org/linux/man-pages/man4/md.4.html
|
||||
[29]: https://fedoramagazine.org/managing-raid-arrays-with-mdadm/
|
||||
[30]: https://man7.org/linux/man-pages/man7/lvmcache.7.html
|
||||
[31]: https://fedoramagazine.org/wp-content/uploads/2020/12/Btrfs-Volume.jpg
|
||||
[32]: https://en.wikipedia.org/wiki/ZFS
|
||||
[33]: https://itsfoss.com/linus-torvalds-zfs/
|
||||
[34]: https://btrfs.wiki.kernel.org/index.php/FAQ#Can_I_have_nodatacow_.28or_chattr_.2BC.29_but_still_have_checksumming.3F
|
||||
[35]: https://arstechnica.com/information-technology/2014/01/bitrot-and-atomic-cows-inside-next-gen-filesystems/
|
||||
[36]: https://man7.org/linux/man-pages/man8/mkfs.btrfs.8.html#DUP_PROFILES_ON_A_SINGLE_DEVICE
|
||||
[37]: https://en.wikipedia.org/wiki/Copy-on-write
|
||||
[38]: https://btrfs.wiki.kernel.org/index.php/Deduplication
|
||||
[39]: https://btrfs.wiki.kernel.org/index.php/UseCases#How_do_I_copy_a_large_file_and_utilize_COW_to_keep_it_from_actually_being_copied.3F
|
||||
[40]: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/
|
||||
[41]: http://snapper.io/
|
||||
[42]: https://btrfs.wiki.kernel.org/index.php/Compression
|
||||
[43]: https://www.man7.org/linux/man-pages/man1/chattr.1.html
|
||||
[44]: https://btrfs.wiki.kernel.org/index.php/Conversion_from_Ext3
|
||||
[45]: https://fedoramagazine.org/reclaim-hard-drive-space-with-lvm/
|
@ -0,0 +1,131 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn Lua by writing a "guess the number" game)
|
||||
[#]: via: (https://opensource.com/article/20/12/lua-guess-number-game)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Learn Lua by writing a "guess the number" game
|
||||
======
|
||||
Get to know Lua, a dynamically typed, lightweight, efficient, and
|
||||
embeddable scripting language, by programming a simple game.
|
||||
![Puzzle pieces coming together to form a computer screen][1]
|
||||
|
||||
If you're a fan of scripting languages like Bash, Python, or Ruby, you might find Lua interesting. Lua is a dynamically typed, lightweight, efficient, and embeddable scripting language with an API to interface with C. It runs by interpreting bytecode with a register-based virtual machine, and it can be used for everything from procedural programming to functional programming to data-driven programming. It can even be used for object-oriented programming through the clever use of arrays, or _tables_, used to mimic classes.
|
||||
|
||||
A great way to get a feel for a language is by writing a simple application you're already familiar with. Recently, some Opensource.com correspondents have demonstrated how to use their favorite languages to create a number-guessing game. [Lua][2] is one of my favorites, so here's my Lua version of the guessing game.
|
||||
|
||||
### Install Lua
|
||||
|
||||
If you're on Linux, you can install Lua from your distribution's software repository. On macOS, you can install Lua from [MacPorts][3] or [Homebrew][4]. On Windows, you can install Lua from [Chocolatey][5].
|
||||
|
||||
Once you have Lua installed, open your favorite text editor and get ready to code.
|
||||
|
||||
### Lua code
|
||||
|
||||
First, you must set up a pseudo-random number generator, so your player has something unpredictable to try to guess. This is a two-step process: first, you start a random seed based on the current time, and then you select a number within the range of 1 to 100:
|
||||
|
||||
|
||||
```
|
||||
math.randomseed(os.[time][6]())
|
||||
number = math.random(1,100)
|
||||
```
|
||||
|
||||
Next, create what Lua calls a _table_ to represent your player. A table is like an [array in Bash][7] or an ArrayList in Java. You can create a table and then assign child variables associated with that table. In this code, `player` is the table, and `player.guess` is an entry in that table:
|
||||
|
||||
|
||||
```
|
||||
player = {}
|
||||
player.guess = 0
|
||||
```
|
||||
|
||||
For the purpose of debugging, print the secret number. This isn't good for the game, but it's great for testing. Comments in Lua are preceded by double dashes:
|
||||
|
||||
|
||||
```
|
||||
`print(number) --debug`
|
||||
```
|
||||
|
||||
Next, set up a `while` loop that runs forever upon the condition that the value assigned to `player.guess` is not equal to the random `number` established at the start of the code. Currently, `player.guess` is set to 0, so it is not equal to `number`. Lua's math operator for inequality is `~=`, which is admittedly unique, but you get used to it after a while.
|
||||
|
||||
The first thing that happens during this infinite loop is that the game prints a prompt so that the player understands the game.
|
||||
|
||||
Next, Lua pauses and waits for the player to enter a guess. Lua reads from files and standard in (stdin) using the `io.read` function. You can assign the results of `io.read` to a variable that is dynamically created in the `player` table. The problem with the player's input is that it is read as a string, even if it's a number. You can convert this input to an integer type using the `tonumber()` function, assigning the result back to the `player.guess` variable that initially contained 0:
|
||||
|
||||
|
||||
```
|
||||
while ( player.guess ~= number ) do
|
||||
print("Guess a number between 1 and 100")
|
||||
player.answer = io.read()
|
||||
player.guess = tonumber(player.answer)
|
||||
```
|
||||
|
||||
Now that `player.guess` contains a new value, it's compared to the random number in an `if` statement. Lua uses the keywords `if`, `elseif`, and `else` and terminates the statement with the keyword `end:`
|
||||
|
||||
|
||||
```
|
||||
if ( player.guess > number ) then
|
||||
print("Too high")
|
||||
elseif ( player.guess < number) then
|
||||
print("Too low")
|
||||
else
|
||||
print("That's right!")
|
||||
os.[exit][8]()
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
At the end, the function `os.exit()` closes the application upon success and the keyword `end` is used twice: once to end the `if` statement and again to end the `while` loop.
|
||||
|
||||
### Run the application
|
||||
|
||||
Run the game in a terminal:
|
||||
|
||||
|
||||
```
|
||||
$ lua ./guess.lua
|
||||
96
|
||||
Guess a number between 1 and 100
|
||||
1
|
||||
Too low
|
||||
Guess a number between 1 and 100
|
||||
99
|
||||
Too high
|
||||
Guess a number between 1 and 100
|
||||
96
|
||||
That's right!
|
||||
```
|
||||
|
||||
That's it!
|
||||
|
||||
### Intuitive and consistent
|
||||
|
||||
As you may be able to tell from this code, Lua is sublimely consistent and fairly intuitive. Its table mechanism is a refreshing way of associating data, and its syntax is minimalistic and efficient. There are few wasted lines in Lua code; in fact, at least one pair of lines in this example could be optimized further, but I wanted to demonstrate data conversion as its own step (maybe you can find the two lines I'm referring to and restructure them).
|
||||
|
||||
Lua is a pleasure to use, and its [documentation is a pleasure to read][9], mostly because there's just not that much to it. You'll learn the core language in no time, and then you'll be free to explore [LuaRocks][10] to discover all the great libraries others have contributed to make your time with Lua even easier. "Lua" means "moon" in Portuguese, so give it a try tonight.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/lua-guess-number-game
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
|
||||
[2]: https://www.lua.org/
|
||||
[3]: https://opensource.com/article/20/11/macports
|
||||
[4]: https://opensource.com/article/20/6/homebrew-mac
|
||||
[5]: https://opensource.com/article/20/3/chocolatey
|
||||
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/time.html
|
||||
[7]: https://opensource.com/article/20/6/associative-arrays-bash
|
||||
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/exit.html
|
||||
[9]: https://www.lua.org/docs.html
|
||||
[10]: https://opensource.com/article/19/11/getting-started-luarocks
|
@ -0,0 +1,73 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Use the Markdown Editor app in Nextcloud)
|
||||
[#]: via: (https://opensource.com/article/20/12/nextcloud-markdown)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Use the Markdown Editor app in Nextcloud
|
||||
======
|
||||
Nextcloud has one of the smoothest editors of the popular Markdown file
|
||||
type, with lots of convenient and intuitive features.
|
||||
![Digital images of a computer desktop][1]
|
||||
|
||||
The advantage of plain text is that there’s no extra computer-specific information cluttering up your otherwise human-readable writing. The good thing about computers is that they’re programmable, and so as long as we humans agree to follow very specific conventions when writing, we can program computers to interpret human-readable text as secret instructions. For instance, by surrounding a word with two asterisks, we not only give a visual cue to humans that a word is significant, but we can also program computers to display the word in **bold**.
|
||||
|
||||
This is exactly the theory and practice behind [Markdown][2], the popular plain text format that promises writers that as long as _they_ use specific plain text conventions, then their text will be rendered with a specific style.
|
||||
|
||||
Traditionally, that has meant that an author writes in plain text and doesn’t see the pretty styling until the text is fed to a converter application (originally `markdown.pl`), but the Markdown Editor app in Nextcloud changes that.
|
||||
|
||||
With Nextcloud’s Markdown Editor, you can type in plain text while seeing the style it renders. This is a gamechanger for authors who struggle to remember Markdown’s sometimes confusing notation (do the brackets become before or after the parentheses in a hyperlink?) or who just don’t like the look of plain text. And better yet, it runs in the (Next)cloud, so it’s available to you anywhere.
|
||||
|
||||
### Install
|
||||
|
||||
To use Nextcloud’s Markdown Editor, you must have an install of Nextcloud. The good news is, Nextcloud is surprisingly _easy_ to install. I’ve installed it on a Raspberry Pi, on a shared server, and even as a local app (which is silly, don’t do it). If you don’t trust your own abilities, you can even rely on [Turnkey Linux][3] to do the hard part for you, or else just purchase managed hosting directly from [Nextcloud.com][4]. Once you have Nextcloud installed, adding apps is simple. Click on your user icon in the top right corner of the Nextcloud interface and select **Apps**. Navigate to the **Office and Text** category and click to install and enable the **Markdown Editor**.
|
||||
|
||||
![Nextcloud app store showing Markdown Editor installer][5]
|
||||
|
||||
### Launching
|
||||
|
||||
After activation, the Markdown Editor gets associated with any file ending in .md in your Nextcloud files, so when you open a Markdown file, you launch Markdown Editor.
|
||||
|
||||
### Using Markdown Editor
|
||||
|
||||
The Markdown Editor contains a large text field for you to type into and a single toolbar along the top.
|
||||
|
||||
![Example markdown file ][6]
|
||||
|
||||
The toolbar contains the basic functions of a word processor—styling your text with bold, italics, and strike-through, creating headings and paragraphs, lists, and so on.
|
||||
|
||||
Many of these functions get invoked automatically as you type if you know Markdown. If you’re not familiar with Markdown, then the toolbar or the usual keyboard shortcuts (**Ctrl+B** for bold, **Ctrl+I** for italics, and so on) help you style your text.
|
||||
|
||||
The great thing about the way Markdown Editor works is that it truly is all things for all users: if you want to type in Markdown, then it accepts that and instantly converts it into visual styling, and if you don’t want to think about Markdown, then it generates the style for you when you use keyboard shortcuts or toolbar buttons. Either way, you never have to see the Markdown syntax, but you also never lose it. It’s the perfect compromise.
|
||||
|
||||
It’s an awfully smart editor, too. It offers to create a hyperlink for you when you select a word, it auto-converts Markdown quickly and smoothly, and it knows a few different "flavors" of Markdown syntax (Commonmark primarily, but also traditional Markdown, Github Markdown, and so on).
|
||||
|
||||
![black text on white background, word highlighted in blue to create an automatic link][7]
|
||||
|
||||
### Try Nextcloud
|
||||
|
||||
I’ve used a few Markdown preview applications, and Nextcloud’s Markdown Editor is one of the smoothest. It respects its user and does the bare minimum to display Markdown, so its conversion is fast and accurate. Because it’s an app in Nextcloud, you also get the benefit of having your work saved instantly, with version control, on your own private, open source cloud. Text editing doesn’t get much better than that.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/nextcloud-markdown
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_desk_home_laptop_browser.png?itok=Y3UVpY0l (Digital images of a computer desktop)
|
||||
[2]: https://opensource.com/article/19/9/introduction-markdown
|
||||
[3]: https://www.turnkeylinux.org/nextcloud
|
||||
[4]: http://nextcloud.com
|
||||
[5]: https://opensource.com/sites/default/files/uploads/nextcloud-app-install-31_days-markdown-opensource.jpg (Nextcloud app store showing Markdown Editor installer)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/nextcloud-markdown-31-days-opensource.jpg (Example markdown file )
|
||||
[7]: https://opensource.com/sites/default/files/uploads/nextcloud-link-31_days_markdown-opensource.jpg (black text on white background, word highlighted in blue to create an automatic link)
|
88
sources/tech/20201231 10 things to love about Git.md
Normal file
88
sources/tech/20201231 10 things to love about Git.md
Normal file
@ -0,0 +1,88 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (10 things to love about Git)
|
||||
[#]: via: (https://opensource.com/article/20/12/git)
|
||||
[#]: author: (Joshua Allen Holm https://opensource.com/users/holmja)
|
||||
|
||||
10 things to love about Git
|
||||
======
|
||||
Knowing more about how Git works makes working with Git easier. Learn
|
||||
more in our readers' favorite Git articles of the year.
|
||||
![Business woman on laptop sitting in front of window][1]
|
||||
|
||||
Git is an essential tool in the open source developer's toolkit. This powerful version-control system has a lot of complex features. Not all of the features are necessary to use Git, but knowing more about how Git works makes working with Git easier.
|
||||
|
||||
During 2020, Opensource.com published many excellent articles about Git, including the top 10 covered below. Each article provides tips and tricks for improving and enhancing your Git experience.
|
||||
|
||||
### How to resolve a git merge conflict
|
||||
|
||||
This tutorial by Brian Breniser begins by defining `git merge` and explaining what merge conflicts are. Then he provides a detailed tutorial about how to [work through a merge conflict][2] when one arises. Breniser also provides a few suggestions for where you can go to learn more about resolving merge conflicts and other Git functions.
|
||||
|
||||
### 4 Git scripts I can't live without
|
||||
|
||||
Vince Power shares his [most important Git scripts][3]. These scripts come from the Git Extras package, which provides over 60 scripts for enhancing Git. Power's favorite scripts are `git-ignore` for editing `.git-ignore` without opening a text editor; `git-info` for providing a summary about a Git repository; `git-mr` and `git-pr` for dealing with merge requests on GitLab and pull requests on GitHub; and `git-release`, which combines Git's `commit`, `tag`, and `push` into a single command.
|
||||
|
||||
### The life-changing magic of git rebase -i
|
||||
|
||||
Learn how to use [git rebase -i to revise your Git history][4] in this article by Dave Neary. Neary starts by explaining how Git handles the history of commits to a repository and the differences between `git commit` and `git rebase`. Next, he explains how to use `git rebase -i` to alter the history of a Git repository to make things cleaner. This allows you to move changes from "fixed typo" commits into other commits and merge similar smaller commits into combined larger commits.
|
||||
|
||||
### Make Git easy with Git Cola
|
||||
|
||||
Opensource.com editor Seth Kenlon demonstrates [how to use Git Cola][5]. Git is a command-line tool, which might turn some people off from using it. Git Cola provides a graphical interface to Git, so users who are not comfortable working on the command line can still take advantage of Git's features. In this article, Kenlon shows how to install Git Cola and accomplish many Git commit tasks using Git Cola's graphical user interface.
|
||||
|
||||
### 6 best practices for teams using Git
|
||||
|
||||
By design, Git is a collaborative tool, but many of the specifics about how to collaborate are left up to teams to decide. Ravi Chandran provides suggestions that any team could adopt [to use Git more effectively][6]. The six best practices, which Chandran explains in the article, are "formalize Git conventions," "merge changes properly," "rebase your feature branch often," "squash commits before merging," "use tags," and "make the software executable print the tag."
|
||||
|
||||
### 7 Git tricks that changed my life
|
||||
|
||||
Rajeev Bera shares [seven Git tricks][7] that improve the user experience when working with Git. The article explores Git's autocorrect option, counting commits, repo optimization, backing up untracked files, knowing the `.git` folder, viewing a file on another branch, and searching in Git.
|
||||
|
||||
### Customizing my Linux terminal with tmux and Git
|
||||
|
||||
Moshe Zadka demonstrates how he [used tmux and Git][8] to customize his Linux terminal. Zadka's article is a fascinating exploration of one person's workflow. He uses GNOME Terminal but enhances it by using tmux and features that allow him to see the status of a Git repository quickly. If files need to be committed or a commit needs to be pushed, a single letter indicates that.
|
||||
|
||||
### Make advanced Git tasks simple with Lazygit
|
||||
|
||||
Jesse Duffield explains how to use [Lazygit, a terminal interface that makes using Git easier][9]. Duffield, who developed Lazygit, details how to use the interface to stage files, rebase interactively, do cherry-picking, search through commits, and open a pull request.
|
||||
|
||||
### Managing Git projects with submodules and subtrees
|
||||
|
||||
Submodules and subtrees are two different ways to include nested subprojects in a Git repository. In [_Managing Git projects with submodules and subtrees_][10], Manaswini Das explains how the two options work and how they differ.
|
||||
|
||||
### Don't love diff? Use Meld instead
|
||||
|
||||
Ben Nuttall shows how to [use Meld instead of diff][11] to compare and merge changes. Meld is a graphical alternative to `diff` with output that is easier to understand. Nuttall demonstrates the difference between comparing two files using `diff` and Meld. He also explains how Meld is Git-aware, which means it can be used to explore changes made to a file since the last time it was committed in Git.
|
||||
|
||||
* * *
|
||||
|
||||
What do you want to learn about Git? Please share your ideas in the comments, and if you have knowledge to share, please [consider writing about it for Opensource.com][12].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/git
|
||||
|
||||
作者:[Joshua Allen Holm][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/holmja
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||
[2]: https://opensource.com/article/20/4/git-merge-conflict
|
||||
[3]: https://opensource.com/article/20/4/git-extras
|
||||
[4]: https://opensource.com/article/20/4/git-rebase-i
|
||||
[5]: https://opensource.com/article/20/3/git-cola
|
||||
[6]: https://opensource.com/article/20/7/git-best-practices
|
||||
[7]: https://opensource.com/article/20/10/advanced-git-tips
|
||||
[8]: https://opensource.com/article/20/7/tmux-git
|
||||
[9]: https://opensource.com/article/20/3/lazygit
|
||||
[10]: https://opensource.com/article/20/5/git-submodules-subtrees
|
||||
[11]: https://opensource.com/article/20/3/meld
|
||||
[12]: https://opensource.com/how-submit-article
|
@ -0,0 +1,58 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (4 considerations for getting started with CI/CD in 2021)
|
||||
[#]: via: (https://opensource.com/article/20/12/cicd)
|
||||
[#]: author: (Jessica Cherry https://opensource.com/users/cherrybomb)
|
||||
|
||||
4 considerations for getting started with CI/CD in 2021
|
||||
======
|
||||
Build your continuous integration/continuous delivery adoption plan by
|
||||
looking back at the top articles of 2020.
|
||||
![Tips and gears turning][1]
|
||||
|
||||
In 2020, Opensource.com's articles about continuous integration and continuous delivery (CI/CD) aimed to help you rethink your infrastructure with continuous delivery. If you're new to the CI/CD way of doing things or you need a refresher, read on for summaries of the top four CI/CD articles of 2020.
|
||||
|
||||
### Success from the start
|
||||
|
||||
If you want to start working with CI/CD but don't know what it takes to be successful, Tonya Brown paves the way with [_8 CI/CD best practices to set you up for success_][2]. This great read covers various deployment pipeline examples and tools to get you moving. But wait, there's more! Tonya also covers CI/CD automation with version control, metrics alerting, and my personal favorite, infrastructure as code. There is even more information jam-packed into this article to get you on the road to success.
|
||||
|
||||
### Give it a try
|
||||
|
||||
Knowing the eight best practices is important, but what happens when you're ready to try CI/CD for yourself? In the introductory article [_Set up Minishift and run Jenkins on Linux_][3], Jessica Cherry presents a step-by-step setup to use Jenkins and create your first pipeline. This tutorial is a great place to start and test your first CI/CD project before jumping in feet-first on your own.
|
||||
|
||||
### Jenkins as code
|
||||
|
||||
If you're already familiar with Jenkins and CI/CD pipelines but want to run configuration as code, Kedar Vijay Kulkarni's article [_Getting started with Jenkins Configuration as Code_][4] is the read for you! This walkthrough shows you how to use a plugin to create Jenkins multibranch pipelines using YAML. In great detail, Kedar shows how to configure even more and manage Jenkins in the infrastructure-as-code way.
|
||||
|
||||
### What about testing?
|
||||
|
||||
Have you ever been curious about automated testing and how it can affect your team? In _[What you need to know about automation testing in CI/CD][5],_ Tonya Brown covers test automation and why it makes sense to automate testing in CI/CD. Tonya also covers what automation means to the testing teams, their needs, and what types of testing to automate. This detailed account of testing automation is a great place to start working towards better testing with automation and CI/CD.
|
||||
|
||||
### Final thoughts
|
||||
|
||||
If the new year brings you new challenges and your automation is limited, take a look back at these articles. If you're wondering what you need to get started, the answer is one computer and some reiterative things done manually. If you take just one step at a time using these great reads, you'll be automated in no time at all!
|
||||
|
||||
Do you have ideas for other articles we should cover in 2021? Please share your suggestions in the comments, or even consider [writing an article][6] about your own CI/CD journey!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/cicd
|
||||
|
||||
作者:[Jessica Cherry][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/cherrybomb
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/gears_devops_learn_troubleshooting_lightbulb_tips_520.png?itok=HcN38NOk (Tips and gears turning)
|
||||
[2]: https://opensource.com/article/20/5/cicd-best-practices
|
||||
[3]: https://opensource.com/article/20/11/minishift-linux
|
||||
[4]: https://opensource.com/article/20/4/jcasc-jenkins
|
||||
[5]: https://opensource.com/article/20/7/automation-testing-cicd
|
||||
[6]: https://opensource.com/how-submit-article
|
342
sources/tech/20201231 Build your own text editor in Java.md
Normal file
342
sources/tech/20201231 Build your own text editor in Java.md
Normal file
@ -0,0 +1,342 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Build your own text editor in Java)
|
||||
[#]: via: (https://opensource.com/article/20/12/write-your-own-text-editor)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Build your own text editor in Java
|
||||
======
|
||||
Sometimes, no one can make your dream tool but you. Here's how to start
|
||||
building your own text editor.
|
||||
![Working from home at a laptop][1]
|
||||
|
||||
There are a lot of text editors available. There are those that run in the terminal, in a GUI, in a browser, and in a browser engine. Many are very good, and some are great. But sometimes, the most satisfying answer to any question is the one you build yourself.
|
||||
|
||||
Make no mistake: building a really good text editor is a lot harder than it may seem. But then again, it’s also not as hard as you might fear to build a basic one. In fact, most programming toolkits already have most of the text editor parts ready for you to use. The components around the text editing, such as a menu bar, file chooser dialogues, and so on, are easy to drop into place. As a result, a basic text editor is a surprisingly fun and elucidating, though intermediate, lesson in programming. You might find yourself eager to use a tool of your own construction, and the more you use it, the more you might be inspired to add to it, learning even more about the programming language you’re using.
|
||||
|
||||
To make this exercise realistic, it’s best to choose a language with a good GUI toolkit. There are many to choose from, including Qt, FLTK, or GTK, but be sure to review the documentation first to ensure it has the features you expect. For this article, I use Java with its built-in Swing widget set. If you want to use a different language or a different toolset, this article can still be useful in giving you an idea of how to approach the problem.
|
||||
|
||||
Writing a text editor in any major toolkit is surprisingly similar, no matter which one you choose. If you’re new to Java and need further information on getting started, read my [Guessing Game article][2] first.
|
||||
|
||||
### Project setup
|
||||
|
||||
Normally, I use and recommend an IDE like [Netbeans][3] or Eclipse, but I find that, when practicing a new language, it can be helpful to do some manual labor, so you better understand the things that get hidden from you when using an IDE. In this article, I assume you’re programming using a text editor and a terminal.
|
||||
|
||||
Before getting started, create a project directory for yourself. In the project folder, create one directory called `src` to hold your source files.
|
||||
|
||||
|
||||
```
|
||||
$ mkdir -p myTextEditor/src
|
||||
$ cd myTextEditor
|
||||
```
|
||||
|
||||
Create an empty file called `TextEdit.java` in your `src` directory:
|
||||
|
||||
|
||||
```
|
||||
`$ touch src/TextEditor.java`
|
||||
```
|
||||
|
||||
Open the file in your favorite text editor (I mean your favorite one that you didn’t write) and get ready to code!
|
||||
|
||||
### Package and imports
|
||||
|
||||
To ensure your Java application has a unique identifier, you must declare a **package** name. The typical format for this is to use a reverse domain name, which is particularly easy should you actually have a domain name. If you don’t, you can use `local` as the top level. As usual for Java and many languages, the line is terminated with a semicolon.
|
||||
|
||||
After naming your Java package, you must tell the Java compiler (`javac`) what libraries to use when building your code. In practice, this is something you usually add to as you code because you rarely know yourself what libraries you need. However, there are some that are obvious beforehand. For instance, you know this text editor is based around the Swing GUI toolkit, so importing `javax.swing.JFrame` and `javax.swing.UIManager` and other related libraries is a given.
|
||||
|
||||
|
||||
```
|
||||
package com.example.textedit;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
```
|
||||
|
||||
For the purpose of this exercise, you get prescient knowledge of all the libraries you need in advance. In real life, regardless of what language you favor, you’ll discover libraries as you research how to solve any given problem, and then you’ll import it into your code and use it. And don’t worry—should you forget to include a library, your compiler or interpreter will warn you!
|
||||
|
||||
### Main window
|
||||
|
||||
This is a single-window application, so the primary class of this application is a JFrame with an `ActionListener` attached to catch menu events. In Java, when you’re using an existing widget element, you "extend" it with your code. This main window needs three fields: the window itself (an instance of JFrame), an indicator for the return value of the file chooser, and the text editor itself (JTextArea).
|
||||
|
||||
|
||||
```
|
||||
public final class TextEdit extends [JFrame][4] implements [ActionListener][5] {
|
||||
private static [JTextArea][6] area;
|
||||
private static [JFrame][4] frame;
|
||||
private static int returnValue = 0;
|
||||
```
|
||||
|
||||
Amazingly, these few lines do about 80% of the work toward implementing a basic text editor because JTextArea is Java’s text entry field. Most of the remaining 80 lines take care of helper features, like saving and opening files.
|
||||
|
||||
### Building a menu
|
||||
|
||||
The `JMenuBar` widget is designed to sit at the top of a JFrame, providing as many entries as you want. Java isn’t a drag-and-drop programming language, though, so for every menu you add, you must also program a function. To keep this project manageable, I provide four functions: creating a new file, opening an existing file, saving text to a file, and closing the application.
|
||||
|
||||
The process of creating a menu is basically the same in most popular toolkits. First, you create the menubar itself, then you create a top-level menu (such as "File"), and then you create submenu items (such as "New," "Save," and so on).
|
||||
|
||||
|
||||
```
|
||||
public TextEdit() { run(); }
|
||||
|
||||
public void run() {
|
||||
frame = new [JFrame][4]("Text Edit");
|
||||
|
||||
// Set the look-and-feel (LNF) of the application
|
||||
// Try to default to whatever the host system prefers
|
||||
try {
|
||||
[UIManager][7].setLookAndFeel([UIManager][7].getSystemLookAndFeelClassName());
|
||||
} catch ([ClassNotFoundException][8] | [InstantiationException][9] | [IllegalAccessException][10] | [UnsupportedLookAndFeelException][11] ex) {
|
||||
Logger.getLogger(TextEdit.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
// Set attributes of the app window
|
||||
area = new [JTextArea][6]();
|
||||
frame.setDefaultCloseOperation([JFrame][4].EXIT_ON_CLOSE);
|
||||
frame.add(area);
|
||||
frame.setSize(640, 480);
|
||||
frame.setVisible(true);
|
||||
|
||||
// Build the menu
|
||||
[JMenuBar][12] menu_main = new [JMenuBar][12]();
|
||||
|
||||
[JMenu][13] menu_file = new [JMenu][13]("File");
|
||||
|
||||
[JMenuItem][14] menuitem_new = new [JMenuItem][14]("New");
|
||||
[JMenuItem][14] menuitem_open = new [JMenuItem][14]("Open");
|
||||
[JMenuItem][14] menuitem_save = new [JMenuItem][14]("Save");
|
||||
[JMenuItem][14] menuitem_quit = new [JMenuItem][14]("Quit");
|
||||
|
||||
menuitem_new.addActionListener(this);
|
||||
menuitem_open.addActionListener(this);
|
||||
menuitem_save.addActionListener(this);
|
||||
menuitem_quit.addActionListener(this);
|
||||
|
||||
menu_main.add(menu_file);
|
||||
|
||||
menu_file.add(menuitem_new);
|
||||
menu_file.add(menuitem_open);
|
||||
menu_file.add(menuitem_save);
|
||||
menu_file.add(menuitem_quit);
|
||||
|
||||
frame.setJMenuBar(menu_main);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
All that’s left to do now is to implement the functions described by the menu items.
|
||||
|
||||
### Programming menu actions
|
||||
|
||||
Your application responds to menu selections because your JFrame has an `ActionListener` attached to it. When you implement an event handler in Java, you must "override" its built-in functions. This sounds more severe than it actually is. You’re not rewriting Java; you’re just implementing functions that have been defined but not implemented by the event handler.
|
||||
|
||||
In this case, you must override the `actionPerformed` method. Because nearly all entries in the **File** menu have something to do with files, my code defines a JFileChooser early. The rest of the code is separated into clauses of an `if` statement, which looks to see what event was received and acts accordingly. Each clause is drastically different from the other because each item suggests something wholly unique. The most similar are **Open** and **Save** because they both use the JFileChooser to select a point in the filesystem to either get or put data.
|
||||
|
||||
The "**New**" selection clears the JTextArea without warning, and **Quit** closes the application without warning. Both of these "features" are dangerous, so should you want to make a small improvement to this code, that’s a good place to start. A friendly warning that the content hasn’t been saved is a vital feature of any good text editor, but for simplicity’s sake, that’s a feature for the future.
|
||||
|
||||
|
||||
```
|
||||
@Override
|
||||
public void actionPerformed([ActionEvent][15] e) {
|
||||
[String][16] ingest = null;
|
||||
[JFileChooser][17] jfc = new [JFileChooser][17]([FileSystemView][18].getFileSystemView().getHomeDirectory());
|
||||
jfc.setDialogTitle("Choose destination.");
|
||||
jfc.setFileSelectionMode([JFileChooser][17].FILES_AND_DIRECTORIES);
|
||||
|
||||
[String][16] ae = e.getActionCommand();
|
||||
if (ae.equals("Open")) {
|
||||
returnValue = jfc.showOpenDialog(null);
|
||||
if (returnValue == [JFileChooser][17].APPROVE_OPTION) {
|
||||
[File][19] f = new [File][19](jfc.getSelectedFile().getAbsolutePath());
|
||||
try{
|
||||
[FileReader][20] read = new [FileReader][20](f);
|
||||
Scanner scan = new Scanner(read);
|
||||
while(scan.hasNextLine()){
|
||||
[String][16] line = scan.nextLine() + "\n";
|
||||
ingest = ingest + line;
|
||||
}
|
||||
area.setText(ingest);
|
||||
}
|
||||
catch ( [FileNotFoundException][21] ex) { ex.printStackTrace(); }
|
||||
}
|
||||
// SAVE
|
||||
} else if (ae.equals("Save")) {
|
||||
returnValue = jfc.showSaveDialog(null);
|
||||
try {
|
||||
[File][19] f = new [File][19](jfc.getSelectedFile().getAbsolutePath());
|
||||
[FileWriter][22] out = new [FileWriter][22](f);
|
||||
out.write(area.getText());
|
||||
out.close();
|
||||
} catch ([FileNotFoundException][21] ex) {
|
||||
[Component][23] f = null;
|
||||
[JOptionPane][24].showMessageDialog(f,"File not found.");
|
||||
} catch ([IOException][25] ex) {
|
||||
[Component][23] f = null;
|
||||
[JOptionPane][24].showMessageDialog(f,"Error.");
|
||||
}
|
||||
} else if (ae.equals("New")) {
|
||||
area.setText("");
|
||||
} else if (ae.equals("Quit")) { [System][26].exit(0); }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That’s technically all there is to this text editor. Of course, nothing’s ever truly done, and besides, there’s still the testing and packaging steps, so there’s still plenty of time to discover missing requisites. In case you’re not picking up on the hint: there’s _definitely_ something missing in this code. Do you know what it is yet? (It’s mentioned mainly in the [Guessing Game article][2].)
|
||||
|
||||
### Testing
|
||||
|
||||
You can now test your application. Launch your text editor from a terminal:
|
||||
|
||||
|
||||
```
|
||||
$ java ./src/TextEdit.java
|
||||
error: can’t find main(String[]) method in class: com.example.textedit.TextEdit
|
||||
```
|
||||
|
||||
It seems that the code hasn’t got a main method. There are a few ways to fix this problem: you could create a main method in `TextEdit.java` and have it run an instance of the `TextEdit` class, or you can create a separate file containing the main method. Both work equally well, but the latter is more realistic in terms of what to expect from large projects, so it’s worth getting used to dealing with separate files that work together to make a complete application.
|
||||
|
||||
Create a `Main.java` file in `src` and open in your favorite editor:
|
||||
|
||||
|
||||
```
|
||||
package com.example.textedit;
|
||||
|
||||
public class Main {
|
||||
public static void main([String][16][] args) {
|
||||
TextEdit runner = new TextEdit();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can try again, but now there are two files that depend upon one another to run, so you have to compile the code. Java uses the `javac` compiler, and you can set your destination directory with the `-d` option:
|
||||
|
||||
|
||||
```
|
||||
`$ javac src/*java -d .`
|
||||
```
|
||||
|
||||
This creates a new directory structure modeled exactly after your package name: `com/example/textedit`. This new classpath contains the files `Main.class` and `TextEdit.class`, which are the two files that make up your application. You can run them with `java` by referencing the location and _name_ (not the filename) of your Main class:
|
||||
|
||||
|
||||
```
|
||||
`$ java info/slackermedia/textedit/Main`
|
||||
```
|
||||
|
||||
Your text editor opens, and you can type into it, open files, and even save your work.
|
||||
|
||||
![White text editor box with single drop down menu with options File, New, Open, Save, and Quit][27]
|
||||
|
||||
### Sharing your work as a Java package
|
||||
|
||||
While it seems to be acceptable to some programmers to deliver applications as an assortment of source files and hearty encouragement to learn how to run them, Java makes it really easy to package up your application so others can run it. You have most of the structure required, but you do need to add some metadata to a `Manifest.txt` file:
|
||||
|
||||
|
||||
```
|
||||
`$ echo "Manifest-Version: 1.0" > Manifest.txt`
|
||||
```
|
||||
|
||||
The `jar` command, used for packaging, is a lot like the [tar][28] command, so many of the options may look familiar to you. To create a JAR file:
|
||||
|
||||
|
||||
```
|
||||
$ jar cvfme TextEdit.jar
|
||||
Manifest.txt
|
||||
com.example.textedit.Main
|
||||
com/example/textedit/*.class
|
||||
```
|
||||
|
||||
From the syntax of the command, you may surmise that it creates a new JAR file called `TextEdit.jar`, with its required manifest data located in `Manifest.txt`. Its main class is defined as an extension of the package name, and the class itself is `com/example/textedit/Main.class`.
|
||||
|
||||
You can view the contents of the JAR file:
|
||||
|
||||
|
||||
```
|
||||
$ jar tvf TextEdit.jar
|
||||
0 Wed Nov 25 META-INF/
|
||||
105 Wed Nov 25 META-INF/MANIFEST.MF
|
||||
338 Wed Nov 25 com/example/textedit/textedit/Main.class
|
||||
4373 Wed Nov 25 com/example/textedit/textedit/TextEdit.class
|
||||
```
|
||||
|
||||
And you can even extract it with the `xvf` options, if you’d like to see how your metadata has been integrated into the `MANIFEST.MF` file.
|
||||
|
||||
Run your JAR file with the `java` command:
|
||||
|
||||
|
||||
```
|
||||
`$ java -jar TextEdit.jar`
|
||||
```
|
||||
|
||||
You can even [create a desktop file][29], so your application launches at the click of an icon in your applications menu.
|
||||
|
||||
### Improve it
|
||||
|
||||
In its current state, this is a very basic text editor, best suited for quick notes or short README documents. Some improvements (such as adding a vertical scrollbar) are quick and easy with a little research, while others (such as implementing an extensive preferences system) require real work.
|
||||
|
||||
But if you’ve been meaning to learn a new language, this could be the perfect practical project for your self-education. Creating a text editor, as you can see, isn’t overwhelming in terms of code, and it’s manageable in scope. If you use text editors frequently, then writing your own can be satisfying and fun. So open your favorite text editor (the one you wrote) and start adding features!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/12/write-your-own-text-editor
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||
[2]: https://opensource.com/article/20/12/learn-java
|
||||
[3]: https://opensource.com/article/20/12/netbeans
|
||||
[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jframe
|
||||
[5]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+actionlistener
|
||||
[6]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jtextarea
|
||||
[7]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+uimanager
|
||||
[8]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+classnotfoundexception
|
||||
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+instantiationexception
|
||||
[10]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+illegalaccessexception
|
||||
[11]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+unsupportedlookandfeelexception
|
||||
[12]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jmenubar
|
||||
[13]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jmenu
|
||||
[14]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jmenuitem
|
||||
[15]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+actionevent
|
||||
[16]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||
[17]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jfilechooser
|
||||
[18]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filesystemview
|
||||
[19]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+file
|
||||
[20]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filereader
|
||||
[21]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filenotfoundexception
|
||||
[22]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filewriter
|
||||
[23]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+component
|
||||
[24]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+joptionpane
|
||||
[25]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+ioexception
|
||||
[26]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
|
||||
[27]: https://opensource.com/sites/default/files/uploads/this-time-its-personal-31_days_yourself-opensource.png (White text editor box with single drop down menu with options File, New, Open, Save, and Quit)
|
||||
[28]: https://opensource.com/article/17/7/how-unzip-targz-file
|
||||
[29]: https://opensource.com/article/18/1/how-install-apps-linux
|
@ -0,0 +1,261 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Djinn: A Code Generator and Templating Language Inspired by Jinja2)
|
||||
[#]: via: (https://theartofmachinery.com/2021/01/01/djinn.html)
|
||||
[#]: author: (Simon Arneaud https://theartofmachinery.com)
|
||||
|
||||
Djinn: A Code Generator and Templating Language Inspired by Jinja2
|
||||
======
|
||||
|
||||
Code generators can be useful tools. I sometimes use the command line version of [Jinja2][1] to generate highly redundant config files and other text files, but it’s feature-limited for transforming data. Obviously the author of Jinja2 thinks differently, but I wanted something like list comprehensions or D’s composable range algorithms.
|
||||
|
||||
I decided to make a tool that’s like Jinja2, but lets me generate complex files by transforming data with range algorithms. The idea was dead simple: a templating language that gets rewritten directly to D code. That way it supports everything D does, simply because it _is_ D. I wanted a standalone code generator, but thanks to [D’s `mixin` feature][2], the same templating language works as an embedded templating language (for HTML in a web app, for example). (For more on that trick, see [this post about translating Brainfuck to D to machine code all at compile time using `mixin`s][3].)
|
||||
|
||||
As usual, [it’s on GitLab][4]. [The examples in this post can be found there, too.][5]
|
||||
|
||||
### Hello world example
|
||||
|
||||
Here’s an example to demonstrate the idea:
|
||||
|
||||
```
|
||||
Hello [= retro("dlrow") ]!
|
||||
[: enum one = 1; :]
|
||||
1 + 1 = [= one + one ]
|
||||
```
|
||||
|
||||
`[= some_expression ]` is like `{{ some_expression }}` in Jinja2, and it renders a value to the output. `[: some_statement; :]` is like `{% some_statement %}` and causes full code statements to be executed. I changed the syntax because D also uses curly braces a lot, and mixing the two made templates hard to read. (There are also special non-D directives, like `include`, that get wrapped in `[<` and `>]`.)
|
||||
|
||||
If you save the above to a file called `hello.txt.dj` and run the `djinn` command line tool against it, you’ll get a file called `hello.txt` containing what you might guess:
|
||||
|
||||
```
|
||||
Hello world!
|
||||
1 + 1 = 2
|
||||
```
|
||||
|
||||
If you’ve used Jinja2, you might be wondering what happened to the second line. Djinn has a special rule that simplifies formatting and whitespace handling: if a source line contains `[:` statements or `[<` directives but doesn’t contain any non-whitespace output, the whole line is ignored for output purposes. Blank lines are still rendered.
|
||||
|
||||
### Generating data
|
||||
|
||||
Okay, now for something a bit more practical: generating CSV data.
|
||||
|
||||
```
|
||||
x,f(x)
|
||||
[: import std.mathspecial;
|
||||
foreach (x; iota(-1.0, 1.0, 0.1)) :]
|
||||
[= "%0.1f,%g", x, normalDistribution(x) ]
|
||||
```
|
||||
|
||||
A `[=` and `]` pair can contain multiple expressions separated by commas. If the first expression is a double-quoted string, it’s interpreted as a [format string][6]. Here’s the output:
|
||||
|
||||
```
|
||||
x,f(x)
|
||||
-1.0,0.158655
|
||||
-0.9,0.18406
|
||||
-0.8,0.211855
|
||||
-0.7,0.241964
|
||||
-0.6,0.274253
|
||||
-0.5,0.308538
|
||||
-0.4,0.344578
|
||||
-0.3,0.382089
|
||||
-0.2,0.42074
|
||||
-0.1,0.460172
|
||||
0.0,0.5
|
||||
0.1,0.539828
|
||||
0.2,0.57926
|
||||
0.3,0.617911
|
||||
0.4,0.655422
|
||||
0.5,0.691462
|
||||
0.6,0.725747
|
||||
0.7,0.758036
|
||||
0.8,0.788145
|
||||
0.9,0.81594
|
||||
```
|
||||
|
||||
### Making an image
|
||||
|
||||
This example is just for the heck of it. [The classic netpbm image library defined a bunch of image formats][7], some of which are text-based. For example, here’s an image of a 3x3 cross:
|
||||
|
||||
```
|
||||
P2 # identifier for Portable GrayMap
|
||||
3 3 # width and height
|
||||
7 # value for pure white (0 is black)
|
||||
7 0 7
|
||||
0 0 0
|
||||
7 0 7
|
||||
```
|
||||
|
||||
You can save the above text to a file named something like `cross.pgm` and many image tools will understand it. Here’s some Djinn code that generates a [Mandelbrot set][8] fractal in the same format:
|
||||
|
||||
```
|
||||
[:
|
||||
import std.complex;
|
||||
enum W = 640;
|
||||
enum H = 480;
|
||||
enum kMaxIter = 20;
|
||||
ubyte mb(uint x, uint y)
|
||||
{
|
||||
const c = complex(3.0 * (x - W / 1.5) / W, 2.0 * (y - H / 2.0) / H);
|
||||
auto z = complex(0.0);
|
||||
ubyte ret = kMaxIter;
|
||||
while (abs(z) <= 2 && --ret) z = z * z + c;
|
||||
return ret;
|
||||
}
|
||||
:]
|
||||
P2
|
||||
[= W ] [= H ]
|
||||
[= kMaxIter ]
|
||||
[: foreach (y; 0..H) :]
|
||||
[= "%(%s %)", iota(W).map!(x => mb(x, y)) ]
|
||||
```
|
||||
|
||||
The resulting file is about 800kB, but it compresses nicely as a PNG:
|
||||
|
||||
```
|
||||
$ # Converting with GraphicsMagick
|
||||
$ gm convert mandelbrot.pgm mandelbrot.png
|
||||
```
|
||||
|
||||
And here it is:
|
||||
|
||||
![][9]
|
||||
|
||||
### Solving a puzzle
|
||||
|
||||
Here’s a puzzle:
|
||||
|
||||
![][10]
|
||||
|
||||
The 5x5 grid needs to be filled in with numbers from 1 to 5, using each number once in each row, and once in each column. (I.e., to make a 5x5 Latin square.) The numbers in neighbouring cells must also satisfy the inequalities indicated by any `>` greater-than signs.
|
||||
|
||||
[I used linear programming (LP) some months ago.][11] LP problems are systems of continuous variables with linear constraints. This time I’ll use mixed integer linear programming (MILP), which generalises LP by also allowing integer-constrained variables. It turns out that’s enough to be NP complete, and MILP happens to be reasonably good for modelling this puzzle.
|
||||
|
||||
In that previous post, I used the Julia library JuMP to help spec the problem. This time I’ll use the [CPLEX text-based format][12], which is supported by several LP and MILP solvers (and can be easily converted to other formats by off-the-shelf tools if needed). Here’s the LP from the previous post in CPLEX format:
|
||||
|
||||
```
|
||||
Minimize
|
||||
obj: v
|
||||
Subject To
|
||||
ptotal: pr + pp + ps = 1
|
||||
rock: 4 ps - 5 pp - v <= 0
|
||||
paper: 5 pr - 8 ps - v <= 0
|
||||
scissors: 8 pp - 4 pr - v <= 0
|
||||
Bounds
|
||||
0 <= pr <= 1
|
||||
0 <= pp <= 1
|
||||
0 <= ps <= 1
|
||||
End
|
||||
```
|
||||
|
||||
CPLEX format is nice to read, but non-trivial problems take a lot of variables and constraints to model, making it painful and error-prone to write out manually. There are domain-specific languages like [ZIMPL][13] for speccing MILPs and LPs in a high-level way. They’re pretty cool for many problems, but ultimately they’re not as expressive as a general-purpose language with a good library like JuMP — or as a code generator with D.
|
||||
|
||||
I’ll model the puzzle using two sets of variables: (v_{r,c}) and (i_{r,c,v}). (v_{r,c}) will hold the value (1-5) of the cell at row (r) and column (c). (i_{r,c,v}) will be an indicator binary that’s 1 if the cell at row (r) and column (c) has value (v), and 0 otherwise. These two sets of variables are redundant representations of the grid, but the first representation makes it easier to model the inequality constraints, while the second representation makes it easier to model the uniqueness constraints. I just need to add some extra constraints to force the two representations to be consistent. But first, let’s start with the basic constraint that each cell must have exactly one value. Mathematically, that means all the indicators for a given row and column must be 0, except for one that is 1. That can be enforced by this equation:
|
||||
|
||||
[i_{r,c,1} + i_{r,c,2} + i_{r,c,3} + i_{r,c,4} + i_{r,c,5} = 1]
|
||||
|
||||
The CPLEX constraints for all rows and columns can be generated with this Djinn code:
|
||||
|
||||
```
|
||||
\ Cell has one value
|
||||
[:
|
||||
foreach (r; iota(N))
|
||||
foreach (c; iota(N))
|
||||
:]
|
||||
[= "%-(%s + %)", vs.map!(v => ivar(r, c, v)) ] = 1
|
||||
[::]
|
||||
```
|
||||
|
||||
`ivar()` is a helper function that gives us the string identifier for an (i) variable, and `vs` stores the numbers 1-5 for convenience. The constraints for uniqueness within rows and columns are exactly the same, but iterating over the other two dimensions of (i).
|
||||
|
||||
To make the (i) vars consistent with the (v) vars, we need constraints like this (remember, only one of the (i) vars is non-zero):
|
||||
|
||||
[i_{r,c,1} + 2i_{r,c,2} + 3i_{r,c,3} + 4i_{r,c,4} + 5i_{r,c,5} = v_{r,c}]
|
||||
|
||||
CPLEX requires all variables to be on the left, so the Djinn code looks like this:
|
||||
|
||||
```
|
||||
\ Link i vars with v vars
|
||||
[:
|
||||
foreach (r; iota(N))
|
||||
foreach (c; iota(N))
|
||||
:]
|
||||
[= "%-(%s + %)", vs.map!(v => text(v, ' ', ivar(r, c, v))) ] - [= vvar(r,c) ] = 0
|
||||
[::]
|
||||
```
|
||||
|
||||
The constraints for the neighouring cell inequalities and for the bottom left corner being 4 are all trivial to write. All that’s left is to declare the indicator variables to be binary, and set the bounds for the (v) vars. All up, there are 150 variables and 111 constraints, plus bounds for the variables. [You can see the full code in the repo.][14]
|
||||
|
||||
The [GNU Linear Programming Kit][15] has a command line tool that can solve this CPLEX MILP. Unfortunately, its output is a big dump of everything, so I used awk to pull out what’s needed:
|
||||
|
||||
```
|
||||
$ time glpsol --lp inequality.lp -o /dev/stdout | awk '/v[0-9][0-9]/ { print $2, $4 }' | sort
|
||||
v00 1
|
||||
v01 3
|
||||
v02 2
|
||||
v03 5
|
||||
v04 4
|
||||
v10 2
|
||||
v11 5
|
||||
v12 4
|
||||
v13 1
|
||||
v14 3
|
||||
v20 3
|
||||
v21 1
|
||||
v22 5
|
||||
v23 4
|
||||
v24 2
|
||||
v30 5
|
||||
v31 4
|
||||
v32 3
|
||||
v33 2
|
||||
v34 1
|
||||
v40 4
|
||||
v41 2
|
||||
v42 1
|
||||
v43 3
|
||||
v44 5
|
||||
|
||||
real 0m0.114s
|
||||
user 0m0.106s
|
||||
sys 0m0.005s
|
||||
```
|
||||
|
||||
Here’s the solution written out in the original grid:
|
||||
|
||||
![][16]
|
||||
|
||||
These examples are just for playing around, but I’m sure you get the idea. The `README.md` for the Djinn repo is itself generated using a Djinn template, by the way.
|
||||
|
||||
As I said, Djinn can also be used as a compile-time templating language embedded inside D code. I primarily wanted a code generator, but that’s a bonus thanks to D’s metaprogramming features.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://theartofmachinery.com/2021/01/01/djinn.html
|
||||
|
||||
作者:[Simon Arneaud][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://theartofmachinery.com
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://jinja2docs.readthedocs.io/en/stable/
|
||||
[2]: https://dlang.org/articles/mixin.html
|
||||
[3]: https://theartofmachinery.com/2017/12/31/compile_time_brainfuck.html
|
||||
[4]: https://gitlab.com/sarneaud/djinn
|
||||
[5]: https://gitlab.com/sarneaud/djinn/-/tree/v0.1.0/examples
|
||||
[6]: https://dlang.org/phobos/std_format.html#format-string
|
||||
[7]: http://netpbm.sourceforge.net/doc/#formats
|
||||
[8]: https://en.wikipedia.org/wiki/Mandelbrot_set
|
||||
[9]: https://theartofmachinery.com/images/djinn/mandelbrot.png
|
||||
[10]: https://theartofmachinery.com/images/djinn/inequality.svg
|
||||
[11]: https://theartofmachinery.com/2020/05/21/glico_weighted_rock_paper_scissors.html
|
||||
[12]: http://lpsolve.sourceforge.net/5.0/CPLEX-format.htm
|
||||
[13]: https://zimpl.zib.de/
|
||||
[14]: https://gitlab.com/sarneaud/djinn/-/tree/v0.1.0/examples/inequality.lp.dj
|
||||
[15]: https://www.gnu.org/software/glpk/
|
||||
[16]: https://theartofmachinery.com/images/djinn/inequality_solution.svg
|
@ -0,0 +1,275 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Solve a charity's problem with the Julia programming language)
|
||||
[#]: via: (https://opensource.com/article/21/1/solve-problem-julia)
|
||||
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
|
||||
|
||||
Solve a charity's problem with the Julia programming language
|
||||
======
|
||||
See how Julia differs from Java, Python, and Groovy to solve a food
|
||||
bank's real-world problem.
|
||||
![Puzzle pieces coming together to form a computer screen][1]
|
||||
|
||||
I have been writing a series of articles about solving a nice, small, and somewhat unusual problem in different programming languages ([Groovy][2], [Python][3], and [Java][4] so far).
|
||||
|
||||
Briefly, the problem is how to unpack bulk supplies into their units (for example, dividing a 10 pack of one-pound bags of your favorite coffee) and repackage them into hampers of similar value to distribute to struggling neighbors in the community.
|
||||
|
||||
The three solutions I have already explored constructed lists of the number of bulk packages acquired. I accomplished this by using maps in Groovy, dictionaries in Python, and tuples implemented as utility classes in Java. I used list-processing functionality in each language to unpack the bulk packages into a list of their constituents, which I modeled using maps, dictionaries, and tuples, respectively. I needed to take an iterative approach to move units from a list into hampers; this iterative approach was quite similar from one language to the other, with the minor difference that I could use `for {...}` loops in Groovy and Java and needed `while…:` in Python. But all in all, they used very similar solutions with hints of functional programming and behavior encapsulated in objects here and there.
|
||||
|
||||
### Meet Julia
|
||||
|
||||
In this article, I'll explore the same problem in [Julia][5], which (among other things) means leaving aside the object-oriented and functional programming paradigms I'm used to. I struggle with languages that aren't object-oriented. I've been programming in Java since around 1997 and in Groovy since about 2008, so I'm used to having data and behavior bundled together. Aside from just generally liking the look of code where method calls hang off objects or sometimes classes, I really like the way class documentation packages up what data is handled by the class and how it is handled. This seems so "natural" to me now that learning a language whose documentation describes types and functions separately seems difficult to me.
|
||||
|
||||
And speaking of learning a language, I'm a real neophyte when it comes to Julia. I like its orientation toward the kinds of problems I typically need to solve (e.g., data, computations, results). I like the desire for speed. I like the decision to make Julia a language in which complicated problems can be solved using a modular and iterative approach. I like the idea of making great existing analytical libraries available. But, my jury is still out on the non-object-oriented design. I also seem to use functional approaches in my Groovy and Java programming more often, so I think I might miss this in Julia.
|
||||
|
||||
But enough speculation, let's code something!
|
||||
|
||||
### The Julia solution
|
||||
|
||||
My first decision is how to implement the data model. Julia supports _composite types_, seemingly similar to `struct` in C, and Julia even uses the keyword `struct`. Of note is that a `struct` is immutable (unless declared a `mutable struct`), which is fine for this problem since the data doesn't need to be mutated.
|
||||
|
||||
By following the approach I took in the Java solution, the `Unit struct` can be defined as:
|
||||
|
||||
|
||||
```
|
||||
struct Unit
|
||||
item::String
|
||||
brand::String
|
||||
price::Int
|
||||
end
|
||||
```
|
||||
|
||||
Similarly, `Pack` is defined as the bulk package of `Unit` instances:
|
||||
|
||||
|
||||
```
|
||||
struct Pack
|
||||
unit::Unit
|
||||
count::Int
|
||||
Pack(item, brand, unitCount,p ackPrice) =
|
||||
new(Unit(item, brand, [div][6](packPrice,unitCount)), unitCount)
|
||||
end
|
||||
```
|
||||
|
||||
There is an interesting thing here: a Julia "inner constructor." In the Java solution, I decided that the units inside bulk packages are (in my mind, anyway) a part of the bulk package and not something seen externally, so I decided I wanted to pass in the item, brand, number of units, and package price and have the `Pack` object create its unit internally. I'll do the same thing here.
|
||||
|
||||
Because Julia isn't object-oriented, I can't add methods to `Pack` to give unit price vs. pack price or to unpack it into a list of `Unit` instances. I can declare "getter" functions that accomplish the same tasks. (I probably don't need these, but I'll do it anyway to see how Julia methods work):
|
||||
|
||||
|
||||
```
|
||||
item(pack::Pack) = pack.unit.item
|
||||
brand(pack::Pack) = pack.unit.brand
|
||||
unitPrice(pack::Pack) = pack.unit.price
|
||||
unitCount(pack::Pack) = pack.count
|
||||
packPrice(pack::Pack) = pack.unit.price * pack.count
|
||||
unpack(pack::Pack) = Iterators.collect(Iterators.repeated(pack.unit,pack.count))
|
||||
```
|
||||
|
||||
The `unpack()` method is quite similar to the method of the same name I declared in the Java class `Pack`. The function `Iterators.repeated(thing,N)` creates an iterator that will deliver `N` copies of `thing`. The `Iterators.collect` (`iterator`) function processes the `iterator` to yield an array made up of the elements it delivers.
|
||||
|
||||
Finally, the `Bought struct`:
|
||||
|
||||
|
||||
```
|
||||
struct Bought
|
||||
pack::Pack
|
||||
count::Int
|
||||
end
|
||||
unpack(bought::Bought) =
|
||||
Iterators.collect(Iterators.flatten(Iterators.repeated(unpack(bought.pack),
|
||||
bought.count)))
|
||||
```
|
||||
|
||||
Once again, I'm creating an array of an array of unpacked `Pack` instances (i.e., units) and using `Iterators.flatten()` to turn that into a simple array.
|
||||
|
||||
Now I can construct the list of what I bought:
|
||||
|
||||
|
||||
```
|
||||
packs = [
|
||||
Bought(Pack("Rice","Best Family",10,5650),1),
|
||||
Bought(Pack("Spaghetti","Best Family",1,327),10),
|
||||
Bought(Pack("Sardines","Fresh Caught",3,2727),3),
|
||||
Bought(Pack("Chickpeas","Southern Style",2,2600),5),
|
||||
Bought(Pack("Lentils","Southern Style",2,2378),5),
|
||||
Bought(Pack("Vegetable oil","Crafco",12,10020),1),
|
||||
Bought(Pack("UHT milk","Atlantic",6,4560),2),
|
||||
Bought(Pack("Flour","Neighbor Mills",10,5200),1),
|
||||
Bought(Pack("Tomato sauce","Best Family",1,190),10),
|
||||
Bought(Pack("Sugar","Good Price",1,565),10),
|
||||
Bought(Pack("Tea","Superior",5,2720),2),
|
||||
Bought(Pack("Coffee","Colombia Select",2,4180),5),
|
||||
Bought(Pack("Tofu","Gourmet Choice",1,1580),10),
|
||||
Bought(Pack("Bleach","Blanchite",5,3550),2),
|
||||
Bought(Pack("Soap","Sunny Day",6,1794),2)]
|
||||
```
|
||||
|
||||
I'm starting to see a pattern here… this looks surprisingly like the Java solution to this problem. As then, this shows that I bought one pack of Best Family Rice containing 10 units that cost 5650 (using those crazy monetary units, like in the other examples). I bought one bulk pack of 10 bags of rice, and I bought 10 bulk packs of one bag each of spaghetti.
|
||||
|
||||
With the list packs of what I bought, I can now unpack into the units before working on redistributing them:
|
||||
|
||||
|
||||
```
|
||||
`units = Iterators.collect(Iterators.flatten(unpack.(packs)))`
|
||||
```
|
||||
|
||||
What's going on here? Well, a construct like `unpack.(packs)`—that is, the dot between the function name and the argument list—applies the function `unpack()` to each element in the list `packs`. This will generate a list of lists corresponding to the unpacked groups of `Packs` I bought. To turn that into a flat list of units, I apply `Iterators.flatten()`. Because `Iterators.flatten()` is lazy, to make the flatten thing happen, I wrap it in `Iterators.collect()`. This kind of composition of functions adheres to the spirit of functional programming, even though you don't see the functions chained together, as programmers who write functionally in JavaScript, Java, or what-have-you are familiar with.
|
||||
|
||||
One observation is that the list of units created here is actually an array whose starting index is 1, not 0.
|
||||
|
||||
With units being the list of units purchased and unpacked, I can now take on repacking them into hampers.
|
||||
|
||||
Here's the code, which is not exceptionally different than the versions in Groovy, Python, and Java:
|
||||
|
||||
|
||||
```
|
||||
1 valueIdeal = 5000
|
||||
2 valueMax = round(valueIdeal * 1.1)
|
||||
3 hamperNumber = 0
|
||||
|
||||
4 while length(units) > 0
|
||||
5 global hamperNumber += 1
|
||||
6 hamper = Unit[]
|
||||
7 value = 0
|
||||
8 canAdd = true
|
||||
9 while canAdd
|
||||
10 u = [rand][7](0:(length(units)-1))
|
||||
11 canAdd = false
|
||||
12 for o = 0:(length(units)-1)
|
||||
13 uo = (u + o) % length(units) + 1
|
||||
14 unit = units[uo]
|
||||
15 if length(units) < 3 || findfirst(u -> u == unit,hamper) === nothing && (value + unit.price) < valueMax
|
||||
16 push!(hamper,unit)
|
||||
17 value += unit.price
|
||||
18 deleteat!(units,uo)
|
||||
19 canAdd = length(units) > 0
|
||||
20 break
|
||||
21 end
|
||||
22 end
|
||||
23 end
|
||||
24 Printf.@[printf][8]("\nHamper %d value %d:\n",hamperNumber,value)
|
||||
25 for unit in hamper
|
||||
26 Printf.@[printf][8]("%-25s%-25s%7d\n",unit.item,unit.brand,unit.price)
|
||||
27 end
|
||||
28 Printf.@[printf][8]("Remaining units %d\n",length(units))
|
||||
29 end
|
||||
```
|
||||
|
||||
Some clarification, by line numbers:
|
||||
|
||||
* Lines 1–3: Set up the ideal and maximum values to be loaded into any given hamper and initialize Groovy's random number generator and the hamper number
|
||||
* Lines 4–29: This `while` loop redistributes units into hampers, as long as there are more available
|
||||
* Lines 5–7: Increment the (global) hamper number, get a new empty hamper (an array of `Unit` instances), and set its value to 0
|
||||
* Line 8 and 9–23: As long as I can add units to the hamper…
|
||||
* Line 10: Gets a random number between zero and the number of remaining units minus 1
|
||||
* Line 11: Assumes I can't find more units to add
|
||||
* Lines 12–22: This `for` loop, starting at the randomly chosen index, will try to find a unit that can be added to the hamper
|
||||
* Lines 13–14: Figure out which unit to look at (remember arrays start at index 1) and get it
|
||||
* Lines 15–21: I can add this unit to the hamper if there are only a few left or if the value of the hamper isn't too high once the unit is added and if that unit isn't already in the hamper
|
||||
* Lines 16–18: Add the unit to the hamper, increment the hamper value by the unit price, and remove the unit from the available units list
|
||||
* Lines 19–20: As long as there are units left, I can add more, so break out of this loop to keep looking
|
||||
* Line 22: On exit from this `for` loop, if I have inspected every remaining unit and could not find one to add to the hamper, the hamper is complete; otherwise, I found one and can continue looking for more
|
||||
* Line 23: On exit from this `while` loop, the hamper is as full as I can make it, so…
|
||||
* Lines 24–28: Print out the contents of the hamper and the remaining units info
|
||||
* Line 29: When I exit this loop, there are no more units left
|
||||
|
||||
|
||||
|
||||
The output of running this code looks quite similar to the output from the other programs:
|
||||
|
||||
|
||||
```
|
||||
Hamper 1 value 5020:
|
||||
Tea Superior 544
|
||||
Sugar Good Price 565
|
||||
Soap Sunny Day 299
|
||||
Chickpeas Southern Style 1300
|
||||
Flour Neighbor Mills 520
|
||||
Rice Best Family 565
|
||||
Spaghetti Best Family 327
|
||||
Bleach Blanchite 710
|
||||
Tomato sauce Best Family 190
|
||||
Remaining units 146
|
||||
|
||||
Hamper 2 value 5314:
|
||||
Flour Neighbor Mills 520
|
||||
Sugar Good Price 565
|
||||
Vegetable oil Crafco 835
|
||||
Coffee Colombia Select 2090
|
||||
UHT milk Atlantic 760
|
||||
Tea Superior 544
|
||||
Remaining units 140
|
||||
|
||||
Hamper 3 value 5298:
|
||||
Tomato sauce Best Family 190
|
||||
Tofu Gourmet Choice 1580
|
||||
Sugar Good Price 565
|
||||
Bleach Blanchite 710
|
||||
Tea Superior 544
|
||||
Lentils Southern Style 1189
|
||||
Flour Neighbor Mills 520
|
||||
Remaining units 133
|
||||
|
||||
…
|
||||
|
||||
Hamper 23 value 4624:
|
||||
Chickpeas Southern Style 1300
|
||||
Vegetable oil Crafco 835
|
||||
Tofu Gourmet Choice 1580
|
||||
Sardines Fresh Caught 909
|
||||
Remaining units 4
|
||||
|
||||
Hamper 24 value 5015:
|
||||
Tofu Gourmet Choice 1580
|
||||
Chickpeas Southern Style 1300
|
||||
Chickpeas Southern Style 1300
|
||||
Vegetable oil Crafco 835
|
||||
Remaining units 0
|
||||
```
|
||||
|
||||
The last hamper is abbreviated in contents and value.
|
||||
|
||||
### Closing thoughts
|
||||
|
||||
Once again, the random-number-driven list manipulation seems to make the "working code" portion of the program pretty similar to the Groovy, Python, and Java versions. To my delight, I found good functional programming support in Julia, at least with respect to the straightforward list processing required for this small problem.
|
||||
|
||||
Given that the main effort revolves around `for` and `while` loops, in Julia, I don't see any construct similar to:
|
||||
|
||||
|
||||
```
|
||||
`for (boolean canAdd = true; canAdd; ) { … }`
|
||||
```
|
||||
|
||||
This means I have to declare the `canAdd` variable outside the `while` loop. Which is too bad—but not a terrible thing.
|
||||
|
||||
I do miss not being able to attach behavior directly to my data, but that's just my appreciation for object-oriented programming showing through. It's certainly not a huge impediment in this program; however, correspondence with a kind author about my Java version made me realize that I should have built a class to fully encapsulate the distribution function into something like a list of hampers, which the main program would just print out. This approach would not be feasible in a non-object-oriented language like Julia.
|
||||
|
||||
Good things: low ceremony, check; decent list-handling, check; compact and readable code, check. All in all, a pleasant experience, supporting the idea that Julia can be a decent choice to solve "ordinary problems" and as a scripting language.
|
||||
|
||||
Next time, I'll do this exercise in [Go][9].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/1/solve-problem-julia
|
||||
|
||||
作者:[Chris Hermansen][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/clhermansen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
|
||||
[2]: https://opensource.com/article/20/9/groovy
|
||||
[3]: https://opensource.com/article/20/9/solve-problem-python
|
||||
[4]: https://opensource.com/article/20/9/problem-solving-java
|
||||
[5]: https://julialang.org/
|
||||
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/div.html
|
||||
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/rand.html
|
||||
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
|
||||
[9]: https://golang.org/
|
@ -0,0 +1,101 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Explore the night sky with this open source astronomy app)
|
||||
[#]: via: (https://opensource.com/article/21/1/kstars)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
Explore the night sky with this open source astronomy app
|
||||
======
|
||||
Stargaze from your Linux desktop or Android device with KStars.
|
||||
![Open source stars.][1]
|
||||
|
||||
I have always been fascinated with the night sky. When I was younger, the only reference materials available were books, and they seemed to depict a sky that looked different from the one I saw from my home.
|
||||
|
||||
More than five years ago, I wrote about my experiences with two open source planetarium apps, [Celestia and Stellarium][2]. Recently, I read about another: [KStars][3]. It's an amazing open source application that helps engage children (and adults) in science and astronomy. Its website says:
|
||||
|
||||
> "KStars is free, open source, cross-platform astronomy software. It provides an accurate graphical simulation of the night sky, from any location on Earth, at any date and time. The display includes up to 100 million stars, 13,000 deep-sky objects, all 8 planets, the Sun and Moon, and thousands of comets, asteroids, supernovae, and satellites."
|
||||
|
||||
KStars is part of the [KDE Education Project][4]. The latest version, available for Linux, Windows, and macOS, integrates [StellarSolver][5], a cross-platform SExtractor, a program that builds a catalog of objects from an astronomical image.
|
||||
|
||||
### Installing KStars
|
||||
|
||||
KStars is freely licensed under the GPLv2.0. The source code is available on the official [KDE GitLab instance][6] and as a read-only mirror on GitHub. The KDE Education Project has excellent [installation documentation][7].
|
||||
|
||||
I'm using [Pop!_OS][8] and found KStars in the Pop!_Shop.
|
||||
|
||||
You can install KStars on Linux from your distribution's software repository. KStars Lite is available for Android from the [Google Play store][9]. The KDE Project maintains an excellent [KStars Handbook][10] to assist users.
|
||||
|
||||
### Using KStars
|
||||
|
||||
After installation, launch the program from your Applications menu. A startup wizard guides you through the initial setup.
|
||||
|
||||
![KStars Startup Wizard][11]
|
||||
|
||||
(Don Watkins, [CC BY-SA 4.0][12])
|
||||
|
||||
The directions are easy to follow. The wizard prompts you to set your home location; unfortunately, my small village was not listed, but a larger nearby community was.
|
||||
|
||||
![KStars location setup][13]
|
||||
|
||||
(Don Watkins, [CC BY-SA 4.0][12])
|
||||
|
||||
You also have the opportunity to download additional data and extra features for the program.
|
||||
|
||||
![KStars add-ons][14]
|
||||
|
||||
(Don Watkins, [CC BY-SA 4.0][12])
|
||||
|
||||
There are many options available. I chose "Common images displayed in the detail window."
|
||||
|
||||
Once you're finished with the setup, KStars presents a map of the night sky as it appears from your location.
|
||||
|
||||
![KStars night sky display][15]
|
||||
|
||||
(Don Watkins, [CC BY-SA 4.0][12])
|
||||
|
||||
It displays the current local time in the upper-left corner (5:58pm on November 30, 2020, in this image).
|
||||
|
||||
Using the left mouse button, you can move the display left, right, up, and down. You can zoom in and out using the mouse's scroll wheel. Placing the mouse cursor over an object and right-clicking describes the object you're looking at.
|
||||
|
||||
![KStars describes objects][16]
|
||||
|
||||
(Don Watkins, [CC BY-SA 4.0][12])
|
||||
|
||||
### Get involved
|
||||
|
||||
KStars is actively soliciting help with bug reports, astronomy knowledge, code, translations, and more. The lead developer and maintainer is [Jasem Mutlaq][17]. If you'd like to contribute, please visit the [project's website][18] or join the mailing list to learn more.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/21/1/kstars
|
||||
|
||||
作者:[Don Watkins][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/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_opensourcestars.png?itok=hnrMETFh (Open source stars.)
|
||||
[2]: https://opensource.com/education/15/7/open-source-apps-explore-night-sky
|
||||
[3]: https://edu.kde.org/kstars/
|
||||
[4]: https://edu.kde.org/
|
||||
[5]: https://github.com/rlancaste/stellarsolver
|
||||
[6]: https://invent.kde.org/education/kstars
|
||||
[7]: https://edu.kde.org/kstars/install.php
|
||||
[8]: https://pop.system76.com/
|
||||
[9]: https://play.google.com/store/apps/details?id=org.kde.kstars.lite&hl=en
|
||||
[10]: https://docs.kde.org/trunk5/en/extragear-edu/kstars/index.html
|
||||
[11]: https://opensource.com/sites/default/files/uploads/kstars_startupwizard.png (KStars Startup Wizard)
|
||||
[12]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||
[13]: https://opensource.com/sites/default/files/uploads/kstars_setlocation.png (KStars location setup)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/kstars_addons.png (KStars add-ons)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/kstars_sky.png (KStars night sky display)
|
||||
[16]: https://opensource.com/sites/default/files/uploads/kstars_objectdescription.png (KStars describes objects)
|
||||
[17]: https://github.com/knro
|
||||
[18]: https://edu.kde.org/kstars
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user