Merge remote-tracking branch 'upstream/master' into Transit

UpdatedTransitBranch
This commit is contained in:
stevenzdg988 2021-03-18 11:57:28 +08:00
commit bfac31904d
25 changed files with 2268 additions and 991 deletions

View File

@ -0,0 +1,148 @@
[#]: collector: (lujun9972)
[#]: translator: (stevenzdg988)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13210-1.html)
[#]: subject: (Get started with Bash programming)
[#]: via: (https://opensource.com/article/20/4/bash-programming-guide)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
如何入门 Bash 编程
======
> 了解如何在 Bash 中编写定制程序以自动执行重复性操作任务。
![](https://img.linux.net.cn/data/attachment/album/202103/17/110745ctcuzcnt0dv0toi7.jpg)
Unix 最初的希望之一是,让计算机的日常用户能够微调其计算机,以适应其独特的工作风格。几十年来,人们对计算机定制的期望已经降低,许多用户认为他们的应用程序和网站的集合就是他们的 “定制环境”。原因之一是许多操作系统的组件未不开源,普通用户无法使用其源代码。
但是对于 Linux 用户而言,定制程序是可以实现的,因为整个系统都围绕着可通过终端使用的命令啦进行的。终端不仅是用于快速命令或深入排除故障的界面;也是一个脚本环境,可以通过为你处理日常任务来减少你的工作量。
### 如何学习编程
如果你以前从未进行过任何编程,可能面临考虑两个不同的挑战:一个是了解怎样编写代码,另一个是了解要编写什么代码。你可以学习 _语法_,但是如果你不知道 _语言_ 中有哪些可用的关键字,你将无法继续。在实践中,要同时开始学习这两个概念,是因为如果没有关键字的堆砌就无法学习语法,因此,最初你要使用基本命令和基本编程结构来编写简单的任务。一旦熟悉了基础知识,就可以探索更多编程语言的内容,从而使你的程序能够做越来越重要的事情。
在 [Bash][2] 中,你使用的大多数 _关键字_ 是 Linux 命令。 _语法_ 就是 Bash。如果你已经频繁地使用过了 Bash则向 Bash 编程的过渡相对容易。但是,如果你不曾使用过 Bash你会很高兴地了解到它是一种为清晰和简单而构建的简单语言。
### 交互设计
有时,学习编程时最难搞清楚的事情就是计算机可以为你做些什么。显然,如果一台计算机可以自己完成你要做的所有操作,那么你就不必再碰计算机了。但是现实是,人类很重要。找到你的计算机可以帮助你的事情的关键是注意到你一周内需要重复执行的任务。计算机特别擅长于重复的任务。
但是,为了能告知计算机为你做某事,你必须知道怎么做。这就是 Bash 擅长的领域:交互式编程。在终端中执行一个动作时,你也在学习如何编写脚本。
例如,我曾经负责将大量 PDF 书籍转换为低墨和友好打印的版本。一种方法是在 PDF 编辑器中打开 PDF从数百张图像页面背景和纹理都算作图像中选择每张图像删除它们然后将其保存到新的 PDF中。仅仅是一本书这样就需要半天时间。
我的第一个想法是学习如何编写 PDF 编辑器脚本,但是经过数天的研究,我找不到可以编写编辑 PDF 应用程序的脚本(除了非常丑陋的鼠标自动化技巧)。因此,我将注意力转向了从终端内找出完成任务的方法。这让我有了几个新发现,包括 GhostScript它是 PostScript 的开源版本PDF 基于的打印机语言)。通过使用 GhostScript 处理了几天的任务,我确认这是解决我的问题的方法。
编写基本的脚本来运行命令,只不过是复制我用来从 PDF 中删除图像的命令和选项,并将其粘贴到文本文件中而已。将这个文件作为脚本运行,大概也会产生同样的结果。
### 向 Bash 脚本传参数
在终端中运行命令与在 Shell 脚本中运行命令之间的区别在于前者是交互式的。在终端中,你可以随时进行调整。例如,如果我刚刚处理 `example_1.pdf` 并准备处理下一个文档,以适应我的命令,则只需要更改文件名即可。
Shell 脚本不是交互式的。实际上Shell _脚本_ 存在的唯一原因是让你不必亲自参与。这就是为什么命令(以及运行它们的 Shell 脚本)会接受参数的原因。
在 Shell 脚本中,有一些预定义的可以反映脚本启动方式的变量。初始变量是 `$0`,它代表了启动脚本的命令。下一个变量是 `$1` ,它表示传递给 Shell 脚本的第一个 “参数”。例如,在命令 `echo hello` 中,命令 `echo``$0,`,关键字 `hello``$1`,而 `world``$2`
在 Shell 中交互如下所示:
```
$ echo hello world
hello world
```
在非交互式 Shell 脚本中,你 _可以_ 以非常直观的方式执行相同的操作。将此文本输入文本文件并将其另存为 `hello.sh`
```
echo hello world
```
执行这个脚本:
```
$ bash hello.sh
hello world
```
同样可以,但是并没有利用脚本可以接受输入这一优势。将 `hello.sh` 更改为:
```
echo $1
```
用引号将两个参数组合在一起来运行脚本:
```
$ bash hello.sh "hello bash"
hello bash
```
对于我的 PDF 瘦身项目,我真的需要这种非交互性,因为每个 PDF 都花了几分钟来压缩。但是通过创建一个接受我的输入的脚本,我可以一次将几个 PDF 文件全部提交给脚本。该脚本按顺序处理了每个文件,这可能需要半小时或稍长一点时间,但是我可以用半小时来完成其他任务。
### 流程控制
创建 Bash 脚本是完全可以接受的,从本质上讲,这些脚本是你开始实现需要重复执行任务的准确过程的副本。但是,可以通过控制信息流的方式来使脚本更强大。管理脚本对数据响应的常用方法是:
* `if`/`then` 选择结构语句
* `for` 循环结构语句
* `while` 循环结构语句
* `case` 语句
计算机不是智能的,但是它们擅长比较和分析数据。如果你在脚本中构建一些数据分析,则脚本会变得更加智能。例如,基本的 `hello.sh` 脚本运行后不管有没有内容都会显示:
```
$ bash hello.sh foo
foo
$ bash hello.sh
$
```
如果在没有接收输入的情况下提供帮助消息,将会更加容易使用。如下是一个 `if`/`then` 语句,如果你以一种基本的方式使用 Bash则你可能不知道 Bash 中存在这样的语句。但是编程的一部分是学习语言,通过一些研究,你将了解 `if/then` 语句:
```
if [ "$1" = "" ]; then
        echo "syntax: $0 WORD"
        echo "If you provide more than one word, enclose them in quotes."
else
        echo "$1"
fi
```
运行新版本的 `hello.sh` 输出如下:
```
$ bash hello.sh
syntax: hello.sh WORD
If you provide more than one word, enclose them in quotes.
$ bash hello.sh "hello world"
hello world
```
### 利用脚本工作
无论你是从 PDF 文件中查找要删除的图像,还是要管理混乱的下载文件夹,抑或要创建和提供 Kubernetes 镜像,学习编写 Bash 脚本都需要先使用 Bash然后学习如何将这些脚本从仅仅是一个命令列表变成响应输入的东西。通常这是一个发现的过程你一定会找到新的 Linux 命令来执行你从未想象过可以通过文本命令执行的任务,你会发现 Bash 的新功能,使你的脚本可以适应所有你希望它们运行的不同方式。
学习这些技巧的一种方法是阅读其他人的脚本。了解人们如何在其系统上自动化死板的命令。看看你熟悉的,并寻找那些陌生事物的更多信息。
另一种方法是下载我们的 [Bash 编程入门][3] 电子书。它向你介绍了特定于 Bash 的编程概念,并且通过学习的构造,你可以开始构建自己的命令。当然,它是免费的,并根据 [创作共用许可证][4] 进行下载和分发授权,所以今天就来获取它吧。
- [下载我们介绍用 Bash 编程的电子书!][3]
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/bash-programming-guide
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[stevenzdg988](https://github.com/stevenzdg988)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
[2]: https://opensource.com/resources/what-bash
[3]: https://opensource.com/downloads/bash-programming-guide
[4]: https://opensource.com/article/20/1/what-creative-commons

View File

@ -0,0 +1,315 @@
[#]: collector: (lujun9972)
[#]: translator: (stevenzdg988)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13212-1.html)
[#]: subject: (Improve your time management with Jupyter)
[#]: via: (https://opensource.com/article/20/9/calendar-jupyter)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
使用 Jupyter 改善你的时间管理
======
> 在 Jupyter 里使用 Python 来分析日历,以了解你是如何使用时间的。
![](https://img.linux.net.cn/data/attachment/album/202103/18/095530cxx6663ptypyzvmx.jpg)
[Python][2] 在探索数据方面具有令人难以置信的可扩展性。利用 [Pandas][3] 或 [Dask][4],你可以将 [Jupyter][5] 扩展到大数据领域。但是小数据、个人资料、私人数据呢?
JupyterLab 和 Jupyter Notebook 为我提供了一个绝佳的环境可以让我审视我的笔记本电脑生活。
我的探索是基于以下事实:我使用的几乎每个服务都有一个 Web API。我使用了诸多此类服务待办事项列表、时间跟踪器、习惯跟踪器等。还有一个几乎每个人都会使用到_日历_。相同的思路也可以应用于其他服务但是日历具有一个很酷的功能几乎所有 Web 日历都支持的开放标准 —— CalDAV。
### 在 Jupyter 中使用 Python 解析日历
大多数日历提供了导出为 CalDAV 格式的方法。你可能需要某种身份验证才能访问这些私有数据。按照你的服务说明进行操作即可。如何获得凭据取决于你的服务,但是最终,你应该能够将这些凭据存储在文件中。我将我的凭据存储在根目录下的一个名为 `.caldav` 的文件中:
```
import os
with open(os.path.expanduser("~/.caldav")) as fpin:
    username, password = fpin.read().split()
```
切勿将用户名和密码直接放在 Jupyter Notebook 的笔记本中!它们可能会很容易因 `git push` 的错误而导致泄漏。
下一步是使用方便的 PyPI [caldav][6] 库。我找到了我的电子邮件服务的 CalDAV 服务器(你可能有所不同):
```
import caldav
client = caldav.DAVClient(url="https://caldav.fastmail.com/dav/", username=username, password=password)
```
CalDAV 有一个称为 `principal`(主键)的概念。它是什么并不重要,只要知道它是你用来访问日历的东西就行了:
```
principal = client.principal()
calendars = principal.calendars()
```
从字面上讲,日历就是关于时间的。访问事件之前,你需要确定一个时间范围。默认一星期就好:
```
from dateutil import tz
import datetime
now = datetime.datetime.now(tz.tzutc())
since = now - datetime.timedelta(days=7)
```
大多数人使用的日历不止一个,并且希望所有事件都在一起出现。`itertools.chain.from_iterable` 方法使这一过程变得简单:
```
import itertools
raw_events = list(
    itertools.chain.from_iterable(
        calendar.date_search(start=since, end=now, expand=True)
        for calendar in calendars
    )
)
```
将所有事件读入内存很重要,以 API 原始的本地格式进行操作是重要的实践。这意味着在调整解析、分析和显示代码时,无需返回到 API 服务刷新数据。
但 “原始” 真的是原始,事件是以特定格式的字符串出现的:
```
print(raw_events[12].data)
```
```
    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//CyrusIMAP.org/Cyrus
     3.3.0-232-g4bdb081-fm-20200825.002-g4bdb081a//EN
    BEGIN:VEVENT
    DTEND:20200825T230000Z
    DTSTAMP:20200825T181915Z
    DTSTART:20200825T220000Z
    SUMMARY:Busy
    UID:
     1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000
     000000010000000CD71CC3393651B419E9458134FE840F5
    END:VEVENT
    END:VCALENDAR
```
幸运的是PyPI 可以再次使用另一个辅助库 [vobject][7] 解围:
```
import io
import vobject
def parse_event(raw_event):
data = raw_event.data
parsed = vobject.readOne(io.StringIO(data))
contents = parsed.vevent.contents
return contents
```
```
parse_event(raw_events[12])
```
```
{'dtend': [<DTEND{}2020-08-25 23:00:00+00:00>],
'dtstamp': [<DTSTAMP{}2020-08-25 18:19:15+00:00>],
'dtstart': [<DTSTART{}2020-08-25 22:00:00+00:00>],
'summary': [<SUMMARY{}Busy>],
'uid': [<UID{}1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000000000010000000CD71CC3393651B419E9458134FE840F5>]}
```
好吧,至少好一点了。
仍有一些工作要做,将其转换为合理的 Python 对象。第一步是 _拥有_ 一个合理的 Python 对象。[attrs][8] 库提供了一个不错的开始:
```
import attr
from __future__ import annotations
@attr.s(auto_attribs=True, frozen=True)
class Event:
    start: datetime.datetime
    end: datetime.datetime
    timezone: Any
    summary: str
```
是时候编写转换代码了!
第一个抽象从解析后的字典中获取值,不需要所有的装饰:
```
def get_piece(contents, name):
return contents[name][0].value
get_piece(_, "dtstart")
datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc())
```
日历事件总有一个“开始”、有一个“结束”、有一个 “持续时间”。一些谨慎的解析逻辑可以将两者协调为同一个 Python 对象:
```
def from_calendar_event_and_timezone(event, timezone):
    contents = parse_event(event)
    start = get_piece(contents, "dtstart")
    summary = get_piece(contents, "summary")
    try:
        end = get_piece(contents, "dtend")
    except KeyError:
        end = start + get_piece(contents, "duration")
    return Event(start=start, end=end, summary=summary, timezone=timezone)
```
将事件放在 _本地_ 时区而不是 UTC 中很有用,因此使用本地时区:
```
my_timezone = tz.gettz()
from_calendar_event_and_timezone(raw_events[12], my_timezone)
Event(start=datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc()), end=datetime.datetime(2020, 8, 25, 23, 0, tzinfo=tzutc()), timezone=tzfile('/etc/localtime'), summary='Busy')
```
既然事件是真实的 Python 对象,那么它们实际上应该具有附加信息。幸运的是,可以将方法添加到类中。
但是要弄清楚哪个事件发生在哪一天不是很直接。你需要在 _本地_ 时区中选择一天:
```
def day(self):
offset = self.timezone.utcoffset(self.start)
fixed = self.start + offset
return fixed.date()
Event.day = property(day)
```
```
print(_.day)
2020-08-25
```
事件在内部始终是以“开始”/“结束”的方式表示的,但是持续时间是有用的属性。持续时间也可以添加到现有类中:
```
def duration(self):
return self.end - self.start
Event.duration = property(duration)
```
```
print(_.duration)
1:00:00
```
现在到了将所有事件转换为有用的 Python 对象了:
```
all_events = [from_calendar_event_and_timezone(raw_event, my_timezone)
              for raw_event in raw_events]
```
全天事件是一种特例,可能对分析生活没有多大用处。现在,你可以忽略它们:
```
# ignore all-day events
all_events = [event for event in all_events if not type(event.start) == datetime.date]
```
事件具有自然顺序 —— 知道哪个事件最先发生可能有助于分析:
```
all_events.sort(key=lambda ev: ev.start)
```
现在,事件已排序,可以将它们加载到每天:
```
import collections
events_by_day = collections.defaultdict(list)
for event in all_events:
    events_by_day[event.day].append(event)
```
有了这些,你就有了作为 Python 对象的带有日期、持续时间和序列的日历事件。
### 用 Python 报到你的生活
现在是时候编写报告代码了!带有适当的标题、列表、重要内容以粗体显示等等,有醒目的格式是很意义。
这就是一些 HTML 和 HTML 模板。我喜欢使用 [Chameleon][9]
```
template_content = """
<html><body>
<div tal:repeat="item items">
<h2 tal:content="item[0]">Day</h2>
<ul>
<li tal:repeat="event item[1]"><span tal:replace="event">Thing</span></li>
</ul>
</div>
</body></html>"""
```
Chameleon 的一个很酷的功能是使用它的 `html` 方法渲染对象。我将以两种方式使用它:
* 摘要将以粗体显示
* 对于大多数活动,我都会删除摘要(因为这是我的个人信息)
```
def __html__(self):
offset = my_timezone.utcoffset(self.start)
fixed = self.start + offset
start_str = str(fixed).split("+")[0]
summary = self.summary
if summary != "Busy":
summary = "&lt;REDACTED&gt;"
return f"<b>{summary[:30]}</b> -- {start_str} ({self.duration})"
Event.__html__ = __html__
```
为了简洁起见,将该报告切成每天的:
```
import chameleon
from IPython.display import HTML
template = chameleon.PageTemplate(template_content)
html = template(items=itertools.islice(events_by_day.items(), 3, 4))
HTML(html)
```
渲染后,它将看起来像这样:
**2020-08-25**
- **\<REDACTED>** -- 2020-08-25 08:30:00 (0:45:00)
- **\<REDACTED>** -- 2020-08-25 10:00:00 (1:00:00)
- **\<REDACTED>** -- 2020-08-25 11:30:00 (0:30:00)
- **\<REDACTED>** -- 2020-08-25 13:00:00 (0:25:00)
- Busy -- 2020-08-25 15:00:00 (1:00:00)
- **\<REDACTED>** -- 2020-08-25 15:00:00 (1:00:00)
- **\<REDACTED>** -- 2020-08-25 19:00:00 (1:00:00)
- **\<REDACTED>** -- 2020-08-25 19:00:12 (1:00:00)
### Python 和 Jupyter 的无穷选择
通过解析、分析和报告各种 Web 服务所拥有的数据,这只是你可以做的事情的表面。
为什么不对你最喜欢的服务试试呢?
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/9/calendar-jupyter
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[stevenzdg988](https://github.com/stevenzdg988)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/moshez
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calendar.jpg?itok=jEKbhvDT (Calendar close up snapshot)
[2]: https://opensource.com/resources/python
[3]: https://pandas.pydata.org/
[4]: https://dask.org/
[5]: https://jupyter.org/
[6]: https://pypi.org/project/caldav/
[7]: https://pypi.org/project/vobject/
[8]: https://opensource.com/article/19/5/python-attrs
[9]: https://chameleon.readthedocs.io/en/latest/

View File

@ -1,38 +1,38 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13209-1.html)
[#]: subject: (Turn your Raspberry Pi into a HiFi music system)
[#]: via: (https://opensource.com/article/21/1/raspberry-pi-hifi)
[#]: author: (Peter Czanik https://opensource.com/users/czanik)
把你的树莓派变成一个 HiFi 音乐系统
把你的树莓派变成一个 HiFi 音乐系统
======
> 为你的朋友、家人、同事或其他任何拥有廉价发烧设备的人播放音乐。
![HiFi 复古立体声][1]
![](https://img.linux.net.cn/data/attachment/album/202103/17/094819ad5vzy0kqwvlxeee.jpg)
在过去的 10 年里,我大部分时间都是远程工作,但当我走进办公室时,我坐在一个充满内向的同伴的房间里,他们很容易被环境噪音和谈话所干扰。我们发现,听音乐可以抑制办公室的噪音,让声音不那么扰人,用愉快的音乐提供一个愉快的工作环境。
起初,我们的一位同事带来了一些老式的有源电脑音箱,把它们连接到他的桌面上,然后问我们想听什么。它可以工作,但音质不是很好,而且只有当他在办公室的时候才可以使用。接下来,我们又买了一对 Altec Lansing 音箱。音质有所改善,但没有什么灵活性。
起初,我们的一位同事带来了一些老式的有源电脑音箱,把它们连接到他的桌面电脑上,然后问我们想听什么。它可以工作,但音质不是很好,而且只有当他在办公室的时候才可以使用。接下来,我们又买了一对 Altec Lansing 音箱。音质有所改善,但没有什么灵活性。
不久之后,我们得到了一台通用 ARM 单板计算机SBC这意味着任何人都可以通过 Web 界面控制播放列表和扬声器。但一块普通的 ARM 开发板意味着我们不能使用流行的音乐设备软件。由于非标准的内核,更新操作系统是一件很痛苦的事情,而且 Web 界面也经常出现故障。
不久之后,我们得到了一台通用 ARM 单板计算机SBC这意味着任何人都可以通过 Web 界面控制播放列表和音箱。但一块普通的 ARM 开发板意味着我们不能使用流行的音乐设备软件。由于非标准的内核,更新操作系统是一件很痛苦的事情,而且 Web 界面也经常出现故障。
当团队壮大并搬进更大的房间后,我们开始梦想着有更好的扬声器和更容易处理软件和硬件组合的方法。
当团队壮大并搬进更大的房间后,我们开始梦想着有更好音箱和更容易处理软件和硬件组合的方法。
为了用一种相对便宜、灵活、音质好的方式解决我们的问题,我们用树莓派、音箱和开源软件开发了一个办公室 HiFi。
### HiFi 硬件
用一个专门的 PC 来播放背景音乐就有点过分了。它昂贵、嘈杂(除非是静音的,但那就更贵了),而且不环保。即使是最便宜的 ARM 板也能胜任这个工作,但从软件的角度来看,它们往往存在问题。树莓派还是比较便宜的,虽然不符合标准,但在硬件和软件方面都有很好的支持。
用一个专门的 PC 来播放背景音乐就有点过分了。它昂贵、嘈杂(除非是静音的,但那就更贵了),而且不环保。即使是最便宜的 ARM 板也能胜任这个工作,但从软件的角度来看,它们往往存在问题。树莓派还是比较便宜的,虽然不是标准的计算机,但在硬件和软件方面都有很好的支持。
接下来的问题是:用什么音箱。质量好的、有源的扬声器很贵。无源音箱的成本较低,但需要一个放大器,这将为这套设备增加另一个盒子。它们还必须使用树莓派的音频输出;虽然可以工作,但并不是最好的,特别是当你已经在高质量的扬声器和放大器上投入资金的时候。
接下来的问题是:用什么音箱。质量好的、有源的音箱很贵。无源音箱的成本较低,但需要一个功放,这需要为这套设备增加另一个盒子。它们还必须使用树莓派的音频输出;虽然可以工作,但并不是最好的,特别是当你已经在高质量的音箱和功放上投入资金的时候。
幸运的是在数以千计的树莓派硬件扩展中有内置数字模拟转换器DAC的放大器。我们选择了 [HiFiBerry 的 Amp][2]。它在我们买来后不久就停产了(被采样率更好的 Amp+ 型号取代),但对于我们的目的来说,它已经足够好了。在开着空调的情况下,我想无论如何你也听不出能达到 48kHz 或 192kHz 的 DAC 有什么不同。
幸运的是在数以千计的树莓派硬件扩展中有内置数字模拟转换器DAC放。我们选择了 [HiFiBerry 的 Amp][2]。它在我们买来后不久就停产了(被采样率更好的 Amp+ 型号取代),但对于我们的目的来说,它已经足够好了。在开着空调的情况下,我想无论如何你也听不出 48kHz 或 192kHz 的 DAC 有什么不同。
音箱方面,我们选择了 [Audioengine P4][3],是在某店家清仓大甩卖的时候买的,价格超低。它很容易让我们的办公室房间充满了声音而不失真(并且还不止充满了我们的房间,有一些失真,而邻居的工程师往往不喜欢)。
音箱方面,我们选择了 [Audioengine P4][3],是在某店家清仓大甩卖的时候买的,价格超低。它很容易让我们的办公室房间充满了声音而不失真(并且还能传到我们的房间之外,有一些失真,隔壁的工程师往往不喜欢)。
### HiFi 软件
@ -40,23 +40,23 @@
幸运的是,使用树莓派作为基础意味着有许多现成的软件设备可用。
我们选择了 [Volumio][4],这是一个将树莓派变成音乐播放设备的开源项目。安装是一个简单的*一步步完成*的过程。安装和升级是完全无痛的,而不用辛辛苦苦地安装和维护一个操作系统,并定期调试破损的 Python 代码。配置 HiFiBerry 放大器不需要编辑任何配置文件,你只需要从列表中选择即可。当然,习惯新的用户界面需要一定的时间,但稳定性和维护的便捷性让这个改变是值得的。
我们选择了 [Volumio][4],这是一个将树莓派变成音乐播放设备的开源项目。安装是一个简单的*一步步完成*的过程。安装和升级是完全无痛的,而不用辛辛苦苦地安装和维护一个操作系统,并定期调试破损的 Python 代码。配置 HiFiBerry 放不需要编辑任何配置文件,你只需要从列表中选择即可。当然,习惯新的用户界面需要一定的时间,但稳定性和维护的便捷性让这个改变是值得的。
![Volumio interface][5]
### 播放音乐并体验
虽然大流行期间我们都在家里办公,但办公室的 HiFi 安装在我家的办公室里,这意味着我可以自由支配它的运行。一个不断变化的用户界面对于一个团队来说会很痛苦,但对于一个有研发背景的人来说,自己玩一个设备,变化是很有趣的。
虽然大流行期间我们都在家里办公,不过我把办公室的 HiFi 安装在我的家庭办公室里,这意味着我可以自由支配它的运行。一个不断变化的用户界面对于一个团队来说会很痛苦,但对于一个有研发背景的人来说,自己玩一个设备,变化是很有趣的。
我不是一个程序员,但我有很强的 Linux 和 Unix 系统管理背景。这意味着,虽然我觉得修复坏掉的 Python 代码很烦人,但 Volumio 对我来说却足够完美,足够无聊(这是一个很好的“问题”)。幸运的是,在树莓派上播放音乐还有很多其他的可能性。
作为一个终端狂人(我甚至从终端窗口启动 LibreOffice我主要使用 Music on Console[MOC][6]来播放我的网络存储NAS中的音乐。我有几百张 CD成了 [FLAC][7] 文件。而且我还从 [BandCamp][8] 或 [Society of Sound][9] 等渠道购买了许多数字专辑。
作为一个终端狂人(我甚至从终端窗口启动 LibreOffice我主要使用 Music on Console[MOC][6]来播放我的网络存储NAS中的音乐。我有几百张 CD转换成了 [FLAC][7] 文件。而且我还从 [BandCamp][8] 或 [Society of Sound][9] 等渠道购买了许多数字专辑。
另一个选择是 [音乐播放器守护进程MPD][10]。把它运行在树莓派上,我可以通过网络使用 Linux 和 Android 的众多客户端之一与我的音乐进行远程交互。
### 音乐不停歇
正如你所看到的,创建一个廉价的 HiFi 系统的可能性在软件和硬件方面几乎是无限的。我们的解决方案只是众多解决方案中的一个,我希望它能启发你建立适合你环境的东西。
正如你所看到的,创建一个廉价的 HiFi 系统在软件和硬件方面几乎是无限可能的。我们的解决方案只是众多解决方案中的一个,我希望它能启发你建立适合你环境的东西。
--------------------------------------------------------------------------------
@ -65,7 +65,7 @@ via: https://opensource.com/article/21/1/raspberry-pi-hifi
作者:[Peter Czanik][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -88,7 +88,7 @@ Program received signal SIGSEGV, Segmentation fault.
要充分利用 GDB你需要将调试符号编译到你的可执行文件中。你可以用 GCC 中的 `-g` 选项来生成这个符号:
```
$ g++ -o debuggy example.cpp
$ g++ -g -o debuggy example.cpp
$ ./debuggy
Hello world.
Segmentation fault
@ -250,7 +250,7 @@ $4 = 02
要查看其在内存中的地址:
```
(gdb) print /o beta
(gdb) print /o &beta
$5 = 0x2
```

View File

@ -4,12 +4,14 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: ( )
[#]: url: ( )
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-13213-1.html)
Cinnamon vs MATE vs Xfce你应该选择那一个 Linux Mint 口味?
======
![](https://img.linux.net.cn/data/attachment/album/202103/18/111916ljidnfwwsxec1fqf.jpg)
Linux Mint 无疑是 [最适合初学者的 Linux 发行版之一][1]。尤其是对于刚刚迈向 Linux 世界的 Windows 用户来说,更是如此。
2006 年以来(也就是 Linux Mint 首次发布的那一年),他们开发了一系列的提高用户的体验的 [工具][2]。此外Linux Mint 是基于 Ubuntu 的,所以你有一个可以寻求帮助的庞大的用户社区。

View File

@ -1,157 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Managing processes on Linux with kill and killall)
[#]: via: (https://opensource.com/article/20/1/linux-kill-killall)
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
Managing processes on Linux with kill and killall
======
Know how to terminate processes and reclaim system resources with the
ps, kill, and killall commands.
![Penguin with green background][1]
In Linux, every program and daemon is a "process." Most processes represent a single running program. Other programs can fork off other processes, such as processes to listen for certain things to happen and then respond to them. And each process requires a certain amount of memory and processing power. The more processes you have running, the more memory and CPU cycles you'll need. On older systems, like my seven-year-old laptop, or smaller computers, like the Raspberry Pi, you can get the most out of your system if you keep an eye on what processes you have running in the background.
You can get a list of running processes with the **ps** command. You'll usually want to give **ps** some options to show more information in its output. I like to use the **-e** option to see every process running on my system, and the **-f** option to get full details about each process. Here are some examples:
```
$ ps
    PID TTY          TIME CMD
  88000 pts/0    00:00:00 bash
  88052 pts/0    00:00:00 ps
  88053 pts/0    00:00:00 head
[/code] [code]
$ ps -e | head
    PID TTY          TIME CMD
      1 ?        00:00:50 systemd
      2 ?        00:00:00 kthreadd
      3 ?        00:00:00 rcu_gp
      4 ?        00:00:00 rcu_par_gp
      6 ?        00:00:02 kworker/0:0H-events_highpri
      9 ?        00:00:00 mm_percpu_wq
     10 ?        00:00:01 ksoftirqd/0
     11 ?        00:00:12 rcu_sched
     12 ?        00:00:00 migration/0
[/code] [code]
$ ps -ef | head
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 13:51 ?        00:00:50 /usr/lib/systemd/systemd --switched-root --system --deserialize 36
root           2       0  0 13:51 ?        00:00:00 [kthreadd]
root           3       2  0 13:51 ?        00:00:00 [rcu_gp]
root           4       2  0 13:51 ?        00:00:00 [rcu_par_gp]
root           6       2  0 13:51 ?        00:00:02 [kworker/0:0H-kblockd]
root           9       2  0 13:51 ?        00:00:00 [mm_percpu_wq]
root          10       2  0 13:51 ?        00:00:01 [ksoftirqd/0]
root          11       2  0 13:51 ?        00:00:12 [rcu_sched]
root          12       2  0 13:51 ?        00:00:00 [migration/0]
```
The last example shows the most detail. On each line, the UID (user ID) shows the user that owns the process. The PID (process ID) represents the numerical ID of each process, and PPID (parent process ID) shows the ID of the process that spawned this one. In any Unix system, processes count up from PID 1, the first process to run once the kernel starts up. Here, **systemd** is the first process, which spawned **kthreadd**. And **kthreadd** created other processes including **rcu_gp**, **rcu_par_gp**, and a bunch of other ones.
### Process management with the kill command
The system will take care of most background processes on its own, so you don't need to worry about them. You should only have to get involved in managing any processes that you create, usually by running applications. While many applications run one process at a time (think about your music player or terminal emulator or game), other applications might create background processes. Some of these might keep running when you exit the application so they can get back to work quickly the next time you start the application.
Process management is an issue when I run Chromium, the open source base for Google's Chrome browser. Chromium works my laptop pretty hard and fires off a lot of extra processes. Right now, I can see these Chromium processes running with only five tabs open:
```
$ ps -ef | fgrep chromium
jhall      66221   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      66230   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
[...]
jhall      66861   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      67329   65132  0 15:45 pts/0    00:00:00 grep -F chromium
```
I've omitted some lines, but there are 20 Chromium processes and one **grep** process that is searching for the string "chromium."
```
$ ps -ef | fgrep chromium | wc -l
21
```
But after I exit Chromium, those processes remain open. How do you shut them down and reclaim the memory and CPU that those processes are taking up?
The **kill** command lets you terminate a process. In the simplest case, you tell **kill** the PID of what you want to stop. For example, to terminate each of these processes, I would need to execute the **kill** command against each of the 20 Chromium process IDs. One way to do that is with a command line that gets the Chromium PIDs and another that runs **kill** against that list:
```
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}'
66221
66230
66239
66257
66262
66283
66284
66285
66324
66337
66360
66370
66386
66402
66503
66539
66595
66734
66848
66861
69702
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}' &gt; /tmp/pids
$ kill $( cat /tmp/pids)
```
Those last two lines are the key. The first command line generates a list of process IDs for the Chromium browser. The second command line runs the **kill** command against that list of process IDs.
### Introducing the killall command
A simpler way to stop a bunch of processes all at once is to use the **killall** command. As you might guess by the name, **killall** terminates all processes that match a name. That means we can use this command to stop all of our rogue Chromium processes. This is as simple as:
```
`$ killall /usr/lib64/chromium-browser/chromium-browser`
```
But be careful with **killall**. This command can terminate any process that matches what you give it. That's why I like to first use **ps -ef** to check my running processes, then run **killall** against the exact path to the command that I want to stop.
You might also want to use the **-i** or **\--interactive** option to ask **killall** to prompt you before it stops each process.
**killall** also supports options to select processes that are older than a specific time using the **-o** or **\--older-than** option. This can be helpful if you discover a set of rogue processes that have been running unattended for several days, for example. Or you can select processes that are younger than a specific time, such as runaway processes you recently started. Use the **-y** or **\--younger-than** option to select these processes.
### Other ways to manage processes
Process management can be an important part of system maintenance. In my early career as a Unix and Linux systems administrator, the ability to kill escaped jobs was a useful tool to keep systems running properly. You may not need to kill rogue processes in a modern Linux desktop, but knowing **kill** and **killall** can help you when things eventually go awry.
You can also look for other ways to manage processes. In my case, I didn't really need to use **kill** or **killall** to stop the background Chromium processes after I exited the browser. There's a simple setting in Chromium to control that:
![Chromium background processes setting][2]
Still, it's always a good idea to keep an eye on what processes are running on your system and know how to manage them when needed.
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/1/linux-kill-killall
作者:[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/linux_penguin_green.png?itok=ENdVzW22 (Penguin with green background)
[2]: https://opensource.com/sites/default/files/uploads/chromium-settings-continue-running.png (Chromium background processes setting)

View File

@ -2,7 +2,7 @@
[#]: via: (https://opensource.com/article/21/2/osi-licenses-cal-cern-ohl)
[#]: author: (Pam Chestek https://opensource.com/users/pchestek)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (wyxplus)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@ -1,186 +0,0 @@
[#]: subject: (5 surprising things you can do with LibreOffice from the command line)
[#]: via: (https://opensource.com/article/21/3/libreoffice-command-line)
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
5 surprising things you can do with LibreOffice from the command line
======
Convert, print, protect, and do more with your files directly from the
command line.
![hot keys for shortcuts or features on computer keyboard][1]
LibreOffice has all the productivity features you'd want from an office software suite, making it a popular open source alternative to Microsoft Office or Google Suite. One of LibreOffice's powers is the ability to operate from the command line. For example, Seth Kenlon recently explained how he uses a global [command-line option to convert multiple files][2] from DOCX to EPUB with LibreOffice. His article inspired me to share some other LibreOffice command-line tips and tricks.
Before we look at some hidden features of LibreOffice commands, you need to understand how to use options with applications. Not all applications accept options (aside from the basics like the `--help` option, which works in most Linux applications).
```
`$ libreoffice --help`
```
This returns descriptions of other options LibreOffice accepts. Some applications don't have many options, but LibreOffice has a few screens worth, so there's plenty to play with.
That said, here are five useful things you can do with LibreOffice at the terminal to make the software even more useful.
### 1\. Customize your launch options
You can modify how you launch LibreOffice. For instance, if you want to open just LibreOffice's word processor component:
```
`$ libreoffice --writer  #starts the word processor`
```
You can open its other components similarly:
```
$ libreoffice --calc  #starts the Calc document
$ libreoffice --draw  #starts an empty Draw document
$ libreoffice --web  #starts and empty HTML document
```
You also can access specific help files from the command line:
```
`$ libreoffice --helpwriter`
```
![LibreOffice Writer help][3]
(Don Watkins, [CC BY-SA 4.0][4])
Or if you need help with the spreadsheet application:
```
`$ libreoffice --helpcalc`
```
You can start LibreOffice without the splash screen:
```
`$ libreoffice --writer --nologo`
```
You can even have it launch minimized in the background while you finish working in your current window:
```
`$ libreoffice --writer --minimized`
```
### 2\. Open a file in read-only mode
You can open files in read-only mode using `--view` to prevent accidentally making and saving changes to an important file:
```
`$ libreoffice --view example.odt`
```
### 3\. Open a document as a template
Have you ever created a document to use as a letterhead or invoice form? LibreOffice has a rich built-in template system, but you can make any document a template with the `-n` option:
```
`$ libreoffice --writer -n example.odt`
```
Your document will open in LibreOffice and you can make changes to it, but you won't overwrite the original file when you save it.
### 4\. Convert documents
When you need to do a small task like converting a file to a new format, it can take as long for the application to launch as it takes to do the task. The solution is the `--headless` option, which executes LibreOffice processes without launching the graphical user interface.
For example, converting a document to EPUB is a pretty simple task in LibreOffice—but it's even easier with the `libreoffice` command:
```
`$ libreoffice --headless --convert-to epub example.odt`
```
Using wildcards means you can convert dozens of documents at once:
```
`$ libreoffice --headless --convert-to epub *.odt`
```
You can convert files to several formats, including PDF, HTML, DOC, DOCX, EPUB, plain text, and many more.
### 5\. Print from the terminal
You can print LibreOffice documents from the command line without opening the application:
```
`$ libreoffice --headless -p example.odt`
```
This option prints to the default printer without opening LibreOffice; it just sends the document to your printer.
To print all the files in a directory:
```
`$ libreoffice -p *.odt`
```
(More than once, I've issued this command and then run out of paper, so make sure you have enough paper loaded in your printer before you start.)
You can also print files to PDF. There's usually no difference between this and using the `--convert-to-pdf` option but it's easy to remember:
```
`$ libreoffice --print-to-file example.odt --headless`
```
### Bonus: Flatpak and command options
If you installed LibreOffice as a [Flatpak][5], all of these command options work, but you have to pass them through Flatpak. Here's an example:
```
`$ flatpak run org.libreoffice.LibreOffice --writer`
```
It's a lot more verbose than a local install, so you might be inspired to [write a Bash alias][6] to make it easier to interact with LibreOffice directly.
### Surprising terminal options
Find out how you can extend the power of LibreOffice from the command line by consulting the man pages:
```
`$ man libreoffice`
```
Were you aware that LibreOffice had such a rich set of command-line options? Have you discovered other options that nobody else seems to know about? Share them in the comments!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/libreoffice-command-line
作者:[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/shortcut_command_function_editing_key.png?itok=a0sEc5vo (hot keys for shortcuts or features on computer keyboard)
[2]: https://opensource.com/article/21/2/linux-workday
[3]: https://opensource.com/sites/default/files/uploads/libreoffice-help.png (LibreOffice Writer help)
[4]: https://creativecommons.org/licenses/by-sa/4.0/
[5]: https://www.libreoffice.org/download/flatpak/
[6]: https://opensource.com/article/19/7/bash-aliases

View File

@ -1,89 +0,0 @@
[#]: subject: (Track your family calendar with a Raspberry Pi and a low-power display)
[#]: via: (https://opensource.com/article/21/3/family-calendar-raspberry-pi)
[#]: author: (Javier Pena https://opensource.com/users/jpena)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Track your family calendar with a Raspberry Pi and a low-power display
======
Help everyone keep up with your family's schedule using open source
tools and an E Ink display.
![Calendar with coffee and breakfast][1]
Some families have a complex schedule: the kids have school and afterschool activities, you have important events you want to remember, everyone has multiple appointments, and so forth. While you can keep track of everything using your cellphone and an app, wouldn't it be better to have a large, low-power display at home to show your family's calendar? Meet the E Ink calendar!
![E Ink calendar][2]
(Javier Pena, [CC BY-SA 4.0][3])
### The hardware
The calendar started as a holiday project, so I tried to reuse as much as I could. This included a Raspberry Pi 2 that had been unused for too long. I did not have an E Ink display, so I had to buy it. Fortunately, I found a vendor that provided [open source drivers and examples][4] for its Raspberry Pi-ready screen, which is connected using some [GPIO][5] ports.
My family also wanted to switch between different calendars, and that required some form of input. Instead of adding a USB keyboard, I opted for a simpler solution and bought a 1x4 matrix keypad, similar to the one described in [this article][6]. This allowed me to connect the keypad to some GPIO ports in the Raspberry Pi.
Finally, I needed a photo frame to house the whole setup. It looks a bit messy on the back, but it gets the job done.
![Calendar internals][7]
(Javier Pena, [CC BY-SA 4.0][3])
### The software
I took inspiration from a [similar project][8] and started writing the Python code for my project. I needed to get data from two areas:
* Weather data, which I got from the [OpenWeather API][9]
* Calendar data; I decided to use the [CalDav standard][10], which lets me connect to a calendar running on my home server
Since I had to wait for some parts to arrive, I used a modular approach for the input and display so that I could debug most of the code without the hardware. The calendar application supports drivers, and I wrote a [Pygame][11] driver to run it on a desktop PC.
The best part of writing the code was being able to reuse existing open source projects, so accessing the different APIs was easy. I could focus on the user interface—having per-person weekly and everyone daily calendars, allowing calendar selection using the keypad—and I had time to add some extra touches, like custom screen savers for special days.
![E Ink calendar screensaver][12]
(Javier Pena, [CC BY-SA 4.0][3])
The final integration step was making sure my calendar application would run on startup and be resilient to errors. I used a base [Raspberry Pi OS][13] image and installed the application as a systemd service so that it would survive failures and system restarts.
Once I finished everything, I uploaded the code [to GitHub][14]. So if you want to create a similar calendar, feel free to have a look and reuse it!
### The result
The calendar has become an everyday appliance in our kitchen. It helps us remember our daily activities, and even our kids use it to check their schedule before going to school.
On a personal note, the project helped me appreciate the _power of open_. Without open source drivers and libraries and open APIs, we would still be organizing our schedule with paper and a pen. Crazy, isn't it?
Need to keep your schedule straight? Learn how to do it using open source with these free...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/family-calendar-raspberry-pi
作者:[Javier Pena][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/jpena
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calendar-coffee.jpg?itok=9idm1917 (Calendar with coffee and breakfast)
[2]: https://opensource.com/sites/default/files/uploads/calendar.jpg (E Ink calendar)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://github.com/waveshare/e-Paper
[5]: https://opensource.com/article/19/3/gpio-pins-raspberry-pi
[6]: https://www.instructables.com/1x4-Membrane-Keypad-w-Arduino/
[7]: https://opensource.com/sites/default/files/uploads/calendar_internals.jpg (Calendar internals)
[8]: https://github.com/zli117/EInk-Calendar
[9]: https://openweathermap.org
[10]: https://en.wikipedia.org/wiki/CalDAV
[11]: https://github.com/pygame/pygame
[12]: https://opensource.com/sites/default/files/uploads/calendar_screensaver.jpg (E Ink calendar screensaver)
[13]: https://www.raspberrypi.org/software/
[14]: https://github.com/javierpena/eink-calendar

View File

@ -1,90 +0,0 @@
[#]: subject: (Set up network parental controls on a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-parental-control)
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Set up network parental controls on a Raspberry Pi
======
With minimal investment of time and money, you can keep your kids safe
online.
![Family learning and reading together at night in a room][1]
Parents are always looking for ways to protect their kids online—from malware, banner ads, pop-ups, activity-tracking scripts, and other concerns—and to prevent them from playing games and watching YouTube when they should be doing their schoolwork. Many businesses use tools that regulate their employees' online safety and activities, but the question is how to make this happen at home?
The short answer is a tiny, inexpensive Raspberry Pi computer that enables you to set parental controls for your kids and your work at home. This article walks you through how easy it is to build your own parental control-enabled home network with a Raspberry Pi.
### Install the hardware and software
For this project, you'll need a Raspberry Pi and a home network router. If you spend only five minutes exploring online shopping sites, you will find a lot of options. The [Raspberry Pi 4][2] and a [TP-Link router][3] are good options for beginners.
Once you have your network device and Pi, you need to install [Pi-hole][4] as a Linux container or a supported operating system. There are several [ways to install it][5], but an easy way is to issue the following command on your Pi:
```
`curl -sSL https://install.pi-hole.net | bash`
```
### Configure Pi-hole as your DNS server
Next, you need to configure the DHCP settings in both your router and Pi-hole:
1. Disable the DHCP server setting in your router
2. Enable the DHCP server in Pi-hole
Every device is different, so there's no way for me to tell you exactly what you need to click on to adjust your settings. Generally, you access your home router through a web browser. Your router's address is sometimes printed on the bottom of the router, and it begins with either 192.168 or 10.
In your web browser, navigate to your router's address and log in with the credentials you received when you got your internet service. It's often as simple as `admin` with a numeric password (sometimes this password is also printed on the router). If you don't know the login, call your internet provider and ask for details.
In the graphical interface, look for a section within your LAN about DHCP, and deactivate the DHCP server. Your router's interface will almost certainly look different from mine, but this is an example of what I saw when setting it up. Uncheck **DHCP server**:
![Disable DHCP][6]
(Daniel Oh, [CC BY-SA 4.0][7])
Next, you _must_ activate the DHCP server on the Pi-hole. If you don't do that, none of your devices will be able to get online unless you manually assign IP addresses!
### Make your network family-friendly
You're all set. Now, your network devices (i.e., mobile phone, tablet PC, laptop, etc.) will automatically find the DHCP server on the Raspberry Pi. Then, each device will be assigned a dynamic IP address to access the internet.
Note: If your router device supports setting a DNS server, you can also configure the DNS clients in your router. The client will refer to the Pi-hole as your DNS server.
To set up rules for which sites and activities your kids can access, open a web browser to the Pi-hole admin page, `http://pi.hole/admin/`. On the dashboard, click on **Whitelist** to add web pages your kids are allowed to access. You can also add sites that your kids aren't allowed to access (e.g., gaming, adult, ads, shopping, etc.) to the **Blocklist**.
![Pi-hole admin dashboard][8]
(Daniel Oh, [CC BY-SA 4.0][7])
### What's next?
Now that you've set up your Raspberry Pi for parental control, you can keep your kids safer online while giving them access to approved entertainment options. This can also decrease your home internet usage by reducing how much your family is streaming. For more advanced usage, access Pi-hole's [documentation][9] and [blogs][10].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-parental-control
作者:[Daniel Oh][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/daniel-oh
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/family_learning_kids_night_reading.png?itok=6K7sJVb1 (Family learning and reading together at night in a room)
[2]: https://www.raspberrypi.org/products/
[3]: https://www.amazon.com/s?k=tp-link+router&crid=3QRLN3XRWHFTC&sprefix=TP-Link%2Caps%2C186&ref=nb_sb_ss_ts-doa-p_3_7
[4]: https://pi-hole.net/
[5]: https://github.com/pi-hole/pi-hole/#one-step-automated-install
[6]: https://opensource.com/sites/default/files/uploads/disabledhcp.jpg (Disable DHCP)
[7]: https://creativecommons.org/licenses/by-sa/4.0/
[8]: https://opensource.com/sites/default/files/uploads/blocklist.png (Pi-hole admin dashboard)
[9]: https://docs.pi-hole.net/
[10]: https://pi-hole.net/blog/#page-content

View File

@ -0,0 +1,95 @@
[#]: subject: (6 things to know about using WebAssembly on Firefox)
[#]: via: (https://opensource.com/article/21/3/webassembly-firefox)
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
6 things to know about using WebAssembly on Firefox
======
Get to know the opportunities and limitations of running WebAssembly on
Firefox.
![Business woman on laptop sitting in front of window][1]
WebAssembly is a portable execution format that has drawn a lot of interest due to its ability to execute applications in the browser at near-native speed. By its nature, WebAssembly has some special properties and limitations. However, by combining it with other technologies, completely new possibilities arise, especially related to gaming in the browser.
This article describes the concepts, possibilities, and limitations of running WebAssembly on Firefox.
### The sandbox
WebAssembly has a [strict security policy][2]. A program or functional unit in WebAssembly is called a _module_. Each module instance runs its own isolated memory space. Therefore, one module cannot access another module's virtual address space, even if they are loaded on the same web page. By design, WebAssembly also considers memory safety and control-flow integrity, which enables an (almost-) deterministic execution.
### Web APIs
Access to many kinds of input and output devices is granted via JavaScript [Web APIs][3]. In the future, access to Web APIs will be available without the detour over to JavaScript, according to this [proposal][4]. C++ programmers can find information about accessing the Web APIs on [Emscripten.org][5]. Rust programmers can use the [wasm-bindgen][6] library that is documented on [rustwasm.github.io][7].
### File input/output
Because WebAssembly is executed in a sandboxed environment, it cannot access the host's filesystem when it is executed in a browser. However, Emscripten offers a solution in the form of a virtual filesystem.
Emscripten makes it possible to preload files to the memory filesystem at compile time. Those files can then be read from within the WebAssembly application, just as you would on an ordinary filesystem. This [tutorial][8] offers more information.
### Persistent data
If you need to store persistent data on the client-side, it must be done over a JavaScript Web API. Refer to Mozilla Developer Network's documentation on [browser storage limits and eviction criteria][9] for more detailed information about the different approaches.
### Memory management
WebAssembly modules operate on linear memory as a [stack machine][10]. This means that concepts like heap memory allocations are not available. However, if you are using `new` in C++ or `Box::new` in Rust, you would expect it to result in a heap memory allocation. The way heap memory allocation requests are translated into WebAssembly relies heavily upon the toolchain. You can find a detailed analysis of how different toolchains deal with heap memory allocations in Frank Rehberger's post about [_WebAssembly and dynamic memory_][11].
### Games!
In combination with [WebGL][12], WebAssembly enables native gaming in the browser due to its high execution speed. The big proprietary game engines [Unity][13] and [Unreal Engine 4][14] show what is possible with WebGL. There are also open source game engines that use WebAssembly and the WebGL interface. Here are some examples:
* Since November 2011, the [id Tech 4][15] engine (better known as the Doom 3 engine) is available under the GPL license on [GitHub][16]. There is also a [WebAssembly port of Doom 3][17].
* The Urho3D engine provides some [impressive examples][18] that can run in the browser.
* If you like retro games, try this [Game Boy emulator][19].
* The [Godot engine is also capable of producing WebAssembly][20]. I couldn't find a demo, but the [Godot editor][21] has been ported to WebAssembly.
### More about WebAssembly
WebAssembly is a promising technology that I believe we will see more frequently in the future. In addition to executing in the browser, WebAssembly can also be used as a portable execution format. The [Wasmer][22] container host enables you to execute WebAssembly code on various platforms.
If you want more demos, examples, and tutorials, take a look at this [extensive collection of WebAssembly topics][23]. Not exclusive to WebAssembly but still worth a look are Mozilla's [collection of games and demos][24].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/webassembly-firefox
作者:[Stephan Avenwedde][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/hansic99
[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://webassembly.org/docs/security/
[3]: https://developer.mozilla.org/en-US/docs/Web/API
[4]: https://github.com/WebAssembly/gc/blob/master/README.md
[5]: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html
[6]: https://github.com/rustwasm/wasm-bindgen
[7]: https://rustwasm.github.io/wasm-bindgen/
[8]: https://emscripten.org/docs/api_reference/Filesystem-API.html
[9]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria
[10]: https://en.wikipedia.org/wiki/Stack_machine
[11]: https://frehberg.wordpress.com/webassembly-and-dynamic-memory/
[12]: https://en.wikipedia.org/wiki/WebGL
[13]: https://beta.unity3d.com/jonas/AngryBots/
[14]: https://www.youtube.com/watch?v=TwuIRcpeUWE
[15]: https://en.wikipedia.org/wiki/Id_Tech_4
[16]: https://github.com/id-Software/DOOM-3
[17]: https://wasm.continuation-labs.com/d3demo/
[18]: https://urho3d.github.io/samples/
[19]: https://vaporboy.net/
[20]: https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html
[21]: https://godotengine.org/editor/latest/godot.tools.html
[22]: https://github.com/wasmerio/wasmer
[23]: https://github.com/mbasso/awesome-wasm
[24]: https://developer.mozilla.org/en-US/docs/Games/Examples

View File

@ -0,0 +1,285 @@
[#]: subject: (Learn how file input and output works in C)
[#]: via: (https://opensource.com/article/21/3/file-io-c)
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Learn how file input and output works in C
======
Understanding I/O can help you do things faster.
![4 manilla folders, yellow, green, purple, blue][1]
If you want to learn input and output in C, start by looking at the `stdio.h` include file. As you might guess from the name, that file defines all the standard ("std") input and output ("io") functions.
The first `stdio.h` function that most people learn is the `printf` function to print formatted output. Or the `puts` function to print a simple string. Those are great functions to print information to the user, but if you want to do more than that, you'll need to explore other functions.
You can learn about some of these functions and methods by writing a replica of a common Linux command. The `cp` command will copy one file to another. If you look at the `cp` man page, you'll see that `cp` supports a broad set of command-line parameters and options. But in the simplest case, `cp` supports copying one file to another:
```
`cp infile outfile`
```
You can write your own version of this `cp` command in C by using only a few basic functions to _read_ and _write_ files.
### Reading and writing one character at a time
You can easily do input and output using the `fgetc` and `fputc` functions. These read and write data one character at a time. The usage is defined in `stdio.h` and is quite straightforward: `fgetc` reads (gets) a single character from a file, and `fputc` puts a single character into a file.
```
int [fgetc][2](FILE *stream);
int [fputc][3](int c, FILE *stream);
```
Writing the `cp` command requires accessing files. In C, you open a file using the `fopen` function, which takes two arguments: the _name_ of the file and the _mode_ you want to use. The mode is usually `r` to read from a file or `w` to write to a file. The mode supports other options too, but for this tutorial, just focus on reading and writing.
Copying one file to another then becomes a matter of opening the source and destination files, then _reading one character at a time_ from the first file, then _writing that character_ to the second file. The `fgetc` function returns either the single character read from the input file or the _end of file_ (`EOF`) marker when the file is done. Once you've read `EOF`, you've finished copying and you can close both files. That code looks like this:
```
  do {
    ch = [fgetc][2](infile);
    if (ch != EOF) {
      [fputc][3](ch, outfile);
    }
  } while (ch != EOF);
```
You can write your own `cp` program with this loop to read and write one character at a time by using the `fgetc` and `fputc` functions. The `cp.c` source code looks like this:
```
#include &lt;stdio.h&gt;
int
main(int argc, char **argv)
{
  FILE *infile;
  FILE *outfile;
  int ch;
  /* parse the command line */
  /* usage: cp infile outfile */
  if (argc != 3) {
    [fprintf][4](stderr, "Incorrect usage\n");
    [fprintf][4](stderr, "Usage: cp infile outfile\n");
    return 1;
  }
  /* open the input file */
  infile = [fopen][5](argv[1], "r");
  if (infile == NULL) {
    [fprintf][4](stderr, "Cannot open file for reading: %s\n", argv[1]);
    return 2;
  }
  /* open the output file */
  outfile = [fopen][5](argv[2], "w");
  if (outfile == NULL) {
    [fprintf][4](stderr, "Cannot open file for writing: %s\n", argv[2]);
    [fclose][6](infile);
    return 3;
  }
  /* copy one file to the other */
  /* use fgetc and fputc */
  do {
    ch = [fgetc][2](infile);
    if (ch != EOF) {
      [fputc][3](ch, outfile);
    }
  } while (ch != EOF);
  /* done */
  [fclose][6](infile);
  [fclose][6](outfile);
  return 0;
}
```
And you can compile that `cp.c` file into a full executable using the GNU Compiler Collection (GCC):
```
`$ gcc -Wall -o cp cp.c`
```
The `-o cp` option tells the compiler to save the compiled program into the `cp` program file. The `-Wall` option tells the compiler to turn on all warnings. If you don't see any warnings, that means everything worked correctly.
### Reading and writing blocks of data
Programming your own `cp` command by reading and writing data one character at a time does the job, but it's not very fast. You might not notice when copying "everyday" files like documents and text files, but you'll really notice the difference when copying large files or when copying files over a network. Working on one character at a time requires significant overhead.
A better way to write this `cp` command is by reading a chunk of the input into memory (called a _buffer_), then writing that collection of data to the second file. This is much faster because the program can read more of the data at one time, which requires fewer "reads" from the file.
You can read a file into a variable by using the `fread` function. This function takes several arguments: the array or memory buffer to read data into (`ptr`), the size of the smallest thing you want to read (`size`), how many of those things you want to read (`nmemb`), and the file to read from (`stream`):
```
`size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);`
```
The different options provide quite a bit of flexibility for more advanced file input and output, such as reading and writing files with a certain data structure. But in the simple case of _reading data from one file_ and _writing data to another file_, you can use a buffer that is an array of characters.
And you can write the buffer to another file using the `fwrite` function. This uses a similar set of options to the `fread` function: the array or memory buffer to read data from, the size of the smallest thing you need to write, how many of those things you need to write, and the file to write to.
```
`size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);`
```
In the case where the program reads a file into a buffer, then writes that buffer to another file, the array (`ptr`) can be an array of a fixed size. For example, you can use a `char` array called `buffer` that is 200 characters long.
With that assumption, you need to change the loop in your `cp` program to _read data from a file into a buffer_ then _write that buffer to another file_:
```
  while (![feof][7](infile)) {
    buffer_length = [fread][8](buffer, sizeof(char), 200, infile);
    [fwrite][9](buffer, sizeof(char), buffer_length, outfile);
  }
```
Here's the full source code to your updated `cp` program, which now uses a buffer to read and write data:
```
#include &lt;stdio.h&gt;
int
main(int argc, char **argv)
{
  FILE *infile;
  FILE *outfile;
  char buffer[200];
  size_t buffer_length;
  /* parse the command line */
  /* usage: cp infile outfile */
  if (argc != 3) {
    [fprintf][4](stderr, "Incorrect usage\n");
    [fprintf][4](stderr, "Usage: cp infile outfile\n");
    return 1;
  }
  /* open the input file */
  infile = [fopen][5](argv[1], "r");
  if (infile == NULL) {
    [fprintf][4](stderr, "Cannot open file for reading: %s\n", argv[1]);
    return 2;
  }
  /* open the output file */
  outfile = [fopen][5](argv[2], "w");
  if (outfile == NULL) {
    [fprintf][4](stderr, "Cannot open file for writing: %s\n", argv[2]);
    [fclose][6](infile);
    return 3;
  }
  /* copy one file to the other */
  /* use fread and fwrite */
  while (![feof][7](infile)) {
    buffer_length = [fread][8](buffer, sizeof(char), 200, infile);
    [fwrite][9](buffer, sizeof(char), buffer_length, outfile);
  }
  /* done */
  [fclose][6](infile);
  [fclose][6](outfile);
  return 0;
}
```
Since you want to compare this program to the other program, save this source code as `cp2.c`. You can compile that updated program using GCC:
```
`$ gcc -Wall -o cp2 cp2.c`
```
As before, the `-o cp2` option tells the compiler to save the compiled program into the `cp2` program file. The `-Wall` option tells the compiler to turn on all warnings. If you don't see any warnings, that means everything worked correctly.
### Yes, it really is faster
Reading and writing data using buffers is the better way to write this version of the `cp` program. Because it reads chunks of a file into memory at once, the program doesn't need to read data as often. You might not notice a difference in using either method on smaller files, but you'll really see the difference if you need to copy something that's much larger or when copying data on slower media like over a network connection.
I ran a runtime comparison using the Linux `time` command. This command runs another program, then tells you how long that program took to complete. For my test, I wanted to see the difference in time, so I copied a 628MB CD-ROM image file I had on my system.
I first copied the image file using the standard Linux `cp` command to see how long that takes. By running the Linux `cp` command first, I also eliminated the possibility that Linux's built-in file-cache system wouldn't give my program a false performance boost. The test with Linux `cp` took much less than one second to run:
```
$ time cp FD13LIVE.iso tmpfile
real    0m0.040s
user    0m0.001s
sys     0m0.003s
```
Copying the same file using my own version of the `cp` command took significantly longer. Reading and writing one character at a time took almost five seconds to copy the file:
```
$ time ./cp FD13LIVE.iso tmpfile
real    0m4.823s
user    0m4.100s
sys     0m0.571s
```
Reading data from an input into a buffer and then writing that buffer to an output file is much faster. Copying the file using this method took less than a second:
```
$ time ./cp2 FD13LIVE.iso tmpfile
real    0m0.944s
user    0m0.224s
sys     0m0.608s
```
My demonstration `cp` program used a buffer that was 200 characters. I'm sure the program would run much faster if I read more of the file into memory at once. But for this comparison, you can already see the huge difference in performance, even with a small, 200 character buffer.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/file-io-c
作者:[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/file_system.jpg?itok=pzCrX1Kc (4 manilla folders, yellow, green, purple, blue)
[2]: http://www.opengroup.org/onlinepubs/009695399/functions/fgetc.html
[3]: http://www.opengroup.org/onlinepubs/009695399/functions/fputc.html
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/fopen.html
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/fclose.html
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/feof.html
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/fread.html
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/fwrite.html

View File

@ -0,0 +1,176 @@
[#]: subject: (Get started with edge computing by programming embedded systems)
[#]: via: (https://opensource.com/article/21/3/rtos-embedded-development)
[#]: author: (Alan Smithee https://opensource.com/users/alansmithee)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Get started with edge computing by programming embedded systems
======
The AT device package for controlling wireless modems is one of RTOS's
most popular extensions.
![Looking at a map][1]
RTOS is an open source [operating system for embedded devices][2] developed by RT-Thread. It provides a standardized, friendly foundation for developers to program a variety of devices and includes a large number of useful libraries and toolkits to make the process easier.
Like Linux, RTOS uses a modular approach, which makes it easy to extend. Packages enable developers to use RTOS for any device they want to target. One of RTOS's most popular extensions is the AT device package, which includes porting files and sample code for different AT devices (i.e., modems).
At over 62,000 downloads (at the time of this writing, at least), one of the most popular extensions to RTOS is the AT device package, which includes porting files and sample code for different AT devices.
### About AT commands
AT commands were originally a protocol to control old dial-up modems. As modem technology moved on to higher bandwidths, it remained useful to have a light and efficient protocol for device control, and major mobile phone manufacturers jointly developed a set of AT commands to control the GSM module on mobile phones.
Today, the AT protocol is still common in networked communication, and there are many devices, including WiFi, Bluetooth, and 4G, that accept AT commands.
If you're creating purpose-built appliances for edge computing input, monitoring, or the Internet of Things (IoT), some of the AT devices supported by RTOS that you may encounter include ESP8266, ESP32, M26, MC20, RW007, MW31, SIM800C, W60X, SIM76XX, A9/A9G, BC26, AIR720, ME3616, M 6315, BC28, and EC200X.
RT-Thread contains the Socket Abstraction Layer (SAL) component, which implements the abstraction of various network protocols and interfaces and provides a standard set of [BSD socket][3] APIs to the upper level. The SAL then takes over the AT socket interface so that developers just need to consider the network interface provided by the network application layer.
This package implements the AT socket on devices (including the ones above), allowing communications through standard socket interfaces in the form of AT commands. The [RT-thread programming guide][4] includes descriptions of specific functions.
The at_device package is distributed under an LGPLv2.1 license, and it's easy to obtain by using the [RT-Thread Env tool][5]. This tool includes a configurator and a package manager, which configure the kernel and component functions and can be used to tailor the components and manage online packages. This enables developers to build systems as if they were building blocks.
### Get the at_device package
To use AT devices with RTOS, you must enable the AT component library and AT socket functionality. This requires:
* RT_Thread 4.0.2+
* RT_Thread AT component 1.3.0+
* RT_Thread SAL component
* RT-Thread netdev component
The AT device package has been updated for multiple versions. Different versions require different configuration options, so they must fit into the corresponding system versions. Most of the currently available AT device package versions are:
* V1.2.0: For RT-Thread versions less than V3.1.3, AT component version equals V1.0.0
* V1.3.0: For RT-Thread versions less than V3.1.3, AT component version equals V1.1.0
* V1.4.0: For RT-Thread versions less than V3.1.3 or equal to V4.0.0, AT component version equals V1.2.0
* V1.5.0: For RT-Thread versions less than V3.1.3 or equal to V4.0.0, AT component version equals V1.2.0
* V1.6.0: For RT-Thread versions equal to V3.1.3 or V4.0.1, AT component version equals V1.2.0
* V2.0.0/V2.0.1: For RT-Thread versions higher than V4.0.1 or higher than 3.1.3, AT component version equals V1.3.0
* Latest version: For RT-Thread versions higher than V4.0.1 or higher than 3.1.3, AT component version equals V1.3.0
Getting the right version is mostly an automatic process done in menuconfig. It provides the best version of the at_device package based on your current system environment.
As mentioned, different versions require different configuration options. For instance, version 1.x supports enabling one AT device at a time:
```
RT-Thread online packages  ---&gt;
     IoT - internet of things  ---&gt;
        -*- AT DEVICE: RT-Thread AT component porting or samples for different device  
        [ ]   Enable at device init by thread
              AT socket device modules (Not selected, please select)  ---&gt;    
              Version (V1.6.0)  ---&gt;
```
The option to enable the AT device init by thread dictates whether the configuration creates a separate thread to initialize the device network.
Version 2.x supports enabling multiple AT devices at the same time:
```
RT-Thread online packages  ---&gt;
     IoT - internet of things  ---&gt;
        -*- AT DEVICE: RT-Thread AT component porting or samples for different device
        [*]   Quectel M26/MC20  ---&gt;
          [*]   Enable initialize by thread
          [*]   Enable sample
          (-1)    Power pin
          (-1)    Power status pin
          (uart3) AT client device name
          (512)   The maximum length of receive line buffer
        [ ]   Quectel EC20  ---&gt;
        [ ]   Espressif ESP32  ---&gt;
        [*]   Espressif ESP8266  ---&gt;
          [*]   Enable initialize by thread
          [*]   Enable sample
          (realthread) WIFI ssid
          (12345678) WIFI password
          (uart2) AT client device name
          (512)   The maximum length of receive line buffer
        [ ]   Realthread RW007  ---&gt;
        [ ]   SIMCom SIM800C  ---&gt;
        [ ]   SIMCom SIM76XX  ---&gt;
        [ ]   Notion MW31  ---&gt;
        [ ]   WinnerMicro W60X  ---&gt;
        [ ]   AiThink A9/A9G  ---&gt;
        [ ]   Quectel BC26  ---&gt;
        [ ]   Luat air720  ---&gt;
        [ ]   GOSUNCN ME3616  ---&gt;
        [ ]   ChinaMobile M6315  ---&gt;
        [ ]   Quectel BC28  ---&gt;
        [ ]   Quectel ec200x  ---&gt;
        Version (latest)  ---&gt;
```
This version includes many other options, including one to enable sample code, which might be particularly useful to new developers or any developer using an unfamiliar device.
You can also control options to choose which pin you want to use to supply power to your component, a pin to indicate the power state, the name of the serial device the sample device uses, and the maximum length of the data the sample device receives. On applicable devices, you can also set the SSID name and password.
In short, there is no shortage of control options.
* V2.X.X version supports enabling multiple AT devices simultaneously, and the enabled device information can be viewed with the `ifocnfig` command in [finsh shell][6].
* V2.X.X version requires the device to register before it's used; the registration can be done in the samples directory file or customized in the application layer.
* Pin options such as **Power pin** and **Power status pin** are configured according to the device's hardware connection. They can be configured as `-1` if the hardware power-on function is not used.
* One AT device should correspond to one serial name, and the **AT client device name** for each device should be different.
### AT components configuration options
When the AT device package is selected and device support is enabled, client functionality for the AT component is selected by default. That means more options—this time for the AT component:
```
RT-Thread Components  ---&gt;
    Network  ---&gt;
        AT commands  ---&gt;
    [ ]   Enable debug log output
    [ ]   Enable AT commands server
    -*-   Enable AT commands client
    (1)     The maximum number of supported clients
    -*-     Enable BSD Socket API support by AT commnads
    [*]     Enable CLI(Command-Line Interface) for AT commands
    [ ]     Enable print RAW format AT command communication data
    (128)   The maximum length of AT Commonds buffer
```
The configuration options related to the AT device package are:
* **The maximum number of supported clients**: Selecting multiple devices in the AT device package requires this option to be configured as the corresponding value.
* **Enable BSD Socket API support by AT commands**: This option will be selected by default when selecting the AT device package.
* **The maximum length of AT Commands buffe:** The maximum length of the data the AT commands can send.
### Anything is possible
When you start programming embedded systems, you quickly realize that you can create anything you can imagine. RTOS aims to help you get there, and its packages offer a head start. Interconnected devices are the expectation now. IoT technology on the [edge][7] must be able to communicate across various protocols, and the AT protocol is the key.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/rtos-embedded-development
作者:[Alan Smithee][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/alansmithee
[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/article/20/6/open-source-rtos
[3]: https://en.wikipedia.org/wiki/Berkeley_sockets
[4]: https://github.com/RT-Thread/rtthread-manual-doc/blob/master/at/at.md
[5]: https://www.rt-thread.io/download.html?download=Env
[6]: https://www.rt-thread.org/download/rttdoc_1_0_0/group__finsh.html
[7]: https://www.redhat.com/en/topics/edge-computing

View File

@ -0,0 +1,165 @@
[#]: subject: (How to write 'Hello World' in WebAssembly)
[#]: via: (https://opensource.com/article/21/3/hello-world-webassembly)
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
How to write 'Hello World' in WebAssembly
======
Get started writing WebAssembly in human-readable text with this
step-by-step tutorial.
![Hello World inked on bread][1]
WebAssembly is a bytecode format that [virtually every browser][2] can compile to its host system's machine code. Alongside JavaScript and WebGL, WebAssembly fulfills the demand for porting applications for platform-independent use in the web browser. As a compilation target for C++ and Rust, WebAssembly enables web browsers to execute code at near-native speed.
When you talk about a WebAssembly, application, you must distinguish between three states:
1. **Source code (e.g., C++ or Rust):** You have an application written in a compatible language that you want to execute in the browser.
2. **WebAssembly bytecode:** You choose WebAssembly bytecode as your compilation target. As a result, you get a `.wasm` file.
3. **Machine code (opcode):** The browser loads the `.wasm` file and compiles it to the corresponding machine code of its host system.
WebAssembly also has a text format that represents the binary format in human-readable text. For the sake of simplicity, I will refer to this as **WASM-text**. WASM-text can be compared to high-level assembly language. Of course, you would not write a complete application based on WASM-text, but it's good to know how it works under the hood (especially for debugging and performance optimization).
This article will guide you through creating the classic _Hello World_ program in WASM-text.
### Creating the .wat file
WASM-text files usually end with `.wat`. Start from scratch by creating an empty text file named `helloworld.wat`, open it with your favorite text editor, and paste in:
```
(module
    ;; Imports from JavaScript namespace
    (import  "console"  "log" (func  $log (param  i32  i32))) ;; Import log function
    (import  "js"  "mem" (memory  1)) ;; Import 1 page of memory (54kb)
   
    ;; Data section of our module
    (data (i32.const 0) "Hello World from WebAssembly!")
   
    ;; Function declaration: Exported as helloWorld(), no arguments
    (func (export  "helloWorld")
        i32.const 0  ;; pass offset 0 to log
        i32.const 29  ;; pass length 29 to log (strlen of sample text)
        call  $log
        )
)
```
The WASM-text format is based upon S-expressions. To enable interaction, JavaScript functions are imported with the `import` statement, and WebAssembly functions are exported with the `export` statement. For this example, import the `log `function from the `console` module, which takes two parameters of type `i32` as input and one page of memory (64KB) to store the string.
The string will be written into the `data` section at offset `0`. The `data` section is an overlay of your memory, and the memory is allocated in the JavaScript part.
Functions are marked with the keyword `func`. The stack is empty when entering a function. Function parameters are pushed onto the stack (here offset and length) before another function is called (see `call $log`). When a function returns an `f32` type (for example), an `f32` variable must remain on the stack when leaving the function (but this is not the case in this example).
### Creating the .wasm file
The WASM-text and the WebAssembly bytecode have 1:1 correspondence. This means you can convert WASM-text into bytecode (and vice versa). You already have the WASM-text, and now you want to create the bytecode.
The conversion can be performed with the [WebAssembly Binary Toolkit][3] (WABT). Make a clone of the repository at that link and follow the installation instructions.
After you build the toolchain, convert WASM-text to bytecode by opening a console and entering:
```
`wat2wasm helloworld.wat -o helloworld.wasm`
```
You can also convert bytecode to WASM-text with:
```
`wasm2wat helloworld.wasm -o helloworld_reverse.wat`
```
A `.wat` file created from a `.wasm` file does not include any function nor parameter names. By default, WebAssembly identifies functions and parameters with their index.
### Compiling the .wasm file
Currently, WebAssembly only coexists with JavaScript, so you have to write a short script to load and compile the `.wasm` file and do the function calls. You also need to define the functions you will import in your WebAssembly module.
Create an empty text file and name it `helloworld.html`, then open your favorite text editor and paste in:
```
&lt;!DOCTYPE  html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta  charset="utf-8"&gt;
    &lt;title&gt;Simple template&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;script&gt;
   
      var memory = new  WebAssembly.Memory({initial:1});
      function  consoleLogString(offset, length) {
        var  bytes = new  Uint8Array(memory.buffer, offset, length);
        var  string = new  TextDecoder('utf8').decode(bytes);
        console.log(string);
      };
      var  importObject = {
        console: {
          log:  consoleLogString
        },
        js : {
          mem:  memory
        }
      };
     
      WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)
      .then(obj  =&gt; {
        obj.instance.exports.helloWorld();
      });
     
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
```
The `WebAssembly.Memory(...)` method returns one page of memory that is 64KB in size. The function `consoleLogString` reads a string from that memory page based on the length and offset. Both objects are passed to your WebAssembly module as part of the `importObject`.
Before you can run this example, you may have to allow Firefox to access files from this directory by typing `about:config` in the address line and setting `privacy.file_unique_origin` to `true`:
![Firefox setting][4]
(Stephan Avenwedde, [CC BY-SA 4.0][5])
> **Caution:** This will make you vulnerable to the [CVE-2019-11730][6] security issue.
Now, open `helloworld.html` in Firefox and enter **Ctrl**+**K** to open the developer console.
![Debugger output][7]
(Stephan Avenwedde, [CC BY-SA 4.0][5])
### Learn more
This Hello World example is just one of the detailed tutorials in MDN's [Understanding WebAssembly text format][8] documentation. If you want to learn more about WebAssembly and how it works under the hood, take a look at these docs.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/hello-world-webassembly
作者:[Stephan Avenwedde][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/hansic99
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/helloworld_bread_lead.jpeg?itok=1r8Uu7gk (Hello World inked on bread)
[2]: https://developer.mozilla.org/en-US/docs/WebAssembly#browser_compatibility
[3]: https://github.com/webassembly/wabt
[4]: https://opensource.com/sites/default/files/uploads/firefox_setting.png (Firefox setting)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://www.mozilla.org/en-US/security/advisories/mfsa2019-21/#CVE-2019-11730
[7]: https://opensource.com/sites/default/files/uploads/debugger_output.png (Debugger output)
[8]: https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format

View File

@ -2,7 +2,7 @@
[#]: via: (https://itsfoss.com/kooha-screen-recorder/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@ -0,0 +1,194 @@
[#]: subject: (My favorite open source project management tools)
[#]: via: (https://opensource.com/article/21/3/open-source-project-management)
[#]: author: (Frank Bergmann https://opensource.com/users/fraber)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
My favorite open source project management tools
======
If you're managing large and complex projects, try replacing Microsoft
Project with an open source option.
![Kanban-style organization action][1]
Projects like building a satellite, developing a robot, or launching a new product are all expensive, involve different providers, and contain hard dependencies that must be tracked.
The approach to project management in the world of large projects is quite simple (in theory at least). You create a project plan and split it into smaller pieces until you can reasonably assign costs, duration, resources, and dependencies to the various activities. Once the project plan is approved by the people in charge of the money, you use it to track the project's execution. Drawing all of the project's activities on a timeline produces a bar chart called a [Gantt chart][2].
Gantt charts have always been used in [waterfall project methodologies][3], but they can also be used with agile. For example, large projects may use a Gantt chart for a scrum sprint and ignore other details like user stories, thereby embedding agile phases. Other large projects may include multiple product releases (e.g., minimum viable product [MVP], second version, third version, etc.). In this case, the super-structure is kind of agile, with each phase planned as a Gantt chart to deal with budgets and complex dependencies.
### Project management tools
There are literally hundreds of tools available to manage large projects with Gantt charts, and Microsoft Project is probably the most popular. It is part of the Microsoft Office family, scales to hundreds of thousands of activities, and has an incredible number of features that support almost every conceivable way to manage a project schedule. With Project, it's not always clear what is more expensive: the software license or the training courses that teach you how to use the tool.
Another drawback is that Microsoft Project is a standalone desktop application, and only one person can update a schedule. You would need to buy licenses for Microsoft Project Server, Project for the web, or Microsoft Planner if you want multiple users to collaborate.
Fortunately, there are open source alternatives to the proprietary tools, including the applications in this article. All are open source and include a Gantt for scheduling hierarchical activities based on resources and dependencies. ProjectLibre, GanttProject, and TaskJuggler are desktop applications for a single project manager; ProjeQtOr and Redmine are web applications for project teams, and ]project-open[ is a web application for managing entire organizations.
I evaluated the tools based on a single user planning and tracking a single large project. My evaluation criteria includes Gantt editor features, availability on Windows, Linux, and macOS, scalability, import/export, and reporting. (Full disclosure: I'm the founder of ]project-open[, and I've been active in several open source communities for many years. This list includes our product, so my views may be biased, but I tried to focus on each product's best features.)
### Redmine 4.1.0
![Redmine][4]
(Frank Bergmann, [CC BY-SA 4.0][5])
[Redmine][6] is a web-based project management tool with a focus on agile methodologies.
The standard installation includes a Gantt timeline view, but it lacks fundamental features like scheduling, drag-and-drop, indent and outdent, and resource assignments. You have to edit task properties individually to change the task tree's structure.
Redmine has Gantt editor plugins, but they are either outdated (e.g., [Plus Gantt][7]) or proprietary (e.g., [ANKO Gantt chart][8]). If you know of other open source Gantt editor plugins, please share them in the comments.
Redmine is written in Ruby on Rails and available for Windows, Linux, and macOS. The core is available under a GPLv2 license.
* **Best for:** IT teams working using agile methodologies
* **Unique selling proposition:** It's the original "upstream" parent project of OpenProject and EasyRedmine.
### ]project-open[ 5.1
![\]project-open\[][9]
(Frank Bergmann, [CC BY-SA 4.0][5])
[]project-open[][10] is a web-based project management system that takes the perspective of an entire organization, similar to an enterprise resource planning (ERP) system. It can also manage project portfolios, budgets, invoicing, sales, human resources, and other functional areas. Specific variants exist for professional services automation (PSA) for running a project company, project management office (PMO) for managing an enterprise's strategic projects, and enterprise project management (EPM) for managing a department's projects.
The ]po[ Gantt editor includes hierarchical tasks, dependencies, and scheduling based on planned work and assigned resources. It does not support resource calendars and non-human resources. The ]po[ system is quite complex, and the GUI might need a refresh.
]project-open[ is written in TCL and JavaScript and available for Windows and Linux. The ]po[ core is available under a GPLv2 license with proprietary extensions available for large companies.
* **Best for:** Medium to large project organizations that need a lot of financial project reporting
* **Unique selling proposition:** ]po[ is an integrated system to run an entire project company or department.
### ProjectLibre 1.9.3
![ProjectLibre][11]
(Frank Bergmann, [CC BY-SA 4.0][5])
[ProjectLibre][12] is probably the closest you can get to Microsoft Project in the open source world. It is a desktop application that supports all-important project planning features, including resource calendars, baselines, and cost management. It also allows you to import and export schedules using MS-Project's file format.
ProjectLibre is perfectly suitable for planning and executing small or midsized projects. However, it's missing some advanced features in MS-Project, and its GUI is not the prettiest.
ProjectLibre is written in Java and available for Windows, Linux, and macOS and licensed under an open source Common Public Attribution (CPAL) license. The ProjectLibre team is currently working on a Web offering called ProjectLibre Cloud under a proprietary license.
* **Best for:** An individual project manager running small to midsized projects or as a viewer for project members who don't have a full MS-Project license
* **Unique selling proposition:** It's the closest you can get to MS-Project with open source.
### GanttProject 2.8.11
![GanttProject][13]
(Frank Bergmann, [CC BY-SA 4.0][5])
[GanttProject][14] is similar to ProjectLibre as a desktop Gantt editor but with a more limited feature set. It doesn't support baselines nor non-human resources, and the reporting functionality is more limited.
GanttProject is a desktop application written in Java and available for Windows, Linux, and macOS under the GPLv3 license.
* **Best for:** Simple Gantt charts or learning Gantt-based project management techniques.
* **Unique selling proposition:** It supports program evaluation and review technique ([PERT][15]) charts and collaboration using WebDAV.
### TaskJuggler 3.7.1
![TaskJuggler][16]
(Frank Bergmann, [CC BY-SA 4.0][5])
[TaskJuggler][17] schedules multiple parallel projects in large organizations, focusing on automatically resolving resource assignment conflicts (i.e., resource leveling).
It is not an interactive Gantt editor but a command-line tool that works similarly to a compiler: It reads a list of tasks from a text file and produces a series of reports with the optimum start and end times for each task depending on the assigned resources, dependencies, priorities, and many other parameters. It supports multiple projects, baselines, resource calendars, shifts, and time zones and has been designed to scale to enterprise scenarios with many projects and resources.
Writing a TaskJuggler input file with its specific syntax may be beyond the average project manager's capabilities. However, you can use ]project-open[ as a graphical frontend for TaskJuggler to generate input, including absences, task progress, and logged hours. When used this way, TaskJuggler becomes a powerful what-if scenario planner.
TaskJuggler is written in Ruby and available for Windows, Linux, and macOS under a GPLv2 license.
* **Best for:** Medium to large departments managed by a true nerd
* **Unique selling proposition:** It excels in automatic resource-leveling.
### ProjeQtOr 9.0.4
![ProjeQtOr][18]
(Frank Bergmann, [CC BY-SA 4.0][5])
[ProjeQtOr][19] is a web-based project management application that's suitable for IT projects. It supports risks, budgets, deliverables, and financial documents in addition to projects, tickets, and activities to integrate many aspects of project management into a single system.
ProjeQtOr provides a Gantt editor with a feature set similar to ProjectLibre, including hierarchical tasks, dependencies, and scheduling based on planned work and assigned resources. However, it doesn't support in-place editing of values (e.g., task name, estimated time, etc.); users must change values in an entry form below the Gantt view and save the values.
ProjeQtOr is written in PHP and available for Windows, Linux, and macOS under the Affero GPL3 license.
* **Best for:** IT departments tracking a list of projects
* **Unique selling proposition:** Lets you store a wealth of information for every project, keeping all information in one place.
### Other tools
The following systems may be valid options for specific use cases but were excluded from the main list for various reasons.
![LIbrePlan][20]
(Frank Bergmann, [CC BY-SA 4.0][5])
* [**LibrePlan**][21] is a web-based project management application focusing on Gantt charts. It would have figured prominently in the list above due to its feature set, but there is no installation available for recent Linux versions (CentOS 7 or 8). The authors say updated instructions will be available soon.
* [**dotProject**][22] is a web-based project management system written in PHP and available under the GPLv2.x license. It includes a Gantt timeline report, but it doesn't have options to edit it, and dependencies don't work yet (they're "only partially functional").
* [**Leantime**][23] is a web-based project management system with a pretty GUI written in PHP and available under the GPLv2 license. It includes a Gantt timeline for milestones but without dependencies.
* [**Orangescrum**][24] is a web-based project-management tool. Gantt charts are available as a paid add-on or with a paid subscription.
* [**Talaia/OpenPPM**][25] is a web-based project portfolio management system. However, version 4.6.1 still says "Coming Soon: Interactive Gantt Charts."
* [**Odoo**][26] and [**OpenProject**][27] both restrict some important features to the paid enterprise edition.
In this review, I aimed to include all open source project management systems that include a Gantt editor with dependency scheduling. If I missed a project or misrepresented something, please let me know in the comments.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/open-source-project-management
作者:[Frank Bergmann][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/fraber
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/kanban_trello_organize_teams_520.png?itok=ObNjCpxt (Kanban-style organization action)
[2]: https://en.wikipedia.org/wiki/Gantt_chart
[3]: https://opensource.com/article/20/3/agiles-vs-waterfall
[4]: https://opensource.com/sites/default/files/uploads/redmine.png (Redmine)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://www.redmine.org/
[7]: https://redmine.org/plugins/plus_gantt
[8]: https://www.redmine.org/plugins/anko_gantt_chart
[9]: https://opensource.com/sites/default/files/uploads/project-open.png (]project-open[)
[10]: https://www.project-open.com
[11]: https://opensource.com/sites/default/files/uploads/projectlibre.png (ProjectLibre)
[12]: http://www.projectlibre.org
[13]: https://opensource.com/sites/default/files/uploads/ganttproject.png (GanttProject)
[14]: https://www.ganttproject.biz
[15]: https://en.wikipedia.org/wiki/Program_evaluation_and_review_technique
[16]: https://opensource.com/sites/default/files/uploads/taskjuggler.png (TaskJuggler)
[17]: https://taskjuggler.org/
[18]: https://opensource.com/sites/default/files/uploads/projeqtor.png (ProjeQtOr)
[19]: https://www.projeqtor.org
[20]: https://opensource.com/sites/default/files/uploads/libreplan.png (LIbrePlan)
[21]: https://www.libreplan.dev/
[22]: https://dotproject.net/
[23]: https://leantime.io
[24]: https://orangescrum.org/
[25]: http://en.talaia-openppm.com/
[26]: https://odoo.com
[27]: http://openproject.org

View File

@ -0,0 +1,163 @@
[#]: subject: (Programming 101: Input and output with Java)
[#]: via: (https://opensource.com/article/21/3/io-java)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Programming 101: Input and output with Java
======
Learn how Java handles reading and writing data.
![Coffee beans and a cup of coffee][1]
When you write a program, your application may need to read from and write to files stored on the user's computer. This is common in situations when you want to load or store configuration options, you need to create log files, or your user wants to save work for later. Every language handles this task a little differently. This article demonstrates how to handle data files with Java.
### Installing Java
Regardless of your computer's platform, you can install Java from [AdoptOpenJDK][2]. This site offers safe and open source builds of Java. On Linux, you may also find AdoptOpenJDK builds in your software repository.
I recommend using the latest long-term support (LTS) release. The latest non-LTS release is best for developers looking to try the latest Java features, but it likely outpaces what most users have installed—either by default on their system or installed previously for some other Java application. Using the LTS release ensures you're up-to-date with what most users have installed.
Once you have Java installed, open your favorite text editor and get ready to code. You might also want to investigate an [integrated development environment for Java][3]. BlueJ is ideal for new programmers, while Eclipse and Netbeans are nice for intermediate and experienced coders.
### Reading a file with Java
Java uses the `File` library to load files.
This example creates a class called `Ingest` to read data from a file. When you open a file in Java, you create a `Scanner` object, which scans the file you provide, line by line. In fact, a `Scanner` is the same concept as a cursor in a text editor, and you can control that "cursor" for reading and writing with `Scanner` methods like `nextLine`:
```
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Ingest {
  public static void main([String][4][] args) {
   
      try {
          [File][5] myFile = new [File][5]("example.txt");
          Scanner myScanner = new Scanner(myFile);
          while (myScanner.hasNextLine()) {
              [String][4] line = myScanner.nextLine();
              [System][6].out.println(line);
          }
          myScanner.close();
      } catch ([FileNotFoundException][7] ex) {
          ex.printStackTrace();  
      } //try
    } //main
} //class
```
This code creates the variable `myfile` under the assumption that a file named `example.txt` exists. If that file does not exist, Java "throws an exception" (this means it found an error in what you attempted to do and says so), which is "caught" by the very specific `FileNotFoundException` library. The fact that there's a library specific to this exact error betrays how common this error is.
Next, it creates a `Scanner` and loads the file into it. I call it `myScanner` to differentiate it from its generic class template. A `while` loop sends `myScanner` over the file, line by line, for as long as there _is_ a next line. That's what the `hasNextLine` method does: it detects whether there's any data after the "cursor." You can simulate this by opening a file in a text editor: Your cursor starts at the very beginning of the file, and you can use the keyboard to scan through the file with the cursor until you run out of lines.
The `while` loop creates a variable `line` and assigns it the data of the current line. Then it prints the contents of `line` just to provide feedback. A more useful program would probably parse each line to extract whatever important data it contains.
At the end of the process, the `myScanner` object closes.
### Running the code
Save your code as `Ingest.java` (it's a Java convention to give classes an initial capital letter and name the file to match). If you try to run this simple application, you will probably receive an error because there is no `example.txt` for the application to load yet:
```
$ java ./Ingest.java
java.io.[FileNotFoundException][7]:
example.txt (No such file or directory)
```
What a perfect opportunity to write a Java application that writes data to a file!
### Writing data to a file with Java
Whether you're storing data that your user creates with your application or just metadata about what a user did in an application (for instance, game saves or recent songs played), there are lots of good reasons to store data for later use. In Java, this is achieved through the `FileWriter` library, this time by opening a file, writing data into it, and then closing the file:
```
import java.io.FileWriter;
import java.io.IOException;
public class Exgest {
  public static void main([String][4][] args) {
    try {
        [FileWriter][8] myFileWriter = new [FileWriter][8]("example.txt", true);
        myFileWriter.write("Hello world\n");
        myFileWriter.close();
    } catch ([IOException][9] ex) {
        [System][6].out.println(ex);
    } // try
  } // main
}
```
The logic and flow of this class are similar to reading a file. Instead of a `Scanner`, it creates a `FileWriter` object with the name of a file. The `true` flag at the end of the `FileWriter` statement tells `FileWriter` to _append_ text to the end of the file. To overwrite a file's contents, remove the `true`:
```
`FileWriter myFileWriter = new FileWriter("example.txt", true);`
```
Because I'm writing plain text into a file, I added my own newline character (`\n`) at the end of the data (`Hello world`) written into the file.
### Trying the code
Save this code as `Exgest.java`, following the Java convention of naming the file to match the class name.
Now that you have the means to create and read data with Java, you can try your new applications, in reverse order:
```
$ java ./Exgest.java
$ java ./Ingest.java
Hello world
$
```
Because it appends data to the end, you can repeat your application to write data as many times as you want to add more data to your file:
```
$ java ./Exgest.java
$ java ./Exgest.java
$ java ./Exgest.java
$ java ./Ingest.java
Hello world
Hello world
Hello world
$
```
### Java and data
You're don't write raw text into a file very often; in the real world, you probably use an additional library to write a specific format instead. For instance, you might use an XML library to write complex data, an INI or YAML library to write configuration files, or any number of specialized libraries to write binary formats like images or audio.
For full information, refer to the [OpenJDK documentation][10].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/io-java
作者:[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/java-coffee-mug.jpg?itok=Bj6rQo8r (Coffee beans and a cup of coffee)
[2]: https://adoptopenjdk.net
[3]: https://opensource.com/article/20/7/ide-java
[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
[5]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+file
[6]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
[7]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filenotfoundexception
[8]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filewriter
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+ioexception
[10]: https://access.redhat.com/documentation/en-us/openjdk/11/

View File

@ -0,0 +1,73 @@
[#]: subject: (Track aircraft with a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/tracking-flights-raspberry-pi)
[#]: author: (Patrick Easters https://opensource.com/users/patrickeasters)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Track aircraft with a Raspberry Pi
======
Explore the open skies with a Raspberry Pi, an inexpensive radio, and
open source software.
![Airplane flying with a globe background][1]
I live near a major airport, and I frequently hear aircraft flying over my house. I also have a curious preschooler, and I find myself answering questions like, "What's that?" and "Where's that plane going?" often. While a quick internet search could answer these questions, I wanted to see if I could answer them myself.
With a Raspberry Pi, an inexpensive radio, and open source software, I can track aircraft as far as 200 miles from my house. Whether you're answering relentless questions from your kids or are just curious about what's in the sky above you, this is something you can try, too.
![Flight map][2]
(Patrick Easters, [CC BY-SA 4.0][3])
### The protocol behind it all
[ADS-B][4] is a technology that aircraft use worldwide to broadcast their location. Aircraft use position data gathered from GPS and periodically broadcast it along with speed and other telemetry so that other aircraft and ground stations can track their position.
Since this protocol is well-known and unencrypted, there are many solutions to receive and parse it, including many that are open source.
### Gathering the hardware
Pretty much any [Raspberry Pi][5] will work for this project. I've used an older Pi 1 Model B, but I'd recommend a Pi 3 or newer to ensure you can keep up with the stream of decoded ADS-B messages.
To receive the ADS-B signals, you need a software-defined radio. Thanks to ultra-cheap radio chips designed for TV tuners, there are quite a few cheap USB receivers to choose from. I use [FlightAware's ProStick Plus][6] because it has a built-in filter to weaken signals outside the 1090MHz band used for ADS-B. Filtering is important since strong signals, such as broadcast FM radio and television, can desensitize the receiver. Any receiver based on RTL-SDR should work.
You will also need an antenna for the receiver. The options are limitless here, ranging from the [more adventurous DIY options][7] to purchasing a [ready-made 1090MHz antenna][8]. Whichever route you choose, antenna placement matters most. ADS-B reception is line-of-sight, so you'll want your antenna to be as high as possible to extend your range. I have mine in my attic, but I got decent results from my house's upper floor.
### Visualizing your data with software
Now that your Pi is equipped to receive ADS-B signals, the real magic happens in the software. Two of the most commonly used open source software projects for ADS-B are [readsb][9] for decoding ADS-B messages and [tar1090][10] for visualization. Combining both provides an interactive map showing all the aircraft your Pi is tracking.
Both projects provide setup instructions, but using a prebuilt image like the [ADSBx Custom Pi Image][11] is the fastest way to get going. The ADSBx image even configures a Prometheus instance with custom metrics like aircraft count.
### Keep experimenting
If the novelty of tracking airplanes with your Raspberry Pi wears off, there are plenty of ways to keep experimenting. Try different antenna designs or find the best antenna placement to maximize the number of aircraft you see.
These are just a few of the ways to track aircraft with your Pi, and hopefully, this inspires you to try it out and learn a bit about the world of radio. Happy tracking!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/tracking-flights-raspberry-pi
作者:[Patrick Easters][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/patrickeasters
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/plane_travel_world_international.png?itok=jG3sYPty (Airplane flying with a globe background)
[2]: https://opensource.com/sites/default/files/uploads/flightmap.png (Flight map)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://en.wikipedia.org/wiki/Automatic_Dependent_Surveillance%E2%80%93Broadcast
[5]: https://www.raspberrypi.org/
[6]: https://www.amazon.com/FlightAware-FA-PROSTICKPLUS-1-Receiver-Built-Filter/dp/B01M7REJJW
[7]: http://www.radioforeveryone.com/p/easy-homemade-ads-b-antennas.html
[8]: https://www.amazon.com/s?k=1090+antenna+sma&i=electronics&ref=nb_sb_noss_2
[9]: https://github.com/wiedehopf/readsb
[10]: https://github.com/wiedehopf/tar1090
[11]: https://www.adsbexchange.com/how-to-feed/adsbx-custom-pi-image/

View File

@ -0,0 +1,107 @@
[#]: subject: (Use gdu for a Faster Disk Usage Checking in Linux Terminal)
[#]: via: (https://itsfoss.com/gdu/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Use gdu for a Faster Disk Usage Checking in Linux Terminal
======
There are two popular [ways to check disk usage in Linux terminal][1]: du command and df command. The [du command is more for checking the space used by a directory][2] and the df command gives you the disk utilization on filesystem level.
There are more friendly [ways to see the disk usage in Linux with graphical tools like GNOME Disks][3]. If you are confined to the terminal, you can use a [TUI][4] tool like [ncdu][5] to get the disk usage information with a sort of graphical touch.
### Gdu: Disk usage checking in Linux terminal
[Gdu][6] is such a tool written in Go (hence the g in gdu). Gdu developer has [benchmark tests][7] to show that it is quite fast for disk usage checking, specifically on SSDs. In fact, gdu is intended primarily for SSDs though it can work for HDD as well.
If you use the gdu command without any options, it shows the disk usage for the current directory you are in.
![][8]
Since it has terminal user interface (TUI), you can navigate through directories and disk using arrows. You can also sort the result by file names or size.
Heres how to do that:
* Up arrow or k to move cursor up
* Down arrow or j to move cursor down
* Enter to select directory / device
* Left arrow or h to go to parent directory
* Use d to delete the selected file or directory
* Use n to sort by name
* Use s to sort by size
* Use c to sort by items
Youll notice some symbols before some file entries. Those have specific meaning.
![][9]
* `!` means an error occurred while reading the directory.
* `.` means an error occurred while reading a subdirectory, size may not be correct.
* `@` means file is a symlink or socket.
* `H` means the file was already counted (hard link).
* `e` means directory is empty.
To see the disk utilization and free space for all mounted disks, use the option `d`:
```
gdu -d
```
It shows all the details in one screen:
![][10]
Sounds like a handy tool, right? Lets see how to get it on your Linux system.
### Installing gdu on Linux
Gdu is available for Arch and Manjaro users through the [AUR][11]. I presume that as an Arch user, you know how to use AUR.
It is included in the universe repository of the upcoming Ubuntu 21.04 but chances are that you are not using it at present. In that case, you may install it using Snap through it may seem like a lot of snap commands:
```
snap install gdu-disk-usage-analyzer
snap connect gdu-disk-usage-analyzer:mount-observe :mount-observe
snap connect gdu-disk-usage-analyzer:system-backup :system-backup
snap alias gdu-disk-usage-analyzer.gdu gdu
```
You may also find the source code on its release page:
[Source code download for gdu][12]
I am more used to of using du and df commands but I can see some Linux users might like gdu. Are you one of them?
--------------------------------------------------------------------------------
via: https://itsfoss.com/gdu/
作者:[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://linuxhandbook.com/df-command/
[2]: https://linuxhandbook.com/find-directory-size-du-command/
[3]: https://itsfoss.com/check-free-disk-space-linux/
[4]: https://itsfoss.com/gui-cli-tui/
[5]: https://dev.yorhel.nl/ncdu
[6]: https://github.com/dundee/gdu
[7]: https://github.com/dundee/gdu#benchmarks
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/gdu-disk-utilization.png?resize=800%2C471&ssl=1
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/gdu-entry-symbols.png?resize=800%2C302&ssl=1
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/gdu-disk-utilization-for-all-drives.png?resize=800%2C471&ssl=1
[11]: https://itsfoss.com/aur-arch-linux/
[12]: https://github.com/dundee/gdu/releases

View File

@ -0,0 +1,159 @@
[#]: collector: "lujun9972"
[#]: translator: "wyxplus"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: subject: "Managing processes on Linux with kill and killall"
[#]: via: "https://opensource.com/article/20/1/linux-kill-killall"
[#]: author: "Jim Hall https://opensource.com/users/jim-hall"
在 Linux 上使用 kill 和 killall 命令来管理进程
======
了解如何使用 pskill 和 killall 命令来终止进程并回收系统资源。
![Penguin with green background][1]
在Linux中每个程序和守护程序都是一个“进程”。 大多数进程代表一个正在运行的程序。 其他程序可以派生出其他进程,比如说有侦听某些事件的发生并对其做出响应的进程。 并且每个进程都需要申请内存空间和处理器使用权。你运行的进程越多,所需的内存和 CPU 使用周期就越多。在老式电脑(例如我使用了 7 年的笔记本电脑或轻量级计算机(例如树莓派)上,如果你关注过后台运行的进程,则可以充分利用你的系统。
你可以使用 **ps** 命令来查看正在运行的进程。你通常会使用 **ps** 命令的参数来显示出更多的输出信息。我喜欢使用 **-e** 参数来查看每个正在运行的进程,以及 **-f** 参数来获得每个进程的全部细节。以下是一些例子:
```
$ ps
PID TTY TIME CMD
88000 pts/0 00:00:00 bash
88052 pts/0 00:00:00 ps
88053 pts/0 00:00:00 head
[/code] [code]
$ ps -e | head
PID TTY TIME CMD
1 ? 00:00:50 systemd
2 ? 00:00:00 kthreadd
3 ? 00:00:00 rcu_gp
4 ? 00:00:00 rcu_par_gp
6 ? 00:00:02 kworker/0:0H-events_highpri
9 ? 00:00:00 mm_percpu_wq
10 ? 00:00:01 ksoftirqd/0
11 ? 00:00:12 rcu_sched
12 ? 00:00:00 migration/0
[/code] [code]
$ ps -ef | head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:51 ? 00:00:50 /usr/lib/systemd/systemd --switched-root --system --deserialize 36
root 2 0 0 13:51 ? 00:00:00 [kthreadd]
root 3 2 0 13:51 ? 00:00:00 [rcu_gp]
root 4 2 0 13:51 ? 00:00:00 [rcu_par_gp]
root 6 2 0 13:51 ? 00:00:02 [kworker/0:0H-kblockd]
root 9 2 0 13:51 ? 00:00:00 [mm_percpu_wq]
root 10 2 0 13:51 ? 00:00:01 [ksoftirqd/0]
root 11 2 0 13:51 ? 00:00:12 [rcu_sched]
root 12 2 0 13:51 ? 00:00:00 [migration/0]
```
最后的例子显示最多的细节。在每一行UID用户 ID表示进程所有者。PID进程 ID代表每个进程的 ID并且 PPID父进程 ID表示父进程的 ID。在任何 Unix 系统中,进程号是从 1 开始编号,内核启动后运行的第一个进程。在这里, **systemd** 是第一个进程,它产生了 **kthreadd**,而 **kthreadd** 创建其他进程,包括 **rcu_gp**, **rcu_par_gp** 和其他许多进程。
### 使用 kill 命令来管理进程
系统会关注大多数后台进程,所以你不必担心这些进程。你只需要关注那些你所运行应用所创建的进程。然而许多应用一次只运行一个进程(如音乐播放器、终端模拟器或游戏等),其他应用则可能产生后台进程。一些应用可能当你退出后还在后台运行,以便下次你使用的时候能快速启动。
当我运行 Chromium作为谷歌 Chrome 浏览器所基于的项目)时,进程管理便成了问题。 Chromium 在我的笔记本电脑上运行非常吃力,并产生了许多额外的进程。现在仅打开五个选项卡,我可以看到这些 Chromium 进程运行情况:
```
$ ps -ef | fgrep chromium
jhall 66221 [...] /usr/lib64/chromium-browser/chromium-browser [...]
jhall 66230 [...] /usr/lib64/chromium-browser/chromium-browser [...]
[...]
jhall 66861 [...] /usr/lib64/chromium-browser/chromium-browser [...]
jhall 67329 65132 0 15:45 pts/0 00:00:00 grep -F chromium
```
我已经省略一些,其中有 20 个 Chromium 进程和一个正在搜索 “chromium" 字符的 **grep** 进程。
```
$ ps -ef | fgrep chromium | wc -l
21
```
但是在我退出 Chromium 之后,这些进程仍旧运行。如何关闭它们并回收这些进程占用的内存和 CPU呢
**kill** 命令能让你终止一个进程。在最简单的情况下,你用 **kill** PID 命令来终止你想终止的进程。例如,要终止这些进程,我需要对 20 个 Chromium 进程 ID 都执行 **kill** 命令。一种方法是使用命令行获取 Chromium PID而另一种方法针对该列表运行 **kill**
```
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}'
66221
66230
66239
66257
66262
66283
66284
66285
66324
66337
66360
66370
66386
66402
66503
66539
66595
66734
66848
66861
69702
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}' &gt; /tmp/pids
$ kill $( cat /tmp/pids)
```
最后两行是关键。第一个命令行为 Chromium 浏览器生成一个进程 ID 列表。第二个命令行针对该进程 ID 列表运行 **kill** 命令。
### 介绍 killall 命令
一次终止多个进程有个更简单方法,使用 **killall** 命令。你或许可以根据名称猜测出,**killall **会终止所有与该名字匹配的进程。这意味着我们可以使用此命令来停止所有流氓 Chromium 进程。这很简单:
```
`$ killall /usr/lib64/chromium-browser/chromium-browser`
```
但是要小心使用 **killall**。该命令能够终止你所给出名称相匹配的所有进程。这就是为什么我喜欢先使用 **ps -ef** 命令来检查我正在运行的进程,然后针对要停止的命令的准确路径运行 **killall**
您可能会想使用 **-i** 或 **\--interactive** 参数,使得 **killkill** 会提示你想要停止每个进程。
**killall** 还支持使用 **-o** 或 **\--than-than** 参数来查找比特定时间更早的进程。例如,这将有助于你发现一组无人值守运行了几天的无赖进程。又或是,你可以查找比特定时间更迟的进程,例如您最近启动的高占用进程。使用 **-y** 或 **\--young-than** 参数来查找这些进程。
### 其他管理进程的方式
进程管理是系统维护重要的一部分。在我早期职业生涯中,作为 Unix 和 Linux 的系统管理员,杀死非法作业的能力是保持系统正常运行的关键。在如今,你可能不需要亲手在 Linux 上的终止恶意进程,但是知道 **kill****killall** 能够在最终出现问题时为你提供帮助。
你也能寻找其他方式来管理进程。对我而言,我不需要在我退出浏览器后,使用 **kill****killall** 来终止后台Chromium 进程。在 Chromium 中有个简单设置可以进行控制:
![Chromium background processes setting][2]
不过,始终关注系统上正在运行哪些进程,并且在需要的时候进行干预是一个明智之举。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/1/linux-kill-killall
作者:[Jim Hall][a]
选题:[lujun9972][b]
译者:[wyxplus](https://github.com/wyxplus)
校对:[校对者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/linux_penguin_green.png?itok=ENdVzW22 "Penguin with green background"
[2]: https://opensource.com/sites/default/files/uploads/chromium-settings-continue-running.png "Chromium background processes setting"

View File

@ -1,146 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (stevenzdg988)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Get started with Bash programming)
[#]: via: (https://opensource.com/article/20/4/bash-programming-guide)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
开始使用 Bash 编程
======
了解如何在 Bash 中编写定制程序以自动执行重复性操作任务。下载我们的新电子书以开始使用。
![命令行提示符][1]
对 Unix 的最初希望之一是授权给日常的计算机用户能够调整其计算机以适应其独特的工作风格。在过去的几十年中,对计算机定制的期望已经降低,许多用户考虑将他们收集的应用程序和网站作为他们的 “定制环境”。 原因之一是许多操作系统的组件未打开,因此普通用户无法使用其源代码。
但是对于Linux用户而言定制程序是可以实现的因为整个系统都基于可通过终端获得的命令。终端不仅是用于快速命令或彻底排除故障的接口也是一个脚本环境可以通过为您处理日常任务来减少您的工作量。
### 如何学习编程
如果您以前从未进行过任何编程,可能面临考虑两个不同的挑战:一个是了解怎样编写代码,另一个是了解编写的代码是什么。您可以学习 _语法_,但是如果您不知道 _语言_ 中有哪些可用的关键字,您将无法继续。在实践中,同时开始学习这两个概念,是因为如果没有关键字的整理就无法学习语法,因此,最初您将使用基础命令和基础编程结构编写简单的任务。一旦熟悉基础,就可以探索更多编程语言的内容,从而使您的程序能够做越来越重要的事情。
在 [Bash][2] 中,您使用的大多数 _关键字_ 是 Linux 命令。 _syntax_ 是 Bash。如果您已经频繁使用 Bash则向 Bash 编程的过渡相对容易。但是,如果您不曾使用过 Bash您会很高兴地学习到它是为清晰和简单而构建的简单语言。
### 交互设计
有时,学习编程时最难解决的事情就是计算机可以为您做些什么。显然,如果一台计算机可以自己完成你要做的所有操作,那么您就不必再触摸计算机了。但是现实是人类很重要。找到您的计算机可以帮助您的事情的关键是通知整个星期重复执行的任务。计算机对重复的处理特别好。
但是,为了能让(告诉)计算机为你做某事(执行某项操作),您必须知道怎么做。这是 Bash 擅长的领域:交互式编程。在终端中执行(命令)时,您还将学习如何编写脚本。
例如,我曾经负责将大量 PDF 书籍转换为低墨和友好打印的版本。一种方法是在 PDF 编辑器中打开 PDF 从数百张图像算作图像的页面背景和纹理中选择每张图像然后删除它们然后将其保存到新的PDF中。这样一本书只需要半天。从数百张图像中选择每张图像-页面背景和纹理记做图像-删除它们,然后将其保存到一个新的 PDF 文件中。这样一本书就要花半天时间。
我的第一个想法是学习如何编写 PDF 编辑器脚本,但是经过数天的研究,我找不到可以编写编辑 PDF 应用程序的脚本(鼠标自动化的外部技巧)。因此,我将注意力转向了从终端内部找出完成任务的方法。这导致了几个新发现,包括 GhostScriptPostScript 的开源版本(基于 PDF 的打印机语言)。通过使用 GhostScript 处理了几天的任务,我确认这是解决我的问题的方法。
制定基本的脚本来运行命令仅仅是关于复制命令和我用来从 PDF 中删除图像并将其粘贴到文本文件中的选项的问题。据推测,将文件作为脚本运行会产生相同的结果。
### 向 Bash 脚本传参数
在终端中运行命令与在 Shell 脚本中运行命令之间的区别在于前者是交互式的。在终端中,您可以随时进行调整。例如,如果我刚刚处理 **example_1.pdf** 并准备处理下一个文档,以适应我的命令,则只需要更改文件名即可。
Shell 脚本不是交互式的。实际上Shell _脚本_ 存在的唯一原因是不必亲自参与。这就是为什么命令(以及运行它们的 Shell 脚本)接受参数的原因。
在 Shell 脚本中,有一些预定义的可以反映脚本启动方式的变量。初始变量是 **$0**,它代表发出的启动脚本的命令。下一个变量是 **$1** ,它表示传递给 Shell 脚本的第一个 “参数”。例如,在命令 **echo hello** 中,命令 **echo****$0,**,关键字 **hello****$1**。在命令 **echo hello world** 中,命令 **echo****$0,**,关键字 **hello****$1**,而 **world****$2**。
在 Shell 中交互如下所示:
```
$ echo hello world
hello world
```
在非交互式 Shell 脚本中,您 _可以_ 以非常直观的方式执行相同的操作。将此文本输入文本文件并将其另存为**hello.sh**
```
`echo hello world`
```
执行这个脚本:
```
$ bash hello.sh
hello world
```
同样可以,但是并没有利用脚本可以接受输入这一优势。将 **hello.sh** 更改为:
```
`echo $1`
```
运行带有用引号将两个参数组合在一起的脚本:
```
$ bash hello.sh "hello bash"
hello bash
```
对于我的 PDF 缩减项目,我真的需要这种非交互性,因为每个 PDF 都花了几分钟来压缩。但是通过创建一个接受我的输入的脚本,我可以一次将几个 PDF 文件全部提交给脚本。该脚本按顺序处理了每个文件,这可能需要半小时或稍长一点时间,但是我可以用半小时来完成其他任务。
### 流控制
创建 Bash 脚本是完全可以接受的,从本质上讲,是你开始实现需要重复执行任务的准确过程的副本。但是,可以通过控制信息流的方式来使脚本更强大。管理脚本对数据响应的常用方法是:
* if/then 选择结构语句
* for 循环结构语句
* while 循环结构语句
* case 语句
计算机不是智能的,但是它们擅长比较和分析数据。如果您在脚本中构建一些数据分析,则脚本会变得更加智能。例如,基本的 **hello.sh** 脚本运行后不管有没有内容都会显示:
```
$ bash hello.sh foo
foo
$ bash hello.sh
$
```
如果在没有接收输入的情况下提供帮助消息,将会更加容易使用。如下是一个 `if/then` 语句,如果您以一种基本的方式使用 Bash则您可能不知道 Bash 中存在这样的语句。但是编程的一部分是学习语言,通过一些研究,您将了解 `if/then` 语句:
```
if [ "$1" = "" ]; then
        echo "syntax: $0 WORD"
        echo "If you provide more than one word, enclose them in quotes."
else
        echo "$1"
fi
```
运行新版本的 **hello.sh** 输出如下:
```
$ bash hello.sh
syntax: hello.sh WORD
If you provide more than one word, enclose them in quotes.
$ bash hello.sh "hello world"
hello world
```
### 利用脚本工作
无论您从PDF文件中查找要删除的图像还是要管理混乱的 Downloads (下载)文件夹,还是要创建和提供 Kubernetes 镜像,学习编写 Bash 脚本都需要先使用 Bash然后再学习采用这些从命令列表到响应输入内容的脚本的方法。通常这是一个发现的过程您一定会找到新的 Linux 命令来执行您无法想象的可以通过文本命令执行的任务,并且您将找到 Bash 的新功能以使您的脚本适应您想要的所有不同方式来执行。
学习这些技巧的一种方法是阅读其他人的脚本。了解人们如何在其系统上自动化死记硬背的命令。查看您熟悉的,并查找有关陌生事物的更多信息。
另一种方法是下载我们的 [Bash 编程入门][3] 电子书。它向您介绍了特定于 Bash 的编程概念,并且通过学习的构造,您可以开始构建自己的命令。当然,它是免费的,并根据 [创建共享][4] 许可证进行下载和分发许可,因此,请立即获取副本。
### [下载我们介绍利用 Bash 编程的电子书!][3]
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/4/bash-programming-guide
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[stevenzdg988](https://github.com/stevenzdg988)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
[2]: https://opensource.com/resources/what-bash
[3]: https://opensource.com/downloads/bash-programming-guide
[4]: https://opensource.com/article/20/1/what-creative-commons

View File

@ -1,300 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (stevenzdg988)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Improve your time management with Jupyter)
[#]: via: (https://opensource.com/article/20/9/calendar-jupyter)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
使用 Jupyter 改善你的时间管理
======
通过在 Jupyter 里使用 Python 分析日历了解您如何使用时间 。
![日历特写快照][1]
[Python][2] 在用于探索数据方面具有令人难以置信的可扩展性选项。利用 [Pandas][3] 或 [Dask][4],您可以将 [Jupyter][5] 扩展到大数据(处理)。但是小数据呢?个人资料?私人数据?
JupyterLab 和 Jupyter Notebook 提供了一个绝佳的环境来仔细检查我基于笔记本电脑的生活。
我的探索是基于以下事实:我使用的几乎每个服务都有一个 Web 应用程序编程接口API。我使用了许多此类服务待办事项列表时间跟踪器习惯跟踪器等。但是几乎每个人都使用_日历_。相同的想法可以应用于其他服务但是日历具有一个很酷的功能几乎所有网络日历都支持的开放标准 `CalDAV`
### 在 Jupyter 中使用 Python 解析日历
大多数日历提供了导出为 `CalDAV` 格式的方法。您可能需要某种身份验证才能访问此私有数据。按照您的服务说明进行操作即可。如何获得凭据取决于您的服务,但是最终,您应该能够将它们存储在文件中。我将我的名为 `.caldav` 的文件存储在根(root)目录中:
```
import os
with open(os.path.expanduser("~/.caldav")) as fpin:
    username, password = fpin.read().split()
```
切勿将用户名和密码直接放在笔记本中!他们可能会很容易因 `git push` 偏离而导致泄漏。
下一步是使用方便的 PyPI [caldav][6] 库。我在 CalDAV 服务器上查找了我的电子邮件服务(您可能有所不同):
```
import caldav
client = caldav.DAVClient(url="<https://caldav.fastmail.com/dav/>", username=username, password=password)
```
CalDAV 有一个称为 `principal`(主键) 的概念。马上进入(该系统)并不重要,除非这是您用于访问日历:
```
principal = client.principal()
calendars = principal.calendars()
```
日历按照字面讲是关于时间的。访问事件之前,您需要确定一个时间范围。默认设置为一星期:
```
from dateutil import tz
import datetime
now = datetime.datetime.now(tz.tzutc())
since = now - datetime.timedelta(days=7)
```
大多数人使用不止一个日历,并且希望所有事件都在一起。`itertools.chain.from_iterable` (方法)使这一过程变得简单:` `
```
import itertools
raw_events = list(
    itertools.chain.from_iterable(
        calendar.date_search(start=since, end=now, expand=True)
        for calendar in calendars
    )
)
```
将所有事件读入内存很重要,以 API 原始的本地格式进行操作是重要的做法。这意味着在调整解析,分析和显示代码时,无需返回到 API 服务刷新数据。
但 “原始” 并不是轻描淡写。事件通过特定格式的字符串实现:
```
`print(raw_events[12].data)`[/code] [code]
    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//CyrusIMAP.org/Cyrus
     3.3.0-232-g4bdb081-fm-20200825.002-g4bdb081a//EN
    BEGIN:VEVENT
    DTEND:20200825T230000Z
    DTSTAMP:20200825T181915Z
    DTSTART:20200825T220000Z
    SUMMARY:Busy
    UID:
     1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000
     000000010000000CD71CC3393651B419E9458134FE840F5
    END:VEVENT
    END:VCALENDAR
```
幸运的是PyPI 再次使用另一个帮助程序库 [vobject][7] 前来解围:
```
import io
import vobject
def parse_event(raw_event):
    data = raw_event.data
    parsed = vobject.readOne(io.StringIO(data))
    contents = parsed.vevent.contents
    return contents
[/code] [code]`parse_event(raw_events[12])`[/code] [code]
    {'dtend': [&lt;DTEND{}2020-08-25 23:00:00+00:00&gt;],
     'dtstamp': [&lt;DTSTAMP{}2020-08-25 18:19:15+00:00&gt;],
     'dtstart': [&lt;DTSTART{}2020-08-25 22:00:00+00:00&gt;],
     'summary': [&lt;SUMMARY{}Busy&gt;],
     'uid': [&lt;UID{}1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000000000010000000CD71CC3393651B419E9458134FE840F5&gt;]}
```
好吧,至少好一点了。
仍有一些工作要做,以将其转换为合理的 Python 对象。第一步是 _拥有_ 一个合理的 Python 对象。[attrs][8] 库提供了一个不错的开始:
```
import attr
from __future__ import annotations
@attr.s(auto_attribs=True, frozen=True)
class Event:
    start: datetime.datetime
    end: datetime.datetime
    timezone: Any
    summary: str
```
是时候编写转换代码了!
第一个抽象在没有所有修饰的情况下从解析字典中获取值:
```
def get_piece(contents, name):
    return contents[name][0].value
[/code] [code]`get_piece(_, "dtstart")`[/code] [code]`    datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc())`
```
日历事件总是有一个开始,有一个“结束”,有一个 “持续时间”。一些谨慎的解析逻辑可以将两者协调为同一个 Python 对象:
```
def from_calendar_event_and_timezone(event, timezone):
    contents = parse_event(event)
    start = get_piece(contents, "dtstart")
    summary = get_piece(contents, "summary")
    try:
        end = get_piece(contents, "dtend")
    except KeyError:
        end = start + get_piece(contents, "duration")
    return Event(start=start, end=end, summary=summary, timezone=timezone)
```
由于将事件放在 _本地_ 时区而不是 UTC 中很有用,因此使用本地时区:
```
`my_timezone = tz.gettz()`[/code] [code]`from_calendar_event_and_timezone(raw_events[12], my_timezone)`[/code] [code]`    Event(start=datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc()), end=datetime.datetime(2020, 8, 25, 23, 0, tzinfo=tzutc()), timezone=tzfile('/etc/localtime'), summary='Busy')`
```
既然事件是真实的Python对象那么它们实际上应该具有附加信息。 幸运的是,将方法添加到类中是可能的。
但是弄清楚哪个事件发生在哪一天不是很明显。您需要在 _本地_ 时区中选择一天:
```
def day(self):
    offset = self.timezone.utcoffset(self.start)
    fixed = self.start + offset
    return fixed.date()
Event.day = property(day)
[/code] [code]`print(_.day)`[/code] [code]`    2020-08-25`
```
事件始终在内部表示为开始/结束,但是知道持续时间是有用的属性。持续时间也可以添加到现有类中:
```
def duration(self):
    return self.end - self.start
Event.duration = property(duration)
[/code] [code]`print(_.duration)`[/code] [code]`    1:00:00`
```
现在到了将所有事件转换为有用的 Python 对象了:
```
all_events = [from_calendar_event_and_timezone(raw_event, my_timezone)
              for raw_event in raw_events]
```
全天事件是一种特例,可能对分析生活没有多大用处。现在,您可以忽略它们:
```
# ignore all-day events
all_events = [event for event in all_events if not type(event.start) == datetime.date]
```
事件具有自然顺序——知道哪个事件最先发生可能有助于分析:
```
`all_events.sort(key=lambda ev: ev.start)`
```
现在,事件已排序,可以将它们加载到每天:
```
import collections
events_by_day = collections.defaultdict(list)
for event in all_events:
    events_by_day[event.day].append(event)
```
这样,您就可以将带有日期,持续时间和序列的日历事件作为 Python 对象。
### 用 Python 报到你的生活
现在是时候编写报告代码了!带有适当的标题,列表,重要内容以粗体显示令人惊奇的格式是很有趣的。
这就是 HTML 和 HTML 模板。我喜欢使用 [Chameleon(变色龙:动态的)][9]
```
template_content = """
&lt;html&gt;&lt;body&gt;
&lt;div tal:repeat="item items"&gt;
&lt;h2 tal:content="item[0]"&gt;Day&lt;/h2&gt;
&lt;ul&gt;
    &lt;li tal:repeat="event item[1]"&gt;&lt;span tal:replace="event"&gt;Thing&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/body&gt;&lt;/html&gt;"""
```
Chameleon 的一个很酷的功能是使用 `html` 方法渲染对象。我将以两种方式使用它:
* 摘要将以 **bold** (**粗体**)显示
* 对于大多数活动,我都会删除摘要(因为这是我的个人信息)
```
def __html__(self):
    offset = my_timezone.utcoffset(self.start)
    fixed = self.start + offset
    start_str = str(fixed).split("+")[0]
    summary = self.summary
    if summary != "Busy":
        summary = "&amp;lt;REDACTED&amp;gt;"
    return f"&lt;b&gt;{summary[:30]}&lt;/b&gt; \-- {start_str} ({self.duration})"
Event.__html__ = __html__
```
为了简洁起见,该报告将切成每天的。
```
import chameleon
from IPython.display import HTML
template = chameleon.PageTemplate(template_content)
html = template(items=itertools.islice(events_by_day.items(), 3, 4))
HTML(html)
```
#### 渲染后,它将看起来像这样:
#### 2020-08-25
* **&lt;编辑&gt;** \-- 2020-08-25 08:30:00 (0:45:00)
* **&lt;编辑&gt;** \-- 2020-08-25 10:00:00 (1:00:00)
* **&lt;编辑&gt;** \-- 2020-08-25 11:30:00 (0:30:00)
* **&lt;编辑&gt;** \-- 2020-08-25 13:00:00 (0:25:00)
* **Busy** \-- 2020-08-25 15:00:00 (1:00:00)
* **&lt;编辑&gt;** \-- 2020-08-25 15:00:00 (1:00:00)
* **&lt;编辑&gt;** \-- 2020-08-25 19:00:00 (1:00:00)
* **&lt;编辑&gt;** \-- 2020-08-25 19:00:12 (1:00:00)
### Python 和 Jupyter 的无穷选择
通过解析,分析和报告各种 Web 服务所拥有的数据,这只是您可以做的事情的表面。
为什么不尝试使用您最喜欢的服务呢?
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/9/calendar-jupyter
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[stevenzdg988](https://github.com/stevenzdg988)
校对:[校对者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/calendar.jpg?itok=jEKbhvDT (Calendar close up snapshot)
[2]: https://opensource.com/resources/python
[3]: https://pandas.pydata.org/
[4]: https://dask.org/
[5]: https://jupyter.org/
[6]: https://pypi.org/project/caldav/
[7]: https://pypi.org/project/vobject/
[8]: https://opensource.com/article/19/5/python-attrs
[9]: https://chameleon.readthedocs.io/en/latest/

View File

@ -0,0 +1,187 @@
[#]: subject: (5 surprising things you can do with LibreOffice from the command line)
[#]: via: (https://opensource.com/article/21/3/libreoffice-command-line)
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
你可以在命令行上用 LibreOffice 做 5 件令人惊讶的事情
======
直接在命令行中对文件进行转换、打印、保护等操作。
![hot keys for shortcuts or features on computer keyboard][1]
LibreOffice 拥有所有你想要的办公软件套件的生产力功能,使其成为微软 Office 或谷歌套件的流行的开源替代品。LibreOffice 的能力之一是可以从命令行操作。例如Seth Kenlon 最近解释了如何使用 LibreOffice 用全局[命令行选项将多个文件][2]从 DOCX 转换为 EPUB。他的文章启发我分享一些其他 LibreOffice 命令行技巧和窍门。
在查看 LibreOffice 命令的一些隐藏功能之前,你需要了解如何使用应用选项。并不是所有的应用都接受选项(除了像 `--help`选项这样的基本选项,它在大多数 Linux 应用中都可以使用)。
```
`$ libreoffice --help`
```
这将返回 LibreOffice 接受的其他选项的描述。有些应用没有太多选项,但 LibreOffice 好几页有用的,所以有很多东西可以玩。
就是说,你可以在终端上使用 LibreOffice 进行以下五项有用的操作,来让使软件更加有用。
### 1\. 自定义你的启动选项
你可以修改你启动 LibreOffice 的方式。例如,如果你想只打开 LibreOffice 的文字处理器组件:
```
`$ libreoffice --writer  #starts the word processor`
```
你可以类似地打开它的其他组件:
```
$ libreoffice --calc  #starts the Calc document
$ libreoffice --draw  #starts an empty Draw document
$ libreoffice --web  #starts and empty HTML document
```
你也可以从命令行访问特定的帮助文件:
```
`$ libreoffice --helpwriter`
```
![LibreOffice Writer help][3]
Don Watkins, [CC BY-SA 4.0][4]
或者如果你需要电子表格应用方面的帮助:
```
`$ libreoffice --helpcalc`
```
你可以在没有启动屏幕的情况下启动 LibreOffice
```
`$ libreoffice --writer --nologo`
```
你甚至可以在你完成当前窗口的工作时,让它在后台最小化:
```
`$ libreoffice --writer --minimized`
```
### 2\. 以只读模式打开一个文件
你可以使用 `--view` 以只读模式打开文件,以防止意外地对重要文件进行修改和保存:
```
`$ libreoffice --view example.odt`
```
### 3\. 打开一个模板文档
你是否曾经创建过用作信头或发票表格的文档LibreOffice 具有丰富的内置模板系统,但是你可以使用 -n 选项将任何文档作为模板:
```
`$ libreoffice --writer -n example.odt`
```
你的文档将在 LibreOffice 中打开,你可以对其进行修改,但保存时不会覆盖原始文件。
### 4\. 转换文档
当你需要做一个小任务,比如将一个文件转换为新的格式时,应用启动的时间可能与完成任务的时间一样长。解决办法是 `--headless` 选项,它可以在不启动图形用户界面的情况下执行 LibreOffice 进程。
例如,在 LibreOffic 中,将一个文档转换为 EPUB 是一个非常简单的任务,但使用 `libreoffice` 命令就更容易:
```
`$ libreoffice --headless --convert-to epub example.odt`
```
使用通配符意味着你可以一次转换几十个文档:
```
`$ libreoffice --headless --convert-to epub *.odt`
```
你可以将文件转换为多种格式,包括 PDF、HTML、DOC、DOCX、EPUB、纯文本等。
### 5\. 从终端打印
你可以从命令行打印 LibreOffice 文档,而无需打开应用:
```
`$ libreoffice --headless -p example.odt`
```
这个选项不需要打开 LibreOffice 就可以使用默认打印机打印,它只是将文档发送到你的打印机。
要打印一个目录中的所有文件:
```
`$ libreoffice -p *.odt`
```
(我不止一次执行了这个命令,然后用完了纸,所以在你开始之前,确保你的打印机里有足够的纸张。)
你也可以把文件输出成 PDF。通常这和使用 `--convert-to-pdf` 选项没有什么区别,但是很容易记住:
```
`$ libreoffice --print-to-file example.odt --headless`
```
### 额外技巧Flatpak 和命令选项
如果你使用 [Flatpak][5] 安装 LibreOffice所有这些命令选项都可以使用但你必须通过 Flatpak 传递。下面是一个例子:
```
`$ flatpak run org.libreoffice.LibreOffice --writer`
```
它比本地安装要麻烦得多,所以你可能会受到启发[写一个 Bash 别名][6]来使它更容易直接与 LibreOffice 交互。
### 令人惊讶的终端选项
通过查阅手册页面,了解如何从命令行扩展 LibreOffice 的功能:
```
`$ man libreoffice`
```
你是否知道 LibreOffice 具有如此丰富的命令行选项? 你是否发现了其他人似乎都不了解的其他选项? 请在评论中分享它们!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/libreoffice-command-line
作者:[Don Watkins][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/don-watkins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/shortcut_command_function_editing_key.png?itok=a0sEc5vo (hot keys for shortcuts or features on computer keyboard)
[2]: https://opensource.com/article/21/2/linux-workday
[3]: https://opensource.com/sites/default/files/uploads/libreoffice-help.png (LibreOffice Writer help)
[4]: https://creativecommons.org/licenses/by-sa/4.0/
[5]: https://www.libreoffice.org/download/flatpak/
[6]: https://opensource.com/article/19/7/bash-aliases

View File

@ -0,0 +1,87 @@
[#]: subject: (Track your family calendar with a Raspberry Pi and a low-power display)
[#]: via: (https://opensource.com/article/21/3/family-calendar-raspberry-pi)
[#]: author: (Javier Pena https://opensource.com/users/jpena)
[#]: collector: (lujun9972)
[#]: translator: (wyxplus)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
利用树莓派和低功耗显示器来显示你家的日程表
======
通过利用开源工具和电子水墨屏,让每个人都清楚你家庭的日程安排。
![Calendar with coffee and breakfast][1]
有些家庭的日程安排很复杂:孩子们有上学活动和放学后的活动,你想要记住的重要事情、许多会议等等。虽然你可以使用手机和应用程序来关注所有事情,但在家中放置大型低功耗显示器以显示家人的日程不是更好吗? 电子水墨日程表刚好满足!
![E Ink calendar][2]
(Javier Pena, [CC BY-SA 4.0][3])
### 硬件
这个项目是作为假日项目开始,因此我试着尽可能多的旧物利用。其中包括一台已经闲置了太长时间树莓派 2。由于我没有电子水墨屏因此我需要购买一个。幸运的是我找到了一家供应商该供应商为树莓派的屏幕提供了 [开源驱动程序和示例][4],该屏幕使用 [GPIO][5] 端口连接。
我的家人还想在不同的日程表之间切换,因此需要某种形式的输入。我没有添加 USB 键盘,而是选择了一种更简单的解决方案,并购买了一个类似于在 [这篇文章][6] 中所描述 1x4 大小的键盘。这使我可以将键盘连接到树莓派中的某些 GPIO 端口。
最后,我需要一个相框来容纳整个设置。虽然背面看起来有些凌乱,但也能搞定。
![Calendar internals][7]
(Javier Pena, [CC BY-SA 4.0][3])
### 软件
我从 [一个类似的项目][8] 中获得了灵感,并开始为我的项目编写 Python 代码。我需要从两个地方获取数据:
* 天气信息:从 [OpenWeather API][9] 获取
* 时间信息:我打算使用 [CalDav standard][10] 连接到一个运行在我家服务器上日程表
由于必须等待一些零件的送达,因此我使用了模块化的方法来进行输入和显示,这样我可以在没有硬件的情况下调试大多数代码。日程表应用程序需要驱动程序,于是我编写了 [Pygame][11] 驱动程序以便能在台式机上运行它。
重构现有的开源项目是编码的最高效的方式。因为调用许多的 API 会减轻编码压力。我可以专注于设计用户界面,其中包括每人每周和每个人的每日的日程,以及允许使用小键盘来选择日程。并且我花时间又添加了一些额外的功能,例如特殊日子的自定义屏幕保护程序。
![E Ink calendar screensaver][12]
(Javier Pena, [CC BY-SA 4.0][3])
最后的集成步骤将确保我的日程表应用程序将在启动时运行,并且能够容错。我使用了原始的 [树莓派系统][13] 映像并将该应用程序配置到 systemd 服务,以便它可以在出现故障和系统重新启动依旧运行。
做完所有工作,我把代码上传到了 [GitHub][14]。因此,如果你要创建类似的日历,可以随时查看并重构它!
### 结论
日程表已成为我们厨房中的日常工具。它可以帮助我们记住我们的日常活动,甚至我们的孩子在上学前,都可以使用它来查看日程的安排。
对我而言这个项目让我感受到开源的力量。如果没有开源的驱动程序、库以及API我们依旧还在用纸和笔来安排日程。很疯狂不是吗
需要确保你的日程不冲突吗?学习如何使用这些免费的开源项目来做到这点。
via: https://opensource.com/article/21/3/family-calendar-raspberry-pi
作者:[Javier Pena][a]
选题:[lujun9972][b]
译者:[wyxplus](https://github.com/wyxplus)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jpena
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calendar-coffee.jpg?itok=9idm1917 "Calendar with coffee and breakfast"
[2]: https://opensource.com/sites/default/files/uploads/calendar.jpg "E Ink calendar"
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://github.com/waveshare/e-Paper
[5]: https://opensource.com/article/19/3/gpio-pins-raspberry-pi
[6]: https://www.instructables.com/1x4-Membrane-Keypad-w-Arduino/
[7]: https://opensource.com/sites/default/files/uploads/calendar_internals.jpg "Calendar internals"
[8]: https://github.com/zli117/EInk-Calendar
[9]: https://openweathermap.org
[10]: https://en.wikipedia.org/wiki/CalDAV
[11]: https://github.com/pygame/pygame
[12]: https://opensource.com/sites/default/files/uploads/calendar_screensaver.jpg "E Ink calendar screensaver"
[13]: https://www.raspberrypi.org/software/
[14]: https://github.com/javierpena/eink-calendar

View File

@ -0,0 +1,89 @@
[#]: subject: (Set up network parental controls on a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-parental-control)
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
在树莓派上设置网络家长控制
======
用最少的时间和金钱投入,就能保证孩子上网安全。
![Family learning and reading together at night in a room][1]
家长们一直在寻找保护孩子们上网的方法,从防止恶意软件、横幅广告、弹出窗口、活动跟踪脚本和其他问题,到防止他们在应该做功课的时候玩游戏和看 YouTube。许多企业使用工具来规范员工的网络安全和活动但问题是如何在家里实现这一点
简短的答案是一台小巧、廉价的树莓派电脑,它可以让你为孩子和你在家的工作设置家长控制。本文将为你介绍如何使用树莓派轻松构建自己的家长控制家庭网络。
### 安装硬件和软件
对于这个项目,你需要一个树莓派和一个家庭网络路由器。如果你只花 5 分钟浏览在线购物网站,你会发现很多选择。[树莓派 4][2] 和 [TP-Link 路由器][3]是初学者的好选择。
有了网络设备和树莓派后,你需要在 Linux 容器或者受支持的操作系统中安装 [Pi-hole][4]。有几种[安装方法][5],但一个简单的方法是在你的树莓派上执行以下命令:
```
`curl -sSL https://install.pi-hole.net | bash`
```
### 配置 Pi-hole 作为你的 DNS 服务器
接下来,你需要在路由器和 Pi-hole 中配置 DHCP 设置:
1. 禁用路由器中的 DHCP 服务器设置
2. 在 Pi-hole 中启用 DHCP 服务器
每台设备都不一样,所以我没有办法告诉你具体需要点击什么来调整设置。一般来说,你可以通过浏览器访问你家的路由器。你的路由器的地址有时会印在路由器的底部, 它以 192.168 或 10 开头。
在浏览器中,打开你的路由器的地址,并用你收到的网络服务凭证登录。它通常是简单的 `admin` 和一个数字密码(有时这个密码也打印在路由器上)。如果你不知道登录名,请打电话给你的供应商并询问详情。
在图形界面中,寻找你的局域网内关于 DHCP 的部分,并停用 DHCP 服务器。 你的路由器界面几乎肯定会与我的不同,但这是一个我设置的例子。取消勾选 **DHCP 服务器**
![Disable DHCP][6]
(Daniel Oh, [CC BY-SA 4.0][7])
接下来,你必须在 Pi-hole 上激活 DHCP 服务器。如果你不这样做,除非你手动分配 IP 地址,否则你的设备将无法上网!
### 让你的网络变得家庭友好
设置完成了。现在,你的网络设备(如手机、平板电脑、笔记本电脑等)将自动找到树莓派上的 DHCP 服务器。然后,每个设备将被分配一个动态 IP 地址来访问互联网。
注意:如果你的路由器设备支持设置 DNS 服务器,你也可以在路由器中配置 DNS 客户端。客户端将把 Pi-hole 作为你的 DNS 服务器。
要设置你的孩子可以访问哪些网站和活动的规则,打开浏览器进入 Pi-hole 管理页面,`http://pi.hole/admin/`。在仪表板上,点击**白名单**来添加你的孩子可以访问的网页。你也可以将不允许孩子访问的网站(如游戏、成人、广告、购物等)添加到**屏蔽列表**。
![Pi-hole admin dashboard][8]
(Daniel Oh, [CC BY-SA 4.0][7])
### 接下来是什么?
现在,你已经在树莓派上设置了家长控制,你可以让你的孩子更安全地上网,同时让他们访问经批准的娱乐选项。这也可以通过减少你的家庭串流来降低你的家庭网络使用量。更多高级使用方法,请访问 Pi-hole 的[文档][9]和[博客][10]。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-parental-control
作者:[Daniel Oh][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/daniel-oh
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/family_learning_kids_night_reading.png?itok=6K7sJVb1 (Family learning and reading together at night in a room)
[2]: https://www.raspberrypi.org/products/
[3]: https://www.amazon.com/s?k=tp-link+router&crid=3QRLN3XRWHFTC&sprefix=TP-Link%2Caps%2C186&ref=nb_sb_ss_ts-doa-p_3_7
[4]: https://pi-hole.net/
[5]: https://github.com/pi-hole/pi-hole/#one-step-automated-install
[6]: https://opensource.com/sites/default/files/uploads/disabledhcp.jpg (Disable DHCP)
[7]: https://creativecommons.org/licenses/by-sa/4.0/
[8]: https://opensource.com/sites/default/files/uploads/blocklist.png (Pi-hole admin dashboard)
[9]: https://docs.pi-hole.net/
[10]: https://pi-hole.net/blog/#page-content