mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-28 23:20:10 +08:00
commit
5e37b47728
64
lctt2020.md
Normal file
64
lctt2020.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Linux 中国旗下贡献者组织 LCTT 七年回顾和展望
|
||||
|
||||
> 这是一篇 LCTT 七周年的纪念文章,也是 LCTT 承前启后的一个里程碑。
|
||||
|
||||
### 写在 LCTT 七年之际
|
||||
|
||||
在 7 年前的今天,我并没有想到,在一个偶然的机会下诞生的 LCTT,它能走过这么长的时间,留下这么多的印痕。是的,一些老朋友或许记得,LCTT 这个 Linux 中国旗下的最主要的开源活动/组成部分,最初只是我发心想完善 man 的中文翻译而产生的副产品。结果,man 中文翻译项目没有做成,而 LCTT 却持续地运营了下来。
|
||||
|
||||
虽然,这些年 LCTT 屡有改进和完善,但是总体来说还是相对保守。当然,LCTT 这些年已经陆续有 400 多位贡献者实质性的参与了贡献,并在此基础上创建了几个 SIG(特别兴趣小组),如[红帽代码英雄 SIG](https://linux.cn/article-12436-1.html)、漫画 SIG、LFS SIG 等。
|
||||
|
||||
作为回顾,我来介绍一下 LCTT 这 7 年间在主项目(TranslateProject)上取得的成就:
|
||||
|
||||
- 贡献者: [435 位](https://linux.cn/lctt-list)
|
||||
- 翻译文章:[5687 篇](https://linux.cn/)
|
||||
- GitHub 提交:[54629 次](https://github.com/LCTT/TranslateProject)
|
||||
- GitHub 拉取请求:[19243 次](https://github.com/LCTT/TranslateProject/pulls)
|
||||
|
||||
这是 LCTT 主项目的提交图:
|
||||
|
||||
![](https://postimg.aliavv.com/mbp/uglsc.png)
|
||||
|
||||
这其中,[钻石级的贡献者有 5 名,五星级贡献者有 6 名,13 位 4 星贡献者](https://linux.cn/lctt-list)。那么,请让我来用一段视频展示一下 LCTT 七年来的历程:
|
||||
|
||||
![](https://img.linux.net.cn/static/video/LCTT%207%20Years.mp4)
|
||||
|
||||
当然,整体的贡献水平呈现长尾分布,大部分贡献者浅尝辄止,我想除了贡献者存在着体验的心态之外,也与 LCTT 没有建立起来合适的社区引导和激励机制有关。此外,就开源社区/开源项目而言,我们也存在一些不足,比如,按 GitHub 建议,我们在如下社区建设方面还缺乏:
|
||||
|
||||
- 社区行为准则
|
||||
- 贡献指南
|
||||
- 议题模板
|
||||
- 拉取请求模板
|
||||
|
||||
因此,在写这篇文章时,我也要宣布一件事,就是我会逐渐淡出 LCTT 的日常管理,改组 LCTT 管理团队,将更多未来的可能交给社区成员来建设,也希望新的社区管理团队可以为 LCTT 创造出一个不同的明天。
|
||||
|
||||
以下,请我们的 Linux 中国的核心合伙人 Bestony 来介绍一下今后 LCTT 的发展计划。
|
||||
|
||||
---
|
||||
|
||||
大家好,我是 Bestony,感谢老王数年来的坚持不懈的投入,正是有老王的坚守,才能有我们如今的成就。在接下来的时间里,我将会帮助老王,更好的运作 LCTT,让老王可以喘口气,也为 LCTT 带来一些新的气象。
|
||||
|
||||
在过去的七年里,我们 LCTT 做了很多事情,我们翻译了数千篇文章,有数百位技能精湛的贡献者。如今,到了 7 年的这个节点上,我也在思考,我们下一步应该怎么走。
|
||||
|
||||
其实,在过去的一年里,LCTT 的问题在不断的浮现:选题方向单一、译者进入门槛较高、大家翻译的质量水平参差不齐、校对的人手不足、译稿外发的反馈不足,这些问题都是我们在过去遇见,但一直没有足够的精力和人力来解决的问题。不过,如今我将加入到 LCTT 的管理团队中,配合老王,一起一个个的解决这些过去遇见的问题。
|
||||
|
||||
![](https://postimg.aliavv.com/mbp/3kfwy.png)
|
||||
|
||||
对于这些问题,有一些我们已经在解决,比如“**选题方向单一**”,在今年的年初,LCTT 与红帽公司(RedHat)[联合建立了 LCRH SIG](https://linux.cn/article-12436-1.html),面向红帽旗下的原创播客《<ruby>[代码英雄](https://www.redhat.com/en/command-line-heroes) <rt>Command Line Heroes</rt></ruby>》进行定向的翻译,目前,第一季度的翻译成功已经全部在 Linux 中国公众号上发布,而第二、三季度的内容,也正在不断的发布过程中。
|
||||
|
||||
![](https://postimg.aliavv.com/mbp/71eup.png)
|
||||
|
||||
LCTT - SIG 将是后续的新的发展方向。**我们将会在保留 LCTT 主体的基础上,鼓励各位译者探索更多的兴趣方向,通过建立起不同的 SIG,引入更多的翻译内容,来帮助大家更好的达成自己想要的翻译目标。** 并且,通过 LCTT 的技术和经验,赋能每一位译者,帮助译者更好的学习、了解各种不同领域的知识。
|
||||
|
||||
而在“**进入门槛较高**”方面,一直以来 Github 的访问慢问题、Git 的概念不熟悉等问题,都是困扰不少新同学的点。而也正是这些点,在不断制约着 LCTT 的发展。在将来,我希望 LCTT 可以打造出自己的翻译工具(也将会为之而奋斗),通过工具辅助的方式,帮助更多人走上翻译的道路,让更多的爱好者们,可以为中文的技术环境贡献一份力。
|
||||
|
||||
![](https://postimg.aliavv.com/mbp/8183e.png)
|
||||
|
||||
后续,我们将会引入翻译工具、自建关键词表、多轮校对手段等方案,帮助更多的译者完成自己的翻译文章,通过翻译,学到自己想要的知识。
|
||||
|
||||
当然,问题并不止我点出来的这些,我们能发展到今天,一定有很多做对了的地方,但同样,我们也有做错了的地方。欢迎你随时联系我,讨论你对于 LCTT 下一步的想法,我相信,你的意见能够帮助 LCTT 变得更好。
|
||||
|
||||
![](https://postimg.aliavv.com/mbp/aq5m9.png)
|
||||
|
||||
最后,**千里之行,始于足下**,刚刚走过 7 年的 LCTT, 希望我们可以在下一个七年,再次相遇。
|
||||
|
315
published/20180710 Building a Messenger App- Messages.md
Normal file
315
published/20180710 Building a Messenger App- Messages.md
Normal file
@ -0,0 +1,315 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (gxlct008)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12680-1.html)
|
||||
[#]: subject: (Building a Messenger App: Messages)
|
||||
[#]: via: (https://nicolasparada.netlify.com/posts/go-messenger-messages/)
|
||||
[#]: author: (Nicolás Parada https://nicolasparada.netlify.com/)
|
||||
|
||||
构建一个即时消息应用(四):消息
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202010/04/114458z1p1188epequ686p.jpg)
|
||||
|
||||
本文是该系列的第四篇。
|
||||
|
||||
* [第一篇: 模式][1]
|
||||
* [第二篇: OAuth][2]
|
||||
* [第三篇: 对话][3]
|
||||
|
||||
在这篇文章中,我们将对端点进行编码,以创建一条消息并列出它们,同时还将编写一个端点以更新参与者上次阅读消息的时间。 首先在 `main()` 函数中添加这些路由。
|
||||
|
||||
```
|
||||
router.HandleFunc("POST", "/api/conversations/:conversationID/messages", requireJSON(guard(createMessage)))
|
||||
router.HandleFunc("GET", "/api/conversations/:conversationID/messages", guard(getMessages))
|
||||
router.HandleFunc("POST", "/api/conversations/:conversationID/read_messages", guard(readMessages))
|
||||
```
|
||||
|
||||
消息会进入对话,因此端点包含对话 ID。
|
||||
|
||||
### 创建消息
|
||||
|
||||
该端点处理对 `/api/conversations/{conversationID}/messages` 的 POST 请求,其 JSON 主体仅包含消息内容,并返回新创建的消息。它有两个副作用:更新对话 `last_message_id` 以及更新参与者 `messages_read_at`。
|
||||
|
||||
```
|
||||
func createMessage(w http.ResponseWriter, r *http.Request) {
|
||||
var input struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
defer r.Body.Close()
|
||||
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
errs := make(map[string]string)
|
||||
input.Content = removeSpaces(input.Content)
|
||||
if input.Content == "" {
|
||||
errs["content"] = "Message content required"
|
||||
} else if len([]rune(input.Content)) > 480 {
|
||||
errs["content"] = "Message too long. 480 max"
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
respond(w, Errors{errs}, http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
conversationID := way.Param(ctx, "conversationID")
|
||||
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
respondError(w, fmt.Errorf("could not begin tx: %v", err))
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
isParticipant, err := queryParticipantExistance(ctx, tx, authUserID, conversationID)
|
||||
if err != nil {
|
||||
respondError(w, fmt.Errorf("could not query participant existance: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if !isParticipant {
|
||||
http.Error(w, "Conversation not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var message Message
|
||||
if err := tx.QueryRowContext(ctx, `
|
||||
INSERT INTO messages (content, user_id, conversation_id) VALUES
|
||||
($1, $2, $3)
|
||||
RETURNING id, created_at
|
||||
`, input.Content, authUserID, conversationID).Scan(
|
||||
&message.ID,
|
||||
&message.CreatedAt,
|
||||
); err != nil {
|
||||
respondError(w, fmt.Errorf("could not insert message: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
UPDATE conversations SET last_message_id = $1
|
||||
WHERE id = $2
|
||||
`, message.ID, conversationID); err != nil {
|
||||
respondError(w, fmt.Errorf("could not update conversation last message ID: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
respondError(w, fmt.Errorf("could not commit tx to create a message: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err = updateMessagesReadAt(nil, authUserID, conversationID); err != nil {
|
||||
log.Printf("could not update messages read at: %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
message.Content = input.Content
|
||||
message.UserID = authUserID
|
||||
message.ConversationID = conversationID
|
||||
// TODO: notify about new message.
|
||||
message.Mine = true
|
||||
|
||||
respond(w, message, http.StatusCreated)
|
||||
}
|
||||
```
|
||||
|
||||
首先,它将请求正文解码为包含消息内容的结构。然后,它验证内容不为空并且少于 480 个字符。
|
||||
|
||||
```
|
||||
var rxSpaces = regexp.MustCompile("\\s+")
|
||||
|
||||
func removeSpaces(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
|
||||
lines := make([]string, 0)
|
||||
for _, line := range strings.Split(s, "\n") {
|
||||
line = rxSpaces.ReplaceAllLiteralString(line, " ")
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" {
|
||||
lines = append(lines, line)
|
||||
}
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
```
|
||||
|
||||
这是删除空格的函数。它遍历每一行,删除两个以上的连续空格,然后回非空行。
|
||||
|
||||
验证之后,它将启动一个 SQL 事务。首先,它查询对话中的参与者是否存在。
|
||||
|
||||
```
|
||||
func queryParticipantExistance(ctx context.Context, tx *sql.Tx, userID, conversationID string) (bool, error) {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
var exists bool
|
||||
if err := tx.QueryRowContext(ctx, `SELECT EXISTS (
|
||||
SELECT 1 FROM participants
|
||||
WHERE user_id = $1 AND conversation_id = $2
|
||||
)`, userID, conversationID).Scan(&exists); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
```
|
||||
|
||||
我将其提取到一个函数中,因为稍后可以重用。
|
||||
|
||||
如果用户不是对话参与者,我们将返回一个 `404 NOT Found` 错误。
|
||||
|
||||
然后,它插入消息并更新对话 `last_message_id`。从这时起,由于我们不允许删除消息,因此 `last_message_id` 不能为 `NULL`。
|
||||
|
||||
接下来提交事务,并在 goroutine 中更新参与者 `messages_read_at`。
|
||||
|
||||
```
|
||||
func updateMessagesReadAt(ctx context.Context, userID, conversationID string) error {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
if _, err := db.ExecContext(ctx, `
|
||||
UPDATE participants SET messages_read_at = now()
|
||||
WHERE user_id = $1 AND conversation_id = $2
|
||||
`, userID, conversationID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
在回复这条新消息之前,我们必须通知一下。这是我们将要在下一篇文章中编写的实时部分,因此我在那里留一了个注释。
|
||||
|
||||
### 获取消息
|
||||
|
||||
这个端点处理对 `/api/conversations/{conversationID}/messages` 的 GET 请求。 它用一个包含会话中所有消息的 JSON 数组进行响应。它还具有更新参与者 `messages_read_at` 的副作用。
|
||||
|
||||
```
|
||||
func getMessages(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
conversationID := way.Param(ctx, "conversationID")
|
||||
|
||||
tx, err := db.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
respondError(w, fmt.Errorf("could not begin tx: %v", err))
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
isParticipant, err := queryParticipantExistance(ctx, tx, authUserID, conversationID)
|
||||
if err != nil {
|
||||
respondError(w, fmt.Errorf("could not query participant existance: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if !isParticipant {
|
||||
http.Error(w, "Conversation not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := tx.QueryContext(ctx, `
|
||||
SELECT
|
||||
id,
|
||||
content,
|
||||
created_at,
|
||||
user_id = $1 AS mine
|
||||
FROM messages
|
||||
WHERE messages.conversation_id = $2
|
||||
ORDER BY messages.created_at DESC
|
||||
`, authUserID, conversationID)
|
||||
if err != nil {
|
||||
respondError(w, fmt.Errorf("could not query messages: %v", err))
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
messages := make([]Message, 0)
|
||||
for rows.Next() {
|
||||
var message Message
|
||||
if err = rows.Scan(
|
||||
&message.ID,
|
||||
&message.Content,
|
||||
&message.CreatedAt,
|
||||
&message.Mine,
|
||||
); err != nil {
|
||||
respondError(w, fmt.Errorf("could not scan message: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
messages = append(messages, message)
|
||||
}
|
||||
|
||||
if err = rows.Err(); err != nil {
|
||||
respondError(w, fmt.Errorf("could not iterate over messages: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
respondError(w, fmt.Errorf("could not commit tx to get messages: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err = updateMessagesReadAt(nil, authUserID, conversationID); err != nil {
|
||||
log.Printf("could not update messages read at: %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
respond(w, messages, http.StatusOK)
|
||||
}
|
||||
```
|
||||
|
||||
首先,它以只读模式开始一个 SQL 事务。检查参与者是否存在,并查询所有消息。在每条消息中,我们使用当前经过身份验证的用户 ID 来了解用户是否拥有该消息(`mine`)。 然后,它提交事务,在 goroutine 中更新参与者 `messages_read_at` 并以消息响应。
|
||||
|
||||
### 读取消息
|
||||
|
||||
该端点处理对 `/api/conversations/{conversationID}/read_messages` 的 POST 请求。 没有任何请求或响应主体。 在前端,每次有新消息到达实时流时,我们都会发出此请求。
|
||||
|
||||
```
|
||||
func readMessages(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
conversationID := way.Param(ctx, "conversationID")
|
||||
|
||||
if err := updateMessagesReadAt(ctx, authUserID, conversationID); err != nil {
|
||||
respondError(w, fmt.Errorf("could not update messages read at: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
```
|
||||
|
||||
它使用了与更新参与者 `messages_read_at` 相同的函数。
|
||||
|
||||
* * *
|
||||
|
||||
到此为止。实时消息是后台仅剩的部分了。请等待下一篇文章。
|
||||
|
||||
- [源代码][4]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://nicolasparada.netlify.com/posts/go-messenger-messages/
|
||||
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[gxlct008](https://github.com/gxlct008)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nicolasparada.netlify.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linux.cn/article-11396-1.html
|
||||
[2]: https://linux.cn/article-11510-1.html
|
||||
[3]: https://linux.cn/article-12056-1.html
|
||||
[4]: https://github.com/nicolasparada/go-messenger-demo
|
@ -0,0 +1,175 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (gxlct008)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12685-1.html)
|
||||
[#]: subject: (Building a Messenger App: Realtime Messages)
|
||||
[#]: via: (https://nicolasparada.netlify.com/posts/go-messenger-realtime-messages/)
|
||||
[#]: author: (Nicolás Parada https://nicolasparada.netlify.com/)
|
||||
|
||||
构建一个即时消息应用(五):实时消息
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202010/05/091113edbuavorm89looja.jpg)
|
||||
|
||||
本文是该系列的第五篇。
|
||||
|
||||
* [第一篇: 模式][1]
|
||||
* [第二篇: OAuth][2]
|
||||
* [第三篇: 对话][3]
|
||||
* [第四篇: 消息][4]
|
||||
|
||||
对于实时消息,我们将使用 <ruby>[服务器发送事件][5]<rt>Server-Sent Events</rt></ruby>。这是一个打开的连接,我们可以在其中传输数据流。我们会有个端点,用户会在其中订阅发送给他的所有消息。
|
||||
|
||||
### 消息户端
|
||||
|
||||
在 HTTP 部分之前,让我们先编写一个<ruby>映射<rt>map</rt></ruby> ,让所有客户端都监听消息。 像这样全局初始化:
|
||||
|
||||
```go
|
||||
type MessageClient struct {
|
||||
Messages chan Message
|
||||
UserID string
|
||||
}
|
||||
|
||||
var messageClients sync.Map
|
||||
```
|
||||
|
||||
### 已创建的新消息
|
||||
|
||||
还记得在 [上一篇文章][4] 中,当我们创建这条消息时,我们留下了一个 “TODO” 注释。在那里,我们将使用这个函数来调度一个 goroutine。
|
||||
|
||||
```go
|
||||
go messageCreated(message)
|
||||
```
|
||||
|
||||
把这行代码插入到我们留注释的位置。
|
||||
|
||||
```go
|
||||
func messageCreated(message Message) error {
|
||||
if err := db.QueryRow(`
|
||||
SELECT user_id FROM participants
|
||||
WHERE user_id != $1 and conversation_id = $2
|
||||
`, message.UserID, message.ConversationID).
|
||||
Scan(&message.ReceiverID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go broadcastMessage(message)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func broadcastMessage(message Message) {
|
||||
messageClients.Range(func(key, _ interface{}) bool {
|
||||
client := key.(*MessageClient)
|
||||
if client.UserID == message.ReceiverID {
|
||||
client.Messages <- message
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
该函数查询接收者 ID(其他参与者 ID),并将消息发送给所有客户端。
|
||||
|
||||
### 订阅消息
|
||||
|
||||
让我们转到 `main()` 函数并添加以下路由:
|
||||
|
||||
```go
|
||||
router.HandleFunc("GET", "/api/messages", guard(subscribeToMessages))
|
||||
```
|
||||
|
||||
此端点处理 `/api/messages` 上的 GET 请求。请求应该是一个 [EventSource][6] 连接。它用一个事件流响应,其中的数据是 JSON 格式的。
|
||||
|
||||
```go
|
||||
func subscribeToMessages(w http.ResponseWriter, r *http.Request) {
|
||||
if a := r.Header.Get("Accept"); !strings.Contains(a, "text/event-stream") {
|
||||
http.Error(w, "This endpoint requires an EventSource connection", http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
|
||||
f, ok := w.(http.Flusher)
|
||||
if !ok {
|
||||
respondError(w, errors.New("streaming unsupported"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
|
||||
h := w.Header()
|
||||
h.Set("Cache-Control", "no-cache")
|
||||
h.Set("Connection", "keep-alive")
|
||||
h.Set("Content-Type", "text/event-stream")
|
||||
|
||||
messages := make(chan Message)
|
||||
defer close(messages)
|
||||
|
||||
client := &MessageClient{Messages: messages, UserID: authUserID}
|
||||
messageClients.Store(client, nil)
|
||||
defer messageClients.Delete(client)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case message := <-messages:
|
||||
if b, err := json.Marshal(message); err != nil {
|
||||
log.Printf("could not marshall message: %v\n", err)
|
||||
fmt.Fprintf(w, "event: error\ndata: %v\n\n", err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "data: %s\n\n", b)
|
||||
}
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
首先,它检查请求头是否正确,并检查服务器是否支持流式传输。我们创建一个消息通道,用它来构建一个客户端,并将其存储在客户端映射中。每当创建新消息时,它都会进入这个通道,因此我们可以通过 `for-select` 循环从中读取。
|
||||
|
||||
<ruby>服务器发送事件<rt>Server-Sent Events</rt></ruby>使用以下格式发送数据:
|
||||
|
||||
```go
|
||||
data: some data here\n\n
|
||||
```
|
||||
|
||||
我们以 JSON 格式发送:
|
||||
|
||||
```json
|
||||
data: {"foo":"bar"}\n\n
|
||||
```
|
||||
|
||||
我们使用 `fmt.Fprintf()` 以这种格式写入响应<ruby>写入器<rt>writter</rt></ruby>,并在循环的每次迭代中刷新数据。
|
||||
|
||||
这个循环会一直运行,直到使用请求上下文关闭连接为止。我们延迟了通道的关闭和客户端的删除,因此,当循环结束时,通道将被关闭,客户端不会收到更多的消息。
|
||||
|
||||
注意,<ruby>服务器发送事件<rt>Server-Sent Events</rt></ruby>(EventSource)的 JavaScript API 不支持设置自定义请求头😒,所以我们不能设置 `Authorization: Bearer <token>`。这就是为什么 `guard()` 中间件也会从 URL 查询字符串中读取令牌的原因。
|
||||
|
||||
* * *
|
||||
|
||||
实时消息部分到此结束。我想说的是,这就是后端的全部内容。但是为了编写前端代码,我将再增加一个登录端点:一个仅用于开发的登录。
|
||||
|
||||
- [源代码][7]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://nicolasparada.netlify.com/posts/go-messenger-realtime-messages/
|
||||
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[gxlct008](https://github.com/gxlct008)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nicolasparada.netlify.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linux.cn/article-11396-1.html
|
||||
[2]: https://linux.cn/article-11510-1.html
|
||||
[3]: https://linux.cn/article-12056-1.html
|
||||
[4]: https://linux.cn/article-12680-1.html
|
||||
[5]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events
|
||||
[6]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource
|
||||
[7]: https://github.com/nicolasparada/go-messenger-demo
|
@ -1,38 +1,38 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (gxlct008)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12692-1.html)
|
||||
[#]: subject: (Building a Messenger App: Development Login)
|
||||
[#]: via: (https://nicolasparada.netlify.com/posts/go-messenger-dev-login/)
|
||||
[#]: author: (Nicolás Parada https://nicolasparada.netlify.com/)
|
||||
|
||||
Building a Messenger App: Development Login
|
||||
构建一个即时消息应用(六):仅用于开发的登录
|
||||
======
|
||||
|
||||
This post is the 6th on a series:
|
||||
![](https://img.linux.net.cn/data/attachment/album/202010/07/101437garmhgi9aza9f9fz.jpg)
|
||||
|
||||
* [Part 1: Schema][1]
|
||||
* [Part 2: OAuth][2]
|
||||
* [Part 3: Conversations][3]
|
||||
* [Part 4: Messages][4]
|
||||
* [Part 5: Realtime Messages][5]
|
||||
本文是该系列的第六篇。
|
||||
|
||||
* [第一篇: 模式][1]
|
||||
* [第二篇: OAuth][2]
|
||||
* [第三篇: 对话][3]
|
||||
* [第四篇: 消息][4]
|
||||
* [第五篇: 实时消息][5]
|
||||
|
||||
我们已经实现了通过 GitHub 登录,但是如果想把玩一下这个 app,我们需要几个用户来测试它。在这篇文章中,我们将添加一个为任何用户提供登录的端点,只需提供用户名即可。该端点仅用于开发。
|
||||
|
||||
We already implemented login through GitHub, but if we want to play around with the app, we need a couple of users to test it. In this post we’ll add an endpoint to login as any user just giving an username. This endpoint will be just for development.
|
||||
首先在 `main()` 函数中添加此路由。
|
||||
|
||||
Start by adding this route in the `main()` function.
|
||||
|
||||
```
|
||||
```go
|
||||
router.HandleFunc("POST", "/api/login", requireJSON(login))
|
||||
```
|
||||
|
||||
### Login
|
||||
### 登录
|
||||
|
||||
This function handles POST requests to `/api/login` with a JSON body with just an username and returns the authenticated user, a token and expiration date of it in JSON format.
|
||||
此函数处理对 `/api/login` 的 POST 请求,其中 JSON body 只包含用户名,并以 JSON 格式返回通过认证的用户、令牌和过期日期。
|
||||
|
||||
```
|
||||
```go
|
||||
func login(w http.ResponseWriter, r *http.Request) {
|
||||
if origin.Hostname() != "localhost" {
|
||||
http.NotFound(w, r)
|
||||
@ -81,9 +81,9 @@ func login(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
```
|
||||
|
||||
First it checks we are on localhost or it responds with `404 Not Found`. It decodes the body skipping validation since this is just for development. Then it queries to the database for a user with the given username, if none is found, it returns with `404 Not Found`. Then it issues a new JSON web token using the user ID as Subject.
|
||||
首先,它检查我们是否在本地主机上,或者响应为 `404 Not Found`。它解码主体跳过验证,因为这只是为了开发。然后在数据库中查询给定用户名的用户,如果没有,则返回 `404 NOT Found`。然后,它使用用户 ID 作为主题发布一个新的 JSON Web 令牌。
|
||||
|
||||
```
|
||||
```go
|
||||
func issueToken(subject string, exp time.Time) (string, error) {
|
||||
token, err := jwtSigner.Encode(jwt.Claims{
|
||||
Subject: subject,
|
||||
@ -96,33 +96,33 @@ func issueToken(subject string, exp time.Time) (string, error) {
|
||||
}
|
||||
```
|
||||
|
||||
The function does the same we did [previously][2]. I just moved it to reuse code.
|
||||
该函数执行的操作与 [前文][2] 相同。我只是将其移过来以重用代码。
|
||||
|
||||
After creating the token, it responds with the user, token and expiration date.
|
||||
创建令牌后,它将使用用户、令牌和到期日期进行响应。
|
||||
|
||||
### Seed Users
|
||||
### 种子用户
|
||||
|
||||
Now you can add users to play with to the database.
|
||||
现在,你可以将要操作的用户添加到数据库中。
|
||||
|
||||
```
|
||||
```sql
|
||||
INSERT INTO users (id, username) VALUES
|
||||
(1, 'john'),
|
||||
(2, 'jane');
|
||||
```
|
||||
|
||||
You can save it to a file and pipe it to the Cockroach CLI.
|
||||
你可以将其保存到文件中,并通过管道将其传送到 Cockroach CLI。
|
||||
|
||||
```
|
||||
```bash
|
||||
cat seed_users.sql | cockroach sql --insecure -d messenger
|
||||
```
|
||||
|
||||
* * *
|
||||
|
||||
That’s it. Once you deploy the code to production and use your own domain this login function won’t be available.
|
||||
就是这样。一旦将代码部署到生产环境并使用自己的域后,该登录功能将不可用。
|
||||
|
||||
This post concludes the backend.
|
||||
本文也结束了所有的后端开发部分。
|
||||
|
||||
[Souce Code][6]
|
||||
- [源代码][6]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -130,16 +130,16 @@ via: https://nicolasparada.netlify.com/posts/go-messenger-dev-login/
|
||||
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[gxlct008](https://github.com/gxlct008)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nicolasparada.netlify.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://nicolasparada.netlify.com/posts/go-messenger-schema/
|
||||
[2]: https://nicolasparada.netlify.com/posts/go-messenger-oauth/
|
||||
[3]: https://nicolasparada.netlify.com/posts/go-messenger-conversations/
|
||||
[4]: https://nicolasparada.netlify.com/posts/go-messenger-messages/
|
||||
[5]: https://nicolasparada.netlify.com/posts/go-messenger-realtime-messages/
|
||||
[1]: https://linux.cn/article-11396-1.html
|
||||
[2]: https://linux.cn/article-11510-1.html
|
||||
[3]: https://linux.cn/article-12056-1.html
|
||||
[4]: https://linux.cn/article-12680-1.html
|
||||
[5]: https://linux.cn/article-12685-1.html
|
||||
[6]: https://github.com/nicolasparada/go-messenger-demo
|
@ -1,31 +1,31 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (gxlct008)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12704-1.html)
|
||||
[#]: subject: (Building a Messenger App: Access Page)
|
||||
[#]: via: (https://nicolasparada.netlify.com/posts/go-messenger-access-page/)
|
||||
[#]: author: (Nicolás Parada https://nicolasparada.netlify.com/)
|
||||
|
||||
Building a Messenger App: Access Page
|
||||
构建一个即时消息应用(七):Access 页面
|
||||
======
|
||||
|
||||
This post is the 7th on a series:
|
||||
![](https://img.linux.net.cn/data/attachment/album/202010/10/101345zj7gfybyee2g9x9e.jpg)
|
||||
|
||||
* [Part 1: Schema][1]
|
||||
* [Part 2: OAuth][2]
|
||||
* [Part 3: Conversations][3]
|
||||
* [Part 4: Messages][4]
|
||||
* [Part 5: Realtime Messages][5]
|
||||
* [Part 6: Development Login][6]
|
||||
本文是该系列的第七篇。
|
||||
|
||||
* [第一篇: 模式][1]
|
||||
* [第二篇: OAuth][2]
|
||||
* [第三篇: 对话][3]
|
||||
* [第四篇: 消息][4]
|
||||
* [第五篇: 实时消息][5]
|
||||
* [第六篇: 仅用于开发的登录][6]
|
||||
|
||||
现在我们已经完成了后端,让我们转到前端。 我将采用单页应用程序方案。
|
||||
|
||||
Now that we’re done with the backend, lets move to the frontend. I will go with a single-page application.
|
||||
首先,我们创建一个 `static/index.html` 文件,内容如下。
|
||||
|
||||
Lets start by creating a file `static/index.html` with the following content.
|
||||
|
||||
```
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@ -40,11 +40,11 @@ Lets start by creating a file `static/index.html` with the following content.
|
||||
</html>
|
||||
```
|
||||
|
||||
This HTML file must be server for every URL and JavaScript will take care of rendering the correct page.
|
||||
这个 HTML 文件必须为每个 URL 提供服务,并且使用 JavaScript 负责呈现正确的页面。
|
||||
|
||||
So lets go the the `main.go` for a moment and in the `main()` function add the following route:
|
||||
因此,让我们将注意力转到 `main.go` 片刻,然后在 `main()` 函数中添加以下路由:
|
||||
|
||||
```
|
||||
```go
|
||||
router.Handle("GET", "/...", http.FileServer(SPAFileSystem{http.Dir("static")}))
|
||||
|
||||
type SPAFileSystem struct {
|
||||
@ -60,15 +60,15 @@ func (spa SPAFileSystem) Open(name string) (http.File, error) {
|
||||
}
|
||||
```
|
||||
|
||||
We use a custom file system so instead of returning `404 Not Found` for unknown URLs, it serves the `index.html`.
|
||||
我们使用一个自定义的文件系统,因此它不是为未知的 URL 返回 `404 Not Found`,而是转到 `index.html`。
|
||||
|
||||
### Router
|
||||
### 路由器
|
||||
|
||||
In the `index.html` we loaded two files: `styles.css` and `main.js`. I leave styling to your taste.
|
||||
在 `index.html` 中我们加载了两个文件:`styles.css` 和 `main.js`。我把样式留给你自由发挥。
|
||||
|
||||
Lets move to `main.js`. Create a `static/main.js` file with the following content:
|
||||
让我们移动到 `main.js`。 创建一个包含以下内容的 `static/main.js` 文件:
|
||||
|
||||
```
|
||||
```javascript
|
||||
import { guard } from './auth.js'
|
||||
import Router from './router.js'
|
||||
|
||||
@ -98,19 +98,19 @@ function view(pageName) {
|
||||
}
|
||||
```
|
||||
|
||||
If you are follower of this blog, you already know how this works. That router is the one showed [here][7]. Just download it from [@nicolasparada/router][8] and save it to `static/router.js`.
|
||||
如果你是这个博客的关注者,你已经知道它是如何工作的了。 该路由器就是在 [这里][7] 显示的那个。 只需从 [@nicolasparada/router][8] 下载并保存到 `static/router.js` 即可。
|
||||
|
||||
We registered four routes. At the root `/` we show the home or access page whether the user is authenticated. At `/callback` we show the callback page. On `/conversations/{conversationID}` we show the conversation or access page whether the user is authenticated and for every other URL, we show a not found page.
|
||||
我们注册了四条路由。 在根路由 `/` 处,我们展示 `home` 或 `access` 页面,无论用户是否通过身份验证。 在 `/callback` 中,我们展示 `callback` 页面。 在 `/conversations/{conversationID}` 上,我们展示对话或 `access` 页面,无论用户是否通过验证,对于其他 URL,我们展示一个 `not-found` 页面。
|
||||
|
||||
We tell the router to render the result to the document body and dispatch a `disconnect` event to each page before leaving.
|
||||
我们告诉路由器将结果渲染为文档主体,并在离开之前向每个页面调度一个 `disconnect` 事件。
|
||||
|
||||
We have each page in a different file and we import them with the new dynamic `import()`.
|
||||
我们将每个页面放在不同的文件中,并使用新的动态 `import()` 函数导入它们。
|
||||
|
||||
### Auth
|
||||
### 身份验证
|
||||
|
||||
`guard()` is a function that given two functions, executes the first one if the user is authenticated, or the sencond one if not. It comes from `auth.js` so lets create a `static/auth.js` file with the following content:
|
||||
`guard()` 是一个函数,给它两个函数作为参数,如果用户通过了身份验证,则执行第一个函数,否则执行第二个。它来自 `auth.js`,所以我们创建一个包含以下内容的 `static/auth.js` 文件:
|
||||
|
||||
```
|
||||
```javascript
|
||||
export function isAuthenticated() {
|
||||
const token = localStorage.getItem('token')
|
||||
const expiresAtItem = localStorage.getItem('expires_at')
|
||||
@ -150,17 +150,17 @@ export function getAuthUser() {
|
||||
}
|
||||
```
|
||||
|
||||
`isAuthenticated()` checks for `token` and `expires_at` from localStorage to tell if the user is authenticated. `getAuthUser()` gets the authenticated user from localStorage.
|
||||
`isAuthenticated()` 检查 `localStorage` 中的 `token` 和 `expires_at`,以判断用户是否已通过身份验证。`getAuthUser()` 从 `localStorage` 中获取经过身份验证的用户。
|
||||
|
||||
When we login, we’ll save all the data to localStorage so it will make sense.
|
||||
当我们登录时,我们会将所有的数据保存到 `localStorage`,这样才有意义。
|
||||
|
||||
### Access Page
|
||||
### Access 页面
|
||||
|
||||
![access page screenshot][9]
|
||||
|
||||
Lets start with the access page. Create a file `static/pages/access-page.js` with the following content:
|
||||
让我们从 `access` 页面开始。 创建一个包含以下内容的文件 `static/pages/access-page.js`:
|
||||
|
||||
```
|
||||
```javascript
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<h1>Messenger</h1>
|
||||
@ -172,15 +172,15 @@ export default function accessPage() {
|
||||
}
|
||||
```
|
||||
|
||||
Because the router intercepts all the link clicks to do its navigation, we must prevent the event propagation for this link in particular.
|
||||
因为路由器会拦截所有链接点击来进行导航,所以我们必须特别阻止此链接的事件传播。
|
||||
|
||||
Clicking on that link will redirect us to the backend, then to GitHub, then to the backend and then to the frontend again; to the callback page.
|
||||
单击该链接会将我们重定向到后端,然后重定向到 GitHub,再重定向到后端,然后再次重定向到前端; 到 `callback` 页面。
|
||||
|
||||
### Callback Page
|
||||
### Callback 页面
|
||||
|
||||
Create the file `static/pages/callback-page.js` with the following content:
|
||||
创建包括以下内容的 `static/pages/callback-page.js` 文件:
|
||||
|
||||
```
|
||||
```javascript
|
||||
import http from '../http.js'
|
||||
import { navigate } from '../router.js'
|
||||
|
||||
@ -211,13 +211,13 @@ function getAuthUser(token) {
|
||||
}
|
||||
```
|
||||
|
||||
The callback page doesn’t render anything. It’s an async function that does a GET request to `/api/auth_user` using the token from the URL query string and saves all the data to localStorage. Then it redirects to `/`.
|
||||
`callback` 页面不呈现任何内容。这是一个异步函数,它使用 URL 查询字符串中的 token 向 `/api/auth_user` 发出 GET 请求,并将所有数据保存到 `localStorage`。 然后重定向到 `/`。
|
||||
|
||||
### HTTP
|
||||
|
||||
There is an HTTP module. Create a `static/http.js` file with the following content:
|
||||
这里是一个 HTTP 模块。 创建一个包含以下内容的 `static/http.js` 文件:
|
||||
|
||||
```
|
||||
```javascript
|
||||
import { isAuthenticated } from './auth.js'
|
||||
|
||||
async function handleResponse(res) {
|
||||
@ -297,15 +297,15 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
This module is a wrapper around the [fetch][10] and [EventSource][11] APIs. The most important part is that it adds the JSON web token to the requests.
|
||||
这个模块是 [fetch][10] 和 [EventSource][11] API 的包装器。最重要的部分是它将 JSON web 令牌添加到请求中。
|
||||
|
||||
### Home Page
|
||||
### Home 页面
|
||||
|
||||
![home page screenshot][12]
|
||||
|
||||
So, when the user login, the home page will be shown. Create a `static/pages/home-page.js` file with the following content:
|
||||
因此,当用户登录时,将显示 `home` 页。 创建一个具有以下内容的 `static/pages/home-page.js` 文件:
|
||||
|
||||
```
|
||||
```javascript
|
||||
import { getAuthUser } from '../auth.js'
|
||||
import { avatar } from '../shared.js'
|
||||
|
||||
@ -334,15 +334,15 @@ function onLogoutClick() {
|
||||
}
|
||||
```
|
||||
|
||||
For this post, this is the only content we render on the home page. We show the current authenticated user and a logout button.
|
||||
对于这篇文章,这是我们在 `home` 页上呈现的唯一内容。我们显示当前经过身份验证的用户和注销按钮。
|
||||
|
||||
When the user clicks to logout, we clear all inside localStorage and do a reload of the page.
|
||||
当用户单击注销时,我们清除 `localStorage` 中的所有内容并重新加载页面。
|
||||
|
||||
### Avatar
|
||||
|
||||
That `avatar()` function is to show the user’s avatar. Because it’s used in more than one place, I moved it to a `shared.js` file. Create the file `static/shared.js` with the following content:
|
||||
那个 `avatar()` 函数用于显示用户的头像。 由于已在多个地方使用,因此我将它移到 `shared.js` 文件中。 创建具有以下内容的文件 `static/shared.js`:
|
||||
|
||||
```
|
||||
```javascript
|
||||
export function avatar(user) {
|
||||
return user.avatarUrl === null
|
||||
? `<figure class="avatar" data-initial="${user.username[0]}"></figure>`
|
||||
@ -350,23 +350,23 @@ export function avatar(user) {
|
||||
}
|
||||
```
|
||||
|
||||
We use a small figure with the user’s initial in case the avatar URL is null.
|
||||
如果头像网址为 `null`,我们将使用用户的姓名首字母作为初始头像。
|
||||
|
||||
You can show the initial with a little of CSS using the `attr()` function.
|
||||
你可以使用 `attr()` 函数显示带有少量 CSS 样式的首字母。
|
||||
|
||||
```
|
||||
```css
|
||||
.avatar[data-initial]::after {
|
||||
content: attr(data-initial);
|
||||
}
|
||||
```
|
||||
|
||||
### Development Login
|
||||
### 仅开发使用的登录
|
||||
|
||||
![access page with login form screenshot][13]
|
||||
|
||||
In the previous post we coded a login for development. Lets add a form for that in the access page. Go to `static/pages/access-page.js` and modify it a little.
|
||||
在上一篇文章中,我们为编写了一个登录代码。让我们在 `access` 页面中为此添加一个表单。 进入 `static/ages/access-page.js`,稍微修改一下。
|
||||
|
||||
```
|
||||
```javascript
|
||||
import http from '../http.js'
|
||||
|
||||
const template = document.createElement('template')
|
||||
@ -420,15 +420,15 @@ function login(username) {
|
||||
}
|
||||
```
|
||||
|
||||
I added a login form. When the user submits the form. It does a POST requets to `/api/login` with the username. Saves all the data to localStorage and reloads the page.
|
||||
我添加了一个登录表单。当用户提交表单时。它使用用户名对 `/api/login` 进行 POST 请求。将所有数据保存到 `localStorage` 并重新加载页面。
|
||||
|
||||
Remember to remove this form once you are done with the frontend.
|
||||
记住在前端完成后删除此表单。
|
||||
|
||||
* * *
|
||||
|
||||
That’s all for this post. In the next one, we’ll continue with the home page to add a form to start conversations and display a list with the latest ones.
|
||||
这就是这篇文章的全部内容。在下一篇文章中,我们将继续使用主页添加一个表单来开始对话,并显示包含最新对话的列表。
|
||||
|
||||
[Souce Code][14]
|
||||
- [源代码][14]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -436,19 +436,19 @@ via: https://nicolasparada.netlify.com/posts/go-messenger-access-page/
|
||||
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[gxlct008](https://github.com/gxlct008)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nicolasparada.netlify.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://nicolasparada.netlify.com/posts/go-messenger-schema/
|
||||
[2]: https://nicolasparada.netlify.com/posts/go-messenger-oauth/
|
||||
[3]: https://nicolasparada.netlify.com/posts/go-messenger-conversations/
|
||||
[4]: https://nicolasparada.netlify.com/posts/go-messenger-messages/
|
||||
[5]: https://nicolasparada.netlify.com/posts/go-messenger-realtime-messages/
|
||||
[6]: https://nicolasparada.netlify.com/posts/go-messenger-dev-login/
|
||||
[1]: https://linux.cn/article-11396-1.html
|
||||
[2]: https://linux.cn/article-11510-1.html
|
||||
[3]: https://linux.cn/article-12056-1.html
|
||||
[4]: https://linux.cn/article-12680-1.html
|
||||
[5]: https://linux.cn/article-12685-1.html
|
||||
[6]: https://linux.cn/article-12692-1.html
|
||||
[7]: https://nicolasparada.netlify.com/posts/js-router/
|
||||
[8]: https://unpkg.com/@nicolasparada/router
|
||||
[9]: https://nicolasparada.netlify.com/img/go-messenger-access-page/access-page.png
|
221
published/20190521 How to Disable IPv6 on Ubuntu Linux.md
Normal file
221
published/20190521 How to Disable IPv6 on Ubuntu Linux.md
Normal file
@ -0,0 +1,221 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (rakino)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12689-1.html)
|
||||
[#]: subject: (How to Disable IPv6 on Ubuntu Linux)
|
||||
[#]: via: (https://itsfoss.com/disable-ipv6-ubuntu-linux/)
|
||||
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
|
||||
|
||||
如何在 Ubuntu Linux 上禁用 IPv6
|
||||
======
|
||||
|
||||
想知道怎样在 Ubuntu 上**禁用 IPv6** 吗?我会在这篇文章中介绍一些方法,以及为什么你应该考虑这一选择;以防改变主意,我也会提到如何**启用,或者说重新启用 IPv6**。
|
||||
|
||||
### 什么是 IPv6?为什么会想要禁用它?
|
||||
|
||||
<ruby>[互联网协议第 6 版][1]<rt>Internet Protocol version 6</rt></ruby>(IPv6)是互联网协议(IP)的最新版本。互联网协议是一种通信协议,它为网络上的计算机提供识别和定位系统,并在互联网上进行通信路由。IPv6 于 1998 年设计,以取代 IPv4 协议。
|
||||
|
||||
**IPv6** 意在提高安全性与性能的同时保证地址不被用尽;它可以在全球范围内为每台设备分配唯一的以 **128 位比特**存储的地址,而 IPv4 只使用了 32 位比特。
|
||||
|
||||
![Disable IPv6 Ubuntu][2]
|
||||
|
||||
尽管 IPv6 的目标是取代 IPv4,但目前还有很长的路要走;互联网上只有不到 **30%** 的网站支持 IPv6([这里][3] 是谷歌的统计),IPv6 有时也给 [一些应用带来问题][4]。
|
||||
|
||||
由于 IPv6 使用全球(唯一分配的)路由地址,以及(仍然)有<ruby>互联网服务供应商<rt>Internet Service Provider</rt></ruby>(ISP)不提供 IPv6 支持的事实,IPv6 这一功能在提供全球服务的<ruby>**虚拟私人网络**<rt>Virtual Private Network</rt></ruby>(VPN)供应商的优先级列表中处于较低的位置,这样一来,他们就可以专注于对 VPN 用户最重要的事情:安全。
|
||||
|
||||
不想让自己暴露在各种威胁之下可能是另一个让你想在系统上禁用 IPv6 的原因。虽然 IPv6 本身比 IPv4 更安全,但我所指的风险是另一种性质上的。如果你不实际使用 IPv6 及其功能,那么[启用 IPv6 后,你会很容易受到各种攻击][5],因而为黑客提供另一种可能的利用工具。
|
||||
|
||||
同样,只配置基本的网络规则是不够的;你必须像对 IPv4 一样,对调整 IPv6 的配置给予同样的关注,这可能会是一件相当麻烦的事情(维护也是)。并且随着 IPv6 而来的将会是一套不同于 IPv4 的问题(鉴于这个协议的年龄,许多问题已经可以在网上找到了),这又会使你的系统多了一层复杂性。
|
||||
|
||||
据观察,在某些情况下,禁用 IPv6 有助于提高 Ubuntu 的 WiFi 速度。
|
||||
|
||||
### 在 Ubuntu 上禁用 IPv6 [高级用户]
|
||||
|
||||
在本节中,我会详述如何在 Ubuntu 上禁用 IPv6 协议,请打开终端(默认快捷键:`CTRL+ALT+T`),让我们开始吧!
|
||||
|
||||
**注意:** 接下来大部分输入终端的命令都需要 root 权限(`sudo`)。
|
||||
|
||||
> 警告!
|
||||
>
|
||||
> 如果你是一个普通 Linux 桌面用户,并且偏好稳定的工作系统,请避开本教程,接下来的部分是为那些知道自己在做什么以及为什么要这么做的用户准备的。
|
||||
|
||||
#### 1、使用 sysctl 禁用 IPv6
|
||||
|
||||
首先,可以执行以下命令来**检查** IPv6 是否已经启用:
|
||||
|
||||
```
|
||||
ip a
|
||||
```
|
||||
|
||||
如果启用了,你应该会看到一个 IPv6 地址(网卡的名字可能会与图中有所不同)
|
||||
|
||||
![IPv6 Address Ubuntu][7]
|
||||
|
||||
在教程《[在 Ubuntu 中重启网络][8]》(LCTT 译注:其实这篇文章并没有提到使用 sysctl 的方法……)中,你已经见过 `sysctl` 命令了,在这里我们也同样会用到它。要**禁用 IPv6**,只需要输入三条命令:
|
||||
|
||||
```
|
||||
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
|
||||
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=1
|
||||
```
|
||||
|
||||
检查命令是否生效:
|
||||
|
||||
```
|
||||
ip a
|
||||
```
|
||||
|
||||
如果命令生效,你应该会发现 IPv6 的条目消失了:
|
||||
|
||||
![IPv6 Disabled Ubuntu][9]
|
||||
|
||||
然而这种方法只能**临时禁用 IPv6**,因此在下次系统启动的时候,IPv6 仍然会被启用。
|
||||
|
||||
(LCTT 译注:这里的临时禁用是指这次所做的改变直到此次关机之前都有效,因为相关的参数是存储在内存中的,可以改变值,但是在内存断电后就会丢失;这种意义上来讲,下文所述的两种方法都是临时的,只不过改变参数值的时机是在系统启动的早期,并且每次系统启动时都有应用而已。那么如何完成这种意义上的永久改变?答案是在编译内核的时候禁用相关功能,然后要后悔就只能重新编译内核了(悲)。)
|
||||
|
||||
一种让选项持续生效的方式是修改文件 `/etc/sysctl.conf`,在这里我用 `vim` 来编辑文件,不过你可以使用任何你想使用的编辑器,以及请确保你拥有**管理员权限**(用 `sudo`):
|
||||
|
||||
![Sysctl Configuration][10]
|
||||
|
||||
将下面这几行(和之前使用的参数相同)加入到文件中:
|
||||
|
||||
```
|
||||
net.ipv6.conf.all.disable_ipv6=1
|
||||
net.ipv6.conf.default.disable_ipv6=1
|
||||
net.ipv6.conf.lo.disable_ipv6=1
|
||||
```
|
||||
|
||||
执行以下命令应用设置:
|
||||
|
||||
```
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
如果在重启之后 IPv6 仍然被启用了,而你还想继续这种方法的话,那么你必须(使用 root 权限)创建文件 `/etc/rc.local` 并加入以下内容:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
# /etc/rc.local
|
||||
|
||||
/etc/sysctl.d
|
||||
/etc/init.d/procps restart
|
||||
|
||||
exit 0
|
||||
```
|
||||
|
||||
接着使用 [chmod 命令][11] 来更改文件权限,使其可执行:
|
||||
|
||||
```
|
||||
sudo chmod 755 /etc/rc.local
|
||||
```
|
||||
|
||||
这会让系统(在启动的时候)从之前编辑过的 sysctl 配置文件中读取内核参数。
|
||||
|
||||
#### 2、使用 GRUB 禁用 IPv6
|
||||
|
||||
另外一种方法是配置 **GRUB**,它会在系统启动时向内核传递参数。这样做需要编辑文件 `/etc/default/grub`(请确保拥有管理员权限)。
|
||||
|
||||
![GRUB Configuration][13]
|
||||
|
||||
现在需要修改文件中分别以 `GRUB_CMDLINE_LINUX_DEFAULT` 和 `GRUB_CMDLINE_LINUX` 开头的两行来在启动时禁用 IPv6:
|
||||
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash ipv6.disable=1"
|
||||
GRUB_CMDLINE_LINUX="ipv6.disable=1"
|
||||
```
|
||||
|
||||
(LCTT 译注:这里是指在上述两行内增加参数 `ipv6.disable=1`,不同的系统中这两行的默认值可能有所不同。)
|
||||
|
||||
保存文件,然后执行命令:
|
||||
|
||||
```
|
||||
sudo update-grub
|
||||
```
|
||||
|
||||
(LCTT 译注:该命令用以更新 GRUB 的配置文件,在没有 `update-grub` 命令的系统中需要使用 `sudo grub-mkconfig -o /boot/grub/grub.cfg` )
|
||||
|
||||
设置会在重启后生效。
|
||||
|
||||
### 在 Ubuntu 上重新启用 IPv6
|
||||
|
||||
要想重新启用 IPv6,你需要撤销之前的所有修改。不过只是想临时启用 IPv6 的话,可以执行以下命令:
|
||||
|
||||
```
|
||||
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=0
|
||||
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
|
||||
```
|
||||
|
||||
否则想要持续启用的话,看看是否修改过 `/etc/sysctl.conf`,可以删除掉之前增加的部分,也可以将它们改为以下值(两种方法等效):
|
||||
|
||||
```
|
||||
net.ipv6.conf.all.disable_ipv6=0
|
||||
net.ipv6.conf.default.disable_ipv6=0
|
||||
net.ipv6.conf.lo.disable_ipv6=0
|
||||
```
|
||||
|
||||
然后应用设置(可选):
|
||||
|
||||
```
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
(LCTT 译注:这里可选的意思可能是如果之前临时启用了 IPv6 就没必要再重新加载配置文件了)
|
||||
|
||||
这样应该可以再次看到 IPv6 地址了:
|
||||
|
||||
![IPv6 Reenabled in Ubuntu][14]
|
||||
|
||||
另外,你也可以删除之前创建的文件 `/etc/rc.local`(可选):
|
||||
|
||||
```
|
||||
sudo rm /etc/rc.local
|
||||
```
|
||||
|
||||
如果修改了文件 `/etc/default/grub`,回去删掉你所增加的参数:
|
||||
|
||||
```
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
|
||||
GRUB_CMDLINE_LINUX=""
|
||||
```
|
||||
|
||||
然后更新 GRUB 配置文件:
|
||||
|
||||
```
|
||||
sudo update-grub
|
||||
```
|
||||
|
||||
### 尾声
|
||||
|
||||
在这篇文章中,我介绍了在 Linux 上**禁用 IPv6** 的方法,并简述了什么是 IPv6 以及可能想要禁用掉它的原因。
|
||||
|
||||
那么,这篇文章对你有用吗?你有禁用掉 IPv6 连接吗?让我们评论区见吧~
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/disable-ipv6-ubuntu-linux/
|
||||
|
||||
作者:[Sergiu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[rakino](https://github.com/rakino)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/sergiu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/IPv6
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/05/disable_ipv6_ubuntu.png?fit=800%2C450&ssl=1
|
||||
[3]: https://www.google.com/intl/en/ipv6/statistics.html
|
||||
[4]: https://whatismyipaddress.com/ipv6-issues
|
||||
[5]: https://www.internetsociety.org/blog/2015/01/ipv6-security-myth-1-im-not-running-ipv6-so-i-dont-have-to-worry/
|
||||
[6]: https://itsfoss.com/remove-drive-icons-from-unity-launcher-in-ubuntu/
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/05/ipv6_address_ubuntu.png?fit=800%2C517&ssl=1
|
||||
[8]: https://linux.cn/article-10804-1.html
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/05/ipv6_disabled_ubuntu.png?fit=800%2C442&ssl=1
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/05/sysctl_configuration.jpg?fit=800%2C554&ssl=1
|
||||
[11]: https://linuxhandbook.com/chmod-command/
|
||||
[12]: https://itsfoss.com/find-which-kernel-version-is-running-in-ubuntu/
|
||||
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/05/grub_configuration-1.jpg?fit=800%2C565&ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/05/ipv6_address_ubuntu-1.png?fit=800%2C517&ssl=1
|
132
published/20190822 Things You Didn-t Know About GNU Readline.md
Normal file
132
published/20190822 Things You Didn-t Know About GNU Readline.md
Normal file
@ -0,0 +1,132 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (rakino)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12706-1.html)
|
||||
[#]: subject: (Things You Didn't Know About GNU Readline)
|
||||
[#]: via: (https://twobithistory.org/2019/08/22/readline.html)
|
||||
[#]: author: (Two-Bit History https://twobithistory.org)
|
||||
|
||||
你所不知的 GNU Readline
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202010/10/222755etdndudtu97wddz7.jpg)
|
||||
|
||||
有时我会觉得自己的计算机是一栋非常大的房子,我每天都会访问这栋房子,也对一楼的大部分房间都了如指掌,但仍然还是有我没有去过的卧室,有我没有打开过的衣柜,有我没有探索过的犄角旮旯。我感到有必要更多地了解我的计算机了,就像任何人都会觉得有必要看看自己家里从未去过的房间一样。
|
||||
|
||||
GNU Readline 是个不起眼的小软件库,我依赖了它多年却没有意识到它的存在,也许有成千上万的人每天都在不经意间使用它。如果你用 Bash shell 的话,每当你自动补全一个文件名,或者在输入的一行文本中移动光标,以及搜索之前命令的历史记录时,你都在使用 GNU Readline;当你在 Postgres(`psql`)或是 Ruby REPL(`irb`)的命令行界面中进行同样的操作时,你依然在使用 GNU Readline。很多软件都依赖 GNU Readline 库来实现用户所期望的功能,不过这些功能是如此的辅助与不显眼,以至于在我看来很少有人会停下来去想它是从哪里来的。
|
||||
|
||||
GNU Readline 最初是自由软件基金会在 20 世纪 80 年代创建的,如今作为每个人的基础计算设施的重要的、甚至看不见的组成部分的它,由一位志愿者维护。
|
||||
|
||||
### 充满特色
|
||||
|
||||
GNU Readline 库的存在,主要是为了增强各种命令行界面,它提供了一组通用的按键,使你可以在一个单行输入中移动和编辑。例如,在 Bash 提示符中按下 `Ctrl-A`,你的光标会跳到行首,而按下 `Ctrl-E` 则会跳到行末;另一个有用的命令是 `Ctrl-U`,它会删除该行中光标之前的所有内容。
|
||||
|
||||
有很长一段时间,我通过反复敲击方向键来在命令行上移动,如今看来这十分尴尬,也不知道为什么,当时的我从来没有想过可以有一种更快的方法。当然了,没有哪一个熟悉 Vim 或 Emacs 这种文本编辑器的程序员愿意长时间地击打方向键,所以像 Readline 这样的东西必然会被创造出来。在 Readline 上可以做的绝非仅仅跳来跳去,你可以像使用文本编辑器那样编辑单行文本——这里有删除单词、单词换位、大写单词、复制和粘贴字符等命令。Readline 的大部分按键/快捷键都是基于 Emacs 的,它基本上就是一个单行文本版的 Emacs 了,甚至还有录制和重放宏的功能。
|
||||
|
||||
我从来没有用过 Emacs,所以很难记住所有不同的 Readline 命令。不过 Readline 有着很巧妙的一点,那就是能够切换到基于 Vim 的模式,在 Bash 中可以使用内置的 `set` 命令来这样做。下面会让 Readline 在当前的 shell 中使用 Vim 风格的命令:
|
||||
|
||||
```
|
||||
$ set -o vi
|
||||
```
|
||||
|
||||
该选项启用后,就可以使用 `dw` 等命令来删除单词了,此时相当于 Emacs 模式下的 `Ctrl-U` 的命令是 `d0`。
|
||||
|
||||
我第一次知道有这个功能的时候很兴奋地想尝试一下,但它对我来说并不是那么好用。我很高兴知道有这种对 Vim 用户的让步,在使用这个功能上你可能会比我更幸运,尤其是你还没有使用 Readline 的默认按键的话;我的问题在于,我听说有基于 Vim 的界面时已经学会了几种默认按键,因此即使启用了 Vim 的选项,也一直在错误地用着默认的按键;另外因为没有某种指示器,所以 Vim 的模态设计在这里会很尴尬——你很容易就忘记了自己处于哪个模式,就因为这样,我卡在了一种虽然使用 Vim 作为文本编辑器,但却在 Readline 上用着 Emacs 风格的命令的情况里,我猜其他很多人也是这样的。
|
||||
|
||||
如果你觉得 Vim 和 Emacs 的键盘命令系统诡异而神秘(这并不是没有道理的),你可以按照喜欢的方式自定义 Readline 的键绑定。Readline 在启动时会读取文件 `~/.inputrc`,它可以用来配置各种选项与键绑定,我做的一件事是重新配置了 `Ctrl-K`:通常情况下该命令会从光标处删除到行末,但我很少这样做,所以我在 `~/.inputrc` 中添加了以下内容,把它绑定为直接删除整行:
|
||||
|
||||
```
|
||||
Control-k: kill-whole-line
|
||||
```
|
||||
|
||||
每个 Readline 命令(文档中称它们为 “函数” )都有一个名称,你可以用这种方式将其与一个键序列联系起来。如果你在 Vim 中编辑 `~/.inputrc`,就会发现 Vim 知道这种文件类型,还会帮你高亮显示有效的函数名,而不高亮无效的函数名。
|
||||
|
||||
`~/.inputrc` 可以做的另一件事是通过将键序列映射到输入字符串上来创建预制宏。[Readline 手册][1]给出了一个我认为特别有用的例子:我经常想把一个程序的输出保存到文件中,这意味着我得经常在 Bash 命令中追加类似 `> output.txt` 这样的东西,为了节省时间,可以把它做成一个 Readline 宏:
|
||||
|
||||
```
|
||||
Control-o: "> output.txt"
|
||||
```
|
||||
|
||||
这样每当你按下 `Ctrl-O` 时,你都会看到 `> output.txt` 被添加到了命令行光标的后面,这样很不错!
|
||||
|
||||
不过你可以用宏做的可不仅仅是为文本串创建快捷方式;在 `~/.inputrc` 中使用以下条目意味着每次按下 `Ctrl-J` 时,行内已有的文本都会被 `$(` 和 `)` 包裹住。该宏先用 `Ctrl-A` 移动到行首,添加 `$(` ,然后再用 `Ctrl-E` 移动到行尾,添加 `)`:
|
||||
|
||||
```
|
||||
Control-j: "\C-a$(\C-e)"
|
||||
```
|
||||
|
||||
如果你经常需要像下面这样把一个命令的输出用于另一个命令的话,这个宏可能会对你有帮助:
|
||||
|
||||
```
|
||||
$ cd $(brew --prefix)
|
||||
```
|
||||
|
||||
`~/.inputrc` 文件也允许你为 Readline 手册中所谓的 “变量” 设置不同的值,这些变量会启用或禁用某些 Readline 行为,你也可以使用这些变量来改变 Readline 中像是自动补全或者历史搜索这些行为的工作方式。我建议开启的一个变量是 `revert-all-at-newline`,它是默认关闭的,当这个变量关闭时,如果你使用反向搜索功能从命令历史记录中提取一行并编辑,但随后又决定搜索另一行,那么你所做的编辑会被保存在历史记录中。我觉得这样会很混乱,因为这会导致你的 Bash 命令历史中出现从未运行过的行。所以在你的 `~/.inputrc` 中加入这个:
|
||||
|
||||
```
|
||||
set revert-all-at-newline on
|
||||
```
|
||||
|
||||
在你用 `~/.inputrc` 设置了选项或键绑定以后,它们会适用于任何使用 Readline 库的地方,显然 Bash 也包括在内,不过你也会在其它像是 `irb` 和 `psql` 这样的程序中受益。如果你经常使用关系型数据库的命令行界面,一个用于插入 `SELECT * FROM` 的 Readline 宏可能会很有用。
|
||||
|
||||
### Chet Ramey
|
||||
|
||||
GNU Readline 如今由凯斯西储大学的高级技术架构师 Chet Ramey 维护,Ramey 同时还负责维护 Bash shell;这两个项目都是由一位名叫 Brian Fox 的自由软件基金会员工在 1988 年开始编写的,但从 1994 年左右开始,Ramey 一直是它们唯一的维护者。
|
||||
|
||||
Ramey 通过电子邮件告诉我,Readline 远非一个原创的想法,它是为了实现 POSIX 规范所规定的功能而被创建的,而 POSIX 规范又是在 20 世纪 80 年代末被制定的。许多早期的 shell,包括 Korn shell 和至少一个版本的 Unix System V shell,都包含行编辑功能。1988 年版的 Korn shell(`ksh88`)提供了 Emacs 风格和 Vi/Vim 风格的编辑模式。据我从[手册页][2]中得知,Korn shell 会通过查看 `VISUAL` 和 `EDITOR` 环境变量来决定你使用的模式,这一点非常巧妙。POSIX 中指定 shell 功能的部分近似于 `ksh88` 的实现,所以 GNU Bash 也要实现一个类似的灵活的行编辑系统来保持兼容,因此就有了 Readline。
|
||||
|
||||
Ramey 第一次参与 Bash 开发时,Readline 还是 Bash 项目目录下的一个单一的源文件,它其实只是 Bash 的一部分;随着时间的推移,Readline 文件慢慢地成为了独立的项目,不过直到 1994 年(Readline 2.0 版本发布),Readline 才完全成为了一个独立的库。
|
||||
|
||||
Readline 与 Bash 密切相关,Ramey 也通常把 Readline 与 Bash 的发布配对,但正如我上面提到的,Readline 是一个可以被任何有命令行界面的软件使用的库,而且它真的很容易使用。下面是一个例子,虽然简单,但这就是在 C 程序中使用 Readline 的方法。向 `readline()` 函数传递的字符串参数就是你希望 Readline 向用户显示的提示符:
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "readline/readline.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char* line = readline("my-rl-example> ");
|
||||
printf("You entered: \"%s\"\n", line);
|
||||
|
||||
free(line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
你的程序会把控制权交给 Readline,它会负责从用户那里获得一行输入(以这样的方式让用户可以做所有花哨的行编辑工作),一旦用户真正提交了这一行,Readline 就会把它返回给你。在我的库搜索路径中有 Readline 库,所以我可以通过调用以下内容来链接 Readline 库,从而编译上面的内容:
|
||||
|
||||
```
|
||||
$ gcc main.c -lreadline
|
||||
```
|
||||
|
||||
当然,Readline 的 API 比起那个单一的函数要丰富得多,任何使用它的人都可以对库的行为进行各种调整,库的用户(开发者)甚至可以添加新的函数,来让最终用户可以通过 `~/.inputrc` 来配置它们,这意味着 Readline 非常容易扩展。但是据我所知,即使是 Bash ,虽然事先有很多配置,最终也会像上面的例子一样调用简单的 `readline()` 函数来获取输入。(参见 GNU Bash 源代码中的[这一行][3],Bash 似乎在这里将获取输入的责任交给了 Readline)。
|
||||
|
||||
Ramey 现在已经在 Bash 和 Readline 上工作了二十多年,但他的工作却从来没有得到过报酬 —— 他一直都是一名志愿者。Bash 和 Readline 仍然在积极开发中,尽管 Ramey 说 Readline 的变化比 Bash 慢得多。我问 Ramey 作为这么多人使用的软件唯一的维护者是什么感觉,他说可能有几百万人在不知不觉中使用 Bash(因为每个苹果设备都运行 Bash),这让他担心一个破坏性的变化会造成多大的混乱,不过他已经慢慢习惯了所有这些人的想法。他还说他会继续在 Bash 和 Readline 上工作,因为在这一点上他已经深深地投入了,而且他也只是单纯地喜欢把有用的软件提供给世界。
|
||||
|
||||
_你可以在 [Chet Ramey 的网站][4]上找到更多关于他的信息。_
|
||||
|
||||
_喜欢这篇文章吗?我会每四周写出一篇像这样的文章。关注推特帐号 [@TwoBitHistory][5] 或者[订阅 RSS][6] 来获取更新吧!_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://twobithistory.org/2019/08/22/readline.html
|
||||
|
||||
作者:[Two-Bit History][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[rakino](https://github.com/rakino)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://twobithistory.org
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://tiswww.case.edu/php/chet/readline/readline.html
|
||||
[2]: https://web.archive.org/web/20151105130220/http://www2.research.att.com/sw/download/man/man1/ksh88.html
|
||||
[3]: https://github.com/bminor/bash/blob/9f597fd10993313262cab400bf3c46ffb3f6fd1e/parse.y#L1487
|
||||
[4]: https://tiswww.case.edu/php/chet/
|
||||
[5]: https://twitter.com/TwoBitHistory
|
||||
[6]: https://twobithistory.org/feed.xml
|
||||
[7]: https://twitter.com/TwoBitHistory/status/1112492084383092738?ref_src=twsrc%5Etfw
|
@ -0,0 +1,159 @@
|
||||
MidnightBSD:或许是你通往 FreeBSD 的大门
|
||||
======
|
||||
|
||||
![](https://www.linux.com/wp-content/uploads/2019/08/midnight_4_0.jpg)
|
||||
|
||||
[FreeBSD][1] 是一个开源操作系统,衍生自著名的 <ruby>[伯克利软件套件][2]<rt>Berkeley Software Distribution</rt></ruby>(BSD)。FreeBSD 的第一个版本发布于 1993 年,并且仍然在继续发展。2007 年左右,Lucas Holt 想要利用 OpenStep(现在是 Cocoa)的 Objective-C 框架、widget 工具包和应用程序开发工具的 [GnuStep][3] 实现,来创建一个 FreeBSD 的分支。为此,他开始开发 MidnightBSD 桌面发行版。
|
||||
|
||||
MidnightBSD(以 Lucas 的猫 Midnight 命名)仍然在积极地(尽管缓慢)开发。从 2017 年 8 月开始,可以获得最新的稳定发布版本(0.8.6)(LCTT 译注:截止至本译文发布时,当前是 2019/10/31 发布的 1.2 版)。尽管 BSD 发行版不是你所说的用户友好型发行版,但上手安装是熟悉如何处理 文本(ncurses)安装过程以及通过命令行完成安装的好方法。
|
||||
|
||||
这样,你最终会得到一个非常可靠的 FreeBSD 分支的桌面发行版。这需要花费一点精力,但是如果你是一名正在寻找扩展你的技能的 Linux 用户……这是一个很好的起点。
|
||||
|
||||
我将带你走过安装 MidnightBSD 的流程,如何添加一个图形桌面环境,然后如何安装应用程序。
|
||||
|
||||
### 安装
|
||||
|
||||
正如我所提到的,这是一个文本(ncurses)安装过程,因此在这里找不到可以用鼠标点击的地方。相反,你将使用你键盘的 `Tab` 键和箭头键。在你下载[最新的发布版本][4]后,将它刻录到一个 CD/DVD 或 USB 驱动器,并启动你的机器(或者在 [VirtualBox][5] 中创建一个虚拟机)。安装程序将打开并给你三个选项(图 1)。使用你的键盘的箭头键选择 “Install”,并敲击回车键。
|
||||
|
||||
![MidnightBSD installer][6]
|
||||
|
||||
*图 1: 启动 MidnightBSD 安装程序。*
|
||||
|
||||
在这里要经历相当多的屏幕。其中很多屏幕是一目了然的:
|
||||
|
||||
1. 设置非默认键盘映射(是/否)
|
||||
2. 设置主机名称
|
||||
3. 添加可选系统组件(文档、游戏、32 位兼容性、系统源码代码)
|
||||
4. 对硬盘分区
|
||||
5. 管理员密码
|
||||
6. 配置网络接口
|
||||
7. 选择地区(时区)
|
||||
8. 启用服务(例如 ssh)
|
||||
9. 添加用户(图 2)
|
||||
|
||||
![Adding a user][7]
|
||||
|
||||
*图 2: 向系统添加一个用户。*
|
||||
|
||||
在你向系统添加用户后,你将被进入到一个窗口中(图 3),在这里,你可以处理任何你可能忘记配置或你想重新配置的东西。如果你不需要作出任何更改,选择 “Exit”,然后你的配置就会被应用。
|
||||
|
||||
![Applying your configurations][8]
|
||||
|
||||
*图 3: 应用你的配置。*
|
||||
|
||||
在接下来的窗口中,当出现提示时,选择 “No”,接下来系统将重启。在 MidnightBSD 重启后,你已经为下一阶段的安装做好了准备。
|
||||
|
||||
### 后安装阶段
|
||||
|
||||
当你最新安装的 MidnightBSD 启动时,你将发现你自己处于命令提示符当中。此刻,还没有图形界面。要安装应用程序,MidnightBSD 依赖于 `mport` 工具。比如说你想安装 Xfce 桌面环境。为此,登录到 MidnightBSD 中,并发出下面的命令:
|
||||
|
||||
```
|
||||
sudo mport index
|
||||
sudo mport install xorg
|
||||
```
|
||||
|
||||
你现在已经安装好 Xorg 窗口服务器了,它允许你安装桌面环境。使用命令来安装 Xfce :
|
||||
|
||||
```
|
||||
sudo mport install xfce
|
||||
```
|
||||
|
||||
现在 Xfce 已经安装好。不过,我们必须让它同命令 `startx` 一起启用。为此,让我们先安装 nano 编辑器。发出命令:
|
||||
|
||||
```
|
||||
sudo mport install nano
|
||||
```
|
||||
|
||||
随着 nano 安装好,发出命令:
|
||||
|
||||
```
|
||||
nano ~/.xinitrc
|
||||
```
|
||||
|
||||
这个文件仅包含一行内容:
|
||||
|
||||
```
|
||||
exec startxfce4
|
||||
```
|
||||
|
||||
保存并关闭这个文件。如果你现在发出命令 `startx`, Xfce 桌面环境将会启动。你应该会感到有点熟悉了吧(图 4)。
|
||||
|
||||
![ Xfce][9]
|
||||
|
||||
*图 4: Xfce 桌面界面已准备好服务。*
|
||||
|
||||
因为你不会总是想必须发出命令 `startx`,你希望启用登录守护进程。然而,它却没有安装。要安装这个子系统,发出命令:
|
||||
|
||||
```
|
||||
sudo mport install mlogind
|
||||
```
|
||||
|
||||
当完成安装后,通过在 `/etc/rc.conf` 文件中添加一个项目来在启动时启用 mlogind。在 `rc.conf` 文件的底部,添加以下内容:
|
||||
|
||||
```
|
||||
mlogind_enable=”YES”
|
||||
```
|
||||
|
||||
保存并关闭该文件。现在,当你启动(或重启)机器时,你应该会看到图形登录屏幕。在写这篇文章的时候,在登录后我最后得到一个空白屏幕和讨厌的 X 光标。不幸的是,目前似乎并没有这个问题的解决方法。所以,要访问你的桌面环境,你必须使用 `startx` 命令。
|
||||
|
||||
### 安装应用
|
||||
|
||||
默认情况下,你找不到很多能可用的应用程序。如果你尝试使用 `mport` 安装应用程序,你很快就会感到沮丧,因为只能找到很少的应用程序。为解决这个问题,我们需要使用 `svnlite` 命令来查看检出的可用 mport 软件列表。回到终端窗口,并发出命令:
|
||||
|
||||
```
|
||||
svnlite co http://svn.midnightbsd.org/svn/mports/trunk mports
|
||||
```
|
||||
|
||||
在你完成这些后,你应该看到一个命名为 `~/mports` 的新目录。使用命令 `cd ~/.mports` 更改到这个目录。发出 `ls` 命令,然后你应该看到许多的类别(图 5)。
|
||||
|
||||
![applications][10]
|
||||
|
||||
*图 5: mport 现在可用的应用程序类别。*
|
||||
|
||||
你想安装 Firefox 吗?如果你查看 `www` 目录,你将看到一个 `linux-firefox` 列表。发出命令:
|
||||
|
||||
```
|
||||
sudo mport install linux-firefox
|
||||
```
|
||||
|
||||
现在你应该会在 Xfce 桌面菜单中看到一个 Firefox 项。翻找所有的类别,并使用 `mport` 命令来安装你需要的所有软件。
|
||||
|
||||
### 一个悲哀的警告
|
||||
|
||||
一个悲哀的小警告是,`mport` (通过 `svnlite`)仅能找到的一个办公套件的版本是 OpenOffice 3 。那是非常过时的。尽管在 `~/mports/editors` 目录中能找到 Abiword ,但是它看起来不能安装。甚至在安装 OpenOffice 3 后,它会输出一个执行格式错误。换句话说,你不能使用 MidnightBSD 在办公生产效率方面做很多的事情。但是,嘿嘿,如果你周围正好有一个旧的 Palm Pilot,你可以安装 pilot-link。换句话说,可用的软件不足以构成一个极其有用的桌面发行版……至少对普通用户不是。但是,如果你想在 MidnightBSD 上开发,你将找到很多可用的工具可以安装(查看 `~/mports/devel` 目录)。你甚至可以使用命令安装 Drupal :
|
||||
|
||||
```
|
||||
sudo mport install drupal7
|
||||
```
|
||||
|
||||
当然,在此之后,你将需要创建一个数据库(MySQL 已经安装)、安装 Apache(`sudo mport install apache24`),并配置必要的 Apache 配置。
|
||||
|
||||
显然地,已安装的和可以安装的是一个应用程序、系统和服务的大杂烩。但是随着足够多的工作,你最终可以得到一个能够服务于特殊目的的发行版。
|
||||
|
||||
### 享受 \*BSD 优良
|
||||
|
||||
这就是如何使 MidnightBSD 启动,并使其运行某种有用的桌面发行版的方法。它不像很多其它的 Linux 发行版一样快速简便,但是如果你想要一个促使你思考的发行版,这可能正是你正在寻找的。尽管大多数竞争对手都准备了很多可以安装的应用软件,但 MidnightBSD 无疑是一个 Linux 爱好者或管理员应该尝试的有趣挑战。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2018/5/midnightbsd-could-be-your-gateway-freebsd
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/jlwallen
|
||||
[1]:https://www.freebsd.org/
|
||||
[2]:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
|
||||
[3]:https://en.wikipedia.org/wiki/GNUstep
|
||||
[4]:http://www.midnightbsd.org/download/
|
||||
[5]:https://www.virtualbox.org/
|
||||
[6]:https://lcom.static.linuxfound.org/sites/lcom/files/midnight_1.jpg (MidnightBSD installer)
|
||||
[7]:https://lcom.static.linuxfound.org/sites/lcom/files/midnight_2.jpg (Adding a user)
|
||||
[8]:https://lcom.static.linuxfound.org/sites/lcom/files/mightnight_3.jpg (Applying your configurations)
|
||||
[9]:https://lcom.static.linuxfound.org/sites/lcom/files/midnight_4.jpg (Xfce)
|
||||
[10]:https://lcom.static.linuxfound.org/sites/lcom/files/midnight_5.jpg (applications)
|
||||
[11]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -0,0 +1,150 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11938-1.html)
|
||||
[#]: subject: (Some Advice for How to Make Emacs Tetris Harder)
|
||||
[#]: via: (https://nickdrozd.github.io/2019/01/14/tetris.html)
|
||||
[#]: author: (nickdrozd https://nickdrozd.github.io)
|
||||
|
||||
如何让 Emacs 俄罗斯方块变得更难
|
||||
======
|
||||
|
||||
你知道吗,Emacs 捆绑了一个俄罗斯方块的实现?只需要输入 `M-x tetris` 就行了。
|
||||
|
||||
![](https://nickdrozd.github.io/assets/2019-01-14-tetris/tetris-normal.png)
|
||||
|
||||
在对文本编辑器的讨论中,Emacs 鼓吹者经常提到这一点。“没错,但是你那个编辑器能运行俄罗斯方块吗?”我很好奇,这会让大家相信 Emacs 更优秀吗?比如,为什么有人会关心他们是否可以在文本编辑器中玩游戏呢?“没错,但是你那台吸尘器能播放 mp3 吗?”
|
||||
|
||||
有人说,俄罗斯方块总是很有趣的。像 Emacs 中的所有东西一样,它的源代码是开放的,易于检查和修改,因此 **我们可以使它变得更加有趣**。所谓更加有趣,我的意思是更难。
|
||||
|
||||
让游戏变得更难的一个最简单的方法就是“隐藏下一个块预览”。你无法在知道下一个块会填满空间的情况下有意地将 S/Z 块放在一个危险的位置——你必须碰碰运气,希望出现最好的情况。下面是没有预览的情况(如你所见,没有预览,我做出的某些选择带来了“可怕的后果”):
|
||||
|
||||
![](https://nickdrozd.github.io/assets/2019-01-14-tetris/tetris-no-preview.png)
|
||||
|
||||
预览框由一个名为 `tetris-draw-next-shape` [^1] 的函数设置:
|
||||
|
||||
```
|
||||
(defun tetris-draw-next-shape ()
|
||||
(dotimes (x 4)
|
||||
(dotimes (y 4)
|
||||
(gamegrid-set-cell (+ tetris-next-x x)
|
||||
(+ tetris-next-y y)
|
||||
tetris-blank)))
|
||||
(dotimes (i 4)
|
||||
(let ((tetris-shape tetris-next-shape)
|
||||
(tetris-rot 0))
|
||||
(gamegrid-set-cell (+ tetris-next-x
|
||||
(aref (tetris-get-shape-cell i) 0))
|
||||
(+ tetris-next-y
|
||||
(aref (tetris-get-shape-cell i) 1))
|
||||
tetris-shape))))
|
||||
```
|
||||
|
||||
首先,我们引入一个标志,决定是否允许显示下一个预览块 [^2]:
|
||||
|
||||
```
|
||||
(defvar tetris-preview-next-shape nil
|
||||
"When non-nil, show the next block the preview box.")
|
||||
```
|
||||
|
||||
现在的问题是,我们如何才能让 `tetris-draw-next-shape` 遵从这个标志?最明显的方法是重新定义它:
|
||||
|
||||
```
|
||||
(defun tetris-draw-next-shape ()
|
||||
(when tetris-preview-next-shape
|
||||
;; existing tetris-draw-next-shape logic
|
||||
))
|
||||
```
|
||||
|
||||
但这不是理想的解决方案。同一个函数有两个定义,这很容易引起混淆,如果上游版本发生变化,我们必须维护修改后的定义。
|
||||
|
||||
一个更好的方法是使用 **advice**。Emacs 的 advice 类似于 **Python 装饰器**,但是更加灵活,因为 advice 可以从任何地方添加到函数中。这意味着我们可以修改函数而不影响原始的源文件。
|
||||
|
||||
有很多不同的方法使用 Emacs advice([查看手册][4]),但是这里我们只使用 `advice-add` 函数和 `:around` 标志。advice 函数将原始函数作为参数,原始函数可能执行也可能不执行。我们这里,我们让原始函数只有在预览标志是非空的情况下才能执行:
|
||||
|
||||
```
|
||||
(defun tetris-maybe-draw-next-shape (tetris-draw-next-shape)
|
||||
(when tetris-preview-next-shape
|
||||
(funcall tetris-draw-next-shape)))
|
||||
|
||||
(advice-add 'tetris-draw-next-shape :around #'tetris-maybe-draw-next-shape)
|
||||
```
|
||||
|
||||
这段代码将修改 `tetris-draw-next-shape` 的行为,而且它可以存储在配置文件中,与实际的俄罗斯方块代码分离。
|
||||
|
||||
去掉预览框是一个简单的改变。一个更激烈的变化是,**让块随机停止在空中**:
|
||||
|
||||
![](https://nickdrozd.github.io/assets/2019-01-14-tetris/tetris-air.png)
|
||||
|
||||
本图中,红色的 I 和绿色的 T 部分没有掉下来,它们被固定下来了。这会让游戏变得 **极其困难**,但却很容易实现。
|
||||
|
||||
和前面一样,我们首先定义一个标志:
|
||||
|
||||
```
|
||||
(defvar tetris-stop-midair t
|
||||
"If non-nil, pieces will sometimes stop in the air.")
|
||||
```
|
||||
|
||||
目前,**Emacs 俄罗斯方块的工作方式** 类似这样子:活动部件有 x 和 y 坐标。在每个时钟滴答声中,y 坐标递增(块向下移动一行),然后检查是否有与现存的块重叠。如果检测到重叠,则将该块回退(其 y 坐标递减)并设置该活动块到位。为了让一个块在半空中停下来,我们所要做的就是破解检测函数 `tetris-test-shape`。
|
||||
|
||||
**这个函数内部做什么并不重要** —— 重要的是它是一个返回布尔值的无参数函数。我们需要它在正常情况下返回布尔值 true(否则我们将出现奇怪的重叠情况),但在其他时候也需要它返回 true。我相信有很多方法可以做到这一点,以下是我的方法的:
|
||||
|
||||
```
|
||||
(defun tetris-test-shape-random (tetris-test-shape)
|
||||
(or (and
|
||||
tetris-stop-midair
|
||||
;; Don't stop on the first shape.
|
||||
(< 1 tetris-n-shapes )
|
||||
;; Stop every INTERVAL pieces.
|
||||
(let ((interval 7))
|
||||
(zerop (mod tetris-n-shapes interval)))
|
||||
;; Don't stop too early (it makes the game unplayable).
|
||||
(let ((upper-limit 8))
|
||||
(< upper-limit tetris-pos-y))
|
||||
;; Don't stop at the same place every time.
|
||||
(zerop (mod (random 7) 10)))
|
||||
(funcall tetris-test-shape)))
|
||||
|
||||
(advice-add 'tetris-test-shape :around #'tetris-test-shape-random)
|
||||
```
|
||||
|
||||
这里的硬编码参数使游戏变得更困难,但仍然可玩。当时我在飞机上喝醉了,所以它们可能需要进一步调整。
|
||||
|
||||
顺便说一下,根据我的 `tetris-scores` 文件,我的 **最高分** 是:
|
||||
|
||||
```
|
||||
01389 Wed Dec 5 15:32:19 2018
|
||||
```
|
||||
|
||||
该文件中列出的分数默认最多为五位数,因此这个分数看起来不是很好。
|
||||
|
||||
### 给读者的练习
|
||||
|
||||
1. 使用 advice 修改 Emacs 俄罗斯方块,使得每当方块下移动时就闪烁显示讯息 “OH SHIT”。消息的大小与块堆的高度成比例(当没有块时,消息应该很小的或不存在的,当最高块接近天花板时,消息应该很大)。
|
||||
2. 在这里给出的 `tetris-test-shape-random` 版本中,每隔七格就有一个半空中停止。一个玩家有可能能计算出时间间隔,并利用它来获得优势。修改它,使间隔随机在一些合理的范围内(例如,每 5 到 10 格)。
|
||||
3. 另一个对使用 Tetris 使用 advise 的场景,你可以试试 [autotetris-mode][1]。
|
||||
4. 想出一个有趣的方法来打乱块的旋转机制,然后使用 advice 来实现它。
|
||||
|
||||
[^1]: Emacs 只有一个巨大的全局命名空间,因此函数和变量名一般以包名做前缀以避免冲突。
|
||||
[^2]: 很多人会说你不应该使用已有的命名空间前缀而且应该将自己定义的所有东西都放在一个预留的命名空间中,比如像这样 `my/tetris-preview-next-shape`,然而这样很难看而且没什么意义,因此我不会这么干。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://nickdrozd.github.io/2019/01/14/tetris.html
|
||||
|
||||
作者:[nickdrozd][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nickdrozd.github.io
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://nullprogram.com/blog/2014/10/19/
|
||||
[2]: https://nickdrozd.github.io/2019/01/14/tetris.html#fn.1
|
||||
[3]: https://nickdrozd.github.io/2019/01/14/tetris.html#fn.2
|
||||
[4]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html
|
||||
[5]: https://nickdrozd.github.io/2019/01/14/tetris.html#fnr.1
|
||||
[6]: https://nickdrozd.github.io/2019/01/14/tetris.html#fnr.2
|
@ -1,21 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11913-1.html)
|
||||
[#]: subject: (Zipping files on Linux: the many variations and how to use them)
|
||||
[#]: via: (https://www.networkworld.com/article/3333640/linux/zipping-files-on-linux-the-many-variations-and-how-to-use-them.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
Zipping files on Linux: the many variations and how to use them
|
||||
在 Linux 上压缩文件:zip 命令的各种变体及用法
|
||||
======
|
||||
![](https://images.idgesg.net/images/article/2019/01/zipper-100785364-large.jpg)
|
||||
|
||||
Some of us have been zipping files on Unix and Linux systems for many decades — to save some disk space and package files together for archiving. Even so, there are some interesting variations on zipping that not all of us have tried. So, in this post, we’re going to look at standard zipping and unzipping as well as some other interesting zipping options.
|
||||
> 除了压缩和解压缩文件外,你还可以使用 zip 命令执行许多有趣的操作。这是一些其他的 zip 选项以及它们如何提供帮助。
|
||||
|
||||
### The basic zip command
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/21/120507ox11ak23f9x2hxaq.jpg)
|
||||
|
||||
First, let’s look at the basic **zip** command. It uses what is essentially the same compression algorithm as **gzip** , but there are a couple important differences. For one thing, the gzip command is used only for compressing a single file where zip can both compress files and join them together into an archive. For another, the gzip command zips “in place”. In other words, it leaves a compressed file — not the original file alongside the compressed copy. Here's an example of gzip at work:
|
||||
为了节省一些磁盘空间并将文件打包在一起进行归档,我们中的一些人已经在 Unix 和 Linux 系统上压缩文件数十年了。即使这样,并不是所有人都尝试过一些有趣的压缩工具的变体。因此,在本文中,我们将介绍标准的压缩和解压缩以及其他一些有趣的压缩选项。
|
||||
|
||||
### 基本的 zip 命令
|
||||
|
||||
首先,让我们看一下基本的 `zip` 命令。它使用了与 `gzip` 基本上相同的压缩算法,但是有一些重要的区别。一方面,`gzip` 命令仅用于压缩单个文件,而 `zip` 既可以压缩文件,也可以将多个文件结合在一起成为归档文件。另外,`gzip` 命令是“就地”压缩。换句话说,它会只留下一个压缩文件,而原始文件则没有了。 这是工作中的 `gzip` 示例:
|
||||
|
||||
```
|
||||
$ gzip onefile
|
||||
@ -23,7 +26,7 @@ $ ls -l
|
||||
-rw-rw-r-- 1 shs shs 10514 Jan 15 13:13 onefile.gz
|
||||
```
|
||||
|
||||
And here's zip. Notice how this command requires that a name be provided for the zipped archive where gzip simply uses the original file name and adds the .gz extension.
|
||||
而下面是 `zip`。请注意,此命令要求为压缩存档提供名称,其中 `gzip`(执行压缩操作后)仅使用原始文件名并添加 `.gz` 扩展名。
|
||||
|
||||
```
|
||||
$ zip twofiles.zip file*
|
||||
@ -35,9 +38,9 @@ $ ls -l
|
||||
-rw-rw-r-- 1 shs shs 21289 Jan 15 13:35 twofiles.zip
|
||||
```
|
||||
|
||||
Notice also that the original files are still sitting there.
|
||||
请注意,原始文件仍位于原处。
|
||||
|
||||
The amount of disk space that is saved (i.e., the degree of compression obtained) will depend on the content of each file. The variation in the example below is considerable.
|
||||
所节省的磁盘空间量(即获得的压缩程度)将取决于每个文件的内容。以下示例中的变化很大。
|
||||
|
||||
```
|
||||
$ zip mybin.zip ~/bin/*
|
||||
@ -56,9 +59,9 @@ $ zip mybin.zip ~/bin/*
|
||||
adding: bin/tt (deflated 6%)
|
||||
```
|
||||
|
||||
### The unzip command
|
||||
### unzip 命令
|
||||
|
||||
The **unzip** command will recover the contents from a zip file and, as you'd likely suspect, leave the zip file intact, whereas a similar gunzip command would leave only the uncompressed file.
|
||||
`unzip` 命令将从一个 zip 文件中恢复内容,并且,如你所料,原来的 zip 文件还保留在那里,而类似的 `gunzip` 命令将仅保留未压缩的文件。
|
||||
|
||||
```
|
||||
$ unzip twofiles.zip
|
||||
@ -71,9 +74,9 @@ $ ls -l
|
||||
-rw-rw-r-- 1 shs shs 21289 Jan 15 13:35 twofiles.zip
|
||||
```
|
||||
|
||||
### The zipcloak command
|
||||
### zipcloak 命令
|
||||
|
||||
The **zipcloak** command encrypts a zip file, prompting you to enter a password twice (to help ensure you don't "fat finger" it) and leaves the file in place. You can expect the file size to vary a little from the original.
|
||||
`zipcloak` 命令对一个 zip 文件进行加密,提示你输入两次密码(以确保你不会“胖手指”),然后将该文件原位存储。你可以想到,文件大小与原始文件会有所不同。
|
||||
|
||||
```
|
||||
$ zipcloak twofiles.zip
|
||||
@ -89,11 +92,11 @@ total 204
|
||||
unencrypted version
|
||||
```
|
||||
|
||||
Keep in mind that the original files are still sitting there unencrypted.
|
||||
请记住,压缩包之外的原始文件仍处于未加密状态。
|
||||
|
||||
### The zipdetails command
|
||||
### zipdetails 命令
|
||||
|
||||
The **zipdetails** command is going to show you details — a _lot_ of details about a zipped file, likely a lot more than you care to absorb. Even though we're looking at an encrypted file, zipdetails does display the file names along with file modification dates, user and group information, file length data, etc. Keep in mind that this is all "metadata." We don't see the contents of the files.
|
||||
`zipdetails` 命令将向你显示详细信息:有关压缩文件的详细信息,可能比你想象的要多得多。即使我们正在查看一个加密的文件,`zipdetails` 也会显示文件名以及文件修改日期、用户和组信息、文件长度数据等。请记住,这都是“元数据”。我们看不到文件的内容。
|
||||
|
||||
```
|
||||
$ zipdetails twofiles.zip
|
||||
@ -233,9 +236,9 @@ $ zipdetails twofiles.zip
|
||||
Done
|
||||
```
|
||||
|
||||
### The zipgrep command
|
||||
### zipgrep命令
|
||||
|
||||
The **zipgrep** command is going to use a grep-type feature to locate particular content in your zipped files. If the file is encrypted, you will need to enter the password provided for the encryption for each file you want to examine. If you only want to check the contents of a single file from the archive, add its name to the end of the zipgrep command as shown below.
|
||||
`zipgrep` 命令将使用 `grep` 类的功能来找到压缩文件中的特定内容。如果文件已加密,则需要为要检查的每个文件输入为加密所提供的密码。如果只想检查归档文件中单个文件的内容,请将其名称添加到 `zipgrep` 命令的末尾,如下所示。
|
||||
|
||||
```
|
||||
$ zipgrep hazard twofiles.zip file1
|
||||
@ -243,9 +246,9 @@ $ zipgrep hazard twofiles.zip file1
|
||||
Certain pesticides should be banned since they are hazardous to the environment.
|
||||
```
|
||||
|
||||
### The zipinfo command
|
||||
### zipinfo 命令
|
||||
|
||||
The **zipinfo** command provides information on the contents of a zipped file whether encrypted or not. This includes the file names, sizes, dates and permissions.
|
||||
`zipinfo` 命令提供有关压缩文件内容的信息,无论是否加密。这包括文件名、大小、日期和权限。
|
||||
|
||||
```
|
||||
$ zipinfo twofiles.zip
|
||||
@ -256,9 +259,9 @@ Zip file size: 21313 bytes, number of entries: 2
|
||||
2 files, 116954 bytes uncompressed, 20991 bytes compressed: 82.1%
|
||||
```
|
||||
|
||||
### The zipnote command
|
||||
### zipnote 命令
|
||||
|
||||
The **zipnote** command can be used to extract comments from zip archives or add them. To display comments, just preface the name of the archive with the command. If no comments have been added previously, you will see something like this:
|
||||
`zipnote` 命令可用于从 zip 归档中提取注释或添加注释。要显示注释,只需在命令前面加上归档名称即可。如果之前未添加任何注释,你将看到类似以下内容:
|
||||
|
||||
```
|
||||
$ zipnote twofiles.zip
|
||||
@ -269,21 +272,21 @@ $ zipnote twofiles.zip
|
||||
@ (zip file comment below this line)
|
||||
```
|
||||
|
||||
If you want to add comments, write the output from the zipnote command to a file:
|
||||
如果要添加注释,请先将 `zipnote` 命令的输出写入到文件:
|
||||
|
||||
```
|
||||
$ zipnote twofiles.zip > comments
|
||||
```
|
||||
|
||||
Next, edit the file you've just created, inserting your comments above the **(comment above this line)** lines. Then add the comments using a zipnote command like this one:
|
||||
接下来,编辑你刚刚创建的文件,将注释插入到 `(comment above this line)` 行上方。然后使用像这样的 `zipnote` 命令添加注释:
|
||||
|
||||
```
|
||||
$ zipnote -w twofiles.zip < comments
|
||||
```
|
||||
|
||||
### The zipsplit command
|
||||
### zipsplit 命令
|
||||
|
||||
The **zipsplit** command can be used to break a zip archive into multiple zip archives when the original file is too large — maybe because you're trying to add one of the files to a small thumb drive. The easiest way to do this seems to be to specify the max size for each of the zipped file portions. This size must be large enough to accomodate the largest included file.
|
||||
当归档文件太大时,可以使用 `zipsplit` 命令将一个 zip 归档文件分解为多个 zip 归档文件,这样你就可以将其中某一个文件放到小型 U 盘中。最简单的方法似乎是为每个部分的压缩文件指定最大大小,此大小必须足够大以容纳最大的所包含的文件。
|
||||
|
||||
```
|
||||
$ zipsplit -n 12000 twofiles.zip
|
||||
@ -296,15 +299,11 @@ $ ls twofile*.zip
|
||||
-rw-rw-r-- 1 shs shs 21377 Jan 15 14:27 twofiles.zip
|
||||
```
|
||||
|
||||
Notice how the extracted files are sequentially named "twofile1" and "twofile2".
|
||||
请注意,提取的文件是如何依次命名为 `twofile1` 和 `twofile2` 的。
|
||||
|
||||
### Wrap-up
|
||||
### 总结
|
||||
|
||||
The **zip** command, along with some of its zipping compatriots, provide a lot of control over how you generate and work with compressed file archives.
|
||||
|
||||
**[ Also see:[Invaluable tips and tricks for troubleshooting Linux][1] ]**
|
||||
|
||||
Join the Network World communities on [Facebook][2] and [LinkedIn][3] to comment on topics that are top of mind.
|
||||
`zip` 命令及其一些压缩工具变体,对如何生成和使用压缩文件归档提供了很多控制。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -312,8 +311,8 @@ via: https://www.networkworld.com/article/3333640/linux/zipping-files-on-linux-t
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,113 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zhangxiangping)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11927-1.html)
|
||||
[#]: subject: (12 open source tools for natural language processing)
|
||||
[#]: via: (https://opensource.com/article/19/3/natural-language-processing-tools)
|
||||
[#]: author: (Dan Barker https://opensource.com/users/barkerd427)
|
||||
|
||||
12 种自然语言处理的开源工具
|
||||
======
|
||||
|
||||
> 让我们看看可以用在你自己的 NLP 应用中的十几个工具吧。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/25/103230j77i7zx8uyymj7y3.jpg)
|
||||
|
||||
在过去的几年里,自然语言处理(NLP)推动了聊天机器人、语音助手、文本预测等这些渗透到我们的日常生活中的语音或文本应用程技术的发展。目前有着各种各样开源的 NLP 工具,所以我决定调查一下当前开源的 NLP 工具来帮助你制定开发下一个基于语音或文本的应用程序的计划。
|
||||
|
||||
尽管我并不熟悉所有工具,但我将从我所熟悉的编程语言出发来介绍这些工具(对于我不熟悉的语言,我无法找到大量的工具)。也就是说,出于各种原因,我排除了三种我熟悉的语言之外的工具。
|
||||
|
||||
R 语言可能是没有被包含在内的最重要的语言,因为我发现的大多数库都有一年多没有更新了。这并不一定意味着它们没有得到很好的维护,但我认为它们应该得到更多的更新,以便和同一领域的其他工具竞争。我还选择了最有可能用在生产场景中的语言和工具(而不是在学术界和研究中使用),而我主要是使用 R 作为研究和发现工具。
|
||||
|
||||
我也惊讶地发现 Scala 的很多库都没有更新了。我上次使用 Scala 已经过去了两年了,当时它非常流行。但是大多数库从那个时候就再没有更新过,或者只有少数一些有更新。
|
||||
|
||||
最后,我排除了 C++。 这主要是因为我上次使用 C++ 编写程序已经有很多年了,而我所工作的组织还没有将 C++ 用于 NLP 或任何数据科学方面的工作。
|
||||
|
||||
### Python 工具
|
||||
|
||||
#### 自然语言工具包(NLTK)
|
||||
|
||||
毋庸置疑,[自然语言工具包(NLTK)][2]是我调研过的所有工具中功能最完善的一个。它几乎实现了自然语言处理中多数功能组件,比如分类、令牌化、词干化、标注、分词和语义推理。每一个都有多种不同的实现方式,所以你可以选择具体的算法和方式。同时,它也支持不同的语言。然而,它以字符串的形式表示所有的数据,对于一些简单的数据结构来说可能很方便,但是如果要使用一些高级的功能来说就可能有点困难。它的使用文档有点复杂,但也有很多其他人编写的使用文档,比如[这本很棒的书][3]。和其他的工具比起来,这个工具库的运行速度有点慢。但总的来说,这个工具包非常不错,可以用于需要具体算法组合的实验、探索和实际应用当中。
|
||||
|
||||
#### SpaCy
|
||||
|
||||
[SpaCy][4] 可能是 NLTK 的主要竞争者。在大多数情况下都比 NLTK 的速度更快,但是 SpaCy 的每个自然语言处理的功能组件只有一个实现。SpaCy 把所有的东西都表示为一个对象而不是字符串,从而简化了应用构建接口。这也方便它与多种框架和数据科学工具的集成,使得你更容易理解你的文本数据。然而,SpaCy 不像 NLTK 那样支持多种语言。它确实接口简单,具有简化的选项集和完备的文档,以及用于语言处理和分析各种组件的多种神经网络模型。总的来说,对于需要在生产中表现出色且不需要特定算法的新应用程序,这是一个很不错的工具。
|
||||
|
||||
#### TextBlob
|
||||
|
||||
[TextBlob][5] 是 NLTK 的一个扩展库。你可以通过 TextBlob 用一种更简单的方式来使用 NLTK 的功能,TextBlob 也包括了 Pattern 库中的功能。如果你刚刚开始学习,这将会是一个不错的工具,可以用于对性能要求不太高的生产环境的应用。总体来说,TextBlob 适用于任何场景,但是对小型项目尤佳。
|
||||
|
||||
#### Textacy
|
||||
|
||||
这个工具是我用过的名字最好听的。先重读“ex”再带出“cy”,多读“[Textacy][6]”几次试试。它不仅仅是名字读起来好,同时它本身也是一个很不错的工具。它使用 SpaCy 作为它自然语言处理核心功能,但它在处理过程的前后做了很多工作。如果你想要使用 SpaCy,那么最好使用 Textacy,从而不用去编写额外的附加代码就可以处理不同种类的数据。
|
||||
|
||||
#### PyTorch-NLP
|
||||
|
||||
[PyTorch-NLP][7] 才出现短短的一年,但它已经有一个庞大的社区了。它适用于快速原型开发。当出现了最新的研究,或大公司或者研究人员推出了完成新奇的处理任务的其他工具时,比如图像转换,它就会被更新。总体来说,PyTorch 的目标用户是研究人员,但它也能用于原型开发,或使用最先进算法的初始生产载荷中。基于此基础上的创建的库也是值得研究的。
|
||||
|
||||
### Node.js 工具
|
||||
|
||||
#### Retext
|
||||
|
||||
[Retext][8] 是 [Unified 集合][9]的一部分。Unified 是一个接口,能够集成不同的工具和插件以便它们能够高效的工作。Retext 是 Unified 工具中使用的三种语法之一,另外的两个分别是用于 Markdown 的 Remark 和用于 HTML 的 Rehype。这是一个非常有趣的想法,我很高兴看到这个社区的发展。Retext 没有涉及很多的底层技术,更多的是使用插件去完成你在 NLP 任务中想要做的事情。拼写检查、字形修复、情绪检测和增强可读性都可以用简单的插件来完成。总体来说,如果你不想了解底层处理技术又想完成你的任务的话,这个工具和社区是一个不错的选择。
|
||||
|
||||
#### Compromise
|
||||
|
||||
[Compromise][10] 显然不是最复杂的工具,如果你正在找拥有最先进的算法和最完备的系统的话,它可能不适合你。然而,如果你想要一个性能好、功能广泛、还能在客户端运行的工具的话,Compromise 值得一试。总体来说,它的名字(“折中”)是准确的,因为作者更关注更具体功能的小软件包,而在功能性和准确性上有所折中,这些小软件包得益于用户对使用环境的理解。
|
||||
|
||||
#### Natural
|
||||
|
||||
[Natural][11] 包含了常规自然语言处理库所具有的大多数功能。它主要是处理英文文本,但也包括一些其它语言,它的社区也欢迎支持其它的语言。它能够进行令牌化、词干化、分类、语音处理、词频-逆文档频率计算(TF-IDF)、WordNet、字符相似度计算和一些变换。它和 NLTK 有的一比,因为它想要把所有东西都包含在一个包里头,但它更易于使用,而且不一定专注于研究。总的来说,这是一个非常完整的库,目前仍在活跃开发中,但可能需要对底层实现有更多的了解才能完全发挥效力。
|
||||
|
||||
#### Nlp.js
|
||||
|
||||
[Nlp.js][12] 建立在其他几个 NLP 库之上,包括 Franc 和 Brain.js。它为许多 NLP 组件提供了一个很好的接口,比如分类、情感分析、词干化、命名实体识别和自然语言生成。它也支持一些其它语言,在你处理英语之外的语言时能提供一些帮助。总之,它是一个不错的通用工具,并且提供了调用其他工具的简化接口。在你需要更强大或更灵活的工具之前,这个工具可能会在你的应用程序中用上很长一段时间。
|
||||
|
||||
### Java 工具
|
||||
|
||||
#### OpenNLP
|
||||
|
||||
[OpenNLP][13] 是由 Apache 基金会管理的,所以它可以很方便地集成到其他 Apache 项目中,比如 Apache Flink、Apache NiFi 和 Apache Spark。这是一个通用的 NLP 工具,包含了所有 NLP 组件中的通用功能,可以通过命令行或者以包的形式导入到应用中来使用它。它也支持很多种语言。OpenNLP 是一个很高效的工具,包含了很多特性,如果你用 Java 开发生产环境产品的话,它是个很好的选择。
|
||||
|
||||
#### Stanford CoreNLP
|
||||
|
||||
[Stanford CoreNLP][14] 是一个工具集,提供了统计 NLP、深度学习 NLP 和基于规则的 NLP 功能。这个工具也有许多其他编程语言的版本,所以可以脱离 Java 来使用。它是由高水平的研究机构创建的一个高效的工具,但在生产环境中可能不是最好的。此工具采用双许可证,具有可以用于商业目的的特定许可证。总之,在研究和实验中它是一个很棒的工具,但在生产系统中可能会带来一些额外的成本。比起 Java 版本来说,读者可能对它的 Python 版本更感兴趣。同样,在 Coursera 上最好的机器学习课程之一是斯坦福教授提供的,[点此][15]访问其他不错的资源。
|
||||
|
||||
#### CogCompNLP
|
||||
|
||||
[CogCompNLP][16] 由伊利诺斯大学开发的一个工具,它也有一个相似功能的 Python 版本。它可以用于处理文本,包括本地处理和远程处理,能够极大地缓解你本地设备的压力。它提供了很多处理功能,比如令牌化、词性标注、断句、命名实体标注、词型还原、依存分析和语义角色标注。它是一个很好的研究工具,你可以自己探索它的不同功能。我不确定它是否适合生产环境,但如果你使用 Java 的话,它值得一试。
|
||||
|
||||
* * *
|
||||
|
||||
你最喜欢的开源 NLP 工具和库是什么?请在评论区分享文中没有提到的工具。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/natural-language-processing-tools
|
||||
|
||||
作者:[Dan Barker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zxp](https://github.com/zhangxiangping)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/barkerd427
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_communication_team.png?itok=CYfZ_gE7 (Chat bubbles)
|
||||
[2]: http://www.nltk.org/
|
||||
[3]: http://www.nltk.org/book_1ed/
|
||||
[4]: https://spacy.io/
|
||||
[5]: https://textblob.readthedocs.io/en/dev/
|
||||
[6]: https://readthedocs.org/projects/textacy/
|
||||
[7]: https://pytorchnlp.readthedocs.io/en/latest/
|
||||
[8]: https://www.npmjs.com/package/retext
|
||||
[9]: https://unified.js.org/
|
||||
[10]: https://www.npmjs.com/package/compromise
|
||||
[11]: https://www.npmjs.com/package/natural
|
||||
[12]: https://www.npmjs.com/package/node-nlp
|
||||
[13]: https://opennlp.apache.org/
|
||||
[14]: https://stanfordnlp.github.io/CoreNLP/
|
||||
[15]: https://opensource.com/article/19/2/learn-data-science-ai
|
||||
[16]: https://github.com/CogComp/cogcomp-nlp
|
236
published/202002/20190407 Manage multimedia files with Git.md
Normal file
236
published/202002/20190407 Manage multimedia files with Git.md
Normal file
@ -0,0 +1,236 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (svtter)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11889-1.html)
|
||||
[#]: subject: (Manage multimedia files with Git)
|
||||
[#]: via: (https://opensource.com/article/19/4/manage-multimedia-files-git)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
|
||||
通过 Git 来管理多媒体文件
|
||||
======
|
||||
|
||||
> 在我们有关 Git 鲜为人知的用法系列的最后一篇文章中,了解如何使用 Git 跟踪项目中的大型多媒体文件。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/13/235436mhub12qhxzmbw11p.png)
|
||||
|
||||
Git 是专用于源代码版本控制的工具。因此,Git 很少被用于非纯文本的项目以及行业。然而,异步工作流的优点是十分诱人的,尤其是在一些日益增长的行业中,这种类型的行业把重要的计算和重要的艺术创作结合起来,这包括网页设计、视觉效果、视频游戏、出版、货币设计(是的,这是一个真实的行业)、教育……等等。还有许多行业属于这个类型。
|
||||
|
||||
在这个 Git 系列文章中,我们分享了六种鲜为人知的 Git 使用方法。在最后一篇文章中,我们将介绍将 Git 的优点带到管理多媒体文件的软件。
|
||||
|
||||
### Git 管理多媒体文件的问题
|
||||
|
||||
众所周知,Git 用于处理非文本文件不是很好,但是这并不妨碍我们进行尝试。下面是一个使用 Git 来复制照片文件的例子:
|
||||
|
||||
```
|
||||
$ du -hs
|
||||
108K .
|
||||
$ cp ~/photos/dandelion.tif .
|
||||
$ git add dandelion.tif
|
||||
$ git commit -m 'added a photo'
|
||||
[master (root-commit) fa6caa7] two photos
|
||||
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||
create mode 100644 dandelion.tif
|
||||
$ du -hs
|
||||
1.8M .
|
||||
```
|
||||
|
||||
目前为止没有什么异常。增加一个 1.8MB 的照片到一个目录下,使得目录变成了 1.8 MB 的大小。所以下一步,我们尝试删除文件。
|
||||
|
||||
```
|
||||
$ git rm dandelion.tif
|
||||
$ git commit -m 'deleted a photo'
|
||||
$ du -hs
|
||||
828K .
|
||||
```
|
||||
|
||||
在这里我们可以看到有些问题:删除一个已经被提交的文件,还是会使得存储库的大小扩大到原来的 8 倍(从 108K 到 828K)。我们可以测试多次来得到一个更好的平均值,但是这个简单的演示与我的经验一致。提交非文本文件,在一开始花费空间比较少,但是一个工程活跃地时间越长,人们可能对静态内容修改的会更多,更多的零碎文件会被加和到一起。当一个 Git 存储库变的越来越大,主要的成本往往是速度。拉取和推送的时间,从最初抿一口咖啡的时间到你觉得你可能断网了。
|
||||
|
||||
静态内容导致 Git 存储库的体积不断扩大的原因是什么呢?那些通过文本的构成的文件,允许 Git 只拉取那些修改的部分。光栅图以及音乐文件对 Git 文件而言与文本不同,你可以查看一下 .png 和 .wav 文件中的二进制数据。所以,Git 只不过是获取了全部的数据,并且创建了一个新的副本,哪怕是一张图仅仅修改了一个像素。
|
||||
|
||||
### Git-portal
|
||||
|
||||
在实践中,许多多媒体项目不需要或者不想追踪媒体的历史记录。相对于文本或者代码的部分,项目的媒体部分一般有一个不同的生命周期。媒体资源一般按一个方向产生:一张图片从铅笔草稿开始,以数字绘画的形式抵达它的目的地。然后,尽管文本能够回滚到早起的版本,但是艺术制品只会一直向前发展。工程中的媒体很少被绑定到一个特定的版本。例外情况通常是反映数据集的图形,通常是可以用基于文本的格式(如 SVG)完成的表、图形或图表。
|
||||
|
||||
所以,在许多同时包含文本(无论是叙事散文还是代码)和媒体的工程中,Git 是一个用于文件管理的,可接受的解决方案,只要有一个在版本控制循环之外的游乐场来给艺术家游玩就行。
|
||||
|
||||
![Graphic showing relationship between art assets and Git][2]
|
||||
|
||||
一个启用这个特性的简单方法是 [Git-portal][3],这是一个通过带有 Git 钩子的 Bash 脚本,它可将静态文件从文件夹中移出 Git 的范围,并通过符号链接来取代它们。Git 提交链接文件(有时候称作别名或快捷方式),这种符号链接文件比较小,所以所有的提交都是文本文件和那些代表媒体文件的链接。因为替身文件是符号链接,所以工程还会像预期的运行,因为本地机器会处理他们,转换成“真实的”副本。当用符号链接替换出文件时,Git-portal 维护了项目的结构,因此,如果你认为 Git-portal 不适合你的项目,或者你需要构建项目的一个没有符号链接的版本(比如用于分发),则可以轻松地逆转该过程。
|
||||
|
||||
Git-portal 也允许通过 `rsync` 来远程同步静态资源,所以用户可以设置一个远程存储位置,来做为一个中心的授权源。
|
||||
|
||||
Git-portal 对于多媒体的工程是一个理想的解决方案。类似的多媒体工程包括视频游戏、桌面游戏、需要进行大型 3D 模型渲染和纹理的虚拟现实工程、[带图][4]以及 .odt 输出的书籍、协作型的[博客站点][5]、音乐项目,等等。艺术家在应用程序中以图层(在图形世界中)和曲目(在音乐世界中)的形式执行版本控制并不少见——因此,Git 不会向多媒体项目文件本身添加任何内容。Git 的功能可用于艺术项目的其他部分(例如散文和叙述、项目管理、字幕文件、致谢、营销副本、文档等),而结构化远程备份的功能则由艺术家使用。
|
||||
|
||||
#### 安装 Git-portal
|
||||
|
||||
Git-portal 的 RPM 安装包位于 <https://klaatu.fedorapeople.org/git-portal>,可用于下载和安装。
|
||||
|
||||
此外,用户可以从 Git-portal 的 Gitlab 主页手动安装。这仅仅是一个 Bash 脚本以及一些 Git 钩子(也是 Bash 脚本),但是需要一个快速的构建过程来让它知道安装的位置。
|
||||
|
||||
```
|
||||
$ git clone https://gitlab.com/slackermedia/git-portal.git git-portal.clone
|
||||
$ cd git-portal.clone
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
#### 使用 Git-portal
|
||||
|
||||
Git-portal 与 Git 一起使用。这意味着,如同 Git 的所有大型文件扩展一样,都需要记住一些额外的步骤。但是,你仅仅需要在处理你的媒体资源的时候使用 Git-portal,所以很容易记住,除非你把大文件都当做文本文件来进行处理(对于 Git 用户很少见)。使用 Git-portal 必须做的一个安装步骤是:
|
||||
|
||||
```
|
||||
$ mkdir bigproject.git
|
||||
$ cd !$
|
||||
$ git init
|
||||
$ git-portal init
|
||||
```
|
||||
|
||||
Git-portal 的 `init` 函数在 Git 存储库中创建了一个 `_portal` 文件夹并且添加到 `.gitignore` 文件中。
|
||||
|
||||
在平日里使用 Git-portal 和 Git 协同十分平滑。一个较好的例子是基于 MIDI 的音乐项目:音乐工作站产生的项目文件是基于文本的,但是 MIDI 文件是二进制数据:
|
||||
|
||||
```
|
||||
$ ls -1
|
||||
_portal
|
||||
song.1.qtr
|
||||
song.qtr
|
||||
song-Track_1-1.mid
|
||||
song-Track_1-3.mid
|
||||
song-Track_2-1.mid
|
||||
$ git add song*qtr
|
||||
$ git-portal song-Track*mid
|
||||
$ git add song-Track*mid
|
||||
```
|
||||
|
||||
如果你查看一下 `_portal` 文件夹,你会发现那里有最初的 MIDI 文件。这些文件在原本的位置被替换成了指向 `_portal` 的链接文件,使得音乐工作站像预期一样运行。
|
||||
|
||||
```
|
||||
$ ls -lG
|
||||
[...] _portal/
|
||||
[...] song.1.qtr
|
||||
[...] song.qtr
|
||||
[...] song-Track_1-1.mid -> _portal/song-Track_1-1.mid*
|
||||
[...] song-Track_1-3.mid -> _portal/song-Track_1-3.mid*
|
||||
[...] song-Track_2-1.mid -> _portal/song-Track_2-1.mid*
|
||||
```
|
||||
|
||||
与 Git 相同,你也可以添加一个目录下的文件。
|
||||
|
||||
```
|
||||
$ cp -r ~/synth-presets/yoshimi .
|
||||
$ git-portal add yoshimi
|
||||
Directories cannot go through the portal. Sending files instead.
|
||||
$ ls -lG _portal/yoshimi
|
||||
[...] yoshimi.stat -> ../_portal/yoshimi/yoshimi.stat*
|
||||
```
|
||||
|
||||
删除功能也像预期一样工作,但是当从 `_portal` 中删除一些东西时,你应该使用 `git-portal rm` 而不是 `git rm`。使用 Git-portal 可以确保文件从 `_portal` 中删除:
|
||||
|
||||
```
|
||||
$ ls
|
||||
_portal/ song.qtr song-Track_1-3.mid@ yoshimi/
|
||||
song.1.qtr song-Track_1-1.mid@ song-Track_2-1.mid@
|
||||
$ git-portal rm song-Track_1-3.mid
|
||||
rm 'song-Track_1-3.mid'
|
||||
$ ls _portal/
|
||||
song-Track_1-1.mid* song-Track_2-1.mid* yoshimi/
|
||||
```
|
||||
|
||||
如果你忘记使用 Git-portal,那么你需要手动删除 `_portal` 下的文件:
|
||||
|
||||
```
|
||||
$ git-portal rm song-Track_1-1.mid
|
||||
rm 'song-Track_1-1.mid'
|
||||
$ ls _portal/
|
||||
song-Track_1-1.mid* song-Track_2-1.mid* yoshimi/
|
||||
$ trash _portal/song-Track_1-1.mid
|
||||
```
|
||||
|
||||
Git-portal 其它的唯一功能,是列出当前所有的链接并且找到里面可能已经损坏的符号链接。有时这种情况会因为项目文件夹中的文件被移动而发生:
|
||||
|
||||
```
|
||||
$ mkdir foo
|
||||
$ mv yoshimi foo
|
||||
$ git-portal status
|
||||
bigproject.git/song-Track_2-1.mid: symbolic link to _portal/song-Track_2-1.mid
|
||||
bigproject.git/foo/yoshimi/yoshimi.stat: broken symbolic link to ../_portal/yoshimi/yoshimi.stat
|
||||
```
|
||||
|
||||
如果你使用 Git-portal 用于私人项目并且维护自己的备份,以上就是技术方面所有你需要知道关于 Git-portal 的事情了。如果你想要添加一个协作者或者你希望 Git-portal 来像 Git 的方式来管理备份,你可以创建一个远程位置。
|
||||
|
||||
#### 增加 Git-portal 远程位置
|
||||
|
||||
为 Git-portal 增加一个远程位置是通过 Git 已有的远程功能来实现的。Git-portal 实现了 Git 钩子(隐藏在存储库 `.git` 文件夹中的脚本),来寻找你的远程位置上是否存在以 `_portal` 开头的文件夹。如果它找到一个,它会尝试使用 `rsync` 来与远程位置同步文件。Git-portal 在用户进行 Git 推送以及 Git 合并的时候(或者在进行 Git 拉取的时候,实际上是进行一次获取和自动合并),都会执行此操作。
|
||||
|
||||
如果你仅克隆了 Git 存储库,那么你可能永远不会自己添加一个远程位置。这是一个标准的 Git 过程:
|
||||
|
||||
```
|
||||
$ git remote add origin git@gitdawg.com:seth/bigproject.git
|
||||
$ git remote -v
|
||||
origin git@gitdawg.com:seth/bigproject.git (fetch)
|
||||
origin git@gitdawg.com:seth/bigproject.git (push)
|
||||
```
|
||||
|
||||
对你的主要 Git 存储库来说,`origin` 这个名字是一个流行的惯例,将其用于 Git 数据是有意义的。然而,你的 Git-portal 数据是分开存储的,所以你必须创建第二个远程位置来让 Git-portal 了解向哪里推送和从哪里拉取。取决于你的 Git 主机,你可能需要一个单独的服务器,因为空间有限的 Git 主机不太可能接受 GB 级的媒体资产。或者,可能你的服务器仅允许你访问你的 Git 存储库而不允许访问外部的存储文件夹:
|
||||
|
||||
```
|
||||
$ git remote add _portal seth@example.com:/home/seth/git/bigproject_portal
|
||||
$ git remote -v
|
||||
origin git@gitdawg.com:seth/bigproject.git (fetch)
|
||||
origin git@gitdawg.com:seth/bigproject.git (push)
|
||||
_portal seth@example.com:/home/seth/git/bigproject_portal (fetch)
|
||||
_portal seth@example.com:/home/seth/git/bigproject_portal (push)
|
||||
```
|
||||
|
||||
你可能不想为所有用户提供服务器上的个人帐户,也不必这样做。为了提供对托管资源库大文件资产的服务器的访问权限,你可以运行一个 Git 前端,比如 [Gitolite][8] 或者你可以使用 `rrsync` (受限的 rsync)。
|
||||
|
||||
现在你可以推送你的 Git 数据到你的远程 Git 存储库,并将你的 Git-portal 数据到你的远程的门户:
|
||||
|
||||
```
|
||||
$ git push origin HEAD
|
||||
master destination detected
|
||||
Syncing _portal content...
|
||||
sending incremental file list
|
||||
sent 9,305 bytes received 18 bytes 1,695.09 bytes/sec
|
||||
total size is 60,358,015 speedup is 6,474.10
|
||||
Syncing _portal content to example.com:/home/seth/git/bigproject_portal
|
||||
```
|
||||
|
||||
如果你已经安装了 Git-portal,并且配置了 `_portal` 的远程位置,你的 `_portal` 文件夹将会被同步,并且从服务器获取新的内容,以及在每一次推送的时候发送新的内容。尽管你不需要进行 Git 提交或者推送来和服务器同步(用户可以使用直接使用 `rsync`),但是我发现对于艺术性内容的改变,提交是有用的。这将会把艺术家及其数字资产集成到工作流的其余部分中,并提供有关项目进度和速度的有用元数据。
|
||||
|
||||
### 其他选择
|
||||
|
||||
如果 Git-portal 对你而言太过简单,还有一些用于 Git 管理大型文件的其他选择。[Git 大文件存储][9](LFS)是一个名为 git-media 的停工项目的分支,这个分支由 GitHub 维护和支持。它需要特殊的命令(例如 `git lfs track` 来保护大型文件不被 Git 追踪)并且需要用户维护一个 `.gitattributes` 文件来更新哪些存储库中的文件被 LFS 追踪。对于大文件而言,它**仅**支持 HTTP 和 HTTPS 远程主机。所以你必须配置 LFS 服务器,才能使得用户可以通过 HTTP 而不是 SSH 或 `rsync` 来进行鉴权。
|
||||
|
||||
另一个相对 LFS 更灵活的选择是 [git-annex][10]。你可以在我的文章 [管理 Git 中大二进制 blob][11] 中了解更多(忽略其中 git-media 这个已经废弃项目的章节,因为其灵活性没有被它的继任者 Git LFS 延续下来)。Git-annex 是一个灵活且优雅的解决方案。它拥有一个细腻的系统来用于添加、删除、移动存储库中的大型文件。因为它灵活且强大,有很多新的命令和规则需要进行学习,所以建议看一下它的[文档][12]。
|
||||
|
||||
然而,如果你的需求很简单,你可能更加喜欢整合已有技术来进行简单且明显任务的解决方案,则 Git-portal 可能是对于工作而言比较合适的工具。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/manage-multimedia-files-git
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[svtter](https://github.com/svtter)
|
||||
校对:[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/video_editing_folder_music_wave_play.png?itok=-J9rs-My (video editing dashboard)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/git-velocity.jpg (Graphic showing relationship between art assets and Git)
|
||||
[3]: http://gitlab.com/slackermedia/git-portal.git
|
||||
[4]: https://www.apress.com/gp/book/9781484241691
|
||||
[5]: http://mixedsignals.ml
|
||||
[6]: mailto:git@gitdawg.com
|
||||
[7]: mailto:seth@example.com
|
||||
[8]: https://opensource.com/article/19/4/file-sharing-git
|
||||
[9]: https://git-lfs.github.com/
|
||||
[10]: https://git-annex.branchable.com/
|
||||
[11]: https://opensource.com/life/16/8/how-manage-binary-blobs-git-part-7
|
||||
[12]: https://git-annex.branchable.com/walkthrough/
|
@ -0,0 +1,189 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (mengxinayan)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11935-1.html)
|
||||
[#]: subject: (How to structure a multi-file C program: Part 1)
|
||||
[#]: via: (https://opensource.com/article/19/7/structure-multi-file-c-part-1)
|
||||
[#]: author: (Erik O'Shaughnessy https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions)
|
||||
|
||||
如何组织构建多文件 C 语言程序(一)
|
||||
======
|
||||
|
||||
> 准备好你喜欢的饮料、编辑器和编译器,放一些音乐,然后开始构建一个由多个文件组成的 C 语言程序。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/26/214517o5p7q45l2a8jkx4k.jpg)
|
||||
|
||||
大家常说计算机编程的艺术部分是处理复杂性,部分是命名某些事物。此外,我认为“有时需要添加绘图”是在很大程度上是正确的。
|
||||
|
||||
在这篇文章里,我会编写一个小型 C 程序,命名一些东西,同时处理一些复杂性。该程序的结构大致基于我在 《[如何写一个好的 C 语言 main 函数][2]》 文中讨论的。但是,这次做一些不同的事。准备好你喜欢的饮料、编辑器和编译器,放一些音乐,让我们一起编写一个有趣的 C 语言程序。
|
||||
|
||||
### 优秀 Unix 程序哲学
|
||||
|
||||
首先,你要知道这个 C 程序是一个 [Unix][3] 命令行工具。这意味着它运行在(或者可被移植到)那些提供 Unix C 运行环境的操作系统中。当贝尔实验室发明 Unix 后,它从一开始便充满了[设计哲学][4]。用我自己的话来说就是:程序只做一件事,并做好它,并且对文件进行一些操作。虽然“只做一件事,并做好它”是有意义的,但是“对文件进行一些操作”的部分似乎有点儿不合适。
|
||||
|
||||
事实证明,Unix 中抽象的 “文件” 非常强大。一个 Unix 文件是以文件结束符(EOF)标志为结尾的字节流。仅此而已。文件中任何其它结构均由应用程序所施加而非操作系统。操作系统提供了系统调用,使得程序能够对文件执行一套标准的操作:打开、读取、写入、寻址和关闭(还有其他,但说起来那就复杂了)。对于文件的标准化访问使得不同的程序共用相同的抽象,而且可以一同工作,即使它们是不同的人用不同语言编写的程序。
|
||||
|
||||
具有共享的文件接口使得构建*可组合的*的程序成为可能。一个程序的输出可以作为另一个程序的输入。Unix 家族的操作系统默认在执行程序时提供了三个文件:标准输入(`stdin`)、标准输出(`stdout`)和标准错误(`stderr`)。其中两个文件是只写的:`stdout` 和 `stderr`。而 `stdin` 是只读的。当我们在常见的 Shell 比如 Bash 中使用文件重定向时,可以看到其效果。
|
||||
|
||||
```
|
||||
$ ls | grep foo | sed -e 's/bar/baz/g' > ack
|
||||
```
|
||||
|
||||
这条指令可以被简要地描述为:`ls` 的结果被写入标准输出,它重定向到 `grep` 的标准输入,`grep` 的标准输出重定向到 `sed` 的标准输入,`sed` 的标准输出重定向到当前目录下文件名为 `ack` 的文件中。
|
||||
|
||||
我们希望我们的程序在这个灵活又出色的生态系统中运作良好,因此让我们编写一个可以读写文件的程序。
|
||||
|
||||
### 喵呜喵呜:流编码器/解码器概念
|
||||
|
||||
当我还是一个露着豁牙的孩子懵懵懂懂地学习计算机科学时,学过很多编码方案。它们中的有些用于压缩文件,有些用于打包文件,另一些毫无用处因此显得十分愚蠢。列举最后这种情况的一个例子:[哞哞编码方案][5]。
|
||||
|
||||
为了让我们的程序有个用途,我为它更新了一个 [21 世纪][6] 的概念,并且实现了一个名为“喵呜喵呜” 的编码方案的概念(毕竟网上大家都喜欢猫)。这里的基本的思路是获取文件并且使用文本 “meow” 对每个半字节(半个字节)进行编码。小写字母代表 0,大写字母代表 1。因为它会将 4 个比特替换为 32 个比特,因此会扩大文件的大小。没错,这毫无意义。但是想象一下人们看到经过这样编码后的惊讶表情。
|
||||
|
||||
```
|
||||
$ cat /home/your_sibling/.super_secret_journal_of_my_innermost_thoughts
|
||||
MeOWmeOWmeowMEoW...
|
||||
```
|
||||
|
||||
这非常棒。
|
||||
|
||||
### 最终的实现
|
||||
|
||||
完整的源代码可以在 [GitHub][7] 上面找到,但是我会写下我在编写程序时的思考。目的是说明如何组织构建多文件 C 语言程序。
|
||||
|
||||
既然已经确定了要编写一个编码和解码“喵呜喵呜”格式的文件的程序时,我在 Shell 中执行了以下的命令 :
|
||||
|
||||
```
|
||||
$ mkdir meowmeow
|
||||
$ cd meowmeow
|
||||
$ git init
|
||||
$ touch Makefile # 编译程序的方法
|
||||
$ touch main.c # 处理命令行选项
|
||||
$ touch main.h # “全局”常量和定义
|
||||
$ touch mmencode.c # 实现对喵呜喵呜文件的编码
|
||||
$ touch mmencode.h # 描述编码 API
|
||||
$ touch mmdecode.c # 实现对喵呜喵呜文件的解码
|
||||
$ touch mmdecode.h # 描述解码 API
|
||||
$ touch table.h # 定义编码查找表
|
||||
$ touch .gitignore # 这个文件中的文件名会被 git 忽略
|
||||
$ git add .
|
||||
$ git commit -m "initial commit of empty files"
|
||||
```
|
||||
|
||||
简单的说,我创建了一个目录,里面全是空文件,并且提交到 git。
|
||||
|
||||
即使这些文件中没有内容,你依旧可以从它的文件名推断每个文件的用途。为了避免万一你无法理解,我在每条 `touch` 命令后面进行了简单描述。
|
||||
|
||||
通常,程序从一个简单 `main.c` 文件开始,只有两三个解决问题的函数。然后程序员轻率地向自己的朋友或者老板展示了该程序,然后为了支持所有新的“功能”和“需求”,文件中的函数数量就迅速爆开了。“程序俱乐部”的第一条规则便是不要谈论“程序俱乐部”,第二条规则是尽量减少单个文件中的函数。
|
||||
|
||||
老实说,C 编译器并不关心程序中的所有函数是否都在一个文件中。但是我们并不是为计算机或编译器写程序,我们是为其他人(有时也包括我们)去写程序的。我知道这可能有些奇怪,但这就是事实。程序体现了计算机解决问题所采用的一组算法,当问题的参数发生了意料之外的变化时,保证人们可以理解它们是非常重要的。当在人们修改程序时,发现一个文件中有 2049 函数时他们会诅咒你的。
|
||||
|
||||
因此,优秀的程序员会将函数分隔开,将相似的函数分组到不同的文件中。这里我用了三个文件 `main.c`、`mmencode.c` 和 `mmdecode.c`。对于这样小的程序,也许看起来有些过头了。但是小的程序很难保证一直小下去,因此哥忒拓展做好计划是一个“好主意”。
|
||||
|
||||
但是那些 `.h` 文件呢?我会在后面解释一般的术语,简单地说,它们被称为头文件,同时它们可以包含 C 语言类型定义和 C 预处理指令。头文件中不应该包含任何函数。你可以认为头文件是提供了应用程序接口(API)的定义的一种 `.c` 文件,可以供其它 `.c` 文件使用。
|
||||
|
||||
### 但是 Makefile 是什么呢?
|
||||
|
||||
我知道下一个轰动一时的应用都是你们这些好孩子们用 “终极代码粉碎者 3000” 集成开发环境来编写的,而构建项目是用 Ctrl-Meta-Shift-Alt-Super-B 等一系列复杂的按键混搭出来的。但是如今(也就是今天),使用 `Makefile` 文件可以在构建 C 程序时帮助做很多有用的工作。`Makefile` 是一个包含如何处理文件的方式的文本文件,程序员可以使用其自动地从源代码构建二进制程序(以及其它东西!)
|
||||
|
||||
以下面这个小东西为例:
|
||||
|
||||
```
|
||||
00 # Makefile
|
||||
01 TARGET= my_sweet_program
|
||||
02 $(TARGET): main.c
|
||||
03 cc -o my_sweet_program main.c
|
||||
```
|
||||
|
||||
`#` 符号后面的文本是注释,例如 00 行。
|
||||
|
||||
01 行是一个变量赋值,将 `TARGET` 变量赋值为字符串 `my_sweet_program`。按照惯例,也是我的习惯,所有 `Makefile` 变量均使用大写字母并用下划线分隔单词。
|
||||
|
||||
02 行包含该<ruby>步骤<rt>recipe</rt></ruby>要创建的文件名和其依赖的文件。在本例中,构建<ruby>目标<rt>target</rt></ruby>是 `my_sweet_program`,其依赖是 `main.c`。
|
||||
|
||||
最后的 03 行使用了一个制表符号(`tab`)而不是四个空格。这是将要执行创建目标的命令。在本例中,我们使用 <ruby>C 编译器<rt>C compiler</rt></ruby>前端 `cc` 以编译链接为 `my_sweet_program`。
|
||||
|
||||
使用 `Makefile` 是非常简单的。
|
||||
|
||||
```
|
||||
$ make
|
||||
cc -o my_sweet_program main.c
|
||||
$ ls
|
||||
Makefile main.c my_sweet_program
|
||||
```
|
||||
|
||||
构建我们喵呜喵呜编码器/解码器的 [Makefile][8] 比上面的例子要复杂,但其基本结构是相同的。我将在另一篇文章中将其分解为 Barney 风格。
|
||||
|
||||
### 形式伴随着功能
|
||||
|
||||
我的想法是程序从一个文件中读取、转换它,并将转换后的结果存储到另一个文件中。以下是我想象使用程序命令行交互时的情况:
|
||||
|
||||
```
|
||||
$ meow < clear.txt > clear.meow
|
||||
$ unmeow < clear.meow > meow.tx
|
||||
$ diff clear.txt meow.tx
|
||||
$
|
||||
```
|
||||
|
||||
我们需要编写代码以进行命令行解析和处理输入/输出流。我们需要一个函数对流进行编码并将结果写到另一个流中。最后,我们需要一个函数对流进行解码并将结果写到另一个流中。等一下,我们在讨论如何写一个程序,但是在上面的例子中,我调用了两个指令:`meow` 和 `unmeow`?我知道你可能会认为这会导致越变越复杂。
|
||||
|
||||
### 次要内容:argv[0] 和 ln 指令
|
||||
|
||||
回想一下,C 语言 main 函数的结构如下:
|
||||
|
||||
```
|
||||
int main(int argc, char *argv[])
|
||||
```
|
||||
|
||||
其中 `argc` 是命令行参数的数量,`argv` 是字符指针(字符串)的列表。`argv[0]` 是包含正在执行的程序的文件路径。在 Unix 系统中许多互补功能的程序(比如:压缩和解压缩)看起来像两个命令,但事实上,它们是在文件系统中拥有两个名称的一个程序。这个技巧是通过使用 `ln` 命令创建文件系统链接来实现两个名称的。
|
||||
|
||||
在我笔记本电脑中 `/usr/bin` 的一个例子如下:
|
||||
|
||||
```
|
||||
$ ls -li /usr/bin/git*
|
||||
3376 -rwxr-xr-x. 113 root root 1.5M Aug 30 2018 /usr/bin/git
|
||||
3376 -rwxr-xr-x. 113 root root 1.5M Aug 30 2018 /usr/bin/git-receive-pack
|
||||
...
|
||||
```
|
||||
|
||||
这里 `git` 和 `git-receive-pack` 是同一个文件但是拥有不同的名字。我们说它们是相同的文件因为它们具有相同的 inode 值(第一列)。inode 是 Unix 文件系统的一个特点,对它的介绍超越了本文的内容范畴。
|
||||
|
||||
优秀或懒惰的程序可以通过 Unix 文件系统的这个特点达到写更少的代码但是交付双倍的程序。首先,我们编写一个基于其 `argv[0]` 的值而作出相应改变的程序,然后我们确保为导致该行为的名称创建链接。
|
||||
|
||||
在我们的 `Makefile` 中,`unmeow` 链接通过以下的方式来创建:
|
||||
|
||||
```
|
||||
# Makefile
|
||||
...
|
||||
$(DECODER): $(ENCODER)
|
||||
$(LN) -f $< $@
|
||||
...
|
||||
```
|
||||
|
||||
我倾向于在 `Makefile` 中将所有内容参数化,很少使用 “裸” 字符串。我将所有的定义都放置在 `Makefile` 文件顶部,以便可以简单地找到并改变它们。当你尝试将程序移植到新的平台上时,需要将 `cc` 改变为某个 `cc` 时,这会很方便。
|
||||
|
||||
除了两个内置变量 `$@` 和 `$<` 之外,该<ruby>步骤<rt>recipe</rt></ruby>看起来相对简单。第一个便是该步骤的目标的快捷方式,在本例中是 `$(DECODER)`(我能记得这个是因为 `@` 符号看起来像是一个目标)。第二个,`$<` 是规则依赖项,在本例中,它解析为 `$(ENCODER)`。
|
||||
|
||||
事情肯定会变得复杂,但它还在管理之中。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/structure-multi-file-c-part-1
|
||||
|
||||
作者:[Erik O'Shaughnessy][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jnyjnyhttps://opensource.com/users/jnyjnyhttps://opensource.com/users/jim-salterhttps://opensource.com/users/cldxsolutions
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_keyboard_coding.png?itok=E0Vvam7A (Programming keyboard.)
|
||||
[2]: https://linux.cn/article-10949-1.html
|
||||
[3]: https://en.wikipedia.org/wiki/Unix
|
||||
[4]: http://harmful.cat-v.org/cat-v/
|
||||
[5]: http://www.jabberwocky.com/software/moomooencode.html
|
||||
[6]: https://giphy.com/gifs/nyan-cat-sIIhZliB2McAo
|
||||
[7]: https://github.com/JnyJny/meowmeow
|
||||
[8]: https://github.com/JnyJny/meowmeow/blob/master/Makefile
|
@ -0,0 +1,208 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11881-1.html)
|
||||
[#]: subject: (How to Go About Linux Boot Time Optimisation)
|
||||
[#]: via: (https://opensourceforu.com/2019/10/how-to-go-about-linux-boot-time-optimisation/)
|
||||
[#]: author: (B Thangaraju https://opensourceforu.com/author/b-thangaraju/)
|
||||
|
||||
如何进行 Linux 启动时间优化
|
||||
======
|
||||
|
||||
![][2]
|
||||
|
||||
> 快速启动嵌入式设备或电信设备,对于时间要求紧迫的应用程序是至关重要的,并且在改善用户体验方面也起着非常重要的作用。这个文章给予一些关于如何增强任意设备的启动时间的重要技巧。
|
||||
|
||||
快速启动或快速重启在各种情况下起着至关重要的作用。为了保持所有服务的高可用性和更好的性能,嵌入式设备的快速启动至关重要。设想有一台运行着没有启用快速启动的 Linux 操作系统的电信设备,所有依赖于这个特殊嵌入式设备的系统、服务和用户可能会受到影响。这些设备维持其服务的高可用性是非常重要的,为此,快速启动和重启起着至关重要的作用。
|
||||
|
||||
一台电信设备的一次小故障或关机,即使只是几秒钟,都可能会对无数互联网上的用户造成破坏。因此,对于很多对时间要求严格的设备和电信设备来说,在它们的设备中加入快速启动的功能以帮助它们快速恢复工作是非常重要的。让我们从图 1 中理解 Linux 启动过程。
|
||||
|
||||
![图 1:启动过程][3]
|
||||
|
||||
### 监视工具和启动过程
|
||||
|
||||
在对机器做出更改之前,用户应注意许多因素。其中包括计算机的当前启动速度,以及占用资源并增加启动时间的服务、进程或应用程序。
|
||||
|
||||
#### 启动图
|
||||
|
||||
为监视启动速度和在启动期间启动的各种服务,用户可以使用下面的命令来安装:
|
||||
|
||||
```
|
||||
sudo apt-get install pybootchartgui
|
||||
```
|
||||
|
||||
你每次启动时,启动图会在日志中保存一个 png 文件,使用户能够查看该 png 文件来理解系统的启动过程和服务。为此,使用下面的命令:
|
||||
|
||||
```
|
||||
cd /var/log/bootchart
|
||||
```
|
||||
|
||||
用户可能需要一个应用程序来查看 png 文件。Feh 是一个面向控制台用户的 X11 图像查看器。不像大多数其它的图像查看器,它没有一个精致的图形用户界面,但它只用来显示图片。Feh 可以用于查看 png 文件。你可以使用下面的命令来安装它:
|
||||
|
||||
```
|
||||
sudo apt-get install feh
|
||||
```
|
||||
|
||||
你可以使用 `feh xxxx.png` 来查看 png 文件。
|
||||
|
||||
|
||||
![图 2:启动图][4]
|
||||
|
||||
图 2 显示了一个正在查看的引导图 png 文件。
|
||||
|
||||
#### systemd-analyze
|
||||
|
||||
但是,对于 Ubuntu 15.10 以后的版本不再需要引导图。为获取关于启动速度的简短信息,使用下面的命令:
|
||||
|
||||
```
|
||||
systemd-analyze
|
||||
```
|
||||
|
||||
![图 3:systemd-analyze 的输出][5]
|
||||
|
||||
图表 3 显示命令 `systemd-analyze` 的输出。
|
||||
|
||||
命令 `systemd-analyze blame` 用于根据初始化所用的时间打印所有正在运行的单元的列表。这个信息是非常有用的,可用于优化启动时间。`systemd-analyze blame` 不会显示服务类型为简单(`Type=simple`)的服务,因为 systemd 认为这些服务应是立即启动的;因此,无法测量初始化的延迟。
|
||||
|
||||
![图 4:systemd-analyze blame 的输出][6]
|
||||
|
||||
图 4 显示 `systemd-analyze blame` 的输出。
|
||||
|
||||
下面的命令打印时间关键的服务单元的树形链条:
|
||||
|
||||
```
|
||||
command systemd-analyze critical-chain
|
||||
```
|
||||
|
||||
图 5 显示命令 `systemd-analyze critical-chain` 的输出。
|
||||
|
||||
![图 5:systemd-analyze critical-chain 的输出][7]
|
||||
|
||||
### 减少启动时间的步骤
|
||||
|
||||
下面显示的是一些可以减少启动时间的各种步骤。
|
||||
|
||||
#### BUM(启动管理器)
|
||||
|
||||
BUM 是一个运行级配置编辑器,允许在系统启动或重启时配置初始化服务。它显示了可以在启动时启动的每个服务的列表。用户可以打开和关闭各个服务。BUM 有一个非常清晰的图形用户界面,并且非常容易使用。
|
||||
|
||||
在 Ubuntu 14.04 中,BUM 可以使用下面的命令安装:
|
||||
|
||||
```
|
||||
sudo apt-get install bum
|
||||
```
|
||||
|
||||
为在 15.10 以后的版本中安装它,从链接 http://apt.ubuntu.com/p/bum 下载软件包。
|
||||
|
||||
以基本的服务开始,禁用扫描仪和打印机相关的服务。如果你没有使用蓝牙和其它不想要的设备和服务,你也可以禁用它们中一些。我强烈建议你在禁用相关的服务前学习服务的基础知识,因为这可能会影响计算机或操作系统。图 6 显示 BUM 的图形用户界面。
|
||||
|
||||
![图 6:BUM][8]
|
||||
|
||||
#### 编辑 rc 文件
|
||||
|
||||
要编辑 rc 文件,你需要转到 rc 目录。这可以使用下面的命令来做到:
|
||||
|
||||
```
|
||||
cd /etc/init.d
|
||||
```
|
||||
|
||||
然而,访问 `init.d` 需要 root 用户权限,该目录基本上包含的是开始/停止脚本,这些脚本用于在系统运行时或启动期间控制(开始、停止、重新加载、启动启动)守护进程。
|
||||
|
||||
在 `init.d` 目录中的 `rc` 文件被称为<ruby>运行控制<rt>run control</rt></ruby>脚本。在启动期间,`init` 执行 `rc` 脚本并发挥它的作用。为改善启动速度,我们可以更改 `rc` 文件。使用任意的文件编辑器打开 `rc` 文件(当你在 `init.d` 目录中时)。
|
||||
|
||||
例如,通过输入 `vim rc` ,你可以更改 `CONCURRENCY=none` 为 `CONCURRENCY=shell`。后者允许某些启动脚本同时执行,而不是依序执行。
|
||||
|
||||
在最新版本的内核中,该值应该被更改为 `CONCURRENCY=makefile`。
|
||||
|
||||
图 7 和图 8 显示编辑 `rc` 文件前后的启动时间比较。可以注意到启动速度有所提高。在编辑 `rc` 文件前的启动时间是 50.98 秒,然而在对 `rc` 文件进行更改后的启动时间是 23.85 秒。
|
||||
|
||||
但是,上面提及的更改方法在 Ubuntu 15.10 以后的操作系统上不工作,因为使用最新内核的操作系统使用 systemd 文件,而不再是 `init.d` 文件。
|
||||
|
||||
![图 7:对 rc 文件进行更改之前的启动速度][9]
|
||||
|
||||
![图 8:对 rc 文件进行更改之后的启动速度][10]
|
||||
|
||||
#### E4rat
|
||||
|
||||
E4rat 代表 e4 <ruby>减少访问时间<rt>reduced access time</rt></ruby>(仅在 ext4 文件系统的情况下)。它是由 Andreas Rid 和 Gundolf Kiefer 开发的一个项目。E4rat 是一个通过碎片整理来帮助快速启动的应用程序。它还会加速应用程序的启动。E4rat 使用物理文件的重新分配来消除寻道时间和旋转延迟,因而达到较高的磁盘传输速度。
|
||||
|
||||
E4rat 可以 .deb 软件包形式获得,你可以从它的官方网站 http://e4rat.sourceforge.net/ 下载。
|
||||
|
||||
Ubuntu 默认安装的 ureadahead 软件包与 e4rat 冲突。因此必须使用下面的命令安装这几个软件包:
|
||||
|
||||
```
|
||||
sudo dpkg purge ureadahead ubuntu-minimal
|
||||
```
|
||||
|
||||
现在使用下面的命令来安装 e4rat 的依赖关系:
|
||||
|
||||
```
|
||||
sudo apt-get install libblkid1 e2fslibs
|
||||
```
|
||||
|
||||
打开下载的 .deb 文件,并安装它。现在需要恰当地收集启动数据来使 e4rat 工作。
|
||||
|
||||
遵循下面所给的步骤来使 e4rat 正确地运行并提高启动速度。
|
||||
|
||||
* 在启动期间访问 Grub 菜单。这可以在系统启动时通过按住 `shift` 按键来完成。
|
||||
* 选择通常用于启动的选项(内核版本),并按 `e`。
|
||||
* 查找以 `linux /boot/vmlinuz` 开头的行,并在该行的末尾添加下面的代码(在句子的最后一个字母后按空格键):`init=/sbin/e4rat-collect or try - quiet splash vt.handsoff =7 init=/sbin/e4rat-collect
|
||||
`。
|
||||
* 现在,按 `Ctrl+x` 来继续启动。这可以让 e4rat 在启动后收集数据。在这台机器上工作,并在接下来的两分钟时间内打开并关闭应用程序。
|
||||
* 通过转到 e4rat 文件夹,并使用下面的命令来访问日志文件:`cd /var/log/e4rat`。
|
||||
* 如果你没有找到任何日志文件,重复上面的过程。一旦日志文件就绪,再次访问 Grub 菜单,并对你的选项按 `e`。
|
||||
* 在你之前已经编辑过的同一行的末尾输入 `single`。这可以让你访问命令行。如果出现其它菜单,选择恢复正常启动(Resume normal boot)。如果你不知为何不能进入命令提示符,按 `Ctrl+Alt+F1` 组合键。
|
||||
* 在你看到登录提示后,输入你的登录信息。
|
||||
* 现在输入下面的命令:`sudo e4rat-realloc /var/lib/e4rat/startup.log`。此过程需要一段时间,具体取决于机器的磁盘速度。
|
||||
* 现在使用下面的命令来重启你的机器:`sudo shutdown -r now`。
|
||||
* 现在,我们需要配置 Grub 来在每次启动时运行 e4rat。
|
||||
* 使用任意的编辑器访问 grub 文件。例如,`gksu gedit /etc/default/grub`。
|
||||
* 查找以 `GRUB CMDLINE LINUX DEFAULT=` 开头的一行,并在引号之间和任何选项之前添加下面的行:`init=/sbin/e4rat-preload 18`。
|
||||
* 它应该看起来像这样:`GRUB CMDLINE LINUX DEFAULT = init=/sbin/e4rat- preload quiet splash`。
|
||||
* 保存并关闭 Grub 菜单,并使用 `sudo update-grub` 更新 Grub 。
|
||||
* 重启系统,你将发现启动速度有明显变化。
|
||||
|
||||
图 9 和图 10 显示在安装 e4rat 前后的启动时间之间的差异。可注意到启动速度的提高。在使用 e4rat 前启动所用时间是 22.32 秒,然而在使用 e4rat 后启动所用时间是 9.065 秒。
|
||||
|
||||
![图 9:使用 e4rat 之前的启动速度][11]
|
||||
|
||||
![图 10:使用 e4rat 之后的启动速度][12]
|
||||
|
||||
### 一些易做的调整
|
||||
|
||||
使用很小的调整也可以达到良好的启动速度,下面列出其中两个。
|
||||
|
||||
#### SSD
|
||||
|
||||
使用固态设备而不是普通的硬盘或者其它的存储设备将肯定会改善启动速度。SSD 也有助于加快文件传输和运行应用程序方面的速度。
|
||||
|
||||
#### 禁用图形用户界面
|
||||
|
||||
图形用户界面、桌面图形和窗口动画占用大量的资源。禁用图形用户界面是获得良好的启动速度的另一个好方法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/10/how-to-go-about-linux-boot-time-optimisation/
|
||||
|
||||
作者:[B Thangaraju][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/b-thangaraju/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/Screenshot-from-2019-10-07-13-16-32.png?&ssl=1 (Screenshot from 2019-10-07 13-16-32)
|
||||
[2]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/Screenshot-from-2019-10-07-13-16-32.png?fit=700%2C499&ssl=1
|
||||
[3]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-1.png?ssl=1
|
||||
[4]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-2.png?ssl=1
|
||||
[5]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-3.png?ssl=1
|
||||
[6]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-4.png?ssl=1
|
||||
[7]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-5.png?ssl=1
|
||||
[8]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-6.png?ssl=1
|
||||
[9]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-7.png?ssl=1
|
||||
[10]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-8.png?ssl=1
|
||||
[11]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-9.png?ssl=1
|
||||
[12]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/10/fig-10.png?ssl=1
|
@ -1,22 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (#:acid 'words: Handle Chromium & Firefox sessions with org-mode)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11926-1.html)
|
||||
[#]: subject: (Handle Chromium & Firefox sessions with org-mode)
|
||||
[#]: via: (https://acidwords.com/posts/2019-12-04-handle-chromium-and-firefox-sessions-with-org-mode.html)
|
||||
[#]: author: (Sanel Z https://acidwords.com/)
|
||||
|
||||
Handle Chromium & Firefox sessions with org-mode
|
||||
通过 Org 模式管理 Chromium 和 Firefox 会话
|
||||
======
|
||||
|
||||
I was big fan of [Session Manager][1], small addon for Chrome and Chromium that will save all open tabs, assign the name to session and, when is needed, restore it.
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/24/113047w8jtoh2o5j085750.jpg)
|
||||
|
||||
Very useful, especially if you are like me, switching between multiple "mind sessions" during the day - research, development or maybe news reading. Or simply, you'd like to remember workflow (and tabs) you had few days ago.
|
||||
我是[会话管理器][1]的铁粉,它是 Chrome 和 Chromium 的小插件,可以保存所有打开的选项卡,为会话命名,并在需要时恢复会话。
|
||||
|
||||
After I decided to ditch all extensions from Chromium except [uBlock Origin][2], it was time to look for alternative. My main goal was it to be browser agnostic and session links had to be stored in text file, so I can enjoy all the goodies of plain text file. What would be better for that than good old [org-mode][3] ;)
|
||||
它非常有用,特别是如果你像我一样,白天的时候需要在多个“思维活动”之间切换——研究、开发或者阅读新闻。或者你只是单纯地希望记住几天前的工作流(和选项卡)。
|
||||
|
||||
Long time ago I found this trick: [Get the currently open tabs in Google Chrome via the command line][4] and with some elisp sugar and coffee, here is the code:
|
||||
在我决定放弃 chromium 上除了 [uBlock Origin][2] 之外的所有扩展后,就必须寻找一些替代品了。我的主要目标是使之与浏览器无关,同时会话链接必须保存在文本文件中,这样我就可以享受所有纯文本的好处了。还有什么比 [org 模式][3]更好呢 ;)
|
||||
|
||||
很久以前我就发现了这个小诀窍:[通过命令行获取当前在谷歌 Chrome 中打开的标签][4] 再加上些 elisp 代码:
|
||||
|
||||
```
|
||||
(require 'cl-lib)
|
||||
@ -57,9 +59,9 @@ Make sure to put cursor on date heading that contains list of urls."
|
||||
(forward-line 1)))))
|
||||
```
|
||||
|
||||
So, how does it work?
|
||||
那么,它的工作原理是什么呢?
|
||||
|
||||
Evaluate above code, open new org-mode file and call `M-x save-chromium-session`. It will create something like this:
|
||||
运行上述代码,打开一个新 org 模式文件并调用 `M-x save-chromium-session`。它会创建类似这样的东西:
|
||||
|
||||
```
|
||||
* [2019-12-04 12:14:02]
|
||||
@ -68,9 +70,9 @@ Evaluate above code, open new org-mode file and call `M-x save-chromium-session`
|
||||
- https://news.ycombinator.com
|
||||
```
|
||||
|
||||
or whatever urls are running in Chromium instance. To restore it back, put cursor on desired date and run `M-x restore-chromium-session`. All tabs should be back.
|
||||
也就是任何在 chromium 实例中运行着的 URL。要还原的话,则将光标置于所需日期上然后运行 `M-x restore-chromium-session`。所有标签都应该恢复了。
|
||||
|
||||
Here is how I use it, with randomly generated data for the purpose of this text:
|
||||
以下是我的使用案例,其中的数据是随机生成的:
|
||||
|
||||
```
|
||||
#+TITLE: Browser sessions
|
||||
@ -88,27 +90,27 @@ Here is how I use it, with randomly generated data for the purpose of this text:
|
||||
- https://news.ycombinator.com
|
||||
```
|
||||
|
||||
Note that hack for reading Chromium session isn't perfect: `strings` will read whatever looks like string and url from binary database and sometimes that will yield small artifacts in urls. But, you can easily edit those and keep session file lean and clean.
|
||||
请注意,用于读取 Chromium 会话的方法并不完美:`strings` 将从二进制数据库中读取任何类似 URL 字符串的内容,有时这将产生不完整的 URL。不过,你可以很方便地地编辑它们,从而保持会话文件简洁。
|
||||
|
||||
To actually open tabs, elisp code will use [browse-url][5] and it can be further customized to run Chromium, Firefox or any other browser with `browse-url-browser-function` variable. Make sure to read documentation for this variable.
|
||||
为了真正打开标签,elisp 代码中使用到了 [browse-url][5],它可以通过 `browse-url-browser-function` 变量进一步定制成运行 Chromium、Firefox 或任何其他浏览器。请务必阅读该变量的相关文档。
|
||||
|
||||
Don't forget to put session file in git, mercurial or svn and enjoy the fact that you will never loose your session history again :)
|
||||
别忘了把会话文件放在 git、mercurial 或 svn 中,这样你就再也不会丢失会话历史记录了 :)
|
||||
|
||||
### What about Firefox?
|
||||
### 那么 Firefox 呢?
|
||||
|
||||
If you are using Firefox (recent versions) and would like to pull session urls, here is how to do it.
|
||||
如果你正在使用 Firefox(最近的版本),并且想要获取会话 URL,下面是操作方法。
|
||||
|
||||
First, download and compile [lz4json][6], small tool that will decompress Mozilla lz4json format, where Firefox stores session data. Session data (at the time of writing this post) is stored in `$HOME/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4`.
|
||||
首先,下载并编译 [lz4json][6],这是一个可以解压缩 Mozilla lz4json 格式的小工具,Firefox 以这种格式来存储会话数据。会话数据(在撰写本文时)存储在 `$HOME/.mozilla/firefox/<unique-name>/sessionstore-backup /recovery.jsonlz4` 中。
|
||||
|
||||
If Firefox is not running, `recovery.jsonlz4` will not be present, but use `previous.jsonlz4` instead.
|
||||
如果 Firefox 没有运行,则没有 `recovery.jsonlz4`,这种情况下用 `previous.jsonlz4` 代替。
|
||||
|
||||
To extract urls, try this in terminal:
|
||||
要提取网址,尝试在终端运行:
|
||||
|
||||
```
|
||||
$ lz4jsoncat recovery.jsonlz4 | grep -oP '"(http.+?)"' | sed 's/"//g' | sort | uniq
|
||||
```
|
||||
|
||||
and update `save-chromium-session` with:
|
||||
然后更新 `save-chromium-session` 为:
|
||||
|
||||
```
|
||||
(defun save-chromium-session ()
|
||||
@ -122,7 +124,7 @@ and update `save-chromium-session` with:
|
||||
;; rest of the code is unchanged
|
||||
```
|
||||
|
||||
Updating documentation strings, function name and any further refactoring is left for exercise.
|
||||
更新本函数的文档字符串、函数名以及进一步的重构都留作练习。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -131,7 +133,7 @@ via: https://acidwords.com/posts/2019-12-04-handle-chromium-and-firefox-sessions
|
||||
作者:[Sanel Z][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,49 +1,45 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (mengxinayan)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11870-1.html)
|
||||
[#]: subject: (8 Commands to Check Memory Usage on Linux)
|
||||
[#]: via: (https://www.2daygeek.com/linux-commands-check-memory-usage/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
8 Commands to Check Memory Usage on Linux
|
||||
检查 Linux 中内存使用情况的 8 条命令
|
||||
======
|
||||
|
||||
Linux is not like Windows and you will not get a GUI always, especially in a server environment.
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/09/121112mg0jigxtcc5xr8or.jpg)
|
||||
|
||||
As a Linux administrator, it is important to know how to check your available and used resources, such as memory, CPU, disk space, etc.
|
||||
Linux 并不像 Windows,你经常不会有图形界面可供使用,特别是在服务器环境中。
|
||||
|
||||
If there are any applications that use too much resources on the system to run your system at the optimum level you need to find and fix.
|
||||
作为一名 Linux 管理员,知道如何获取当前可用的和已经使用的资源情况,比如内存、CPU、磁盘等,是相当重要的。如果某一应用在你的系统上占用了太多的资源,导致你的系统无法达到最优状态,那么你需要找到并修正它。
|
||||
|
||||
If you want to **[find out the top 10 memory (RAM) consumption processes in Linux][1]**, go to the following article.
|
||||
如果你想找到消耗内存前十名的进程,你需要去阅读这篇文章:[如何在 Linux 中找出内存消耗最大的进程][1]。
|
||||
|
||||
In Linux, there are commands for everything, so use the corresponding commands.
|
||||
在 Linux 中,命令能做任何事,所以使用相关命令吧。在这篇教程中,我们将会给你展示 8 个有用的命令来即查看在 Linux 系统中内存的使用情况,包括 RAM 和交换分区。
|
||||
|
||||
In this tutorial, we will show you eight powerful commands to check memory usage on a Linux system, including RAM and swap.
|
||||
创建交换分区在 Linux 系统中是非常重要的,如果你想了解如何创建,可以去阅读这篇文章:[在 Linux 系统上创建交换分区][2]。
|
||||
|
||||
**[Creating swap space on a Linux system][2]** is very important.
|
||||
下面的命令可以帮助你以不同的方式查看 Linux 内存使用情况。
|
||||
|
||||
The following commands can help you check memory usage in Linux in different ways.
|
||||
* `free` 命令
|
||||
* `/proc/meminfo` 文件
|
||||
* `vmstat` 命令
|
||||
* `ps_mem` 命令
|
||||
* `smem` 命令
|
||||
* `top` 命令
|
||||
* `htop` 命令
|
||||
* `glances` 命令
|
||||
|
||||
* free Command
|
||||
* /proc/meminfo File
|
||||
* vmstat Command
|
||||
* ps_mem Command
|
||||
* smem Command
|
||||
* top Command
|
||||
* htop Command
|
||||
* glances Command
|
||||
### 1)如何使用 free 命令查看 Linux 内存使用情况
|
||||
|
||||
[free 命令][3] 是被 Linux 管理员广泛使用的主要命令。但是它提供的信息比 `/proc/meminfo` 文件少。
|
||||
|
||||
`free` 命令会分别展示物理内存和交换分区内存中已使用的和未使用的数量,以及内核使用的缓冲区和缓存。
|
||||
|
||||
### 1) How to Check Memory Usage on Linux Using the free Command
|
||||
|
||||
**[Free command][3]** is the most powerful command widely used by the Linux administrator. But it provides very little information compared to the “/proc/meminfo” file.
|
||||
|
||||
Free command displays the total amount of free and used physical and swap memory on the system, as well as buffers and caches used by the kernel.
|
||||
|
||||
These information is gathered from the “/proc/meminfo” file.
|
||||
这些信息都是从 `/proc/meminfo` 文件中获取的。
|
||||
|
||||
```
|
||||
# free -m
|
||||
@ -52,24 +48,18 @@ Mem: 15867 9199 1702 3315 4965 3039
|
||||
Swap: 17454 666 16788
|
||||
```
|
||||
|
||||
* **total:** Total installed memory
|
||||
* **used:** Memory is currently in use by running processes (used= total – free – buff/cache)
|
||||
* **free:** Unused memory (free= total – used – buff/cache)
|
||||
* **shared:** Memory shared between two or more processes (multiple processes)
|
||||
* **buffers:** Memory reserved by the kernel to hold a process queue request.
|
||||
* **cache:** Size of the page cache that holds recently used files in RAM
|
||||
* **buff/cache:** Buffers + Cache
|
||||
* **available:** Estimation of how much memory is available for starting new applications, without swapping.
|
||||
* `total`:总的内存量
|
||||
* `used`:被当前运行中的进程使用的内存量(`used` = `total` – `free` – `buff/cache`)
|
||||
* `free`: 未被使用的内存量(`free` = `total` – `used` – `buff/cache`)
|
||||
* `shared`: 在两个或多个进程之间共享的内存量
|
||||
* `buffers`: 内存中保留用于内核记录进程队列请求的内存量
|
||||
* `cache`: 在 RAM 中存储最近使用过的文件的页缓冲大小
|
||||
* `buff/cache`: 缓冲区和缓存总的使用内存量
|
||||
* `available`: 可用于启动新应用的可用内存量(不含交换分区)
|
||||
|
||||
### 2) 如何使用 /proc/meminfo 文件查看 Linux 内存使用情况
|
||||
|
||||
|
||||
### 2) How to Check Memory Usage on Linux Using the /proc/meminfo File
|
||||
|
||||
The “/proc/meminfo” file is a virtual file that contains various real-time information about memory usage.
|
||||
|
||||
It shows memory stats in kilobytes, most of which are somewhat difficult to understand.
|
||||
|
||||
However it contains useful information about memory usage.
|
||||
`/proc/meminfo` 文件是一个包含了多种内存使用的实时信息的虚拟文件。它展示内存状态单位使用的是 kB,其中大部分属性都难以理解。然而它也包含了内存使用情况的有用信息。
|
||||
|
||||
```
|
||||
# cat /proc/meminfo
|
||||
@ -124,13 +114,11 @@ DirectMap2M: 14493696 kB
|
||||
DirectMap1G: 2097152 kB
|
||||
```
|
||||
|
||||
### 3) How to Check Memory Usage on Linux Using the vmstat Command
|
||||
### 3) 如何使用 vmstat 命令查看 Linux 内存使用情况
|
||||
|
||||
The **[vmstat command][4]** is another useful tool for reporting virtual memory statistics.
|
||||
[vmstat 命令][4] 是另一个报告虚拟内存统计信息的有用工具。
|
||||
|
||||
vmstat reports information about processes, memory, paging, block IO, traps, disks, and cpu functionality.
|
||||
|
||||
vmstat does not require special permissions, and it can help identify system bottlenecks.
|
||||
`vmstat` 报告的信息包括:进程、内存、页面映射、块 I/O、陷阱、磁盘和 CPU 特性信息。`vmstat` 不需要特殊的权限,并且它可以帮助诊断系统瓶颈。
|
||||
|
||||
```
|
||||
# vmstat
|
||||
@ -140,58 +128,35 @@ procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
|
||||
1 0 682060 1769324 234188 4853500 0 3 25 91 31 16 34 13 52 0 0
|
||||
```
|
||||
|
||||
If you want to understand this in detail, read the field description below.
|
||||
如果你想详细了解每一项的含义,阅读下面的描述。
|
||||
|
||||
**Procs**
|
||||
* `procs`:进程
|
||||
* `r`: 可以运行的进程数目(正在运行或等待运行)
|
||||
* `b`: 处于不可中断睡眠中的进程数目
|
||||
* `memory`:内存
|
||||
* `swpd`: 使用的虚拟内存数量
|
||||
* `free`: 空闲的内存数量
|
||||
* `buff`: 用作缓冲区内存的数量
|
||||
* `cache`: 用作缓存内存的数量
|
||||
* `inact`: 不活动的内存数量(使用 `-a` 选项)
|
||||
* `active`: 活动的内存数量(使用 `-a` 选项)
|
||||
* `Swap`:交换分区
|
||||
* `si`: 每秒从磁盘交换的内存数量
|
||||
* `so`: 每秒交换到磁盘的内存数量
|
||||
* `IO`:输入输出
|
||||
* `bi`: 从一个块设备中收到的块(块/秒)
|
||||
* `bo`: 发送到一个块设备的块(块/秒)
|
||||
* `System`:系统
|
||||
* `in`: 每秒的中断次数,包括时钟。
|
||||
* `cs`: 每秒的上下文切换次数。
|
||||
* `CPU`:下面这些是在总的 CPU 时间占的百分比
|
||||
* `us`: 花费在非内核代码上的时间占比(包括用户时间,调度时间)
|
||||
* `sy`: 花费在内核代码上的时间占比 (系统时间)
|
||||
* `id`: 花费在闲置的时间占比。在 Linux 2.5.41 之前,包括 I/O 等待时间
|
||||
* `wa`: 花费在 I/O 等待上的时间占比。在 Linux 2.5.41 之前,包括在空闲时间中
|
||||
* `st`: 被虚拟机偷走的时间占比。在 Linux 2.6.11 之前,这部分称为 unknown
|
||||
|
||||
* **r:** The number of runnable processes (running or waiting for run time).
|
||||
* **b:** The number of processes in uninterruptible sleep.
|
||||
|
||||
|
||||
|
||||
**Memory**
|
||||
|
||||
* **swpd:** the amount of virtual memory used.
|
||||
* **free:** the amount of idle memory.
|
||||
* **buff:** the amount of memory used as buffers.
|
||||
* **cache:** the amount of memory used as cache.
|
||||
* **inact:** the amount of inactive memory. (-a option)
|
||||
* **active:** the amount of active memory. (-a option)
|
||||
|
||||
|
||||
|
||||
**Swap**
|
||||
|
||||
* **si:** Amount of memory swapped in from disk (/s).
|
||||
* **so:** Amount of memory swapped to disk (/s).
|
||||
|
||||
|
||||
|
||||
**IO**
|
||||
|
||||
* **bi:** Blocks received from a block device (blocks/s).
|
||||
* **bo:** Blocks sent to a block device (blocks/s).
|
||||
|
||||
|
||||
|
||||
**System**
|
||||
|
||||
* **in:** The number of interrupts per second, including the clock.
|
||||
* **cs:** The number of context switches per second.
|
||||
|
||||
|
||||
|
||||
**CPU : These are percentages of total CPU time.**
|
||||
|
||||
* **us:** Time spent running non-kernel code. (user time, including nice time)
|
||||
* **sy:** Time spent running kernel code. (system time)
|
||||
* **id:** Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time.
|
||||
* **wa:** Time spent waiting for IO. Prior to Linux 2.5.41, included in idle.
|
||||
* **st:** Time stolen from a virtual machine. Prior to Linux 2.6.11, unknown.
|
||||
|
||||
|
||||
|
||||
Run the following command for detailed information.
|
||||
运行下面的命令查看详细的信息。
|
||||
|
||||
```
|
||||
# vmstat -s
|
||||
@ -223,16 +188,13 @@ Run the following command for detailed information.
|
||||
1577163147 boot time
|
||||
3318 forks
|
||||
```
|
||||
### 4) 如何使用 ps_mem 命令查看 Linux 内存使用情况
|
||||
|
||||
### 4) How to Check Memory Usage on Linux Using the ps_mem Command
|
||||
[ps_mem][5] 是一个用来查看当前内存使用情况的简单的 Python 脚本。该工具可以确定每个程序使用了多少内存(不是每个进程)。
|
||||
|
||||
**[ps_mem][5]** is a simple Python script that allows you to get core memory usage accurately for a program in Linux.
|
||||
该工具采用如下的方法计算每个程序使用内存:总的使用 = 程序进程私有的内存 + 程序进程共享的内存。
|
||||
|
||||
This can determine how much RAM is used per program (not per process).
|
||||
|
||||
It calculates the total amount of memory used per program, total = sum (private RAM for program processes) + sum (shared RAM for program processes).
|
||||
|
||||
The shared RAM is problematic to calculate, and the tool automatically selects the most accurate method available for the running kernel.
|
||||
计算共享内存是存在不足之处的,该工具可以为运行中的内核自动选择最准确的方法。
|
||||
|
||||
```
|
||||
# ps_mem
|
||||
@ -285,15 +247,13 @@ The shared RAM is problematic to calculate, and the tool automatically selects t
|
||||
==================================
|
||||
```
|
||||
|
||||
### 5) How to Check Memory Usage on Linux Using the smem Command
|
||||
### 5)如何使用 smem 命令查看 Linux 内存使用情况
|
||||
|
||||
**[smem][6]** is a tool that can provide numerous reports of memory usage on Linux systems. Unlike existing tools, smem can report Proportional Set Size (PSS), Unique Set Size (USS) and Resident Set Size (RSS).
|
||||
[smem][6] 是一个可以为 Linux 系统提供多种内存使用情况报告的工具。不同于现有的工具,`smem` 可以报告<ruby>比例集大小<rt>Proportional Set Size</rt></ruby>(PSS)、<ruby>唯一集大小<rt>Unique Set Size</rt></ruby>(USS)和<ruby>驻留集大小<rt>Resident Set Size</rt></ruby>(RSS)。
|
||||
|
||||
Proportional Set Size (PSS): refers to the amount of memory used by libraries and applications in the virtual memory system.
|
||||
|
||||
Unique Set Size (USS) : Unshared memory is reported as USS (Unique Set Size).
|
||||
|
||||
Resident Set Size (RSS) : The standard measure of physical memory (it typically shared among multiple applications) usage known as resident set size (RSS) will significantly overestimate memory usage.
|
||||
- 比例集大小(PSS):库和应用在虚拟内存系统中的使用量。
|
||||
- 唯一集大小(USS):其报告的是非共享内存。
|
||||
- 驻留集大小(RSS):物理内存(通常多进程共享)使用情况,其通常高于内存使用量。
|
||||
|
||||
```
|
||||
# smem -tk
|
||||
@ -336,13 +296,11 @@ Resident Set Size (RSS) : The standard measure of physical memory (it typically
|
||||
90 1 0 4.8G 5.2G 8.0G
|
||||
```
|
||||
|
||||
### 6) How to Check Memory Usage on Linux Using the top Command
|
||||
### 6) 如何使用 top 命令查看 Linux 内存使用情况
|
||||
|
||||
**[top command][7]** is one of the most frequently used commands by Linux administrators to understand and view the resource usage for a process on a Linux system.
|
||||
[top 命令][7] 是一个 Linux 系统的管理员最常使用的用于查看进程的资源使用情况的命令。
|
||||
|
||||
It displays the total memory of the system, current memory usage, free memory and total memory used by the buffers.
|
||||
|
||||
In addition, it displays total swap memory, current swap usage, free swap memory, and total cached memory by the system.
|
||||
该命令会展示了系统总的内存量、当前内存使用量、空闲内存量和缓冲区使用的内存总量。此外,该命令还会展示总的交换空间内存量、当前交换空间的内存使用量、空闲的交换空间内存量和缓存使用的内存总量。
|
||||
|
||||
```
|
||||
# top -b | head -10
|
||||
@ -368,27 +326,25 @@ KiB Swap: 17873388 total, 17873388 free, 0 used. 9179772 avail Mem
|
||||
2174 daygeek 20 2466680 122196 78604 S 0.8 0.8 0:17.75 WebExtensi+
|
||||
```
|
||||
|
||||
### 7) How to Check Memory Usage on Linux Using the htop Command
|
||||
### 7) 如何使用 htop 命令查看 Linux 内存使用情况
|
||||
|
||||
The **[htop command][8]** is an interactive process viewer for Linux/Unix systems. It is a text-mode application and requires the ncurses library, it was developed by Hisham.
|
||||
[htop 命令][8] 是一个可交互的 Linux/Unix 系统进程查看器。它是一个文本模式应用,且使用它需要 Hisham 开发的 ncurses 库。
|
||||
|
||||
It is designed as an alternative to the top command.
|
||||
该名令的设计目的使用来代替 `top` 命令。该命令与 `top` 命令很相似,但是其允许你可以垂直地或者水平地的滚动以便可以查看系统中所有的进程情况。
|
||||
|
||||
This is similar to the top command, but allows you to scroll vertically and horizontally to see all the processes running the system.
|
||||
`htop` 命令拥有不同的颜色,这个额外的优点当你在追踪系统性能情况时十分有用。
|
||||
|
||||
htop comes with Visual Colors, which have added benefits and are very evident when it comes to tracking system performance.
|
||||
此外,你可以自由地执行与进程相关的任务,比如杀死进程或者改变进程的优先级而不需要其进程号(PID)。
|
||||
|
||||
You are free to carry out any tasks related to processes, such as process killing and renicing without entering their PIDs.
|
||||
![][10]
|
||||
|
||||
[![][9]][10]
|
||||
### 8)如何使用 glances 命令查看 Linux 内存使用情况
|
||||
|
||||
### 8) How to Check Memory Usage on Linux Using the glances Command
|
||||
[Glances][11] 是一个 Python 编写的跨平台的系统监视工具。
|
||||
|
||||
**[Glances][11]** is a cross-platform system monitoring tool written in Python.
|
||||
你可以在一个地方查看所有信息,比如:CPU 使用情况、内存使用情况、正在运行的进程、网络接口、磁盘 I/O、RAID、传感器、文件系统信息、Docker、系统信息、运行时间等等。
|
||||
|
||||
You can see all information in one place such as CPU usage, Memory usage, running process, Network interface, Disk I/O, Raid, Sensors, Filesystem info, Docker, System info, Uptime, etc,.
|
||||
|
||||
![][9]
|
||||
![][12]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -397,20 +353,21 @@ via: https://www.2daygeek.com/linux-commands-check-memory-usage/
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/how-to-find-high-cpu-consumption-processes-in-linux/
|
||||
[2]: https://www.2daygeek.com/add-extend-increase-swap-space-memory-file-partition-linux/
|
||||
[3]: https://www.2daygeek.com/free-command-to-check-memory-usage-statistics-in-linux/
|
||||
[4]: https://www.2daygeek.com/linux-vmstat-command-examples-tool-report-virtual-memory-statistics/
|
||||
[5]: https://www.2daygeek.com/ps_mem-report-core-memory-usage-accurately-in-linux/
|
||||
[6]: https://www.2daygeek.com/smem-linux-memory-usage-statistics-reporting-tool/
|
||||
[1]: https://linux.cn/article-11542-1.html
|
||||
[2]: https://linux.cn/article-9579-1.html
|
||||
[3]: https://linux.cn/article-8314-1.html
|
||||
[4]: https://linux.cn/article-8157-1.html
|
||||
[5]: https://linux.cn/article-8639-1.html
|
||||
[6]: https://linux.cn/article-7681-1.html
|
||||
[7]: https://www.2daygeek.com/linux-top-command-linux-system-performance-monitoring-tool/
|
||||
[8]: https://www.2daygeek.com/linux-htop-command-linux-system-performance-resource-monitoring-tool/
|
||||
[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/12/linux-commands-check-memory-usage-2.jpg
|
||||
[11]: https://www.2daygeek.com/linux-glances-advanced-real-time-linux-system-performance-monitoring-tool/
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/12/linux-commands-check-memory-usage-3.jpg
|
@ -0,0 +1,57 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Morisun029)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11875-1.html)
|
||||
[#]: subject: (Top CI/CD resources to set you up for success)
|
||||
[#]: via: (https://opensource.com/article/19/12/cicd-resources)
|
||||
[#]: author: (Jessica Cherry https://opensource.com/users/jrepka)
|
||||
|
||||
顶级 CI / CD 资源,助你成功
|
||||
======
|
||||
|
||||
> 随着企业期望实现无缝、灵活和可扩展的部署,持续集成和持续部署成为 2019 年的关键主题。
|
||||
|
||||
![Plumbing tubes in many directions][1]
|
||||
|
||||
对于 CI/CD 和 DevOps 来说,2019 年是非常棒的一年。Opensource.com 的作者分享了他们专注于无缝、灵活和可扩展部署时是如何朝着敏捷和 scrum 方向发展的。以下是我们 2019 年发布的 CI/CD 文章中的一些重要文章。
|
||||
|
||||
### 学习和提高你的 CI/CD 技能
|
||||
|
||||
我们最喜欢的一些文章集中在 CI/CD 的实操经验上,并涵盖了许多方面。通常以 [Jenkins][2] 管道开始,Bryant Son 的文章《[用 Jenkins 构建 CI/CD 管道][3]》将为你提供足够的经验,以开始构建你的第一个管道。Daniel Oh 在《[用 DevOps 管道进行自动验收测试][4]》一文中,提供了有关验收测试的重要信息,包括可用于自行测试的各种 CI/CD 应用程序。我写的《[安全扫描 DevOps 管道][5]》非常简短,其中简要介绍了如何使用 Jenkins 平台在管道中设置安全性。
|
||||
|
||||
### 交付工作流程
|
||||
|
||||
正如 Jithin Emmanuel 在《[Screwdriver:一个用于持续交付的可扩展构建平台][6]》中分享的,在学习如何使用和提高你的 CI/CD 技能方面,工作流程很重要,特别是当涉及到管道时。Emily Burns 在《[为什么 Spinnaker 对 CI/CD 很重要][7]》中解释了灵活地使用 CI/CD 工作流程准确构建所需内容的原因。Willy-Peter Schaub 还盛赞了为所有产品创建统一管道的想法,以便《[在一个 CI/CD 管道中一致地构建每个产品][8]》。这些文章将让你很好地了解在团队成员加入工作流程后会发生什么情况。
|
||||
|
||||
### CI/CD 如何影响企业
|
||||
|
||||
2019 年也是认识到 CI/CD 的业务影响以及它是如何影响日常运营的一年。Agnieszka Gancarczyk 分享了 Red Hat 《[小型 Scrum vs. 大型 Scrum][9]》的调查结果, 包括受访者对 Scrum、敏捷运动及对团队的影响的不同看法。Will Kelly 的《[持续部署如何影响整个组织][10]》,也提及了开放式沟通的重要性。Daniel Oh 也在《[DevOps 团队必备的 3 种指标仪表板][11]》中强调了指标和可观测性的重要性。最后是 Ann Marie Fred 的精彩文章《[不在生产环境中测试?要在生产环境中测试!][12]》详细说明了在验收测试前在生产环境中测试的重要性。
|
||||
|
||||
感谢许多贡献者在 2019 年与 Opensource 的读者分享他们的见解,我期望在 2020 年里从他们那里了解更多有关 CI/CD 发展的信息。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/cicd-resources
|
||||
|
||||
作者:[Jessica Cherry][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Morisun029](https://github.com/Morisun029)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jrepka
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/plumbing_pipes_tutorial_how_behind_scenes.png?itok=F2Z8OJV1 (Plumbing tubes in many directions)
|
||||
[2]: https://jenkins.io/
|
||||
[3]: https://linux.cn/article-11546-1.html
|
||||
[4]: https://opensource.com/article/19/4/devops-pipeline-acceptance-testing
|
||||
[5]: https://opensource.com/article/19/7/security-scanning-your-devops-pipeline
|
||||
[6]: https://opensource.com/article/19/3/screwdriver-cicd
|
||||
[7]: https://opensource.com/article/19/8/why-spinnaker-matters-cicd
|
||||
[8]: https://opensource.com/article/19/7/cicd-pipeline-rule-them-all
|
||||
[9]: https://opensource.com/article/19/3/small-scale-scrum-vs-large-scale-scrum
|
||||
[10]: https://opensource.com/article/19/7/organizational-impact-continuous-deployment
|
||||
[11]: https://linux.cn/article-11183-1.html
|
||||
[12]: https://opensource.com/article/19/5/dont-test-production
|
@ -1,22 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (laingke)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11857-1.html)
|
||||
[#]: subject: (Data streaming and functional programming in Java)
|
||||
[#]: via: (https://opensource.com/article/20/1/javastream)
|
||||
[#]: author: (Marty Kalin https://opensource.com/users/mkalindepauledu)
|
||||
|
||||
Java 中的数据流和函数式编程
|
||||
======
|
||||
学习如何使用 Java 8 中的流 API 和函数式编程结构。
|
||||
![computer screen ][1]
|
||||
|
||||
当 Java SE 8(又名核心 Java 8)在 2014 年被推出时,它引入了一些从根本上影响 IT 编程的更改。这些更改中有两个紧密相连的部分:流API和功能编程构造。本文使用代码示例,从基础到高级特性,介绍每个部分并说明它们之间的相互作用。
|
||||
> 学习如何使用 Java 8 中的流 API 和函数式编程结构。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/06/002505flazlb4cg4aavvb4.jpg)
|
||||
|
||||
当 Java SE 8(又名核心 Java 8)在 2014 年被推出时,它引入了一些更改,从根本上影响了用它进行的编程。这些更改中有两个紧密相连的部分:流 API 和函数式编程构造。本文使用代码示例,从基础到高级特性,介绍每个部分并说明它们之间的相互作用。
|
||||
|
||||
### 基础特性
|
||||
|
||||
流 API 是在数据序列中迭代元素的简洁而高级的方法。包 `java.util.stream` 和 `java.util.function` 包含用于流 API 和相关函数式编程构造的新库。当然,一个代码示例胜过千言万语。
|
||||
流 API 是在数据序列中迭代元素的简洁而高级的方法。包 `java.util.stream` 和 `java.util.function` 包含了用于流 API 和相关函数式编程构造的新库。当然,代码示例胜过千言万语。
|
||||
|
||||
下面的代码段用大约 2,000 个随机整数值填充了一个 `List`:
|
||||
|
||||
@ -26,7 +28,9 @@ List<Integer> list = new ArrayList<Integer>(); // 空 list
|
||||
for (int i = 0; i < 2048; i++) list.add(rand.nextInt()); // 填充它
|
||||
```
|
||||
|
||||
另一个 `for` 循环可用于遍历填充 list,以将偶数值收集到另一个 list 中。流 API 提供了一种更简洁的方法来执行此操作:
|
||||
另外用一个 `for` 循环可用于遍历填充列表,以将偶数值收集到另一个列表中。
|
||||
|
||||
流 API 提供了一种更简洁的方法来执行此操作:
|
||||
|
||||
```
|
||||
List <Integer> evens = list
|
||||
@ -37,43 +41,42 @@ List <Integer> evens = list
|
||||
|
||||
这个例子有三个来自流 API 的函数:
|
||||
|
||||
> `stream` 函数可以将**集合**转换为流,而流是一个每次可访问一个值的传送带。流化是惰性的(因此也是高效的),因为值是根据需要产生的,而不是一次性产生的。
|
||||
|
||||
> `filter` 函数确定哪些流的值(如果有的话)通过了处理管道中的下一个阶段,即 `collect` 阶段。`filter` 函数是 _<ruby>高阶的<rt>higher-order</rt></ruby>_,因为它的参数是一个函数 —— 在这个例子中是一个 lambda 表达式,它是一个未命名的函数,并且是 Java 新的函数式编程结构的核心。
|
||||
- `stream` 函数可以将**集合**转换为流,而流是一个每次可访问一个值的传送带。流化是惰性的(因此也是高效的),因为值是根据需要产生的,而不是一次性产生的。
|
||||
- `filter` 函数确定哪些流的值(如果有的话)通过了处理管道中的下一个阶段,即 `collect` 阶段。`filter` 函数是 <ruby>高阶的<rt>higher-order</rt></ruby>,因为它的参数是一个函数 —— 在这个例子中是一个 lambda 表达式,它是一个未命名的函数,并且是 Java 新的函数式编程结构的核心。
|
||||
|
||||
lambda 语法与传统的 Java 完全不同:
|
||||
|
||||
```
|
||||
`n -> (n & 0x1) == 0`
|
||||
n -> (n & 0x1) == 0
|
||||
```
|
||||
|
||||
箭头(一个减号后面紧跟着一个大于号)将左边的参数列表与右边的函数体分隔开。参数 `n` 虽未明确输入,但可以显式输入。在任何情况下,编译器都会计算出 `n` 是 `Integer`。如果有多个参数,这些参数将被括在括号中,并用逗号分隔。
|
||||
箭头(一个减号后面紧跟着一个大于号)将左边的参数列表与右边的函数体分隔开。参数 `n` 虽未明确类型,但也可以明确。在任何情况下,编译器都会发现 `n` 是个 `Integer`。如果有多个参数,这些参数将被括在括号中,并用逗号分隔。
|
||||
|
||||
在本例中,函数体检查一个整数的最低顺序(最右)位是否为零,以表示为偶数。过滤器应返回一个布尔值。尽管可以,但函数的主体中没有显式的 `return`。如果主体没有显式的 `return`,则主体的最后一个表达式是返回值。在这个例子中,主体按照 lambda 编程的思想编写,由一个简单的布尔表达式 `(n & 0x1) == 0` 组成。
|
||||
在本例中,函数体检查一个整数的最低位(最右)是否为零,这用来表示偶数。过滤器应返回一个布尔值。尽管可以,但该函数的主体中没有显式的 `return`。如果主体没有显式的 `return`,则主体的最后一个表达式即是返回值。在这个例子中,主体按照 lambda 编程的思想编写,由一个简单的布尔表达式 `(n & 0x1) == 0` 组成。
|
||||
|
||||
> `collect` 函数将偶数值收集到引用为 `evens` 的 list 中。如下例所示,`collect` 函数是线程安全的,因此,即使在多个线程之间共享了过滤操作,该函数也可以正常工作。
|
||||
- `collect` 函数将偶数值收集到引用为 `evens` 的列表中。如下例所示,`collect` 函数是线程安全的,因此,即使在多个线程之间共享了过滤操作,该函数也可以正常工作。
|
||||
|
||||
### 方便的功能和轻松实现多线程
|
||||
|
||||
在生产环境中,数据流的源可能是文件或网络连接。为了学习流 API, Java 提供了诸如 `IntStream` 这样的类型,它可以用各种类型的元素生成流。这里有一个 `IntStream` 的例子:
|
||||
|
||||
```
|
||||
IntStream // 整型流
|
||||
IntStream // 整型流
|
||||
.range(1, 2048) // 生成此范围内的整型流
|
||||
.parallel() // 为多个线程分区数据
|
||||
.filter(i -> ((i & 0x1) > 0)) // 奇偶校验 - 只允许奇数通过
|
||||
.forEach(System.out::println); // 打印每个值
|
||||
```
|
||||
|
||||
`IntStream` 类型包括一个 `range` 函数,该函数在指定的范围内生成一个整数值流,在本例中,以 1 为增量,从 1 递增到 2,048。`parallel` 函数自动工作划分到多个线程中,在各个线程中进行过滤和打印。(线程数通常与主机系统上的 CPU 数量匹配。)函数 `forEach` 参数是一个_方法引用_,在本例中是对封装在 `System.out` 中的 `println` 方法的引用,方法输出类型为 `PrintStream`。方法和构造器引用的语法将在稍后讨论。
|
||||
`IntStream` 类型包括一个 `range` 函数,该函数在指定的范围内生成一个整数值流,在本例中,以 1 为增量,从 1 递增到 2048。`parallel` 函数自动划分该工作到多个线程中,在各个线程中进行过滤和打印。(线程数通常与主机系统上的 CPU 数量匹配。)函数 `forEach` 参数是一个*方法引用*,在本例中是对封装在 `System.out` 中的 `println` 方法的引用,方法输出类型为 `PrintStream`。方法和构造器引用的语法将在稍后讨论。
|
||||
|
||||
由于具有多线程,因此整数值整体上以任意顺序打印,但在给定线程中按顺序打印。例如,如果线程 T1 打印 409 和 411,那么 T1 将按照顺序 409-411 打印,但是其它某个线程可能会预先打印 2,045。`parallel` 调用后面的线程是并发执行的,因此它们的输出顺序是不确定的。
|
||||
由于具有多线程,因此整数值整体上以任意顺序打印,但在给定线程中是按顺序打印的。例如,如果线程 T1 打印 409 和 411,那么 T1 将按照顺序 409-411 打印,但是其它某个线程可能会预先打印 2045。`parallel` 调用后面的线程是并发执行的,因此它们的输出顺序是不确定的。
|
||||
|
||||
### map/reduce 模式
|
||||
|
||||
_map/reduce_ 模式在处理大型数据集方面已变得很流行。一个 map/reduce 宏操作由两个微操作构成。首先,将数据分散(_mapped_)到各个工作程序中,然后将单独的结果收集在一起 —— 也可能收集统计起来成为一个值,即 _reduction_。Reduction 可以采用不同的形式,如以下示例所示。
|
||||
*map/reduce* 模式在处理大型数据集方面变得很流行。一个 map/reduce 宏操作由两个微操作构成。首先,将数据分散(<ruby>映射<rt>mapped</rt></ruby>)到各个工作程序中,然后将单独的结果收集在一起 —— 也可能收集统计起来成为一个值,即<ruby>归约<rt>reduction</rt></ruby>。归约可以采用不同的形式,如以下示例所示。
|
||||
|
||||
下面 `Number` 类的实例用 **EVEN** 或 **ODD** 表示有奇偶校验的整数值:
|
||||
下面 `Number` 类的实例用 `EVEN` 或 `ODD` 表示有奇偶校验的整数值:
|
||||
|
||||
```
|
||||
public class Number {
|
||||
@ -92,7 +95,7 @@ public class Number {
|
||||
}
|
||||
```
|
||||
|
||||
下面的代码演示了带有 `Number` 流进行 map/reduce 的情形,从而表明流 API 不仅可以处理 `int` 和 `float` 等基本类型,还可以处理程序员自定义的类类型。
|
||||
下面的代码演示了用 `Number` 流进行 map/reduce 的情形,从而表明流 API 不仅可以处理 `int` 和 `float` 等基本类型,还可以处理程序员自定义的类类型。
|
||||
|
||||
在下面的代码段中,使用了 `parallelStream` 而不是 `stream` 函数对随机整数值列表进行流化处理。与前面介绍的 `parallel` 函数一样,`parallelStream` 变体也可以自动执行多线程。
|
||||
|
||||
@ -115,14 +118,14 @@ System.out.println("The sum of the randomly generated values is: " + sum4All);
|
||||
方法引用 `Number::getValue` 可以用下面的 lambda 表达式替换。参数 `n` 是流中的 `Number` 实例中的之一:
|
||||
|
||||
```
|
||||
`mapToInt(n -> n.getValue())`
|
||||
mapToInt(n -> n.getValue())
|
||||
```
|
||||
|
||||
通常,lambdas 和方法引用是可互换的:如果像 `mapToInt` 这样的高阶函数可以采用一种形式作为参数,那么这个函数也可以采用另一种形式。这两个函数式编程结构具有相同的目的 —— 对作为参数传入的数据执行一些自定义操作。在两者之间进行选择通常是为了方便。例如,lambda 可以在没有封装类的情况下编写,而方法则不能。。我的习惯是使用 lambda,除非已经有了适当的封装方法。
|
||||
通常,lambda 表达式和方法引用是可互换的:如果像 `mapToInt` 这样的高阶函数可以采用一种形式作为参数,那么这个函数也可以采用另一种形式。这两个函数式编程结构具有相同的目的 —— 对作为参数传入的数据执行一些自定义操作。在两者之间进行选择通常是为了方便。例如,lambda 可以在没有封装类的情况下编写,而方法则不能。我的习惯是使用 lambda,除非已经有了适当的封装方法。
|
||||
|
||||
当前示例末尾的 `sum` 函数通过结合来自 `parallelStream` 线程的部分和,以线程安全的方式进行归约。但是,程序员有责任确保在 `parallelStream` 调用引发的多线程过程中,程序员自己的函数调用(在本例中为 `getValue`)是线程安全的。
|
||||
|
||||
最后一点值得强调。lambda 语法鼓励编写 _<ruby>纯函数<rt>pure function</rt></ruby>_,即函数的返回值仅取决于传入的参数(如果有);纯函数没有副作用,例如更新类中的 `static` 字段。因此,纯函数是线程安全的,并且如果传递给高阶函数的函数参数(例如 `filter` 和 `map` )是纯函数,则流 API 效果最佳。
|
||||
最后一点值得强调。lambda 语法鼓励编写<ruby>纯函数<rt>pure function</rt></ruby>,即函数的返回值仅取决于传入的参数(如果有);纯函数没有副作用,例如更新一个类中的 `static` 字段。因此,纯函数是线程安全的,并且如果传递给高阶函数的函数参数(例如 `filter` 和 `map` )是纯函数,则流 API 效果最佳。
|
||||
|
||||
对于更细粒度的控制,有另一个流 API 函数,名为 `reduce`,可用于对 `Number` 流中的值求和:
|
||||
|
||||
@ -135,11 +138,10 @@ Integer sum4AllHarder = listOfNums
|
||||
|
||||
此版本的 `reduce` 函数带有两个参数,第二个参数是一个函数:
|
||||
|
||||
> 第一个参数(在这种情况下为零)是 _特征_ 值,该值用作求和操作的初始值,并且在求和过程中流结束时用作默认值。
|
||||
- 第一个参数(在这种情况下为零)是*特征*值,该值用作求和操作的初始值,并且在求和过程中流结束时用作默认值。
|
||||
- 第二个参数是*累加器*,在本例中,这个 lambda 表达式有两个参数:第一个参数(`sofar`)是正在运行的和,第二个参数(`next`)是来自流的下一个值。运行的和以及下一个值相加,然后更新累加器。请记住,由于开始时调用了 `parallelStream`,因此 `map` 和 `reduce` 函数现在都在多线程上下文中执行。
|
||||
|
||||
> 第二个参数是 _累加器_,在本例中,这个 lambda 表达式有两个参数:第一个参数(`sofar`)是正在运行的和,第二个参数(`next`)是来自流的下一个值。运行总和以及下一个值相加,然后更新累加器。请记住,由于开始时调用了 `parallelStream`,因此 `map` 和 `reduce` 函数现在都在多线程上下文中执行。
|
||||
|
||||
在到目前为止的示例中,流值被收集,然后被归并,但是,通常情况下,流 API 中的 `Collectors` 可以累积值,而不需要将它们减少到单个值。正如下一个代码段所示,收集活动可以生成任意丰富的数据结构。该示例使用与前面示例相同的 `listOfNums`:
|
||||
在到目前为止的示例中,流值被收集,然后被规约,但是,通常情况下,流 API 中的 `Collectors` 可以累积值,而不需要将它们规约到单个值。正如下一个代码段所示,收集活动可以生成任意丰富的数据结构。该示例使用与前面示例相同的 `listOfNums`:
|
||||
|
||||
```
|
||||
Map<Number.Parity, List<Number>> numMap = listOfNums
|
||||
@ -150,7 +152,7 @@ List<Number> evens = numMap.get(Number.Parity.EVEN);
|
||||
List<Number> odds = numMap.get(Number.Parity.ODD);
|
||||
```
|
||||
|
||||
第一行中的 `numMap` 指的是一个 `Map`,它的键是一个 `Number` 奇偶校验位(**ODD** 或 **EVEN**),其值是一个具有指定奇偶校验位值的 `Number` 实例的`List`。同样,通过 `parallelStream` 调用进行多线程处理,然后 `collect` 调用(以线程安全的方式)将部分结果组装到 `numMap` 引用的 `Map` 中。然后,在 `numMap` 上调用 `get` 方法两次,一次获取 `evens`,第二次获取 `odds`。
|
||||
第一行中的 `numMap` 指的是一个 `Map`,它的键是一个 `Number` 奇偶校验位(`ODD` 或 `EVEN`),其值是一个具有指定奇偶校验位值的 `Number` 实例的 `List`。同样,通过 `parallelStream` 调用进行多线程处理,然后 `collect` 调用(以线程安全的方式)将部分结果组装到 `numMap` 引用的 `Map` 中。然后,在 `numMap` 上调用 `get` 方法两次,一次获取 `evens`,第二次获取 `odds`。
|
||||
|
||||
实用函数 `dumpList` 再次使用来自流 API 的高阶 `forEach` 函数:
|
||||
|
||||
@ -184,7 +186,7 @@ Value: 41 (parity: odd)
|
||||
|
||||
### 用于代码简化的函数式结构
|
||||
|
||||
函数式结构(如方法引用和 lambdas)非常适合在流 API 中使用。这些构造代表了 Java 中对高阶函数的主要简化。即使在糟糕的过去,Java 也通过 `Method` 和 `Constructor` 类型在技术上支持高阶函数,这些类型的实例可以作为参数传递给其它函数。由于其复杂性,这些类型在生产级 Java 中很少使用。例如,调用 `Method` 需要对象引用(如果方法是非**静态**的)或至少一个类标识符(如果方法是**静态**的)。然后,被调用的 `Method` 的参数作为**对象**实例传递给它,如果没有发生多态(那会出现另一种复杂性!),则可能需要显式向下转换。相比之下,lambda 和方法引用很容易作为参数传递给其它函数。
|
||||
函数式结构(如方法引用和 lambda 表达式)非常适合在流 API 中使用。这些构造代表了 Java 中对高阶函数的主要简化。即使在糟糕的过去,Java 也通过 `Method` 和 `Constructor` 类型在技术上支持高阶函数,这些类型的实例可以作为参数传递给其它函数。由于其复杂性,这些类型在生产级 Java 中很少使用。例如,调用 `Method` 需要对象引用(如果方法是非**静态**的)或至少一个类标识符(如果方法是**静态**的)。然后,被调用的 `Method` 的参数作为**对象**实例传递给它,如果没有发生多态(那会出现另一种复杂性!),则可能需要显式向下转换。相比之下,lambda 和方法引用很容易作为参数传递给其它函数。
|
||||
|
||||
但是,新的函数式结构在流 API 之外具有其它用途。考虑一个 Java GUI 程序,该程序带有一个供用户按下的按钮,例如,按下以获取当前时间。按钮按下的事件处理程序可能编写如下:
|
||||
|
||||
@ -201,7 +203,7 @@ updateCurrentTime.addActionListener(new ActionListener() {
|
||||
这个简短的代码段很难解释。关注第二行,其中方法 `addActionListener` 的参数开始如下:
|
||||
|
||||
```
|
||||
`new ActionListener() {`
|
||||
new ActionListener() {
|
||||
```
|
||||
|
||||
这似乎是错误的,因为 `ActionListener` 是一个**抽象**接口,而**抽象**类型不能通过调用 `new` 实例化。但是,事实证明,还有其它一些实例被实例化了:一个实现此接口的未命名内部类。如果上面的代码封装在名为 `OldJava` 的类中,则该未命名的内部类将被编译为 `OldJava$1.class`。`actionPerformed` 方法在这个未命名的内部类中被重写。
|
||||
@ -209,7 +211,7 @@ updateCurrentTime.addActionListener(new ActionListener() {
|
||||
现在考虑使用新的函数式结构进行这个令人耳目一新的更改:
|
||||
|
||||
```
|
||||
`updateCurrentTime.addActionListener(e -> currentTime.setText(new Date().toString()));`
|
||||
updateCurrentTime.addActionListener(e -> currentTime.setText(new Date().toString()));
|
||||
```
|
||||
|
||||
lambda 表达式中的参数 `e` 是一个 `ActionEvent` 实例,而 lambda 的主体是对按钮上的 `setText` 的简单调用。
|
||||
@ -227,7 +229,7 @@ interface BinaryIntOp {
|
||||
}
|
||||
```
|
||||
|
||||
注释 `@FunctionalInterface` 适用于声明 _唯一_ 抽象方法的任何接口;在本例中,这个抽象接口是 `compute`。一些标准接口,(例如具有唯一声明方法 `run` 的 `Runnable` 接口)同样符合这个要求。在此示例中,`compute` 是已声明的方法。该接口可用作引用声明中的目标类型:
|
||||
注释 `@FunctionalInterface` 适用于声明*唯一*抽象方法的任何接口;在本例中,这个抽象接口是 `compute`。一些标准接口,(例如具有唯一声明方法 `run` 的 `Runnable` 接口)同样符合这个要求。在此示例中,`compute` 是已声明的方法。该接口可用作引用声明中的目标类型:
|
||||
|
||||
```
|
||||
BinaryIntOp div = (arg1, arg2) -> arg1 / arg2;
|
||||
@ -236,7 +238,7 @@ div.compute(12, 3); // 4
|
||||
|
||||
包 `java.util.function` 提供各种函数式接口。以下是一些示例。
|
||||
|
||||
下面的代码段介绍了参数化的 `Predicate` 函数式接口。在此示例中,带有参数 `String` 的 `Predicate<String>` 类型可以引用具有 `String` 参数的 lambda 表达式或诸如 `isEmpty` 之类的 `String` 方法。通常情况下,_predicate_ 是一个返回布尔值的函数。
|
||||
下面的代码段介绍了参数化的 `Predicate` 函数式接口。在此示例中,带有参数 `String` 的 `Predicate<String>` 类型可以引用具有 `String` 参数的 lambda 表达式或诸如 `isEmpty` 之类的 `String` 方法。通常情况下,Predicate 是一个返回布尔值的函数。
|
||||
|
||||
```
|
||||
Predicate<String> pred = String::isEmpty; // String 方法的 predicate 声明
|
||||
@ -247,7 +249,7 @@ Arrays.asList(strings)
|
||||
.forEach(System.out::println); // 只打印空字符串
|
||||
```
|
||||
|
||||
在字符串长度为零的情况下,`isEmpty` predicate 判定结果为 `true`。 因此,只有空字符串才能进入管道的 `forEach` 阶段。
|
||||
在字符串长度为零的情况下,`isEmpty` Predicate 判定结果为 `true`。 因此,只有空字符串才能进入管道的 `forEach` 阶段。
|
||||
|
||||
下一段代码将演示如何将简单的 lambda 或方法引用组合成更丰富的 lambda 或方法引用。考虑这一系列对 `IntUnaryOperator` 类型的引用的赋值,它接受一个整型参数并返回一个整型值:
|
||||
|
||||
@ -308,16 +310,16 @@ Arrays.asList(arrayBR).stream().forEach(BedRocker::dump);
|
||||
|
||||
`Arrays.asList` 实用程序再次用于流化一个数组 `names`,然后将流的每一项传递给 `map` 函数,该函数的参数现在是构造器引用 `BedRocker::new`。这个构造器引用通过在每次调用时生成和初始化一个 `BedRocker` 实例来充当一个对象工厂。在第二行执行之后,名为 `bedrockers` 的流由五项 `BedRocker` 组成。
|
||||
|
||||
这个例子可以通过关注高阶 `map` 函数来进一步阐明。在通常情况下,一个映射将一个类型的值(例如,一个 `int`)转换为另一个 _相同_ 类型的值(例如,一个整数的后继):
|
||||
这个例子可以通过关注高阶 `map` 函数来进一步阐明。在通常情况下,一个映射将一个类型的值(例如,一个 `int`)转换为另一个*相同*类型的值(例如,一个整数的后继):
|
||||
|
||||
```
|
||||
map(n -> n + 1) // 将 n 映射到其后继
|
||||
```
|
||||
|
||||
然而,在 `BedRocker` 这个例子中,转换更加戏剧化,因为一个类型的值(代表一个名字的 `String`)被映射到一个 _不同_ 类型的值,在这个例子中,就是一个 `BedRocker` 实例,这个字符串就是它的名字。转换是通过一个构造器调用来完成的,它是由构造器引用来实现的:
|
||||
然而,在 `BedRocker` 这个例子中,转换更加戏剧化,因为一个类型的值(代表一个名字的 `String`)被映射到一个*不同*类型的值,在这个例子中,就是一个 `BedRocker` 实例,这个字符串就是它的名字。转换是通过一个构造器调用来完成的,它是由构造器引用来实现的:
|
||||
|
||||
```
|
||||
`map(BedRocker::new) // 将 String 映射到 BedRocker
|
||||
map(BedRocker::new) // 将 String 映射到 BedRocker
|
||||
```
|
||||
|
||||
传递给构造器的值是 `names` 数组中的其中一项。
|
||||
@ -325,13 +327,13 @@ map(n -> n + 1) // 将 n 映射到其后继
|
||||
此代码示例的第二行还演示了一个你目前已经非常熟悉的转换:先将数组先转换成 `List`,然后再转换成 `Stream`:
|
||||
|
||||
```
|
||||
`Stream<BedRocker> bedrockers = Arrays.asList(names).stream().map(BedRocker::new);`
|
||||
Stream<BedRocker> bedrockers = Arrays.asList(names).stream().map(BedRocker::new);
|
||||
```
|
||||
|
||||
第三行则是另一种方式 —— 流 `bedrockers` 通过使用_数组_构造器引用 `BedRocker[]::new` 调用 `toArray` 方法:
|
||||
第三行则是另一种方式 —— 流 `bedrockers` 通过使用*数组*构造器引用 `BedRocker[]::new` 调用 `toArray` 方法:
|
||||
|
||||
```
|
||||
`BedRocker[ ] arrayBR = bedrockers.toArray(BedRocker[]::new);`
|
||||
BedRocker[ ] arrayBR = bedrockers.toArray(BedRocker[]::new);
|
||||
```
|
||||
|
||||
该构造器引用不会创建单个 `BedRocker` 实例,而是创建这些实例的整个数组:该构造器引用现在为 `BedRocker[]:new`,而不是 `BedRocker::new`。为了进行确认,将 `arrayBR` 转换为 `List`,再次对其进行流式处理,以便可以使用 `forEach` 来打印 `BedRocker` 的名字。
|
||||
@ -348,7 +350,7 @@ Baby Puss
|
||||
|
||||
### <ruby>柯里化<rt>Currying</rt></ruby>
|
||||
|
||||
_柯里化_ 函数是指减少函数执行任何工作所需的显式参数的数量(通常减少到一个)。(该术语是为了纪念逻辑学家 Haskell Curry。)一般来说,函数的参数越少,调用起来就越容易,也更健壮。(回想一下一些需要半打左右参数的噩梦般的函数!)因此,应将柯里化视为简化函数调用的一种尝试。`java.util.function` 包中的接口类型适合于柯里化,如以下示例所示。
|
||||
*柯里化*函数是指减少函数执行任何工作所需的显式参数的数量(通常减少到一个)。(该术语是为了纪念逻辑学家 Haskell Curry。)一般来说,函数的参数越少,调用起来就越容易,也更健壮。(回想一下一些需要半打左右参数的噩梦般的函数!)因此,应将柯里化视为简化函数调用的一种尝试。`java.util.function` 包中的接口类型适合于柯里化,如以下示例所示。
|
||||
|
||||
引用的 `IntBinaryOperator` 接口类型是为函数接受两个整型参数,并返回一个整型值:
|
||||
|
||||
@ -368,13 +370,12 @@ mult2.applyAsInt(10, 30); // 300
|
||||
arg1 -> (arg2 -> arg1 * arg2) // 括号可以省略
|
||||
```
|
||||
|
||||
完整的 lambda 以 `arg1,` 开头,而该 lambda 的主体以及返回的值是另一个以 `arg2` 开头的 lambda。返回的 lambda 仅接受一个参数(`arg2`),但返回了两个数字的乘积(`arg1` 和 `arg2`)。下面的概述,再加上代码,应该可以更好地进行说明。
|
||||
完整的 lambda 以 `arg1` 开头,而该 lambda 的主体以及返回的值是另一个以 `arg2` 开头的 lambda。返回的 lambda 仅接受一个参数(`arg2`),但返回了两个数字的乘积(`arg1` 和 `arg2`)。下面的概述,再加上代码,应该可以更好地进行说明。
|
||||
|
||||
以下是如何柯里化 `mult2` 的概述:
|
||||
|
||||
> 类型为 `IntFunction<IntUnaryOperator>` 的 lambda 被写入并调用,其整型值为 10。返回的 `IntUnaryOperator` 缓存了值 10,因此变成了已柯里化版本的 `mult2`,在本例中为 `curriedMult2`。
|
||||
|
||||
> 然后使用单个显式参数(例如,20)调用 `curriedMult2` 函数,该参数与缓存的参数(在本例中为 10)相乘以生成返回的乘积。。
|
||||
- 类型为 `IntFunction<IntUnaryOperator>` 的 lambda 被写入并调用,其整型值为 10。返回的 `IntUnaryOperator` 缓存了值 10,因此变成了已柯里化版本的 `mult2`,在本例中为 `curriedMult2`。
|
||||
- 然后使用单个显式参数(例如,20)调用 `curriedMult2` 函数,该参数与缓存的参数(在本例中为 10)相乘以生成返回的乘积。。
|
||||
|
||||
这是代码的详细信息:
|
||||
|
||||
@ -391,7 +392,7 @@ IntFunction<IntUnaryOperator> curriedMult2Maker = n1 -> (n2 -> n1 * n2);
|
||||
IntUnaryOperator curriedMult2 = curriedMult2Maker2.apply(10);
|
||||
```
|
||||
|
||||
值 10 现在缓存在 `curriedMult2` 函数中,以便 `curriedMult2` 调用中的显式整型参数乘以 10:
|
||||
值 `10` 现在缓存在 `curriedMult2` 函数中,以便 `curriedMult2` 调用中的显式整型参数乘以 10:
|
||||
|
||||
```
|
||||
curriedMult2.applyAsInt(20); // 200 = 10 * 20
|
||||
@ -423,9 +424,9 @@ dataStream
|
||||
.collect(...); // 或者,也可以进行归约:阶段 N
|
||||
```
|
||||
|
||||
自动多线程,以 `parallel` 和 `parallelStream` 调用为例,建立在 Java 的 fork/join 框架上,该框架支持 _<ruby>任务窃取<rt>task stealing</rt></ruby>_ 以提高效率。假设 `parallelStream` 调用后面的线程池由八个线程组成,并且 `dataStream` 被八种方式分区。某个线程(例如,T1)可能比另一个线程(例如,T7)工作更快,这意味着应该将 T7 的某些任务移到 T1 的工作队列中。这会在运行时自动发生。
|
||||
自动多线程,以 `parallel` 和 `parallelStream` 调用为例,建立在 Java 的 fork/join 框架上,该框架支持 <ruby>任务窃取<rt>task stealing</rt></ruby> 以提高效率。假设 `parallelStream` 调用后面的线程池由八个线程组成,并且 `dataStream` 被八种方式分区。某个线程(例如,T1)可能比另一个线程(例如,T7)工作更快,这意味着应该将 T7 的某些任务移到 T1 的工作队列中。这会在运行时自动发生。
|
||||
|
||||
在这个简单的多线程世界中,程序员的主要职责是编写线程安全函数,这些函数作为参数传递给在流 API 中占主导地位的高阶函数。 尤其是 lambda 鼓励编写纯函数(因此是线程安全的)函数。
|
||||
在这个简单的多线程世界中,程序员的主要职责是编写线程安全函数,这些函数作为参数传递给在流 API 中占主导地位的高阶函数。尤其是 lambda 鼓励编写纯函数(因此是线程安全的)函数。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -434,7 +435,7 @@ via: https://opensource.com/article/20/1/javastream
|
||||
作者:[Marty Kalin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[laingke](https://github.com/laingke)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,65 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hopefully2333)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11877-1.html)
|
||||
[#]: subject: (What's HTTPS for secure computing?)
|
||||
[#]: via: (https://opensource.com/article/20/1/confidential-computing)
|
||||
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||
|
||||
用于安全计算的 HTTPS 是什么?
|
||||
======
|
||||
|
||||
> 在默认的情况下,网站的安全性还不足够。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/11/123552rqncn4c7474j44jq.jpg)
|
||||
|
||||
在过去的几年里,寻找一个只以 “http://...” 开头的网站变得越来越难,这是因为业界终于意识到,网络安全“是件事”,同时也是因为客户端和服务端之间建立和使用 https 连接变得更加容易了。类似的转变可能正以不同的方式发生在云计算、边缘计算、物联网、区块链,人工智能、机器学习等领域。长久以来,我们都知道我们应该对存储的静态数据和在网络中传输的数据进行加密,但是在使用和处理数据的时候对它进行加密是困难且昂贵的。可信计算(使用例如<ruby>受信任的执行环境<rt>Trusted Execution Environments</rt></ruby> TEEs 这样的硬件功能来提供数据和算法这种类型的保护)可以保护主机系统中的或者易受攻击的环境中的数据。
|
||||
|
||||
关于 [TEEs][2],当然,还有我和 Nathaniel McCallum 共同创立的 [Enarx 项目][3],我已经写了几次文章(参见《[给每个人的 Enarx(一个任务)][4]》 和 《[Enarx 迈向多平台][5]》)。Enarx 使用 TEEs 来提供独立于平台和语言的部署平台,以此来让你能够安全地将敏感应用或者敏感组件(例如微服务)部署在你不信任的主机上。当然,Enarx 是完全开源的(顺便提一下,我们使用的是 Apache 2.0 许可证)。能够在你不信任的主机上运行工作负载,这是可信计算的承诺,它扩展了使用静态敏感数据和传输中数据的常规做法:
|
||||
|
||||
* **存储**:你要加密你的静态数据,因为你不完全信任你的基础存储架构。
|
||||
* **网络**:你要加密你正在传输中的数据,因为你不完全信任你的基础网络架构。
|
||||
* **计算**:你要加密你正在使用中的数据,因为你不完全信任你的基础计算架构。
|
||||
|
||||
关于信任,我有非常多的话想说,而且,上述说法里的单词“**完全**”是很重要的(在重新读我写的这篇文章的时候,我新加了这个单词)。不论哪种情况,你必须在一定程度上信任你的基础设施,无论是传递你的数据包还是存储你的数据块,例如,对于计算基础架构,你必须要去信任 CPU 和与之关联的固件,这是因为如果你不信任他们,你就无法真正地进行计算(现在有一些诸如<ruby>同态加密<rt>homomorphic encryption</rt></ruby>一类的技术,这些技术正在开始提供一些可能性,但是它们依然有限,这些技术还不够成熟)。
|
||||
|
||||
考虑到发现的一些 CPU 安全性问题,是否应该完全信任 CPU 有时自然会产生疑问,以及它们是否在针对其所在的主机的物理攻击中具有完全的安全性。
|
||||
|
||||
这两个问题的回答都是“不”,但是在考虑到大规模可用性和普遍推广的成本,这已经是我们当前拥有的最好的技术了。为了解决第二个问题,没有人去假装这项技术(或者任何的其他技术)是完全安全的:我们需要做的是思考我们的[威胁模型][6]并确定这个情况下的 TEEs 是否为我们的特殊需求提供了足够的安全防护。关于第一个问题,Enarx 采用的模型是在部署时就对你是否信任一个特定的 CPU 组做出决定。举个例子,如果供应商 Q 的 R 代芯片被发现有漏洞,可以很简单地说“我拒绝将我的工作内容部署到 Q 的 R 代芯片上去,但是仍然可以部署到 Q 的 S 型号、T 型号和 U 型号的芯片以及任何 P、M 和 N 供应商的任何芯片上去。”
|
||||
|
||||
我认为这里发生了三处改变,这些改变引起了人们现在对<ruby>机密计算<rt>confidential computing</rt></ruby>的兴趣和采用。
|
||||
|
||||
1. **硬件可用**:只是在过去的 6 到 12 个月里,支持 TEEs 的硬件才开始变得广泛可用,这会儿市场上的主要例子是 Intel 的 SGX 和 AMD 的 SEV。我们期望在未来可以看到支持 TEE 的硬件的其他例子。
|
||||
2. **行业就绪**:就像上云越来越多地被接受作为应用程序部署的模型,监管机构和立法机构也在提高各类组织保护其管理的数据的要求。组织开始呼吁在不受信任的主机运行敏感程序(或者是处理敏感数据的应用程序)的方法,更确切地说,是在无法完全信任且带有敏感数据的主机上运行的方法。这不足为奇:如果芯片制造商看不到这项技术的市场,他们就不会投太多的钱在这项技术上。Linux 基金会的[机密计算联盟(CCC)][7]的成立就是业界对如何寻找使用加密计算的通用模型并且鼓励开源项目使用这些技术感兴趣的案例。(红帽发起的 Enarx 是一个 CCC 项目。)
|
||||
3. **开放源码**:就像区块链一样,机密计算是使用开源绝对明智的技术之一。如果你要运行敏感程序,你需要去信任正在为你运行的程序。不仅仅是 CPU 和固件,同样还有在 TEE 内执行你的工作负载的框架。可以很好地说,“我不信任主机机器和它上面的软件栈,所以我打算使用 TEE,”但是如果你不够了解 TEE 软件环境,那你就是将一种软件不透明换成另外一种。TEEs 的开源支持将允许你或者社区(实际上是你与社区)以一种专有软件不可能实现的方式来检查和审计你所运行的程序。这就是为什么 CCC 位于 Linux 基金会旗下(这个基金会致力于开放式开发模型)并鼓励 TEE 相关的软件项目加入且成为开源项目(如果它们还没有成为开源)。
|
||||
|
||||
我认为,在过去的 15 到 20 年里,硬件可用、行业就绪和开放源码已成为推动技术改变的驱动力。区块链、人工智能、云计算、<ruby>大规模计算<rt>webscale computing</rt></ruby>、大数据和互联网商务都是这三个点同时发挥作用的例子,并且在业界带来了巨大的改变。
|
||||
|
||||
在一般情况下,安全是我们这数十年来听到的一种承诺,并且其仍然未被实现。老实说,我不确定它未来会不会实现。但是随着新技术的到来,特定用例的安全变得越来越实用和无处不在,并且在业内受到越来越多的期待。这样看起来,机密计算似乎已准备好成为成为下一个重大变化 —— 而你,我亲爱的读者,可以一起来加入到这场革命(毕竟它是开源的)。
|
||||
|
||||
这篇文章最初是发布在 Alice, Eve, and Bob 上的,这是得到了作者许可的重发。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/confidential-computing
|
||||
|
||||
作者:[Mike Bursell][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hopefully2333](https://github.com/hopefully2333)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mikecamel
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/secure_https_url_browser.jpg?itok=OaPuqBkG (Secure https browser)
|
||||
[2]: https://aliceevebob.com/2019/02/26/oh-how-i-love-my-tee-or-do-i/
|
||||
[3]: https://enarx.io/
|
||||
[4]: https://aliceevebob.com/2019/08/20/enarx-for-everyone-a-quest/
|
||||
[5]: https://aliceevebob.com/2019/10/29/enarx-goes-multi-platform/
|
||||
[6]: https://aliceevebob.com/2018/02/20/there-are-no-absolutes-in-security/
|
||||
[7]: https://confidentialcomputing.io/
|
||||
[8]: tmp.VEZpFGxsLv#1
|
||||
[9]: https://aliceevebob.com/2019/12/03/confidential-computing-the-new-https/
|
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (heguangzhi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11893-1.html)
|
||||
[#]: subject: (What I learned going from prison to Python)
|
||||
[#]: via: (https://opensource.com/article/20/1/prison-to-python)
|
||||
[#]: author: (Shadeed "Sha" Wallace-Stepter https://opensource.com/users/shastepter)
|
||||
|
||||
从监狱到 Python
|
||||
======
|
||||
|
||||
> 入狱后,开源编程是如何提供机会的。
|
||||
|
||||
![书架上的编程书籍][1]
|
||||
|
||||
不到一年前,我还在圣昆廷州立监狱服刑,我是无期徒刑。
|
||||
|
||||
我高三的时候,我抢劫了一个人并向他开了枪。现在,我经过一段时间才意识到并承认自己做错了,这是在经历了陪审团审判并看到我的行为带来的恶果后,我知道需要改变自己,我也确实做到了。尽管我对我的行为表示懊悔,但我毕竟开枪打了一个人,并差点杀了他。做这样的事是有后果的,这是理所当然的。所以在我 18 岁的时候,我被判了终身监禁。
|
||||
|
||||
监狱是一个非常可怕的地方;我是不推荐你去的。但是我必须去,所以我去了。我不告诉你具体的细节,但你可以放心,这是一个没有太多动机去改变的地方,许多人在这里养成的坏习惯比他们过去在别处养成的更多。
|
||||
|
||||
我是幸运儿之一。当我在服刑的时候,发生了一些不同寻常的事情。我开始想象自己出狱后的的未来,虽然在这之前,我还是已经在那里度过了我整个成年生活。
|
||||
|
||||
现在你想想:我是黑人,只受过高中教育。我没有工作经历,如果我离开监狱,在被释放前,我还是一个被定罪的重罪犯。当每个雇主看到我的简历,都不会有“我需要雇用这个人”想法,我认为是正常的。
|
||||
|
||||
我不知道我的选择是什么,但我已经下定决心了。我需要做些活下去的事情,并且这和我入狱前的生活一点也不像。
|
||||
|
||||
### Python 之路
|
||||
|
||||
最终,我被关在了圣昆廷州立监狱,我不知道我为何幸运地被关在那里。圣昆廷提供了几个自助和教育编程项目。这些[改造机会][2]帮助囚犯使他们拥有在获释后避免再次犯罪的技能。
|
||||
|
||||
作为其中一个编程项目的一部分,2017 年我通过圣昆廷媒体项目认识了[杰西卡·麦凯拉][3]。杰西卡是编程语言 [Python][4] 的爱好者,她开始向我推荐 Python 有多棒,以及它是刚起步的人学习的完美语言。这就是故事变得比小说更精彩的地方。
|
||||
|
||||
> 感谢 [@northbaypython][5] 让 [@ShaStepter][6] 和我重复 [@pycon][7] 的主题演讲,让他们被录制下来。我很荣幸与大家分享:
|
||||
>
|
||||
> 从监狱到 Pythone: https://t.co/rcumoAgZHm
|
||||
>
|
||||
> 大规模裁员:如果我们不雇佣被判重罪的人,谁会呢? https://t.co/fENDUFdxfX
|
||||
>
|
||||
> [pic.Twitter.com/kpjo8d3ul6][8]
|
||||
>
|
||||
> —杰西卡·麦凯拉(@jessicamckellar)[2019 年 11 月 5 日][9]
|
||||
|
||||
杰西卡向我介绍了一些 Python 视频教程,这些教程是她为一家名叫 [O’Reilly Media][10] 的公司做的,课程是在线的,如果我能接触到它们,那该有多好呀。不幸的是,在监狱里上网是不可能的。但是,我遇到了一个叫 Tim O’Reilly 的人,他最近刚来到圣昆廷。在他访问之后,Tim 从他的公司 O’Reilly Media 公司向监狱的编程班捐赠了大量内容。最终,我拿到了一款平板电脑,上面有杰西卡的 Python 教程,并学会了如何使用这些 Python 教程进行编码。
|
||||
|
||||
真是难以置信。背景和生活与我完全不同的陌生人把这些联系在一起,让我学会了编码。
|
||||
|
||||
### 对 Python 社区的热爱
|
||||
|
||||
在这之后,我开始经常和杰西卡见面,她开始告诉我关于开源社区的情况。我了解到,从根本上说,开源社区就是关于伙伴关系和协作的社区。之所以如此有效,是因为没有人被排除在外。
|
||||
|
||||
对我来说,一个努力寻找自己定位的人,我所看到的是一种非常基本的爱——通过合作和接受的爱,通过接触的爱,通过包容的爱。我渴望成为其中的一部分。所以我继续学习 Python,不幸的是,我无法获得更多的教程,但是我能够从开源社区收集的大量书面知识中获益。我读一切提到 Python 的东西,从平装本到晦涩难懂的杂志文章,我使用平板电脑来解决我读到的 Python 问题。
|
||||
|
||||
我对 Python 和编程的热情不是我的许多同龄人所共有的。除了监狱编程课上的极少数人之外,我认识的其他人都没有提到过编程;一般囚犯都不知道。我认为这是因为有过监禁经历的人无法接触编程,尤其是如果你是有色人种。
|
||||
|
||||
### 监狱外的 Python 生活
|
||||
|
||||
然而,在 2018 年 8 月 17 日,我得到了生命中的惊喜。时任州长的杰里·布朗将我 27 年的刑期减刑,在服刑将近 19 年后,我被释放出狱了。
|
||||
|
||||
但现实情况是,这也是为什么我认为编程和开源社区如此有价值。我是一名 37 岁的黑人罪犯,没有工作经历,刚刚在监狱服刑 18 年。我有犯罪史,并且现存偏见导致没有多少职业适合我。但是编程是少数例外之一。
|
||||
|
||||
现在,监禁后重返社会的人们迫切需要包容,但当谈及工作场所的多样性以及对多样性的需求时,你真的听不到这个群体被提及或包容。
|
||||
|
||||
> 还有什么:
|
||||
>
|
||||
> 1、背景调查:询问他们在你的公司是如何使用的。
|
||||
>
|
||||
> 2、初级角色:删除虚假的、不必要的先决条件,这些条件将排除有记录的合格人员。
|
||||
>
|
||||
> 3、积极拓展:与当地再就业项目合作,创建招聘渠道。
|
||||
>
|
||||
> [pic.twitter.com/WnzdEUTuxr][11]
|
||||
>
|
||||
> —杰西卡·麦凯拉(@jessicamckellar)[2019 年 5 月 12 日][12]
|
||||
|
||||
|
||||
因此,我想谦卑地挑战开源社区的所有程序员和成员,让他们围绕包容和多样性展开思考。今天,我自豪地站在你们面前,代表一个大多数人都没有想到的群体——以前被监禁的人。但是我们存在,我们渴望证明我们的价值,最重要的是,我们期待被接受。当我们重返社会时,许多挑战等待着我们,我请求你们允许我们有机会展示我们的价值。欢迎我们,接受我们,最重要的是,包容我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/prison-to-python
|
||||
|
||||
作者:[Shadeed "Sha" Wallace-Stepter][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[heguangzhi](https://github.com/heguangzhi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/shastepter
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/books_programming_languages.jpg?itok=KJcdnXM2 (Programming books on a shelf)
|
||||
[2]: https://www.dailycal.org/2019/02/27/san-quentin-rehabilitation-programs-offer-inmates-education-a-voice/
|
||||
[3]: https://twitter.com/jessicamckellar?lang=en
|
||||
[4]: https://www.python.org/
|
||||
[5]: https://twitter.com/northbaypython?ref_src=twsrc%5Etfw
|
||||
[6]: https://twitter.com/ShaStepter?ref_src=twsrc%5Etfw
|
||||
[7]: https://twitter.com/pycon?ref_src=twsrc%5Etfw
|
||||
[8]: https://t.co/Kpjo8d3ul6
|
||||
[9]: https://twitter.com/jessicamckellar/status/1191601209917837312?ref_src=twsrc%5Etfw
|
||||
[10]: http://shop.oreilly.com/product/110000448.do
|
||||
[11]: https://t.co/WnzdEUTuxr
|
||||
[12]: https://twitter.com/jessicamckellar/status/1127640222504636416?ref_src=twsrc%5Etfw
|
@ -0,0 +1,172 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Morisun029)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11886-1.html)
|
||||
[#]: subject: (Use this Python script to find bugs in your Overcloud)
|
||||
[#]: via: (https://opensource.com/article/20/1/logtool-root-cause-identification)
|
||||
[#]: author: (Arkady Shtempler https://opensource.com/users/ashtempl)
|
||||
|
||||
用 Python 脚本发现 OpenStack Overcloud 中的问题
|
||||
======
|
||||
|
||||
> LogTool 是一组 Python 脚本,可帮助你找出 Overcloud 节点中问题的根本原因。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/12/211455woy57xx5q19cx175.jpg)
|
||||
|
||||
OpenStack 在其 Overcloud 节点和 Undercloud 主机上存储和管理了一堆日志文件。因此,使用 OSP 日志文件来排查遇到的问题并不是一件容易的事,尤其在你甚至都不知道是什么原因导致问题时。
|
||||
|
||||
如果你正处于这种情况,那么 [LogTool][2] 可以使你的生活变得更加轻松!它会为你节省本需要人工排查问题所需的时间和精力。LogTool 基于模糊字符串匹配算法,可提供过去发生的所有唯一错误和警告信息。你可以根据日志中的时间戳导出特定时间段(例如 10 分钟前、一个小时前、一天前等)的这些信息。
|
||||
|
||||
LogTool 是一组 Python 脚本,其主要模块 `PyTool.py` 在 Undercloud 主机上执行。某些操作模式使用直接在 Overcloud 节点上执行的其他脚本,例如从 Overcloud 日志中导出错误和警告信息。
|
||||
|
||||
LogTool 支持 Python 2 和 Python 3,你可以根据需要更改工作目录:[LogTool_Python2][3] or [LogTool_Python3][4]。
|
||||
|
||||
### 操作方式
|
||||
|
||||
#### 1、从 Overcloud 日志中导出错误和警告信息
|
||||
|
||||
此模式用于从过去发生的 Overcloud 节点中提取 **错误** 和 **警告** 信息。作为用户,系统将提示你提供“开始时间”和“调试级别”,以用于提取错误或警告消息。例如,如果在过去 10 分钟内出了问题,你则可以只提取该时间段内的错误和警告消息。
|
||||
|
||||
此操作模式将为每个 Overcloud 节点生成一个包含结果文件的目录。结果文件是经过压缩的简单文本文件(`*.gz`),以减少从 Overcloud 节点下载所需的时间。将压缩文件转换为常规文本文件,可以使用 `zcat` 或类似工具。此外,Vi 的某些版本和 Emacs 的任何最新版本均支持读取压缩数据。结果文件分为几部分,并在底部包含目录。
|
||||
|
||||
LogTool 可以即时检测两种日志文件:标准和非标准。在标准文件中,每条日志行都有一个已知的和已定义的结构:时间戳、调试级别、信息等等。在非标准文件中,日志的结构未知。例如,它可能是第三方的日志。在目录中,你可以找到每个部分的“名称 --> 行号”例如:
|
||||
|
||||
* **原始数据 - 从标准 OSP 日志中提取的错误/警告消息:** 这部分包含所有提取的错误/警告消息,没有任何修改或更改。这些消息是 LogTool 用于模糊匹配分析的原始数据。
|
||||
* **统计信息 - 每个标准 OSP 日志的错误/警告信息数量:** 在此部分,你将找到每个标准日志文件的错误和警告数量。这些信息可以帮助你了解用于排查问题根本原因的潜在组件。
|
||||
* **统计信息 - 每个标准 OSP 日志文件的唯一消息:** 这部分提供指定时间戳内的唯一的错误和警告消息。有关每个唯一错误或警告的更多详细信息,请在“原始数据”部分中查找相同的消息。
|
||||
* **统计信息 - 每个非标准日志文件在任意时间的唯一消息:** 此部分包含非标准日志文件中的唯一消息。遗憾的是,LogTool 无法像标准日志文件那样的处理方式处理这些日志文件。因此,在你提取“特定时间”的日志信息时会被忽略,你会看到过去创建的所有唯一的错误/警告消息。因此,首先,向下滚动到结果文件底部的目录并查看其部分-使用目录中的行索引跳到相关部分,其中第 3、4 和 5 行的信息最重要。
|
||||
|
||||
#### 2、从 Overcloud 节点下载所有日志
|
||||
|
||||
所有 Overcloud 节点的日志将被压缩并下载到 Undercloud 主机上的本地目录。
|
||||
|
||||
#### 3、所有 Overcloud 日志中搜索字符串
|
||||
|
||||
该模式“grep”(搜索)由用户在所有 Overcloud 日志上提供的字符串。例如,你可能希望查看特定请求的所有日志消息,例如,“Create VM”的失败的请求 ID。
|
||||
|
||||
#### 4、检查 Overcloud 上当前的 CPU、RAM 和磁盘使用情况
|
||||
|
||||
该模式显示每个 Overcloud 节点上的当前 CPU、RAM 和磁盘信息。
|
||||
|
||||
#### 5、执行用户脚本
|
||||
|
||||
该模式使用户可以在 Overcloud 节点上运行自己的脚本。例如,假设 Overcloud 部署失败,你就需要在每个控制器节点上执行相同的过程来修复该问题。你可以实现“替代方法”脚本,并使用此模式在控制器上运行它。
|
||||
|
||||
#### 6、仅按给定的时间戳下载相关日志
|
||||
|
||||
此模式仅下载 Overcloud 上 “给定的时间戳”的“上次修改时间”的日志。例如,如果 10 分钟前出现错误,则与旧日志文件就没有关系,因此无需下载。此外,你不能(或不应)在某些错误报告工具中附加大文件,因此此模式可能有助于编写错误报告。
|
||||
|
||||
#### 7、从 Undercloud 日志中导出错误和警告信息
|
||||
|
||||
这与上面的模式 1 相同。
|
||||
|
||||
#### 8、在 Overcloud 上检查不正常的 docker
|
||||
|
||||
此模式用于在节点上搜索不正常的 Docker。
|
||||
|
||||
#### 9、下载 OSP 日志并在本地运行 LogTool
|
||||
|
||||
此模式允许你从 Jenkins 或 Log Storage 下载 OSP 日志(例如,`cougar11.scl.lab.tlv.redhat.com`),并在本地分析。
|
||||
|
||||
#### 10、在 Undercloud 上分析部署日志
|
||||
|
||||
此模式可以帮助你了解 Overcloud 或 Undercloud 部署过程中出了什么问题。例如,在`overcloud_deploy.sh` 脚本中,使用 `--log` 选项时会生成部署日志;此类日志的问题是“不友好”,你很难理解是什么出了问题,尤其是当详细程度设置为 `vv` 或更高时,使得日志中的数据难以读取。此模式提供有关所有失败任务的详细信息。
|
||||
|
||||
#### 11、分析 Gerrit(Zuul)失败的日志
|
||||
|
||||
此模式用于分析 Gerrit(Zuul)日志文件。它会自动从远程 Gerrit 门下载所有文件(HTTP 下载)并在本地进行分析。
|
||||
|
||||
### 安装
|
||||
|
||||
GitHub 上有 LogTool,使用以下命令将其克隆到你的 Undercloud 主机:
|
||||
|
||||
```
|
||||
git clone https://github.com/zahlabut/LogTool.git
|
||||
```
|
||||
|
||||
该工具还使用了一些外部 Python 模块:
|
||||
|
||||
#### Paramiko
|
||||
|
||||
默认情况下,SSH 模块通常会安装在 Undercloud 上。使用以下命令来验证是否已安装:
|
||||
|
||||
```
|
||||
ls -a /usr/lib/python2.7/site-packages | grep paramiko
|
||||
```
|
||||
|
||||
如果需要安装模块,请在 Undercloud 上执行以下命令:
|
||||
|
||||
```
|
||||
sudo easy_install pip
|
||||
sudo pip install paramiko==2.1.1
|
||||
```
|
||||
|
||||
#### BeautifulSoup
|
||||
|
||||
此 HTML 解析器模块仅在使用 HTTP 下载日志文件的模式下使用。它用于解析 Artifacts HTML 页面以获取其中的所有链接。安装 BeautifulSoup,请输入以下命令:
|
||||
|
||||
```
|
||||
pip install beautifulsoup4
|
||||
```
|
||||
|
||||
你还可以通过执行以下命令使用 [requirements.txt][6] 文件安装所有必需的模块:
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 配置
|
||||
|
||||
所有必需的参数都直接在 `PyTool.py` 脚本中设置。默认值为:
|
||||
|
||||
```
|
||||
overcloud_logs_dir = '/var/log/containers'
|
||||
overcloud_ssh_user = 'heat-admin'
|
||||
overcloud_ssh_key = '/home/stack/.ssh/id_rsa'
|
||||
undercloud_logs_dir ='/var/log/containers'
|
||||
source_rc_file_path='/home/stack/'
|
||||
```
|
||||
|
||||
### 用法
|
||||
|
||||
此工具是交互式的,因此要启动它,只需输入:
|
||||
|
||||
```
|
||||
cd LogTool
|
||||
python PyTool.py
|
||||
```
|
||||
|
||||
### 排除 LogTool 故障
|
||||
|
||||
|
||||
在运行时会创建两个日志文件:`Error.log` 和 `Runtime.log`。请在你要打开的问题的描述中添加两者的内容。
|
||||
|
||||
### 局限性
|
||||
|
||||
LogTool 进行硬编码以处理最大 500 MB 的文件。
|
||||
|
||||
### LogTool_Python3 脚本
|
||||
|
||||
在 [github.com/zahlabut/LogTool][2] 获取。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/logtool-root-cause-identification
|
||||
|
||||
作者:[Arkady Shtempler][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Morisun029](https://github.com/译者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ashtempl
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/search_find_code_python_programming.png?itok=ynSL8XRV (Searching for code)
|
||||
[2]: https://github.com/zahlabut/LogTool
|
||||
[3]: https://github.com/zahlabut/LogTool/tree/master/LogTool_Python2
|
||||
[4]: https://github.com/zahlabut/LogTool/tree/master/LogTool_Python3
|
||||
[5]: https://opensource.com/article/19/2/getting-started-cat-command
|
||||
[6]: https://github.com/zahlabut/LogTool/blob/master/LogTool_Python3/requirements.txt
|
@ -1,22 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11856-1.html)
|
||||
[#]: subject: (One open source chat tool to rule them all)
|
||||
[#]: via: (https://opensource.com/article/20/1/open-source-chat-tool)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
一个管理所有聊天的开源聊天工具
|
||||
一个通过 IRC 管理所有聊天的开源聊天工具
|
||||
======
|
||||
BitlBee 将多个聊天应用集合到一个界面中。在我们的 20 个使用开源提升生产力的系列的第九篇文章中了解如何设置和使用 BitlBee。
|
||||
![Person using a laptop][1]
|
||||
|
||||
> BitlBee 将多个聊天应用集合到一个界面中。在我们的 20 个使用开源提升生产力的系列的第九篇文章中了解如何设置和使用 BitlBee。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/05/123636dw8uw34mbkqzmw84.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 将所有聊天都放到 BitlBee 中
|
||||
|
||||
即时消息和聊天已经成为网络世界的主要内容。如果你像我一样,你可能打开五六个不同的应用与你的朋友、同事和其他人交谈。跟上所有聊天真的很痛苦。谢天谢地,你可以使用一个应用(好吧,是两个)将这些聊天整个到一个地方。
|
||||
即时消息和聊天已经成为网络世界的主要内容。如果你像我一样,你可能打开五六个不同的应用与你的朋友、同事和其他人交谈。关注所有聊天真的很痛苦。谢天谢地,你可以使用一个应用(好吧,是两个)将这些聊天整个到一个地方。
|
||||
|
||||
![BitlBee on XChat][2]
|
||||
|
||||
@ -24,12 +26,11 @@ BitlBee 将多个聊天应用集合到一个界面中。在我们的 20 个使
|
||||
|
||||
BitlBee 几乎包含在所有 Linux 发行版中。在 Ubuntu 上安装(我选择的 Linux 桌面),类似这样:
|
||||
|
||||
|
||||
```
|
||||
`sudo apt install bitlbee-libpurple`
|
||||
sudo apt install bitlbee-libpurple
|
||||
```
|
||||
|
||||
在其他发行版上,包名可能略有不同,但搜索 _bitlbee_ 应该就能看到。
|
||||
在其他发行版上,包名可能略有不同,但搜索 “bitlbee” 应该就能看到。
|
||||
|
||||
你会注意到我用的 libpurple 版的 BitlBee。这个版本能让我使用 [libpurple][4] 即时消息库中提供的所有协议,该库最初是为 [Pidgin][5] 开发的。
|
||||
|
||||
@ -37,47 +38,43 @@ BitlBee 几乎包含在所有 Linux 发行版中。在 Ubuntu 上安装(我选
|
||||
|
||||
![Initial BitlBee connection][7]
|
||||
|
||||
你将自动连接到控制频道和 **bitlbee**。此频道对于你是独一无二的,每个人在多用户系统上都有自己的频道。在这里你可以配置服务。
|
||||
|
||||
在控制频道中输入 **help**,你可以随时获得完整的文档。浏览它,然后使用 **register** 命令在服务器上注册帐户。
|
||||
你将自动连接到控制频道 &bitlbee。此频道对于你是独一无二的,在多用户系统上每个人都有一个自己的。在这里你可以配置该服务。
|
||||
|
||||
在控制频道中输入 `help`,你可以随时获得完整的文档。浏览它,然后使用 `register` 命令在服务器上注册帐户。
|
||||
|
||||
```
|
||||
`register <mypassword>`
|
||||
register <mypassword>
|
||||
```
|
||||
|
||||
现在,你在服务器上所做的任何配置更改(IM 帐户、设置等)都将在输入 **save** 时保存。每当你连接时,使用 **identify <mypassword>** 连接到你的帐户并加载这些设置。
|
||||
现在,你在服务器上所做的任何配置更改(IM 帐户、设置等)都将在输入 `save` 时保存。每当你连接时,使用 `identify <mypassword>` 连接到你的帐户并加载这些设置。
|
||||
|
||||
![purple settings][8]
|
||||
|
||||
命令 **help purple** 将显示 libpurple 提供的所有可用协议。例如,我安装了 [**telegram-purple**][9] 包,它增加了连接到 Telegram 的能力。我可以使用 **account add** 命令将我的电话号码作为帐户添加。
|
||||
|
||||
命令 `help purple` 将显示 libpurple 提供的所有可用协议。例如,我安装了 [telegram-purple][9] 包,它增加了连接到 Telegram 的能力。我可以使用 `account add` 命令将我的电话号码作为帐户添加。
|
||||
|
||||
```
|
||||
`account add telegram +15555555`
|
||||
account add telegram +15555555
|
||||
```
|
||||
|
||||
BitlBee 将显示它已添加帐户。你可以使用 **account list** 列出你的帐户。因为我只有一个帐户,我可以通过 **account 0 on** 登录,它会进行 Telegram 登录,列出我所有的朋友和聊天,接下来就能正常聊天了。
|
||||
BitlBee 将显示它已添加帐户。你可以使用 `account list` 列出你的帐户。因为我只有一个帐户,我可以通过 `account 0 on` 登录,它会进行 Telegram 登录,列出我所有的朋友和聊天,接下来就能正常聊天了。
|
||||
|
||||
但是,对于 Slack 这个最常见的聊天系统之一呢?你可以安装 [**slack-libpurple**][10] 插件,并且对 Slack 执行同样的操作。如果你不愿意编译和安装这些,这可能不适合你。
|
||||
|
||||
按照插件页面上的说明操作,安装后重新启动 BitlBee 服务。现在,当你运行 **help purple** 时,应该会列出 Slack。像其他协议一样添加一个 Slack 帐户。
|
||||
但是,对于 Slack 这个最常见的聊天系统之一呢?你可以安装 [slack-libpurple][10] 插件,并且对 Slack 执行同样的操作。如果你不愿意编译和安装这些,这可能不适合你。
|
||||
|
||||
按照插件页面上的说明操作,安装后重新启动 BitlBee 服务。现在,当你运行 `help purple` 时,应该会列出 Slack。像其他协议一样添加一个 Slack 帐户。
|
||||
|
||||
```
|
||||
account add slack [ksonney@myslack.slack.com][11]
|
||||
account add slack ksonney@myslack.slack.com
|
||||
account 1 set password my_legcay_API_token
|
||||
account 1 on
|
||||
```
|
||||
|
||||
你知道么,你已经连接到 Slack 中,你可以通过 **chat add** 命令添加你感兴趣的 Slack 频道。比如:
|
||||
|
||||
你知道么,你已经连接到 Slack 中,你可以通过 `chat add` 命令添加你感兴趣的 Slack 频道。比如:
|
||||
|
||||
```
|
||||
`chat add 1 happyparty`
|
||||
chat add 1 happyparty
|
||||
```
|
||||
|
||||
将 Slack 频道 happyparty 添加为本地频道 #happyparty。现在可以使用标准 IRC **/join** 命令访问该频道。这很酷。
|
||||
将 Slack 频道 happyparty 添加为本地频道 #happyparty。现在可以使用标准 IRC `/join` 命令访问该频道。这很酷。
|
||||
|
||||
BitlBee 和 IRC 客户端帮助我的(大部分)聊天和即时消息保存在一个地方,并减少了我的分心,因为我不再需要查找并切换到任何一个刚刚找我的应用上。
|
||||
|
||||
@ -88,7 +85,7 @@ via: https://opensource.com/article/20/1/open-source-chat-tool
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,40 +1,41 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11858-1.html)
|
||||
[#]: subject: (Use this Twitter client for Linux to tweet from the terminal)
|
||||
[#]: via: (https://opensource.com/article/20/1/tweet-terminal-rainbow-stream)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用这个 Twitter 客户端在 Linux 终端中发推特
|
||||
======
|
||||
在我们的 20 个使用开源提升生产力的系列的第十篇文章中使用 Rainbow Stream 跟上你的 Twitter 流而无需离开终端。
|
||||
![Chat bubbles][1]
|
||||
|
||||
> 在我们的 20 个使用开源提升生产力的系列的第十篇文章中,使用 Rainbow Stream 跟上你的 Twitter 流而无需离开终端。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/06/113720bwi55j7xcccwwwi0.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 通过 Rainbow Stream 跟上Twitter
|
||||
|
||||
我喜欢社交网络和微博。它快速、简单,还有我可以与世界分享我的想法。当然,缺点是几乎所有非 Windows 的桌面客户端都是网站的封装。[Twitter][2] 有很多客户端,但我真正想要的是轻量、易于使用,最重要的是吸引人的客户端。
|
||||
我喜欢社交网络和微博。它快速、简单,还有我可以与世界分享我的想法。当然,缺点是几乎所有非 Windows 的桌面客户端都对是网站的封装。[Twitter][2] 有很多客户端,但我真正想要的是轻量、易于使用,最重要的是吸引人的客户端。
|
||||
|
||||
![Rainbow Stream for Twitter][3]
|
||||
|
||||
[Rainbow Stream][4] 是好看的 Twitter 客户端之一。它简单易用,并且可以通过 **pip3 install rainbowstream** 快速安装。第一次运行时,它将打开浏览器窗口,并让你通过 Twitter 授权。完成后,你将回到命令行,你的 Twitter 时间线将开始滚动。
|
||||
[Rainbow Stream][4] 是好看的 Twitter 客户端之一。它简单易用,并且可以通过 `pip3 install rainbowstream` 快速安装。第一次运行时,它将打开浏览器窗口,并让你通过 Twitter 授权。完成后,你将回到命令行,你的 Twitter 时间线将开始滚动。
|
||||
|
||||
![Rainbow Stream first run][5]
|
||||
|
||||
要了解的最重要的命令是 **p** 暂停推流、**r** 继续推流、**h** 得帮助,以及 **t** 发布新的推文。例如,**h tweets** 将提供发送和回复推文的所有选项。另一个有用的帮助页面是 **h messages**,它提供了处理直接消息的命令,这是我妻子和我经常使用的东西。还有很多其他命令,我会回头获得很多帮助。
|
||||
要了解的最重要的命令是 `p` 暂停推流、`r` 继续推流、`h` 得到帮助,以及 `t` 发布新的推文。例如,`h tweets` 将提供发送和回复推文的所有选项。另一个有用的帮助页面是 `h messages`,它提供了处理直接消息的命令,这是我妻子和我经常使用的东西。还有很多其他命令,我会回头获得很多帮助。
|
||||
|
||||
随着时间线的滚动,你可以看到它有完整的 UTF-8 支持,并以正确的字体显示推文被转推以及喜欢的次数,图标和 emoji 也能正确显示。
|
||||
|
||||
![Kill this love][6]
|
||||
|
||||
关于 Rainbow Stream 的_最好_功能之一就是你不必放弃照片和图像。默认情况下,此功能是关闭的,但是你可以使用 **config** 命令尝试它。
|
||||
|
||||
关于 Rainbow Stream 的*最好*功能之一就是你不必放弃照片和图像。默认情况下,此功能是关闭的,但是你可以使用 `config` 命令尝试它。
|
||||
|
||||
```
|
||||
`config IMAGE_ON_TERM = true`
|
||||
config IMAGE_ON_TERM = true
|
||||
```
|
||||
|
||||
此命令将任何图像渲染为 ASCII 艺术。如果你有大量照片流,它可能会有点多,但是我喜欢。它有非常复古的 1990 年代 BBS 感觉,我也确实喜欢 1990 年代的 BBS 场景。
|
||||
@ -50,7 +51,7 @@ via: https://opensource.com/article/20/1/tweet-terminal-rainbow-stream
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,16 +1,18 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11869-1.html)
|
||||
[#]: subject: (Read Reddit from the Linux terminal)
|
||||
[#]: via: (https://opensource.com/article/20/1/open-source-reddit-client)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
在 Linux 终端中阅读 Reddit
|
||||
======
|
||||
在我们的 20 个使用开源提升生产力的系列的第十一篇文章中使用 Reddit 客户端 Tuir 在工作中短暂休息一下。
|
||||
![Digital creative of a browser on the internet][1]
|
||||
|
||||
> 在我们的 20 个使用开源提升生产力的系列的第十一篇文章中使用 Reddit 客户端 Tuir 在工作中短暂休息一下。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/09/104113w1ytjmlv1jly0j1t.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
@ -20,23 +22,23 @@
|
||||
|
||||
![/r/emacs in Tuir][3]
|
||||
|
||||
当我阅读 Reddit(不仅仅是看动物宝宝的图片)时,我使用 [Tuir][4],代表 Terminal UI for Reddit(Reddit 终端 UI)。Tuir 是功能齐全的 Reddit 客户端,可以在运行 Python 的任何系统上运行。安装是通过 pip 完成的,非常轻松。
|
||||
当我阅读 Reddit(不仅仅是看动物宝宝的图片)时,我使用 [Tuir][4](Reddit 终端 UI)。Tuir 是功能齐全的 Reddit 客户端,可以在运行 Python 的任何系统上运行。安装是通过 `pip` 完成的,非常简单。
|
||||
|
||||
首次运行时,Tuir 会进入 Reddit 默认文章列表。屏幕的顶部和底部有列出不同命令的栏。顶部栏显示你在 Reddit 上的位置,第二行显示根据 Reddit “Hot/New/Controversial” 等类别筛选的命令。按下筛选器前面的数字触发筛选。
|
||||
|
||||
![Filtering by Reddit's "top" category][5]
|
||||
|
||||
你可以使用箭头键或 **j**、**k**、**h** 和 **l** 键浏览列表,这与 Vi/Vim 使用的键相同。底部栏有用于应用导航的命令。如果要跳转到另一个子板,只需按 **/** 键打开提示,然后输入你要进入的子板名称。
|
||||
你可以使用箭头键或 `j`、`k`、`h` 和 `l` 键浏览列表,这与 Vi/Vim 使用的键相同。底部栏有用于应用导航的命令。如果要跳转到另一个子板,只需按 `/` 键打开提示,然后输入你要进入的子板名称。
|
||||
|
||||
![Logging in][6]
|
||||
|
||||
某些东西除非你登录,否则无法访问。如果你尝试执行需要登录的操作,那么 Tuir 就会提示你,例如发布新文章 (**c**) 或赞成/反对 (**a** 和 **z**)。要登录,请按 **u** 键。这将打开浏览器以通过 OAuth2 登录,Tuir 将保存令牌。之后,你的用户名应出现在屏幕的右上方。
|
||||
某些东西除非你登录,否则无法访问。如果你尝试执行需要登录的操作,那么 Tuir 就会提示你,例如发布新文章 (`c`)或赞成/反对 (`a` 和 `z`)。要登录,请按 `u` 键。这将打开浏览器以通过 OAuth2 登录,Tuir 将保存令牌。之后,你的用户名应出现在屏幕的右上方。
|
||||
|
||||
Tuir 还可以打开浏览器来查看图像、加载链接等。稍作调整,它甚至可以在终端中显示图像(尽管我没有设法使其正常工作)。
|
||||
Tuir 还可以打开浏览器来查看图像、加载链接等。稍作调整,它甚至可以在终端中显示图像(尽管我没有让它可以正常工作)。
|
||||
|
||||
总的来说,我对 Tuir 在我需要休息时能快速跟上 Reddit 感到很满意。
|
||||
|
||||
Tuir 是现已淘汰的 [RTV][7] 的两个分叉之一。另一个是 [TTRV][8],它还无法通过 pip 安装,但功能相同。我期待看到它们随着时间的推移脱颖而出。
|
||||
Tuir 是现已淘汰的 [RTV][7] 的两个分叉之一。另一个是 [TTRV][8],它还无法通过 `pip` 安装,但功能相同。我期待看到它们随着时间的推移脱颖而出。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -45,7 +47,7 @@ via: https://opensource.com/article/20/1/open-source-reddit-client
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,35 +1,36 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11876-1.html)
|
||||
[#]: subject: (Get your RSS feeds and podcasts in one place with this open source tool)
|
||||
[#]: via: (https://opensource.com/article/20/1/open-source-rss-feed-reader)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用此开源工具将你的RSS 订阅源和播客放在一起
|
||||
使用此开源工具在一起收取你的 RSS 订阅源和播客
|
||||
======
|
||||
在我们的 20 个使用开源提升生产力的系列的第十二篇文章中使用 Newsboat 跟上你的新闻 RSS 源和播客。
|
||||
![Ship captain sailing the Kubernetes seas][1]
|
||||
|
||||
> 在我们的 20 个使用开源提升生产力的系列的第十二篇文章中使用 Newsboat 收取你的新闻 RSS 源和播客。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/10/162526wv5jdl0m12sw10md.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 使用 Newsboat 访问你的 RSS 源和播客
|
||||
|
||||
RSS 新闻源是了解各个网站最新消息的非常方便的方法。除了 Opensource.com,我还会关注 [SysAdvent][2] 年度 sysadmin 工具,还有一些我最喜欢的作者以及一些网络漫画。RSS 阅读器可以让我“批处理”阅读内容,因此,我每天不会在不同的网站上花费很多时间。
|
||||
RSS 新闻源是了解各个网站最新消息的非常方便的方法。除了 Opensource.com,我还会关注 [SysAdvent][2] sysadmin 年度工具,还有一些我最喜欢的作者以及一些网络漫画。RSS 阅读器可以让我“批处理”阅读内容,因此,我每天不会在不同的网站上花费很多时间。
|
||||
|
||||
![Newsboat][3]
|
||||
|
||||
[Newsboat][4] 是一个基于终端的 RSS 订阅源阅读器,外观感觉很像电子邮件程序 [Mutt][5]。它使阅读新闻变得容易,并有许多不错的功能。
|
||||
|
||||
安装 Newsboat 非常容易,因为它包含在大多数发行版(以及 MacOS 上的 Homebrew)中。安装后,只需在 **~/.newsboat/urls** 中添加订阅源。如果你是从其他阅读器迁移而来,并有导出的 OPML 文件,那么可以使用以下方式导入:
|
||||
|
||||
安装 Newsboat 非常容易,因为它包含在大多数发行版(以及 MacOS 上的 Homebrew)中。安装后,只需在 `~/.newsboat/urls` 中添加订阅源。如果你是从其他阅读器迁移而来,并有导出的 OPML 文件,那么可以使用以下方式导入:
|
||||
|
||||
```
|
||||
`newsboat -i </path/to/my/feeds.opml>`
|
||||
newsboat -i </path/to/my/feeds.opml>
|
||||
```
|
||||
|
||||
添加订阅源后,Newsboat 的界面非常熟悉,特别是如果你使用过 Mutt。你可以使用箭头键上下滚动,使用 **r** 检查某个源中是否有新项目,使用 **R** 检查所有源中是否有新项目,按**回车**打开订阅源,并选择要阅读的文章。
|
||||
添加订阅源后,Newsboat 的界面非常熟悉,特别是如果你使用过 Mutt。你可以使用箭头键上下滚动,使用 `r` 检查某个源中是否有新项目,使用 `R` 检查所有源中是否有新项目,按回车打开订阅源,并选择要阅读的文章。
|
||||
|
||||
![Newsboat article list][6]
|
||||
|
||||
@ -39,7 +40,7 @@ RSS 新闻源是了解各个网站最新消息的非常方便的方法。除了
|
||||
|
||||
#### 播客
|
||||
|
||||
Newsboat 还通过 Podboat 提供了[播客支持][10],podboat 是一个附带的应用,它可帮助下载和排队播客节目。在 Newsboat 中查看播客源时,按下 **e** 将节目添加到你的下载队列中。所有信息将保存在 **~/.newsboat** 目录中的队列文件中。Podboat 读取此队列并将节目下载到本地磁盘。你可以在 Podboat 的用户界面(外观和行为类似于 Newsboat)执行此操作,也可以使用 ** podboat -a ** 让 Podboat 下载所有内容。作为播客人和播客听众,我认为这_真的_很方便。
|
||||
Newsboat 还通过 Podboat 提供了[播客支持][10],Podboat 是一个附带的应用,它可帮助下载和排队播客节目。在 Newsboat 中查看播客源时,按下 `e` 将节目添加到你的下载队列中。所有信息将保存在 `~/.newsboat` 目录中的队列文件中。Podboat 读取此队列并将节目下载到本地磁盘。你可以在 Podboat 的用户界面(外观和行为类似于 Newsboat)执行此操作,也可以使用 `podboat -a` 让 Podboat 下载所有内容。作为播客人和播客听众,我认为这*真的*很方便。
|
||||
|
||||
![Podboat][11]
|
||||
|
||||
@ -52,7 +53,7 @@ via: https://opensource.com/article/20/1/open-source-rss-feed-reader
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,107 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11920-1.html)
|
||||
[#]: subject: (Screenshot your Linux system configuration with Bash tools)
|
||||
[#]: via: (https://opensource.com/article/20/1/screenfetch-neofetch)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
使用 Bash 工具截屏 Linux 系统配置
|
||||
======
|
||||
|
||||
> 使用 ScreenFetch 和 Neofetch 与其他人轻松分享你的 Linux 环境。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/23/124525yiiqs18ll736oro8.jpg)
|
||||
|
||||
你可能有很多原因想要与他人分享你的 Linux 配置。你可能正在寻求帮助来对系统上的问题进行故障排除,或者你对所创建的环境感到非常自豪,因此想向其他开源爱好者展示。
|
||||
|
||||
你可以在 Bash 提示符下使用 `cat /proc/cpuinfo` 或 `lscpu` 命令获取某些信息。但是,如果你想共享更多详细信息,例如你的操作系统、内核、运行时间、shell 环境,屏幕分辨率等,那么可以选择两个很棒的工具:screenFetch 和 Neofetch。
|
||||
|
||||
### screenFetch
|
||||
|
||||
[screenFetch][2] 是 Bash 命令行程序,它可以产生非常漂亮的系统配置和运行时间的截图。这是方便的与它人共享系统配置的方法。
|
||||
|
||||
在许多 Linux 发行版上安装 screenFetch 很简单。
|
||||
|
||||
在 Fedora 上,输入:
|
||||
|
||||
```
|
||||
$ sudo dnf install screenfetch
|
||||
```
|
||||
|
||||
在 Ubuntu 上,输入:
|
||||
|
||||
```
|
||||
$ sudo apt install screenfetch
|
||||
```
|
||||
|
||||
对于其他操作系统,包括 FreeBSD、MacOS 等,请查阅 screenFetch 的 wiki [安装页面][3]。安装 screenFetch 后,它可以生成详细而彩色的截图,如下所示:
|
||||
|
||||
![screenFetch][4]
|
||||
|
||||
ScreenFetch 还提供各种命令行选项来调整你的结果。例如,`screenfetch -v` 返回详细输出,逐行显示每个选项以及上面的显示。
|
||||
|
||||
`screenfetch -n` 在显示系统信息时消除了操作系统图标。
|
||||
|
||||
![screenfetch -n option][5]
|
||||
|
||||
其他选项包括 `screenfetch -N`,它去除所有输出的颜色。`screenfetch -t`,它根据终端的大小截断输出。`screenFetch -E`,它可抑制错误输出。
|
||||
|
||||
请检查手册页来了解其他选项。screenFetch 在 GPLv3 许可证下的开源,你可以在它的 [GitHub 仓库][6]中了解有关该项目的更多信息。
|
||||
|
||||
### Neofetch
|
||||
|
||||
[Neofetch][7] 是创建系统信息截图的另一个工具。它是用 Bash 3.2 编写的,在 [MIT 许可证][8]下开源。
|
||||
|
||||
根据项目网站所述,“Neofetch 支持近 150 种不同的操作系统。从 Linux 到 Windows,一直到 Minix、AIX 和 Haiku 等更晦涩的操作系统。”
|
||||
|
||||
![Neofetch][9]
|
||||
|
||||
该项目维护了一个 wiki,其中包含用于各种发行版和操作系统的出色的[安装文档][10]。
|
||||
|
||||
如果你使用的是 Fedora、RHEL 或 CentOS,那么可以在 Bash 提示符下使用以下命令安装 Neofetch:
|
||||
|
||||
```
|
||||
$ sudo dnf install neofetch
|
||||
```
|
||||
|
||||
在 Ubuntu 17.10 及更高版本上,你可以使用:
|
||||
|
||||
```
|
||||
$ sudo apt install neofetch
|
||||
```
|
||||
|
||||
首次运行时,Neofetch 将 `~/.config/neofetch/config.conf` 文件写入主目录(`.config/config.conf`),它让你可以[自定义和控制][11] Neofetch 输出的各个方面。例如,你可以配置 Neofetch 使用图像、ASCII 文件、你选择的壁纸,或者完全不使用。config.conf 文件还让与它人分享配置变得容易。
|
||||
|
||||
如果 Neofetch 不支持你的操作系统或不提供所需选项,请在项目的 [GitHub 仓库][12]中打开一个问题。
|
||||
|
||||
### 总结
|
||||
|
||||
无论为什么要共享系统配置,screenFetch 或 Neofetch 都应该能做到。你是否知道在 Linux 上提供此功能的另一个开源工具?请在评论中分享你的最爱。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/screenfetch-neofetch
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI- (metrics and data shown on a computer screen)
|
||||
[2]: https://github.com/KittyKatt/screenFetch
|
||||
[3]: https://github.com/KittyKatt/screenFetch/wiki/Installation
|
||||
[4]: https://opensource.com/sites/default/files/uploads/screenfetch.png (screenFetch)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/screenfetch-n.png (screenfetch -n option)
|
||||
[6]: http://github.com/KittyKatt/screenFetch
|
||||
[7]: https://github.com/dylanaraps/neofetch
|
||||
[8]: https://github.com/dylanaraps/neofetch/blob/master/LICENSE.md
|
||||
[9]: https://opensource.com/sites/default/files/uploads/neofetch.png (Neofetch)
|
||||
[10]: https://github.com/dylanaraps/neofetch/wiki/Installation
|
||||
[11]: https://github.com/dylanaraps/neofetch/wiki/Customizing-Info
|
||||
[12]: https://github.com/dylanaraps/neofetch/issues
|
105
published/202002/20200123 How to stop typosquatting attacks.md
Normal file
105
published/202002/20200123 How to stop typosquatting attacks.md
Normal file
@ -0,0 +1,105 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11899-1.html)
|
||||
[#]: subject: (How to stop typosquatting attacks)
|
||||
[#]: via: (https://opensource.com/article/20/1/stop-typosquatting-attacks)
|
||||
[#]: author: (Sam Bocetta https://opensource.com/users/sambocetta)
|
||||
|
||||
如何防范误植攻击
|
||||
======
|
||||
|
||||
> <ruby>误植<rt>Typosquatting</rt></ruby>是一种引诱用户将敏感数据泄露给不法分子的方式,针对这种攻击方式,我们很有必要了解如何保护我们的组织、我们的开源项目以及我们自己。
|
||||
|
||||
![Gears above purple clouds][1]
|
||||
|
||||
除了常规手段以外,网络罪犯还会利用社会工程的方式,试图让安全意识较弱的人泄露私人信息或是有价值的证书。很多[网络钓鱼骗局][2]的实质都是攻击者伪装成信誉良好的公司或组织,然后借此大规模传播病毒或恶意软件。
|
||||
|
||||
<ruby>[误植][3]<rt>Typosquatting</rt></ruby>就是其中一个常用的手法。它是一种社会工程学的攻击方式,通过使用一些合法网站的错误拼写的 URL 以引诱用户访问恶意网站,这样的做法既使真正的原网站遭受声誉上的损害,又诱使用户向这些恶意网站提交个人敏感信息。因此,网站的管理人员和用户双方都应该意识到这个问题带来的风险,并采取措施加以保护。
|
||||
|
||||
一些由广大开发者在公共代码库中维护的开源软件通常都被认为具有安全上的优势,但当面临社会工程学攻击或恶意软件植入时,开源软件也需要注意以免受到伤害。
|
||||
|
||||
下面就来关注一下误植攻击的发展趋势,以及这种攻击方式在未来可能对开源软件造成的影响。
|
||||
|
||||
### 什么是误植?
|
||||
|
||||
误植是一种非常特殊的网络犯罪形式,其背后通常是一个更大的网络钓鱼骗局。不法分子首先会购买和注册域名,而他们注册的域名通常是一个常用网站的错误拼写形式,例如在正确拼写的基础上添加一个额外的元音字母,又或者是将字母“i”替换成字母“l”。对于同一个正常域名,不法分子通常会注册数十个拼写错误的变体域名。
|
||||
|
||||
用户一旦访问这样的域名,不法分子的目的就已经成功了一半。为此,他们会通过电子邮件的方式,诱导用户访问这样的伪造域名。伪造域名指向的页面中,通常都带有一个简单的登录界面,还会附上熟悉的被模仿网站的徽标,尽可能让用户认为自己访问的是真实的网站。
|
||||
|
||||
如果用户没有识破这一个骗局,在页面中提交了诸如银行卡号、用户名、密码等敏感信息,这些数据就会被不法分子所完全掌控。进一步来看,如果这个用户在其它网站也使用了相同的用户名和密码,那就有同样受到波及的风险。受害者最终可能会面临身份被盗、信用记录被破坏等危险。
|
||||
|
||||
### 最近的一些案例
|
||||
|
||||
从网站的所有方来看,遭到误植攻击可能会带来一场公关危机。尽管网站域名的所有者没有参与到犯罪当中,但这会被认为是一次管理上的失职,因为域名所有者有主动防御误植攻击的责任,以避免这一类欺诈事件的发生。
|
||||
|
||||
在几年之前就发生过[一起案件][4],很多健康保险客户收到了一封指向 we11point.com 的钓鱼电子邮件,其中 URL 里正确的字母“l”被换成了数字“1”,从而导致一批用户成为了这一次攻击的受害者。
|
||||
|
||||
最初,与特定国家/地区相关的顶级域名是不允许随意注册的。但后来国际域名规则中放开这一限制之后,又兴起了一波新的误植攻击。例如最常见的一种手法就是注册一个与 .com 域名类似的 .om 域名,一旦在输入 URL 时不慎遗漏了字母 c 就会给不法分子带来可乘之机。
|
||||
|
||||
### 网站如何防范误植攻击
|
||||
|
||||
对于一个公司来说,最好的策略就是永远比误植攻击采取早一步的行动。
|
||||
|
||||
也就是说,在注册域名的时候,不仅要注册自己商标名称的域名,最好还要同时注册可能由于拼写错误产生的其它域名。当然,没有太大必要把可能导致错误的所有顶级域名都注册掉,但至少要把可能导致错误的一些一级域名抢注下来。
|
||||
|
||||
如果你有让用户跳转到一个第三方网站的需求,务必要让用户从你的官方网站上进行跳转,而不应该通过类似群发邮件的方式向用户告知 URL。因此,必须明确一个策略:在与用户通信交流时,不将用户引导到官方网站以外的地方去。在这样的情况下,如果有不法分子试图以你公司的名义发布虚假消息,用户将会从带有异样的页面或 URL 上有所察觉。
|
||||
|
||||
你可以使用类似 [DNS Twist][5] 的开源工具来扫描公司正在使用的域名,它可以确定是否有相似的域名已被注册,从而暴露潜在的误植攻击。DNS Twist 可以在 Linux 系统上通过一系列的 shell 命令来运行。
|
||||
|
||||
还有一些网络提供商(ISP)会将防护误植攻击作为他们网络产品的一部分。这就相当于一层额外的保护,如果用户不慎输入了带有拼写错误的 URL,就会被提示该页面已经被阻止并重定向到正确的域名。
|
||||
|
||||
如果你是系统管理员,还可以考虑运行一个自建的 [DNS 服务器][6],以便通过黑名单的机制禁止对某些域名的访问。
|
||||
|
||||
你还可以密切监控网站的访问流量,如果来自某个特定地区的用户被集体重定向到了虚假的站点,那么访问量将会发生骤降。这也是一个有效监控误植攻击的角度。
|
||||
|
||||
防范误植攻击与防范其它网络攻击一样需要保持警惕。所有用户都希望网站的所有者能够扫除那些与正主类似的假冒站点,如果这项工作没有做好,用户的信任对你的信任程度就会每况愈下。
|
||||
|
||||
### 误植对开源软件的影响
|
||||
|
||||
因为开源项目的源代码是公开的,所以其中大部分项目都会进行安全和渗透测试。但错误是不可能完全避免的,如果你参与了开源项目,还是有需要注意的地方。
|
||||
|
||||
当你收到一个不明来源的<ruby>合并请求<rt>Merge Request</rt></ruby>或补丁时,必须在合并之前仔细检查,尤其是相关代码涉及到网络层面的时候。不要屈服于只测试构建的诱惑; 一定要进行严格的检查和测试,以确保没有恶意代码混入正常的代码当中。
|
||||
|
||||
同时,还要严格按照正确的方法使用域名,避免不法分子创建仿冒的下载站点并提供带有恶意代码的软件。可以通过如下所示的方法使用数字签名来确保你的软件没有被篡改:
|
||||
|
||||
```
|
||||
gpg --armor --detach-sig \
|
||||
--output advent-gnome.sig \
|
||||
example-0.0.1.tar.xz
|
||||
```
|
||||
|
||||
同时给出你提供的文件的校验和:
|
||||
|
||||
```
|
||||
sha256sum example-0.0.1.tar.xz > example-0.0.1.txt
|
||||
```
|
||||
|
||||
无论你的用户会不会去用上这些安全措施,你也应该提供这些必要的信息。因为只要有那么一个人留意到签名有异样,就能为你敲响警钟。
|
||||
|
||||
### 总结
|
||||
|
||||
人类犯错在所难免。世界上数百万人输入同一个网址时,总会有人出现拼写的错误。不法分子也正是抓住了这个漏洞才得以实施误植攻击。
|
||||
|
||||
用抢注域名的方式去完全根治误植攻击也是不太现实的,我们更应该关注这种攻击的传播方式以减轻它对我们的影响。最好的保护就是和用户之间建立信任,并积极检测误植攻击的潜在风险。作为开源社区,我们更应该团结起来一起应对误植攻击。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/stop-typosquatting-attacks
|
||||
|
||||
作者:[Sam Bocetta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/sambocetta
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/chaos_engineer_monster_scary_devops_gear_kubernetes.png?itok=GPYLvfVh (Gears above purple clouds)
|
||||
[2]: https://www.cloudberrylab.com/resources/guides/types-of-phishing/
|
||||
[3]: https://en.wikipedia.org/wiki/Typosquatting
|
||||
[4]: https://www.menlosecurity.com/blog/-a-new-approach-to-end-typosquatting
|
||||
[5]: https://github.com/elceef/dnstwist
|
||||
[6]: https://opensource.com/article/17/4/build-your-own-name-server
|
@ -1,29 +1,30 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11879-1.html)
|
||||
[#]: subject: (Use this open source tool to get your local weather forecast)
|
||||
[#]: via: (https://opensource.com/article/20/1/open-source-weather-forecast)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用这个开源工具获取本地天气预报
|
||||
======
|
||||
在我们的 20 个使用开源提升生产力的系列的第十三篇文章中使用 wego 来了解出门前你是否要需要外套、雨伞或者防晒霜。
|
||||
![Sky with clouds and grass][1]
|
||||
|
||||
> 在我们的 20 个使用开源提升生产力的系列的第十三篇文章中使用 wego 来了解出门前你是否要需要外套、雨伞或者防晒霜。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/11/140842a8qwomfeg9mwegg8.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 使用 wego 了解天气
|
||||
|
||||
过去十年我对我的职业最满意的地方之一是大多数时候是远程工作。尽管现实情况是我很多时候是在家里办公,但我可以在世界上任何地方工作。缺点是,离家时我会根据天气做出一些决定。在我居住的地方,”晴朗“可以表示从”酷热“、”低于零度“到”一小时内会小雨“。能够了解实际情况和快速预测非常有用。
|
||||
过去十年我对我的职业最满意的地方之一是大多数时候是远程工作。尽管现实情况是我很多时候是在家里办公,但我可以在世界上任何地方工作。缺点是,离家时我会根据天气做出一些决定。在我居住的地方,“晴朗”可以表示从“酷热”、“低于零度”到“一小时内会小雨”。能够了解实际情况和快速预测非常有用。
|
||||
|
||||
![Wego][2]
|
||||
|
||||
[Wego][3] 是用 Go 编写的程序,可以获取并显示你的当地天气。如果你愿意,它甚至可以用闪亮的 ASCII 艺术效果进行渲染。
|
||||
|
||||
要安装 wego,你需要确保在系统上安装了[Go][4]。之后,你可以使用 **go get** 命令获取最新版本。你可能还想将 **~/go/bin** 目录添加到路径中:
|
||||
|
||||
要安装 `wego`,你需要确保在系统上安装了[Go][4]。之后,你可以使用 `go get` 命令获取最新版本。你可能还想将 `~/go/bin` 目录添加到路径中:
|
||||
|
||||
```
|
||||
go get -u github.com/schachmat/wego
|
||||
@ -31,11 +32,9 @@ export PATH=~/go/bin:$PATH
|
||||
wego
|
||||
```
|
||||
|
||||
首次运行时,wego 会报告缺失 API 密钥。现在你需要决定一个后端。默认后端是 [Forecast.io][5],它是 [Dark Sky][6]的一部分。Wego还支持 [OpenWeatherMap][7] 和 [WorldWeatherOnline][8]。我更喜欢 OpenWeatherMap,因此我将在此向你展示如何设置。
|
||||
|
||||
你需要在 OpenWeatherMap 中[注册 API 密钥][9]。注册是免费的,尽管免费的 API 密钥限制了一天可以查询的数量,但这对于普通用户来说应该没问题。得到 API 密钥后,将它放到 **~/.wegorc** 文件中。现在可以填写你的位置、语言以及使用公制、英制(英国/美国)还是国际单位制(SI)。OpenWeatherMap 可通过名称、邮政编码、坐标和 ID 确定位置,这是我喜欢它的原因之一。
|
||||
|
||||
首次运行时,`wego` 会报告缺失 API 密钥。现在你需要决定一个后端。默认后端是 [Forecast.io][5],它是 [Dark Sky][6]的一部分。`wego` 还支持 [OpenWeatherMap][7] 和 [WorldWeatherOnline][8]。我更喜欢 OpenWeatherMap,因此我将在此向你展示如何设置。
|
||||
|
||||
你需要在 OpenWeatherMap 中[注册 API 密钥][9]。注册是免费的,尽管免费的 API 密钥限制了一天可以查询的数量,但这对于普通用户来说应该没问题。得到 API 密钥后,将它放到 `~/.wegorc` 文件中。现在可以填写你的位置、语言以及使用公制、英制(英国/美国)还是国际单位制(SI)。OpenWeatherMap 可通过名称、邮政编码、坐标和 ID 确定位置,这是我喜欢它的原因之一。
|
||||
|
||||
```
|
||||
# wego configuration for OEM
|
||||
@ -53,16 +52,15 @@ owm-lang=en
|
||||
units=imperial
|
||||
```
|
||||
|
||||
现在,在命令行运行 **wego** 将显示接下来三天的当地天气。
|
||||
现在,在命令行运行 `wego` 将显示接下来三天的当地天气。
|
||||
|
||||
Wego 还可以输出 JSON 以便程序使用,还可显示 emoji。你可以使用 **-f** 参数或在 **.wegorc** 文件中指定前端。
|
||||
`wego` 还可以输出 JSON 以便程序使用,还可显示 emoji。你可以使用 `-f` 参数或在 `.wegorc` 文件中指定前端。
|
||||
|
||||
![Wego at login][10]
|
||||
|
||||
如果你想在每次打开 shell 或登录主机时查看天气,只需将 wego 添加到 **~/.bashrc**(我这里是 **~/.zshrc**)即可。
|
||||
|
||||
[wttr.in][11] 项目是 wego 上的基于 Web 的封装。它提供了一些其他显示选项,并且可以在同名网站上看到。关于 wttr.in 的一件很酷的事情是,你可以使用 **curl** 获取一行天气信息。我有一个名为 **get_wttr** 的 shell 函数,用于获取当前简化的预报信息。
|
||||
如果你想在每次打开 shell 或登录主机时查看天气,只需将 wego 添加到 `~/.bashrc`(我这里是 `~/.zshrc`)即可。
|
||||
|
||||
[wttr.in][11] 项目是 wego 上的基于 Web 的封装。它提供了一些其他显示选项,并且可以在同名网站上看到。关于 wttr.in 的一件很酷的事情是,你可以使用 `curl` 获取一行天气信息。我有一个名为 `get_wttr` 的 shell 函数,用于获取当前简化的预报信息。
|
||||
|
||||
```
|
||||
get_wttr() {
|
||||
@ -81,7 +79,7 @@ via: https://opensource.com/article/20/1/open-source-weather-forecast
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,147 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11882-1.html)
|
||||
[#]: subject: (3 handy command-line internet speed tests)
|
||||
[#]: via: (https://opensource.com/article/20/1/internet-speed-tests)
|
||||
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
|
||||
|
||||
3 个方便的命令行网速测试工具
|
||||
======
|
||||
|
||||
> 用这三个开源工具检查你的互联网和局域网速度。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/12/115915kk6hkax1vparkuvk.jpg)
|
||||
|
||||
能够验证网络连接速度使您可以控制计算机。 使您可以在命令行中检查互联网和网络速度的三个开源工具是 Speedtest、Fast 和 iPerf。
|
||||
|
||||
### Speedtest
|
||||
|
||||
[Speedtest][2] 是一个旧宠。它用 Python 实现,并打包在 Apt 中,也可用 `pip` 安装。你可以将它作为命令行工具或在 Python 脚本中使用。
|
||||
|
||||
使用以下命令安装:
|
||||
|
||||
```
|
||||
sudo apt install speedtest-cli
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```
|
||||
sudo pip3 install speedtest-cli
|
||||
```
|
||||
|
||||
然后使用命令 `speedtest` 运行它:
|
||||
|
||||
```
|
||||
$ speedtest
|
||||
Retrieving speedtest.net configuration...
|
||||
Testing from CenturyLink (65.128.194.58)...
|
||||
Retrieving speedtest.net server list...
|
||||
Selecting best server based on ping...
|
||||
Hosted by CenturyLink (Cambridge, UK) [20.49 km]: 31.566 ms
|
||||
Testing download speed................................................................................
|
||||
Download: 68.62 Mbit/s
|
||||
Testing upload speed......................................................................................................
|
||||
Upload: 10.93 Mbit/s
|
||||
```
|
||||
|
||||
它给你提供了互联网上传和下载的网速。它快速而且可脚本调用,因此你可以定期运行它,并将输出保存到文件或数据库中,以记录一段时间内的网络速度。
|
||||
|
||||
### Fast
|
||||
|
||||
[Fast][3] 是 Netflix 提供的服务。它的网址是 [Fast.com][4],同时它有一个可通过 `npm` 安装的命令行工具:
|
||||
|
||||
```
|
||||
npm install --global fast-cli
|
||||
```
|
||||
|
||||
网站和命令行程序都提供了相同的基本界面:它是一个尽可能简单的速度测试:
|
||||
|
||||
```
|
||||
$ fast
|
||||
|
||||
82 Mbps ↓
|
||||
```
|
||||
|
||||
该命令返回你的网络下载速度。要获取上传速度,请使用 `-u` 标志:
|
||||
|
||||
```
|
||||
$ fast -u
|
||||
|
||||
⠧ 80 Mbps ↓ / 8.2 Mbps ↑
|
||||
```
|
||||
|
||||
### iPerf
|
||||
|
||||
[iPerf][5] 测试的是局域网速度(而不是像前两个工具一样测试互联网速度)的好方法。Debian、Raspbian 和 Ubuntu 用户可以使用 apt 安装它:
|
||||
|
||||
```
|
||||
sudo apt install iperf
|
||||
```
|
||||
|
||||
它还可用于 Mac 和 Windows。
|
||||
|
||||
安装完成后,你需要在同一网络上的两台计算机上使用它(两台都必须安装 iPerf)。指定其中一台作为服务器。
|
||||
|
||||
获取服务端计算机的 IP 地址:
|
||||
|
||||
```
|
||||
ip addr show | grep inet.*brd
|
||||
```
|
||||
|
||||
你的本地 IP 地址(假设为 IPv4 本地网络)以 `192.168` 或 `10` 开头。记下 IP 地址,以便可以在另一台计算机(指定为客户端的计算机)上使用它。
|
||||
|
||||
在服务端启动 `iperf`:
|
||||
|
||||
```
|
||||
iperf -s
|
||||
```
|
||||
|
||||
它会等待来自客户端的传入连接。将另一台计算机作为为客户端并运行此命令,将示例中的 IP 替换为服务端计算机的 IP:
|
||||
|
||||
```
|
||||
iperf -c 192.168.1.2
|
||||
```
|
||||
|
||||
![iPerf][6]
|
||||
|
||||
只需几秒钟即可完成测试,然后返回传输大小和计算出的带宽。我使用家用服务器作为服务端,在 PC 和笔记本电脑上进行了一些测试。我最近在房屋周围安装了六类线以太网,因此我的有线连接速度达到 1Gbps,但 WiFi 连接速度却低得多。
|
||||
|
||||
![iPerf][7]
|
||||
|
||||
你可能注意到它记录到 16Gbps。那是我使用服务器进行自我测试,因此它只是在测试写入磁盘的速度。该服务器具有仅 16 Gbps 的硬盘驱动器,但是我的台式机有 46Gbps,另外我的(较新的)笔记本超过了 60Gbps,因为它们都有固态硬盘。
|
||||
|
||||
![iPerf][8]
|
||||
|
||||
### 总结
|
||||
|
||||
通过这些工具来了解你的网络速度是一项非常简单的任务。如果你更喜欢脚本或者在命令行中运行,上面的任何一个都能满足你。如果你要了解点对点的指标,iPerf 能满足你。
|
||||
|
||||
你还使用其他哪些工具来衡量家庭网络?在评论中分享你的评论。
|
||||
|
||||
本文最初发表在 Ben Nuttall 的 [Tooling blog][9] 上,并获准在此使用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/internet-speed-tests
|
||||
|
||||
作者:[Ben Nuttall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/bennuttall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/train-plane-speed-big-machine.png?itok=f377dXKs (Old train)
|
||||
[2]: https://github.com/sivel/speedtest-cli
|
||||
[3]: https://github.com/sindresorhus/fast-cli
|
||||
[4]: https://fast.com/
|
||||
[5]: https://iperf.fr/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/iperf.png (iPerf)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/iperf2.png (iPerf)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/iperf3.png (iPerf)
|
||||
[9]: https://tooling.bennuttall.com/command-line-speedtest-tools/
|
@ -0,0 +1,111 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11892-1.html)
|
||||
[#]: subject: (Run multiple consoles at once with this open source window environment)
|
||||
[#]: via: (https://opensource.com/article/20/1/multiple-consoles-twin)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用开源窗口环境 twin 一次运行多个控制台
|
||||
======
|
||||
|
||||
> 在我们的 20 个使用开源提升生产力的系列的第十四篇文章中用 twin 模拟了老式的 DESQview 体验。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/14/193658tlbyft0lbu44f0s3.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 通过 twin 克服“一个屏幕,一个应用程序”的限制
|
||||
|
||||
还有人记得 [DESQview][2] 吗?我们在 Windows、Linux 和 MacOS 中理所当然地可以在屏幕上同时运行多个程序,而 DESQview 赋予了 DOS 同样的功能。在我运营拨号 BBS 服务的初期,DESQview 是必需的,它使我能够让 BBS 在后台运行,同时在前台进行其他操作。例如,当有人拨打电话时,我可能正在开发新功能或设置新的外部程序而不会影响他们的体验。后来,在我早期做支持工作的时候,我可以同时运行我的工作电子邮件([MHS 上的 DaVinci 电子邮件][3])、支持单据系统和其他 DOS 程序。这是令人吃惊的!
|
||||
|
||||
![twin][4]
|
||||
|
||||
从那时起,运行多个控制台应用程序的功能已经发展了很多。但是 [tmux][5] 和 [Screen][6] 等应用仍然遵循“一个屏幕,一个应用”的显示方式。好吧,是的,tmux 具有屏幕拆分和窗格,但是不像 DESQview 那样具有将窗口“浮动”在其他窗口上的功能,就我个人而言,我怀念那个功能。
|
||||
|
||||
让我们来看看 [twin][7](文本模式窗口环境)。我认为,这个相对年轻的项目是 DESQview 的精神继任者。它支持控制台和图形环境,并具有与会话脱离和重新接驳的功能。设置起来并不是那么容易,但是它可以在大多数现代操作系统上运行。
|
||||
|
||||
Twin 是从源代码安装的(现在是这样)。但是首先,你需要安装所需的开发库。库名称将因操作系统而异。 以下示例显示了在我的 Ubuntu 19.10 系统中的情况。一旦安装了依赖库,请从 Git 中检出 twin 源代码,并运行 `./configure` 和 `make`,它们应自动检测所有内容并构建 twin:
|
||||
|
||||
```
|
||||
sudo apt install libx11-dev libxpm-dev libncurses-dev zlib1g-dev libgpm-dev
|
||||
git clone git@github.com:cosmos72/twin.git
|
||||
cd twin
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
注意:如果要在 MacOS 或 BSD 上进行编译,则需要在运行 `make` 之前在文件 `include/Tw/autoconf.h` 和 `include/twautoconf.h` 中注释掉 `#define socklen_t int`。这个问题应该在 [twin #57][9] 解决了。
|
||||
|
||||
![twin text mode][10]
|
||||
|
||||
第一次调用 twin 是一个挑战。你需要通过 `--hw` 参数告诉它正在使用哪种显示。例如,要启动文本模式的 twin,请输入 `twin --hw=tty,TERM=linux`。这里指定的 `TERM` 变量替代了你当前 Shell 中终端变量。要启动图形版本,运行 `twin --hw=X@$DISPLAY`。在 Linux 上,twin 一般都“可以正常工作”,而在 MacOS 上,Twin 基本是只能在终端上使用。
|
||||
|
||||
*真正*的乐趣是可以通过 `twattach` 和 `twdisplay` 命令接驳到正在运行的会话的功能。它们使你可以接驳到其他正在运行的 twin 会话。例如,在 Mac 上,我可以运行以下命令以接驳到演示机器上运行的 twin 会话:
|
||||
|
||||
```
|
||||
twdisplay --twin@20days2020.local:0 --hw=tty,TERM=linux
|
||||
```
|
||||
|
||||
![remote twin session][11]
|
||||
|
||||
通过多做一些工作,你还可以将其用作登录外壳,以代替控制台上的 [getty][12]。这需要 gdm 鼠标守护程序、twdm 应用程序(包括)和一些额外的配置。在使用 systemd 的系统上,首先安装并启用 gdm(如果尚未安装),然后使用 `systemctl` 为控制台(我使用 tty6)创建一个覆盖。这些命令必须以 root 用户身份运行;在 Ubuntu 上,它们看起来像这样:
|
||||
|
||||
```
|
||||
apt install gdm
|
||||
systemctl enable gdm
|
||||
systemctl start gdm
|
||||
systemctl edit getty@tty6
|
||||
```
|
||||
|
||||
`systemctl edit getty@tty6` 命令将打开一个名为 `override.conf` 的空文件。它可以定义 systemd 服务设置以覆盖 tty6 的默认设置。将内容更新为:
|
||||
|
||||
```
|
||||
[service]
|
||||
ExecStart=
|
||||
ExecStart=-/usr/local/sbin/twdm --hw=tty@/dev/tty6,TERM=linux
|
||||
StandardInput=tty
|
||||
StandardOutput=tty
|
||||
```
|
||||
|
||||
现在,重新加载 systemd 并重新启动 tty6 以获得 twin 登录提示界面:
|
||||
|
||||
```
|
||||
systemctl daemon-reload
|
||||
systemctl restart getty@tty6
|
||||
```
|
||||
|
||||
![twin][13]
|
||||
|
||||
这将为登录的用户启动一个 twin 会话。我不建议在多用户系统中使用此会话,但是对于个人桌面来说,这是很酷的。并且,通过使用 `twattach` 和 `twdisplay`,你可以从本地 GUI 或远程桌面访问该会话。
|
||||
|
||||
我认为 twin 真是太酷了。它还有一些细节不够完善,但是基本功能都已经有了,并且有一些非常好的文档。另外,它也使我可以在现代操作系统上稍解对 DESQview 式的体验的渴望。我希望随着时间的推移它会有所改进,希望你和我一样喜欢它。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/multiple-consoles-twin
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_web_internet_website.png?itok=g5B_Bw62 (Digital creative of a browser on the internet)
|
||||
[2]: https://en.wikipedia.org/wiki/DESQview
|
||||
[3]: https://en.wikipedia.org/wiki/Message_Handling_System
|
||||
[4]: https://opensource.com/sites/default/files/uploads/productivity_14-1.png (twin)
|
||||
[5]: https://github.com/tmux/tmux/wiki
|
||||
[6]: https://www.gnu.org/software/screen/
|
||||
[7]: https://github.com/cosmos72/twin
|
||||
[8]: mailto:git@github.com
|
||||
[9]: https://github.com/cosmos72/twin/issues/57
|
||||
[10]: https://opensource.com/sites/default/files/uploads/productivity_14-2.png (twin text mode)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/productivity_14-3.png (remote twin session)
|
||||
[12]: https://en.wikipedia.org/wiki/Getty_(Unix)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/productivity_14-4.png (twin)
|
@ -0,0 +1,117 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11900-1.html)
|
||||
[#]: subject: (Use tmux to create the console of your dreams)
|
||||
[#]: via: (https://opensource.com/article/20/1/tmux-console)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用 tmux 创建你的梦想主控台
|
||||
======
|
||||
|
||||
> 使用 tmux 可以做很多事情,尤其是在将 tmuxinator 添加到其中时。在我们的二十篇系列文章的第十五期中查看它们,以在 2020 年实现开源生产力的提高。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/16/220832bd4l1ag4tlqxlpr4.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 使用 tmux 和 tmuxinator 全部放到主控台上
|
||||
|
||||
到目前为止,在本系列文章中,我已经撰写了有关单个应用程序和工具的文章。从今天开始,我将把它们放在一起进行全面设置以简化操作。让我们从命令行开始。为什么使用命令行?简而言之,在命令行上工作可以使我能够从运行 SSH 的任何位置访问许多这些工具和功能。我可以 SSH 进入我的一台个人计算机,并在工作计算机上运行与我的个人计算机上所使用的相同设置。我要使用的主要工具是 [tmux][2]。
|
||||
|
||||
大多数人都只使用了 tmux 非常基础的功能,比如说在远程服务器上打开 tmux,然后启动进程,也许还会打开第二个会话以查看日志文件或调试信息,然后断开连接并在稍后返回。但是其实你可以使用 tmux 做很多工作。
|
||||
|
||||
![tmux][3]
|
||||
|
||||
首先,如果你有一个已有的 tmux 配置文件,请对其进行备份。tmux 的配置文件是 `~/.tmux.conf`。将其移动到另一个目录,例如 `~/tmp`。现在,用 Git 克隆 [Oh My Tmux][4] 项目。从该克隆目录中将 `.tmux.conf` 符号链接到你的家目录,并复制该克隆目录中的 `.tmux.conf.local` 文件到家目录中以进行调整:
|
||||
|
||||
```
|
||||
cd ~
|
||||
mkdir ~/tmp
|
||||
mv ~/.tmux.conf ~/tmp/
|
||||
git clone https://github.com/gpakosz/.tmux.git
|
||||
ln -s ~/.tmux/.tmux.conf ./
|
||||
cp ~/.tmux/.tmux.conf.local ./
|
||||
```
|
||||
|
||||
`.tmux.conf.local` 文件包含了本地设置和覆盖的设置。例如,我稍微更改了默认颜色,然后启用了 [Powerline][5] 分隔线。下面的代码段仅显示了我更改过的内容:
|
||||
|
||||
```
|
||||
tmux_conf_theme_24b_colour=true
|
||||
tmux_conf_theme_focused_pane_bg='default'
|
||||
tmux_conf_theme_pane_border_style=fat
|
||||
tmux_conf_theme_left_separator_main='\uE0B0'
|
||||
tmux_conf_theme_left_separator_sub='\uE0B1'
|
||||
tmux_conf_theme_right_separator_main='\uE0B2'
|
||||
tmux_conf_theme_right_separator_sub='\uE0B3'
|
||||
#tmux_conf_battery_bar_symbol_full='◼'
|
||||
#tmux_conf_battery_bar_symbol_empty='◻'
|
||||
tmux_conf_battery_bar_symbol_full='♥'
|
||||
tmux_conf_battery_bar_symbol_empty='·'
|
||||
tmux_conf_copy_to_os_clipboard=true
|
||||
set -g mouse on
|
||||
```
|
||||
|
||||
请注意,你不需要安装 Powerline,你只需要支持 Powerline 符号的字体即可。我在与控制台相关的所有内容中几乎都使用 [Hack Nerd Font][6],因为它易于阅读并且具有许多有用的额外符号。你还会注意到,我打开了操作系统剪贴板支持和鼠标支持。
|
||||
|
||||
现在,当 tmux 启动时,底部的状态栏会以吸引人的颜色提供更多信息。`Ctrl` + `b` 仍然是输入命令的 “引导” 键,但其他一些进行了更改。现在水平拆分(顶部/底部)窗格为 `Ctrl` + `b` + `-`,垂直拆分为 `Ctrl` + `b` + `_`。启用鼠标模式后,你可以单击以在窗格之间切换,并拖动分隔线以调整其大小。打开新窗口仍然是 `Ctrl` + `b` + `n`,你现在可以单击底部栏上的窗口名称在它们之间进行切换。同样,`Ctrl` + `b` + `e` 将打开 `.tmux.conf.local` 文件以进行编辑。退出编辑器时,tmux 将重新加载配置,而不会重新加载其他任何内容。这很有用。
|
||||
|
||||
到目前为止,我仅对功能和视觉显示进行了一些简单的更改,并增加了鼠标支持。现在,我将它设置为以一种有意义的方式启动我想要的应用程序,而不必每次都重新定位和调整它们的大小。为此,我将使用 [tmuxinator][7]。tmuxinator 是 tmux 的启动器,它允许你指定和管理布局以及使用 YAML 文件自动启动应用程序。要使用它,请启动 tmux 并创建要在其中运行程序的窗格。然后,使用 `Ctrl` + `b` + `n` 打开一个新窗口,并执行 `tmux list-windows`。你将获得有关布局的详细信息。
|
||||
|
||||
![tmux layout information][8]
|
||||
|
||||
请注意上面代码中的第一行,我在其中设置了四个窗格,每个窗格中都有一个应用程序。保存运行时的输出以供以后使用。现在,运行 `tmuxinator new 20days` 以创建名为 “20days” 的布局。这将显示一个带有默认布局文件的文本编辑器。它包含很多有用的内容,我建议你阅读所有选项。首先输入上方的布局信息以及所需的应用程序:
|
||||
|
||||
```
|
||||
# /Users/ksonney/.config/tmuxinator/20days.yml
|
||||
name: 20days
|
||||
root: ~/
|
||||
windows:
|
||||
- mail:
|
||||
layout: d9da,208x60,0,0[208x26,0,0{104x26,0,0,0,103x26,105,0,5},208x33,0,27{104x33,0,27,1,103x33,105,27,4}]] @0
|
||||
panes:
|
||||
- alot
|
||||
- abook
|
||||
- ikhal
|
||||
- todo.sh ls +20days
|
||||
```
|
||||
|
||||
注意空格缩进!与 Python 代码一样,空格和缩进关系到文件的解释方式。保存该文件,然后运行 `tmuxinator 20days`。你应该会得到四个窗格,分别是 [alot][9] 邮件程序、[abook][10]、ikhal(交互式 [khal][11] 的快捷方式)以及 [todo.txt][12] 中带有 “+20days” 标签的任何内容。
|
||||
|
||||
![sample layout launched by tmuxinator][13]
|
||||
|
||||
你还会注意到,底部栏上的窗口标记为 “Mail”。你可以单击该名称(以及其他命名的窗口)以跳到该视图。漂亮吧?我在同一个文件中还设置了名为 “Social” 的第二个窗口,包括 [Tuir][14]、[Newsboat][15]、连接到 [BitlBee][16] 的 IRC 客户端和 [Rainbow Stream][17]。
|
||||
|
||||
tmux 是我跟踪所有事情的生产力动力之源,有了 tmuxinator,我不必在不断调整大小、放置和启动我的应用程序上费心。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/tmux-console
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hat drink at the computer)
|
||||
[2]: https://github.com/tmux/tmux
|
||||
[3]: https://opensource.com/sites/default/files/uploads/productivity_15-1.png (tumux)
|
||||
[4]: https://github.com/gpakosz/.tmux
|
||||
[5]: https://github.com/powerline/powerline
|
||||
[6]: https://www.nerdfonts.com/
|
||||
[7]: https://github.com/tmuxinator/tmuxinator
|
||||
[8]: https://opensource.com/sites/default/files/uploads/productivity_15-2.png (tmux layout information)
|
||||
[9]: https://opensource.com/article/20/1/organize-email-notmuch
|
||||
[10]: https://opensource.com/article/20/1/sync-contacts-locally
|
||||
[11]: https://opensource.com/article/20/1/open-source-calendar
|
||||
[12]: https://opensource.com/article/20/1/open-source-to-do-list
|
||||
[13]: https://opensource.com/sites/default/files/uploads/productivity_15-3.png (sample layout launched by tmuxinator)
|
||||
[14]: https://opensource.com/article/20/1/open-source-reddit-client
|
||||
[15]: https://opensource.com/article/20/1/open-source-rss-feed-reader
|
||||
[16]: https://opensource.com/article/20/1/open-source-chat-tool
|
||||
[17]: https://opensource.com/article/20/1/tweet-terminal-rainbow-stream
|
@ -0,0 +1,113 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11908-1.html)
|
||||
[#]: subject: (Use Vim to send email and check your calendar)
|
||||
[#]: via: (https://opensource.com/article/20/1/vim-email-calendar)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用 Vim 发送邮件和检查日历
|
||||
======
|
||||
|
||||
> 在 2020 年用开源实现更高生产力的二十种方式的第十六篇文章中,直接通过文本编辑器管理你的电子邮件和日历。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/19/185842eyz2znxx1yc2ctnc.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 用 Vim 做(几乎)所有事情,第一部分
|
||||
|
||||
我经常使用两个文本编辑器 —— [Vim][2] 和 [Emacs][3]。为什么两者都用呢?它们有不同的使用场景,在本系列的后续几篇文章中,我将讨论其中的一些用例。
|
||||
|
||||
![][4]
|
||||
|
||||
好吧,为什么要在 Vim 中执行所有操作?因为如果有一个应用程序是我可以访问的每台计算机上都有的,那就是 Vim。如果你像我一样,可能已经在 Vim 中打发了很多时光。那么,为什么不将其用于**所有事情**呢?
|
||||
|
||||
但是,在此之前,你需要做一些事情。首先是确保你的 Vim 具有 Ruby 支持。你可以使用 `vim --version | grep ruby`。如果结果不是 `+ruby`,则需要解决这个问题。这可能有点麻烦,你应该查看发行版的文档以获取正确的软件包。在 MacOS 上,用的是官方的 MacVim(不是 Brew 发行的),在大多数 Linux 发行版中,用的是 vim-nox 或 vim-gtk,而不是 vim-gtk3。
|
||||
|
||||
我使用 [Pathogen][5] 自动加载插件和捆绑软件。如果你使用 [Vundle][6] 或其他 Vim 软件包管理器,则需要调整以下命令才能使用它。
|
||||
|
||||
#### 在 Vim 中管理你的邮件
|
||||
|
||||
使 Vim 在你的生产力计划中发挥更大作用的一个很好的起点是使用它通过 [Notmuch] [7] 发送和接收电子邮件,和使用 [abook] [8] 访问你的联系人列表。你需要为此安装一些东西。下面的所有示例代码都运行在 Ubuntu 上,因此如果你使用其他发行版,则需要对此进行调整。通过以下步骤进行设置:
|
||||
|
||||
```
|
||||
sudo apt install notmuch-vim ruby-mail
|
||||
curl -o ~/.vim/plugin/abook --create-dirs https://raw.githubusercontent.com/dcbaker/vim-abook/master/plugin/abook.vim
|
||||
```
|
||||
|
||||
到目前为止,一切都很顺利。现在启动 Vim 并执行 `:NotMuch`。由于是用较旧版本的邮件库 `notmuch-vim` 编写的,可能会出现一些警告,但总的来说,Vim 现在将成为功能齐全的 Notmuch 邮件客户端。
|
||||
|
||||
![Reading Mail in Vim][9]
|
||||
|
||||
如果要搜索特定标签,请输入 `\t`,输入标签名称,然后按回车。这将拉出一个带有该标签的所有消息的列表。`\s` 组合键会弹出 `Search:` 提示符,可以对 Notmuch 数据库进行全面搜索。使用箭头键浏览消息列表,按回车键显示所选项目,然后输入 `\q` 退出当前视图。
|
||||
|
||||
要撰写邮件,请使用 `\c` 按键。你将看到一条空白消息。这是 `abook.vim` 插件发挥作用的位置。按下 `Esc` 并输入 `:AbookQuery <SomeName>`,其中 `<SomeName>` 是你要查找的名称或电子邮件地址的一部分。你将在 abook 数据库中找到与你的搜索匹配的条目列表。通过键入你想要的地址的编号,将其添加到电子邮件的地址行中。完成电子邮件的键入和编辑,按 `Esc` 退出编辑模式,然后输入 `,s` 发送。
|
||||
|
||||
如果要在 `:NotMuch` 启动时更改默认文件夹视图,则可以将变量 `g:notmuch_folders` 添加到你的 `.vimrc` 文件中:
|
||||
|
||||
```
|
||||
let g:notmuch_folders = [
|
||||
\ [ 'new', 'tag:inbox and tag:unread' ],
|
||||
\ [ 'inbox', 'tag:inbox' ],
|
||||
\ [ 'unread', 'tag:unread' ],
|
||||
\ [ 'News', 'tag:@sanenews' ],
|
||||
\ [ 'Later', 'tag:@sanelater' ],
|
||||
\ [ 'Patreon', 'tag:@patreon' ],
|
||||
\ [ 'LivestockConservancy', 'tag:livestock-conservancy' ],
|
||||
\ ]
|
||||
```
|
||||
|
||||
Notmuch 插件的文档中涵盖了更多设置,包括设置标签键和使用其它的邮件程序。
|
||||
|
||||
#### 在 Vim 中查询日历
|
||||
|
||||
![][10]
|
||||
|
||||
遗憾的是,似乎没有使用 vCalendar 或 iCalendar 格式的 Vim 日历程序。有个 [Calendar.vim][11],做得很好。设置 Vim 通过以下方式访问你的日历:
|
||||
|
||||
```
|
||||
cd ~/.vim/bundle
|
||||
git clone git@github.com:itchyny/calendar.vim.git
|
||||
```
|
||||
|
||||
现在,你可以通过输入 `:Calendar` 在 Vim 中查看日历。你可以使用 `<` 和 `>` 键在年、月、周、日和时钟视图之间切换。如果要从一个特定的视图开始,请使用 `-view=` 标志告诉它你希望看到哪个视图。你也可以在任何视图中定位日期。例如,如果我想查看 2020 年 7 月 4 日这一周的情况,请输入 `:Calendar -view week 7 4 2020`。它的帮助信息非常好,可以使用 `?` 键参看。
|
||||
|
||||
![][13]
|
||||
|
||||
Calendar.vim 还支持 Google Calendar(我需要),但是在 2019 年 12 月,Google 禁用了它的访问权限。作者已在 [GitHub 上的这个提案][14]中发布了一种变通方法。
|
||||
|
||||
这样你就在 Vim 中有了这些:你的邮件、地址簿和日历。但是这些还没有完成; 下一篇你将在 Vim 上做更多的事情!
|
||||
|
||||
Vim 为作家提供了很多好处,无论他们是否具有技术意识。
|
||||
|
||||
需要保持时间表正确吗?了解如何使用这些免费的开源软件来做到这一点。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/vim-email-calendar
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[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://www.vim.org/
|
||||
[3]: https://www.gnu.org/software/emacs/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/day16-image1.png
|
||||
[5]: https://github.com/tpope/vim-pathogen
|
||||
[6]: https://github.com/VundleVim/Vundle.vim
|
||||
[7]: https://opensource.com/article/20/1/organize-email-notmuch
|
||||
[8]: https://opensource.com/article/20/1/sync-contacts-locally
|
||||
[9]: https://opensource.com/sites/default/files/uploads/productivity_16-2.png (Reading Mail in Vim)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/day16-image3.png
|
||||
[11]: https://github.com/itchyny/calendar.vim
|
||||
[12]: mailto:git@github.com
|
||||
[13]: https://opensource.com/sites/default/files/uploads/day16-image4.png
|
||||
[14]: https://github.com/itchyny/calendar.vim/issues/156
|
@ -1,33 +1,32 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (LazyWolfLin)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11867-1.html)
|
||||
[#]: subject: (What's your favorite Linux distribution?)
|
||||
[#]: via: (https://opensource.com/article/20/1/favorite-linux-distribution)
|
||||
[#]: author: (Opensource.com https://opensource.com/users/admin)
|
||||
|
||||
你最喜欢哪个 Linux 发行版?
|
||||
======
|
||||
参与我们的第七届[年度调查][5],让我们了解你对 Linux 发行版的偏好。
|
||||
|
||||
![Hand putting a Linux file folder into a drawer][1]
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/08/004438ei1y4pp44pw4xy3w.jpg)
|
||||
|
||||
你最喜欢哪个 Linux 发行版?参与我们的第七届[年度调查][5]。虽然有所变化,但现在仍有数百种 [Linux 发行版][2] 保持活跃且运作良好。发行版、包管理器和桌面的组合为 Linux 用户创建了无数客制化系统环境。
|
||||
你最喜欢哪个 Linux 发行版?虽然有所变化,但现在仍有数百种 [Linux 发行版][2]保持活跃且运作良好。发行版、包管理器和桌面的组合为 Linux 用户创建了无数客制化系统环境。
|
||||
|
||||
我们询问了社区的作者们,哪个是他们的最爱以及原因。尽管回答中存在一些共性(由于各种原因,Fedora 和 Ubuntu 是最受欢迎的选择),但我们也听到一些惊奇的回答。以下是他们的一些回答:
|
||||
|
||||
“我使用 Fedora 发行版!我喜欢这样的社区,成员们共同创建一个令人敬畏的操作系统,展现了开源软件世界最伟大的造物。”——Matthew Miller
|
||||
> “我使用 Fedora 发行版!我喜欢这样的社区,成员们共同创建一个令人惊叹的操作系统,展现了开源软件世界最伟大的造物。”——Matthew Miller
|
||||
|
||||
“我在家中使用 Arch。作为一名游戏玩家,我希望可以轻松使用最新版本的 Wine 和 GFX 驱动,同时最大限度地掌控我的系统。所以我选择一个滚动升级并且每个包都保持领先的发行版。”——Aimi Hobson
|
||||
> “我在家中使用 Arch。作为一名游戏玩家,我希望可以轻松使用最新版本的 Wine 和 GFX 驱动,同时最大限度地掌控我的系统。所以我选择一个滚动升级并且每个包都保持领先的发行版。”——Aimi Hobson
|
||||
|
||||
“NixOS,在业余爱好者市场中没有比这更合适的。”——Alexander Sosedkin
|
||||
> “NixOS,在业余爱好者市场中没有比这更合适的。”——Alexander Sosedkin
|
||||
|
||||
“我用过每个 Fedora 版本作为我的工作系统。这意味着我从第一个版本开始使用。从前,我问自己是否将有一天我会忘记我用的系统版本号。而这一天已经到来了。所以,现在是什么时候呢?”——Hugh Brock
|
||||
> “我用过每个 Fedora 版本作为我的工作系统。这意味着我从第一个版本开始使用。从前,我问自己是否会忘记我使用的是哪一个版本。而这一天已经到来了,是从什么时候开始忘记了的呢?”——Hugh Brock
|
||||
|
||||
“通常,在我的房屋和办公室里都有运行 Ubuntu、CentOS 和 Fedora 的机器。我依赖这些发行版来完成各种工作。Fedora 用于高性能和获取最新版本的应用和库。Ubuntu 用于那些需要大型支持社区。CentOS 则当我们需要稳如磐石的服务器平台时。”——Steve Morris
|
||||
> “通常,在我的家里和办公室里都有运行 Ubuntu、CentOS 和 Fedora 的机器。我依赖这些发行版来完成各种工作。Fedora 速度很快,而且可以获取最新版本的应用和库。Ubuntu 有大型社区支持,可以轻松使用。CentOS 则当我们需要稳如磐石的服务器平台时。”——Steve Morris
|
||||
|
||||
“我最喜欢?对于社区以及如何为发行版构建软件包(从源码构建而非二进制文件),我选择 Fedora。对于可用包的范围和包的定义和开发,我选择 Debian。对于文档,我选择 Arch。对于新手的提问,我以前会推荐 Ubuntu,而现在会推荐 Fedora。”——Al Stone
|
||||
> “我最喜欢?对于社区以及如何为发行版构建软件包(从源码构建而非二进制文件),我选择 Fedora。对于可用包的范围和包的定义和开发,我选择 Debian。对于文档,我选择 Arch。对于新手的提问,我以前会推荐 Ubuntu,而现在会推荐 Fedora。”——Al Stone
|
||||
|
||||
* * *
|
||||
|
||||
@ -44,7 +43,7 @@ via: https://opensource.com/article/20/1/favorite-linux-distribution
|
||||
作者:[Opensource.com][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[LazyWolfLin](https://github.com/LazyWolfLin)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,106 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11912-1.html)
|
||||
[#]: subject: (Use Vim to manage your task list and access Reddit and Twitter)
|
||||
[#]: via: (https://opensource.com/article/20/1/vim-task-list-reddit-twitter)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用 Vim 管理任务列表和访问 Reddit 和 Twitter
|
||||
======
|
||||
|
||||
> 在 2020 年用开源实现更高生产力的二十种方式的第十七篇文章中,了解在编辑器中处理待办列表以及获取社交信息。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/21/112633yf3mx8qlssltugzm.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 用 Vim 做(几乎)所有事情,第 2 部分
|
||||
|
||||
在[昨天的文章][2]中,你开始用 Vim 检查邮件和日历。今天,你可以做的更多。首先,你会在 Vim 编辑器中跟踪任务,然后获取社交信息。
|
||||
|
||||
#### 使用 todo.txt-vim 在 Vim 中跟踪待办任务
|
||||
|
||||
![to-dos and Twitter with Vim][3]
|
||||
|
||||
使用 Vim 编辑一个文本待办事件是一件自然的事,而 [todo.txt-vim][4] 包使其更加简单。首先安装 todo.txt-vim 包:
|
||||
|
||||
```
|
||||
git clone https://github.com/freitass/todo.txt-vim ~/.vim/bundle/todo.txt-vim
|
||||
vim ~/path/to/your/todo.txt
|
||||
```
|
||||
|
||||
todo.txt-vim 自动识别以 `todo.txt` 和 `done.txt` 结尾的文件作为 [todo.txt][5] 文件。它添加特定于 todo.txt 格式的键绑定。你可以使用 `\x` 标记“已完成”的内容,使用 `\d` 将其设置为当前日期,然后使用 `\a`、`\b` 和 `\c` 更改优先级。你可以提升(`\k`)或降低(`\j`)优先级,并根据项目(`\s+`)、上下文(`\s@`)或日期(`\sd`)排序(`\s`)。完成后,你可以和平常一样关闭和保存文件。
|
||||
|
||||
todo.txt-vim 包是我几天前写的 [todo.sh 程序][6]的一个很好的补充,使用 [todo edit][7] 加载项,它可以增强的你待办事项列表跟踪。
|
||||
|
||||
#### 使用 vim-reddit 读取 Reddit
|
||||
|
||||
![Reddit in Vim][8]
|
||||
|
||||
Vim 还有一个不错的用于 [Reddit][9] 的加载项,叫 [vim-reddit][10]。它不如 [Tuir][11] 好,但是用于快速查看最新的文章,它还是不错的。首先安装捆绑包:
|
||||
|
||||
```
|
||||
git clone https://github.com/DougBeney/vim-reddit.git ~/.vim/bundle/vim-reddit
|
||||
vim
|
||||
```
|
||||
|
||||
现在输入 `:Reddit` 将加载 Reddit 首页。你可以使用 `:Reddit name` 加载特定子板。打开文章列表后,使用箭头键导航或使用鼠标滚动。按 `o` 将在 Vim 中打开文章(除非它多媒体文章,它会打开浏览器),然后按 `c` 打开评论。如果要直接转到页面,请按 `O` 而不是 `o`。只需按 `u` 就能返回。当你 Reddit 看完后,输入 `:bd` 就行。vim-reddit 唯一的缺点是无法登录或发布新文章和评论。话又说回来,有时这是一件好事。
|
||||
|
||||
#### 使用 twitvim 在 Vim 中发推
|
||||
|
||||
![Twitter in Vim][12]
|
||||
|
||||
最后,我们有 [twitvim][13],这是一个于阅读和发布 Twitter 的 Vim 软件包。它需要更多设置。首先从 GitHub 安装 twitvim:
|
||||
|
||||
```
|
||||
git clone https://github.com/twitvim/twitvim.git ~/.vim/bundle/twitvim
|
||||
```
|
||||
|
||||
现在你需要编辑 `.vimrc` 文件并设置一些选项。它帮助插件知道使用哪些库与 Twitter 交互。运行 `vim --version` 并查看哪些语言的前面有 `+` 就代表你的 Vim 支持它。
|
||||
|
||||
![Enabled and Disabled things in vim][14]
|
||||
|
||||
因为我的是 `+perl -python +python3`,所以我知道我可以启用 Perl 和 Python 3 但不是 Python 2 (python)。
|
||||
|
||||
```
|
||||
" TwitVim Settings
|
||||
let twitvim_enable_perl = 1
|
||||
" let twitvim_enable_python = 1
|
||||
let twitvim_enable_python3 = 1
|
||||
```
|
||||
|
||||
现在,你可以通过运行 `:SetLoginTwitter` 启动浏览器窗口,它会打开一个浏览器窗口要求你授权 VimTwit 访问你的帐户。在 Vim 中输入提供的 PIN 后就可以了。
|
||||
|
||||
Twitvim 的命令不像其他包中一样简单。要加载好友和关注者的时间线,请输入 `:FriendsTwitter`。要列出提及你的和回复,请使用 `:MentionsTwitter`。发布新推文是 `:PosttoTwitter <Your message>`。你可以滚动列表并输入 `\r` 回复特定推文,你可以用 `\d` 直接给某人发消息。
|
||||
|
||||
就是这些了。你现在可以在 Vim 中做(几乎)所有事了!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/vim-task-list-reddit-twitter
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_chat_communication_message.png?itok=LKjiLnQu (Chat via email)
|
||||
[2]: https://linux.cn/article-11908-1.html
|
||||
[3]: https://opensource.com/sites/default/files/uploads/productivity_17-1.png (to-dos and Twitter with Vim)
|
||||
[4]: https://github.com/freitass/todo.txt-vim
|
||||
[5]: http://todotxt.org
|
||||
[6]: https://opensource.com/article/20/1/open-source-to-do-list
|
||||
[7]: https://github.com/todotxt/todo.txt-cli/wiki/Todo.sh-Add-on-Directory#edit-open-in-text-editor
|
||||
[8]: https://opensource.com/sites/default/files/uploads/productivity_17-2.png (Reddit in Vim)
|
||||
[9]: https://reddit.com
|
||||
[10]: https://github.com/DougBeney/vim-reddit
|
||||
[11]: https://opensource.com/article/20/1/open-source-reddit-client
|
||||
[12]: https://opensource.com/sites/default/files/uploads/productivity_17-3.png (Twitter in Vim)
|
||||
[13]: https://github.com/twitvim/twitvim
|
||||
[14]: https://opensource.com/sites/default/files/uploads/productivity_17-4.png (Enabled and Disabled things in vim)
|
@ -0,0 +1,146 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11932-1.html)
|
||||
[#]: subject: (Send email and check your calendar with Emacs)
|
||||
[#]: via: (https://opensource.com/article/20/1/emacs-mail-calendar)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用 Emacs 发送电子邮件和检查日历
|
||||
======
|
||||
|
||||
> 在 2020 年用开源实现更高生产力的二十种方式的第十八篇文章中,使用 Emacs 文本编辑器管理电子邮件和查看日程安排。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/26/103647mnee75vxhcc00z06.jpg)
|
||||
|
||||
去年,我给你们带来了 2019 年的 19 天新生产力工具系列。今年,我将采取一种不同的方式:建立一个新的环境,让你使用已用或未用的工具来在新的一年里变得更有效率。
|
||||
|
||||
### 使用 Emacs 做(几乎)所有的事情,第 1 部分
|
||||
|
||||
两天前,我曾经说过我经常使用 [Vim][2] 和 [Emacs][3],在本系列的 [16][4] 和 [17][5] 天,我讲解了如何在 Vim 中做几乎所有的事情。现在,Emacs 的时间到了!
|
||||
|
||||
![Emacs 中的邮件和日历][6]
|
||||
|
||||
在深入之前,我需要说明两件事。首先,我这里使用默认的 Emacs 配置,而不是我之前[写过][8]的 [Spacemacs][7]。为什么呢?因为这样一来我使用的就是默认快捷键,从而使你可以参考文档,而不必将“原生的 Emacs” 转换为 Spacemacs。第二,在本系列文章中我没有对 Org 模式进行任何设置。Org 模式本身几乎可以自成一个完整的系列,它非常强大,但是设置可能非常复杂。
|
||||
|
||||
#### 配置 Emacs
|
||||
|
||||
配置 Emacs 比配置 Vim 稍微复杂一些,但以我之见,从长远来看,这样做是值得的。首先我们创建一个配置文件,并在 Emacs 中打开它:
|
||||
|
||||
```
|
||||
mkdir ~/.emacs.d
|
||||
emacs ~/.emacs.d/init.el
|
||||
```
|
||||
|
||||
接下来,向内置的包管理器添加一些额外的包源。在 `init.el` 中添加以下内容:
|
||||
|
||||
```
|
||||
(package-initialize)
|
||||
(add-to-list 'package-archives '("melpa" . "<http://melpa.org/packages/>"))
|
||||
(add-to-list 'package-archives '("org" . "<http://orgmode.org/elpa/>") t)
|
||||
(add-to-list 'package-archives '("gnu" . "<https://elpa.gnu.org/packages/>"))
|
||||
(package-refresh-contents)
|
||||
```
|
||||
|
||||
使用 `Ctrl+x Ctrl+s` 保存文件,然后按下 `Ctrl+x Ctrl+c` 退出,再重启 Emacs。Emacs 会在启动时下载所有的插件包列表,之后你就可以使用内置的包管理器安装插件了。输入 `Meta+x` 会弹出命令提示符(大多数键盘上 `Meta` 键就是的 `Alt` 键,而在 MacOS 上则是 `Option`)。在命令提示符下输入 `package-list-packages` 就会显示可以安装的包列表。遍历该列表并使用 `i` 键选择以下包:
|
||||
|
||||
```
|
||||
bbdb
|
||||
bbdb-vcard
|
||||
calfw
|
||||
calfw-ical
|
||||
notmuch
|
||||
```
|
||||
|
||||
选好软件包后按 `x` 安装它们。根据你的网络连接情况,这可能需要一段时间。你也许会看到一些编译错误,但是可以忽略它们。安装完成后,使用组合键 `Ctrl+x Ctrl+f` 打开 `~/.emacs.d/init.el`,并在 `(package-refresh-packages)` 之后、 `(custom-set-variables` 之前添加以下行到文件中。
|
||||
`(custom-set-variables` 行由 Emacs 内部维护,你永远不应该修改它之后的任何内容。以 `;;` 开头的行则是注释。
|
||||
|
||||
```
|
||||
;; Set up bbdb
|
||||
(require 'bbdb)
|
||||
(bbdb-initialize 'message)
|
||||
(bbdb-insinuate-message)
|
||||
(add-hook 'message-setup-hook 'bbdb-insinuate-mail)
|
||||
;; set up calendar
|
||||
(require 'calfw)
|
||||
(require 'calfw-ical)
|
||||
;; Set this to the URL of your calendar. Google users will use
|
||||
;; the Secret Address in iCalendar Format from the calendar settings
|
||||
(cfw:open-ical-calendar "<https://path/to/my/ics/file.ics>")
|
||||
;; Set up notmuch
|
||||
(require 'notmuch)
|
||||
;; set up mail sending using sendmail
|
||||
(setq send-mail-function (quote sendmail-send-it))
|
||||
(setq user-mail-address "[myemail@mydomain.com][9]"
|
||||
user-full-name "My Name")
|
||||
```
|
||||
|
||||
现在,你已经准备好使用自己的配置启动 Emacs 了!保存 `init.el` 文件(`Ctrl+x Ctrl+s`),退出 Emacs(`Ctrl+x Ctrl+c`),然后重启之。这次重启要多花些时间。
|
||||
|
||||
#### 使用 Notmuch 在 Emacs 中读写电子邮件
|
||||
|
||||
一旦你看到了 Emacs 启动屏幕,你就可以使用 [Notmuch][10] 来阅读电子邮件了。键入 `Meta+x notmuch`,你将看到 notmuch 的 Emacs 界面。
|
||||
|
||||
![使用 notmuch 阅读邮件][11]
|
||||
|
||||
所有加粗的项目都是指向电子邮件视图的链接。你可以通过点击鼠标或者使用 `tab` 键在它们之间跳转并按回车来访问它们。你可以使用搜索栏来搜索 Notmuch 的数据库,语法与 Notmuch 命令行上的[语法][12] 相同。如果你愿意,还可以使用 `[save]` 按钮保存搜索以便未来使用,这些搜索会被添加到屏幕顶部的列表中。如果你进入一个链接就会看到一个相关电子邮件的列表。你可以使用箭头键在列表中导航,并在要读取的消息上按回车。按 `r` 可以回复一条消息,`f` 转发该消息,`q` 退出当前屏幕。
|
||||
|
||||
你可以通过键入 `Meta+x compose-mail` 来编写新消息。撰写、回复和转发都将打开编写邮件的界面。写完邮件后,按 `Ctrl+c Ctrl+c` 发送。如果你决定不发送它,按 `Ctrl+c Ctrl+k` 关闭消息撰写缓冲区(窗口)。
|
||||
|
||||
#### 使用 BBDB 在 Emacs 中自动补完电子邮件地址
|
||||
|
||||
![在消息中使用 BBDB 地址][13]
|
||||
|
||||
那么通讯录怎么办?这就是 [BBDB][14] 发挥作用的地方。但首先我们需要从 [abook][15] 导入所有地址,方法是打开命令行并运行以下导出命令:
|
||||
|
||||
```
|
||||
abook --convert --outformat vcard --outfile ~/all-my-addresses.vcf --infile ~/.abook/addresses
|
||||
```
|
||||
|
||||
Emacs 启动后,运行 `Meta+x bbdb-vcard-import-file`。它将提示你输入要导入的文件名,即 `~/all-my-address.vcf`。导入完成后,在编写消息时,可以开始输入名称并使用 `Tab` 搜索和自动完成 “to” 字段的内容。BBDB 还会打开一个联系人缓冲区,以便你确保它是正确的。
|
||||
|
||||
既然在 [vdirsyncer][16] 中已经为每个地址都生成了对应的 .vcf 文件了,为什么我们还要这样做呢?如果你像我一样,有许多地址,一次处理一个地址是很麻烦的。这样做,你就可以把所有的东西都放在 abook 里,做成一个大文件。
|
||||
|
||||
#### 使用 calfw 在 Emacs 中浏览日历
|
||||
|
||||
![calfw 日历 ][17]
|
||||
|
||||
最后,你可以使用 Emacs 查看日历。在上面的配置中,你安装了 [calfw][18] 包,并添加了一些行来告诉它在哪里可以找到要加载的日历。Calfw 是 “<ruby>Emacs 日历框架<rt>Calendar Framework for Emacs</rt></ruby>”的简称,它支持多种日历格式。我使用的是谷歌日历,这也是我放在配置中的链接。日历将在启动时自动加载,你可以通过 `Ctrl+x+b` 命令切换到 cfw-calendar 缓冲区来查看日历。
|
||||
|
||||
Calfw 提供日、周、双周和月视图。你可以在日历顶部选择视图,并使用箭头键导航日历。不幸的是,calfw 只能查看日历,所以你仍然需要使用 [khal][19] 之类的工具或通过 web 界面来添加、删除和修改事件。
|
||||
|
||||
这就是 Emacs 中的邮件、日历和邮件地址。明天我会展示更多。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/emacs-mail-calendar
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_paper_envelope_document.png?itok=uPj_kouJ (Document sending)
|
||||
[2]: https://www.vim.org/
|
||||
[3]: https://www.gnu.org/software/emacs/
|
||||
[4]: https://linux.cn/article-11908-1.html
|
||||
[5]: https://linux.cn/article-11912-1.html
|
||||
[6]: https://opensource.com/sites/default/files/uploads/productivity_18-1.png (Mail and calendar in Emacs)
|
||||
[7]: https://www.spacemacs.org/
|
||||
[8]: https://opensource.com/article/19/12/spacemacs
|
||||
[9]: mailto:myemail@mydomain.com
|
||||
[10]: https://notmuchmail.org/
|
||||
[11]: https://opensource.com/sites/default/files/uploads/productivity_18-2.png (Reading mail with Notmuch)
|
||||
[12]: https://linux.cn/article-11807-1.html
|
||||
[13]: https://opensource.com/sites/default/files/uploads/productivity_18-3.png (Composing a message with BBDB addressing)
|
||||
[14]: https://www.jwz.org/bbdb/
|
||||
[15]: https://linux.cn/article-11834-1.html
|
||||
[16]: https://linux.cn/article-11812-1.html
|
||||
[17]: https://opensource.com/sites/default/files/uploads/productivity_18-4.png (calfw calendar)
|
||||
[18]: https://github.com/kiwanami/emacs-calfw
|
||||
[19]: https://khal.readthedocs.io/en/v0.9.2/index.html
|
@ -0,0 +1,101 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11863-1.html)
|
||||
[#]: subject: (4 cool new projects to try in COPR for January 2020)
|
||||
[#]: via: (https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january-2020/)
|
||||
[#]: author: (Dominik Turecek https://fedoramagazine.org/author/dturecek/)
|
||||
|
||||
COPR 仓库中 4 个很酷的新项目(2020.01)
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
COPR 是个人软件仓库[集合][2],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
|
||||
本文介绍了 COPR 中一些有趣的新项目。如果你第一次使用 COPR,请参阅 [COPR 用户文档][3]。
|
||||
|
||||
### Contrast
|
||||
|
||||
[Contrast][4] 是一款小应用,用于检查两种颜色之间的对比度并确定其是否满足 [WCAG][5] 中指定的要求。可以使用十六进制 RGB 代码或使用颜色选择器选择颜色。除了显示对比度之外,Contrast 还以选定的颜色为背景上显示短文本来显示比较。
|
||||
|
||||
![][6]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[仓库][7]当前为 Fedora 31 和 Rawhide 提供了 Contrast。要安装 Contrast,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable atim/contrast
|
||||
sudo dnf install contrast
|
||||
```
|
||||
|
||||
### Pamixer
|
||||
|
||||
[Pamixer][8] 是一个使用 PulseAudio 调整和监控声音设备音量的命令行工具。你可以显示设备的当前音量并直接增加/减小它,或静音/取消静音。Pamixer 可以列出所有源和接收器。
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[仓库][7]当前为 Fedora 31 和 Rawhide 提供了 Pamixer。要安装 Pamixer,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable opuk/pamixer
|
||||
sudo dnf install pamixer
|
||||
```
|
||||
|
||||
### PhotoFlare
|
||||
|
||||
[PhotoFlare][10] 是一款图像编辑器。它有简单且布局合理的用户界面,其中的大多数功能都可在工具栏中使用。尽管它不支持使用图层,但 PhotoFlare 提供了诸如各种颜色调整、图像变换、滤镜、画笔和自动裁剪等功能。此外,PhotoFlare 可以批量编辑图片,来对所有图片应用相同的滤镜和转换,并将结果保存在指定目录中。
|
||||
|
||||
![][11]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[仓库][7]当前为 Fedora 31 提供了 PhotoFlare。要安装 PhotoFlare,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable adriend/photoflare
|
||||
sudo dnf install photoflare
|
||||
```
|
||||
|
||||
### Tdiff
|
||||
|
||||
[Tdiff][13] 是用于比较两个文件树的命令行工具。除了显示某些文件或目录仅存在于一棵树中之外,tdiff 还显示文件大小、类型和内容,所有者用户和组 ID、权限、修改时间等方面的差异。
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[仓库][7]当前为 Fedora 29-31、Rawhide、EPEL 6-8 和其他发行版提供了 tdiff。要安装 tdiff,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable fif/tdiff
|
||||
sudo dnf install tdiff
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january-2020/
|
||||
|
||||
作者:[Dominik Turecek][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/dturecek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg
|
||||
[2]: https://copr.fedorainfracloud.org/
|
||||
[3]: https://docs.pagure.org/copr.copr/user_documentation.html#
|
||||
[4]: https://gitlab.gnome.org/World/design/contrast
|
||||
[5]: https://www.w3.org/WAI/standards-guidelines/wcag/
|
||||
[6]: https://fedoramagazine.org/wp-content/uploads/2020/01/contrast-screenshot.png
|
||||
[7]: https://copr.fedorainfracloud.org/coprs/atim/contrast/
|
||||
[8]: https://github.com/cdemoulins/pamixer
|
||||
[9]: https://copr.fedorainfracloud.org/coprs/opuk/pamixer/
|
||||
[10]: https://photoflare.io/
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2020/01/photoflare-screenshot.png
|
||||
[12]: https://copr.fedorainfracloud.org/coprs/adriend/photoflare/
|
||||
[13]: https://github.com/F-i-f/tdiff
|
||||
[14]: https://copr.fedorainfracloud.org/coprs/fif/tdiff/
|
@ -0,0 +1,113 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11896-1.html)
|
||||
[#]: subject: (Joplin: The True Open Source Evernote Alternative)
|
||||
[#]: via: (https://itsfoss.com/joplin/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Joplin:真正的 Evernote 开源替代品
|
||||
======
|
||||
|
||||
> Joplin 是一个开源笔记记录和待办应用。你可以将笔记组织到笔记本中并标记它们。Joplin 还提供网络剪贴板来保存来自互联网的文章。
|
||||
|
||||
### Joplin:开源笔记管理器
|
||||
|
||||
![][4]
|
||||
|
||||
如果你喜欢 [Evernote][2],那么你不会不太适应这个开源软件 [Joplin][3]。
|
||||
|
||||
Joplin 是一个优秀的开源笔记应用,拥有丰富的功能。你可以记笔记、记录待办事项并且通过和 Dropbox 和 NextCloud 等云服务链接来跨设备同步笔记。同步过程通过端到端加密保护。
|
||||
|
||||
Joplin 还有一个 Web 剪贴板,能让你将网页另存为笔记。这个网络剪贴板可用于 Firefox 和 Chrome/Chromium 浏览器。
|
||||
|
||||
Joplin 可以导入 enex 格式的 Evernote 文件,这让从 Evernote 切换变得容易。
|
||||
|
||||
因为数据自行保存,所以你可以用 Joplin 格式或者原始格式导出所有文件。
|
||||
|
||||
### Joplin 的功能
|
||||
|
||||
![][1]
|
||||
|
||||
以下是 Joplin 的所有功能列表:
|
||||
|
||||
* 将笔记保存到笔记本和子笔记本中,以便更好地组织
|
||||
* 创建待办事项清单
|
||||
* 可以标记和搜索笔记
|
||||
* 离线优先,因此即使没有互联网连接,所有数据始终在设备上可用
|
||||
* Markdown 笔记支持图片、数学符号和复选框
|
||||
* 支持附件
|
||||
* 可在桌面、移动设备和终端(CLI)使用
|
||||
* 可在 Firefox 和 Chrome 使用[网页剪切板][5]
|
||||
* 端到端加密
|
||||
* 保留笔记历史
|
||||
* 根据名称、时间等对笔记进行排序
|
||||
* 可与 [Nextcloud][7]、Dropbox、WebDAV 和 OneDrive 等各种[云服务][6]同步
|
||||
* 从 Evernote 导入文件
|
||||
* 导出 JEX 文件(Joplin 导出格式)和原始文件
|
||||
* 支持笔记、待办事项、标签和笔记本
|
||||
* 任意跳转功能
|
||||
* 支持移动设备和桌面应用通知
|
||||
* 地理位置支持
|
||||
* 支持多种语言
|
||||
* 外部编辑器支持:在 Joplin 中一键用你最喜欢的编辑器打开笔记
|
||||
|
||||
### 在 Linux 和其它平台上安装 Joplin
|
||||
|
||||
![][10]
|
||||
|
||||
[Joplin][11] 是一个跨平台应用,可用于 Linux、macOS 和 Windows。在移动设备上,你可以[获取 APK 文件][12]将其安装在 Android 和基于 Android 的 ROM 上。你也可以[从谷歌 Play 商店下载][13]。
|
||||
|
||||
在 Linux 中,你可以获取 Joplin 的 [AppImage][14] 文件,并作为可执行文件运行。你需要为下载的文件授予执行权限。
|
||||
|
||||
- [下载 Joplin][15]
|
||||
|
||||
### 体验 Joplin
|
||||
|
||||
Joplin 中的笔记使用 Markdown,但你不需要了解它。编辑器的顶部面板能让你以图形方式选择项目符号、标题、图像、链接等。
|
||||
|
||||
虽然 Joplin 提供了许多有趣的功能,但你需要自己去尝试。例如,默认情况下未启用 Web 剪切板,我需要发现如何打开它。
|
||||
|
||||
你需要从桌面应用启用剪切板。在顶部菜单中,进入 “Tools->Options”。你可以在此处找到 Web 剪切板选项:
|
||||
|
||||
![Enable Web Clipper from the desktop application first][16]
|
||||
|
||||
它的 Web 剪切板不如 Evernote 的 Web 剪切板聪明,后者可以以图形方式剪辑网页文章的一部分。但是,也足够了。
|
||||
|
||||
这是一个在活跃开发中的开源软件,我希望它随着时间的推移得到更多的改进。
|
||||
|
||||
### 总结
|
||||
|
||||
如果你正在寻找一个不错的拥有 Web 剪切板的笔记应用,你可以试试 Joplin。如果你喜欢它,并将继续使用,尝试通过捐赠或改进代码和文档来帮助 Joplin 开发。我以 FOSS 的名义[捐赠][17]了 25 欧。
|
||||
|
||||
如果你曾经使用过 Joplin,或者仍在使用它,你对此的体验如何?如果你用的是其他笔记应用,你会切换到 Joplin 么?欢迎分享你的观点。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/joplin/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/joplin_logo.png?ssl=1
|
||||
[2]: https://evernote.com/
|
||||
[3]: https://joplinapp.org/
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/01/joplin_featured.jpg?ssl=1
|
||||
[5]: https://joplinapp.org/clipper/
|
||||
[6]: https://itsfoss.com/cloud-services-linux/
|
||||
[7]: https://nextcloud.com/
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/joplin_ubuntu.jpg?ssl=1
|
||||
[11]: https://github.com/laurent22/joplin
|
||||
[12]: https://itsfoss.com/download-apk-ubuntu/
|
||||
[13]: https://play.google.com/store/apps/details?id=net.cozic.joplin&hl=en_US
|
||||
[14]: https://itsfoss.com/use-appimage-linux/
|
||||
[15]: https://github.com/laurent22/joplin/releases
|
||||
[16]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/01/joplin_web_clipper.jpg?ssl=1
|
||||
[17]: https://itsfoss.com/donations-foss/
|
@ -0,0 +1,92 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11915-1.html)
|
||||
[#]: subject: (Meet FuryBSD: A New Desktop BSD Distribution)
|
||||
[#]: via: (https://itsfoss.com/furybsd/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
认识 FuryBSD:一个新的桌面 BSD 发行版
|
||||
======
|
||||
|
||||
在过去的几个月中,出现了一些新的桌面 BSD。之前有 [HyperbolaBSD,它之前是 Hyperbola GNU/Linux][1]。[BSD][2] 世界中的另一个新入者是 [FuryBSD][3]。
|
||||
|
||||
### FuryBSD:一个新的 BSD 发行版
|
||||
|
||||
![][4]
|
||||
|
||||
从本质上讲,FuryBSD 是一个非常简单的小东西。根据[它的网站][5]:“FuryBSD 一个是基于 FreeBSD 的轻量级桌面发行版。” 它基本上是预配置了桌面环境,并预安装了多个应用的 FreeBSD。目地是快速地在你的计算机上运行基于 FreeBSD 的系统。
|
||||
|
||||
你可能会认为这听起来很像其他几个已有的 BSD,例如 [NomadBSD][6] 和 [GhostBSD][7]。这些 BSD 与 FuryBSD 之间的主要区别在于 FuryBSD 与现有的 FreeBSD 更加接近。例如,FuryBSD 使用 FreeBSD 安装程序,而其他发行版则用了自己的安装程序和工具。
|
||||
|
||||
正如[它的网站][8]所说:“尽管 FuryBSD 可能类似于 PC-BSD 和 TrueOS 等图形化 BSD 项目,但 FuryBSD 是由不同的团队创建的,并且采用了不同与 FreeBSD 着重于紧密集成的方法。这样可以降低开销,并保持与上游的兼容性。”开发负责人还告诉我:“FuryBSD 的一个主要重点是使其成为一种小型现场版介质,并带有一些测试硬件驱动程序的辅助工具。”
|
||||
|
||||
当前,你可以进入 [FuryBSD 主页][3]并下载 XFCE 或 KDE 的 LiveCD。GNOME 版本正在开发中。
|
||||
|
||||
### FuryBSD 的背后是谁
|
||||
|
||||
FuryBSD 的主要开发者是 [Joe Maloney][9]。Joe 多年来一直是 FreeBSD 的用户。他为 PC-BSD 等其他 BSD 项目做过贡献。他还与 GhostBSD 的创建者 Eric Turgeon 一起重写了 GhostBSD LiveCD。在此过程中,他对 BSD 有了更好的了解,并开始形成自己如何做一个发行版的想法。
|
||||
|
||||
Joe 与其他参与 BSD 世界多年的开发者一起加入了开发,例如 Jaron Parsons、Josh Smith 和 Damian Szidiropulosz。
|
||||
|
||||
### FuryBSD 的未来
|
||||
|
||||
目前,FuryBSD 仅仅是预配置的 FreeBSD。但是,开发者有一份[要改进的清单][5]。包括:
|
||||
|
||||
* 可靠的加载框架、第三方专有图形驱动、无线网络
|
||||
* 进一步整理 LiveCD 体验,以使其更加友好
|
||||
* 开箱即用的打印支持
|
||||
* 包含更多默认应用,以提供完整的桌面体验
|
||||
* 集成的 [ZFS][10] 复制工具,用于备份和还原
|
||||
* Live 镜像持久化选项
|
||||
* 默认自定义 pkg 仓库
|
||||
* 用于应用更新的持续集成
|
||||
* 桌面 FreeBSD 的质量保证
|
||||
* 自定义、色彩方案和主题
|
||||
* 目录服务集成
|
||||
* 安全加固
|
||||
|
||||
开发者非常清楚地表明,他们所做的任何更改都需要大量的思考和研究。他们不会改进某个功能,只会在它破坏一些东西时删除或者修改它。
|
||||
|
||||
![FuryBSD desktop][11]
|
||||
|
||||
### 你可以如何帮助 FuryBSD?
|
||||
|
||||
目前,该项目还很年轻。由于所有项目都需要帮助才能生存,所以我问 Joe 他们正在寻求什么样的帮助。他说:“我们可以帮助[在论坛上回答问题][12]、回答 [GitHub][13] 上的问题,完善文档。”他还说如果人们想增加对其他桌面环境的支持,欢迎发起拉取请求。
|
||||
|
||||
### 最后的想法
|
||||
|
||||
尽管我还没有尝试过,但是我对 FuryBSD 感觉不错。听起来项目在掌握中。十多年来,Joe Maloney 一直在思考如何达到最佳的 BSD 桌面体验。与大多数 Linux 发行版基本上都是经过重新设计的 Ubuntu 不同,FuryBSD 背后的开发者知道他们在做什么,并且他们在更看重质量而不是花哨的功能。
|
||||
|
||||
你对这个在不断增长的桌面 BSD 市场的新入者怎么看?你尝试过 FuryBSD 或者会尝试一下吗?请在下面的评论中告诉我们。
|
||||
|
||||
如果你觉得这篇文章有趣,请在 Hacker News 或 [Reddit][14] 等社交媒体上分享它。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/furybsd/
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/hyperbola-linux-bsd/
|
||||
[2]: https://itsfoss.com/bsd/
|
||||
[3]: https://www.furybsd.org/
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/fury-bsd.jpg?ssl=1
|
||||
[5]: https://www.furybsd.org/manifesto/
|
||||
[6]: https://itsfoss.com/nomadbsd/
|
||||
[7]: https://ghostbsd.org/
|
||||
[8]: https://www.furybsd.org/furybsd-video-overview-at-knoxbug/
|
||||
[9]: https://github.com/pkgdemon
|
||||
[10]: https://itsfoss.com/what-is-zfs/
|
||||
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/FuryBSDS-desktop.jpg?resize=800%2C450&ssl=1
|
||||
[12]: https://forums.furybsd.org/
|
||||
[13]: https://github.com/furybsd
|
||||
[14]: https://reddit.com/r/linuxusersgroup
|
87
published/202002/20200131 Intro to the Linux command line.md
Normal file
87
published/202002/20200131 Intro to the Linux command line.md
Normal file
@ -0,0 +1,87 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (qianmingtian)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11864-1.html)
|
||||
[#]: subject: (Intro to the Linux command line)
|
||||
[#]: via: (https://www.networkworld.com/article/3518440/intro-to-the-linux-command-line.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
Linux 命令行简介
|
||||
======
|
||||
|
||||
> 下面是一些针对刚开始使用 Linux 命令行的人的热身练习。警告:它可能会上瘾。
|
||||
|
||||
![](https://images.idgesg.net/images/article/2020/01/cmd_linux-control_linux-logo_-100828420-large.jpg)
|
||||
|
||||
如果你是 Linux 新手,或者从来没有花时间研究过命令行,你可能不会理解为什么这么多 Linux 爱好者坐在舒适的桌面前兴奋地输入命令来使用大量工具和应用。在这篇文章中,我们将快速浏览一下命令行的奇妙之处,看看能否让你着迷。
|
||||
|
||||
首先,要使用命令行,你必须打开一个命令工具(也称为“命令提示符”)。如何做到这一点将取决于你运行的 Linux 版本。例如,在 RedHat 上,你可能会在屏幕顶部看到一个 “Activities” 选项卡,它将打开一个选项列表和一个用于输入命令的小窗口(类似 “cmd” 为你打开的窗口)。在 Ubuntu 和其他一些版本中,你可能会在屏幕左侧看到一个小的终端图标。在许多系统上,你可以同时按 `Ctrl+Alt+t` 键打开命令窗口。
|
||||
|
||||
如果你使用 PuTTY 之类的工具登录 Linux 系统,你会发现自己已经处于命令行界面。
|
||||
|
||||
一旦你得到你的命令行窗口,你会发现自己坐在一个提示符面前。它可能只是一个 `$` 或者像 `user@system:~$` 这样的东西,但它意味着系统已经准备好为你运行命令了。
|
||||
|
||||
一旦你走到这一步,就应该开始输入命令了。下面是一些要首先尝试的命令,以及这里是一些特别有用的命令的 [PDF][4] 和适合打印和做成卡片的双面命令手册。
|
||||
|
||||
|
||||
| 命令 | 用途 |
|
||||
|---|---|
|
||||
| `pwd` | 显示我在文件系统中的位置(在最初进入系统时运行将显示主目录) |
|
||||
| `ls` | 列出我的文件 |
|
||||
| `ls -a` | 列出我更多的文件(包括隐藏文件) |
|
||||
| `ls -al` | 列出我的文件,并且包含很多详细信息(包括日期、文件大小和权限) |
|
||||
| `who` | 告诉我谁登录了(如果只有你,不要失望) |
|
||||
| `date` | 日期提醒我今天是星期几(也显示时间) |
|
||||
| `ps` | 列出我正在运行的进程(可能只是你的 shell 和 `ps` 命令) |
|
||||
|
||||
一旦你从命令行角度习惯了 Linux 主目录之后,就可以开始探索了。也许你会准备好使用以下命令在文件系统中闲逛:
|
||||
|
||||
| 命令 | 用途 |
|
||||
|---|---|
|
||||
| `cd /tmp` | 移动到其他文件夹(本例中,打开 `/tmp` 文件夹) |
|
||||
| `ls` | 列出当前位置的文件 |
|
||||
| `cd` | 回到主目录(不带参数的 `cd` 总是能将你带回到主目录) |
|
||||
| `cat .bashrc` | 显示文件的内容(本例中显示 `.bashrc` 文件的内容) |
|
||||
| `history` | 显示最近执行的命令 |
|
||||
| `echo hello` | 跟自己说 “hello” |
|
||||
| `cal` | 显示当前月份的日历 |
|
||||
|
||||
要了解为什么高级 Linux 用户如此喜欢命令行,你将需要尝试其他一些功能,例如重定向和管道。“重定向”是当你获取命令的输出并将其放到文件中而不是在屏幕上显示时。“管道”是指你将一个命令的输出发送给另一条将以某种方式对其进行操作的命令。这是可以尝试的命令:
|
||||
|
||||
| 命令 | 用途 |
|
||||
|---|---|
|
||||
| `echo "echo hello" > tryme` | 创建一个新的文件并将 “echo hello” 写入该文件 |
|
||||
| `chmod 700 tryme` | 使新建的文件可执行 |
|
||||
| `tryme` | 运行新文件(它应当运行文件中包含的命令并且显示 “hello” )|
|
||||
| `ps aux` | 显示所有运行中的程序 |
|
||||
| `ps aux | grep $USER` | 显示所有运行中的程序,但是限制输出的内容包含你的用户名 |
|
||||
| `echo $USER` | 使用环境变量显示你的用户名 |
|
||||
| `whoami` | 使用命令显示你的用户名 |
|
||||
| `who | wc -l` | 计数所有当前登录的用户数目 |
|
||||
|
||||
### 总结
|
||||
|
||||
一旦你习惯了基本命令,就可以探索其他命令并尝试编写脚本。 你可能会发现 Linux 比你想象的要强大并且好用得多.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3518440/intro-to-the-linux-command-line.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[qianmingtian][c]
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[c]: https://github.com/qianmingtian
|
||||
[1]: https://commons.wikimedia.org/wiki/File:Tux.svg
|
||||
[2]: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
[3]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE21620&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage)
|
||||
[4]: https://www.networkworld.com/article/3391029/must-know-linux-commands.html
|
||||
[5]: https://www.networkworld.com/newsletters/signup.html
|
||||
[6]: https://www.facebook.com/NetworkWorld/
|
||||
[7]: https://www.linkedin.com/company/network-world
|
@ -1,20 +1,20 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (LazyWolfLin)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11853-1.html)
|
||||
[#]: subject: (4 Key Changes to Look Out for in Linux Kernel 5.6)
|
||||
[#]: via: (https://itsfoss.com/linux-kernel-5-6/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
四大亮点带你看 Linux Kernel 5.6
|
||||
四大亮点带你看 Linux 内核 5.6
|
||||
======
|
||||
|
||||
当我们体验 Linux 5.5 稳定发行版带来更好的硬件支持时,Linux 5.6 已经来了。
|
||||
当我们还在体验 Linux 5.5 稳定发行版带来更好的硬件支持时,Linux 5.6 已经来了。
|
||||
|
||||
说实话,Linux 5.6 比 5.5 更令人兴奋。即使即将发布的 Ubuntu 20.04 LTS 发行版将开箱集成 Linux 5.5,你也需要真正了解 Linux 5.6 kernel 为我们提供了什么。
|
||||
说实话,Linux 5.6 比 5.5 更令人兴奋。即使即将发布的 Ubuntu 20.04 LTS 发行版将自带 Linux 5.5,你也需要切实了解一下 Linux 5.6 内核为我们提供了什么。
|
||||
|
||||
我将在本文中重点介绍 Linux 5.6 发行版中值得期待的关键更改和功能:
|
||||
我将在本文中重点介绍 Linux 5.6 发布版中值得期待的关键更改和功能:
|
||||
|
||||
### Linux 5.6 功能亮点
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
当 Linux 5.6 有新消息时,我会努力更新这份功能列表。但现在让我们先看一下当前已知的内容:
|
||||
|
||||
#### 1\. 支持 WireGuard
|
||||
#### 1、支持 WireGuard
|
||||
|
||||
WireGuard 将被添加到 Linux 5.6,出于各种原因的考虑它可能将取代 [OpenVPN][2]。
|
||||
|
||||
@ -30,44 +30,44 @@ WireGuard 将被添加到 Linux 5.6,出于各种原因的考虑它可能将取
|
||||
|
||||
同样,[Ubuntu 20.04 LTS 将支持 WireGuard][4]。
|
||||
|
||||
#### 2\. 支持 USB4
|
||||
#### 2、支持 USB4
|
||||
|
||||
Linux 5.6 也将支持 **USB4**。
|
||||
|
||||
如果你不了解 USB 4.0 (USB4),你可以阅读这份[文档][5].
|
||||
如果你不了解 USB 4.0 (USB4),你可以阅读这份[文档][5]。
|
||||
|
||||
根据文档,“_USB4 将使 USB 的最大带宽增大一倍并支持同时多数据和显示接口并行。_”
|
||||
根据文档,“USB4 将使 USB 的最大带宽增大一倍并支持<ruby>多并发数据和显示协议<rt>multiple simultaneous data and display protocols</rt></ruby>。”
|
||||
|
||||
另外,虽然我们都知道 USB4 基于 Thunderbolt 接口协议,但它将向后兼容 USB 2.0、USB 3.0 以及 Thunderbolt 3,这将是一个好消息。
|
||||
|
||||
#### 3\. 使用 LZO/LZ4 压缩 F2FS 数据
|
||||
#### 3、使用 LZO/LZ4 压缩 F2FS 数据
|
||||
|
||||
Linux 5.6 也将支持使用LZO/LZ4 算法压缩 F2FS 数据。
|
||||
Linux 5.6 也将支持使用 LZO/LZ4 算法压缩 F2FS 数据。
|
||||
|
||||
换句话说,这只是 Linux 文件系统的一种新压缩技术,你可以选择待定的文件扩展名。
|
||||
换句话说,这只是 Linux 文件系统的一种新压缩技术,你可以选择待定的文件扩展技术。
|
||||
|
||||
#### 4\. 解决 32 位系统的 2038 年问题
|
||||
#### 4、解决 32 位系统的 2038 年问题
|
||||
|
||||
Unix 和 Linux 将时间值以 32 位有符号整数格式存储,其最大值为 2147483647。时间值如果超过这个数值则将由于整数溢出而存储为负数。
|
||||
|
||||
这意味着对于32位系统,时间值不能超过 1970 年 1 月 1 日后的 2147483647 秒。也就是说,在 UTC 时间 2038 年 1 月 19 日 03:14:07 时,由于整数溢出,时间将显示为 1901 年 12 月 13 日而不是 2038 年 1 月 19 日。
|
||||
这意味着对于 32 位系统,时间值不能超过 1970 年 1 月 1 日后的 2147483647 秒。也就是说,在 UTC 时间 2038 年 1 月 19 日 03:14:07 时,由于整数溢出,时间将显示为 1901 年 12 月 13 日而不是 2038 年 1 月 19 日。
|
||||
|
||||
Linux kernel 5.6 解决了这个问题,因此 32 位系统可以运行到 2038 年以后。
|
||||
Linux kernel 5.6 解决了这个问题,因此 32 位系统也可以运行到 2038 年以后。
|
||||
|
||||
#### 5\. 改进硬件支持
|
||||
#### 5、改进硬件支持
|
||||
|
||||
很显然,在下一次发布版中,硬件支持也将继续提升。而支持新式无线外设的计划也同样紧迫。
|
||||
很显然,在下一个发布版中,硬件支持也将继续提升。而支持新式无线外设的计划也同样是优先的。
|
||||
|
||||
新内核中将增加对 MX Master 3 鼠标以及罗技其他无线产品的支持。
|
||||
|
||||
除了罗技的产品外,你还可以期待获得许多不同硬件的支持(包括对 AMD GPUs、NVIDIA GPUs 和 Intel Tiger Lake 芯片组的支持)。
|
||||
除了罗技的产品外,你还可以期待获得许多不同硬件的支持(包括对 AMD GPU、NVIDIA GPU 和 Intel Tiger Lake 芯片组的支持)。
|
||||
|
||||
#### 6\. 其他更新
|
||||
#### 6、其他更新
|
||||
|
||||
此外,Linux 5.6 中除了上述主要的新增功能或支持外,下一个内核版本也将进行其他一些改进:
|
||||
|
||||
* 改进 AMD Zen 的温度/功率报告
|
||||
* 修复华硕飞行堡垒系列笔记本中 AMD CPUs 过热
|
||||
* 修复华硕飞行堡垒系列笔记本中 AMD CPU 过热
|
||||
* 开源支持 NVIDIA RTX 2000 图灵系列显卡
|
||||
* 内建 FSCRYPT 加密
|
||||
|
||||
@ -82,7 +82,7 @@ via: https://itsfoss.com/linux-kernel-5-6/
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[LazyWolfLin](https://github.com/LazyWolfLin)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,83 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (qianmingtian)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11902-1.html)
|
||||
[#]: subject: (Give an old MacBook new life with Linux)
|
||||
[#]: via: (https://opensource.com/article/20/2/macbook-linux-elementary)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
用 Linux 让旧 MacBook 焕发新生
|
||||
======
|
||||
|
||||
> Elementary OS 的最新版本 Hera 是一个令人印象深刻的平台,它可以让过时的 MacBook 得以重生。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/18/113614k2jx6ju7uuu0alhk.png)
|
||||
|
||||
当我安装苹果的 [MacOS Mojave][2] 时,它使我以前可靠的 MacBook Air 慢得像爬一样。我的计算机发售于 2015 年,具有 4 GB 内存、i5 处理器和 Broadcom 4360 无线卡,但是对于我的日常使用来说,Mojava 有点过分了,它不能和 [GnuCash][3] 一起工作,这激起了我重返 Linux 的欲望。我很高兴能重返,但是我深感遗憾的是,我的这台出色的 MacBook 被闲置了。
|
||||
|
||||
我在 MacBook Air 上尝试了几种 Linux 发行版,但总会有缺陷。有时是无线网卡;还有一次,它缺少对触摸板的支持。看了一些不错的评论后,我决定尝试 [Elementary OS][4] 5.0(Juno)。我用 USB [制作了启动盘][5],并将其插入 MacBook Air 。我来到了一个<ruby>现场<rt>live</rt></ruby>桌面,并且操作系统识别出了我的 Broadcom 无线芯片组 —— 我认为这可能行得通!
|
||||
|
||||
我喜欢在 Elementary OS 中看到的内容。它的 [Pantheon][6] 桌面真的很棒,并且其外观和使用起来的感觉对 Apple 用户来说很熟悉 —— 它的显示屏底部有一个扩展坞,并带有一些指向常用应用程序的图标。我对我之前期待的预览感到满意,所以我决定安装它,然后我的无线设备消失了。真的很令人失望。我真的很喜欢 Elementary OS ,但是没有无线网络是不行的。
|
||||
|
||||
时间快进到 2019 年 12 月,当我在 [Linux4Everyone][7] 播客上听到有关 Elementary 最新版本 v.5.1(Hera) 使 MacBook 复活的评论时,我决定用 Hera 再试一次。我下载了 ISO ,创建了可启动驱动器,将其插入电脑,这次操作系统识别了我的无线网卡。我可以在上面工作了。
|
||||
|
||||
![运行 Hera 的 MacBook Air][8]
|
||||
|
||||
我非常高兴我轻巧又功能强大的 MacBook Air 通过 Linux 焕然一新。我一直在更详细地研究 Elementary OS,我可以告诉你我印象深刻的东西。
|
||||
|
||||
### Elementary OS 的功能
|
||||
|
||||
根据 [Elementary 的博客][9],“新设计的登录和锁定屏幕问候语看起来更清晰、效果更好,并且修复了以前问候语中报告的许多问题,包括输入焦点问题,HiDPI 问题和更好的本地化。Hera 的新设计是为了响应来自 Juno 的用户反馈,并启用了一些不错的新功能。”
|
||||
|
||||
“不错的新功能”是在轻描淡写 —— Elementary OS 拥有我见过的最佳设计的 Linux 用户界面之一。默认情况下,系统上的“系统设置”图标位于扩展坞上。更改设置很容易,很快我就按照自己的喜好配置了系统。我需要的文字大小比默认值大,辅助功能是易于使用的,允许我设置大文字和高对比度。我还可以使用较大的图标和其他选项来调整扩展坞。
|
||||
|
||||
![Elementary OS 的设置界面][10]
|
||||
|
||||
按下 Mac 的 Command 键将弹出一个键盘快捷键列表,这对新用户非常有帮助。
|
||||
|
||||
![Elementary OS 的键盘快捷键][11]
|
||||
|
||||
Elementary OS 附带的 [Epiphany][12] Web 浏览器,我发现它非常易于使用。它与 Chrome、Chromium 或 Firefox 略有不同,但它已经绰绰有余。
|
||||
|
||||
对于注重安全的用户(我们应该都是),Elementary OS 的安全和隐私设置提供了多个选项,包括防火墙、历史记录、锁定,临时和垃圾文件的自动删除以及用于位置服务开/关的开关。
|
||||
|
||||
![Elementary OS 的隐私与安全][13]
|
||||
|
||||
### 有关 Elementray OS 的更多信息
|
||||
|
||||
Elementary OS 最初于 2011 年发布,其最新版本 Hera 于 2019 年 12 月 3 日发布。 Elementary 的联合创始人兼 CXO 的 [Cassidy James Blaede][14] 是操作系统的 UX 架构师。 Cassidy 喜欢使用开放技术来设计和构建有用、可用和令人愉悦的数字产品。
|
||||
|
||||
Elementary OS 具有出色的用户[文档][15],其代码(在 GPL 3.0 下许可)可在 [GitHub][16] 上获得。Elementary OS 鼓励参与该项目,因此请务必伸出援手并[加入社区][17]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/macbook-linux-elementary
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[qianmingtian][c]
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[c]: https://github.com/qianmingtian
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_cafe_brew_laptop_desktop.jpg?itok=G-n1o1-o (Coffee and laptop)
|
||||
[2]: https://en.wikipedia.org/wiki/MacOS_Mojave
|
||||
[3]: https://www.gnucash.org/
|
||||
[4]: https://elementary.io/
|
||||
[5]: https://opensource.com/life/14/10/test-drive-linux-nothing-flash-drive
|
||||
[6]: https://opensource.com/article/19/12/pantheon-linux-desktop
|
||||
[7]: https://www.linux4everyone.com/20-macbook-pro-elementary-os
|
||||
[8]: https://opensource.com/sites/default/files/uploads/macbookair_hera.png (MacBook Air with Hera)
|
||||
[9]: https://blog.elementary.io/introducing-elementary-os-5-1-hera/
|
||||
[10]: https://opensource.com/sites/default/files/uploads/elementaryos_settings.png (Elementary OS's Settings screen)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/elementaryos_keyboardshortcuts.png (Elementary OS's Keyboard shortcuts)
|
||||
[12]: https://en.wikipedia.org/wiki/GNOME_Web
|
||||
[13]: https://opensource.com/sites/default/files/uploads/elementaryos_privacy-security.png (Elementary OS's Privacy and Security screen)
|
||||
[14]: https://github.com/cassidyjames
|
||||
[15]: https://elementary.io/docs/learning-the-basics#learning-the-basics
|
||||
[16]: https://github.com/elementary
|
||||
[17]: https://elementary.io/get-involved
|
@ -0,0 +1,158 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (guevaraya)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11930-1.html)
|
||||
[#]: subject: (Troubleshoot Kubernetes with the power of tmux and kubectl)
|
||||
[#]: via: (https://opensource.com/article/20/2/kubernetes-tmux-kubectl)
|
||||
[#]: author: (Abhishek Tamrakar https://opensource.com/users/tamrakar)
|
||||
|
||||
利用 Tmux 和 kubectl 解决 Kubernetes 故障
|
||||
======
|
||||
|
||||
> 一个使用 tmux 的 kubectl 插件可以使 Kubernetes 疑难问题变得更简单。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/25/125435a4v3vpss3s4w3sks.jpg)
|
||||
|
||||
[Kubernetes][2] 是一个活跃的开源容器管理平台,它提供了可扩展性、高可用性、健壮性和富有弹性的应用程序管理。它的众多特性之一是支持通过其主要的二进制客户端 [kubectl][3] 运行定制脚本或可执行程序,kubectl 很强大的,允许用户在 Kubernetes 集群上用它直接做很多事情。
|
||||
|
||||
### 使用别名进行 Kubernetes 的故障排查
|
||||
|
||||
使用 Kubernetes 进行容器编排的人都知道由于设计上原因带来了其功能的复杂性。举例说,迫切需要以更快的速度并且几乎不需要手动干预的方式来简化 Kubernetes 中的故障排除(除过特殊情况)。
|
||||
|
||||
在故障排查功能方面,有很多场景需要考虑。在一种场景下,你知道你需要运行什么,但是这个命令的语法(即使作为一个单独的命令运行)过于复杂,或需要一、两次交互才能起作用。
|
||||
|
||||
例如,如果你需要经常进入一个系统命名空间中运行的容器,你可能发现自己在重复地键入:
|
||||
|
||||
```
|
||||
kubectl --namespace=kube-system exec -i -t <your-pod-name>
|
||||
```
|
||||
|
||||
为了简化故障排查,你可以用这些指令的命令行别名。比如,你可以增加下面命令到你的隐藏配置文件(`.bashrc` 或 `.zshrc`):
|
||||
|
||||
```
|
||||
alias ksysex='kubectl --namespace=kube-system exec -i -t'
|
||||
```
|
||||
|
||||
这是来自于 [Kubernetes 常见别名][4]存储库的一个例子,它展示了一种简化 `kubectl` 中的功能的方法。像这种场景下的简单情形,使用别名很有用。
|
||||
|
||||
### 切换到 kubectl 插件
|
||||
|
||||
更复杂的故障排查场景是需要一个一个的执行很多命令,调查环境,最后得出结论。仅仅用别名方法是不能解决这种情况的;你需要知道你所部署的 Kubernetes 之间逻辑和相关性,你真正需要的是自动化,以在更短的时间内输出你想要的。
|
||||
|
||||
考虑到你的集群有 10 ~ 20 或 50 ~ 100 个命名空间来提供不同的微服务。一般在进行故障排查时,什么对你有帮助?
|
||||
|
||||
* 你需要能够快速分辨出抛出错误的是哪个 命名空间的哪个 Pod 的东西。
|
||||
* 你需要一些可监视一个命名空间的所有 Pod 日志的东西。
|
||||
* 你可能也需要监视特定命名空间的出现错误的某个 Pod 的日志。
|
||||
|
||||
涵盖这些要点的解决方案对于定位生产环境的问题有很大的帮助,以及在开发和测试环节中也很有用。
|
||||
|
||||
你可以用 [kubectl 插件][5]创建比简单的别名更强大的功能。插件类似于其它用任何语言编写的独立脚本,但被设计为可以扩充 Kubernetes 管理员的主要命令。
|
||||
|
||||
创建一个插件,你必须用 `kubectl-<your-plugin-name>` 的正确的语法来拷贝这个脚本到 `$PATH` 中的导出目录之一,并需要为其赋予可执行权限(`chmod +x`)。
|
||||
|
||||
创建插件之后将其移动到路径中,你可以立即运行它。例如,我的路径下有一个 `kubectl-krawl` 和 `kubectl-kmux`:
|
||||
|
||||
```
|
||||
$ kubectl plugin list
|
||||
The following compatible plugins are available:
|
||||
|
||||
/usr/local/bin/kubectl-krawl
|
||||
/usr/local/bin/kubectl-kmux
|
||||
|
||||
$ kubectl kmux
|
||||
```
|
||||
|
||||
现在让我们见识下带有 tmux 的 Kubernetes 的有多强大。
|
||||
|
||||
### 驾驭强大的 tmux
|
||||
|
||||
[Tmux][6] 是一个非常强大的工具,许多管理员和运维团队都依赖它来解决与易操作性相关的问题:通过将窗口分成多个窗格以便在多台计算机上运行并行的调试来监视日志。它的主要的优点是可在命令行或自动化脚本中使用。
|
||||
|
||||
我创建[一个 kubectl 插件][7],使用 tmux 使故障排查更加简单。我将通过注释来解析插件背后的逻辑(插件的完整代码留待给你实现):
|
||||
|
||||
```
|
||||
# NAMESPACE 是要监控的名字空间
|
||||
# POD 是 Pod 名称
|
||||
# Containers 是容器名称
|
||||
|
||||
# 初始化一个计数器 n 以计算循环计数的数量,
|
||||
# 之后 tmux 使用它来拆分窗格。
|
||||
n=0;
|
||||
|
||||
# 在 Pod 和容器列表上开始循环
|
||||
while IFS=' ' read -r POD CONTAINERS
|
||||
do
|
||||
# tmux 为每个 Pod 创建一个新窗口
|
||||
tmux neww $COMMAND -n $POD 2>/dev/null
|
||||
# 对运行中的 Pod 中 的所有容器启动循环
|
||||
for CONTAINER in ${CONTAINERS//,/ }
|
||||
do
|
||||
if [ x$POD = x -o x$CONTAINER = x ]; then
|
||||
# 如果任何值为 null,则退出。
|
||||
warn "Looks like there is a problem getting pods data."
|
||||
break
|
||||
fi
|
||||
|
||||
# 设置要执行的命令
|
||||
COMMAND=”kubectl logs -f $POD -c $CONTAINER -n $NAMESPACE”
|
||||
# 检查 tmux 会话
|
||||
if tmux has-session -t <会话名> 2>/dev/null;
|
||||
then
|
||||
<设置会话退出>
|
||||
else
|
||||
<创建会话>
|
||||
fi
|
||||
# 在当前窗口为每个容器切分窗格
|
||||
tmux selectp -t $n \; \
|
||||
splitw $COMMAND \; \
|
||||
select-layout tiled \;
|
||||
# 终止容器循环
|
||||
done
|
||||
|
||||
# 用 Pod 名称重命名窗口以识别
|
||||
tmux renamew $POD 2>/dev/null
|
||||
|
||||
# 增加计数器
|
||||
((n+=1))
|
||||
|
||||
# 终止 Pod 循环
|
||||
done<<(<从 kubernetes 集群获取 Pod 和容器的列表>)
|
||||
|
||||
# 最后选择窗口并附加会话
|
||||
tmux selectw -t <会话名>:1 \; \
|
||||
attach-session -t <会话名>\;
|
||||
```
|
||||
|
||||
运行插件脚本后,将产生类似于下图的输出。每个 Pod 有一个自己的窗口,每个容器(如果有多个)被分割到其窗口中 Pod 窗格中,并在日志到达时输出。Tmux 之美如下可见;通过正确的配置,你甚至会看到哪个窗口正处于激活运行状态(可看到标签是白色的)。
|
||||
|
||||
![kmux 插件的输出][8]
|
||||
|
||||
### 总结
|
||||
|
||||
别名是在 Kubernetes 环境下常见的也有用的简易故障排查方法。当环境变得复杂,用高级脚本生成的kubectl 插件是一个更强大的方法。至于用哪个编程语言来编写 kubectl 插件是没有限制。唯一的要求是该名字在路径中是可执行的,并且不能与已知的 kubectl 命令重复。
|
||||
|
||||
要阅读完整的插件源码,或试试我创建的插件,请查看我的 [kube-plugins-github][7] 存储库。欢迎提交提案和补丁。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/kubernetes-tmux-kubectl
|
||||
|
||||
作者:[Abhishek Tamrakar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[guevaraya](https://github.com/guevaraya)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/tamrakar
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_4.png?itok=VGZO8CxT (一个坐在笔记本面前的妇女)
|
||||
[2]: https://opensource.com/resources/what-is-kubernetes
|
||||
[3]: https://kubernetes.io/docs/reference/kubectl/overview/
|
||||
[4]: https://github.com/ahmetb/kubectl-aliases/blob/master/.kubectl_aliases
|
||||
[5]: https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/
|
||||
[6]: https://opensource.com/article/19/6/tmux-terminal-joy
|
||||
[7]: https://github.com/abhiTamrakar/kube-plugins
|
||||
[8]: https://raw.githubusercontent.com/abhiTamrakar/kube-plugins/master/kmux/kmux.png
|
@ -0,0 +1,76 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11866-1.html)
|
||||
[#]: subject: (Ubuntu 19.04 Has Reached End of Life! Existing Users Must Upgrade to Ubuntu 19.10)
|
||||
[#]: via: (https://itsfoss.com/ubuntu-19-04-end-of-life/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Ubuntu 19.04 已经到期!现有用户必须升级到 Ubuntu 19.10
|
||||
======
|
||||
|
||||
> Ubuntu 19.04 已在 2020 年 1 月 23 日到期,这意味着运行 Ubuntu 19.04 的系统将不再会接收到安全和维护更新,因此将使其容易受到攻击。
|
||||
|
||||
![][1]
|
||||
|
||||
[Ubuntu 19.04][2] 发布于 2019 年 4 月 18 日。由于它不是长期支持(LTS)版本,因此只有 9 个月的支持。完成它的发行周期后,Ubuntu 19.04 于 2020 年 1 月 23 日到期。
|
||||
|
||||
Ubuntu 19.04 带来了一些视觉和性能方面的改进,为时尚和美观的 Ubuntu 外观铺平了道路。与其他常规 Ubuntu 版本一样,它的生命周期为 9 个月。它如今结束了。
|
||||
|
||||
### Ubuntu 19.04 终止了吗?这是什么意思?
|
||||
|
||||
EOL(End of life)是指在某个日期之后操作系统版本将无法获得更新。你可能已经知道 Ubuntu(或其他操作系统)提供了安全性和维护升级,以使你的系统免受网络攻击。当发行版到期后,操作系统将停止接收这些重要更新。
|
||||
|
||||
如果你的操作系统版本到期后继续使用该系统,那么系统将容易受到网络和恶意软件的攻击。不仅如此。在 Ubuntu 中,你使用 APT 从软件中心下载的应用也不会更新。实际上,你将不再能够[使用 apt-get 命令安装新软件][3](如果不是立即,那就是逐渐地)。
|
||||
|
||||
### 所有 Ubuntu 19.04 用户必须升级到 Ubuntu 19.10
|
||||
|
||||
从 2020 年 1 月 23 日开始,Ubuntu 19.04 将停止接收更新。你必须升级到 2020 年 7 月之前受支持的 Ubuntu 19.10。这也适用于其他[官方 Ubuntu 衍生版][4],例如 Lubuntu、Xubuntu、Kubuntu 等。
|
||||
|
||||
你可以在“设置 -> 细节” 或使用如下命令来[检查你的 Ubuntu 版本][9]:
|
||||
|
||||
```
|
||||
lsb_release -a
|
||||
```
|
||||
|
||||
#### 如何升级到 Ubuntu 19.10?
|
||||
|
||||
值得庆幸的是,Ubuntu 提供了简单的方法来将现有系统升级到新版本。实际上,Ubuntu 还会提示你有新的 Ubuntu 版本可用,你应该升级到该版本。
|
||||
|
||||
![Existing Ubuntu 19.04 should see a message to upgrade to Ubuntu 19.10][5]
|
||||
|
||||
如果你的互联网连接良好,那么可以使用[和更新 Ubuntu 一样的 Software Updater 工具][6]。在上图中,你只需单击 “Upgrade” 按钮并按照说明进行操作。我已经编写了有关使用此方法[升级到 Ubuntu 18.04][7]的文章。
|
||||
|
||||
如果你没有良好的互联网连接,那么有一种临时方案。在外部磁盘上备份家目录或重要数据。
|
||||
|
||||
然后,制作一个 Ubuntu 19.10 的 Live USB。下载 Ubuntu 19.10 ISO,并使用 Ubuntu 系统上已安装的启动磁盘创建器从该 ISO 创建 Live USB。
|
||||
|
||||
从该 Live USB 引导,然后继续“安装” Ubuntu 19.10。在安装过程中,你应该看到一个删除 Ubuntu 19.04 并将其替换为 Ubuntu 19.10 的选项。选择此选项,然后像重新[安装 Ubuntu][8]一样进行下去。
|
||||
|
||||
#### 你是否仍在使用 Ubuntu 19.04、18.10、17.10 或其他不受支持的版本?
|
||||
|
||||
你应该注意,目前仅 Ubuntu 16.04、18.04 和 19.10(或更高版本)版本还受支持。如果你运行的不是这些 Ubuntu 版本,那么你必须升级到较新版本。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/ubuntu-19-04-end-of-life/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/End-of-Life-Ubuntu-19.04.png?ssl=1
|
||||
[2]: https://itsfoss.com/ubuntu-19-04-release/
|
||||
[3]: https://itsfoss.com/apt-get-linux-guide/
|
||||
[4]: https://itsfoss.com/which-ubuntu-install/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/ubuntu_19_04_end_of_life.jpg?ssl=1
|
||||
[6]: https://itsfoss.com/update-ubuntu/
|
||||
[7]: https://itsfoss.com/upgrade-ubuntu-version/
|
||||
[8]: https://itsfoss.com/install-ubuntu/
|
||||
[9]: https://itsfoss.com/how-to-know-ubuntu-unity-version/
|
96
published/202002/20200205 Getting started with GnuCash.md
Normal file
96
published/202002/20200205 Getting started with GnuCash.md
Normal file
@ -0,0 +1,96 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11895-1.html)
|
||||
[#]: subject: (Getting started with GnuCash)
|
||||
[#]: via: (https://opensource.com/article/20/2/gnucash)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
开始使用 GnuCash
|
||||
======
|
||||
|
||||
> 使用 GnuCash 管理你的个人或小型企业会计。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/15/124236wz5e0z5vq7571qby.jpg)
|
||||
|
||||
在过去的四年里,我一直在用 [GnuCash][2] 来管理我的个人财务,我对此非常满意。这个开源(GPL v3)项目自 1998 年首次发布以来一直成长和改进,2019 年 12 月发布的最新版本 3.8 增加了许多改进和 bug 修复。
|
||||
|
||||
GnuCash 可在 Windows、MacOS 和 Linux 中使用。它实现了一个复式记账系统,并可以导入各种流行的开放和专有文件格式,包括 QIF、QFX、OFX、CSV 等。这使得从其他财务应用转换(包括 Quicken)而来很容易,它是为取代这些而出现的。
|
||||
|
||||
借助 GnuCash,你可以跟踪个人财务状况以及小型企业会计和开票。它没有集成的工资系统。根据文档,你可以在 GnuCash 中跟踪工资支出,但你必须在该软件外计算税金和扣减。
|
||||
|
||||
### 安装
|
||||
|
||||
要在 Linux 上安装 GnuCash:
|
||||
|
||||
* 在 Red Hat、CentOS 或 Fedora 中: `$ sudo dnf install gnucash`
|
||||
* 在 Debian、Ubuntu 或 Pop_OS 中: `$ sudo apt install gnucash`
|
||||
|
||||
你也可以从 [Flathub][3] 安装它,我在运行 Elementary OS 的笔记本上使用它。(本文中的所有截图都来自此次安装)。
|
||||
|
||||
### 设置
|
||||
|
||||
安装并启动程序后,你将看到一个欢迎屏幕,该页面提供了创建新账户集、导入 QIF 文件或打开新用户教程的选项。
|
||||
|
||||
![GnuCash Welcome screen][4]
|
||||
|
||||
#### 个人账户
|
||||
|
||||
如果你选择第一个选项(正如我所做的那样),GnuCash 会打开一个页面帮你起步。它收集初始数据并设置账户首选项,例如账户类型和名称、商业数据(例如,税号)和首选货币。
|
||||
|
||||
![GnuCash new account setup][5]
|
||||
|
||||
GnuCash 支持个人银行账户、商业账户、汽车贷款、CD 和货币市场账户、儿童保育账户等。
|
||||
|
||||
例如,首先创建一个简单的支票簿。你可以输入账户的初始余额或以多种格式导入现有账户数据。
|
||||
|
||||
![GnuCash import data][6]
|
||||
|
||||
#### 开票
|
||||
|
||||
GnuCash 还支持小型企业功能,包括客户、供应商和开票。要创建发票,请在 “Business -> Invoice” 中输入数据。
|
||||
|
||||
![GnuCash create invoice][7]
|
||||
|
||||
然后,你可以将发票打印在纸上,也可以将其导出到 PDF 并通过电子邮件发送给你的客户。
|
||||
|
||||
![GnuCash invoice][8]
|
||||
|
||||
### 获取帮助
|
||||
|
||||
如果你有任何疑问,它有一个优秀的帮助,你可在菜单栏的右侧获取指导。
|
||||
|
||||
![GnuCash help][9]
|
||||
|
||||
该项目的网站包含许多有用的信息的链接,例如 GnuCash [功能][10]的概述。GnuCash 还提供了[详细的文档][11],可供下载和离线阅读,它还有一个 [wiki][12],为用户和开发人员提供了有用的信息。
|
||||
|
||||
你可以在项目的 [GitHub][13] 仓库中找到其他文件和文档。GnuCash 项目由志愿者驱动。如果你想参与,请查看项目的 wiki 上的 [Getting involved][14] 部分。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/gnucash
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_whitehurst_money.png?itok=ls-SOzM0 (A dollar sign in a network)
|
||||
[2]: https://www.gnucash.org/
|
||||
[3]: https://flathub.org/apps/details/org.gnucash.GnuCash
|
||||
[4]: https://opensource.com/sites/default/files/images/gnucash_welcome.png (GnuCash Welcome screen)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/gnucash_newaccountsetup.png (GnuCash new account setup)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/gnucash_importdata.png (GnuCash import data)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/gnucash_enter-invoice.png (GnuCash create invoice)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/gnucash_invoice.png (GnuCash invoice)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/gnucash_help.png (GnuCash help)
|
||||
[10]: https://www.gnucash.org/features.phtml
|
||||
[11]: https://www.gnucash.org/docs/v3/C/gnucash-help.pdf
|
||||
[12]: https://wiki.gnucash.org/wiki/GnuCash
|
||||
[13]: https://github.com/Gnucash
|
||||
[14]: https://wiki.gnucash.org/wiki/GnuCash#Getting_involved_in_the_GnuCash_project
|
218
published/202002/20200206 3 ways to use PostgreSQL commands.md
Normal file
218
published/202002/20200206 3 ways to use PostgreSQL commands.md
Normal file
@ -0,0 +1,218 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Morisun029)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11904-1.html)
|
||||
[#]: subject: (3 ways to use PostgreSQL commands)
|
||||
[#]: via: (https://opensource.com/article/20/2/postgresql-commands)
|
||||
[#]: author: (Greg Pittman https://opensource.com/users/greg-p)
|
||||
|
||||
3 种使用 PostgreSQL 命令的方式
|
||||
======
|
||||
|
||||
> 无论你需要的东西简单(如一个购物清单)亦或复杂(如色卡生成器) ,PostgreSQL 命令都能使它变得容易起来。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/18/124003twk7fryz2krw2r39.jpg)
|
||||
|
||||
在 [PostgreSQL 入门][2]一文中, 我解释了如何安装、设置和开始使用这个开源数据库软件。不过,使用 [PostgreSQL][3] 中的命令可以做更多事情。
|
||||
|
||||
例如,我使用 Postgres 来跟踪我的杂货店购物清单。我的大多数杂货店购物是在家里进行的,而且每周进行一次大批量的采购。我去几个不同的地方购买清单上的东西,因为每家商店都提供特定的选品或质量,亦或更好的价格。最初,我制作了一个 HTML 表单页面来管理我的购物清单,但这样无法保存我的输入内容。因此,在想到要购买的物品时我必须马上列出全部清单,然后到采购时我常常会忘记一些我需要或想要的东西。
|
||||
|
||||
相反,使用 PostgreSQL,当我想到需要的物品时,我可以随时输入,并在购物前打印出来。你也可以这样做。
|
||||
|
||||
### 创建一个简单的购物清单
|
||||
|
||||
首先,输入 `psql` 命令进入数据库,然后用下面的命令创建一个表:
|
||||
|
||||
```
|
||||
Create table groc (item varchar(20), comment varchar(10));
|
||||
```
|
||||
|
||||
输入如下命令在清单中加入商品:
|
||||
|
||||
```
|
||||
insert into groc values ('milk', 'K');
|
||||
insert into groc values ('bananas', 'KW');
|
||||
```
|
||||
|
||||
括号中有两个信息(逗号隔开):前面是你需要买的东西,后面字母代表你要购买的地点以及哪些东西是你每周通常都要买的(`W`)。
|
||||
|
||||
因为 `psql` 有历史记录,你可以按向上键在括号内编辑信息,而无需输入商品的整行信息。
|
||||
|
||||
在输入一小部分商品后,输入下面命令来检查前面的输入内容。
|
||||
|
||||
```
|
||||
Select * from groc order by comment;
|
||||
|
||||
item | comment
|
||||
----------------+---------
|
||||
ground coffee | H
|
||||
butter | K
|
||||
chips | K
|
||||
steak | K
|
||||
milk | K
|
||||
bananas | KW
|
||||
raisin bran | KW
|
||||
raclette | L
|
||||
goat cheese | L
|
||||
onion | P
|
||||
oranges | P
|
||||
potatoes | P
|
||||
spinach | PW
|
||||
broccoli | PW
|
||||
asparagus | PW
|
||||
cucumber | PW
|
||||
sugarsnap peas | PW
|
||||
salmon | S
|
||||
(18 rows)
|
||||
```
|
||||
|
||||
此命令按 `comment` 列对结果进行排序,以便按购买地点对商品进行分组,从而使你的购物更加方便。
|
||||
|
||||
使用 `W` 来指明你每周要买的东西,当你要清除表单为下周的列表做准备时,你可以将每周的商品保留在购物清单上。输入:
|
||||
|
||||
```
|
||||
delete from groc where comment not like '%W';
|
||||
```
|
||||
|
||||
注意,在 PostgreSQL 中 `%` 表示通配符(而非星号)。所以,要保存输入内容,需要输入:
|
||||
|
||||
```
|
||||
delete from groc where item like 'goat%';
|
||||
```
|
||||
|
||||
不能使用 `item = 'goat%'`,这样没用。
|
||||
|
||||
在购物时,用以下命令输出清单并打印或发送到你的手机:
|
||||
|
||||
```
|
||||
\o groclist.txt
|
||||
select * from groc order by comment;
|
||||
\o
|
||||
```
|
||||
|
||||
最后一个命令 `\o` 后面没有任何内容,将重置输出到命令行。否则,所有的输出会继续输出到你创建的杂货店购物文件 `groclist.txt` 中。
|
||||
|
||||
### 分析复杂的表
|
||||
|
||||
这个逐项列表对于数据量小的表来说没有问题,但是对于数据量大的表呢?几年前,我帮 [FreieFarbe.de][4] 的团队从 HLC 调色板中创建一个自由色的色样册。事实上,任何能想象到的打印色都可按色调、亮度、浓度(饱和度)来规定。最终结果是 [HLC Color Atlas][5],下面是我们如何实现的。
|
||||
|
||||
该团队向我发送了具有颜色规范的文件,因此我可以编写可与 Scribus 配合使用的 Python 脚本,以轻松生成色样册。一个例子像这样开始:
|
||||
|
||||
```
|
||||
HLC, C, M, Y, K
|
||||
H010_L15_C010, 0.5, 49.1, 0.1, 84.5
|
||||
H010_L15_C020, 0.0, 79.7, 15.1, 78.9
|
||||
H010_L25_C010, 6.1, 38.3, 0.0, 72.5
|
||||
H010_L25_C020, 0.0, 61.8, 10.6, 67.9
|
||||
H010_L25_C030, 0.0, 79.5, 18.5, 62.7
|
||||
H010_L25_C040, 0.4, 94.2, 17.3, 56.5
|
||||
H010_L25_C050, 0.0, 100.0, 15.1, 50.6
|
||||
H010_L35_C010, 6.1, 32.1, 0.0, 61.8
|
||||
H010_L35_C020, 0.0, 51.7, 8.4, 57.5
|
||||
H010_L35_C030, 0.0, 68.5, 17.1, 52.5
|
||||
H010_L35_C040, 0.0, 81.2, 22.0, 46.2
|
||||
H010_L35_C050, 0.0, 91.9, 20.4, 39.3
|
||||
H010_L35_C060, 0.1, 100.0, 17.3, 31.5
|
||||
H010_L45_C010, 4.3, 27.4, 0.1, 51.3
|
||||
```
|
||||
|
||||
这与原始数据相比,稍有修改,原始数据用制表符分隔。我将其转换成 CSV 格式(用逗号分割值),我更喜欢其与 Python 一起使用(CSV 文也很有用,因为它可轻松导入到电子表格程序中)。
|
||||
|
||||
在每一行中,第一项是颜色名称,其后是其 C、M、Y 和 K 颜色值。 该文件包含 1,793 种颜色,我想要一种分析信息的方法,以了解这些值的范围。这就是 PostgreSQL 发挥作用的地方。我不想手动输入所有数据 —— 我认为输入过程中我不可能不出错,而且令人头痛。幸运的是,PostgreSQL 为此提供了一个命令。
|
||||
|
||||
首先用以下命令创建数据库:
|
||||
|
||||
```
|
||||
Create table hlc_cmyk (color varchar(40), c decimal, m decimal, y decimal, k decimal);
|
||||
```
|
||||
|
||||
然后通过以下命令引入数据:
|
||||
|
||||
```
|
||||
\copy hlc_cmyk from '/home/gregp/HLC_Atlas_CMYK_SampleData.csv' with (header, format CSV);
|
||||
```
|
||||
|
||||
开头有反斜杠,是因为使用纯 `copy` 命令的权限仅限于 root 用户和 Postgres 的超级用户。在括号中,`header` 表示第一行包含标题,应忽略,`CSV` 表示文件格式为 CSV。请注意,在此方法中,颜色名称不需要用括号括起来。
|
||||
|
||||
如果操作成功,会看到 `COPY NNNN`,其中 N 表示插入到表中的行数。
|
||||
|
||||
最后,可以用下列命令查询:
|
||||
|
||||
```
|
||||
select * from hlc_cmyk;
|
||||
|
||||
color | c | m | y | k
|
||||
---------------+-------+-------+-------+------
|
||||
H010_L15_C010 | 0.5 | 49.1 | 0.1 | 84.5
|
||||
H010_L15_C020 | 0.0 | 79.7 | 15.1 | 78.9
|
||||
H010_L25_C010 | 6.1 | 38.3 | 0.0 | 72.5
|
||||
H010_L25_C020 | 0.0 | 61.8 | 10.6 | 67.9
|
||||
H010_L25_C030 | 0.0 | 79.5 | 18.5 | 62.7
|
||||
H010_L25_C040 | 0.4 | 94.2 | 17.3 | 56.5
|
||||
H010_L25_C050 | 0.0 | 100.0 | 15.1 | 50.6
|
||||
H010_L35_C010 | 6.1 | 32.1 | 0.0 | 61.8
|
||||
H010_L35_C020 | 0.0 | 51.7 | 8.4 | 57.5
|
||||
H010_L35_C030 | 0.0 | 68.5 | 17.1 | 52.5
|
||||
```
|
||||
|
||||
|
||||
所有的 1,793 行数据都是这样的。回想起来,我不能说此查询对于 HLC 和 Scribus 任务是绝对必要的,但是它减轻了我对该项目的一些担忧。
|
||||
|
||||
为了生成 HLC 色谱,我使用 Scribus 为色板页面中的 13,000 多种颜色自动创建了颜色图表。
|
||||
|
||||
我可以使用 `copy` 命令输出数据:
|
||||
|
||||
```
|
||||
\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV);
|
||||
```
|
||||
|
||||
我还可以使用 `where` 子句根据某些值来限制输出。
|
||||
|
||||
例如,以下命令将仅发送以 `H10` 开头的色调值。
|
||||
|
||||
```
|
||||
\copy hlc_cmyk to '/home/gregp/hlc_cmyk_backup.csv' with (header, format CSV) where color like 'H10%';
|
||||
```
|
||||
|
||||
### 备份或传输数据库或表
|
||||
|
||||
我在此要提到的最后一个命令是 `pg_dump`,它用于备份 PostgreSQL 数据库,并在 `psql` 控制台之外运行。 例如:
|
||||
|
||||
```
|
||||
pg_dump gregp -t hlc_cmyk > hlc.out
|
||||
pg_dump gregp > dball.out
|
||||
```
|
||||
|
||||
第一行是导出 `hlc_cmyk` 表及其结构。第二行将转储 `gregp` 数据库中的所有表。这对于备份或传输数据库或表非常有用。
|
||||
|
||||
要将数据库或表传输到另一台电脑(查看 [PostgreSQL 入门][2]那篇文章获取详细信息),首先在要转入的电脑上创建一个数据库,然后执行相反的操作。
|
||||
|
||||
```
|
||||
psql -d gregp -f dball.out
|
||||
```
|
||||
|
||||
一步创建所有表并输入数据。
|
||||
|
||||
### 总结
|
||||
|
||||
在本文中,我们了解了如何使用 `WHERE` 参数限制操作,以及如何使用 PostgreSQL 通配符 `%`。我们还了解了如何将大批量数据加载到表中,然后将部分或全部表数据输出到文件,甚至是将整个数据库及其所有单个表输出。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/postgresql-commands
|
||||
|
||||
作者:[Greg Pittman][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Morisun029](https://github.com/Morisun029)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/greg-p
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos)
|
||||
[2]: https://linux.cn/article-11593-1.html
|
||||
[3]: https://www.postgresql.org/
|
||||
[4]: http://freiefarbe.de
|
||||
[5]: https://www.freiefarbe.de/en/thema-farbe/hlc-colour-atlas/
|
@ -0,0 +1,186 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11884-1.html)
|
||||
[#]: subject: (Best Open Source eCommerce Platforms to Build Online Shopping Websites)
|
||||
[#]: via: (https://itsfoss.com/open-source-ecommerce/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
7 个可用于自建电商站点的开源解决方案
|
||||
======
|
||||
|
||||
在[之前的文章][1]中,我介绍过一些开源<ruby>内容管理系统<rt>Content Management System</rt></ruby>(CMS),顾名思义,这些 CMS 平台更适用于以内容为主的站点。
|
||||
|
||||
那如果想要建立自己的线上购物站点呢?我们正好还有一些优秀的开源电商解决方案,可以自行部署在自己的 Linux 服务器上。
|
||||
|
||||
这些电商解决方案是专为搭建线上购物站点设计的,因此都集成了库存管理、商品列表、购物车、下单、愿望清单以及支付这些必需的基础功能。
|
||||
|
||||
但请注意,这篇文章并不会进行深入介绍。因此,我建议最好广泛试用其中的多个产品,以便进一步的了解和比较。
|
||||
|
||||
### 优秀的开源电商解决方案
|
||||
|
||||
![][2]
|
||||
|
||||
开源电商解决方案种类繁多,一些缺乏维护的都会被我们忽略掉,以免搭建出来的站点因维护不及时而受到影响。
|
||||
|
||||
另外,以下的列表排名不分先后。
|
||||
|
||||
#### 1、nopCommerce
|
||||
|
||||
![][3]
|
||||
|
||||
nopCommerce 是基于 [ASP.NET Core][4] 的自由开源的电商解决方案。如果你要找的是基于 PHP 的解决方案,可以跳过这一节了。
|
||||
|
||||
nopCommerce 的管理面板界面具有简洁易用的特点,如果你还使用过 OpenCart,就可能会感到似曾相识(我不是在抱怨)。在默认情况下,它就已经自带了很多基本的功能,同时还为移动端用户提供了响应式的设计。
|
||||
|
||||
你可以在其[官方商店][5]中获取到一些兼容的界面主题和应用扩展,还可以选择付费的支持服务。
|
||||
|
||||
在开始使用前,你可以从 nopCommerce 的[官方网站][6]下载源代码包,然后进行自定义配置和部署;也可以直接下载完整的软件包快速安装到 web 服务器上。详细信息可以查阅 nopCommerce 的 [GitHub 页面][7]或官方网站。
|
||||
|
||||
- [nopCommerce][8]
|
||||
|
||||
#### 2、OpenCart
|
||||
|
||||
![][9]
|
||||
|
||||
OpenCart 是一个基于 PHP 的非常流行的电商解决方案,就我个人而言,我曾为一个项目用过它,并且体验非常好,如果不是最好的话。
|
||||
|
||||
或许你会觉得它维护得不是很频繁,但实际上使用 OpenCart 的开发者并不在少数。你可以获得许多受支持的扩展并将它们的功能加入到 OpenCart 中。
|
||||
|
||||
OpenCart 不一定是适合所有人的“现代”电商解决方案,但如果你需要的只是一个基于 PHP 的开源解决方案,OpenCart 是个值得一试的选择。在大多数具有一键式应用程序安装支持的网络托管平台中,应该可以安装 OpenCart。想要了解更多,可以查阅 OpenCart 的官方网站或 [GitHub 页面][10]。
|
||||
|
||||
- [OpenCart][11]
|
||||
|
||||
#### 3、PrestaShop
|
||||
|
||||
![][12]
|
||||
|
||||
PrestaShop 也是一个可以尝试的开源电商解决方案。
|
||||
|
||||
PrestaShop 是一个积极维护下的开源解决方案,它的官方商店中也有额外提供主题和扩展。与 OpenCart 不同,在托管服务平台上,你可能找不到一键安装的 PrestaShop。但不需要担心,从官方网站下载下来之后,它的部署过程也并不复杂。如果你需要帮助,也可以参考 PrestaShop 的[安装指南][15]。
|
||||
|
||||
PrestaShop 的特点就是配置丰富和易于使用,我发现很多其它用户也在用它,你也不妨试用一下。
|
||||
|
||||
你也可以在 PrestaShop 的 [GitHub 页面][16]查阅到更多相关内容。
|
||||
|
||||
- [PrestaShop][17]
|
||||
|
||||
#### 4、WooCommerce
|
||||
|
||||
![][18]
|
||||
|
||||
如果你想用 [WordPress][19] 来搭建电商站点,不妨使用 WooCommerce。
|
||||
|
||||
从技术上来说,这种方式其实是搭建一个 WordPress 应用,然后把 WooCommerce 作为一个插件或扩展以实现电商站点所需要的功能。很多 web 开发者都知道如何使用 WordPress,因此 WooCommerce 的学习成本不会很高。
|
||||
|
||||
WordPress 作为目前最好的开源站点项目之一,对大部分人来说都不会有太高的门槛。它具有易用、稳定的特点,同时还支持大量的扩展插件。
|
||||
|
||||
WooCommerce 的灵活性也是一大亮点,在它的线上商店提供了许多设计和扩展可供选择。你也可以到它的 [GitHub 页面][20]查看相关介绍。
|
||||
|
||||
- [WooCommerce][21]
|
||||
|
||||
#### 5、Zen Cart
|
||||
|
||||
![][22]
|
||||
|
||||
这或许是一个稍显古老的电商解决方案,但同时也是最好的开源解决方案之一。如果你喜欢老式风格的模板(主要基于 HTML),而且只需要一些基础性的扩展,那你也可以尝试使用 Zen Cart。
|
||||
|
||||
就我个人而言,我不建议把 Zen Cart 用在一个新项目当中。但考虑到它仍然是一个活跃更新中的解决方案,如果你喜欢的话,也不妨用它来进行试验。
|
||||
|
||||
你也可以在 [SourceForge][23] 找到 Zen Cart 这个项目。
|
||||
|
||||
- [Zen Cart][24]
|
||||
|
||||
#### 6、Magento
|
||||
|
||||
![Image Credits: Magestore][25]
|
||||
|
||||
Magento 是 Abode 旗下的开源电商解决方案,从某种角度来说,可能比 WordPress 表现得更为优秀。
|
||||
|
||||
Magento 完全是作为电商应用程序而生的,因此你会发现它的很多基础功能都非常好用,甚至还提供了高级的定制。
|
||||
|
||||
但如果你使用的是 Magento 的开源版,可能会接触不到托管版的一些高级功能,两个版本的差异,可以在[官方文档][26]中查看到。如果你使用托管版,还可以选择相关的托管支持服务。
|
||||
|
||||
想要了解更多,可以查看 Magento 的 [GitHub 页面][27]。
|
||||
|
||||
- [Magento][28]
|
||||
|
||||
#### 7、Drupal
|
||||
|
||||
![Drupal][29]
|
||||
|
||||
Drupal 是一个适用于创建电商站点的开源 CMS 解决方案。
|
||||
|
||||
我没有使用过 Drupal,因此我不太确定它用起来是否足够灵活。但从它的官方网站上来看,它提供的扩展模块和主题列表,足以让你轻松完成一个电商站点需要做的任何事情。
|
||||
|
||||
跟 WordPress 类似,Drupal 在服务器上的部署并不复杂,不妨看看它的使用效果。在它的[下载页面][30]可以查看这个项目以及下载最新的版本。
|
||||
|
||||
- [Drupal][31]
|
||||
|
||||
#### 8、Odoo eCommerce
|
||||
|
||||
![Odoo Ecommerce Platform][32]
|
||||
|
||||
如果你还不知道,Odoo 提供了一套开源商务应用程序。他们还提供了[开源会计软件][33]和 CRM 解决方案,我们将会在单独的列表中进行介绍。
|
||||
|
||||
对于电子商务门户,你可以根据需要使用其在线拖放生成器自定义网站。你也可以推广该网站。除了简单的主题安装和自定义选项之外,你还可以利用 HTML/CSS 在一定程度上手动自定义外观。
|
||||
|
||||
你也可以查看其 [GitHub][34] 页面以进一步了解它。
|
||||
|
||||
- [Odoo eCommerce][35]
|
||||
|
||||
### 总结
|
||||
|
||||
我敢肯定还有更多的开源电子商务平台,但是,我现在还没有遇到比我上面列出的更好的东西。
|
||||
|
||||
如果你还有其它值得一提的产品,可以在评论区发表。也欢迎在评论区分享你对开源电商解决方案的经验和想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/open-source-ecommerce/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/open-source-cms/
|
||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/open-source-eCommerce.png?ssl=1
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/nopCommerce.png?ssl=1
|
||||
[4]: https://en.wikipedia.org/wiki/ASP.NET_Core
|
||||
[5]: https://www.nopcommerce.com/marketplace
|
||||
[6]: https://www.nopcommerce.com/download-nopcommerce
|
||||
[7]: https://github.com/nopSolutions/nopCommerce
|
||||
[8]: https://www.nopcommerce.com/
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/opencart.jpg?ssl=1
|
||||
[10]: https://github.com/opencart/opencart
|
||||
[11]: https://www.opencart.com/
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/01/prestashop.jpg?ssl=1
|
||||
[13]: https://addons.prestashop.com/en/3-templates-prestashop
|
||||
[14]: https://addons.prestashop.com/en/
|
||||
[15]: http://doc.prestashop.com/display/PS17/Installing+PrestaShop
|
||||
[16]: https://github.com/PrestaShop/PrestaShop
|
||||
[17]: https://www.prestashop.com/en
|
||||
[18]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/01/woocommerce.jpg?ssl=1
|
||||
[19]: https://wordpress.org/
|
||||
[20]: https://github.com/woocommerce/woocommerce
|
||||
[21]: https://woocommerce.com/
|
||||
[22]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/Zen-cart.jpg?ssl=1
|
||||
[23]: https://sourceforge.net/projects/zencart/
|
||||
[24]: https://www.zen-cart.com/
|
||||
[25]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/magento.jpg?ssl=1
|
||||
[26]: https://magento.com/compare-open-source-and-magento-commerce
|
||||
[27]: https://github.com/magento
|
||||
[28]: https://magento.com/
|
||||
[29]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/drupal.png?ssl=1
|
||||
[30]: https://www.drupal.org/project/drupal
|
||||
[31]: https://www.drupal.org/industries/ecommerce
|
||||
[32]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/odoo-ecommerce-platform.jpg?w=800&ssl=1
|
||||
[33]: https://itsfoss.com/open-source-accounting-software/
|
||||
[34]: https://github.com/odoo/odoo
|
||||
[35]: https://www.odoo.com/page/open-source-ecommerce
|
@ -0,0 +1,112 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chai-yuan)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11897-1.html)
|
||||
[#]: subject: (Connect Fedora to your Android phone with GSConnect)
|
||||
[#]: via: (https://fedoramagazine.org/connect-fedora-to-your-android-phone-with-gsconnect/)
|
||||
[#]: author: (Lokesh Krishna https://fedoramagazine.org/author/lowkeyskywalker/)
|
||||
|
||||
使用 GSConnect 将 Android 手机连接到 Fedora 系统
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
苹果和微软公司都不同程度的提供了桌面产品与移动设备集成。Fedora 提供了类似甚至更高集成度的工具——GSConnect。它可以让你将安卓手机和你的 Fedora 桌面配对并使用。请继续阅读,以了解更多关于它的情况以及它是如何工作的信息。
|
||||
|
||||
### GSConnect 是什么?
|
||||
|
||||
GSConnect 是针对 GNOME 桌面定制的 KDE Connect 程序。KDE Connect 可以使你的设备能够互相通信。但是,在 Fedora 默认的 GNOME 桌面上安装它需要安装大量的 KDE 依赖。
|
||||
|
||||
GSConnect 是一个 KDE Connect 的完整实现,其以 GNOME shell 的拓展形式出现。安装后,GSConnect 允许你执行以下操作及更多:
|
||||
|
||||
* 在计算机上接收电话通知并回复信息
|
||||
* 用手机操纵你的桌面
|
||||
* 在不同设备之间分享文件与链接
|
||||
* 在计算机上查看手机电量
|
||||
* 让手机响铃以便你能找到它
|
||||
|
||||
### 设置 GSConnect 扩展
|
||||
|
||||
设置 GSConnect 需要安装两个组件:计算机上的 GSConnect 扩展和 Android 设备上的 KDE Connect 应用。
|
||||
|
||||
首先,从 GNOME Shell 扩展网站上安装 [GSConnect][2] 扩展。(Fedora Magazine 有一篇关于[如何安装 GNOME Shell 扩展][3]的文章,可以帮助你完成这一步。)
|
||||
|
||||
KDE Connect 应用程序可以在 Google 的 [Play 商店][4]上找到。它也可以在 FOSS Android 应用程序库 [F-Droid][5] 上找到。
|
||||
|
||||
一旦安装了这两个组件,就可以配对两个设备。安装扩展后它在你的系统菜单中显示为“<ruby>移动设备<rt>Mobile Devices</rt></ruby>”。单击它会出现一个下拉菜单,你可以从中访问“<ruby>移动设置<rt>Mobile Settings</rt></ruby>”。
|
||||
|
||||
![][6]
|
||||
|
||||
你可以在这里用 GSConnect 查看并管理已配对的设备。进入此界面后,需要在 Android 设备上启动应用程序。
|
||||
|
||||
你可以在任意一台设备上进行配对初始化,在这里我们从 Android 设备连接到计算机。点击应用程序上的“刷新”,只要两个设备都在同一个无线网络环境中,你的 Android 设备便可以搜索到你的计算机。现在可以向桌面发送配对请求,并在桌面上接受配对请求以完成配对。
|
||||
|
||||
![][7]
|
||||
|
||||
### 使用 GSConnect
|
||||
|
||||
配对后,你将需要在 Android 设备授予权限,才能使用 GSConnect 上提供的许多功能。单击设备列表中的已配对设备,便可以查看所有可用功能,并根据你的偏好和需要启用或禁用它们。
|
||||
|
||||
![][8]
|
||||
|
||||
请记住,你还需要在这个 Android 应用程序中授予相应的权限才能使用这些功能。启用权限后,你现在可以访问桌面上的移动联系人,获得消息通知并回复消息,甚至同步桌面和 Android 设备的剪贴板。
|
||||
|
||||
### 将你的浏览器与“文件”应用集成
|
||||
|
||||
GSConnect 允许你直接从计算机上的文件资源管理器的关联菜单向 Android 设备发送文件。
|
||||
|
||||
在 Fedora 的默认 GNOME 桌面上,你需要安装 `nautilus-python` 依赖包,以便在关联菜单中显示配对的设备。安装此命令非常简单,只需要在你的首选终端运行以下命令:
|
||||
|
||||
```
|
||||
$ sudo dnf install nautilus-python
|
||||
```
|
||||
|
||||
完成后,将在“<ruby>文件<rt>Files</rt></ruby>”应用的关联菜单中显示“<ruby>发送到移动设备<rt>Send to Mobile Device</rt></ruby>”选项。
|
||||
|
||||
![][9]
|
||||
|
||||
同样,为你的浏览器安装相应的 WebExtension,无论是 [Firefox][10] 还是 [Chrome][11] 浏览器,都可以将链接发送到你的 Android 设备。你可以选择直接发送链接以在浏览器中直接打开,或将其作为短信息发送。
|
||||
|
||||
### 运行命令
|
||||
|
||||
GSConnect 允许你定义命令,然后可以从远程设备在计算机上运行这些命令。这使得你可以远程截屏,或者从你的 Android 设备锁定和解锁你的桌面。
|
||||
|
||||
![][12]
|
||||
|
||||
要使用此功能,可以使用标准的 shell 命令和 GSConnect 提供的 CLI。该项目的 GitHub 存储库(CLI Scripting)中提供了有关此操作的文档。
|
||||
|
||||
[KDE UserBase Wiki][13] 有一个命令示例列表。这些例子包括控制桌面的亮度和音量、锁定鼠标和键盘,甚至更改桌面主题。其中一些命令是针对 KDE Plasma 设计的,需要进行修改才能在 GNOME 桌面上运行。
|
||||
|
||||
### 探索并享受乐趣
|
||||
|
||||
GSConnect 使我们能够享受到极大的便利和舒适。深入研究首选项,查看你可以做的所有事情,灵活的使用这些命令功能发挥创意,并在下面的评论中自由分享你解锁的新方式。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/connect-fedora-to-your-android-phone-with-gsconnect/
|
||||
|
||||
作者:[Lokesh Krishna][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[chai-yuan](https://github.com/chai-yuan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/lowkeyskywalker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/12/gsconnect-816x345.jpg
|
||||
[2]: https://extensions.gnome.org/extension/1319/gsconnect/
|
||||
[3]: https://fedoramagazine.org/install-gnome-shell-extension/
|
||||
[4]: https://play.google.com/store/apps/details?id=org.kde.kdeconnect_tp
|
||||
[5]: https://f-droid.org/en/packages/org.kde.kdeconnect_tp/
|
||||
[6]: https://fedoramagazine.org/wp-content/uploads/2020/01/within-the-menu-1024x576.png
|
||||
[7]: https://fedoramagazine.org/wp-content/uploads/2020/01/pair-request-1024x576.png
|
||||
[8]: https://fedoramagazine.org/wp-content/uploads/2020/01/permissions-1024x576.png
|
||||
[9]: https://fedoramagazine.org/wp-content/uploads/2020/01/send-to-mobile-2-1024x576.png
|
||||
[10]: https://addons.mozilla.org/en-US/firefox/addon/gsconnect/
|
||||
[11]: https://chrome.google.com/webstore/detail/gsconnect/jfnifeihccihocjbfcfhicmmgpjicaec
|
||||
[12]: https://fedoramagazine.org/wp-content/uploads/2020/01/commands-1024x576.png
|
||||
[13]: https://userbase.kde.org/KDE_Connect/Tutorials/Useful_commands
|
||||
[14]: https://unsplash.com/@pathum_danthanarayana?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[15]: https://unsplash.com/s/photos/android?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
@ -0,0 +1,118 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11905-1.html)
|
||||
[#]: subject: (Customize your internet with an open source search engine)
|
||||
[#]: via: (https://opensource.com/article/20/2/open-source-search-engine)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
用开源搜索引擎定制你的互联网
|
||||
======
|
||||
|
||||
> 上手开源的对等 Web 索引器 YaCy。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/19/103541la7erglz7oloa4ye.jpg)
|
||||
|
||||
很久以前,互联网很小,小到几个人就可以索引它们,这些人收集了所有网站的名称和链接,并按主题将它们分别列在页面或印刷书籍中。随着万维网网络的发展,形成了“网站环”形式,具有类似的内容、主题或敏感性的站点捆绑在一起,形成了通往每个成员的循环路径。环中任何站点的访问者都可以单击按钮以转到环中的下一个或上一个站点,以发现与其兴趣相关的新站点。
|
||||
|
||||
又过了一段时间,互联网似乎变得臃肿不堪了。每个人都在网络上,有很多冗余信息和垃圾邮件,多到让你无法找到任何东西。Yahoo 和 AOL、CompuServe 以及类似的服务各自采用了不同的方法来解决这个问题,但是直到谷歌出现后,现代的搜索模型才得以普及。按谷歌的做法,互联网应该通过搜索引擎进行索引、排序和排名。
|
||||
|
||||
### 为什么选择开源替代品?
|
||||
|
||||
像谷歌和 DuckDuckGo 这样的搜索引擎显然是卓有成效的。你可能是通过搜索引擎访问的本站。尽管对于因主机没有选择遵循优化搜索引擎的最佳实践从而导致会内容陷入困境这件事仍存在争论,但用于管理丰富的文化、知识和轻率的信息(即互联网)的现代解决方案是冷冰冰的索引。
|
||||
|
||||
但是也许出于隐私方面的考虑,或者你希望为使互联网更加独立而做出贡献,你或许不愿意使用谷歌或 DuckDuckGo。如果你对此感兴趣,那么可以考虑参加 [YaCy][2],这是一个对等互联网索引器和搜索引擎。
|
||||
|
||||
### 安装 YaCy
|
||||
|
||||
要安装并尝试 YaCy,请首先确保已安装 Java。如果你使用的是 Linux,则可以按照我的《[如何在 Linux 上安装 Java][3]》中的说明进行操作。如果你使用 Windows 或 MacOS,请从 [AdoptOpenJDK.net][4] 获取安装程序。
|
||||
|
||||
安装 Java 后,请根据你的平台[下载安装程序][5]。
|
||||
|
||||
如果你使用的是 Linux,请解压缩 tarball 并将其移至 `/opt` 目录:
|
||||
|
||||
```
|
||||
$ sudo tar --extract --file yacy_*z --directory /opt
|
||||
```
|
||||
|
||||
根据下载的安装程序的说明启动 YaCy。
|
||||
|
||||
在 Linux 上,启动在后台运行的 YaCy:
|
||||
|
||||
```
|
||||
$ /opt/startYACY.sh &
|
||||
```
|
||||
|
||||
在 Web 浏览器中,导航到 `localhost:8090` 并进行搜索。
|
||||
|
||||
![YaCy start page][6]
|
||||
|
||||
### 将 YaCy 添加到你的地址栏
|
||||
|
||||
如果你使用的是 Firefox Web 浏览器,则只需单击几下,即可在 Awesome Bar(Mozilla 给 URL 栏起的名称)中将 YaCy 设置为默认搜索引擎。
|
||||
|
||||
首先,如果尚未显示,在 Firefox 工具栏中使专用搜索栏显示出来(你不必使搜索栏保持一直可见;只需要激活它足够长的时间即可添加自定义搜索引擎)。Firefox 右上角的“汉堡”菜单中的“自定义”菜单中提供了搜索栏。在 Firefox 工具栏上的搜索栏可见后,导航至 `localhost:8090`,然后单击刚添加的 Firefox 搜索栏中的放大镜图标。单击选项将 YaCy 添加到你的 Firefox 的搜索引擎中。
|
||||
|
||||
![Adding YaCy to Firefox][7]
|
||||
|
||||
完成此操作后,你可以在 Firefox 首选项中将其标记为默认值,或者仅在 Firefox 搜索栏中执行的搜索中选择性地使用它。如果将其设置为默认搜索引擎,则可能不需要专用搜索栏,因为 Awesome Bar 也使用默认引擎,因此可以将其从工具栏中删除。
|
||||
|
||||
### 对等搜索引擎如何工作
|
||||
|
||||
YaCy 是一个开源的分布式搜索引擎。它是用 [Java][8] 编写的,因此可以在任何平台上运行,并且可以执行 Web 爬网、索引和搜索。这是一个对等(P2P)网络,因此每个运行 YaCy 的用户都将努力地不断跟踪互联网的变化情况。当然,没有单个用户能拥有整个互联网的完整索引,因为这将需要一个数据中心来容纳,但是该索引分布在所有 YaCy 用户中且是冗余的。它与 BitTorrent 非常相似(因为它使用分布式哈希表 DHT 来引用索引条目),只不过你所共享的数据是单词和 URL 关联的矩阵。通过混合哈希表返回的结果,没人能说出谁搜索了哪些单词,因此所有搜索在功能上都是匿名的。这是用于无偏见、无广告、未跟踪和匿名搜索的有效系统,你只需要使用它就加入了它。
|
||||
|
||||
### 搜索引擎和算法
|
||||
|
||||
索引互联网的行为是指将网页分成单个单词,然后将页面的 URL 与每个单词相关联。在搜索引擎中搜索一个或多个单词将获取与该查询关联的所有 URL。YaCy 客户端在运行时也是如此。
|
||||
|
||||
客户端要做的另一件事是为你的浏览器提供搜索界面。你可以将 Web 浏览器指向 `localhost:8090` 来搜索 YaCy,而不是在要搜索时导航到谷歌。你甚至可以将其添加到浏览器的搜索栏中(取决于浏览器的可扩展性),因此可以从 URL 栏中进行搜索。
|
||||
|
||||
### YaCy 的防火墙设置
|
||||
|
||||
首次开始使用 YaCy 时,它可能运行在“初级”模式下。这意味着你的客户端爬网的站点仅对你可用,因为其他 YaCy 客户端无法访问你的索引条目。要加入对等环境,必须在路由器的防火墙(或者你正在运行的软件防火墙)中打开端口 8090,这称为“高级”模式。
|
||||
|
||||
如果你使用的是 Linux,则可以在《[使用防火墙让你的 Linux 更加强大][9]》中找到有关计算机防火墙的更多信息。在其他平台上,请参考操作系统的文档。
|
||||
|
||||
互联网服务提供商(ISP)提供的路由器上几乎总是启用了防火墙,并且有太多种类的防火墙无法准确说明。大多数路由器都提供了在防火墙上“打洞”的选项,因为许多流行的联网游戏都需要双向流量。
|
||||
|
||||
如果你知道如何登录路由器(通常为 192.168.0.1 或 10.1.0.1,但可能因制造商的设置而异),则登录并查找配置面板来控制“防火墙”或“端口转发”或“应用”。
|
||||
|
||||
找到路由器防火墙的首选项后,将端口 8090 添加到白名单。例如:
|
||||
|
||||
![Adding YaCy to an ISP router][10]
|
||||
|
||||
如果路由器正在进行端口转发,则必须使用相同的端口将传入的流量转发到计算机的 IP 地址。例如:
|
||||
|
||||
![Adding YaCy to an ISP router][11]
|
||||
|
||||
如果由于某种原因无法调整防火墙设置,那也没事。YaCy 将继续以初级模式运行并作为对等搜索网络的客户端运行。
|
||||
|
||||
### 你的互联网
|
||||
|
||||
使用 YaCy 搜索引擎可以做的不仅仅是被动搜索。你可以强制抓取不太显眼的网站,可以请求对网站进行网络抓取,可以选择使用 YaCy 进行本地搜索等等。你可以更好地控制*你的*互联网的所呈现的一切。高级用户越多,索引的网站就越多。索引的网站越多,所有用户的体验就越好。加入吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/open-source-search-engine
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
|
||||
[2]: https://yacy.net/
|
||||
[3]: https://linux.cn/article-11614-1.html
|
||||
[4]: https://adoptopenjdk.net/releases.html
|
||||
[5]: https://yacy.net/download_installation/
|
||||
[6]: https://opensource.com/sites/default/files/uploads/yacy-startpage.jpg (YaCy start page)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/yacy-add-firefox.jpg (Adding YaCy to Firefox)
|
||||
[8]: https://opensource.com/resources/java
|
||||
[9]: https://opensource.com/article/19/7/make-linux-stronger-firewalls
|
||||
[10]: https://opensource.com/sites/default/files/uploads/router-add-app.jpg (Adding YaCy to an ISP router)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/router-add-app1.jpg (Adding YaCy to an ISP router)
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11888-1.html)
|
||||
[#]: subject: (NVIDIA’s Cloud Gaming Service GeForce NOW Shamelessly Ignores Linux)
|
||||
[#]: via: (https://itsfoss.com/geforce-now-linux/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
NVIDIA 的云游戏服务 GeForce NOW 无耻地忽略了Linux
|
||||
======
|
||||
|
||||
NVIDIA 的 [GeForce NOW][1] 云游戏服务对于那些可能没有硬件但想使用 GeForce NOW 在最新的最好的游戏上获得尽可能好的游戏体验玩家来说是充满前景的(在线推流游戏,并可以在任何设备上玩)。
|
||||
|
||||
该服务仅限于一些用户(以等待列表的形式)使用。然而,他们最近宣布 [GeForce NOW 面向所有人开放][2]。但实际上并不是。
|
||||
|
||||
有趣的是,它**并不是面向全球所有区域**。而且,更糟的是 **GeForce NOW 不支持 Linux**。
|
||||
|
||||
![][3]
|
||||
|
||||
### GeForce NOW 并不是向“所有人开放”
|
||||
|
||||
制作一个基于订阅的云服务来玩游戏的目的是消除平台依赖性。
|
||||
|
||||
就像你通常使用浏览器访问网站一样,你应该能够在每个平台上玩游戏。是这个概念吧?
|
||||
|
||||
![][4]
|
||||
|
||||
好吧,这绝对不是火箭科学,但是 NVIDIA 仍然不支持 Linux(和 iOS)?
|
||||
|
||||
### 是因为没有人使用 Linux 吗?
|
||||
|
||||
我非常不同意这一点,即使这是某些不支持 Linux 的原因。如果真是这样,我不会使用 Linux 作为主要桌面操作系统来为 “It’s FOSS” 写文章。
|
||||
|
||||
不仅如此,如果 Linux 不值一提,你认为为何一个 Twitter 用户会提到缺少 Linux 支持?
|
||||
|
||||
![][5]
|
||||
|
||||
是的,也许用户群不够大,但是在考虑将其作为基于云的服务时,**不支持 Linux** 显得没有意义。
|
||||
|
||||
从技术上讲,如果 Linux 上没有游戏,那么 **Valve** 就不会在 Linux 上改进 [Steam Play][6] 来帮助更多用户在 Linux 上玩纯 Windows 的游戏。
|
||||
|
||||
我不想说任何不正确的说法,但台式机 Linux 游戏的发展比以往任何时候都要快(即使统计上要比 Mac 和 Windows 要低)。
|
||||
|
||||
### 云游戏不应该像这样
|
||||
|
||||
![][7]
|
||||
|
||||
如上所述,找到使用 Steam Play 的 Linux 玩家不难。只是你会发现 Linux 上游戏玩家的整体“市场份额”低于其他平台。
|
||||
|
||||
即使这是事实,云游戏也不应该依赖于特定平台。而且,考虑到 GeForce NOW 本质上是一种基于浏览器的可以玩游戏的流媒体服务,所以对于像 NVIDIA 这样的大公司来说,支持 Linux 并不困难。
|
||||
|
||||
来吧,Nvidia,*你想要我们相信在技术上支持 Linux 有困难?或者,你只是想说不值得支持 Linux 平台?*
|
||||
|
||||
### 结语
|
||||
|
||||
不管我为 GeForce NOW 服务发布而感到多么兴奋,当看到它根本不支持 Linux,我感到非常失望。
|
||||
|
||||
如果像 GeForce NOW 这样的云游戏服务在不久的将来开始支持 Linux,**你可能没有理由使用 Windows 了**(*咳嗽*)。
|
||||
|
||||
你怎么看待这件事?在下面的评论中让我知道你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/geforce-now-linux/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.nvidia.com/en-us/geforce-now/
|
||||
[2]: https://blogs.nvidia.com/blog/2020/02/04/geforce-now-pc-gaming/
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/nvidia-geforce-now-linux.jpg?ssl=1
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/nvidia-geforce-now.png?ssl=1
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/geforce-now-twitter-1.jpg?ssl=1
|
||||
[6]: https://itsfoss.com/steam-play/
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/ge-force-now.jpg?ssl=1
|
@ -0,0 +1,98 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11916-1.html)
|
||||
[#]: subject: (What is WireGuard? Why Linux Users Going Crazy Over it?)
|
||||
[#]: via: (https://itsfoss.com/wireguard/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
什么是 WireGuard?为什么 Linux 用户为它疯狂?
|
||||
======
|
||||
|
||||
从普通的 Linux 用户到 Linux 创建者 [Linus Torvalds][1],每个人都对 WireGuard 很感兴趣。什么是 WireGuard,它为何如此特别?
|
||||
|
||||
### 什么是 WireGuard?
|
||||
|
||||
![][2]
|
||||
|
||||
[WireGuard][3] 是一个易于配置、快速且安全的开源 [VPN][4],它利用了最新的加密技术。目的是提供一种更快、更简单、更精简的通用 VPN,它可以轻松地在树莓派这类低端设备到高端服务器上部署。
|
||||
|
||||
[IPsec][5] 和 OpenVPN 等大多数其他解决方案是几十年前开发的。安全研究人员和内核开发人员 Jason Donenfeld 意识到它们速度慢且难以正确配置和管理。
|
||||
|
||||
这让他创建了一个新的开源 VPN 协议和解决方案,它更加快速、安全、易于部署和管理。
|
||||
|
||||
WireGuard 最初是为 Linux 开发的,但现在可用于 Windows、macOS、BSD、iOS 和 Android。它仍在活跃开发中。
|
||||
|
||||
### 为什么 WireGuard 如此受欢迎?
|
||||
|
||||
![][6]
|
||||
|
||||
除了可以跨平台之外,WireGuard 的最大优点之一就是易于部署。配置和部署 WireGuard 就像配置和使用 SSH 一样容易。
|
||||
|
||||
看看 [WireGuard 设置指南][7]。安装 WireGuard、生成公钥和私钥(像 SSH 一样),设置防火墙规则并启动服务。现在将它和 [OpenVPN 设置指南][8]进行比较——有太多要做的了。
|
||||
|
||||
WireGuard 的另一个好处是它有一个仅 4000 行代码的精简代码库。将它与 [OpenVPN][9](另一个流行的开源 VPN)的 100,000 行代码相比。显然,调试 WireGuard 更加容易。
|
||||
|
||||
不要因其简单而小看它。WireGuard 支持所有最新的加密技术,例如 [Noise 协议框架][10]、[Curve25519][11]、[ChaCha20][12]、[Poly1305][13]、[BLAKE2][14]、[SipHash24][15]、[HKDF][16] 和安全受信任结构。
|
||||
|
||||
由于 WireGuard 运行在[内核空间][17],因此可以高速提供安全的网络。
|
||||
|
||||
这些是 WireGuard 越来越受欢迎的一些原因。Linux 创造者 Linus Torvalds 非常喜欢 WireGuard,以至于将其合并到 [Linux Kernel 5.6][18] 中:
|
||||
|
||||
> 我能否再次声明对它的爱,并希望它能很快合并?也许代码不是完美的,但我不在乎,与 OpenVPN 和 IPSec 的恐怖相比,这是一件艺术品。
|
||||
>
|
||||
> Linus Torvalds
|
||||
|
||||
### 如果 WireGuard 已经可用,那么将其包含在 Linux 内核中有什么大惊小怪的?
|
||||
|
||||
这可能会让新的 Linux 用户感到困惑。你知道可以在 Linux 上安装和配置 WireGuard VPN 服务器,但同时也会看到 Linux Kernel 5.6 将包含 WireGuard 的消息。让我向您解释。
|
||||
|
||||
目前,你可以将 WireGuard 作为[内核模块][19]安装在 Linux 中。而诸如 VLC、GIMP 等常规应用安装在 Linux 内核之上(在 [用户空间][20]中),而不是内部。
|
||||
|
||||
当将 WireGuard 安装为内核模块时,基本上需要你自行修改 Linux 内核并向其添加代码。从 5.6 内核开始,你无需手动添加内核模块。默认情况下它将包含在内核中。
|
||||
|
||||
在 5.6 内核中包含 WireGuard 很有可能[扩展 WireGuard 的采用,从而改变当前的 VPN 场景][21]。
|
||||
|
||||
### 总结
|
||||
|
||||
WireGuard 之所以受欢迎是有充分理由的。诸如 [Mullvad VPN][23] 之类的一些流行的[关注隐私的 VPN][22] 已经在使用 WireGuard,并且在不久的将来,采用率可能还会增长。
|
||||
|
||||
希望你对 WireGuard 有所了解。与往常一样,欢迎提供反馈。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/wireguard/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/linus-torvalds-facts/
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/wireguard.png?ssl=1
|
||||
[3]: https://www.wireguard.com/
|
||||
[4]: https://en.wikipedia.org/wiki/Virtual_private_network
|
||||
[5]: https://en.wikipedia.org/wiki/IPsec
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/wireguard-logo.png?ssl=1
|
||||
[7]: https://www.linode.com/docs/networking/vpn/set-up-wireguard-vpn-on-ubuntu/
|
||||
[8]: https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04
|
||||
[9]: https://openvpn.net/
|
||||
[10]: https://noiseprotocol.org/
|
||||
[11]: https://cr.yp.to/ecdh.html
|
||||
[12]: https://cr.yp.to/chacha.html
|
||||
[13]: https://cr.yp.to/mac.html
|
||||
[14]: https://blake2.net/
|
||||
[15]: https://131002.net/siphash/
|
||||
[16]: https://eprint.iacr.org/2010/264
|
||||
[17]: http://www.linfo.org/kernel_space.html
|
||||
[18]: https://itsfoss.com/linux-kernel-5-6/
|
||||
[19]: https://wiki.archlinux.org/index.php/Kernel_module
|
||||
[20]: http://www.linfo.org/user_space.html
|
||||
[21]: https://www.zdnet.com/article/vpns-will-change-forever-with-the-arrival-of-wireguard-into-linux/
|
||||
[22]: https://itsfoss.com/best-vpn-linux/
|
||||
[23]: https://mullvad.net/en/
|
@ -0,0 +1,114 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11906-1.html)
|
||||
[#]: subject: (Install All Essential Media Codecs in Ubuntu With This Single Command [Beginner’s Tip])
|
||||
[#]: via: (https://itsfoss.com/install-media-codecs-ubuntu/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
一条命令在 Ubuntu 中安装所有基本的媒体编解码器
|
||||
======
|
||||
|
||||
如果你刚刚安装了 Ubuntu 或其他 [Ubuntu 特色版本][1] 如 Kubuntu、Lubuntu 等,你会注意到系统无法播放某些音频或视频文件。
|
||||
|
||||
对于视频文件,你可以[在 Ubuntu 上安装 VLC][2]。[VLC][3] 是 [Linux 上的最佳视频播放器][4]之一,它几乎可以播放任何视频文件格式。但你仍然会遇到无法播放音频和 flash 的麻烦。
|
||||
|
||||
好消息是 [Ubuntu][5] 提供了一个软件包来安装所有基本的媒体编解码器:ubuntu-restricted-extras。
|
||||
|
||||
![][6]
|
||||
|
||||
### 什么是 Ubuntu Restricted Extras?
|
||||
|
||||
ubuntu-restricted-extras 是一个包含各种基本软件,如 Flash 插件、[unrar][7]、[gstreamer][8]、mp4、[Ubuntu 中的 Chromium 浏览器][9]的编解码器等的软件包。
|
||||
|
||||
由于这些软件不是开源软件,并且其中一些涉及软件专利,因此 Ubuntu 默认情况下不会安装它们。你必须使用 multiverse 仓库,它是 Ubuntu 专门为用户提供非开源软件而创建的仓库。
|
||||
|
||||
请阅读本文以[了解有关各种 Ubuntu 仓库的更多信息][10]。
|
||||
|
||||
### 如何安装 Ubuntu Restricted Extras?
|
||||
|
||||
令我惊讶的是,我发现软件中心未列出 Ubuntu Restricted Extras。不管怎样,你都可以使用命令行安装该软件包,这非常简单。
|
||||
|
||||
在菜单中搜索或使用[终端键盘快捷键 Ctrl+Alt+T][11] 打开终端。
|
||||
|
||||
由于 ubuntu-restrcited-extras 软件包在 multiverse 仓库中,因此你应验证系统上已启用 multiverse 仓库:
|
||||
|
||||
```
|
||||
sudo add-apt-repository multiverse
|
||||
```
|
||||
|
||||
然后你可以使用以下命令安装:
|
||||
|
||||
```
|
||||
sudo apt install ubuntu-restricted-extras
|
||||
```
|
||||
|
||||
输入回车后,你会被要求输入密码,**当你输入密码时,屏幕不会有显示**。这是正常的。输入你的密码并回车。
|
||||
|
||||
它将显示大量要安装的包。按回车确认选择。
|
||||
|
||||
你会看到 [EULA][12](最终用户许可协议),如下所示:
|
||||
|
||||
![Press Tab key to select OK and press Enter key][13]
|
||||
|
||||
浏览此页面可能会很麻烦,但是请放心。只需按 Tab 键,它将高亮选项。当高亮在正确的选项上,按下回车确认你的选择。
|
||||
|
||||
![Press Tab key to highlight Yes and press Enter key][14]
|
||||
|
||||
安装完成后,由于新安装的媒体编解码器,你应该可以播放 MP3 和其他媒体格式了。
|
||||
|
||||
##### 在 Kubuntu、Lubuntu、Xubuntu 上安装受限制的额外软件包
|
||||
|
||||
请记住,Kubuntu、Lubuntu 和 Xubuntu 都有此软件包,并有各自不同的名称。它们本应使用相同的名字,但不幸的是并不是。
|
||||
|
||||
在 Kubuntu 上,使用以下命令:
|
||||
|
||||
```
|
||||
sudo apt install kubuntu-restricted-extras
|
||||
```
|
||||
|
||||
在 Lubuntu 上,使用:
|
||||
|
||||
```
|
||||
sudo apt install lubuntu-restricted-extras
|
||||
```
|
||||
|
||||
在 Xubuntu 上,你应该使用:
|
||||
|
||||
```
|
||||
sudo apt install xubuntu-restricted-extras
|
||||
```
|
||||
|
||||
我一直建议将 ubuntu-restricted-extras 作为[安装 Ubuntu 后要做的基本事情][15]之一。只需一个命令即可在 Ubuntu 中安装多个编解码器。
|
||||
|
||||
希望你喜欢 Ubuntu 初学者系列中这一技巧。以后,我将分享更多此类技巧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-media-codecs-ubuntu/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/which-ubuntu-install/
|
||||
[2]: https://itsfoss.com/install-latest-vlc/
|
||||
[3]: https://www.videolan.org/index.html
|
||||
[4]: https://itsfoss.com/video-players-linux/
|
||||
[5]: https://ubuntu.com/
|
||||
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/Media_Codecs_in_Ubuntu.png?ssl=1
|
||||
[7]: https://itsfoss.com/use-rar-ubuntu-linux/
|
||||
[8]: https://gstreamer.freedesktop.org/
|
||||
[9]: https://itsfoss.com/install-chromium-ubuntu/
|
||||
[10]: https://itsfoss.com/ubuntu-repositories/
|
||||
[11]: https://itsfoss.com/ubuntu-shortcuts/
|
||||
[12]: https://en.wikipedia.org/wiki/End-user_license_agreement
|
||||
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/installing_ubuntu_restricted_extras.jpg?ssl=1
|
||||
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/installing_ubuntu_restricted_extras_1.jpg?ssl=1
|
||||
[15]: https://itsfoss.com/things-to-do-after-installing-ubuntu-18-04/
|
@ -0,0 +1,118 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chai-yuan)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11909-1.html)
|
||||
[#]: subject: (Playing Music on your Fedora Terminal with MPD and ncmpcpp)
|
||||
[#]: via: (https://fedoramagazine.org/playing-music-on-your-fedora-terminal-with-mpd-and-ncmpcpp/)
|
||||
[#]: author: (Carmine Zaccagnino https://fedoramagazine.org/author/carzacc/)
|
||||
|
||||
在你的 Fedora 终端上播放音乐
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
MPD(Music Playing Daemon),顾名思义,是一个音乐(Music)播放(Playing)守护进程(Daemon)。它可以播放音乐,并且作为一个守护进程,任何软件都可以与之交互并播放声音,包括一些 CLI 客户端。
|
||||
|
||||
其中一个被称为 `ncmpcpp`,它是对之前 `ncmpc` 工具的改进。名字的变化与编写它们的语言没有太大关系:都是 C++,而之所以被称为 `ncmpcpp`,因为它是 “NCurses Music Playing Client Plus Plus”。 缘故
|
||||
|
||||
### 安装 MPD 和 ncmpcpp
|
||||
|
||||
`ncmpmpcc` 的客户端可以从官方 Fedora 库中通过 `dnf` 命令直接安装。
|
||||
|
||||
```
|
||||
$ sudo dnf install ncmpcpp
|
||||
```
|
||||
|
||||
另一方面,MPD 必须从 RPMFusion free 库安装,你可以通过运行:
|
||||
|
||||
```
|
||||
$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
|
||||
```
|
||||
|
||||
然后你可以运行下面的命令安装它:
|
||||
|
||||
```
|
||||
$ sudo dnf install mpd
|
||||
```
|
||||
|
||||
### 配置并启用 MPD
|
||||
|
||||
设置 MPD 最简单的方法是以普通用户的身份运行它。默认情况是以专用 `mpd` 用户的身份运行它,但这会导致各种权限问题。
|
||||
|
||||
在运行它之前,我们需要创建一个本地配置文件,允许我们作为普通用户运行。
|
||||
|
||||
首先在 `~/.config` 里创建一个名叫 `mpd` 的目录:
|
||||
|
||||
```
|
||||
$ mkdir ~/.config/mpd
|
||||
```
|
||||
|
||||
将配置文件拷贝到此目录下:
|
||||
|
||||
```
|
||||
$ cp /etc/mpd.conf ~/.config/mpd
|
||||
```
|
||||
|
||||
然后用 `vim`、`nano` 或 `gedit` 之类的软件编辑它:
|
||||
|
||||
```
|
||||
$ nano ~/.config/mpd/mpd.conf
|
||||
```
|
||||
|
||||
我建议你通读所有内容,检查是否有任何需要做的事情,但对于大多数设置你都可以删除,只需保留以下内容:
|
||||
|
||||
```
|
||||
db_file "~/.config/mpd/mpd.db"
|
||||
log_file "syslog"
|
||||
```
|
||||
|
||||
现在你可以运行它了:
|
||||
|
||||
```
|
||||
$ mpd
|
||||
```
|
||||
|
||||
没有报错,这将在后台启动 MPD 守护进程。
|
||||
|
||||
### 使用 ncmpcpp
|
||||
|
||||
只需运行:
|
||||
|
||||
```
|
||||
$ ncmpcpp
|
||||
```
|
||||
|
||||
你将在终端中看到一个由 ncurses 所支持的图形用户界面。
|
||||
|
||||
按下 `4` 键,然后就可以看到本地的音乐目录,用方向键进行选择并按下回车进行播放。
|
||||
|
||||
多播放几个歌曲就会创建一个*播放列表*,让你可以使用 `>` 键(不是右箭头, 是右尖括号)移动到下一首,并使用 `<` 返回上一首。`+` 和 `–` 键可以调节音量。`Q` 键可以让你退出 `ncmpcpp` 但不停止播放音乐。你可以按下 `P` 来控制暂停和播放。
|
||||
|
||||
你可以按下 `1` 键来查看当前播放列表(这是默认的视图)。从这个视图中,你可以按 `i` 查看有关当前歌曲的信息(标签)。按 `6` 可更改当前歌曲的标签。
|
||||
|
||||
按 `\` 按钮将在视图顶部添加(或删除)信息面板。在左上角,你可以看到如下的内容:
|
||||
|
||||
```
|
||||
[------]
|
||||
```
|
||||
|
||||
按下 `r`、`z`、`y`、`R`、`x` 将会分别切换到 `repeat`、`random`、`single`、`consume` 和 `crossfade` 等播放模式,并将这个小指示器中的 `–` 字符替换为选定模式。
|
||||
|
||||
按下 `F1` 键将会显示一些帮助文档,包含一系列的键绑定列表,因此无需在此处列出完整列表。所以继续吧!做一个极客,在你的终端上播放音乐!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/playing-music-on-your-fedora-terminal-with-mpd-and-ncmpcpp/
|
||||
|
||||
作者:[Carmine Zaccagnino][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[chai-yuan](https://github.com/chai-yuan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/carzacc/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/02/play_music_mpd-816x346.png
|
||||
[2]: https://rpmfusion.org/Configuration
|
@ -0,0 +1,220 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11936-1.html)
|
||||
[#]: subject: (Scan Kubernetes for errors with KRAWL)
|
||||
[#]: via: (https://opensource.com/article/20/2/kubernetes-scanner)
|
||||
[#]: author: (Abhishek Tamrakar https://opensource.com/users/tamrakar)
|
||||
|
||||
使用 KRAWL 扫描 Kubernetes 错误
|
||||
======
|
||||
|
||||
> 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。
|
||||
|
||||
![Ship captain sailing the Kubernetes seas][1]
|
||||
|
||||
当你使用 Kubernetes 运行容器时,你通常会发现它们堆积在一起。这是设计使然。它是容器的优点之一:每当需要新的容器时,它们启动成本都很低。你可以使用前端工具(如 OpenShift 或 OKD)来管理 Pod 和容器。这些工具使可视化设置变得容易,并且它具有一组丰富的用于快速交互的命令。
|
||||
|
||||
如果管理容器的平台不符合你的要求,你也可以仅使用 Kubernetes 工具链获取这些信息,但这需要大量命令才能全面了解复杂环境。出于这个原因,我编写了 [KRAWL][2],这是一个简单的脚本,可用于扫描 Kubernetes 集群命名空间下的 Pod 和容器,并在发现任何事件时,显示事件的输出。它也可用作为 Kubernetes 插件使用。这是获取大量有用信息的快速简便方法。
|
||||
|
||||
### 先决条件
|
||||
|
||||
* 必须安装 `kubectl`。
|
||||
* 集群的 kubeconfig 配置必须在它的默认位置(`$HOME/.kube/config`)或已被导出到环境变量(`KUBECONFIG=/path/to/kubeconfig`)。
|
||||
|
||||
### 使用
|
||||
|
||||
|
||||
```
|
||||
$ ./krawl
|
||||
```
|
||||
|
||||
![KRAWL script][3]
|
||||
|
||||
### 脚本
|
||||
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
# AUTHOR: Abhishek Tamrakar
|
||||
# EMAIL: abhishek.tamrakar08@gmail.com
|
||||
# LICENSE: Copyright (C) 2018 Abhishek Tamrakar
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
##
|
||||
#define the variables
|
||||
KUBE_LOC=~/.kube/config
|
||||
#define variables
|
||||
KUBECTL=$(which kubectl)
|
||||
GET=$(which egrep)
|
||||
AWK=$(which awk)
|
||||
red=$(tput setaf 1)
|
||||
normal=$(tput sgr0)
|
||||
# define functions
|
||||
|
||||
# wrapper for printing info messages
|
||||
info()
|
||||
{
|
||||
printf '\n\e[34m%s\e[m: %s\n' "INFO" "$@"
|
||||
}
|
||||
|
||||
# cleanup when all done
|
||||
cleanup()
|
||||
{
|
||||
rm -f results.csv
|
||||
}
|
||||
|
||||
# just check if the command we are about to call is available
|
||||
checkcmd()
|
||||
{
|
||||
#check if command exists
|
||||
local cmd=$1
|
||||
if [ -z "${!cmd}" ]
|
||||
then
|
||||
printf '\n\e[31m%s\e[m: %s\n' "ERROR" "check if $1 is installed !!!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_namespaces()
|
||||
{
|
||||
#get namespaces
|
||||
namespaces=( \
|
||||
$($KUBECTL get namespaces --ignore-not-found=true | \
|
||||
$AWK '/Active/ {print $1}' \
|
||||
ORS=" ") \
|
||||
)
|
||||
#exit if namespaces are not found
|
||||
if [ ${#namespaces[@]} -eq 0 ]
|
||||
then
|
||||
printf '\n\e[31m%s\e[m: %s\n' "ERROR" "No namespaces found!!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#get events for pods in errored state
|
||||
get_pod_events()
|
||||
{
|
||||
printf '\n'
|
||||
if [ ${#ERRORED[@]} -ne 0 ]
|
||||
then
|
||||
info "${#ERRORED[@]} errored pods found."
|
||||
for CULPRIT in ${ERRORED[@]}
|
||||
do
|
||||
info "POD: $CULPRIT"
|
||||
info
|
||||
$KUBECTL get events \
|
||||
--field-selector=involvedObject.name=$CULPRIT \
|
||||
-ocustom-columns=LASTSEEN:.lastTimestamp,REASON:.reason,MESSAGE:.message \
|
||||
--all-namespaces \
|
||||
--ignore-not-found=true
|
||||
done
|
||||
else
|
||||
info "0 pods with errored events found."
|
||||
fi
|
||||
}
|
||||
|
||||
#define the logic
|
||||
get_pod_errors()
|
||||
{
|
||||
printf "%s %s %s\n" "NAMESPACE,POD_NAME,CONTAINER_NAME,ERRORS" > results.csv
|
||||
printf "%s %s %s\n" "---------,--------,--------------,------" >> results.csv
|
||||
for NAMESPACE in ${namespaces[@]}
|
||||
do
|
||||
while IFS=' ' read -r POD CONTAINERS
|
||||
do
|
||||
for CONTAINER in ${CONTAINERS//,/ }
|
||||
do
|
||||
COUNT=$($KUBECTL logs --since=1h --tail=20 $POD -c $CONTAINER -n $NAMESPACE 2>/dev/null| \
|
||||
$GET -c '^error|Error|ERROR|Warn|WARN')
|
||||
if [ $COUNT -gt 0 ]
|
||||
then
|
||||
STATE=("${STATE[@]}" "$NAMESPACE,$POD,$CONTAINER,$COUNT")
|
||||
else
|
||||
#catch pods in errored state
|
||||
ERRORED=($($KUBECTL get pods -n $NAMESPACE --no-headers=true | \
|
||||
awk '!/Running/ {print $1}' ORS=" ") \
|
||||
)
|
||||
fi
|
||||
done
|
||||
done< <($KUBECTL get pods -n $NAMESPACE --ignore-not-found=true -o=custom-columns=NAME:.metadata.name,CONTAINERS:.spec.containers[*].name --no-headers=true)
|
||||
done
|
||||
printf "%s\n" ${STATE[@]:-None} >> results.csv
|
||||
STATE=()
|
||||
}
|
||||
#define usage for seprate run
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
|
||||
USAGE: "${0##*/} </path/to/kube-config>(optional)"
|
||||
|
||||
This program is a free software under the terms of Apache 2.0 License.
|
||||
COPYRIGHT (C) 2018 Abhishek Tamrakar
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
#check if basic commands are found
|
||||
trap cleanup EXIT
|
||||
checkcmd KUBECTL
|
||||
#
|
||||
#set the ground
|
||||
if [ $# -lt 1 ]; then
|
||||
if [ ! -e ${KUBE_LOC} -a ! -s ${KUBE_LOC} ]
|
||||
then
|
||||
info "A readable kube config location is required!!"
|
||||
usage
|
||||
fi
|
||||
elif [ $# -eq 1 ]
|
||||
then
|
||||
export KUBECONFIG=$1
|
||||
elif [ $# -gt 1 ]
|
||||
then
|
||||
usage
|
||||
fi
|
||||
#play
|
||||
get_namespaces
|
||||
get_pod_errors
|
||||
|
||||
printf '\n%40s\n' 'KRAWL'
|
||||
printf '%s\n' '---------------------------------------------------------------------------------'
|
||||
printf '%s\n' ' Krawl is a command line utility to scan pods and prints name of errored pods '
|
||||
printf '%s\n\n' ' +and containers within. To use it as kubernetes plugin, please check their page '
|
||||
printf '%s\n' '================================================================================='
|
||||
|
||||
cat results.csv | sed 's/,/,|/g'| column -s ',' -t
|
||||
get_pod_events
|
||||
```
|
||||
|
||||
此文最初发布在 [KRAWL 的 GitHub 仓库][2]下的 README 中,并被或许重用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/kubernetes-scanner
|
||||
|
||||
作者:[Abhishek Tamrakar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/tamrakar
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/ship_captain_devops_kubernetes_steer.png?itok=LAHfIpek (Ship captain sailing the Kubernetes seas)
|
||||
[2]: https://github.com/abhiTamrakar/kube-plugins/tree/master/krawl
|
||||
[3]: https://opensource.com/sites/default/files/uploads/krawl_0.png (KRAWL script)
|
||||
[4]: mailto:abhishek.tamrakar08@gmail.com
|
@ -0,0 +1,101 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11919-1.html)
|
||||
[#]: subject: (Top hacks for the YaCy open source search engine)
|
||||
[#]: via: (https://opensource.com/article/20/2/yacy-search-engine-hacks)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
使用开源搜索引擎 YaCy 的技巧
|
||||
======
|
||||
|
||||
> 无需适应其他人的眼光,而是使用 YaCY 搜索引擎定义你想要的互联网。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/23/115822jqkdyjwzdqwdad0y.jpg)
|
||||
|
||||
在我以前介绍 [YaCy 入门][2]的文章中讲述过 [YaCy][3] 这个<ruby>对等<rt>peer-to-peer</rt></ruby>式的搜索引擎是如何安装和使用的。YaCy 最令人兴奋的一点就是它事实上是一个本地客户端,全球范围内的每一个 YaCy 用户都是构成整个这个分布式搜索引擎架构的一个节点,这意味着每个用户都可以掌控自己的互联网搜索体验。
|
||||
|
||||
Google 曾经提供过 google.com/linux 这样的主题简便方式以便快速筛选出和 Linux 相关的搜索内容,这个小功能受到了很多人的青睐,但 Google 最终还是在 2011 年的时候把它[下线][4]了。
|
||||
|
||||
而 YaCy 则让自定义搜索引擎变得可能。
|
||||
|
||||
### 自定义 YaCy
|
||||
|
||||
YaCy 安装好之后,只需要访问 `localhost:8090` 就可以使用了。要自定义搜索引擎,只需要点击右上角的“<ruby>管理<rt>Administration</rt></ruby>”按钮(它可能隐藏在小屏幕的菜单图标中)。
|
||||
|
||||
你可以在管理面板中配置 YaCy 对系统资源的使用策略,以及如何跟其它的 YaCy 客户端进行交互。
|
||||
|
||||
![YaCy profile selector][5]
|
||||
|
||||
例如,点击侧栏中的“<ruby>第一步<rt>First steps</rt></ruby>”按钮可以配置备用端口,以及设置 YaCy 对内存和硬盘的使用量;而“<ruby>监控<rt>Monitoring</rt></ruby>”面板则可以监控 YaCy 的运行状况。大多数功能都只需要在面板上点击几下就可以完成了,例如以下几个常用的功能。
|
||||
|
||||
### 内网搜索应用
|
||||
|
||||
目前市面上也有不少公司推出了[内网搜索应用][6],而 YaCy 可以免费为你提供一个。对于能够通过 HTTP、FTP、Samba 等协议访问的文件,YaCy 都可以进行索引,因此无论是作为私人的文件搜索还是企业内部的本地共享文件搜索,YaCy 都可以实现。它可以让内部网络中的用户使用你个人的 YaCy 实例来查找共享文件,于此同时保持对内部网络以外的用户不可见。
|
||||
|
||||
### 网络配置
|
||||
|
||||
YaCy 在默认情况下就支持隐私和隔离。点击“<ruby>用例与账号<rt>Use Case & Account</rt></ruby>”页面顶部的“<ruby>网络配置<rt>Network Configuration</rt></ruby>”链接,即可进入网络配置面板设置对等网络。
|
||||
|
||||
![YaCy network configuration][7]
|
||||
|
||||
### 爬取站点
|
||||
|
||||
YaCy 的分布式运作方式决定了它对页面的爬取是由用户驱动的。并没有一个大型公司对整个互联网上的所有可访问页面都进行搜索,对于 YaCy 来说也是这样,一个站点只有在被用户指定爬取的前提下,才会被 YaCy 爬取并进入索引。
|
||||
|
||||
YaCy 客户端提供了两种爬取页面的方式:你可以手动爬取,并让 YaCy 根据建议去爬取。
|
||||
|
||||
![YaCy advanced crawler][8]
|
||||
|
||||
#### 手动爬取
|
||||
|
||||
手动爬取是指由用户输入指定的网站 URL 并启动 YaCy 的爬虫任务。只需要点击“<ruby>高级爬虫<rt>Advanced Crawler</rt></ruby>”并输入计划爬取的若干 URL,然后选择页面底部的“<ruby>进行远程索引<rt>Do Remote indexing</rt></ruby>”选项,这个选项会让客户端向互联网广播它要索引的 URL,可选地接受这些请求的客户端可以帮助你爬取这些 URL。
|
||||
|
||||
点击页面底部的“<ruby>开始新爬虫任务<rt>Start New Crawl Job</rt></ruby>”按钮就可以开始进行爬取了,我就是这样对一些常用和有用站点进行爬取和索引的。
|
||||
|
||||
爬虫任务启动之后,YaCy 会将这些 URL 对应的页面在本地生成和存储索引。在高级模式下,也就是本地计算机允许 8090 端口流量进出时,全网的 YaCy 用户都可以使用到这一份索引。
|
||||
|
||||
#### 加入爬虫网络
|
||||
|
||||
尽管一些非常敬业的 YaCy 高级用户已经强迫症般地在互联网上爬取了很多页面,但对于全网浩如烟海的页面而言也只是沧海一粟。单个用户所拥有的资源远不及很多大公司的网络爬虫,但大量 YaCy 用户如果联合起来成为一个社区,能产生的力量就大得多了。只要开启了 YaCy 的爬虫请求广播功能,就可以让其它客户端参与进来爬取更多页面。
|
||||
|
||||
只需要在“<ruby>高级爬虫<rt>Advanced Crawler</rt></ruby>”面板中点击页面顶部的“<ruby>远程爬取<rt>Remote Crawling</rt></ruby>”,勾选“<ruby>加载<rt>Load</rt></ruby>”旁边的复选框,就可以让你的客户端接受其它人发来的爬虫任务请求了。
|
||||
|
||||
![YaCy remote crawling][9]
|
||||
|
||||
### YaCy 监控相关
|
||||
|
||||
YaCy 除了作为一个非常强大的搜索引擎,还提供了很丰富的主题和用户体验。你可以在“<ruby>监控<rt>Monitor</rt></ruby>”面板中监控 YaCy 客户端的网络运行状况,甚至还可以了解到有多少人从 YaCy 社区中获取到了自己所需要的东西。
|
||||
|
||||
![YaCy monitoring screen][10]
|
||||
|
||||
### 搜索引擎发挥了作用
|
||||
|
||||
你使用 YaCy 的时间越长,就越会思考搜索引擎如何改变自己的视野,因为你对互联网的体验很大一部分来自于你在搜索引擎中一次次简单查询的结果。实际上,当你和不同行业的人交流时,可能会注意到每个人对“互联网”的理解都有所不同。有些人会认为,互联网的搜索引擎中充斥着各种广告和推广,同时也仅仅能从搜索结果中获取到有限的信息。例如,假设有人不断搜索关于关键词 X 的内容,那么大部分商业搜索引擎都会在搜索结果中提高关键词 X 的权重,但与此同时,另一个关键词 Y 的权重则会相对降低,从而让关键词 Y 被淹没在搜索结果当中,即使这样对完成特定任务更好。
|
||||
|
||||
就像在现实生活中一样,走出虚拟的世界视野会让你看到一个更广阔的世界。尝试使用 YaCy,看看你发现了什么。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/yacy-search-engine-hacks
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[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/browser_desktop_website_checklist_metrics.png?itok=OKKbl1UR (Browser of things)
|
||||
[2]: https://linux.cn/article-11905-1.html
|
||||
[3]: https://yacy.net/
|
||||
[4]: https://www.linuxquestions.org/questions/linux-news-59/is-there-no-more-linux-google-884306/
|
||||
[5]: https://opensource.com/sites/default/files/uploads/yacy-profiles.jpg (YaCy profile selector)
|
||||
[6]: https://en.wikipedia.org/wiki/Vivisimo
|
||||
[7]: https://opensource.com/sites/default/files/uploads/yacy-network-config.jpg (YaCy network configuration)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/yacy-advanced-crawler.jpg (YaCy advanced crawler)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/yacy-remote-crawl-accept.jpg (YaCy remote crawling)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/yacy-monitor.jpg (YaCy monitoring screen)
|
@ -0,0 +1,103 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11917-1.html)
|
||||
[#]: subject: (Dino is a Modern Looking Open Source XMPP Client)
|
||||
[#]: via: (https://itsfoss.com/dino-xmpp-client/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Dino:一个有着现代外观的开源 XMPP 客户端
|
||||
======
|
||||
|
||||
> Dino 是一个相对较新的开源 XMPP 客户端,它试图提供良好的用户体验,鼓励注重隐私的用户使用 XMPP 发送消息。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/22/102844mhzgzb3533xgq6d8.jpg)
|
||||
|
||||
### Dino:一个开源 XMPP 客户端
|
||||
|
||||
![][1]
|
||||
|
||||
[XMPP][2](<ruby>可扩展通讯和表示协议<rt>eXtensible Messaging Presence Protocol</rt></ruby>) 是一个去中心化的网络模型,可促进即时消息传递和协作。去中心化意味着没有中央服务器可以访问你的数据。通信直接点对点。
|
||||
|
||||
我们中的一些人可能会称它为“老派”技术,可能是因为 XMPP 客户端通常用户体验非常糟糕,或者仅仅是因为它需要时间来适应(或设置它)。
|
||||
|
||||
这时候 [Dino][3] 作为现代 XMPP 客户端出现了,在不损害你的隐私的情况下提供干净清爽的用户体验。
|
||||
|
||||
### 用户体验
|
||||
|
||||
![][4]
|
||||
|
||||
Dino 试图改善 XMPP 客户端的用户体验,但值得注意的是,它的外观和感受将在一定程度上取决于你的 Linux 发行版。你的图标主题或 Gnome 主题会让你的个人体验更好或更糟。
|
||||
|
||||
从技术上讲,它的用户界面非常简单,易于使用。所以,我建议你看下 Ubuntu 中的[最佳图标主题][5]和 [GNOME 主题][6]来调整 Dino 的外观。
|
||||
|
||||
### Dino 的特性
|
||||
|
||||
![Dino Screenshot][7]
|
||||
|
||||
你可以将 Dino 用作 Slack、[Signal][8] 或 [Wire][9] 的替代产品,来用于你的业务或个人用途。
|
||||
|
||||
它提供了消息应用所需的所有基本特性,让我们看下你可以从中得到的:
|
||||
|
||||
* 去中心化通信
|
||||
* 如果无法设置自己的服务器,它支持公共 XMPP 的服务器
|
||||
* 和其他流行消息应用相似的 UI,因此易于使用
|
||||
* 图像和文件共享
|
||||
* 支持多个帐户
|
||||
* 高级消息搜索
|
||||
* 支持 [OpenPGP][10] 和 [OMEMO][11] 加密
|
||||
* 轻量级原生桌面应用
|
||||
|
||||
### 在 Linux 上安装 Dino
|
||||
|
||||
你可能会发现它列在你的软件中心中,也可能未找到。Dino 为基于 Debian(deb)和 Fedora(rpm)的发行版提供了可用的二进制文件。
|
||||
|
||||
Dino 在 Ubuntu 的 universe 仓库中,你可以使用以下命令安装它:
|
||||
|
||||
```
|
||||
sudo apt install dino-im
|
||||
```
|
||||
|
||||
类似地,你可以在 [GitHub 分发包页面][12]上找到其他 Linux 发行版的包。
|
||||
|
||||
如果你想要获取最新的,你可以在 [OpenSUSE 的软件页面][13]找到 Dino 的 **.deb** 和 .**rpm** (每日构建版)安装在 Linux 中。
|
||||
|
||||
在任何一种情况下,前往它的 [Github 页面][14]或点击下面的链接访问官方网站。
|
||||
|
||||
- [下载 Dino][3]
|
||||
|
||||
### 总结
|
||||
|
||||
在我编写这篇文章时快速测试过它,它工作良好,没有出过问题。我将尝试探索更多,并希望能涵盖更多有关 XMPP 的文章来鼓励用户使用 XMPP 的客户端和服务器用于通信。
|
||||
|
||||
你觉得 Dino 怎么样?你会推荐另一个可能好于 Dino 的开源 XMPP 客户端吗?在下面的评论中让我知道你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/dino-xmpp-client/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/dino-main.png?ssl=1
|
||||
[2]: https://xmpp.org/about/
|
||||
[3]: https://dino.im/
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/dino-xmpp-client.jpg?ssl=1
|
||||
[5]: https://itsfoss.com/best-icon-themes-ubuntu-16-04/
|
||||
[6]: https://itsfoss.com/best-gtk-themes/
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/dino-screenshot.png?ssl=1
|
||||
[8]: https://itsfoss.com/signal-messaging-app/
|
||||
[9]: https://itsfoss.com/wire-messaging-linux/
|
||||
[10]: https://www.openpgp.org/
|
||||
[11]: https://en.wikipedia.org/wiki/OMEMO
|
||||
[12]: https://github.com/dino/dino/wiki/Distribution-Packages
|
||||
[13]: https://software.opensuse.org/download.html?project=network:messaging:xmpp:dino&package=dino
|
||||
[14]: https://github.com/dino/dino
|
||||
|
@ -0,0 +1,84 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11903-1.html)
|
||||
[#]: subject: (How to Change the Default Terminal in Ubuntu)
|
||||
[#]: via: (https://itsfoss.com/change-default-terminal-ubuntu/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
如何在 Ubuntu 中更改默认终端
|
||||
======
|
||||
|
||||
<ruby>终端<rt>Terminal</rt></ruby>是 Linux 系统的关键部分。它能让你通过 shell 访问 Linux 系统。Linux 上有多个终端应用(技术上称为终端仿真器)。
|
||||
|
||||
大多数[桌面环境][1]都有自己的终端实现。它们的外观可能有所不同,并且可能有不同的快捷键。例如,[Guake 终端][2]对高级用户非常有用,它提供了一些可能无法在发行版默认终端中使用的功能。
|
||||
|
||||
你可以在系统上安装其他终端,并将其设为默认,并能通过[快捷键 Ctrl+Alt+T][3] 打开。
|
||||
|
||||
现在问题来了,如何在 Ubuntu 中更改默认终端。它没有遵循[更改 Ubuntu 中的默认应用][4]的标准方式,要怎么做?
|
||||
|
||||
### 更改 Ubuntu 中的默认终端
|
||||
|
||||
![][5]
|
||||
|
||||
在基于 Debian 的发行版中,有一个方便的命令行程序,称为 [update-alternatives][6],可用于处理默认应用。
|
||||
|
||||
你可以使用它来更改默认的命令行文本编辑器、终端等。为此,请运行以下命令:
|
||||
|
||||
```
|
||||
sudo update-alternatives --config x-terminal-emulator
|
||||
```
|
||||
|
||||
它将显示系统上存在的所有可作为默认值的终端仿真器。当前的默认终端标有星号。
|
||||
|
||||
```
|
||||
abhishek@nuc:~$ sudo update-alternatives --config x-terminal-emulator
|
||||
There are 2 choices for the alternative x-terminal-emulator (providing /usr/bin/x-terminal-emulator).
|
||||
|
||||
Selection Path Priority Status
|
||||
------------------------------------------------------------
|
||||
0 /usr/bin/gnome-terminal.wrapper 40 auto mode
|
||||
1 /usr/bin/gnome-terminal.wrapper 40 manual mode
|
||||
* 2 /usr/bin/st 15 manual mode
|
||||
|
||||
Press <enter> to keep the current choice[*], or type selection number:
|
||||
```
|
||||
|
||||
你要做的就是输入选择编号。对我而言,我想使用 GNOME 终端,而不是来自 [Regolith 桌面][7]的终端。
|
||||
|
||||
```
|
||||
Press <enter> to keep the current choice[*], or type selection number: 1
|
||||
update-alternatives: using /usr/bin/gnome-terminal.wrapper to provide /usr/bin/x-terminal-emulator (x-terminal-emulator) in manual mode
|
||||
```
|
||||
|
||||
> **自动模式 vs 手动模式**
|
||||
>
|
||||
> 你可能已经在 `update-alternatives` 命令的输出中注意到了自动模式和手动模式。
|
||||
>
|
||||
> 如果选择自动模式,那么在安装或删除软件包时,系统可能会自动决定默认应用。该决定受优先级数字的影响(如上一节中的命令输出所示)。
|
||||
>
|
||||
> 假设你的系统上安装了 5 个终端仿真器,并删除了默认的仿真器。现在,你的系统将检查哪些仿真器处于自动模式。如果有多个,它将选择优先级最高的一个作为默认仿真器。
|
||||
|
||||
我希望你觉得这个小技巧有用。随时欢迎提出问题和建议。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/change-default-terminal-ubuntu/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/best-linux-desktop-environments/
|
||||
[2]: http://guake-project.org/
|
||||
[3]: https://itsfoss.com/ubuntu-shortcuts/
|
||||
[4]: https://itsfoss.com/change-default-applications-ubuntu/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/switch_default_terminal_ubuntu.png?ssl=1
|
||||
[6]: https://manpages.ubuntu.com/manpages/trusty/man8/update-alternatives.8.html
|
||||
[7]: https://itsfoss.com/regolith-linux-desktop/
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11944-1.html)
|
||||
[#]: subject: (How to use byobu to multiplex SSH sessions)
|
||||
[#]: via: (https://opensource.com/article/20/2/byobu-ssh)
|
||||
[#]: author: (Ben Nuttall https://opensource.com/users/bennuttall)
|
||||
|
||||
如何使用 byobu 复用 SSH 会话
|
||||
======
|
||||
|
||||
> Byobu 能让你在保持会话活跃的情况下维护多个终端窗口,通过 SSH 连接、断开、重连以及共享访问。
|
||||
|
||||
![Person drinking a hat drink at the computer][1]
|
||||
|
||||
[Byobu][2] 是基于文本的窗口管理器和终端多路复用器。它类似于 [GNU Screen][3],但更现代、更直观。它还适用于大多数 Linux、BSD 和 Mac 发行版。
|
||||
|
||||
Byobu 能让你在保持会话活跃的情况下维护多个终端窗口、通过 SSH(secure shell)连接、断开、重连,甚至让其他人访问。
|
||||
|
||||
比如,你 SSH 进入树莓派或服务器,并运行(比如) `sudo apt update && sudo apt upgrade`,然后你在它运行的时候失去了互联网连接,你的命令会丢失无效。然而,如果你首先启动 byobu 会话,那么它会继续运行,在你重连后,你会发现它仍在继续运行。
|
||||
|
||||
![The byobu logo is a fun play on screens.][4]
|
||||
|
||||
Byobu 名称来自于日语的装饰性多面板屏风,它可作为折叠式隔断,我认为这很合适。
|
||||
|
||||
要在 Debian/Raspbian/Ubuntu 上安装 byobu:
|
||||
|
||||
```
|
||||
sudo apt install byobu
|
||||
```
|
||||
|
||||
接着启用它:
|
||||
|
||||
```
|
||||
byobu-enable
|
||||
```
|
||||
|
||||
现在,请退出 SSH 会话并重新登录,你将会在 byobu 会话中登录。运行类似 `sudo apt update` 命令并关闭窗口(或输入转义序列([Enter + ~ + .][5])并重新登录。你将看到更新命令在你离开后还在运行。
|
||||
|
||||
有*很多*我不常使用的功能。我通常使用的是:
|
||||
|
||||
* `F2` – 新窗口
|
||||
* `F3/F4` – 在窗口间导航
|
||||
* `Ctrl`+`F2` – 垂直拆分窗格
|
||||
* `Shift`+`F2` – 水平拆分窗格
|
||||
* `Shift`+`左箭头/Shift`+`右箭头` – 在拆分窗格间导航
|
||||
* `Shift`+`F11` – 放大(或缩小)拆分窗格
|
||||
|
||||
### 我们如何使用 byobu
|
||||
|
||||
Byobu 对于维护 [piwheels][6](一个用于树莓派的方便的,预编译 Python 包)很好用。我水平拆分了窗格,在上半部分显示了 piwheels 监视器,在下半部分实时显示了 syslog 条目。接着,如果我们想要做其他事情,我们可以切换到另外一个窗口。当我们进行协作分析时,这特别方便,因为当我在 IRC 中聊天时,我可以看到我的同事 Dave 输入了什么(并纠正他的错字)。
|
||||
|
||||
我在家庭和办公服务器上启用了 byobu,因此,当我登录到任何一台计算机时,一切都与我离开时一样。它正在运行多个作业、在特定目录中保留一个窗口,以另一个用户身份运行进程等。
|
||||
|
||||
![byobu screenshot][7]
|
||||
|
||||
Byobu 对于在树莓派上进行开发也很方便。你可以在桌面上启动它,运行命令,然后 SSH 进入,并连接到该命令运行所在的会话。请注意,启用 byobu 不会更改终端启动器的功能。只需运行 `byobu` 即可启动它。
|
||||
|
||||
本文最初发表在 Ben Nuttall 的 [Tooling blog][8] 中,并获许重用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/byobu-ssh
|
||||
|
||||
作者:[Ben Nuttall][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/bennuttall
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hat drink at the computer)
|
||||
[2]: https://byobu.org/
|
||||
[3]: http://www.gnu.org/software/screen/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/byobu.png (byobu screen)
|
||||
[5]: https://www.google.com/search?client=ubuntu&channel=fs&q=Enter-tilde-dot&ie=utf-8&oe=utf-8
|
||||
[6]: https://opensource.com/article/20/1/piwheels
|
||||
[7]: https://opensource.com/sites/default/files/uploads/byobu-screenshot.png (byobu screenshot)
|
||||
[8]: https://tooling.bennuttall.com/byobu/
|
@ -0,0 +1,95 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11939-1.html)
|
||||
[#]: subject: (elementary OS is Building an App Center Where You Can Buy Open Source Apps for Your Linux Distribution)
|
||||
[#]: via: (https://itsfoss.com/appcenter-for-everyone/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
elementary OS 正在构建一个可以买应用的开源应用商店
|
||||
======
|
||||
|
||||
> elementary OS 正在构建一个应用中心生态系统,你可以在其中购买用于 Linux 发行版的开源应用程序。
|
||||
|
||||
### 众筹构建一个开源应用中心
|
||||
|
||||
![][1]
|
||||
|
||||
[elementary OS][2] 最近宣布,它正在[众筹举办一个构建应用中心的活动][3],你可以从这个应用中心购买开源应用程序。应用中心中的应用程序将为 Flatpak 格式。
|
||||
|
||||
尽管这是 elementary OS 发起的活动,但这个新的应用中心也将适用于其他发行版。
|
||||
|
||||
该活动旨在资助在美国科罗拉多州丹佛市进行的一项一周个人开发冲刺活动,其中包括来自 elementary OS、[Endless][4]、[Flathub][5] 和 [GNOME][6] 的开发人员。
|
||||
|
||||
众筹活动已经超过了筹集 1 万美元的目标(LCTT 译注:截止至本译文发布,已近 15000 美金)。但你仍然可以为其提供资金,因为其他资金将用于开发 elementary OS。
|
||||
|
||||
### 这个应用中心将带来什么功能
|
||||
|
||||
其重点是提供“安全”应用程序,因此使用 [Flatpak][7] 应用来提供受限的应用程序。在这种格式下,默认情况下将会限制应用程序访问系统或个人文件,并在技术层面上将它们与其他应用程序隔离。
|
||||
|
||||
仅当你明确表示同意时,应用程序才能访问操作系统和个人文件。
|
||||
|
||||
除了安全性,[Flatpak][8] 还捆绑了所有依赖项。这样,即使当前 Linux 发行版中不提供这些依赖项,应用程序开发人员也可以利用这种最先进的技术使用它。
|
||||
|
||||
AppCenter 还具有钱包功能,可以保存你的信用卡详细信息。这样,你无需每次输入卡的详细信息即可快速为应用付费。
|
||||
|
||||
![][9]
|
||||
|
||||
这个新的开源“应用中心”也将适用于其他 Linux 发行版。
|
||||
|
||||
### 受到了 elementary OS 自己的“按需付费”应用中心模型成功的启发
|
||||
|
||||
几年前,elementary OS 推出了自己的应用中心。应用中心的“按需付费”方法很受欢迎。开发人员可以为其开源应用设置最低金额,而用户可以选择支付等于或高于最低金额的金额。
|
||||
|
||||
![][10]
|
||||
|
||||
这帮助了几位独立开发人员可以对其开源应用程序接受付款。该应用中心现在拥有约 160 个原生应用程序,elementary OS 表示已通过应用中心向开发人员支付了数千美元。
|
||||
|
||||
受到此应用中心实验在 elementary OS 中的成功的启发,他们现在也希望将此应用中心的方法也引入其他发行版。
|
||||
|
||||
### 如果应用程序是开源的,你怎么为此付费?
|
||||
|
||||
某些人仍然对 FOSS(自由而开源)的概念感到困惑。在这里,该软件的“源代码”是“开源的”,任何人都可以“自由”进行修改和重新分发。
|
||||
|
||||
但这并不意味着开源软件必须免费。一些开发者依靠捐赠,而另一些则收取支持费用。
|
||||
|
||||
获得开源应用程序的报酬可能会鼓励开发人员创建 [Linux 应用程序][11]。
|
||||
|
||||
### 让我们拭目以待
|
||||
|
||||
![][12]
|
||||
|
||||
就个人而言,我不是 Flatpak 或 Snap 包格式的忠实拥护者。它们确实有其优点,但是它们花费了相对更多的时间来启动,并且它们的包大小很大。如果安装了多个此类 Snap 或 Flatpak 软件包,磁盘空间就会慢慢耗尽。
|
||||
|
||||
也需要对这个新的应用程序生态系统中的假冒和欺诈开发者保持警惕。想象一下,如果某些骗子开始创建冷门的开源应用程序的 Flatpak 程序包,并将其放在应用中心上?我希望开发人员采用某种机制来淘汰此类应用程序。
|
||||
|
||||
我确实希望这个新的应用中心能够复制在 elementary OS 中已经看到的成功。对于桌面 Linux 的开源应用程序,我们绝对需要更好的生态系统。
|
||||
|
||||
你对此有何看法?这是正确的方法吗?你对改进应用中心有什么建议?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/appcenter-for-everyone/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/appcenter.png?ssl=1
|
||||
[2]: https://elementary.io/
|
||||
[3]: https://www.indiegogo.com/projects/appcenter-for-everyone/
|
||||
[4]: https://itsfoss.com/endless-linux-computers/
|
||||
[5]: https://flathub.org/
|
||||
[6]: https://www.gnome.org/
|
||||
[7]: https://flatpak.org/
|
||||
[8]: https://itsfoss.com/flatpak-guide/
|
||||
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/02/appcenter-wallet.png?ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/appcenter-payment.png?ssl=1
|
||||
[11]: https://itsfoss.com/essential-linux-applications/
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/open_source_app_center.png?ssl=1
|
@ -0,0 +1,97 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Morisun029)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11924-1.html)
|
||||
[#]: subject: (Why developers like to code at night)
|
||||
[#]: via: (https://opensource.com/article/20/2/why-developers-code-night)
|
||||
[#]: author: (Matt Shealy https://opensource.com/users/mshealy)
|
||||
|
||||
程序员为什么喜欢在晚上编码
|
||||
======
|
||||
|
||||
> 对许多开源程序员来说,夜间的工作计划是创造力和生产力来源的关键。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/24/104251b2hxch46h45c8zwd.jpg)
|
||||
|
||||
如果你问大多数开发人员更喜欢在什么时候工作,大部人会说他们最高效的时间在晚上。这对于那些在工作之余为开源项目做贡献的人来说更是如此(尽管如此,希望在他们的健康范围内[避免透支][2])。
|
||||
|
||||
有些人喜欢从晚上开始,一直工作到凌晨,而另一些人则很早就起床(例如,凌晨 4 点),以便在开始日常工作之前完成大部分编程工作。
|
||||
|
||||
这种工作习惯可能会使许多开发人员看起来像个怪人,不合时宜。但是,为什么有这么多的程序员喜欢在非正常时间工作,原因有很多:
|
||||
|
||||
### 制造者日程
|
||||
|
||||
根据 <ruby>[保罗·格雷厄姆][3]<rt>Paul Graham</rt></ruby> 的观点,“生产东西”的人倾向于遵守 制造者日程 —— 他们更愿意以半天或更长时间为单位使用时间。事实上,大多数[开发人员也有相同的偏好][4]。(LCTT 译注:保罗·格雷厄姆有[一篇文章][8]述及制造者日程和管理者日程。)
|
||||
|
||||
一方面,开发人员从事大型抽象系统工作,需要思维空间来处理整个模型。将他们的日程分割成 15 分钟或 30 分钟的时间段来处理电子邮件、会议、电话以及来自同事的打断,工作效果只会适得其反。
|
||||
|
||||
另一方面,通常不可能以小时为单位进行有效编程。因为这么短的时间几乎不够让你把思绪放在手头的任务上并开始工作。
|
||||
|
||||
上下文切换也会对编程产生不利影响。在晚上工作,开发人员可以避免尽可能多的干扰。在没有不断的干扰的情况下,他们可以花几个小时专注于手头任务,并尽可能提高工作效率。
|
||||
|
||||
### 平和安静的环境
|
||||
|
||||
由于晚上或凌晨不太会有来自各种活动的噪音(例如,办公室闲谈、街道上的交通),这使许多程序员感到放松,促使他们更具创造力和生产力,特别是在处理诸如编码之类的精神刺激任务时。
|
||||
|
||||
独处与平静,加上他们知道自己将有几个小时不被中断的工作时间,通常会使他们摆脱白天工作计划相关的时间压力,从而产出高质量的工作。
|
||||
|
||||
更不用说了,当解决了一个棘手的问题后,没有什么比尽情享受自己最喜欢的午夜小吃更美好的事情了!
|
||||
|
||||
### 沟通
|
||||
|
||||
与在公司内工作的程序员相比,从事开源项目的开发人员可以拥有不同的沟通节奏。大多数开源项目的沟通都是通过邮件或 GitHub 上的评论等渠道异步完成的。很多时候,其他程序员在不同的国家和时区,因此实时交流通常需要开发人员变成一个夜猫子。
|
||||
|
||||
### 昏昏欲睡的大脑
|
||||
|
||||
这听起来可能违反直觉,但是随着时间的推移,大脑会变得非常疲倦,因此只能专注于一项任务。晚上工作从根本上消除了多任务处理,而这是保持专注和高效的主要障碍。当大脑处于昏昏欲睡的状态时,你是无法保持专注的!
|
||||
|
||||
此外,许多开发人员在入睡时思考要解决的问题通常会取得重大进展。潜意识开始工作,答案通常在他们半睡半醒的凌晨时分就出现了。
|
||||
|
||||
这不足为奇,因为[睡眠可增强大脑功能][5],可帮助我们理解新信息并进行更有创造性的思考。当解决方案在凌晨出现时,这些开发人员便会起来开始工作,不错过任何机会。
|
||||
|
||||
### 灵活和创造性思考
|
||||
|
||||
许多程序员体会到晚上创造力会提升。前额叶皮层,即大脑中与集中能力有关的部分,在一天结束时会感到疲倦。这似乎为某些人提供了更灵活和更具创造性的思考。
|
||||
|
||||
匹兹堡大学医学院精神病学助理教授 [Brant Hasler][6] 表示:“由于自上而下的控制和‘认知抑制’的减少,大脑可能会解放出来进行更发散的思考,从而使人们更容易地将不同概念之间的联系建立起来。” 结合轻松环境所带来的积极情绪,开发人员可以更轻松地产生创新想法。
|
||||
|
||||
此外,在没有干扰的情况下集中精力几个小时,“沉浸在你做的事情中”。这可以帮助你更好地专注于项目并参与其中,而不必担心周围发生的事情。
|
||||
|
||||
### 明亮的电脑屏幕
|
||||
|
||||
因为整天看着明亮的屏幕, 许多程序员的睡眠周期被延迟。电脑屏幕发出的蓝光[扰乱我们的昼夜节律][7],延迟了释放诱发睡眠的褪黑激素和提高人的机敏性,并将人体生物钟重置到更晚的时间。从而导致,开发人员往往睡得越来越晚。
|
||||
|
||||
### 来自过去的影响
|
||||
|
||||
过去,大多数开发人员是出于必要在晚上工作,因为在白天当公司其他人都在使用服务器时,共享服务器的计算能力支撑不了编程工作,所以开发人员需要等到深夜才能执行白天无法进行的任务,例如测试项目、运行大量的“编码-编译-运行-调试”周期以及部署新代码。现在尽管服务器功能变强大了,大多数可以满足需求,但夜间工作的趋势仍是这种文化的一部分。
|
||||
|
||||
### 结语
|
||||
|
||||
尽管开发人员喜欢在晚上工作的原因很多,但请记住,做为夜猫子并不意味着你应该克扣睡眠时间。睡眠不足会导致压力和焦虑,并最终导致倦怠。
|
||||
|
||||
获得足够质量的睡眠是维持良好身体健康和大脑功能的关键。例如,它可以帮助你整合新信息、巩固记忆、创造性思考、清除身体积聚的毒素、调节食欲并防止过早衰老。
|
||||
|
||||
无论你是哪种日程,请确保让你的大脑得到充分的休息,这样你就可以在一整天及每天的工作中发挥最大的作用!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/why-developers-code-night
|
||||
|
||||
作者:[Matt Shealy][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Morisun029](https://github.com/Morisun029)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mshealy
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_code_programming_laptop.jpg?itok=ormv35tV (Person programming on a laptop on a building)
|
||||
[2]: https://opensource.com/article/19/11/burnout-open-source-communities
|
||||
[3]: http://www.paulgraham.com/makersschedule.html
|
||||
[4]: https://www.chamberofcommerce.com/business-advice/software-development-trends-overtaking-the-market
|
||||
[5]: https://amerisleep.com/blog/sleep-impacts-brain-health/
|
||||
[6]: https://www.vice.com/en_us/article/mb58a8/late-night-creativity-spike
|
||||
[7]: https://www.sleepfoundation.org/articles/how-blue-light-affects-kids-sleep
|
||||
[8]: http://www.paulgraham.com/makersschedule.html
|
@ -0,0 +1,196 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11931-1.html)
|
||||
[#]: subject: (Digging up IP addresses with the Linux dig command)
|
||||
[#]: via: (https://www.networkworld.com/article/3527430/digging-up-ip-addresses-with-the-dig-command.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
使用 dig 命令挖掘域名解析信息
|
||||
======
|
||||
|
||||
> 命令行工具 `dig` 是用于解析域名和故障排查的一个利器。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/26/094028jgvzguau1pdgicpz.jpg)
|
||||
|
||||
从主要功能上来说,`dig` 和 `nslookup` 之间差异不大,但 `dig` 更像一个加强版的 `nslookup`,可以查询到一些由域名服务器管理的信息,这在排查某些问题的时候非常有用。总的来说,`dig` 是一个既简单易用又功能强大的命令行工具。(LCTT 译注:`dig` 和 `nslookup` 行为的主要区别来自于 `dig` 使用是是操作系统本身的解析库,而 `nslookup` 使用的是该程序自带的解析库,这有时候会带来一些行为差异。此外,从表现形式上看,`dig` 返回是结果是以 BIND 配置信息的格式返回的,也带有更多的技术细节。)
|
||||
|
||||
`dig` 最基本的功能就是查询域名信息,因此它的名称实际上是“<ruby>域名信息查询工具<rt>Domain Information Groper</rt></ruby>”的缩写。`dig` 向用户返回的内容可以非常详尽,也可以非常简洁,展现内容的多少完全由用户在查询时使用的选项来决定。
|
||||
|
||||
### 我只需要查询 IP 地址
|
||||
|
||||
如果只需要查询某个域名指向的 IP 地址,可以使用 `+short` 选项:
|
||||
|
||||
```
|
||||
$ dig facebook.com +short
|
||||
31.13.66.35
|
||||
```
|
||||
|
||||
在查询的时候发现有的域名会指向多个 IP 地址?这其实是网站提高其可用性的一种措施。
|
||||
|
||||
```
|
||||
$ dig networkworld.com +short
|
||||
151.101.2.165
|
||||
151.101.66.165
|
||||
151.101.130.165
|
||||
151.101.194.165
|
||||
```
|
||||
|
||||
也正是由于这些网站通过负载均衡实现高可用,在下一次查询的时候,或许会发现这几个 IP 地址的排序有所不同。(LCTT 译注:浏览器等应用默认会使用返回的第一个 IP 地址,因此这样实现了一种简单的负载均衡。)
|
||||
|
||||
```
|
||||
$ dig networkworld.com +short
|
||||
151.101.130.165
|
||||
151.101.194.165
|
||||
151.101.2.165
|
||||
151.101.66.165
|
||||
```
|
||||
|
||||
### 标准返回
|
||||
|
||||
`dig` 的标准返回内容则包括这个工具本身的一些信息,以及请求域名服务器时返回的响应内容:
|
||||
|
||||
```
|
||||
$ dig networkworld.com
|
||||
|
||||
; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>*gt; networkworld.com
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39932
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 65494
|
||||
;; QUESTION SECTION:
|
||||
;networkworld.com. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
networkworld.com. 300 IN A 151.101.194.165
|
||||
networkworld.com. 300 IN A 151.101.130.165
|
||||
networkworld.com. 300 IN A 151.101.66.165
|
||||
networkworld.com. 300 IN A 151.101.2.165
|
||||
|
||||
;; Query time: 108 msec
|
||||
;; SERVER: 127.0.0.53#53(127.0.0.53)
|
||||
;; WHEN: Thu Feb 13 13:49:53 EST 2020
|
||||
;; MSG SIZE rcvd: 109
|
||||
```
|
||||
|
||||
由于域名服务器有缓存机制,返回的内容可能是之前缓存好的信息。在这种情况下,`dig` 最后显示的<ruby>查询时间<rt>Query time</rt></ruby>会是 0 毫秒(0 msec):
|
||||
|
||||
```
|
||||
;; Query time: 0 msec <==
|
||||
;; SERVER: 127.0.0.53#53(127.0.0.53)
|
||||
;; WHEN: Thu Feb 13 15:30:09 EST 2020
|
||||
;; MSG SIZE rcvd: 109
|
||||
```
|
||||
|
||||
### 向谁查询?
|
||||
|
||||
在默认情况下,`dig` 会根据 `/etc/resolv.conf` 这个文件的内容决定向哪个域名服务器获取查询结果。你也可以使用 `@` 来指定 `dig` 请求的域名服务器。
|
||||
|
||||
在下面的例子中,就指定了 `dig` 向 Google 的域名服务器 8.8.8.8 查询域名信息。
|
||||
|
||||
```
|
||||
$ dig @8.8.8.8 networkworld.com
|
||||
|
||||
; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>> @8.8.8.8 networkworld.com
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21163
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 512
|
||||
;; QUESTION SECTION:
|
||||
;networkworld.com. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
networkworld.com. 299 IN A 151.101.130.165
|
||||
networkworld.com. 299 IN A 151.101.66.165
|
||||
networkworld.com. 299 IN A 151.101.194.165
|
||||
networkworld.com. 299 IN A 151.101.2.165
|
||||
|
||||
;; Query time: 48 msec
|
||||
;; SERVER: 8.8.8.8#53(8.8.8.8)
|
||||
;; WHEN: Thu Feb 13 14:26:14 EST 2020
|
||||
;; MSG SIZE rcvd: 109
|
||||
```
|
||||
|
||||
想要知道正在使用的 `dig` 工具的版本,可以使用 `-v` 选项。你会看到类似这样:
|
||||
|
||||
```
|
||||
$ dig -v
|
||||
DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu
|
||||
```
|
||||
|
||||
或者这样的返回信息:
|
||||
|
||||
```
|
||||
$ dig -v
|
||||
DiG 9.11.4-P2-RedHat-9.11.4-22.P2.el8
|
||||
```
|
||||
|
||||
如果你觉得 `dig` 返回的内容过于详细,可以使用 `+noall`(不显示所有内容)和 `+answer`(仅显示域名服务器的响应内容)选项,域名服务器的详细信息就会被忽略,只保留域名解析结果。
|
||||
|
||||
```
|
||||
$ dig networkworld.com +noall +answer
|
||||
|
||||
; <<>> DiG 9.11.5-P4-5.1ubuntu2.1-Ubuntu <<>> networkworld.com +noall +answer
|
||||
;; global options: +cmd
|
||||
networkworld.com. 300 IN A 151.101.194.165
|
||||
networkworld.com. 300 IN A 151.101.130.165
|
||||
networkworld.com. 300 IN A 151.101.66.165
|
||||
networkworld.com. 300 IN A 151.101.2.165
|
||||
```
|
||||
|
||||
### 批量查询域名
|
||||
|
||||
如果你要查询多个域名,可以把这些域名写入到一个文件内(`domains`),然后使用下面的 `dig` 命令遍历整个文件并给出所有查询结果。
|
||||
|
||||
```
|
||||
$ dig +noall +answer -f domains
|
||||
networkworld.com. 300 IN A 151.101.66.165
|
||||
networkworld.com. 300 IN A 151.101.2.165
|
||||
networkworld.com. 300 IN A 151.101.130.165
|
||||
networkworld.com. 300 IN A 151.101.194.165
|
||||
world.std.com. 77972 IN A 192.74.137.5
|
||||
uushenandoah.org. 1982 IN A 162.241.24.209
|
||||
amazon.com. 18 IN A 176.32.103.205
|
||||
amazon.com. 18 IN A 176.32.98.166
|
||||
amazon.com. 18 IN A 205.251.242.103
|
||||
```
|
||||
|
||||
你也可以在上面的命令中使用 `+short` 选项,但如果其中有些域名指向多个 IP 地址,就无法看出哪些 IP 地址对应哪个域名了。在这种情况下,更好地做法应该是让 `awk` 对返回内容进行处理,只留下第一列和最后一列:
|
||||
|
||||
```
|
||||
$ dig +noall +answer -f domains | awk '{print $1,$NF}'
|
||||
networkworld.com. 151.101.66.165
|
||||
networkworld.com. 151.101.130.165
|
||||
networkworld.com. 151.101.194.165
|
||||
networkworld.com. 151.101.2.165
|
||||
world.std.com. 192.74.137.5
|
||||
amazon.com. 176.32.98.166
|
||||
amazon.com. 205.251.242.103
|
||||
amazon.com. 176.32.103.205
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3527430/digging-up-ip-addresses-with-the-dig-command.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/newsletters/signup.html
|
||||
[2]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE21620&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage)
|
||||
[3]: https://www.facebook.com/NetworkWorld/
|
||||
[4]: https://www.linkedin.com/company/network-world
|
115
published/202002/20200217 How to get MongoDB Server on Fedora.md
Normal file
115
published/202002/20200217 How to get MongoDB Server on Fedora.md
Normal file
@ -0,0 +1,115 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11942-1.html)
|
||||
[#]: subject: (How to get MongoDB Server on Fedora)
|
||||
[#]: via: (https://fedoramagazine.org/how-to-get-mongodb-server-on-fedora/)
|
||||
[#]: author: (Honza Horak https://fedoramagazine.org/author/hhorak/)
|
||||
|
||||
如何在 Fedora 上安装 MongoDB 服务器
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Mongo(来自 “humongous” —— 巨大的)是一个高性能、开源、无模式的、面向文档的数据库,它是最受欢迎的 [NoSQL][2] 数据库之一。它使用 JSON 作为文档格式,并且可以在多个服务器节点之间进行扩展和复制。
|
||||
|
||||
### 有关许可证更改的故事
|
||||
|
||||
MongoDB 上游决定更改服务器代码的许可证已经一年多了。先前的许可证是 GNU Affero General Public License v3(AGPLv3)。但是,上游公司写了一个新许可证,旨在使运行 MongoDB 即服务的公司可以回馈社区。新许可证称为 Server Side Public License(SSPLv1),关于这个举措及其解释的更多说明,请参见 [MongoDB SSPL FAQ][3]。
|
||||
|
||||
Fedora 一直只包含自由软件。当 SSPL 发布后,Fedora [确定][4]它并不是自由软件许可证。许可证更改日期(2018 年 10 月)之前发布的所有 MongoDB 版本都可保留在 Fedora 中,但之后再也不更新的软件包会带来安全问题。因此,从 Fedora 30 开始,Fedora 社区决定完全[移除 MongoDB 服务器][5]。
|
||||
|
||||
### 开发人员还有哪些选择?
|
||||
|
||||
是的,还有替代方案,例如 PostgreSQL 在最新版本中也支持 JSON,它可以在无法再使用 MongoDB 的情况下使用它。使用 JSONB 类型,索引在 PostgreSQL 中可以很好地工作,其性能可与 MongoDB 媲美,甚至不会受到 ACID 的影响。
|
||||
|
||||
开发人员可能选择 MongoDB 的技术原因并未随许可证而改变,因此许多人仍想使用它。重要的是要意识到,SSPL 许可证仅更改仅针对 MongoDB 服务器。MongoDB 上游还开发了其他项目,例如 MongoDB 工具、C 和 C++ 客户端库以及用于各种动态语言的连接器,这些项目在客户端使用(通过网络与服务器通信的应用中)。由于这些包的许可证人保持自由(主要是 Apache 许可证),因此它们保留在 Fedora 仓库中,因此用户可以将其用于应用开发。
|
||||
|
||||
唯一的变化实际是服务器软件包本身,它已从 Fedora 仓库中完全删除。让我们看看 Fedora 用户可以如何获取非自由的包。
|
||||
|
||||
### 如何从上游安装 MongoDB 服务器
|
||||
|
||||
当 Fedora 用户想要安装 MongoDB 服务器时,他们需要直接向上游获取 MongoDB。但是,上游不为 Fedora 提供 RPM 包。相反,MongoDB 服务器可以获取源码 tarball,用户需要自己进行编译(这需要一些开发知识),或者 Fedora 用户可以使用一些兼容的包。在兼容的选项中,最好的选择是 RHEL-8 RPM。以下步骤描述了如何安装它们以及如何启动守护进程。
|
||||
|
||||
#### 1、使用上游 RPM 创建仓库(RHEL-8 构建)
|
||||
|
||||
```
|
||||
$ sudo cat > /etc/yum.repos.d/mongodb.repo >>EOF
|
||||
[mongodb-upstream]
|
||||
name=MongoDB Upstream Repository
|
||||
baseurl=https://repo.mongodb.org/yum/redhat/8Server/mongodb-org/4.2/x86_64/
|
||||
gpgcheck=1
|
||||
enabled=1
|
||||
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
|
||||
EOF
|
||||
```
|
||||
|
||||
#### 2、安装元软件包,来拉取服务器和工具包
|
||||
|
||||
```
|
||||
$ sudo dnf install mongodb-org
|
||||
......
|
||||
Installed:
|
||||
mongodb-org-4.2.3-1.el8.x86_64 mongodb-org-mongos-4.2.3-1.el8.x86_64
|
||||
mongodb-org-server-4.2.3-1.el8.x86_64 mongodb-org-shell-4.2.3-1.el8.x86_64
|
||||
mongodb-org-tools-4.2.3-1.el8.x86_64
|
||||
|
||||
Complete!
|
||||
```
|
||||
|
||||
#### 3、启动 MongoDB 守护进程
|
||||
|
||||
```
|
||||
$ sudo systemctl status mongod
|
||||
● mongod.service - MongoDB Database Server
|
||||
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
|
||||
Active: active (running) since Sat 2020-02-08 12:33:45 EST; 2s ago
|
||||
Docs: https://docs.mongodb.org/manual
|
||||
Process: 15768 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
|
||||
Process: 15769 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
|
||||
Process: 15770 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
|
||||
Process: 15771 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=0/SUCCESS)
|
||||
Main PID: 15773 (mongod)
|
||||
Memory: 70.4M
|
||||
CPU: 611ms
|
||||
CGroup: /system.slice/mongod.service
|
||||
|
||||
```
|
||||
|
||||
#### 4、通过 mongo shell 连接服务器来验证是否运行
|
||||
|
||||
```
|
||||
$ mongo
|
||||
MongoDB shell version v4.2.3
|
||||
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
|
||||
Implicit session: session { "id" : UUID("20b6e61f-c7cc-4e9b-a25e-5e306d60482f") }
|
||||
MongoDB server version: 4.2.3
|
||||
Welcome to the MongoDB shell.
|
||||
For interactive help, type "help".
|
||||
For more comprehensive documentation, see
|
||||
http://docs.mongodb.org/
|
||||
---
|
||||
```
|
||||
|
||||
|
||||
就是这样了。如你所见,RHEL-8 包完美兼容,只要 Fedora 包还与 RHEL-8 兼容,它就应该会一直兼容。请注意,在使用时必须遵守 SSPLv1 许可证。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/how-to-get-mongodb-server-on-fedora/
|
||||
|
||||
作者:[Honza Horak][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/hhorak/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/02/mongodb-816x348.png
|
||||
[2]: https://en.wikipedia.org/wiki/NoSQL
|
||||
[3]: https://www.mongodb.com/licensing/server-side-public-license/faq
|
||||
[4]: https://lists.fedoraproject.org/archives/list/legal@lists.fedoraproject.org/thread/IQIOBOGWJ247JGKX2WD6N27TZNZZNM6C/
|
||||
[5]: https://fedoraproject.org/wiki/Changes/MongoDB_Removal
|
166
published/202002/20200217 How to install Vim plugins.md
Normal file
166
published/202002/20200217 How to install Vim plugins.md
Normal file
@ -0,0 +1,166 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (qianmingtian)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11923-1.html)
|
||||
[#]: subject: (How to install Vim plugins)
|
||||
[#]: via: (https://opensource.com/article/20/2/how-install-vim-plugins)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何安装 Vim 插件
|
||||
======
|
||||
|
||||
> 无论你是手动安装还是通过包管理器安装,插件都可以帮助你在工作流中打造一个完美的 Vim 。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/23/215719kwhqzwwj1ezoen6o.jpg)
|
||||
|
||||
虽然 [Vim][2] 是快速且高效的,但在默认情况下,它仅仅只是一个文本编辑器。至少,这就是没有插件的情况 Vim 应当具备的样子,插件构建在 Vim 之上,并添加额外的功能,使 Vim 不仅仅是一个输入文本的窗口。有了合适的插件组合,你可以控制你的生活,形成你自己独特的 Vim 体验。你可以[自定义你的主题][3],你可以添加语法高亮,代码 linting,版本跟踪器等等。
|
||||
|
||||
### 怎么安装 Vim 插件
|
||||
|
||||
Vim 可以通过插件进行扩展,但很长一段时间以来,并没有官方的安装方式去安装这些插件。从 Vim 8 开始,有一个关于插件如何安装和加载的结构。你可能会在网上或项目自述文件中遇到旧的说明,但只要你运行 Vim 8 或更高版本,你应该根据 Vim 的[官方插件安装方法][4]安装或使用 Vim 包管理器。你可以使用包管理器,无论你运行的是什么版本(包括比 8.x 更老的版本),这使得安装过程比你自己维护更新更容易。
|
||||
|
||||
手动和自动安装方法都值得了解,所以请继续阅读以了解这两种方法。
|
||||
|
||||
### 手动安装插件(Vim 8 及以上版本)
|
||||
|
||||
所谓的 “Vim 包”是一个包含一个或多个插件的目录。默认情况下,你的 Vim 设置包含在 `~/.vim` 中,这是 Vim 在启动时寻找插件的地方。(下面的示例使用了通用名称 `vendor` 来表示插件是从其它地方获得的。)
|
||||
|
||||
当你启动 Vim 时,它首先处理你的 `.vimrc`文件,然后扫描 `~/.vim` 中的所有目录,查找包含在 `pack/*/start` 中的插件。
|
||||
|
||||
默认情况下,你的 `~/.vim` 目录(如果你有的话)中没有这样的文件结构,所以设置为:
|
||||
|
||||
```
|
||||
$ mkdir -p ~/.vim/pack/vendor/start
|
||||
```
|
||||
|
||||
现在,你可以将 Vim 插件放在 `~/.vim/pack/vendor/start` 中,它们会在你启动 Vim 时自动加载。
|
||||
|
||||
例如,尝试安装一下 [NERDTree][5],这是一个基于文本的 Vim 文件管理器。首先,使用 Git 克隆 NERDTree 存储库的快照:
|
||||
|
||||
```
|
||||
$ git clone --depth 1 \
|
||||
https://github.com/preservim/nerdtree.git \
|
||||
~/.vim/pack/vendor/start/nerdtree
|
||||
```
|
||||
|
||||
启动 Vim 或者 gvim,然后键入如下命令:
|
||||
|
||||
```
|
||||
:NERDTree
|
||||
```
|
||||
|
||||
Vim 窗口左侧将打开一个文件树。
|
||||
|
||||
![NERDTree plugin][6]
|
||||
|
||||
如果你不想让一个插件每次启动 Vim 时都自动加载,你可以在 `~/.vim/pack/vendor` 中创建 `opt` 文件夹:
|
||||
|
||||
```
|
||||
$ mkdir ~/.vim/pack/vendor/opt
|
||||
```
|
||||
|
||||
任何安装到 `opt` 的插件都可被 Vim 使用,但是只有当你使用 `packadd` 命令将它们添加到一个会话中时,它们才会被加载到内存中。例如,一个虚构的叫 foo 的插件:
|
||||
|
||||
```
|
||||
:packadd foo
|
||||
```
|
||||
|
||||
Vim 官方建议每个插件项目在 `~/.Vim/pack` 中创建自己的目录。例如,如果你要安装 NERDTree 插件和假想的 foo 插件,你需要创建这样的目录结构:
|
||||
|
||||
```
|
||||
$ mkdir -p ~/.vim/pack/NERDTree/start/
|
||||
$ git clone --depth 1 \
|
||||
https://github.com/preservim/nerdtree.git \
|
||||
~/.vim/pack/NERDTree/start/NERDTree
|
||||
$ mkdir -p ~/.vim/pack/foo/start/
|
||||
$ git clone --depth 1 \
|
||||
https://notabug.org/foo/foo.git \
|
||||
~/.vim/pack/foo/start/foo
|
||||
```
|
||||
|
||||
这样做是否方便取决于你。
|
||||
|
||||
### 使用 Vim 包管理器(任何 Vim 版本)
|
||||
|
||||
自从 Vim 8 以后,包管理器变得不那么有用了,但是一些用户仍然喜欢它们,因为它们能够自动更新一些插件。有几个包管理器可供选择,并且它们各不相同,但是 [vim-plug][7] 有一些很棒的特性和最好的文档,这使我们很容易开始并在以后深入研究。
|
||||
|
||||
#### 使用 vim-plug 安装插件
|
||||
|
||||
安装 vim-plug,以便它在启动时自动加载:
|
||||
|
||||
```
|
||||
$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
|
||||
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
|
||||
```
|
||||
|
||||
创建一个 `~/.vimrc` 文件(如果你还没有这个文件),然后输入以下文本:
|
||||
|
||||
```
|
||||
call plug#begin()
|
||||
Plug 'preservim/NERDTree'
|
||||
call plug#end()
|
||||
```
|
||||
|
||||
每次要安装插件时,都必须在 `plug#begin()` 和 `plug#end()` 之间输入插件的名称和位置(上面以 NERDTree 文件管理器为例)。如果你所需的插件未托管在 GitHub 上,你可以提供完整的 URL,而不仅仅是 GitHub 的用户名和项目 ID。你甚至可以在 `~/.vim` 目录之外“安装”本地插件。
|
||||
|
||||
最后,启动 Vim 并提示 vim-plug 安装 `~/.vimrc` 中列出的插件:
|
||||
|
||||
```
|
||||
:PlugInstall
|
||||
```
|
||||
|
||||
等待插件下载。
|
||||
|
||||
#### 通过 vim-plug 更新插件
|
||||
|
||||
与手动安装过程相比,编辑 `~/.vimrc` 并使用命令来进行安装可能看起来并没有多省事,但是 vim-plug 的真正优势在更新。更新所有安装的插件,使用这个 Vim 命令:
|
||||
|
||||
```
|
||||
:PlugUpdate
|
||||
```
|
||||
|
||||
如果你不想更新所有的插件,你可以通过添加插件的名字来更新任何插件:
|
||||
|
||||
```
|
||||
:PlugUpdate NERDTree
|
||||
```
|
||||
|
||||
#### 恢复插件
|
||||
|
||||
vim-plug 的另一个优点是它的导出和恢复功能。Vim 用户都知道,正是插件的缘故,通常每个用户使用 Vim 的工作方式都是独一无二的。一旦你安装和配置了正确的插件组合,你最不想要的局面就是再也找不到它们。
|
||||
|
||||
Vim-plug 有这个命令来生成一个脚本来恢复所有当前的插件:
|
||||
|
||||
```
|
||||
:PlugSnapshot ~/vim-plug.list
|
||||
```
|
||||
vim-plug 还有许多其他的功能,所以请参考它的[项目页面][7]以获得完整的文档。
|
||||
|
||||
### 打造一个完美的 Vim
|
||||
|
||||
当你整天都在做一个项目时,你希望每一个小细节都能为你提供最好的服务。了解 Vim 和它的许多插件,直到你为你所做的事情构建出一个完美的应用程序。
|
||||
|
||||
有喜欢的 Vim 插件吗?请在评论中告诉我们吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/how-install-vim-plugins
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[qianmingtian][c]
|
||||
校对:[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
|
||||
[c]: https://github.com/qianmingtian
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos)
|
||||
[2]: https://www.vim.org/
|
||||
[3]: https://opensource.com/article/19/12/colors-themes-vim
|
||||
[4]: https://github.com/vim/vim/blob/03c3bd9fd094c1aede2e8fe3ad8fd25b9f033053/runtime/doc/repeat.txt#L515
|
||||
[5]: https://github.com/preservim/nerdtree
|
||||
[6]: https://opensource.com/sites/default/files/uploads/vim-nerdtree.jpg (NERDTree plugin)
|
||||
[7]: https://github.com/junegunn/vim-plug
|
104
published/202002/20200219 Don-t like IDEs- Try grepgitvi.md
Normal file
104
published/202002/20200219 Don-t like IDEs- Try grepgitvi.md
Normal file
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11934-1.html)
|
||||
[#]: subject: (Don't like IDEs? Try grepgitvi)
|
||||
[#]: via: (https://opensource.com/article/20/2/no-ide-script)
|
||||
[#]: author: (Yedidyah Bar David https://opensource.com/users/didib)
|
||||
|
||||
不喜欢 IDE?试试看 grepgitvi
|
||||
======
|
||||
|
||||
> 一个简单又原始的脚本来用 Vim 打开你选择的文件。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/26/113942a99a1aujmjpfnfrh.jpg)
|
||||
|
||||
像大多数开发者一样,我整天都在搜索和阅读源码。就我个人而言,我从来没有习惯过集成开发环境 (IDE),多年来,我主要使用 `grep` (找到文件),并复制/粘贴文件名来打开 Vi(m)。
|
||||
|
||||
最终,我写了这个脚本,并根据需要缓慢地对其进行了完善。
|
||||
|
||||
它依赖 [Vim][2] 和 [rlwrap][3],并使用 Apache 2.0 许可证开源。要使用该脚本,请[将它放到 PATH 中][4],然后在文本目录下运行:
|
||||
|
||||
```
|
||||
grepgitvi <grep options> <grep/vim search pattern>
|
||||
```
|
||||
|
||||
它将返回搜索结果的编号列表,并提示你输入结果编号并打开 Vim。退出 Vim 后,它将再次显示列表,直到你输入除结果编号以外的任何内容。你也可以使用向上和向下箭头键选择一个文件。(这对我来说)更容易找到我已经看过的结果。
|
||||
|
||||
与现代 IDE 甚至与 Vim 的更复杂的用法相比,它简单而原始,但它对我有用。
|
||||
|
||||
### 脚本
|
||||
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
# grepgitvi - grep source files, interactively open vim on results
|
||||
# Doesn't really have to do much with git, other than ignoring .git
|
||||
#
|
||||
# Copyright Yedidyah Bar David 2019
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Requires vim and rlwrap
|
||||
#
|
||||
# Usage: grepgitvi <grep options> <grep/vim pattern>
|
||||
#
|
||||
|
||||
TMPD=$(mktemp -d /tmp/grepgitvi.XXXXXX)
|
||||
UNCOLORED=${TMPD}/uncolored
|
||||
COLORED=${TMPD}/colored
|
||||
|
||||
RLHIST=${TMPD}/readline-history
|
||||
|
||||
[ -z "${DIRS}" ] && DIRS=.
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${TMPD}"
|
||||
}
|
||||
|
||||
trap cleanup 0
|
||||
|
||||
find ${DIRS} -iname .git -prune -o \! -iname "*.min.css*" -type f -print0 > ${TMPD}/allfiles
|
||||
|
||||
cat ${TMPD}/allfiles | xargs -0 grep --color=always -n -H "$@" > $COLORED
|
||||
cat ${TMPD}/allfiles | xargs -0 grep -n -H "$@" > $UNCOLORED
|
||||
|
||||
max=`cat $UNCOLORED | wc -l`
|
||||
pat="${@: -1}"
|
||||
|
||||
inp=''
|
||||
while true; do
|
||||
echo "============================ grep results ==============================="
|
||||
cat $COLORED | nl
|
||||
echo "============================ grep results ==============================="
|
||||
prompt="Enter a number between 1 and $max or anything else to quit: "
|
||||
inp=$(rlwrap -H $RLHIST bash -c "read -p \"$prompt\" inp; echo \$inp")
|
||||
if ! echo "$inp" | grep -q '^[0-9][0-9]*$' || [ "$inp" -gt "$max" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
filename=$(cat $UNCOLORED | awk -F: "NR==$inp"' {print $1}')
|
||||
linenum=$(cat $UNCOLORED | awk -F: "NR==$inp"' {print $2-1}')
|
||||
vim +:"$linenum" +"norm zz" +/"${pat}" "$filename"
|
||||
done
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/no-ide-script
|
||||
|
||||
作者:[Yedidyah Bar David][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/didib
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/files_documents_paper_folder.png?itok=eIJWac15 (Files in a folder)
|
||||
[2]: https://www.vim.org/
|
||||
[3]: https://linux.die.net/man/1/rlwrap
|
||||
[4]: https://opensource.com/article/17/6/set-path-linux
|
@ -0,0 +1,49 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (heguangzhi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11940-1.html)
|
||||
[#]: subject: (How Kubernetes Became the Standard for Compute Resources)
|
||||
[#]: via: (https://www.linux.com/articles/how-kubernetes-became-the-standard-for-compute-resources/)
|
||||
[#]: author: (Swapnil Bhartiya https://www.linux.com/author/swapnil/)
|
||||
|
||||
Kubernetes 如何成为计算资源的标准
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/28/131634mwzyylmv93m4ccws.jpg)
|
||||
|
||||
对于原生云生态系统来说,2019 年是改变游戏规则的一年。有大的[并购][1],如 Red Hat Docker 和 Pivotal,并出现其他的玩家,如 Rancher Labs 和 Mirantis。
|
||||
|
||||
Rancher Labs (一家为采用容器的团队提供完整软件栈的公司)的联合创始人兼首席执行官盛亮表示:“所有这些整合和并购,都表明这一领域的市场成熟的速度很快。”
|
||||
|
||||
传统上,像 Kubernetes 和 Docker 这样的新兴技术吸引着开发者和像脸书和谷歌这样的超级用户。除了这群人之外则没什么兴趣。然而,这两种技术都在企业层面得到了广泛采用。突然间,出现了一个巨大的市场,有着巨大的机会。几乎每个人都跳了进去。有人带来了创新的解决方案,也有人试图赶上其他人。它很快变得非常拥挤和热闹起来。
|
||||
|
||||
它也改变了创新的方式。[早期采用者通常是精通技术的公司][2]。现在,几乎每个人都在使用它,即使是在不被认为是 Kubernetes 地盘的地方。它改变了市场动态,像 Rancher Labs 这样的公司见证了独特的用例。
|
||||
|
||||
盛亮补充道,“我从来没有经历过像 Kubernete 这样快速、动态的市场或技术演变。当我们五年前开始的时候,这是一个非常拥挤的空间。随着时间的推移,我们大多数的友商因为这样或那样的原因消失了。他们要么无法适应变化,要么选择不适应某些变化。”
|
||||
|
||||
在 Kubernetes 的早期,最明显的机会是建立 Kubernetes 发行版本和 Kubernetes 业务。这是新技术。众所周知,它的安装、升级和操作相当的复杂。
|
||||
|
||||
当谷歌、AWS 和微软进入市场时,一切都变了。当时,一群供应商蜂拥而至,为平台提供解决方案。盛亮表示:“一旦像谷歌这样的云提供商决定将 Kubernetes 作为一项服务,并免费提供亏本出售的商品,以推动基础设施消费;我们就知道,运营和支持 Kubernetes 业务的优势将非常有限了。”
|
||||
|
||||
对谷歌之外的其它玩家来说,并非一切都不好。由于云供应商通过将它作为服务来提供,消除了 Kubernetes 带来的所有复杂性,这意味着更广泛地采用该技术,即使是那些由于运营成本而不愿使用该技术的人也是如此。这意味着 Kubernetes 将变得无处不在,并将成为一个行业标准。
|
||||
|
||||
“Rancher Labs 是极少数将此视为机遇并比其他公司看得更远的公司之一。我们意识到 Kubernetes 将成为新的计算标准,就像 TCP/IP 成为网络标准一样,”盛亮说。
|
||||
|
||||
CNCF 在围绕 Kubernetes 构建一个充满活力的生态系统方面发挥着至关重要的作用,创建了一个庞大的社区来构建、培育和商业化原生云开源技术。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/articles/how-kubernetes-became-the-standard-for-compute-resources/
|
||||
|
||||
作者:[Swapnil Bhartiya][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[heguangzhi](https://github.com/heguangzhi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/author/swapnil/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.cloudfoundry.org/blog/2019-is-the-year-of-consolidation-why-ibms-deal-with-red-hat-is-a-harbinger-of-things-to-come/
|
||||
[2]: https://www.packet.com/blog/open-source-season-on-the-kubernetes-highway/
|
@ -0,0 +1,128 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11929-1.html)
|
||||
[#]: subject: (How to Install Latest Git Version on Ubuntu)
|
||||
[#]: via: (https://itsfoss.com/install-git-ubuntu/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
如何在 Ubuntu 上安装最新版本的 Git
|
||||
======
|
||||
|
||||
在 Ubuntu 上安装 Git 非常容易。它存在于 [Ubuntu 的主仓库][1]中,你可以像这样[使用 apt 命令][2]安装它:
|
||||
|
||||
```
|
||||
sudo apt install git
|
||||
```
|
||||
|
||||
很简单?是不是?
|
||||
|
||||
只有一点点小问题(这可能根本不是问题),就是它安装的 [Git][3] 版本。
|
||||
|
||||
在 LTS 系统上,软件稳定性至关重要,这就是为什么 Ubuntu 18.04 和其他发行版经常提供较旧但稳定的软件版本的原因,它们都经过发行版的良好测试。
|
||||
|
||||
这就是为什么当你检查 Git 版本时,会看到安装的版本会比 [Git 网站上当前最新 Git 版本][4]旧:
|
||||
|
||||
```
|
||||
$ git --version
|
||||
git version 2.17.1
|
||||
```
|
||||
|
||||
在编写本教程时,网站上提供的版本为 2.25。那么,如何在 Ubuntu 上安装最新的 Git?
|
||||
|
||||
### 在基于 Ubuntu 的 Linux 发行版上安装最新的 Git
|
||||
|
||||
![][5]
|
||||
|
||||
一种方法是[从源代码安装][6]。这种很酷又老派的方法不适合所有人。值得庆幸的是,Ubuntu Git 维护团队提供了 [PPA][7],莫可以使用它轻松地安装最新的稳定 Git 版本。
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:git-core/ppa
|
||||
sudo apt update
|
||||
sudo apt install git
|
||||
```
|
||||
|
||||
即使你以前使用 `apt` 安装了 Git,它也将更新为最新的稳定版本。
|
||||
|
||||
```
|
||||
$ git --version
|
||||
git version 2.25.0
|
||||
```
|
||||
|
||||
[使用PPA][8] 的好处在于,如果发布了新的 Git 稳定版本,那么就可以通过系统更新获得它。[仅更新 Ubuntu][9] 来获取最新的 Git 稳定版本。
|
||||
|
||||
### 配置 Git (推荐给开发者)
|
||||
|
||||
如果你出于开发目的安装了 Git,你会很快开始克隆仓库,进行更改并提交更改。
|
||||
|
||||
如果你尝试提交代码,那么你可能会看到 “Please tell me who you are” 这样的错误:
|
||||
|
||||
```
|
||||
$ git commit -m "update readme"
|
||||
|
||||
*** Please tell me who you are.
|
||||
|
||||
Run
|
||||
|
||||
git config --global user.email "you@example.com"
|
||||
git config --global user.name "Your Name"
|
||||
|
||||
to set your account's default identity.
|
||||
Omit --global to set the identity only in this repository.
|
||||
|
||||
fatal: unable to auto-detect email address (got 'abhishek@itsfoss.(none)')
|
||||
```
|
||||
|
||||
这是因为你还没配置必要的个人信息。
|
||||
|
||||
正如错误已经暗示的那样,你可以像这样设置全局 Git 配置:
|
||||
|
||||
```
|
||||
git config --global user.name "Your Name"
|
||||
git config --global user.email "you@example.com"
|
||||
```
|
||||
|
||||
你可以使用以下命令检查 Git 配置:
|
||||
|
||||
```
|
||||
git config --list
|
||||
```
|
||||
|
||||
它应该显示如下输出:
|
||||
|
||||
```
|
||||
user.email=you@example.com
|
||||
user.name=Your Name
|
||||
```
|
||||
|
||||
配置保存在 `~/.gitconfig` 中。你可以手动修改配置。
|
||||
|
||||
### 结尾
|
||||
|
||||
我希望这个小教程可以帮助你在 Ubuntu 上安装 Git。使用 PPA,你可以轻松获得最新的 Git 版本。
|
||||
|
||||
如果你有任何疑问或建议,请随时在评论部分提问。也欢迎直接写“谢谢” :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-git-ubuntu/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/ubuntu-repositories/
|
||||
[2]: https://itsfoss.com/apt-command-guide/
|
||||
[3]: https://git-scm.com/
|
||||
[4]: https://git-scm.com/downloads
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/02/install_git_ubuntu.png?ssl=1
|
||||
[6]: https://itsfoss.com/install-software-from-source-code/
|
||||
[7]: https://launchpad.net/~git-core/+archive/ubuntu/ppa
|
||||
[8]: https://itsfoss.com/ppa-guide/
|
||||
[9]: https://itsfoss.com/update-ubuntu/
|
@ -0,0 +1,483 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (heguangzhi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11943-1.html)
|
||||
[#]: subject: (Using Python and GNU Octave to plot data)
|
||||
[#]: via: (https://opensource.com/article/20/2/python-gnu-octave-data-science)
|
||||
[#]: author: (Cristiano L. Fontana https://opensource.com/users/cristianofontana)
|
||||
|
||||
使用 Python 和 GNU Octave 绘制数据
|
||||
======
|
||||
|
||||
> 了解如何使用 Python 和 GNU Octave 完成一项常见的数据科学任务。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/29/114750tr7qykssk90yrvyz.jpg)
|
||||
|
||||
数据科学是跨越编程语言的知识领域。有些语言以解决这一领域的问题而闻名,而另一些则鲜为人知。这篇文章将帮助你熟悉用一些流行的语言完成数据科学的工作。
|
||||
|
||||
### 选择 Python 和 GNU Octave 做数据科学工作
|
||||
|
||||
我经常尝试学习一种新的编程语言。为什么?这既有对旧方式的厌倦,也有对新方式的好奇。当我开始学习编程时,我唯一知道的语言是 C 语言。那些年的编程生涯既艰难又危险,因为我必须手动分配内存、管理指针、并记得释放内存。
|
||||
|
||||
后来一个朋友建议我试试 Python,现在我的编程生活变得轻松多了。虽然程序运行变得慢多了,但我不必通过编写分析软件来受苦了。然而,我很快就意识到每种语言都有比其它语言更适合自己的应用场景。后来我学习了一些其它语言,每种语言都给我带来了一些新的启发。发现新的编程风格让我可以将一些解决方案移植到其他语言中,这样一切都变得有趣多了。
|
||||
|
||||
为了对一种新的编程语言(及其文档)有所了解,我总是从编写一些执行我熟悉的任务的示例程序开始。为此,我将解释如何用 Python 和 GNU Octave 编写一个程序来完成一个你可以归类为数据科学的特殊任务。如果你已经熟悉其中一种语言,从它开始,然后通过其他语言寻找相似之处和不同之处。这篇文章并不是对编程语言的详尽比较,只是一个小小的展示。
|
||||
|
||||
所有的程序都应该在[命令行][2]上运行,而不是用[图形用户界面][3](GUI)。完整的例子可以在 [polyglot_fit 存储库][4]中找到。
|
||||
|
||||
### 编程任务
|
||||
|
||||
你将在本系列中编写的程序:
|
||||
|
||||
* 从 [CSV 文件][5]中读取数据
|
||||
* 用直线插入数据(例如 `f(x)=m ⋅ x + q`)
|
||||
* 将结果生成图像文件
|
||||
|
||||
这是许多数据科学家遇到的常见情况。示例数据是 [Anscombe 的四重奏][6]的第一组,如下表所示。这是一组人工构建的数据,当用直线拟合时会给出相同的结果,但是它们的曲线非常不同。数据文件是一个文本文件,以制表符作为列分隔符,开头几行作为标题。此任务将仅使用第一组(即前两列)。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202002/29/122805h3yrs1dkrgysssxk.png)
|
||||
|
||||
### Python 方式
|
||||
|
||||
[Python][7] 是一种通用编程语言,是当今最流行的语言之一(依据 [TIOBE 指数][8]、[RedMonk 编程语言排名][9]、[编程语言流行指数][10]、[GitHub Octoverse 状态][11]和其他来源的调查结果)。它是一种[解释型语言][12];因此,源代码由执行该指令的程序读取和评估。它有一个全面的[标准库][13]并且总体上非常好用(我对这最后一句话没有证据;这只是我的拙见)。
|
||||
|
||||
#### 安装
|
||||
|
||||
要使用 Python 开发,你需要解释器和一些库。最低要求是:
|
||||
|
||||
* [NumPy][14] 用于简化数组和矩阵的操作
|
||||
* [SciPy][15] 用于数据科学
|
||||
* [Matplotlib][16] 用于绘图
|
||||
|
||||
在 [Fedora][17] 安装它们是很容易的:
|
||||
|
||||
```
|
||||
sudo dnf install python3 python3-numpy python3-scipy python3-matplotlib
|
||||
```
|
||||
|
||||
#### 代码注释
|
||||
|
||||
在 Python中,[注释][18]是通过在行首添加一个 `#` 来实现的,该行的其余部分将被解释器丢弃:
|
||||
|
||||
```
|
||||
# 这是被解释器忽略的注释。
|
||||
```
|
||||
|
||||
[fitting_python.py][19] 示例使用注释在源代码中插入许可证信息,第一行是[特殊注释][20],它允许该脚本在命令行上执行:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
```
|
||||
|
||||
这一行通知命令行解释器,该脚本需要由程序 `python3` 执行。
|
||||
|
||||
#### 需要的库
|
||||
|
||||
在 Python 中,库和模块可以作为一个对象导入(如示例中的第一行),其中包含库的所有函数和成员。可以通过使用 `as` 方式用自定义标签重命名它们:
|
||||
|
||||
```
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
import matplotlib.pyplot as plt
|
||||
```
|
||||
|
||||
你也可以决定只导入一个子模块(如第二行和第三行)。语法有两个(基本上)等效的方式:`import module.submodule` 和 `from module import submodule`。
|
||||
|
||||
#### 定义变量
|
||||
|
||||
Python 的变量是在第一次赋值时被声明的:
|
||||
|
||||
```
|
||||
input_file_name = "anscombe.csv"
|
||||
delimiter = "\t"
|
||||
skip_header = 3
|
||||
column_x = 0
|
||||
column_y = 1
|
||||
```
|
||||
|
||||
变量类型由分配给变量的值推断。没有具有常量值的变量,除非它们在模块中声明并且只能被读取。习惯上,不应被修改的变量应该用大写字母命名。
|
||||
|
||||
#### 打印输出
|
||||
|
||||
通过命令行运行程序意味着输出只能打印在终端上。Python 有 [print()][21] 函数,默认情况下,该函数打印其参数,并在输出的末尾添加一个换行符:
|
||||
|
||||
```
|
||||
print("#### Anscombe's first set with Python ####")
|
||||
```
|
||||
|
||||
在 Python 中,可以将 `print()` 函数与[字符串类][23]的[格式化能力][22]相结合。字符串具有`format` 方法,可用于向字符串本身添加一些格式化文本。例如,可以添加格式化的浮点数,例如:
|
||||
|
||||
```
|
||||
print("Slope: {:f}".format(slope))
|
||||
```
|
||||
|
||||
#### 读取数据
|
||||
|
||||
使用 NumPy 和函数 [genfromtxt()][24] 读取 CSV 文件非常容易,该函数生成 [NumPy 数组][25]:
|
||||
|
||||
```
|
||||
data = np.genfromtxt(input_file_name, delimiter = delimiter, skip_header = skip_header)
|
||||
```
|
||||
|
||||
在 Python 中,一个函数可以有数量可变的参数,你可以通过指定所需的参数来传递一个参数的子集。数组是非常强大的矩阵状对象,可以很容易地分割成更小的数组:
|
||||
|
||||
```
|
||||
x = data[:, column_x]
|
||||
y = data[:, column_y]
|
||||
```
|
||||
|
||||
冒号选择整个范围,也可以用来选择子范围。例如,要选择数组的前两行,可以使用:
|
||||
|
||||
```
|
||||
first_two_rows = data[0:1, :]
|
||||
```
|
||||
|
||||
#### 拟合数据
|
||||
|
||||
SciPy 提供了方便的数据拟合功能,例如 [linregress()][26] 功能。该函数提供了一些与拟合相关的重要值,如斜率、截距和两个数据集的相关系数:
|
||||
|
||||
```
|
||||
slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
|
||||
|
||||
print("Slope: {:f}".format(slope))
|
||||
print("Intercept: {:f}".format(intercept))
|
||||
print("Correlation coefficient: {:f}".format(r_value))
|
||||
```
|
||||
|
||||
因为 `linregress()` 提供了几条信息,所以结果可以同时保存到几个变量中。
|
||||
|
||||
#### 绘图
|
||||
|
||||
Matplotlib 库仅仅绘制数据点,因此,你应该定义要绘制的点的坐标。已经定义了 `x` 和 `y` 数组,所以你可以直接绘制它们,但是你还需要代表直线的数据点。
|
||||
|
||||
```
|
||||
fit_x = np.linspace(x.min() - 1, x.max() + 1, 100)
|
||||
```
|
||||
|
||||
[linspace()][27] 函数可以方便地在两个值之间生成一组等距值。利用强大的 NumPy 数组可以轻松计算纵坐标,该数组可以像普通数值变量一样在公式中使用:
|
||||
|
||||
```
|
||||
fit_y = slope * fit_x + intercept
|
||||
```
|
||||
|
||||
该公式在数组中逐元素应用;因此,结果在初始数组中具有相同数量的条目。
|
||||
|
||||
要绘图,首先,定义一个包含所有图形的[图形对象][28]:
|
||||
|
||||
```
|
||||
fig_width = 7 #inch
|
||||
fig_height = fig_width / 16 * 9 #inch
|
||||
fig_dpi = 100
|
||||
|
||||
fig = plt.figure(figsize = (fig_width, fig_height), dpi = fig_dpi)
|
||||
```
|
||||
|
||||
一个图形可以画几个图;在 Matplotlib 中,这些图被称为[轴][29]。本示例定义一个单轴对象来绘制数据点:
|
||||
|
||||
```
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
ax.plot(fit_x, fit_y, label = "Fit", linestyle = '-')
|
||||
ax.plot(x, y, label = "Data", marker = '.', linestyle = '')
|
||||
|
||||
ax.legend()
|
||||
ax.set_xlim(min(x) - 1, max(x) + 1)
|
||||
ax.set_ylim(min(y) - 1, max(y) + 1)
|
||||
ax.set_xlabel('x')
|
||||
ax.set_ylabel('y')
|
||||
```
|
||||
|
||||
将该图保存到 [PNG 图形文件][30]中,有:
|
||||
|
||||
```
|
||||
fig.savefig('fit_python.png')
|
||||
```
|
||||
|
||||
如果要显示(而不是保存)该绘图,请调用:
|
||||
|
||||
```
|
||||
plt.show()
|
||||
```
|
||||
|
||||
此示例引用了绘图部分中使用的所有对象:它定义了对象 `fig` 和对象 `ax`。这在技术上是不必要的,因为 `plt` 对象可以直接用于绘制数据集。《[Matplotlib 教程][31]》展示了这样一个接口:
|
||||
|
||||
```
|
||||
plt.plot(fit_x, fit_y)
|
||||
```
|
||||
|
||||
坦率地说,我不喜欢这种方法,因为它隐藏了各种对象之间发生的重要交互。不幸的是,有时[官方的例子][32]有点令人困惑,因为他们倾向于使用不同的方法。在这个简单的例子中,引用图形对象是不必要的,但是在更复杂的例子中(例如在图形用户界面中嵌入图形时),引用图形对象就变得很重要了。
|
||||
|
||||
#### 结果
|
||||
|
||||
命令行输入:
|
||||
|
||||
```
|
||||
#### Anscombe's first set with Python ####
|
||||
Slope: 0.500091
|
||||
Intercept: 3.000091
|
||||
Correlation coefficient: 0.816421
|
||||
```
|
||||
|
||||
这是 Matplotlib 产生的图像:
|
||||
|
||||
![Plot and fit of the dataset obtained with Python][33]
|
||||
|
||||
### GNU Octave 方式
|
||||
|
||||
[GNU Octave][34] 语言主要用于数值计算。它提供了一个简单的操作向量和矩阵的语法,并且有一些强大的绘图工具。这是一种像 Python 一样的解释语言。由于 Octave 的语法[几乎兼容][35] [MATLAB][36],它经常被描述为一个替代 MATLAB 的免费方案。Octave 没有被列为最流行的编程语言,而 MATLAB 则是,所以 Octave 在某种意义上是相当流行的。MATLAB 早于 NumPy,我觉得它是受到了前者的启发。当你看这个例子时,你会看到相似之处。
|
||||
|
||||
#### 安装
|
||||
|
||||
[fitting_octave.m][37] 的例子只需要基本的 Octave 包,在 Fedora 中安装相当简单:
|
||||
|
||||
```
|
||||
sudo dnf install octave
|
||||
```
|
||||
|
||||
#### 代码注释
|
||||
|
||||
在 Octave 中,你可以用百分比符号(`%`)为代码添加注释,如果不需要与 MATLAB 兼容,你也可以使用 `#`。使用 `#` 的选项允许你编写像 Python 示例一样的特殊注释行,以便直接在命令行上执行脚本。
|
||||
|
||||
#### 必要的库
|
||||
|
||||
本例中使用的所有内容都包含在基本包中,因此你不需要加载任何新的库。如果你需要一个库,[语法][38]是 `pkg load module`。该命令将模块的功能添加到可用功能列表中。在这方面,Python 具有更大的灵活性。
|
||||
|
||||
#### 定义变量
|
||||
|
||||
变量的定义与 Python 的语法基本相同:
|
||||
|
||||
```
|
||||
input_file_name = "anscombe.csv";
|
||||
delimiter = "\t";
|
||||
skip_header = 3;
|
||||
column_x = 1;
|
||||
column_y = 2;
|
||||
```
|
||||
|
||||
请注意,行尾有一个分号;这不是必需的,但是它会抑制该行结果的输出。如果没有分号,解释器将打印表达式的结果:
|
||||
|
||||
```
|
||||
octave:1> input_file_name = "anscombe.csv"
|
||||
input_file_name = anscombe.csv
|
||||
octave:2> sqrt(2)
|
||||
ans = 1.4142
|
||||
```
|
||||
|
||||
#### 打印输出结果
|
||||
|
||||
强大的函数 [printf()][39] 是用来在终端上打印的。与 Python 不同,`printf()` 函数不会自动在打印字符串的末尾添加换行,因此你必须添加它。第一个参数是一个字符串,可以包含要传递给函数的其他参数的格式信息,例如:
|
||||
|
||||
```
|
||||
printf("Slope: %f\n", slope);
|
||||
```
|
||||
|
||||
在 Python 中,格式是内置在字符串本身中的,但是在 Octave 中,它是特定于 `printf()` 函数。
|
||||
|
||||
#### 读取数据
|
||||
|
||||
[dlmread()][40] 函数可以读取类似 CSV 文件的文本内容:
|
||||
|
||||
```
|
||||
data = dlmread(input_file_name, delimiter, skip_header, 0);
|
||||
```
|
||||
|
||||
结果是一个[矩阵][41]对象,这是 Octave 中的基本数据类型之一。矩阵可以用类似于 Python 的语法进行切片:
|
||||
|
||||
```
|
||||
x = data(:, column_x);
|
||||
y = data(:, column_y);
|
||||
```
|
||||
|
||||
根本的区别是索引从 1 开始,而不是从 0 开始。因此,在该示例中,`x` 列是第一列。
|
||||
|
||||
#### 拟合数据
|
||||
|
||||
要用直线拟合数据,可以使用 [polyfit()][42] 函数。它用一个多项式拟合输入数据,所以你只需要使用一阶多项式:
|
||||
|
||||
```
|
||||
p = polyfit(x, y, 1);
|
||||
|
||||
slope = p(1);
|
||||
intercept = p(2);
|
||||
```
|
||||
|
||||
结果是具有多项式系数的矩阵;因此,它选择前两个索引。要确定相关系数,请使用 [corr()][43] 函数:
|
||||
|
||||
```
|
||||
r_value = corr(x, y);
|
||||
```
|
||||
|
||||
最后,使用 `printf()` 函数打印结果:
|
||||
|
||||
```
|
||||
printf("Slope: %f\n", slope);
|
||||
printf("Intercept: %f\n", intercept);
|
||||
printf("Correlation coefficient: %f\n", r_value);
|
||||
```
|
||||
|
||||
#### 绘图
|
||||
|
||||
与 Matplotlib 示例一样,首先需要创建一个表示拟合直线的数据集:
|
||||
|
||||
```
|
||||
fit_x = linspace(min(x) - 1, max(x) + 1, 100);
|
||||
fit_y = slope * fit_x + intercept;
|
||||
```
|
||||
|
||||
与 NumPy 的相似性也很明显,因为它使用了 [linspace()][44] 函数,其行为就像 Python 的等效版本一样。
|
||||
|
||||
同样,与 Matplotlib 一样,首先创建一个[图][45]对象,然后创建一个[轴][46]对象来保存这些图:
|
||||
|
||||
```
|
||||
fig_width = 7; %inch
|
||||
fig_height = fig_width / 16 * 9; %inch
|
||||
fig_dpi = 100;
|
||||
|
||||
fig = figure("units", "inches",
|
||||
"position", [1, 1, fig_width, fig_height]);
|
||||
|
||||
ax = axes("parent", fig);
|
||||
|
||||
set(ax, "fontsize", 14);
|
||||
set(ax, "linewidth", 2);
|
||||
```
|
||||
|
||||
要设置轴对象的属性,请使用 [set()][47] 函数。然而,该接口相当混乱,因为该函数需要一个逗号分隔的属性和值对列表。这些对只是代表属性名的一个字符串和代表该属性值的第二个对象的连续。还有其他设置各种属性的函数:
|
||||
|
||||
```
|
||||
xlim(ax, [min(x) - 1, max(x) + 1]);
|
||||
ylim(ax, [min(y) - 1, max(y) + 1]);
|
||||
xlabel(ax, 'x');
|
||||
ylabel(ax, 'y');
|
||||
```
|
||||
|
||||
绘图是用 [plot()][48] 功能实现的。默认行为是每次调用都会重置坐标轴,因此需要使用函数 [hold()][49]。
|
||||
|
||||
```
|
||||
hold(ax, "on");
|
||||
|
||||
plot(ax, fit_x, fit_y,
|
||||
"marker", "none",
|
||||
"linestyle", "-",
|
||||
"linewidth", 2);
|
||||
plot(ax, x, y,
|
||||
"marker", ".",
|
||||
"markersize", 20,
|
||||
"linestyle", "none");
|
||||
|
||||
hold(ax, "off");
|
||||
```
|
||||
|
||||
此外,还可以在 `plot()` 函数中添加属性和值对。[legend][50] 必须单独创建,标签应手动声明:
|
||||
|
||||
```
|
||||
lg = legend(ax, "Fit", "Data");
|
||||
set(lg, "location", "northwest");
|
||||
```
|
||||
|
||||
最后,将输出保存到 PNG 图像:
|
||||
|
||||
```
|
||||
image_size = sprintf("-S%f,%f", fig_width * fig_dpi, fig_height * fig_dpi);
|
||||
image_resolution = sprintf("-r%f,%f", fig_dpi);
|
||||
|
||||
print(fig, 'fit_octave.png',
|
||||
'-dpng',
|
||||
image_size,
|
||||
image_resolution);
|
||||
```
|
||||
|
||||
令人困惑的是,在这种情况下,选项被作为一个字符串传递,带有属性名和值。因为在 Octave 字符串中没有 Python 的格式化工具,所以必须使用 [sprintf()][51] 函数。它的行为就像 `printf()` 函数,但是它的结果不是打印出来的,而是作为字符串返回的。
|
||||
|
||||
在这个例子中,就像在 Python 中一样,图形对象很明显被引用以保持它们之间的交互。如果说 Python 在这方面的文档有点混乱,那么 [Octave 的文档][52]就更糟糕了。我发现的大多数例子都不关心引用对象;相反,它们依赖于绘图命令作用于当前活动图形。全局[根图形对象][53]跟踪现有的图形和轴。
|
||||
|
||||
#### 结果
|
||||
|
||||
命令行上的结果输出是:
|
||||
|
||||
```
|
||||
#### Anscombe's first set with Octave ####
|
||||
Slope: 0.500091
|
||||
Intercept: 3.000091
|
||||
Correlation coefficient: 0.816421
|
||||
```
|
||||
|
||||
它显示了用 Octave 生成的结果图像。
|
||||
|
||||
![Plot and fit of the dataset obtained with Octave][54]
|
||||
|
||||
###接下来
|
||||
|
||||
Python 和 GNU Octave 都可以绘制出相同的信息,尽管它们的实现方式不同。如果你想探索其他语言来完成类似的任务,我强烈建议你看看 [Rosetta Code][55]。这是一个了不起的资源,可以看到如何用多种语言解决同样的问题。
|
||||
|
||||
你喜欢用什么语言绘制数据?在评论中分享你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/python-gnu-octave-data-science
|
||||
|
||||
作者:[Cristiano L. Fontana][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[heguangzhi](https://github.com/heguangzhi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/cristianofontana
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/analytics-graphs-charts.png?itok=sersoqbV (Analytics: Charts and Graphs)
|
||||
[2]: https://en.wikipedia.org/wiki/Command-line_interface
|
||||
[3]: https://en.wikipedia.org/wiki/Graphical_user_interface
|
||||
[4]: https://gitlab.com/cristiano.fontana/polyglot_fit
|
||||
[5]: https://en.wikipedia.org/wiki/Comma-separated_values
|
||||
[6]: https://en.wikipedia.org/wiki/Anscombe%27s_quartet
|
||||
[7]: https://www.python.org/
|
||||
[8]: https://www.tiobe.com/tiobe-index/
|
||||
[9]: https://redmonk.com/sogrady/2019/07/18/language-rankings-6-19/
|
||||
[10]: http://pypl.github.io/PYPL.html
|
||||
[11]: https://octoverse.github.com/
|
||||
[12]: https://en.wikipedia.org/wiki/Interpreted_language
|
||||
[13]: https://docs.python.org/3/library/
|
||||
[14]: https://numpy.org/
|
||||
[15]: https://www.scipy.org/
|
||||
[16]: https://matplotlib.org/
|
||||
[17]: https://getfedora.org/
|
||||
[18]: https://en.wikipedia.org/wiki/Comment_(computer_programming)
|
||||
[19]: https://gitlab.com/cristiano.fontana/polyglot_fit/-/blob/master/fitting_python.py
|
||||
[20]: https://en.wikipedia.org/wiki/Shebang_(Unix)
|
||||
[21]: https://docs.python.org/3/library/functions.html#print
|
||||
[22]: https://docs.python.org/3/library/string.html#string-formatting
|
||||
[23]: https://docs.python.org/3/library/string.html
|
||||
[24]: https://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html
|
||||
[25]: https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html
|
||||
[26]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html
|
||||
[27]: https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html
|
||||
[28]: https://matplotlib.org/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure
|
||||
[29]: https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes
|
||||
[30]: https://en.wikipedia.org/wiki/Portable_Network_Graphics
|
||||
[31]: https://matplotlib.org/tutorials/introductory/pyplot.html#sphx-glr-tutorials-introductory-pyplot-py
|
||||
[32]: https://matplotlib.org/gallery/index.html
|
||||
[33]: https://opensource.com/sites/default/files/uploads/fit_python.png (Plot and fit of the dataset obtained with Python)
|
||||
[34]: https://www.gnu.org/software/octave/
|
||||
[35]: https://wiki.octave.org/FAQ#Differences_between_Octave_and_Matlab
|
||||
[36]: https://en.wikipedia.org/wiki/MATLAB
|
||||
[37]: https://gitlab.com/cristiano.fontana/polyglot_fit/-/blob/master/fitting_octave.m
|
||||
[38]: https://octave.org/doc/v5.1.0/Using-Packages.html#Using-Packages
|
||||
[39]: https://octave.org/doc/v5.1.0/Formatted-Output.html#XREFprintf
|
||||
[40]: https://octave.org/doc/v5.1.0/Simple-File-I_002fO.html#XREFdlmread
|
||||
[41]: https://octave.org/doc/v5.1.0/Matrices.html
|
||||
[42]: https://octave.org/doc/v5.1.0/Polynomial-Interpolation.html
|
||||
[43]: https://octave.org/doc/v5.1.0/Correlation-and-Regression-Analysis.html#XREFcorr
|
||||
[44]: https://octave.sourceforge.io/octave/function/linspace.html
|
||||
[45]: https://octave.org/doc/v5.1.0/Multiple-Plot-Windows.html
|
||||
[46]: https://octave.org/doc/v5.1.0/Graphics-Objects.html#XREFaxes
|
||||
[47]: https://octave.org/doc/v5.1.0/Graphics-Objects.html#XREFset
|
||||
[48]: https://octave.org/doc/v5.1.0/Two_002dDimensional-Plots.html#XREFplot
|
||||
[49]: https://octave.org/doc/v5.1.0/Manipulation-of-Plot-Windows.html#XREFhold
|
||||
[50]: https://octave.org/doc/v5.1.0/Plot-Annotations.html#XREFlegend
|
||||
[51]: https://octave.org/doc/v5.1.0/Formatted-Output.html#XREFsprintf
|
||||
[52]: https://octave.org/doc/v5.1.0/Two_002dDimensional-Plots.html#Two_002dDimensional-Plots
|
||||
[53]: https://octave.org/doc/v5.1.0/Graphics-Objects.html#XREFgroot
|
||||
[54]: https://opensource.com/sites/default/files/uploads/fit_octave.png (Plot and fit of the dataset obtained with Octave)
|
||||
[55]: http://www.rosettacode.org/
|
220
published/202003/20170918 Fun and Games in Emacs.md
Normal file
220
published/202003/20170918 Fun and Games in Emacs.md
Normal file
@ -0,0 +1,220 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11949-1.html)
|
||||
[#]: subject: (Fun and Games in Emacs)
|
||||
[#]: via: (https://www.masteringemacs.org/article/fun-games-in-emacs)
|
||||
[#]: author: (Mickey Petersen https://www.masteringemacs.org/about)
|
||||
|
||||
“Emacs 游戏机”完全指南
|
||||
======
|
||||
|
||||
又是周一,你正在为你的老板 Lumbergh (LCTT 译注:《上班一条虫》中的副总裁)努力倒腾那些 [无聊之极的文档][1]。为什么不玩玩 Emacs 中类似 zork 的文字冒险游戏来让你的大脑从单调的工作中解脱出来呢?
|
||||
|
||||
但说真的,Emacs 中既有游戏,也有古怪的玩物。有些你可能有所耳闻。这些玩意唯一的共同点就是,它们大多是很久以前就添加到 Emacs 中的:有些东西真的是相当古怪(如你将在下面看到的),而另一些则显然是由无聊的员工或学生们编写的。它们全有一个共同点,都带着一种奇思妙想和随意性,这在今天的 Emacs 中很少见。Emacs 现在变得十分严肃,在某种程度上,它已经与 20 世纪 80 年代那些游戏被编写出来的时候大不一样。
|
||||
|
||||
### 汉诺塔
|
||||
|
||||
[汉诺塔][2] 是一款古老的数学解密游戏,有些人可能对它很熟悉,因为它的递归和迭代解决方案经常被用于计算机科学教学辅助。
|
||||
|
||||
![Tower of Hanoi Screenshot](https://www.masteringemacs.org/static/uploads/hanoi.png)
|
||||
|
||||
Emacs 中有三个命令可以运行汉诺塔:`M-x hanoi` 默认为 3 个碟子; `M-x hanoi-unix` 和 `M-x hanoi-unix-64` 使用 unix 时间戳的位数(32 位或 64 位)作为默认盘子的个数,并且每秒钟自动移动一次,两者不同之处在于后者假装使用 64 位时钟(因此有 64 个碟子)。
|
||||
|
||||
Emacs 中汉诺塔的实现可以追溯到 20 世纪 80 年代中期——确实是久得可怕。它有一些自定义选项(`M-x customize-group RET hanoi RET`),如启用彩色碟子等。当你离开汉诺塔缓冲区或输入一个字符,你会收到一个讽刺的告别信息(见上图)。
|
||||
|
||||
### 5x5
|
||||
|
||||
![5x5 game grid](https://www.masteringemacs.org/static/uploads/5x5.png)
|
||||
|
||||
5x5 的游戏是一个逻辑解密游戏:你有一个 5x5 的网格,中间的十字被填满;你的目标是通过按正确的顺序切换它们的空满状态来填充所有的单元格,从而获得胜利。这并不像听起来那么容易!
|
||||
|
||||
输入 `M-x 5x5` 就可以开始玩了,使用可选的数字参数可以改变网格的大小。这款游戏的有趣之处在于它能向你建议下一步行动并尝试找到该游戏网格的解法。它用到了 Emacs 自己的一款非常酷的符号 RPN 计算器 `M-x calc`(在《[Emacs 快乐计算][3]》这篇文章中,我使用它来解决了一个简单的问题)。
|
||||
|
||||
所以我喜欢这个游戏的原因是它提供了一个非常复杂的解题器——真的,你应该通过 `M-x find-library RET 5x5` 来阅读其源代码——这是一个试图通过暴力破解游戏解法的“破解器”。
|
||||
|
||||
创建一个更大的游戏网格,例如输入 `M-10 M-x 5x5`,然后运行下面某个 `crack` 命令。破解器将尝试通过迭代获得最佳解决方案。它会实时运行该游戏,观看起来非常有趣:
|
||||
|
||||
- `M-x 5x5-crack-mutating-best`: 试图通过变异最佳解决方案来破解 5x5。
|
||||
- `M-x 5x5-crack-mutating-current`: 试图通过变异当前解决方案来破解 5x5。
|
||||
- `M-x 5x5-crack-random`: 尝试使用随机方案解破解 5x5。
|
||||
- `M-x 5x5-crack-xor-mutate`: 尝试通过将当前方案和最佳方案进行异或运算来破解 5x5。
|
||||
|
||||
### 文本动画
|
||||
|
||||
你可以通过运行 `M-x animation-birthday-present` 并给出你的名字来显示一个奇特的生日礼物动画。它看起来很酷!
|
||||
|
||||
![xkcd](https://imgs.xkcd.com/comics/real_programmers.png)
|
||||
|
||||
这里用的 `animate` 包也用在了 `M-x butterfly` 命令中,这是一个向上面的 [XKCD][4] 漫画致敬而添加到 Emacs 中的命令。当然,漫画中的 Emacs 命令在技术上是无效的,但它的幽默足以弥补这一点。
|
||||
|
||||
### 黑箱
|
||||
|
||||
我将逐字引用这款游戏的目标:
|
||||
|
||||
> 游戏的目标是通过向黑盒子发射光线来找到四个隐藏的球。有四种可能:
|
||||
> 1) 射线将通过盒子不受干扰;
|
||||
> 2) 它将击中一个球并被吸收;
|
||||
> 3) 它将偏转并退出盒子,或
|
||||
> 4) 立即偏转,甚至不能进入盒子。
|
||||
|
||||
所以,这有点像我们小时候玩的[战舰游戏][5],但是……是专为物理专业高学历的人准备的吧?
|
||||
|
||||
这是另一款添加于 20 世纪 80 年代的游戏。我建议你输入 `C-h f blackbox` 来阅读玩法说明(文档巨大)。
|
||||
|
||||
|
||||
### 泡泡
|
||||
|
||||
![Bubbles game](https://www.masteringemacs.org/static/uploads/bubbles.png)
|
||||
|
||||
`M-x bubble` 游戏相当简单:你必须用尽可能少移动清除尽可能多的“泡泡”。当你移除气泡时,其他气泡会掉落并粘在一起。这是一款有趣的游戏,此外如果你使用 Emacs 的图形用户界面,它还支持图像显示。而且它还支持鼠标。
|
||||
|
||||
你可以通过调用 `M-x bubbles-set-game-<difficulty>` 来设置难度,其中 `<difficulty>` 可以是这些之一:`easy`、`medium`、`difficult`、`hard` 或 `userdefined`。此外,你可以使用:`M-x custom-group bubbles` 来更改图形、网格大小和颜色。
|
||||
|
||||
由于它即简单又有趣,这是 Emacs 中我最喜欢的游戏之一。
|
||||
|
||||
### 幸运饼干
|
||||
|
||||
我喜欢 `fortune` 命令。每当我启动一个新 shell 时,这些与文学片段、谜语相结合的刻薄、无益、常常带有讽刺意味的“建议”就会点亮我的一天。
|
||||
|
||||
令人困惑的是,Emacs 中有两个包或多或少地做着类似的事情:`fortune` 和 `cookie`。前者主要用于在电子邮件签名中添加幸运饼干消息,而后者只是一个简单的 fortune 格式阅读器。
|
||||
|
||||
不管怎样,使用 Emacs 的 `cookie` 包前,你首先需要通过 `customize-option RET cookie RET` 来自定义变量 `cookie-file` 告诉它从哪找到 fortune 文件。
|
||||
|
||||
如果你的操作系统是 Ubuntu,那么你先安装 `fortune` 软件包,然后就能在 `/usr/share/games/fortune/` 目录中找到这些文件了。
|
||||
|
||||
之后你就可以调用 `M-x cookie` 随机显示 fortune 内容,或者,如果你想的话,也可以调用 `M-x cookie-apropos` 查找所有匹配的饼干。
|
||||
|
||||
### 破译器
|
||||
|
||||
这个包完美地抓住了 Emacs 的功利本质:这个包为你破解简单的替换密码(如“密码谜题”)提供了一个很有用的界面。你知道,二十多年前,有些人确实迫切需要破解很多基本的密码。正是像这个模块这样的小玩意让我非常高兴地用起 Emacs 来:一个只对少数人有用的模块,但是,如果你突然需要它了,那么它就在那里等着你。
|
||||
|
||||
那么如何使用它呢?让我们假设使用 “rot13” 密码:在 26 个字符的字母表中,将字符旋转 13 个位置。
|
||||
通过 `M-x ielm` (Emacs 用于 [运行 Elisp][6] 的 REPL 环境)可以很容易在 Emacs 中进行尝试:
|
||||
|
||||
```
|
||||
*** Welcome to IELM *** Type (describe-mode) for help.
|
||||
ELISP> (rot13 "Hello, World")
|
||||
"Uryyb, Jbeyq"
|
||||
ELISP> (rot13 "Uryyb, Jbeyq")
|
||||
"Hello, World"
|
||||
ELISP>
|
||||
```
|
||||
|
||||
简而言之,你将明文旋转了 13 个位置,就得到了密文。你又旋转了一次 13 个位置,就返回了最初的明文。 这就是这个包可以帮助你解决的问题。
|
||||
|
||||
那么,decipher 模块又是如何帮助我们的呢?让我们创建一个新的缓冲区 `test-cipher` 并输入你的密文(在我的例子中是 `Uryyb,Jbeyq`)。
|
||||
|
||||
![cipher](https://www.masteringemacs.org/static/uploads/cipher.png)
|
||||
|
||||
你现在面对的是一个相当复杂的界面。现在把光标放在紫色行的密文的任意字符上,并猜测这个字符可能是什么:Emacs 将根据你的选择更新其他明文的猜测结果,并告诉你目前为止字母表中的字符是如何分配的。
|
||||
|
||||
你现在可以用下面各种助手命令来关闭选项,以帮助推断密码字符可能对应的明文字符:
|
||||
|
||||
- `D`: 列出示意图(该加密算法中双字符对)及其频率
|
||||
- `F`: 表示每个密文字母的频率
|
||||
- `N`: 显示字符的邻近信息。我不确定这是干啥的。
|
||||
- `M` 和 `R`: 保存和恢复一个检查点,允许你对工作进行分支以探索破解密码的不同方法。
|
||||
|
||||
总而言之,对于这样一个深奥的任务,这个包是相当令人印象深刻的!如果你经常破解密码,也许这个程序包能帮上忙?
|
||||
|
||||
### 医生
|
||||
|
||||
![doctor](https://www.masteringemacs.org/static/uploads/doctor.png)
|
||||
|
||||
啊,Emacs 医生。其基于最初的 [ELIZA][7],“医生”试图对你说的话进行心理分析,并试图把问题复述给你。体验几分钟,相当有趣,它也是 Emacs 中最著名的古怪玩意之一。你可以使用 `M-x doctor` 来运行它。
|
||||
|
||||
### Dunnet
|
||||
|
||||
Emacs 自己特有的类 Zork 文字冒险游戏。输入 `M-x dunnet` 就能玩了。这是一款相当不错的游戏,简单的说,它是另一款非常著名的 Emacs 游戏,很少有人真正玩到通关。
|
||||
|
||||
如果你发现自己能在无聊的文档工作之间空出时间来,那么这是一个超级棒的游戏,内置“老板屏幕”,因为它是纯文本的。
|
||||
|
||||
哦,还有,不要想着吃掉那块 CPU 卡 :)
|
||||
|
||||
### 五子棋
|
||||
|
||||
![gomoku](https://www.masteringemacs.org/static/uploads/gomoku.png)
|
||||
|
||||
另一款写于 20 世纪 80 年代的游戏。你必须将 5 个方块连成一条线,井字棋风格。你可以运行 `M-x gomoku` 来与 Emacs 对抗。游戏还支持鼠标,非常方便。你也可以自定义 `gomoku` 组来调整网格的大小。
|
||||
|
||||
### 生命游戏
|
||||
|
||||
[康威的生命游戏][8] 是细胞自动机的一个著名例子。Emacs 版本提供了一些启动模式,你可以(通过 elisp 编程)调整 `life-patterns` 变量来更改这些模式。
|
||||
|
||||
你可以用 `M-x life` 触发生命游戏。事实上,所有的东西,包括显示代码、注释等等一切,总共不到 300 行,这也让人印象深刻。
|
||||
|
||||
### 乒乓,贪吃蛇和俄罗斯方块
|
||||
|
||||
![tetris](https://www.masteringemacs.org/static/uploads/tetris.png)
|
||||
|
||||
这些经典游戏都是使用 Emacs 包 `gamegrid` 实现的,这是一个用于构建网格游戏(如俄罗斯方块和贪吃蛇)的通用框架。gamegrid 包的伟大之处在于它同时兼容图形化和终端 Emacs:如果你在 GUI 中运行 Emacs,你会得到精美的图形;如果你没有,你看到简单的 ASCII 艺术。
|
||||
|
||||
你可以通过输入 `M-x pong`、`M-x snake`、`M-x tetris` 来运行这些游戏。
|
||||
|
||||
特别是俄罗斯方块游戏实现的非常到位,会逐渐增加速度并且能够滑块。而且既然你已经有了源代码,你完全可以移除那个讨厌的 Z 形块,没人喜欢它!
|
||||
|
||||
### Solitaire
|
||||
|
||||
![solitaire image](https://www.masteringemacs.org/static/uploads/solitaire.png)
|
||||
|
||||
可惜,这不是纸牌游戏,而是一个基于“钉子”的游戏,你可以选择一块石头(`o`)并“跳过”相邻的石头进入洞中(`.`),并在这个过程中去掉你跳过的石头,最终只能在棋盘上留下一块石头,重复该过程直到棋盘被请空(只保留一个石头)。
|
||||
|
||||
如果你卡住了,有一个内置的解题器名为 `M-x solitire-solve`。
|
||||
|
||||
### Zone
|
||||
|
||||
我的另一个最爱。这是一个屏幕保护程序——或者更确切地说,是一系列的屏幕保护程序。
|
||||
|
||||
输入 `M-x zone`,然后看看屏幕上发生了什么!
|
||||
|
||||
你可以通过运行 `M-x zone-when-idle`(或从 elisp 调用它)来配置屏幕保护程序的空闲时间,时间以秒为单位。你也可以通过 `M-x zone-leave-me-alone` 来关闭它。
|
||||
|
||||
如果在你的同事看着的时候启动它,你的同事肯定会抓狂的。
|
||||
|
||||
### 乘法解谜
|
||||
|
||||
![mpuz](https://www.masteringemacs.org/static/uploads/mpuz.png)
|
||||
|
||||
这是另一个脑筋急转弯的益智游戏。当你运行 `M-x mpuz` 时,将看到一个乘法解谜题,你必须将字母替换为对应的数字,并确保数字相加(相乘?)符合结果。
|
||||
|
||||
如果遇到难题,可以运行 `M-x mpuz-show-solution` 来解决。
|
||||
|
||||
### 杂项
|
||||
|
||||
还有更多好玩的东西,但它们就不如刚才那些那么好玩好用了:
|
||||
|
||||
- 你可以通过 `M-x morse-region` 和 `M-x unmorse-region` 将一个区域翻译成莫尔斯电码。
|
||||
- Dissociated Press 是一个非常简单的命令,它将一个类似随机穿行的马尔可夫链生成器应用到缓冲区中的文本中,并以此生成无意义的文本。试一下 `M-x dissociated-press`。
|
||||
- `gametree` 软件包是一个通过电子邮件记录和跟踪国际象棋游戏的复杂方法。
|
||||
- `M-x spook` 命令插入随机单词(通常是到电子邮件中),目的是混淆/超载 “NSA 拖网渔船” —— 记住,这个模块可以追溯到 20 世纪 80 年代和 90 年代,那时应该有间谍们在监听各种单词。当然,即使是在十年前,这样做也会显得非常偏执和古怪,不过现在看来已经不那么奇怪了……
|
||||
|
||||
### 总结
|
||||
|
||||
我喜欢 Emacs 附带的游戏和玩具。它们大多来自于,嗯,我们姑且称之为一个不同的时代:一个允许或甚至鼓励奇思妙想的时代。有些玩意非常经典(如俄罗斯方块和汉诺塔),有些对经典游戏进行了有趣的变种(如黑盒)——但我很高兴这么多年后它们依然存在于 Emacs 中。我想知道时至今日,类似这些的玩意是否还会再纳入 Emacs 的代码库中;嗯,它们很可能不会——它们将被归入包管理仓库中,而在这个干净而无菌的世界中,它们无疑属于包管理仓库。
|
||||
|
||||
Emacs 要求将对 Emacs 体验不重要的内容转移到包管理仓库 ELPA 中。我的意思是,作为一个开发者,这是有道理的,但是……对于每一个被移出并流放到 ELPA 的包,我们是不是在蚕食 Emacs 的精髓?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
via: https://www.masteringemacs.org/article/fun-games-in-emacs
|
||||
|
||||
作者:[Mickey Petersen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.masteringemacs.org/about
|
||||
[b]:https://github.com/lujun9972
|
||||
[1]:https://en.wikipedia.org/wiki/Office_Space
|
||||
[2]:https://en.wikipedia.org/wiki/Tower_of_Hanoi
|
||||
[3]:https://www.masteringemacs.org/article/fun-emacs-calc
|
||||
[4]:http://www.xkcd.com
|
||||
[5]:https://en.wikipedia.org/wiki/Battleship_(game)
|
||||
[6]:https://www.masteringemacs.org/article/evaluating-elisp-emacs
|
||||
[7]:https://en.wikipedia.org/wiki/ELIZA
|
||||
[8]:https://en.wikipedia.org/wiki/Conway's_Game_of_Life
|
@ -0,0 +1,71 @@
|
||||
探索自由而开放的 Web 字体
|
||||
======
|
||||
|
||||
> 谷歌字体和开放字体库中的免费 Web 字体已经改变了游戏规则,但仅在有限的范围内。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/08/174910xoklikblgkkbooib.jpg)
|
||||
|
||||
毫无疑问,近些年来互联网的面貌已经被开源字体所改变。早在 2010 年之前,你在 Web 浏览器上几乎只能看到微软制作的通常“Web 安全”的[核心字体][1]。但这一年(2010)正好是好几轮技术革新开始的见证之年:<ruby>[Web 开放字体格式][2]<rt>Web Open Font Format</rt></ruby>(WOFF)的引入为通过 HTTP 有效地传输字体文件提供了一个开放的标准,以及像[谷歌字体][3]和<ruby>[开放字体库][4]<rt>Open Font Library</rt></ruby>这样的 Web 字体服务的推出,使得 Web 内容发布者可以在开源许可证之下免费使用海量的字体库。
|
||||
|
||||
这些事件对 Web 排版的积极影响再夸大都不过分。但是要将 Web 开放字体的成功与整个开源排版等同起来,并得到结论——挑战已经远离了我们,困难悉数被解决了——却很容易。然而事实并非如此,如果你很关注字体,那么好消息是你有好多机会参与到对这些字体的改进工作当中去。
|
||||
|
||||
对新手来说,至关重要的是必须要意识到谷歌字体和开放字体库提供了专用的服务(为网页提供字体),而没有为其他使用情况制定字体解决方案。这不是服务方面的缺点,这只是意味着我们必须去开发其它的解决方案。
|
||||
|
||||
需要解决的问题还非常多。可能最明显的例子就是给 Linux 桌面计算机的其他软件安装字体所遇到的尴尬情况。你可以通过任何一种服务下载任何一种 Web 字体,但是你得到的只是一个最普通的压缩包文件,里面有一些 TTF 或 OTF 二进制文件和一个普通文本文件的许可证。接下来会发生什么完完全全需要你去猜。
|
||||
|
||||
大部分用户很快学会了“正确”的步骤就是手动地复制这些字体二进制文件到他们硬盘里几个特殊文件夹里的某一个里。但是这样做只能使这个文件对操作系统可见。它并不能为用户体验带来什么提升。再强调一遍,这不是 Web 字体服务的缺陷,相反它佐证了对于关于服务到哪里停止和需要在其他方面做更多工作的观点。
|
||||
|
||||
在用户视角来说,一个巨大的提升可能就是在“只是下载”这个阶段,操作系统或者桌面环境变得更智能。系统或桌面环境不仅会把字体文件安装到正确的位置上,更重要的是,当用户选择要在一个项目中使用的字体时,它会自己添加用户所需要的重要的元数据。
|
||||
|
||||
这些附加信息包含的内容与它如何呈现给用户与另一个挑战有关:与其它操作系统相比,在 Linux 环境管理一个字体库显然不那么令人满意。字体管理器总是时不时的出现一下(例如 [GTK+ 字体管理器][5],这是最近的一个例子),但是它们很少变得流行起来。我一直在思考一大堆这些软件让人失望的方面。一个核心的原因是它们把自己局限于只展示内嵌在二进制字体文件内的信息:基本字符集的覆盖、粗细/宽度和斜率的设定,内置的许可证和版权说明等等。
|
||||
|
||||
但是除了这些内嵌数据中的内容,在选择字体的过程中还涉及很多决策。严肃的字体用户,像信息设计者、杂志文章作者,或者书籍美工设计者,他们的字体选择是根据每一份文件的要求和需求做出的。这当然包含了许可证信息,但它还包含了更多,像关于设计师和厂商的信息、潮流风格的趋势,或者字体在使用中的细节。
|
||||
|
||||
举个例子,如果你的文档包含了英语和阿拉伯文,你多半想要拉丁文和阿拉伯文的字体由同时熟悉这两种<ruby>字母系统<rt>script</rt></ruby>的设计师所设计。否则,你将浪费一大堆时间来微调字体大小和行间距来使两种字母系统良好地结合在一起。你可能从经验中学到,某些设计师或字体厂商比其他人更善于多种字母系统设计。或许和你职业相关的是今天的时尚杂志几乎无一例外的采用 “[Didone][6]”风格的字体,“[Didone][6]”是指一种两百多年前最先被 [Firmin Didot][7] 和 [Giambattista Bodoni][8] 设计出来的超高反差的字体风格。这种字体恰好就是现在的潮流。
|
||||
|
||||
但是像 Didone、Didot 或 Bodoni 这些术语都不可能会出现在二进制文件的内置数据当中,你也不容易判断拉丁文和阿拉伯文是否相得益彰或其它关于字体的历史背景。这些信息有可能出现在补充的材料中,类似某种字形样本或字体文件中,如果这些东西存在的话。
|
||||
|
||||
<ruby>字形样本<rt>specimen</rt></ruby>是一份设计好的文档(一般是 PDF),它展示了这种字体的使用情况,而且包括了背景信息。字形样本经常在挑选字体时充当市场营销和外观样例的双重角色。一份精心设计的样本展示了字体在实际应用中的情况和在自动生成的字符表中所不能体现的风格。字形样本文件也有可能包含了一些其他重要信息,比如怎样激活字体的 OpenType 特性、提供的数学表达式或古体字,或者它在支持的多种语言上的风格变化。在字体管理应用程序中向用户提供此类材料,对于帮助用户找到适合其项目需求的字体将大有帮助。
|
||||
|
||||
当然,如果我们希望一个字体管理软件能够处理文件和样本问题,我们也必须仔细观察一下各种发行版提供的字体包所随附的内容。Linux 的用户刚开始只有自动安装的那几种字体,并且发行版存储库提供的包是大部分用户除了下载通用的压缩包档案之外的唯一字体来源。这些包往往非常的“简陋”。商业字体总的来说都包含了样本、文档,还有其他的支持项目,然而开源字体往往没有这些配套文件。
|
||||
|
||||
也有一些优秀的开放字体提供了高质量的样本和文档(例如 [SIL Gentium][9] 和 [Bungee][10] 是两种差异明显但是都有效的方案),但是它们几乎不涉足下游的打包工作链。我们显然可以做的更好一些。
|
||||
|
||||
要在系统的字体交互方面提供更丰富的用户体验上面还存在一些技术问题。一方面,[AppStream][11] 的元数据标准定义了一些字体文件特有的参数,但是到现在为止,这些参数没有包含样本、设计师/厂商和其他相关细节的任何信息。另外一个例子,[SPDX][13](<ruby>软件包数据交换<rt>Software Package Data Exchange</rt></ruby>)格式也没有包含太多用于分发字体的软件许可证(及许可证变体)。
|
||||
|
||||
最后,就像任何一个唱片爱好者都会告诉你的,一个不允许你编辑和完善你的 MP3 曲库中的 ID3 信息的音乐播放器很快就会变得令人失望(LCTT 译注:ID3 信息是 MP3 文件头部的元信息,用于存储歌曲信息)。你想要处理标签里的错误、想要添加注释和专辑封面之类的信息,本质上,这就是完善你的音乐库。同样,你可能也想要让你的本地字体库也保持在一个方便使用的状态。
|
||||
|
||||
但是改动字体文件的内置数据一直有所忌讳,因为字体往往是被内置或附加到其他文件里的。如果你随意改变了字体二进制文件中的字段,然后将其与你的演示文稿一起重新分发,那么下载这些演示文稿的任何人最终都会得到错误的元数据,但这个错误不是他们自己造成的。所以任何一个要改善字体管理体验的人都要想明白如何从策略上解决对内置或外置的字体元数据的重复修改。
|
||||
|
||||
除了技术角度之外,丰富的字体管理经验也是一项设计挑战。就像我在前面说的一样,有几种开放字体也带了良好的样本和精心编写的文档。但是更多的字体包这两者都没有,还有大量的更老的字体包已经没有人维护了。这很可能意味着大部分开放字体包想要获得样本和证明文件的唯一办法就是让社区去创建它们。
|
||||
|
||||
也许这是一个很高的要求。但是开源设计社区现在比以往任何时候都要庞大,它是整个自由开源软件运动中的一个高度活跃的组成部分。所以谁知道呢,也许明年这个时候会发现,在 Linux 桌面系统查找、下载和使用字体会变成一种完全不同的体验。
|
||||
|
||||
在这一连串关于现代 Linux 用户的文字设计上的挑战的思考中包含了打包、文档设计,甚至有可能需要在桌面环境加入不少新的软件部分。此外还有其他一系列的东西也需要考虑。其共通性就是在 Web 字体服务不可及的地方,事情就会变得更加困难。
|
||||
|
||||
从我的视角来看,最好的消息是现在比起以前有更多的人对这个话题感兴趣。我认为我们要感谢像谷歌字体和开放字体库这样的 Web 字体服务巨头让开放字体得到了更高的关注。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/3/webfonts
|
||||
|
||||
作者:[Nathan Willis][a]
|
||||
译者:[Fisherman110](https://github.com/Fisherman110)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/n8willis
|
||||
[1]:https://en.wikipedia.org/wiki/Core_fonts_for_the_Web
|
||||
[2]:https://en.wikipedia.org/wiki/Web_Open_Font_Format
|
||||
[3]:https://fonts.google.com/
|
||||
[4]:https://fontlibrary.org/
|
||||
[5]:https://fontmanager.github.io/
|
||||
[6]:https://en.wikipedia.org/wiki/Didone_(typography)
|
||||
[7]:https://en.wikipedia.org/wiki/Firmin_Didot
|
||||
[8]:https://en.wikipedia.org/wiki/Giambattista_Bodoni
|
||||
[9]:https://software.sil.org/gentium/
|
||||
[10]:https://djr.com/bungee/
|
||||
[11]:https://www.freedesktop.org/wiki/Distributions/AppStream/
|
||||
[12]:https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Fonts.html
|
||||
[13]:https://spdx.org/
|
@ -0,0 +1,109 @@
|
||||
你所不知道的用 less 查看文件的高级用法
|
||||
======
|
||||
|
||||
> 使用 less 文件查看器的一些技巧。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/16/152826assmtybsohopo4b7.png)
|
||||
|
||||
最近,我正在拜读 Scott Nesbitt 的文章《[在 Linux 命令行中使用 less 来查看文本文件][1]》,并受到了一些启发,所以我想分享一些使用 `less` 命令的技巧。
|
||||
|
||||
### LESS 环境变量
|
||||
|
||||
如果你定义了环境变量 `LESS`(例如在 `.bashrc` 中),那么 `less` 会将其视为一个选项列表,就像在命令行中传递给它一样。
|
||||
|
||||
我这样定义:
|
||||
|
||||
```
|
||||
LESS='-C -M -I -j 10 -# 4'
|
||||
```
|
||||
|
||||
它的意思是:
|
||||
|
||||
* `-C` – 通过不从底部滚动来加快全屏打印速度。
|
||||
* `-M` – 在最后一行(状态行)显示更多信息。你可以使用 `-PM` 来自定义显示的信息,但我通常只用 `-M`。
|
||||
* `-I` – 忽略搜索中的大小写。
|
||||
* `-j 10` – 在终端的第 10 行而不是第一行显示搜索结果。这样,每次按 `n` 或(`N`) 跳到下一个(或上一个)匹配项时,就会有 10 条上下文。
|
||||
* `-# 4` – 当按下向右或向左的箭头时,会向右或向左跳四个字符。默认情况时跳转半个屏幕,我觉得太多了。一般来说,`less` 似乎(至少部分)是按最初开发它时的环境优化的,那时使用慢速调制解调器和低带宽的互联网连接,所以跳过半个屏幕是有意义的。
|
||||
|
||||
### PAGER 环境变量
|
||||
|
||||
许多程序使用在 `PAGER` 环境变量中的命令来显示信息。因此,你可以在 `.bashrc` 中设置 `PAGER=less`,然后让程序运行 `less`。查看手册页(`man 7 environ`)中是否有其它此类变量。
|
||||
|
||||
### -S
|
||||
|
||||
`-S` 告诉 `less` 将长行切断而不是将它们换行。除非我在(或我要)查看文件,否则我很少需要这样做。幸运的是,你可以在 `less` 中输入所有命令行选项,就像它们是键盘命令一样。因此,如果我想在文件已经打开的情况下隔断长行,我可以简单地输入 `-S`。(LCTT 译注:注意大写 `S` ,并按回车)
|
||||
|
||||
这是我经常使用的一个例子:
|
||||
|
||||
```
|
||||
su - postgres
|
||||
export PAGER=less # 因为我不用在所有的机器上编辑 postgres 的 .bashrc
|
||||
psql
|
||||
```
|
||||
|
||||
有时当我查看一个 `SELECT` 命令的输出非常宽时,我会输入 `-S` 以便将其格式化的漂亮一些。如果当我按下右箭头想查看更多内容时它跳得太远(因为我没有设置 `-#`),则可以输入 `-#8`,那么每次按下右箭头都会向右移动八个字符。
|
||||
|
||||
有时在多次输入 `-S` 之后,我会退出 psql 并设置环境变量后再次运行它:
|
||||
|
||||
```
|
||||
export LESS=-S
|
||||
```
|
||||
|
||||
### F
|
||||
|
||||
命令 `F` 可以使 `less` 像 `tail -f` 一样工作,等待更多的数据被添加到文件后再显示它们。与 `tail -f` 相比,它的一个优点是,高亮显示搜索匹配仍然有效。因此,你可以输入 `less /var/log/logfile`,搜索某些内容时,它将高亮显示所有出现的内容(除非你使用了 `-g`),然后按下 `F` 键,当更多数据写入到日志时,`less` 将显示它并高亮新的匹配项。
|
||||
|
||||
按下 `F` 后,可以按 `Ctrl+C` 来停止其查找新数据(这不会干掉它),这样你可以返回文件查看旧内容,搜索其它内容等,然后再次按 `F` 键来查看更多新数据。
|
||||
|
||||
### 搜索
|
||||
|
||||
搜索使用系统的正则表达式库,这通常意味着你可以使用扩展正则表达式。特别是,搜索 `one|two|three` 可以找到并高亮所有的 one、two 或 three。
|
||||
|
||||
我经常使用的另一种模式是 `.*someting.*`,特别是对于一些很长的日志行(例如,跨越多个终端宽度的行),它会高亮整行。这种模式使查看一行的起始和结束位置变得更加容易。我还会结合其它内容,例如 `.*one thing.*|.*another thing.*`,或者使用 `key: .*|.*marker.*` 来查看 `key` 的内容。例如,一个日志文件中包含一些字典/哈希的转储。它会高亮相关的标记行,这样我就看到上下文了,甚至,如果我知道这个值被引号引起来的话,就可以:
|
||||
|
||||
```
|
||||
key: '[^']*'|.*marker.*
|
||||
```
|
||||
|
||||
`less` 会保留你的搜索项的历史纪录,并将其保存到磁盘中以备将来调用。当你按下 `/` 或 `?` 时,可以使用向上或向下箭头浏览历史记录(以及进行基本的行编辑)。
|
||||
|
||||
在撰写本文时,我无意间看了下 `less` 手册页,发现了一个非常有用的功能:使用 `&!pattern` 跳过无关的行。例如,当我在 `/var/log/messages` 中寻找内容时,经常会一个个迭代使用以下命令:
|
||||
|
||||
```
|
||||
cat /var/log/messages | egrep -v 'systemd: Started Session' | less
|
||||
cat /var/log/messages | egrep -v 'systemd: Started Session|systemd: Starting Session' | less
|
||||
cat /var/log/messages | egrep -v 'systemd: Started Session|systemd: Starting Session|User Slice' | less
|
||||
cat /var/log/messages | egrep -v 'systemd: Started Session|systemd: Starting Session|User Slice|dbus' | less
|
||||
cat /var/log/messages | egrep -v 'systemd: Started Session|systemd: Starting Session|User Slice|dbus|PackageKit Daemon' | less
|
||||
```
|
||||
|
||||
但是现在我知道如何在 `less` 中做同样的事情。例如,我可以输入 `&!systemd: Started Session`,然后想要隐藏 `systemd: Starting Session`,所以我输入 `&!`,并使用向上箭头从历史记录中获得上一次搜索的结果。然后我接着输入 `|systemd: Starting Session` 并按下回车,继续以相同的方式添加更多条目,直到我过滤掉足够多的条目,看到更有趣的内容。
|
||||
|
||||
### =
|
||||
|
||||
命令 `=` 显示有关文件和位置的更多信息,甚至比 `-M` 更多。如果文件非常大,计算 `=` 花费的时间太长,可以按下 `Ctrl+C`,它将停止尝试计算。
|
||||
|
||||
如果你正在查看的内容来自管道而不是文件,则 `=`(和 `-M`)不会显示未知内容,包括文件中的行数和字节数。要查看这些数据,如果你知道管道命令将很快结束,则可以使用 `G` 跳到最后,然后 `less` 将开始显示这些信息。
|
||||
|
||||
如果按下 `G` 并且写入管道的命令花费的时间比预期的长,你可以按下 `Ctrl+C`,该命令将被终止。即使你没有按 `G`,`Ctrl+C` 键也会杀死它。因此,如果你不想终止命令,请不要意外按下 `Ctrl+C`。出于这个原因,如果命令执行了某些操作(不仅是显示信息),通常更安全的做法是将其输出写入文件并在单独的终端中查看文件,而不是使用管道。
|
||||
|
||||
### 为什么你需要 less
|
||||
|
||||
`less` 是一个非常强大的程序,与该领域中较新的竞争者(例如 `most` 和 `moar`)不同,你可能会在几乎所有的系统上找到它,就像 `vi` 一样。因此,即使你使用 GUI 查看器或编辑器,花一些时间浏览 `less` 手册页也是值得的,至少可以了解一下它的用处。这样,当你需要做一些已有的功能可能提供的工作时,就会知道如何要搜索手册页或互联网来找到所需的内容。
|
||||
|
||||
有关更多信息,访问 [less 主页][2]。该网站有一个不错的常见问题解答,其中包含更多提示和技巧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/5/advanced-use-less-text-file-viewer
|
||||
|
||||
作者:[Yedidyah Bar David][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/didib
|
||||
[1]:http://opensource.com/article/18/4/using-less-view-text-files-command-line
|
||||
[2]:http://www.greenwoodsoftware.com/less/
|
@ -1,41 +1,41 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (PsiACE)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12056-1.html)
|
||||
[#]: subject: (Building a Messenger App: Conversations)
|
||||
[#]: via: (https://nicolasparada.netlify.com/posts/go-messenger-conversations/)
|
||||
[#]: author: (Nicolás Parada https://nicolasparada.netlify.com/)
|
||||
|
||||
Building a Messenger App: Conversations
|
||||
构建一个即时消息应用(三):对话
|
||||
======
|
||||
|
||||
This post is the 3rd in a series:
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/30/193824w7xsj2ixs8frsal8.jpg)
|
||||
|
||||
* [Part 1: Schema][1]
|
||||
* [Part 2: OAuth][2]
|
||||
本文是该系列的第三篇。
|
||||
|
||||
* [第一篇:模式][1]
|
||||
* [第二篇:OAuth][2]
|
||||
|
||||
在我们的即时消息应用中,消息表现为两个参与者对话的堆叠。如果你想要开始一场对话,就应该向应用提供你想要交谈的用户,而当对话创建后(如果该对话此前并不存在),就可以向该对话发送消息。
|
||||
|
||||
In our messenger app, messages are stacked by conversations between two participants. You start a conversation providing the user you want to chat with, the conversations is created (if not exists already) and you can start sending messages to that conversations.
|
||||
就前端而言,我们可能想要显示一份近期对话列表。并在此处显示对话的最后一条消息以及另一个参与者的姓名和头像。
|
||||
|
||||
On the front-end we’re interested in showing a list of the lastest conversations. There we’ll show the last message of it and the name and avatar of the other participant.
|
||||
在这篇帖子中,我们将会编写一些<ruby>端点<rt>endpoint</rt></ruby>来完成像“创建对话”、“获取对话列表”以及“找到单个对话”这样的任务。
|
||||
|
||||
In this post, we’ll code the endpoints to start a conversation, list the latest and find a single one.
|
||||
首先,要在主函数 `main()` 中添加下面的路由。
|
||||
|
||||
Inside the `main()` function add this routes.
|
||||
|
||||
```
|
||||
```go
|
||||
router.HandleFunc("POST", "/api/conversations", requireJSON(guard(createConversation)))
|
||||
router.HandleFunc("GET", "/api/conversations", guard(getConversations))
|
||||
router.HandleFunc("GET", "/api/conversations/:conversationID", guard(getConversation))
|
||||
```
|
||||
|
||||
These three endpoints require authentication so we use the `guard()` middleware. There is a new middleware that checks for the request content type JSON.
|
||||
这三个端点都需要进行身份验证,所以我们将会使用 `guard()` 中间件。我们也会构建一个新的中间件,用于检查请求内容是否为 JSON 格式。
|
||||
|
||||
### Require JSON Middleware
|
||||
### JSON 请求检查中间件
|
||||
|
||||
```
|
||||
```go
|
||||
func requireJSON(handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if ct := r.Header.Get("Content-Type"); !strings.HasPrefix(ct, "application/json") {
|
||||
@ -47,11 +47,11 @@ func requireJSON(handler http.HandlerFunc) http.HandlerFunc {
|
||||
}
|
||||
```
|
||||
|
||||
If the request isn’t JSON, it responds with a `415 Unsupported Media Type` error.
|
||||
如果<ruby>请求<rt>request</rt></ruby>不是 JSON 格式,那么它会返回 `415 Unsupported Media Type`(不支持的媒体类型)错误。
|
||||
|
||||
### Create Conversation
|
||||
### 创建对话
|
||||
|
||||
```
|
||||
```go
|
||||
type Conversation struct {
|
||||
ID string `json:"id"`
|
||||
OtherParticipant *User `json:"otherParticipant"`
|
||||
@ -60,9 +60,9 @@ type Conversation struct {
|
||||
}
|
||||
```
|
||||
|
||||
So, a conversation holds a reference to the other participant and the last message. Also has a bool field to tell if it has unread messages.
|
||||
就像上面的代码那样,对话中保持对另一个参与者和最后一条消息的引用,还有一个 `bool` 类型的字段,用来告知是否有未读消息。
|
||||
|
||||
```
|
||||
```go
|
||||
type Message struct {
|
||||
ID string `json:"id"`
|
||||
Content string `json:"content"`
|
||||
@ -74,11 +74,11 @@ type Message struct {
|
||||
}
|
||||
```
|
||||
|
||||
Messages are for the next post, but I define the struct now since we are using it. Most of the fields are the same as the database table. We have `Mine` to tell if the message is owned by the current authenticated user and `ReceiverID` will be used to filter messanges once we add realtime capabilities.
|
||||
我们会在下一篇文章介绍与消息相关的内容,但由于我们这里也需要用到它,所以先定义了 `Message` 结构体。其中大多数字段与数据库表一致。我们需要使用 `Mine` 来断定消息是否属于当前已验证用户所有。一旦加入实时功能,`ReceiverID` 可以帮助我们过滤消息。
|
||||
|
||||
Lets write the HTTP handler then. It’s quite long but don’t be scared.
|
||||
接下来让我们编写 HTTP 处理程序。尽管它有些长,但也没什么好怕的。
|
||||
|
||||
```
|
||||
```go
|
||||
func createConversation(w http.ResponseWriter, r *http.Request) {
|
||||
var input struct {
|
||||
Username string `json:"username"`
|
||||
@ -170,19 +170,19 @@ func createConversation(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
```
|
||||
|
||||
For this endpoint you do a POST request to `/api/conversations` with a JSON body containing the username of the user you want to chat with.
|
||||
在此端点,你会向 `/api/conversations` 发送 POST 请求,请求的 JSON 主体中包含要对话的用户的用户名。
|
||||
|
||||
So first it decodes the request body into an struct with the username. Then it validates that the username is not empty.
|
||||
因此,首先需要将请求主体解析成包含用户名的结构。然后,校验用户名不能为空。
|
||||
|
||||
```
|
||||
```go
|
||||
type Errors struct {
|
||||
Errors map[string]string `json:"errors"`
|
||||
}
|
||||
```
|
||||
|
||||
This is the `Errors` struct. It’s just a map. If you enter an empty username you get this JSON with a `422 Unprocessable Entity` error.
|
||||
这是错误消息的结构体 `Errors`,它仅仅是一个映射。如果输入空用户名,你就会得到一段带有 `422 Unprocessable Entity`(无法处理的实体)错误消息的 JSON 。
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"errors": {
|
||||
"username": "Username required"
|
||||
@ -190,17 +190,17 @@ This is the `Errors` struct. It’s just a map. If you enter an empty username y
|
||||
}
|
||||
```
|
||||
|
||||
Then, we begin an SQL transaction. We only received an username, but we need the actual user ID. So the first part of the transaction is to query for the id and avatar of that user (the other participant). If the user is not found, we respond with a `404 Not Found` error. Also, if the user happens to be the same as the current authenticated user, we respond with `403 Forbidden`. There should be two different users, not the same.
|
||||
然后,我们开始执行 SQL 事务。收到的仅仅是用户名,但事实上,我们需要知道实际的用户 ID 。因此,事务的第一项内容是查询另一个参与者的 ID 和头像。如果找不到该用户,我们将会返回 `404 Not Found`(未找到) 错误。另外,如果找到的用户恰好和“当前已验证用户”相同,我们应该返回 `403 Forbidden`(拒绝处理)错误。这是由于对话只应当在两个不同的用户之间发起,而不能是同一个。
|
||||
|
||||
Then, we try to find a conversation those two users have in common. We use `INTERSECT` for that. If there is one, we redirect to that conversation `/api/conversations/{conversationID}` and return there.
|
||||
然后,我们试图找到这两个用户所共有的对话,所以需要使用 `INTERSECT` 语句。如果存在,只需要通过 `/api/conversations/{conversationID}` 重定向到该对话并将其返回。
|
||||
|
||||
If no common conversation was found, we continue by creating a new one and adding the two participants. Finally, we `COMMIT` the transaction and respond with the newly created conversation.
|
||||
如果未找到共有的对话,我们需要创建一个新的对话并添加指定的两个参与者。最后,我们 `COMMIT` 该事务并使用新创建的对话进行响应。
|
||||
|
||||
### Get Conversations
|
||||
### 获取对话列表
|
||||
|
||||
This endpoint `/api/conversations` is to get all the conversations of the current authenticated user.
|
||||
端点 `/api/conversations` 将获取当前已验证用户的所有对话。
|
||||
|
||||
```
|
||||
```go
|
||||
func getConversations(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
@ -267,17 +267,17 @@ func getConversations(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
```
|
||||
|
||||
This handler just does a query to the database. It queries to the conversations table with some joins… First, to the messages table to get the last message. Then to the participants, but it adds a condition to a participant whose ID is not the one of the current authenticated user; this is the other participant. Then it joins to the users table to get his username and avatar. And finally joins with the participants again but with the contrary condition, so this participant is the current authenticated user. We compare `messages_read_at` with the message `created_at` to know whether the conversation has unread messages. And we use the message `user_id` to check if it’s “mine” or not.
|
||||
该处理程序仅对数据库进行查询。它通过一些联接来查询对话表……首先,从消息表中获取最后一条消息。然后依据“ID 与当前已验证用户不同”的条件,从参与者表找到对话的另一个参与者。然后联接到用户表以获取该用户的用户名和头像。最后,再次联接参与者表,并以相反的条件从该表中找出参与对话的另一个用户,其实就是当前已验证用户。我们会对比消息中的 `messages_read_at` 和 `created_at` 两个字段,以确定对话中是否存在未读消息。然后,我们通过 `user_id` 字段来判定该消息是否属于“我”(指当前已验证用户)。
|
||||
|
||||
Note that this query assumes that a conversation has just two users. It only works for that scenario. Also, if you want to show a count of the unread messages, this design isn’t good. I think you could add a `unread_messages_count` `INT` field on the `participants` table and increment it each time a new message is created and reset it when the user read them.
|
||||
注意,此查询过程假定对话中只有两个用户参与,它也仅仅适用于这种情况。另外,该设计也不很适用于需要显示未读消息数量的情况。如果需要显示未读消息的数量,我认为可以在 `participants` 表上添加一个`unread_messages_count` `INT` 字段,并在每次创建新消息的时候递增它,如果用户已读则重置该字段。
|
||||
|
||||
Then it iterates over the rows, scan each one to make an slice of conversations and respond with those at the end.
|
||||
接下来需要遍历每一条记录,通过扫描每一个存在的对话来建立一个<ruby>对话切片<rt>slice of conversations</rt></ruby>并在最后进行响应。
|
||||
|
||||
### Get Conversation
|
||||
### 找到单个对话
|
||||
|
||||
This endpoint `/api/conversations/{conversationID}` respond with a single conversation by its ID.
|
||||
端点 `/api/conversations/{conversationID}` 会根据 ID 对单个对话进行响应。
|
||||
|
||||
```
|
||||
```go
|
||||
func getConversation(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
authUserID := ctx.Value(keyAuthUserID).(string)
|
||||
@ -321,17 +321,17 @@ func getConversation(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
```
|
||||
|
||||
The query is quite similar. We’re not interested in showing the last message, so we omit those fields, but we need the message to know whether the conversation has unread messages. This time we do a `LEFT JOIN` instead of an `INNER JOIN` because the `last_message_id` is `NULLABLE`; in other case we won’t get any rows. We use an `IFNULL` in the `has_unread_messages` comparison for that reason too. Lastly, we filter by ID.
|
||||
这里的查询与之前有点类似。尽管我们并不关心最后一条消息的显示问题,并因此忽略了与之相关的一些字段,但是我们需要根据这条消息来判断对话中是否存在未读消息。此时,我们使用 `LEFT JOIN` 来代替 `INNER JOIN`,因为 `last_message_id` 字段是 `NULLABLE`(可以为空)的;而其他情况下,我们无法得到任何记录。基于同样的理由,我们在 `has_unread_messages` 的比较中使用了 `IFNULL` 语句。最后,我们按 ID 进行过滤。
|
||||
|
||||
If the query returns no rows, we respond with a `404 Not Found` error, otherwise `200 OK` with the found conversation.
|
||||
如果查询没有返回任何记录,我们的响应会返回 `404 Not Found` 错误,否则响应将会返回 `200 OK` 以及找到的对话。
|
||||
|
||||
* * *
|
||||
|
||||
Yeah, that concludes with the conversation endpoints.
|
||||
本篇帖子以创建了一些对话端点结束。
|
||||
|
||||
Wait for the next post to create and list messages 👋
|
||||
在下一篇帖子中,我们将会看到如何创建并列出消息。
|
||||
|
||||
[Souce Code][3]
|
||||
- [源代码][3]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -340,12 +340,12 @@ via: https://nicolasparada.netlify.com/posts/go-messenger-conversations/
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[PsiACE](https://github.com/PsiACE)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://nicolasparada.netlify.com/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://nicolasparada.netlify.com/posts/go-messenger-schema/
|
||||
[2]: https://nicolasparada.netlify.com/posts/go-messenger-oauth/
|
||||
[1]: https://linux.cn/article-11396-1.html
|
||||
[2]: https://linux.cn/article-11510-1.html
|
||||
[3]: https://github.com/nicolasparada/go-messenger-demo
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11953-1.html)
|
||||
[#]: subject: (Troubleshooting hardware problems in Linux)
|
||||
[#]: via: (https://opensource.com/article/18/12/troubleshooting-hardware-problems-linux)
|
||||
[#]: author: (Daniel Oh https://opensource.com/users/daniel-oh)
|
||||
@ -12,11 +12,11 @@ Linux 硬件故障排除指南
|
||||
|
||||
> 了解是什么原因导致你的 Linux 硬件发生故障,以便你可以将其恢复并快速运行。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_other11x_cc.png?itok=I_kCDYj0)
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/03/101312zcazy02wl2g8uhy1.jpg)
|
||||
|
||||
[Linux 服务器][1]在物理机、虚拟化、私有云、公共云和混合云等许多不同种类的基础设施中运行着关键的业务应用程序。对于 Linux 系统管理员来说,了解如何管理 Linux 硬件基础设施(包括与 [网络][2]、存储、Linux 容器相关的软件定义的功能)和 Linux 服务器上的多种工具非常重要。
|
||||
[Linux 服务器][1]在物理机、虚拟化、私有云、公共云和混合云等许多不同种类的基础设施中运行着关键的业务应用程序。对于 Linux 系统管理员来说,了解如何管理 Linux 硬件基础设施(包括与 [网络][2]、存储、Linux 容器相关的软件定义功能)和 Linux 服务器上的多种工具非常重要。
|
||||
|
||||
在 Linux 上进行故障排除和解决与硬件相关的问题可能需要一些时间。即使是经验丰富的系统管理员,有时也会花费数小时来解决神秘的硬件和软件差异。
|
||||
在 Linux 上进行排除和解决与硬件相关的问题可能需要一些时间。即使是经验丰富的系统管理员,有时也会花费数小时来解决神秘的硬件和软件差异。
|
||||
|
||||
以下提示可以使你更快、更轻松地对 Linux 中的硬件进行故障排除。许多不同的事情都可能导致 Linux 硬件出现问题。在开始诊断它们之前,明智的做法是了解最常见的问题以及最有可能找到问题的地方。
|
||||
|
||||
@ -54,7 +54,7 @@ xvdb 202:16 0 20G 0 disk
|
||||
....
|
||||
```
|
||||
|
||||
### 深入到多个日志当中
|
||||
### 深入到各个日志当中
|
||||
|
||||
使用 `dmesg` 可以找出内核最新消息中的错误和警告。例如,这是 `dmesg | more` 命令的输出:
|
||||
|
||||
@ -93,7 +93,7 @@ Dec 1 13:21:33 bastion dnsmasq[30201]: using nameserver 127.0.0.1#53 for domai
|
||||
|
||||
### 分析网络功能
|
||||
|
||||
你可能有成千上万的云原生应用程序在一个复杂的网络环境中为业务提供服务。其中可能包括虚拟化、多云和混合云。这意味着,作为故障排除的一部分,你应该分析网络连接是否正常工作。弄清 Linux 服务器中网络功能的有用命令包括:`ip addr`、`traceroute`、`nslookup`、`dig` 和 `ping` 等。例如,这是 `ip addr show` 命令的输出:
|
||||
你可能有成千上万的云原生应用程序在一个复杂的网络环境中为业务提供服务,其中可能包括虚拟化、多云和混合云。这意味着,作为故障排除的一部分,你应该分析网络连接是否正常工作。弄清 Linux 服务器中网络功能的有用命令包括:`ip addr`、`traceroute`、`nslookup`、`dig` 和 `ping` 等。例如,这是 `ip addr show` 命令的输出:
|
||||
|
||||
```
|
||||
# ip addr show
|
||||
@ -129,7 +129,7 @@ via: https://opensource.com/article/18/12/troubleshooting-hardware-problems-linu
|
||||
作者:[Daniel Oh][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/) 荣誉推出
|
||||
|
235
published/202003/20190113 Editing Subtitles in Linux.md
Normal file
235
published/202003/20190113 Editing Subtitles in Linux.md
Normal file
@ -0,0 +1,235 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (chenmu-kk)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11946-1.html)
|
||||
[#]: subject: (Editing Subtitles in Linux)
|
||||
[#]: via: (https://itsfoss.com/editing-subtitles)
|
||||
[#]: author: (Shirish https://itsfoss.com/author/shirish/)
|
||||
|
||||
如何在 Linux 中编辑字幕
|
||||
======
|
||||
|
||||
我作为一位世界电影和地区电影爱好者已经几十年了。这期间字幕是一个必不可少的工具,它可以使我享受来自不同国家不同语言的优秀电影。
|
||||
|
||||
如果你喜欢观看带有字幕的电影,你可能会注意到有时字幕并不同步或者说并不正确。
|
||||
|
||||
你知道你可以自己编写字幕并使得它们更完美吗?让我们向你展示一些 Linux 中的基本字幕编辑吧。
|
||||
|
||||
![Editing subtitles in Linux][1]
|
||||
|
||||
### 从闭路字幕数据中提取字幕
|
||||
|
||||
大概在 2012、2013 年我开始了解到有一款叫做 [CCEextractor][2] 的工具。随着时间的推移,它已经成为我必不可少的工具之一,尤其是当我偶然发现一份内含有字幕的媒体文件。
|
||||
|
||||
CCExtractor 负责解析视频文件以及从<ruby>闭路字幕<rt>closed captions</rt></ruby>数据中产生独立的字幕文件。
|
||||
|
||||
CCExtractor 是一个跨平台的、自由开源工具。自它形成的那年起该工具已经成熟了不少而如今已成为 [GSOC][3] 和谷歌编码输入的一部分。
|
||||
|
||||
简单来说,这个工具基本上是一系列脚本,这些脚本以一种顺序方式一个接着一个地给你提供提取到的字幕。
|
||||
|
||||
你可以按照[本页][5]的 CCExtractor 安装指南进行操作。
|
||||
|
||||
若安装后你想从媒体文件中提取字幕,请按以下步骤操作:
|
||||
|
||||
```
|
||||
ccextractor <path_to_video_file>
|
||||
```
|
||||
|
||||
该命令将会输出以下内容:
|
||||
|
||||
```
|
||||
$ ccextractor $something.mkv
|
||||
CCExtractor 0.87, Carlos Fernandez Sanz, Volker Quetschke.
|
||||
Teletext portions taken from Petr Kutalek's telxcc
|
||||
--------------------------------------------------------------------------
|
||||
Input: $something.mkv
|
||||
[Extract: 1] [Stream mode: Autodetect]
|
||||
[Program : Auto ] [Hauppage mode: No] [Use MythTV code: Auto]
|
||||
[Timing mode: Auto] [Debug: No] [Buffer input: No]
|
||||
[Use pic_order_cnt_lsb for H.264: No] [Print CC decoder traces: No]
|
||||
[Target format: .srt] [Encoding: UTF-8] [Delay: 0] [Trim lines: No]
|
||||
[Add font color data: Yes] [Add font typesetting: Yes]
|
||||
[Convert case: No] [Video-edit join: No]
|
||||
[Extraction start time: not set (from start)]
|
||||
[Extraction end time: not set (to end)]
|
||||
[Live stream: No] [Clock frequency: 90000]
|
||||
[Teletext page: Autodetect]
|
||||
[Start credits text: None]
|
||||
[Quantisation-mode: CCExtractor's internal function]
|
||||
-----------------------------------------------------------------
|
||||
Opening file: $something.mkv
|
||||
File seems to be a Matroska/WebM container
|
||||
Analyzing data in Matroska mode
|
||||
|
||||
Document type: matroska
|
||||
Timecode scale: 1000000
|
||||
Muxing app: libebml v1.3.1 + libmatroska v1.4.2
|
||||
Writing app: mkvmerge v8.2.0 ('World of Adventure') 64bit
|
||||
Title: $something
|
||||
|
||||
Track entry:
|
||||
Track number: 1
|
||||
UID: 1
|
||||
Type: video
|
||||
Codec ID: V_MPEG4/ISO/AVC
|
||||
Language: mal
|
||||
Name: $something
|
||||
|
||||
Track entry:
|
||||
Track number: 2
|
||||
UID: 2
|
||||
Type: audio
|
||||
Codec ID: A_MPEG/L3
|
||||
Language: mal
|
||||
Name: $something
|
||||
|
||||
Track entry:
|
||||
Track number: 3
|
||||
UID: somenumber
|
||||
Type: subtitle
|
||||
Codec ID: S_TEXT/UTF8
|
||||
Name: $something
|
||||
99% | 144:34
|
||||
100% | 144:34
|
||||
Output file: $something_eng.srt
|
||||
Done, processing time = 6 seconds
|
||||
Issues? Open a ticket here
|
||||
https://github.com/CCExtractor/ccextractor/issues
|
||||
```
|
||||
它会大致浏览媒体文件。在这个例子中,它发现该媒体文件是马拉雅拉姆语言(mal)并且格式是 [.mkv][6]。之后它将字幕文件提取出来,命名为源文件名并添加“_eng”后缀。
|
||||
|
||||
CCExtractor 是一款用来增强字幕功能和字幕编辑的优秀工具,我将在下一部分对它进行介绍。
|
||||
|
||||
> 趣味阅读:在 [vicaps][7] 有一份有趣的字幕提要,它讲解和分享为何字幕对我们如此重要。对于那些对这类话题感兴趣的人来说,这里面也有许多电影制作的细节。
|
||||
|
||||
### 用 SubtitleEditor 工具编辑字幕
|
||||
|
||||
你大概意识到大多数的字幕都是 [.srt 格式][8] 的。这种格式的优点在于你可以将它加载到文本编辑器中并对它进行少量的修改。
|
||||
|
||||
当进入一个简单的文本编辑器时,一个 srt 文件看起来会是这个样子:
|
||||
|
||||
```
|
||||
1
|
||||
00:00:00,959 --> 00:00:13,744
|
||||
"THE CABINET
|
||||
OF DR. CALIGARI"
|
||||
|
||||
2
|
||||
00:00:40,084 --> 00:01:02,088
|
||||
A TALE of the modern re-appearance of an 11th Century Myth
|
||||
involting the strange and mysterious influence
|
||||
of a mountebank monk over a somnambulist.
|
||||
```
|
||||
|
||||
我分享的节选字幕来自于一部非常老的德国电影《[卡里加里博士的小屋][9]》(1920)。
|
||||
|
||||
Subtitleeditor 是一款非常棒的字幕编辑软件。字幕编辑器可以用来设置字幕持续时间、与多媒体文件同步的字幕帧率以及字幕间隔时间等等。接下来我将在这分享一些基本的字幕编辑。
|
||||
|
||||
![][10]
|
||||
|
||||
首先,以安装 ccextractor 工具同样的方式安装 subtitleeditor 工具,使用你自己喜爱的安装方式。在 Debian 中,你可以使用命令:
|
||||
|
||||
```
|
||||
sudo apt install subtitleeditor
|
||||
```
|
||||
|
||||
当你安装完成后,让我们来看一下在你编辑字幕时一些常见的场景。
|
||||
|
||||
#### 调整帧率使其媒体文件同步
|
||||
|
||||
如果你发现字幕与视频不同步,一个原因可能是视频文件的帧率与字幕文件的帧率并不一致。
|
||||
|
||||
你如何得知这些文件的帧率呢,然后呢?为了获取视频文件的帧率,你可以使用 `mediainfo` 工具。首先你可能需要发行版的包管理器来安装它。
|
||||
|
||||
使用 `mediainfo` 非常简单:
|
||||
|
||||
```
|
||||
$ mediainfo somefile.mkv | grep Frame
|
||||
Format settings : CABAC / 4 Ref Frames
|
||||
Format settings, ReFrames : 4 frames
|
||||
Frame rate mode : Constant
|
||||
Frame rate : 25.000 FPS
|
||||
Bits/(Pixel*Frame) : 0.082
|
||||
Frame rate : 46.875 FPS (1024 SPF)
|
||||
```
|
||||
|
||||
现在你可以看到视频文件的帧率是 25.000 FPS 。我们看到的另一个帧率则是音频文件的帧率。虽然我可以分享为何在视频解码和音频解码等地方会使用特定的 fps,但这将会是一个不同的主题,与它相关的历史信息有很多。
|
||||
|
||||
下一个问题是解决字幕文件的帧率,这个稍微有点复杂。
|
||||
|
||||
通常情况下,大多数字幕都是压缩格式的。将.zip 归档文件和字幕文件(以 XXX.srt 结尾)一起解压缩。除此之外,通常还会有一个同名的 .info 文件,该文件可能包含字幕的帧率。
|
||||
|
||||
如果不是,那么通常最好去某个站点并从具有该帧速率信息的站点下载字幕。对于这个特定的德文文件,我使用 [Opensubtitle.org][11] 来找到它。
|
||||
|
||||
正如你在链接中所看到的,字幕的帧率是 23.976 FPS 。很明显,它不能与帧率为 25.000 FPS 的视频文件一起很好地播放。
|
||||
|
||||
在这种情况下,你可以使用字幕编辑工具来改变字幕文件的帧率。
|
||||
|
||||
按下 `CTRL+A` 选择字幕文件中的全部内容。点击 “Timings -> Change Framerate” ,将 23.976 fps 改为 25.000 fps 或者你想要的其他帧率,保存已更改的文件。
|
||||
|
||||
![synchronize frame rates of subtitles in Linux][12]
|
||||
|
||||
#### 改变字幕文件的起点
|
||||
|
||||
有时以上的方法就足够解决问题了,但有时候以上方法并不足够解决问题。
|
||||
|
||||
在帧率相同时,你可能会发现字幕文件的开头与电影或媒体文件中起点并不相同。
|
||||
|
||||
在这种情况下,请按以下步骤进行操作:
|
||||
|
||||
按下 `CTRL+A` 键选中字幕文件的全部内容。点击 “Timings -> Select Move Subtitle” 。
|
||||
|
||||
![Move subtitles using Subtitle Editor on Linux][13]
|
||||
|
||||
设定字幕文件的新起点,保存已更改的文件。
|
||||
|
||||
![Move subtitles using Subtitle Editor in Linux][14]
|
||||
|
||||
如果你想要时间更精确一点,那么可以使用 [mpv][15] 来查看电影或者媒体文件并点击进度条(可以显示电影或者媒体文件的播放进度),它也会显示微秒。
|
||||
|
||||
通常我喜欢精准无误的操作,因此我会试着尽可能地仔细调节。相较于人类的反应时间来说,MPV 中的反应时间很精确。如果我想要极其精确的时间,那么我可以使用像 [Audacity][16] 之类的东西,但是那是另一种工具,你可以在上面做更多的事情。那也将会是我未来博客中将要探讨的东西。
|
||||
|
||||
#### 调整字幕间隔时间
|
||||
|
||||
有时,两种方法都采用了还不够,甚至你可能需要缩短或增加间隔时间以使其与媒体文件同步。这是较为繁琐的工作之一,因为你必须单独确定每个句子的间隔时间。尤其是在媒体文件中帧率可变的情况下(现已很少见,但你仍然会得到此类文件)
|
||||
|
||||
在这种设想下,你可能因为无法实现自动编辑而不得不手动的修改间隔时间。最好的方式是修改视频文件(会降低视频质量)或者换另一个更高质量的片源,用你喜欢的设置对它进行[转码][17] 。这又是一重大任务,以后我会在我的一些博客文章上阐明。
|
||||
|
||||
### 总结
|
||||
|
||||
以上我分享的内容或多或少是对现有字幕文件的改进。如果从头开始,你需要花费大量的时间。我完全没有分享这一点,因为一部电影或一个小时内的任何视频材料都可以轻易地花费 4-6 个小时,甚至更多的时间,这取决于字幕员的技巧、耐心、上下文、行话、口音、是否是以英语为母语的人、翻译等,所有的这些都会对字幕的质量产生影响。
|
||||
|
||||
我希望自此以后你会觉得这件事很有趣,并将你的字幕处理的更好一点。如果你有其他想要补充的问题,请在下方留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/editing-subtitles
|
||||
|
||||
作者:[Shirish][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[chenmu-kk](https://github.com/chenmu-kk)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/shirish/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/editing-subtitles-in-linux.jpeg?resize=800%2C450&ssl=1
|
||||
[2]: https://www.ccextractor.org/
|
||||
[3]: https://itsfoss.com/best-open-source-internships/
|
||||
[4]: https://www.ccextractor.org/public:codein:google_code-in_2018
|
||||
[5]: https://github.com/CCExtractor/ccextractor/wiki/Installation
|
||||
[6]: https://en.wikipedia.org/wiki/Matroska
|
||||
[7]: https://www.vicaps.com/blog/history-of-silent-movies-and-subtitles/
|
||||
[8]: https://en.wikipedia.org/wiki/SubRip#SubRip_text_file_format
|
||||
[9]: https://www.imdb.com/title/tt0010323/
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/12/subtitleeditor.jpg?ssl=1
|
||||
[11]: https://www.opensubtitles.org/en/search/sublanguageid-eng/idmovie-4105
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/subtitleeditor-frame-rate-sync.jpg?resize=800%2C450&ssl=1
|
||||
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/Move-subtitles-Caligiri.jpg?resize=800%2C450&ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/move-subtitles.jpg?ssl=1
|
||||
[15]: https://itsfoss.com/mpv-video-player/
|
||||
[16]: https://www.audacityteam.org/
|
||||
[17]: https://en.wikipedia.org/wiki/Transcoding
|
||||
[18]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/editing-subtitles-in-linux.jpeg?fit=800%2C450&ssl=1
|
@ -0,0 +1,283 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "FSSlc"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-12051-1.html"
|
||||
[#]: subject: "ffsend – Easily And Securely Share Files From Linux Command Line Using Firefox Send Client"
|
||||
[#]: via: "https://www.2daygeek.com/ffsend-securely-share-files-folders-from-linux-command-line-using-firefox-send-client/"
|
||||
[#]: author: "Vinoth Kumar https://www.2daygeek.com/author/vinoth/"
|
||||
|
||||
ffsend:在命令行中通过 FireFox Send 分享文件
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/29/202308w7ormrouomij2dzq.jpg)
|
||||
|
||||
Linux 用户偏爱使用 `scp` 或 `rsync` 来进行文件或目录的复制拷贝。不过在 Linux 上正出现了许多新的可选方式,因为 Linux 是开源的,所以任何人都可以为 Linux 开发一个安全软件。
|
||||
|
||||
在过去我们已经写了多篇有关安全分享这个话题的文章,它们分别是 [OnionShare][1]、[Magic Wormhole][2]、[Transfer.sh][3] 和 [Dcp – Dat Copy][4]。
|
||||
|
||||
今天我们甚至还将继续讨论这个话题,我们将介绍名为 `ffsend` 的工具。
|
||||
|
||||
### ffsend 是什么?
|
||||
|
||||
[ffsend][5] 是 Firefox Send 服务的一个命令行客户端,允许用户通过命令行来传递和接收文件或目录。
|
||||
|
||||
它允许我们通过一个安全、私密、加密的链接,使用一个简单的命令来轻易安全地分享文件和目录。
|
||||
|
||||
通过 Firefox 的 Send 服务共享的文件最大大小为 2GB(LCTT 译注:现在官网上写的是最大 1GB,登录后最大 2.5GB)。其他人可以通过这个工具或者网页浏览器来下载这些分享的文件。
|
||||
|
||||
所有的文件都是在客户端加密的,并且秘钥将不会被共享到远程主机。另外,你还可以为上传的文件额外设置一个密码。
|
||||
|
||||
上传的文件在下载(默认被下载 1 次,最多可被下载 10 次)后或者 24 小时后,就会自动删除。这将确保你的文件不会一直保留在网络上。
|
||||
|
||||
该工具当前处于 alpha 阶段,使用时请自担风险。而且,当前只有有限的安装方式可用。
|
||||
|
||||
### ffsend 的特点:
|
||||
|
||||
* 全功能且使用友好的命令行工具
|
||||
* 可以安全地上传和下载文件与目录
|
||||
* 总是在客户端加密
|
||||
* 可用额外的密码进行保护、密码生成和可配置下载次数限制
|
||||
* 内置的文件或目录的打包和解压
|
||||
* 可以轻松地管理你的历史分享记录
|
||||
* 能够使用你自己的 Send 主机
|
||||
* 审查或者删除共享文件
|
||||
* 精准的错误报告
|
||||
* 低内存消耗,用于加密或上传下载
|
||||
* 无需交互,可以集成在脚本中
|
||||
|
||||
### 如何在 LInux 中安装 ffsend 呢?
|
||||
|
||||
当前除了 Debian 和 Arch Linux 系统,其他发行版还没有相应的安装包(LCTT 译注:这个信息已过时,最新内容请看[这里](https://github.com/timvisee/ffsend#install))。然而,我们可以轻易地根据我们自己的操作系统和架构下载到相应的预编译二进制文件。
|
||||
|
||||
运行下面的命令来为你的操作系统下载 `ffsend` 最新可用的版本(LCTT 译注:当前最新版本为 v0.2.58):
|
||||
|
||||
```
|
||||
$ wget https://github.com/timvisee/ffsend/releases/download/v0.1.2/ffsend-v0.1.2-linux-x64.tar.gz
|
||||
```
|
||||
|
||||
然后使用下面的命令来解压 tar 包:
|
||||
|
||||
```
|
||||
$ tar -xvf ffsend-v0.1.2-linux-x64.tar.gz
|
||||
```
|
||||
|
||||
接着运行下面的命令来查看你的 `PATH` 环境变量:
|
||||
|
||||
```
|
||||
$ echo $PATH
|
||||
/home/daygeek/.cargo/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
|
||||
```
|
||||
|
||||
正如我先前告知的那样,下面我们要做的就是将这个可执行文件放置到 `PATH` 环境变量中的某个目录中:
|
||||
|
||||
```
|
||||
$ sudo mv ffsend /usr/local/sbin
|
||||
```
|
||||
|
||||
直接运行 `ffsend` 可以获取其基本使用信息:
|
||||
|
||||
```
|
||||
$ ffsend
|
||||
ffsend 0.1.2
|
||||
Usage: ffsend [FLAGS] ...
|
||||
|
||||
Easily and securely share files from the command line.
|
||||
A fully featured Firefox Send client.
|
||||
|
||||
Missing subcommand. Here are the most used:
|
||||
ffsend upload ...
|
||||
ffsend download ...
|
||||
|
||||
To show all subcommands, features and other help:
|
||||
ffsend help [SUBCOMMAND]
|
||||
```
|
||||
|
||||
对于使用基于 Arch Linux 系统的用户可以简单地借助 [AUR 助手][6]来安装它,因为这个包已经在 AUR 软件仓库中了。
|
||||
|
||||
```
|
||||
$ yay -S ffsend
|
||||
```
|
||||
|
||||
对于使用 Debian/Ubuntu 系统的用户,使用 [DPKG 命令][7]来安装 `ffsend`。
|
||||
|
||||
```
|
||||
$ wget https://github.com/timvisee/ffsend/releases/download/v0.1.2/ffsend_0.1.2_amd64.deb
|
||||
$ sudo dpkg -i ffsend_0.1.2_amd64.deb
|
||||
```
|
||||
|
||||
### 如何使用 ffsend
|
||||
|
||||
这并不复杂,我们可以简单地通过下面的语法来发送文件。
|
||||
|
||||
**语法:**
|
||||
|
||||
```
|
||||
$ ffsend upload [/Path/to/the/file/name]
|
||||
```
|
||||
|
||||
在下面的例子中,我们将上传一个名为 `passwd-up1.sh` 的文件,一旦你上传了该文件,你将得到一个唯一的 URL。
|
||||
|
||||
```
|
||||
$ ffsend upload passwd-up1.sh --copy
|
||||
Upload complete
|
||||
Share link: https://send.firefox.com/download/a4062553f4/#yy2_VyPaUMG5HwXZzYRmpQ
|
||||
```
|
||||
|
||||
![][9]
|
||||
|
||||
在任何远端的系统上,只需要使用上面那个唯一的 URL 就可以下载上传的文件了。
|
||||
|
||||
**语法:**
|
||||
|
||||
```
|
||||
$ ffsend download [Generated URL]
|
||||
```
|
||||
|
||||
命令的输出如下:
|
||||
|
||||
```
|
||||
$ ffsend download https://send.firefox.com/download/a4062553f4/#yy2_VyPaUMG5HwXZzYRmpQ
|
||||
Download complete
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
使用下面的语法来对目录进行上传:
|
||||
|
||||
```
|
||||
$ ffsend upload [/Path/to/the/Directory] --copy
|
||||
```
|
||||
|
||||
在下面的例子中,我们将上传一个名为 `2g` 的目录:
|
||||
|
||||
```
|
||||
$ ffsend upload /home/daygeek/2g --copy
|
||||
You've selected a directory, only a single file may be uploaded.
|
||||
Archive the directory into a single file? [Y/n]: y
|
||||
Archiving...
|
||||
Upload complete
|
||||
Share link: https://send.firefox.com/download/90aa5cfe67/#hrwu6oXZRG2DNh8vOc3BGg
|
||||
```
|
||||
|
||||
在任意的远端系统中,只需要利用上面生成的唯一 URL 就可以获取到刚才上传的目录了。
|
||||
|
||||
```
|
||||
$ ffsend download https://send.firefox.com/download/90aa5cfe67/#hrwu6oXZRG2DNh8vOc3BGg
|
||||
You're downloading an archive, extract it into the selected directory? [Y/n]: y
|
||||
Extracting...
|
||||
Download complete
|
||||
```
|
||||
|
||||
上面已经通过安全、私密和加密过的链接来发送了文件。然而,如果你想在你的掌控范围内再添加额外的安全措施,你可以为文件添加密码。
|
||||
|
||||
```
|
||||
$ ffsend upload file-copy-rsync.sh --copy --password
|
||||
Password:
|
||||
Upload complete
|
||||
Share link: https://send.firefox.com/download/0742d24515/#P7gcNiwZJ87vF8cumU71zA
|
||||
```
|
||||
|
||||
当你在远端系统中尝试下载该文件时,它将要求你输入密码:
|
||||
|
||||
```
|
||||
$ ffsend download https://send.firefox.com/download/0742d24515/#P7gcNiwZJ87vF8cumU71zA
|
||||
This file is protected with a password.
|
||||
Password:
|
||||
Download complete
|
||||
```
|
||||
|
||||
另外,你还可以在上传过程中提供下载次数限制来限制文件被下载的次数。
|
||||
|
||||
```
|
||||
$ ffsend upload file-copy-scp.sh --copy --downloads 10
|
||||
Upload complete
|
||||
Share link: https://send.firefox.com/download/23cb923c4e/#LVg6K0CIb7Y9KfJRNZDQGw
|
||||
```
|
||||
|
||||
然后你可以在任意的远程系统中使用上面的唯一 URL 来下载该文件:
|
||||
|
||||
```
|
||||
ffsend download https://send.firefox.com/download/23cb923c4e/#LVg6K0CIb7Y9KfJRNZDQGw
|
||||
Download complete
|
||||
```
|
||||
|
||||
假如你想看这个链接的更多细节,你可以使用下面的命令来查看它的信息,它将为你展示文件名称、文件大小、被下载次数以及过期时间。
|
||||
|
||||
**语法:**
|
||||
|
||||
```
|
||||
$ ffsend info [Generated URL]
|
||||
|
||||
$ ffsend info https://send.firefox.com/download/23cb923c4e/#LVg6K0CIb7Y9KfJRNZDQGw
|
||||
ID: 23cb923c4e
|
||||
Name: file-copy-scp.sh
|
||||
Size: 115 B
|
||||
MIME: application/x-sh
|
||||
Downloads: 3 of 10
|
||||
Expiry: 23h58m (86280s)
|
||||
```
|
||||
|
||||
此外,你还可以使用下面的命令来查看你的传输历史:
|
||||
|
||||
```
|
||||
$ ffsend history
|
||||
# LINK EXPIRY
|
||||
1 https://send.firefox.com/download/23cb923c4e/#LVg6K0CIb7Y9KfJRNZDQGw 23h57m
|
||||
2 https://send.firefox.com/download/0742d24515/#P7gcNiwZJ87vF8cumU71zA 23h55m
|
||||
3 https://send.firefox.com/download/90aa5cfe67/#hrwu6oXZRG2DNh8vOc3BGg 23h52m
|
||||
4 https://send.firefox.com/download/a4062553f4/#yy2_VyPaUMG5HwXZzYRmpQ 23h46m
|
||||
5 https://send.firefox.com/download/74ff30e43e/#NYfDOUp_Ai-RKg5g0fCZXw 23h44m
|
||||
6 https://send.firefox.com/download/69afaab1f9/#5z51_94jtxcUCJNNvf6RcA 23h43m
|
||||
```
|
||||
|
||||
假如你不想再分享某个链接,你可以使用下面的语法来删除它:
|
||||
|
||||
**语法:**
|
||||
|
||||
```
|
||||
$ ffsend delete [Generated URL]
|
||||
|
||||
$ ffsend delete https://send.firefox.com/download/69afaab1f9/#5z51_94jtxcUCJNNvf6RcA
|
||||
File deleted
|
||||
```
|
||||
|
||||
### 如何在浏览器中使用 Send
|
||||
|
||||
另外,你还可以通过使用 firefox 浏览器打开 https://send.firefox.com/ 来完成相应的分享。
|
||||
|
||||
只需要拖拽该文件就可以上传它:
|
||||
|
||||
![][11]
|
||||
|
||||
一旦该文件被下载,它将展示 100% 的下载状态。
|
||||
|
||||
![][12]
|
||||
|
||||
想查看其他的可能选项,请浏览它对应的 man 信息或者帮助页。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/ffsend-securely-share-files-folders-from-linux-command-line-using-firefox-send-client/
|
||||
|
||||
作者:[Vinoth Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/vinoth/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linux.cn/article-9177-1.html
|
||||
[2]: https://www.2daygeek.com/wormhole-securely-share-files-from-linux-command-line/
|
||||
[3]: https://www.2daygeek.com/transfer-sh-easy-fast-way-share-files-over-internet-from-command-line/
|
||||
[4]: https://linux.cn/article-10516-1.html
|
||||
[5]: https://github.com/timvisee/ffsend
|
||||
[6]: https://www.2daygeek.com/category/aur-helper/
|
||||
[7]: https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/
|
||||
[8]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[9]: https://www.2daygeek.com/wp-content/uploads/2019/01/ffsend-easily-and-securely-share-files-from-linux-command-line-using-firefox-send-client-1.png
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/01/ffsend-easily-and-securely-share-files-from-linux-command-line-using-firefox-send-client-2.png
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2019/01/ffsend-easily-and-securely-share-files-from-linux-command-line-using-firefox-send-client-3.png
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/01/ffsend-easily-and-securely-share-files-from-linux-command-line-using-firefox-send-client-4.png
|
98
published/202003/20190422 9 ways to save the planet.md
Normal file
98
published/202003/20190422 9 ways to save the planet.md
Normal file
@ -0,0 +1,98 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MFGJT)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11978-1.html)
|
||||
[#]: subject: (9 ways to save the planet)
|
||||
[#]: via: (https://opensource.com/article/19/4/save-planet)
|
||||
[#]: author: (Jen Wike Huger https://opensource.com/users/jen-wike/users/alanfdoss/users/jmpearce)
|
||||
|
||||
九种用开源拯救地球的方法
|
||||
======
|
||||
|
||||
> 这些主意都用到了有关的开源技巧。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/10/004034vbl5qb5lbij66zil.jpg)
|
||||
|
||||
人们可以做些什么来拯救地球?这个问题可能会让人感到压抑,因为有时我们感觉个人可以做的贡献太少了。但是作为地球公民,我们从来不是一个人。所以,我向我们的作家社区征集了一些开源软件或硬件可以帮助改变现状的方法。以下是他们的回复。
|
||||
|
||||
### 九种利用开源的方法来拯救地球的方式
|
||||
|
||||
#### 1、在你的终端禁用闪烁的光标
|
||||
|
||||
这听起来可能有点傻,但是那个无关紧要的闪烁的光标可能导致[每小时两瓦特的额外电力开销][2]。如果要禁用光标闪烁,可以通过更改终端设置:<ruby>编辑<rt>Edit</rt></ruby> > <ruby>偏好设置<rt>Preferences</rt></ruby> > <ruby>光标<rt>Cursor</rt></ruby> > <ruby>光标闪烁<rt>Cursor blinking</rt></ruby> > <ruby>禁用<rt>Disabled</rt></ruby>。
|
||||
|
||||
*由 Mars Toktonaliev 推荐*
|
||||
|
||||
#### 2、减少有关动物产品和加工食物的消费
|
||||
|
||||
这样做的一种方法是在你的手机中添加这些开源的 App:Daily Dozen、OpenFoodFacts、OpenVegeMap 和 Food Restrictions。这些 App 可以帮助你准备一份健康的素食饮食计划,为你找到素食主义者和严格素食主义者可以就餐的餐厅,还可以帮助你把你的饮食需求告诉别人,即使他们不和你讲同一种语言。如果想要了解更多有关这些的 App 的信息,你可以阅读《[4 款“吃草”的开源应用][3]》。
|
||||
|
||||
*由 Joshua Allen Holm 推荐*
|
||||
|
||||
#### 3、让旧电脑重焕新生
|
||||
|
||||
怎么做?当然是用 Linux。通过给那些自己得不到新电脑的人创造一台新电脑来传递爱心,同时也可以避免让这台电脑进到垃圾填埋场。可以在 [The Asian Penguins][4] 看看我们是怎么做的。
|
||||
|
||||
*由 Stu Keroff 推荐*
|
||||
|
||||
#### 4、在你不使用设备时关闭它们
|
||||
|
||||
你可以使用带有主插座和控制插座的“智能插座板”。把你的电脑连接到主插座上,这样的话当你打开电脑时所有你连接到控制插座上的设备如显示器,打印机等也都会打开。一个更简单的、技术含量更低的方法是使用一个带有计时器的插座板。我在家里就是用的这个。你可以用计时器上的开关设定一个定时开关电源的时间表。这样可以在没有人在家时自动关闭网络打印机。或者以我的用了六年的笔记本电脑为例,我通过一个交替使用外接电源(插座打开)和使用电脑电池(插座关闭)的电源计划延长了电脑电池的寿命。
|
||||
|
||||
*由 Jim Hall 推荐*
|
||||
|
||||
#### 5、减少供暖通风系统(HVAC)的使用
|
||||
|
||||
在夏天,透过窗户的阳光可以为室内提供很多热量。使用 Home Assistant 可以[基于一天中的时间的][6],甚至是基于太阳高度角[自动调节][5]窗帘和遮阳棚。
|
||||
|
||||
*由 Michael Hrivnak 推荐*
|
||||
|
||||
#### 6、出门就把恒温器关闭或调低
|
||||
|
||||
如果你的家用恒温器具有“离开”功能,你很容易忘记在出门时启用它。借助自动化,任何连接到网络的恒温器都可以在你不在家时自动节省能量。[Stataway][7] 就是一个这样项目。它通过调用你的手机的 GPS 坐标来决定是将你的恒温器设置为“在家”还是“离开”。
|
||||
|
||||
*由 Michael Hrivnak 推荐*
|
||||
|
||||
#### 7、为未来储蓄算力
|
||||
|
||||
我有一个主意:创建一个可以读取可选的能量阵列(如风能或太阳能)的输出的脚本。这个脚本应该将计算集群中的服务器从睡眠模式更改为激活模式,直到过量的电能(超出可以储存的部分)被用尽。然后在高产能时段使用这些过量的电能来进行需要大量计算的项目,比如渲染。这个过程本质应该是免费的,因为使用的能量无法被储存起来挪作它用。我相信现有的监控、能量管理和服务器阵列工具一定可以实现这个功能。那么剩下的只是一些整合上的问题,就可以让整个系统工作起来。
|
||||
|
||||
*由 Terry Hancock 推荐*
|
||||
|
||||
#### 8、关掉你的灯
|
||||
|
||||
根据<ruby>[人工夜空亮度图集][8]<rt>World Atlas of Artificial Night Sky Brightness</rt></ruby>的说法,光污染影响了全世界超过 80% 的人口。这一结论在 2016 年(遵循 CC-NC 4.0 协议)发表在公开访问的期刊《<ruby>科学进展<rt>Science Advances</rt></ruby>》上。关闭外部照明是一个可以使野生生物、人类健康受益并让我们享受夜晚的天空的快速途径,而且可以减少能量消耗。访问 [darksky.org][9] 来查看更多减少外部照明影响的方法。
|
||||
|
||||
*由 Michael Hrivnak 推荐*
|
||||
|
||||
#### 9、减少你的 CPU 数量
|
||||
|
||||
就我个人而言,我记得我以前有很多在地下室运行的电脑作为我的 IT 游乐场/实验室。我现在对于能源消耗更加注意了,所以确实大大地减少了我的 CPU 数量。我现在更喜欢利用虚拟机、区域和容器等技术。另外,我很高兴有小型电脑和 SoC 电脑这种东西,比如树莓派,因为我可以用一台这样的电脑做很多事情,比如运行一个 DNS 或者 Web 服务器,而无需使整个屋子变热并积累昂贵的电费账单。
|
||||
|
||||
P.S. 这些电脑都运行于 Linux、FreeBSD,或者 Raspbian 系统!
|
||||
|
||||
*由 Alan Formy-Duvall 推荐*
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/save-planet
|
||||
|
||||
作者:[Jen Wike Huger][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MFGJT](https://github.com/MFGJT)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jen-wike/users/alanfdoss/users/jmpearce
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/pixelated-world.png?itok=fHjM6m53
|
||||
[2]: https://www.redhat.com/archives/fedora-devel-list/2009-January/msg02406.html
|
||||
[3]: https://linux.cn/article-10926-1.html
|
||||
[4]: https://opensource.com/article/19/2/asian-penguins-close-digital-divide
|
||||
[5]: https://www.home-assistant.io/docs/automation/trigger/#sun-trigger
|
||||
[6]: https://www.home-assistant.io/components/cover/
|
||||
[7]: https://github.com/mhrivnak/stataway
|
||||
[8]: http://advances.sciencemag.org/content/2/6/e1600377
|
||||
[9]: http://darksky.org/
|
@ -0,0 +1,288 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "way-ww"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-12027-1.html"
|
||||
[#]: subject: "How To Enable Or Disable SSH Access For A Particular User Or Group In Linux?"
|
||||
[#]: via: "https://www.2daygeek.com/allow-deny-enable-disable-ssh-access-user-group-in-linux/"
|
||||
[#]: author: "2daygeek http://www.2daygeek.com/author/2daygeek/"
|
||||
|
||||
如何在 Linux 上为特定的用户或用户组启用或禁用 SSH?
|
||||
======
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/23/105915r1azn34i82sp48ca.jpg)
|
||||
|
||||
由于你的公司标准规定,你可能只能允许部分人访问 Linux 系统。或者你可能只能够允许几个用户组中的用户访问 Linux 系统。那么如何实现这样的要求呢?最好的方法是什么呢?如何使用一个简单的方法去实现呢?
|
||||
|
||||
是的,我们会有很多种方法去实现它。但是我们应该使用简单轻松的方法。为了简单轻松的完成目的,我们可以通过对 `/etc/ssh/sshd_config` 文件做必要的修改来实现。在这篇文章中我们将会向你展示实现要求的详细步骤。
|
||||
|
||||
为什么我们要这样做呢?是出于安全的原因。你可以访问[这个链接][1]来获取更多关于 openSSH 的使用方法。
|
||||
|
||||
### 什么是 SSH ?
|
||||
|
||||
openssh 全称为 OpenBSD Secure Shell。Secure Shell(ssh)是一个自由开源的网络工具,它能让我们在一个不安全的网络中通过使用 Secure Shell(SSH)协议来安全访问远程主机。
|
||||
|
||||
它采用了客户端-服务器架构(C/S),拥有用户身份认证、加密、在计算机和隧道之间传输文件等功能。
|
||||
|
||||
我们也可以用 `telnet` 或 `rcp` 等传统工具来完成,但是这些工具都不安全,因为它们在执行任何动作时都会使用明文来传输密码。
|
||||
|
||||
### 如何在 Linux 中允许用户使用 SSH?
|
||||
|
||||
通过以下内容,我们可以为指定的用户或用户列表启用 `ssh` 访问。如果你想要允许多个用户,那么你可以在添加用户时在同一行中用空格来隔开他们。
|
||||
|
||||
为了达到目的只需要将下面的值追加到 `/etc/ssh/sshd_config` 文件中去。 在这个例子中, 我们将会允许用户 `user3` 使用 ssh。
|
||||
|
||||
```
|
||||
# echo "AllowUsers user3" >> /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
你可以运行下列命令再次检查是否添加成功。
|
||||
|
||||
```
|
||||
# cat /etc/ssh/sshd_config | grep -i allowusers
|
||||
AllowUsers user3
|
||||
```
|
||||
|
||||
这样就行了, 现在只需要重启 `ssh` 服务和见证奇迹了。(下面这两条命令效果相同, 请根据你的服务管理方式选择一条执行即可)
|
||||
|
||||
```
|
||||
# systemctl restart sshd
|
||||
或
|
||||
# service restart sshd
|
||||
```
|
||||
|
||||
接下来很简单,只需打开一个新的终端或者会话尝试用不同的用户身份访问 Linux 系统。是的,这里 `user2` 用户是不被允许使用 SSH 登录的并且会得到如下所示的错误信息。
|
||||
|
||||
```
|
||||
# ssh user2@192.168.1.4
|
||||
user2@192.168.1.4's password:
|
||||
Permission denied, please try again.
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:00:35 CentOS7 sshd[4900]: User user2 from 192.168.1.6 not allowed because not listed in AllowUsers
|
||||
Mar 29 02:00:35 CentOS7 sshd[4900]: input_userauth_request: invalid user user2 [preauth]
|
||||
Mar 29 02:00:40 CentOS7 unix_chkpwd[4902]: password check failed for user (user2)
|
||||
Mar 29 02:00:40 CentOS7 sshd[4900]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6 user=user2
|
||||
Mar 29 02:00:43 CentOS7 sshd[4900]: Failed password for invalid user user2 from 192.168.1.6 port 42568 ssh2
|
||||
```
|
||||
|
||||
与此同时用户 `user3` 被允许登入系统因为他在被允许的用户列表中。
|
||||
|
||||
```
|
||||
# ssh user3@192.168.1.4
|
||||
user3@192.168.1.4's password:
|
||||
[user3@CentOS7 ~]$
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:01:13 CentOS7 sshd[4939]: Accepted password for user3 from 192.168.1.6 port 42590 ssh2
|
||||
Mar 29 02:01:13 CentOS7 sshd[4939]: pam_unix(sshd:session): session opened for user user3 by (uid=0)
|
||||
```
|
||||
|
||||
### 如何在 Linux 中阻止用户使用 SSH ?
|
||||
|
||||
通过以下内容,我们可以配置指定的用户或用户列表禁用 `ssh`。如果你想要禁用多个用户,那么你可以在添加用户时在同一行中用空格来隔开他们。
|
||||
|
||||
为了达到目的只需要将以下值追加到 `/etc/ssh/sshd_config` 文件中去。 在这个例子中, 我们将禁用用户 `user1` 使用 `ssh`。
|
||||
|
||||
```
|
||||
# echo "DenyUsers user1" >> /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
你可以运行下列命令再次检查是否添加成功。
|
||||
|
||||
```
|
||||
# cat /etc/ssh/sshd_config | grep -i denyusers
|
||||
DenyUsers user1
|
||||
```
|
||||
|
||||
这样就行了, 现在只需要重启 `ssh` 服务和见证奇迹了。
|
||||
|
||||
```
|
||||
# systemctl restart sshd
|
||||
活
|
||||
# service restart sshd
|
||||
```
|
||||
|
||||
接下来很简单,只需打开一个新的终端或者会话,尝试使用被禁用的用户身份被访问 Linux 系统。是的,这里 `user1` 用户在禁用名单中。所以,当你尝试登录时,你将会得到如下所示的错误信息。
|
||||
|
||||
```
|
||||
# ssh user1@192.168.1.4
|
||||
user1@192.168.1.4's password:
|
||||
Permission denied, please try again.
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 01:53:42 CentOS7 sshd[4753]: User user1 from 192.168.1.6 not allowed because listed in DenyUsers
|
||||
Mar 29 01:53:42 CentOS7 sshd[4753]: input_userauth_request: invalid user user1 [preauth]
|
||||
Mar 29 01:53:46 CentOS7 unix_chkpwd[4755]: password check failed for user (user1)
|
||||
Mar 29 01:53:46 CentOS7 sshd[4753]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6 user=user1
|
||||
Mar 29 01:53:48 CentOS7 sshd[4753]: Failed password for invalid user user1 from 192.168.1.6 port 42522 ssh2
|
||||
```
|
||||
|
||||
### 如何在 Linux 中允许用户组使用 SSH?
|
||||
|
||||
通过以下内容,我们可以允许一个指定的组或多个组使用 `ssh`。
|
||||
|
||||
如果你想要允许多个组使用 `ssh` 那么你在添加用户组时需要在同一行中使用空格来隔开他们。
|
||||
|
||||
为了达到目的只需将以下值追加到 `/etc/ssh/sshd_config` 文件中去。在这个例子中,我们将允许 `2g-admin` 组使用 ssh。
|
||||
|
||||
```
|
||||
# echo "AllowGroups 2g-admin" >> /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
你可以运行下列命令再次检查是否添加成功。
|
||||
|
||||
```
|
||||
# cat /etc/ssh/sshd_config | grep -i allowgroups
|
||||
AllowGroups 2g-admin
|
||||
```
|
||||
|
||||
运行下列命令查看属于该用户组的用户有哪些。
|
||||
|
||||
```
|
||||
# getent group 2g-admin
|
||||
2g-admin:x:1005:user1,user2,user3
|
||||
```
|
||||
|
||||
这样就行了, 现在只需要重启 `ssh` 服务和见证奇迹了。
|
||||
|
||||
```
|
||||
# systemctl restart sshd
|
||||
或
|
||||
# service restart sshd
|
||||
```
|
||||
|
||||
是的, `user1` 被允许登入系统因为用户 `user1` 属于 `2g-admin` 组。
|
||||
|
||||
```
|
||||
# ssh user1@192.168.1.4
|
||||
user1@192.168.1.4's password:
|
||||
[user1@CentOS7 ~]$
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:10:21 CentOS7 sshd[5165]: Accepted password for user1 from 192.168.1.6 port 42640 ssh2
|
||||
Mar 29 02:10:22 CentOS7 sshd[5165]: pam_unix(sshd:session): session opened for user user1 by (uid=0)
|
||||
```
|
||||
|
||||
是的, `user2` 被允许登入系统因为用户 `user2` 同样属于 `2g-admin` 组。
|
||||
|
||||
```
|
||||
# ssh user2@192.168.1.4
|
||||
user2@192.168.1.4's password:
|
||||
[user2@CentOS7 ~]$
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:10:38 CentOS7 sshd[5225]: Accepted password for user2 from 192.168.1.6 port 42642 ssh2
|
||||
Mar 29 02:10:38 CentOS7 sshd[5225]: pam_unix(sshd:session): session opened for user user2 by (uid=0)
|
||||
```
|
||||
|
||||
当你尝试使用其他不在被允许的组中的用户去登入系统时, 你将会得到如下所示的错误信息。
|
||||
|
||||
```
|
||||
# ssh ladmin@192.168.1.4
|
||||
ladmin@192.168.1.4's password:
|
||||
Permission denied, please try again.
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:12:36 CentOS7 sshd[5306]: User ladmin from 192.168.1.6 not allowed because none of user's groups are listed in AllowGroups
|
||||
Mar 29 02:12:36 CentOS7 sshd[5306]: input_userauth_request: invalid user ladmin [preauth]
|
||||
Mar 29 02:12:56 CentOS7 unix_chkpwd[5310]: password check failed for user (ladmin)
|
||||
Mar 29 02:12:56 CentOS7 sshd[5306]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6 user=ladmin
|
||||
Mar 29 02:12:58 CentOS7 sshd[5306]: Failed password for invalid user ladmin from 192.168.1.6 port 42674 ssh2
|
||||
```
|
||||
|
||||
### 如何在 Linux 中阻止用户组使用 SSH?
|
||||
|
||||
通过以下内容,我们可以禁用指定的组或多个组使用 `ssh`。
|
||||
|
||||
如果你想要禁用多个用户组使用 `ssh`,那么你需要在添加用户组时在同一行中使用空格来隔开他们。
|
||||
|
||||
为了达到目的只需要将下面的值追加到 `/etc/ssh/sshd_config` 文件中去。
|
||||
|
||||
```
|
||||
# echo "DenyGroups 2g-admin" >> /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
你可以运行下列命令再次检查是否添加成功。
|
||||
|
||||
```
|
||||
# # cat /etc/ssh/sshd_config | grep -i denygroups
|
||||
DenyGroups 2g-admin
|
||||
|
||||
# getent group 2g-admin
|
||||
2g-admin:x:1005:user1,user2,user3
|
||||
```
|
||||
|
||||
这样就行了, 现在只需要重启 `ssh` 服务和见证奇迹了。
|
||||
|
||||
```
|
||||
# systemctl restart sshd
|
||||
或
|
||||
# service restart sshd
|
||||
```
|
||||
|
||||
是的 `user1` 不被允许登入系统,因为他是 `2g-admin` 用户组中的一员。他属于被禁用 `ssh` 的组中。
|
||||
|
||||
```
|
||||
# ssh user1@192.168.1.4
|
||||
user1@192.168.1.4's password:
|
||||
Permission denied, please try again.
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:17:32 CentOS7 sshd[5400]: User user1 from 192.168.1.6 not allowed because a group is listed in DenyGroups
|
||||
Mar 29 02:17:32 CentOS7 sshd[5400]: input_userauth_request: invalid user user1 [preauth]
|
||||
Mar 29 02:17:38 CentOS7 unix_chkpwd[5402]: password check failed for user (user1)
|
||||
Mar 29 02:17:38 CentOS7 sshd[5400]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6 user=user1
|
||||
Mar 29 02:17:41 CentOS7 sshd[5400]: Failed password for invalid user user1 from 192.168.1.6 port 42710 ssh2
|
||||
```
|
||||
|
||||
除了 `2g-admin` 用户组之外的用户都可以使用 ssh 登入系统。 例如,`ladmin` 等用户就允许登入系统。
|
||||
|
||||
```
|
||||
# ssh ladmin@192.168.1.4
|
||||
ladmin@192.168.1.4's password:
|
||||
[ladmin@CentOS7 ~]$
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Mar 29 02:19:13 CentOS7 sshd[5432]: Accepted password for ladmin from 192.168.1.6 port 42716 ssh2
|
||||
Mar 29 02:19:13 CentOS7 sshd[5432]: pam_unix(sshd:session): session opened for user ladmin by (uid=0)
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/allow-deny-enable-disable-ssh-access-user-group-in-linux/
|
||||
|
||||
作者:[2daygeek][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[way-ww](https://github.com/way-ww)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: http://www.2daygeek.com/author/2daygeek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/category/ssh-tutorials/
|
@ -0,0 +1,224 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (mengxinayan)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12000-1.html)
|
||||
[#]: subject: (How to structure a multi-file C program: Part 2)
|
||||
[#]: via: (https://opensource.com/article/19/7/structure-multi-file-c-part-2)
|
||||
[#]: author: (Erik O'Shaughnessy https://opensource.com/users/jnyjny)
|
||||
|
||||
如何组织构建多文件 C 语言程序(二)
|
||||
======
|
||||
|
||||
> 我将在本系列的第二篇中深入研究由多个文件组成的 C 程序的结构。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/16/122928i6qheufnh24jq2qf.jpg)
|
||||
|
||||
在[第一篇][2]中,我设计了一个名为[喵呜喵呜][3]的多文件 C 程序,该程序实现了一个玩具[编解码器][4]。我也提到了程序设计中的 Unix 哲学,即在一开始创建多个空文件,并建立一个好的结构。最后,我创建了一个 `Makefile` 文件夹并阐述了它的作用。在本文中将另一个方向展开:现在我将介绍简单但具有指导性的喵呜喵呜编解码器的实现。
|
||||
|
||||
当读过我的《[如何写一个好的 C 语言 main 函数][5]》后,你会觉得喵呜喵呜编解码器的 `main.c` 文件的结构很熟悉,其主体结构如下:
|
||||
|
||||
```
|
||||
/* main.c - 喵呜喵呜流式编解码器 */
|
||||
|
||||
/* 00 系统包含文件 */
|
||||
/* 01 项目包含文件 */
|
||||
/* 02 外部声明 */
|
||||
/* 03 定义 */
|
||||
/* 04 类型定义 */
|
||||
/* 05 全局变量声明(不要用)*/
|
||||
/* 06 附加的函数原型 */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* 07 变量声明 */
|
||||
/* 08 检查 argv[0] 以查看该程序是被如何调用的 */
|
||||
/* 09 处理来自用户的命令行选项 */
|
||||
/* 10 做点有用的事情 */
|
||||
}
|
||||
|
||||
/* 11 其它辅助函数 */
|
||||
```
|
||||
|
||||
### 包含项目头文件
|
||||
|
||||
位于第二部分中的 `/* 01 项目包含文件 */` 的源代码如下:
|
||||
|
||||
|
||||
```
|
||||
/* main.c - 喵呜喵呜流式编解码器 */
|
||||
...
|
||||
/* 01 项目包含文件 */
|
||||
#include "main.h"
|
||||
#include "mmecode.h"
|
||||
#include "mmdecode.h"
|
||||
```
|
||||
|
||||
`#include` 是 C 语言的预处理命令,它会将该文件名的文件内容拷贝到当前文件中。如果程序员在头文件名称周围使用双引号(`""`),编译器将会在当前目录寻找该文件。如果文件被尖括号包围(`<>`),编译器将在一组预定义的目录中查找该文件。
|
||||
|
||||
[main.h][6] 文件中包含了 [main.c][7] 文件中用到的定义和类型定义。我喜欢尽可能多将声明放在头文件里,以便我在我的程序的其他位置使用这些定义。
|
||||
|
||||
头文件 [mmencode.h][8] 和 [mmdecode.h][9] 几乎相同,因此我以 `mmencode.h` 为例来分析。
|
||||
|
||||
```
|
||||
/* mmencode.h - 喵呜喵呜流编解码器 */
|
||||
|
||||
#ifndef _MMENCODE_H
|
||||
#define _MMENCODE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int mm_encode(FILE *src, FILE *dst);
|
||||
|
||||
#endif /* _MMENCODE_H */
|
||||
```
|
||||
|
||||
`#ifdef`、`#define`、`#endif` 指令统称为 “防护” 指令。其可以防止 C 编译器在一个文件中多次包含同一文件。如果编译器在一个文件中发现多个定义/原型/声明,它将会产生警告。因此这些防护措施是必要的。
|
||||
|
||||
在这些防护内部,只有两个东西:`#include` 指令和函数原型声明。我在这里包含了 `stdio.h` 头文件,以便于能在函数原型中使用 `FILE` 定义。函数原型也可以被包含在其他 C 文件中,以便于在文件的命名空间中创建它。你可以将每个文件视为一个独立的命名空间,其中的变量和函数不能被另一个文件中的函数或者变量使用。
|
||||
|
||||
编写头文件很复杂,并且在大型项目中很难管理它。不要忘记使用防护。
|
||||
|
||||
### 喵呜喵呜编码的最终实现
|
||||
|
||||
该程序的功能是按照字节进行 `MeowMeow` 字符串的编解码,事实上这是该项目中最简单的部分。截止目前我所做的工作便是支持允许在适当的位置调用此函数:解析命令行,确定要使用的操作,并打开将要操作的文件。下面的循环是编码的过程:
|
||||
|
||||
```
|
||||
/* mmencode.c - 喵呜喵呜流式编解码器 */
|
||||
...
|
||||
while (!feof(src)) {
|
||||
|
||||
if (!fgets(buf, sizeof(buf), src))
|
||||
break;
|
||||
|
||||
for(i=0; i<strlen(buf); i++) {
|
||||
lo = (buf[i] & 0x000f);
|
||||
hi = (buf[i] & 0x00f0) >> 4;
|
||||
fputs(tbl[hi], dst);
|
||||
fputs(tbl[lo], dst);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
简单的说,当文件中还有数据块时( `feof(3)` ),该循环读取(`feof(3)` )文件中的一个数据块。然后将读入的内容的每个字节分成两个 `hi` 和 `lo` 的<ruby>半字节<rt>nibble</rt></ruby>。半字节是半个字节,即 4 个位。这里的奥妙之处在于可以用 4 个位来编码 16 个值。我将 `hi` 和 `lo` 用作 16 个字符串查找表 `tbl` 的索引,表中包含了用半字节编码的 `MeowMeow` 字符串。这些字符串使用 `fputs(3)` 函数写入目标 `FILE` 流,然后我们继续处理缓存区的下一个字节。
|
||||
|
||||
该表使用 [table.h][14] 中的宏定义进行初始化,在没有特殊原因(比如:要展示包含了另一个项目的本地头文件)时,我喜欢使用宏来进行初始化。我将在未来的文章中进一步探讨原因。
|
||||
|
||||
### 喵呜喵呜解码的实现
|
||||
|
||||
我承认在开始工作前花了一些时间。解码的循环与编码类似:读取 `MeowMeow` 字符串到缓冲区,将编码从字符串转换为字节
|
||||
|
||||
```
|
||||
/* mmdecode.c - 喵呜喵呜流式编解码器 */
|
||||
...
|
||||
int mm_decode(FILE *src, FILE *dst)
|
||||
{
|
||||
if (!src || !dst) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return stupid_decode(src, dst);
|
||||
}
|
||||
```
|
||||
|
||||
这不符合你的期望吗?
|
||||
|
||||
在这里,我通过外部公开的 `mm_decode()` 函数公开了 `stupid_decode()` 函数细节。我上面所说的“外部”是指在这个文件之外。因为 `stupid_decode()` 函数不在该头文件中,因此无法在其他文件中调用它。
|
||||
|
||||
当我们想发布一个可靠的公共接口时,有时候会这样做,但是我们还没有完全使用函数解决问题。在本例中,我编写了一个 I/O 密集型函数,该函数每次从源中读取 8 个字节,然后解码获得 1 个字节写入目标流中。较好的实现是一次处理多于 8 个字节的缓冲区。更好的实现还可以通过缓冲区输出字节,进而减少目标流中单字节的写入次数。
|
||||
|
||||
```
|
||||
/* mmdecode.c - 喵呜喵呜流式编解码器 */
|
||||
...
|
||||
int stupid_decode(FILE *src, FILE *dst)
|
||||
{
|
||||
char buf[9];
|
||||
decoded_byte_t byte;
|
||||
int i;
|
||||
|
||||
while (!feof(src)) {
|
||||
if (!fgets(buf, sizeof(buf), src))
|
||||
break;
|
||||
byte.field.f0 = isupper(buf[0]);
|
||||
byte.field.f1 = isupper(buf[1]);
|
||||
byte.field.f2 = isupper(buf[2]);
|
||||
byte.field.f3 = isupper(buf[3]);
|
||||
byte.field.f4 = isupper(buf[4]);
|
||||
byte.field.f5 = isupper(buf[5]);
|
||||
byte.field.f6 = isupper(buf[6]);
|
||||
byte.field.f7 = isupper(buf[7]);
|
||||
|
||||
fputc(byte.value, dst);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
我并没有使用编码器中使用的位移方法,而是创建了一个名为 `decoded_byte_t` 的自定义数据结构。
|
||||
|
||||
```
|
||||
/* mmdecode.c - 喵呜喵呜流式编解码器 */
|
||||
...
|
||||
|
||||
typedef struct {
|
||||
unsigned char f7:1;
|
||||
unsigned char f6:1;
|
||||
unsigned char f5:1;
|
||||
unsigned char f4:1;
|
||||
unsigned char f3:1;
|
||||
unsigned char f2:1;
|
||||
unsigned char f1:1;
|
||||
unsigned char f0:1;
|
||||
} fields_t;
|
||||
|
||||
typedef union {
|
||||
fields_t field;
|
||||
unsigned char value;
|
||||
} decoded_byte_t;
|
||||
```
|
||||
|
||||
初次看到代码时可能会感到有点儿复杂,但不要放弃。`decoded_byte_t` 被定义为 `fields_t` 和 `unsigned char` 的 **联合**。可以将联合中的命名成员看作同一内存区域的别名。在这种情况下,`value` 和 `field` 指向相同的 8 位内存区域。将 `field.f0` 设置为 `1` 也将会设置 `value` 中的最低有效位。
|
||||
|
||||
虽然 `unsigned char` 并不神秘,但是对 `fields_t` 的类型定义(`typedef`)也许看起来有些陌生。现代 C 编译器允许程序员在结构体中指定单个位字段的值。字段所在的类型是一个无符号整数类型,并在成员标识符后紧跟一个冒号和一个整数,该整数指定了位字段的长度。
|
||||
|
||||
这种数据结构使得按字段名称访问字节中的每个位变得简单,并可以通过联合中的 `value` 字段访问组合后的值。我们依赖编译器生成正确的移位指令来访问字段,这可以在调试时为你节省不少时间。
|
||||
|
||||
最后,因为 `stupid_decode()` 函数一次仅从源 `FILE` 流中读取 8 个字节,所以它效率并不高。通常我们尝试最小化读写次数,以提高性能和降低调用系统调用的开销。请记住:少量的读取/写入大的块比大量的读取/写入小的块好得多。
|
||||
|
||||
### 总结
|
||||
|
||||
用 C 语言编写一个多文件程序需要程序员要比只是是一个 `main.c` 做更多的规划。但是当你添加功能或者重构时,只需要多花费一点儿努力便可以节省大量时间以及避免让你头痛的问题。
|
||||
|
||||
回顾一下,我更喜欢这样做:多个文件,每个文件仅有简单功能;通过头文件公开那些文件中的小部分功能;把数字常量和字符串常量保存在头文件中;使用 `Makefile` 而不是 Bash 脚本来自动化处理事务;使用 `main()` 函数来处理命令行参数解析并作为程序主要功能的框架。
|
||||
|
||||
我知道我只是蜻蜓点水般介绍了这个简单的程序,并且我很高兴知道哪些事情对你有所帮助,以及哪些主题需要详细的解释。请在评论中分享你的想法,让我知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/structure-multi-file-c-part-2
|
||||
|
||||
作者:[Erik O'Shaughnessy][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[萌新阿岩](https://github.com/mengxinayan)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jnyjny
|
||||
[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]: https://linux.cn/article-11935-1.html
|
||||
[3]: https://github.com/jnyjny/MeowMeow.git
|
||||
[4]: https://en.wikipedia.org/wiki/Codec
|
||||
[5]: https://linux.cn/article-10949-1.html
|
||||
[6]: https://github.com/JnyJny/meowmeow/blob/master/main.h
|
||||
[7]: https://github.com/JnyJny/meowmeow/blob/master/main.c
|
||||
[8]: https://github.com/JnyJny/meowmeow/blob/master/mmencode.h
|
||||
[9]: https://github.com/JnyJny/meowmeow/blob/master/mmdecode.h
|
||||
[10]: http://www.opengroup.org/onlinepubs/009695399/functions/feof.html
|
||||
[11]: http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html
|
||||
[12]: http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html
|
||||
[13]: http://www.opengroup.org/onlinepubs/009695399/functions/fputs.html
|
||||
[14]: https://github.com/JnyJny/meowmeow/blob/master/table.h
|
||||
[15]: http://www.opengroup.org/onlinepubs/009695399/functions/isupper.html
|
||||
[16]: http://www.opengroup.org/onlinepubs/009695399/functions/fputc.html
|
@ -0,0 +1,215 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (caiichenr)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11986-1.html)
|
||||
[#]: subject: (Building a non-breaking breakpoint for Python debugging)
|
||||
[#]: via: (https://opensource.com/article/19/8/debug-python)
|
||||
[#]: author: (Liran Haimovitch https://opensource.com/users/liranhaimovitch)
|
||||
|
||||
在 Python 调试过程中设置不中断的断点
|
||||
======
|
||||
|
||||
> 你对如何让调试器变得更快产生过兴趣吗?本文将分享我们在为 Python 构建调试器时得到的一些经验。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/12/104433hq3qx2k81w1wamwm.jpg)
|
||||
|
||||
整段故事讲的是我们在 [Rookout][2] 公司的团队为 Python 调试器开发不中断断点的经历,以及开发过程中得到的经验。我将在本月于旧金山举办的 [PyBay 2019][3] 上介绍有关 Python 调试过程的更多细节,但现在就让我们立刻开始这段故事。
|
||||
|
||||
### Python 调试器的心脏:sys.set_trace
|
||||
|
||||
在诸多可选的 Python 调试器中,使用最广泛的三个是:
|
||||
|
||||
* pdb,它是 Python 标准库的一部分
|
||||
* PyDev,它是内嵌在 Eclipse 和 Pycharm 等 IDE 中的调试器
|
||||
* ipdb,它是 IPython 的调试器
|
||||
|
||||
Python 调试器的选择虽多,但它们几乎都基于同一个函数:`sys.settrace`。 值得一提的是, [sys.settrace][4] 可能也是 Python 标准库中最复杂的函数。
|
||||
|
||||
![set_trace Python 2 docs page][5]
|
||||
|
||||
简单来讲,`settrace` 的作用是为解释器注册一个跟踪函数,它在下列四种情形发生时被调用:
|
||||
|
||||
* 函数调用
|
||||
* 语句执行
|
||||
* 函数返回
|
||||
* 异常抛出
|
||||
|
||||
一个简单的跟踪函数看上去大概是这样:
|
||||
|
||||
```
|
||||
def simple_tracer(frame, event, arg):
|
||||
co = frame.f_code
|
||||
func_name = co.co_name
|
||||
line_no = frame.f_lineno
|
||||
print("{e} {f} {l}".format(
|
||||
e=event, f=func_name, l=line_no))
|
||||
return simple_tracer
|
||||
```
|
||||
|
||||
在分析函数时我们首先关注的是参数和返回值,该跟踪函数的参数分别是:
|
||||
|
||||
* `frame`,当前堆栈帧,它是包含当前函数执行时解释器里完整状态的对象
|
||||
* `event`,事件,它是一个值可能为 `call`、`line`、`return` 或 `exception` 的字符串
|
||||
* `arg`,参数,它的取值基于 `event` 的类型,是一个可选项
|
||||
|
||||
该跟踪函数的返回值是它自身,这是由于解释器需要持续跟踪两类跟踪函数:
|
||||
|
||||
* **全局跟踪函数(每线程)**:该跟踪函数由当前线程调用 `sys.settrace` 来设置,并在解释器创建一个新的堆栈帧时被调用(即代码中发生函数调用时)。虽然没有现成的方式来为不同的线程设置跟踪函数,但你可以调用 `threading.settrace` 来为所有新创建的 `threading` 模块线程设置跟踪函数。
|
||||
* **局部跟踪函数(每一帧)**:解释器将该跟踪函数的值设置为全局跟踪函数创建帧时的返回值。同样也没有现成的方法能够在帧被创建时自动设置局部跟踪函数。
|
||||
|
||||
该机制的目的是让调试器对被跟踪的帧有更精确的把握,以减少对性能的影响。
|
||||
|
||||
### 简单三步构建调试器 (我们最初的设想)
|
||||
|
||||
仅仅依靠上文提到的内容,用自制的跟踪函数来构建一个真正的调试器似乎有些不切实际。幸运的是,Python 的标准调试器 pdb 是基于 Bdb 构建的,后者是 Python 标准库中专门用于构建调试器的基类。
|
||||
|
||||
基于 Bdb 的简易断点调试器看上去是这样的:
|
||||
|
||||
```
|
||||
import bdb
|
||||
import inspect
|
||||
|
||||
class Debugger(bdb.Bdb):
|
||||
def __init__(self):
|
||||
Bdb.__init__(self)
|
||||
self.breakpoints = dict()
|
||||
self.set_trace()
|
||||
|
||||
def set_breakpoint(self, filename, lineno, method):
|
||||
self.set_break(filename, lineno)
|
||||
try :
|
||||
self.breakpoints[(filename, lineno)].add(method)
|
||||
except KeyError:
|
||||
self.breakpoints[(filename, lineno)] = [method]
|
||||
|
||||
def user_line(self, frame):
|
||||
if not self.break_here(frame):
|
||||
return
|
||||
|
||||
# Get filename and lineno from frame
|
||||
(filename, lineno, _, _, _) = inspect.getframeinfo(frame)
|
||||
|
||||
methods = self.breakpoints[(filename, lineno)]
|
||||
for method in methods:
|
||||
method(frame)
|
||||
```
|
||||
|
||||
这个调试器类的全部构成是:
|
||||
|
||||
1. 继承 `Bdb`,定义一个简单的构造函数来初始化基类,并开始跟踪。
|
||||
2. 添加 `set_breakpoint` 方法,它使用 `Bdb` 来设置断点,并跟踪这些断点。
|
||||
3. 重载 `Bdb` 在当前用户行调用的 `user_line` 方法,该方法一定被一个断点调用,之后获取该断点的源位置,并调用已注册的断点。
|
||||
|
||||
### 这个简易的 Bdb 调试器效率如何呢?
|
||||
|
||||
Rookout 的目标是在生产级性能的使用场景下提供接近普通调试器的使用体验。那么,让我们来看看先前构建出来的简易调试器表现的如何。
|
||||
|
||||
为了衡量调试器的整体性能开销,我们使用如下两个简单的函数来进行测试,它们分别在不同的情景下执行了 1600 万次。请注意,在所有情景下断点都不会被执行。
|
||||
|
||||
```
|
||||
def empty_method():
|
||||
pass
|
||||
|
||||
def simple_method():
|
||||
a = 1
|
||||
b = 2
|
||||
c = 3
|
||||
d = 4
|
||||
e = 5
|
||||
f = 6
|
||||
g = 7
|
||||
h = 8
|
||||
i = 9
|
||||
j = 10
|
||||
```
|
||||
|
||||
在使用调试器的情况下需要大量的时间才能完成测试。糟糕的结果指明了,这个简陋 `Bdb` 调试器的性能还远不足以在生产环境中使用。
|
||||
|
||||
![First Bdb debugger results][6]
|
||||
|
||||
### 对调试器进行优化
|
||||
|
||||
降低调试器的额外开销主要有三种方法:
|
||||
|
||||
1. **尽可能的限制局部跟踪**:由于每一行代码都可能包含大量事件,局部跟踪比全局跟踪的开销要大得多。
|
||||
2. **优化 `call` 事件并尽快将控制权还给解释器**:在 `call` 事件发生时调试器的主要工作是判断是否需要对该事件进行跟踪。
|
||||
3. **优化 `line` 事件并尽快将控制权还给解释器**:在 `line` 事件发生时调试器的主要工作是判断我们在此处是否需要设置一个断点。
|
||||
|
||||
于是我们复刻了 `Bdb` 项目,精简特征、简化代码,针对使用场景进行优化。这些工作虽然得到了一些效果,但仍无法满足我们的需求。因此我们又继续进行了其它的尝试,将代码优化并迁移至 `.pyx` 使用 [Cython][7] 进行编译,可惜结果(如下图所示)依旧不够理想。最终,我们在深入了解 CPython 源码之后意识到,让跟踪过程快到满足生产需求是不可能的。
|
||||
|
||||
![Second Bdb debugger results][8]
|
||||
|
||||
### 放弃 Bdb 转而尝试字节码操作
|
||||
|
||||
熬过先前对标准调试方法进行的试验-失败-再试验循环所带来的失望,我们将目光转向另一种选择:字节码操作。
|
||||
|
||||
Python 解释器的工作主要分为两个阶段:
|
||||
|
||||
1. **将 Python 源码编译成 Python 字节码**:这种(对人类而言)不可读的格式专为执行的效率而优化,它们通常缓存在我们熟知的 `.pyc` 文件当中。
|
||||
2. **遍历 解释器循环中的字节码**: 在这一步中解释器会逐条的执行指令。
|
||||
|
||||
我们选择的模式是:使用**字节码操作**来设置没有全局额外开销的**不中断断点**。这种方式的实现首先需要在内存中的字节码里找到我们感兴趣的部分,然后在该部分的相关机器指令前插入一个函数调用。如此一来,解释器无需任何额外的工作即可实现我们的不中断断点。
|
||||
|
||||
这种方法并不依靠魔法来实现,让我们简要地举个例子。
|
||||
|
||||
首先定义一个简单的函数:
|
||||
|
||||
```
|
||||
def multiply(a, b):
|
||||
result = a * b
|
||||
return result
|
||||
```
|
||||
|
||||
在 [inspect][9] 模块(其包含了许多实用的单元)的文档里,我们得知可以通过访问 `multiply.func_code.co_code` 来获取函数的字节码:
|
||||
|
||||
```
|
||||
'|\x00\x00|\x01\x00\x14}\x02\x00|\x02\x00S'
|
||||
```
|
||||
|
||||
使用 Python 标准库中的 [dis][10] 模块可以翻译这些不可读的字符串。调用 `dis.dis(multiply.func_code.co_code)` 之后,我们就可以得到:
|
||||
|
||||
```
|
||||
4 0 LOAD_FAST 0 (a)
|
||||
3 LOAD_FAST 1 (b)
|
||||
6 BINARY_MULTIPLY
|
||||
7 STORE_FAST 2 (result)
|
||||
|
||||
5 10 LOAD_FAST 2 (result)
|
||||
13 RETURN_VALUE
|
||||
```
|
||||
|
||||
与直截了当的解决方案相比,这种方法让我们更靠近发生在调试器背后的事情。可惜 Python 并没有提供在解释器中修改函数字节码的方法。我们可以对函数对象进行重写,不过那样做的效率满足不了大多数实际的调试场景。最后我们不得不采用一种迂回的方式来使用原生拓展才能完成这一任务。
|
||||
|
||||
### 总结
|
||||
|
||||
在构建一个新工具时,总会学到许多事情的工作原理。这种刨根问底的过程能够使你的思路跳出桎梏,从而得到意料之外的解决方案。
|
||||
|
||||
在 Rookout 团队中构建不中断断点的这段时间里,我学到了许多有关编译器、调试器、服务器框架、并发模型等等领域的知识。如果你希望更深入的了解字节码操作,谷歌的开源项目 [cloud-debug-python][11] 为编辑字节码提供了一些工具。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/8/debug-python
|
||||
|
||||
作者:[Liran Haimovitch][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[caiichenr](https://github.com/caiichenr)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/liranhaimovitch
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python_jungle_lead.jpeg?itok=pFKKEvT- (Real python in the graphic jungle)
|
||||
[2]: https://rookout.com/
|
||||
[3]: https://pybay.com/
|
||||
[4]: https://docs.python.org/3/library/sys.html#sys.settrace
|
||||
[5]: https://opensource.com/sites/default/files/uploads/python2docs.png (set_trace Python 2 docs page)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/debuggerresults1.png (First Bdb debugger results)
|
||||
[7]: https://cython.org/
|
||||
[8]: https://opensource.com/sites/default/files/uploads/debuggerresults2.png (Second Bdb debugger results)
|
||||
[9]: https://docs.python.org/2/library/inspect.html
|
||||
[10]: https://docs.python.org/2/library/dis.html
|
||||
[11]: https://github.com/GoogleCloudPlatform/cloud-debug-python
|
||||
[12]: https://pybay.com/speaker/liran-haimovitch/
|
||||
[13]: https://ti.to/sf-python/pybay2019/discount/OpenSource35
|
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (cycoe)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11994-1.html)
|
||||
[#]: subject: (Debugging in Emacs: The Grand Unified Debugger)
|
||||
[#]: via: (https://opensourceforu.com/2019/09/debugging-in-emacs-the-grand-unified-debugger/)
|
||||
[#]: author: (Vineeth Kartha https://opensourceforu.com/author/vineeth-kartha/)
|
||||
|
||||
Emacs 调试秘籍之 GUD 调试器
|
||||
======
|
||||
|
||||
![][2]
|
||||
|
||||
> 本文简短地对 Emacs 的调试工具 GUD 的特性进行了探索。
|
||||
|
||||
如果你是一个 C 或 C++ 开发者,你很可能已经使用过 GDB(GNU 调试器),毫无疑问,它是现今最强大、最无可匹敌的调试器之一。它唯一的缺点就是它基于命令行,虽然仍能提供许多强大的功能,但有时也会具有一些局限性。这也就是为什么聪明的人们开始追求整合了编辑器和调试器的<ruby>图形化<rt> GUI </rt></ruby><ruby>集成开发环境<rt>Integrated Development Environment</rt></ruby>。仍有些开发者坚信使用鼠标会降低工作效率,在 GUI 上用鼠标点~点~点~是来自恶魔的诱惑。
|
||||
|
||||
因为 Emacs 是现今最酷的文本编辑器之一,我将为你展示如何在不碰鼠标且不离开 Emacs 的情况下,实现写代码、编译代码、调试代码的过程。
|
||||
|
||||
GUD(LCTT 译注:全称<ruby>大统一调试器<rt>Grand Unified Debugger</rt></ruby>,鉴于其缩写形式更为人熟知,以下全文将使用缩写替代此全称)是 Emacs 下的一个<ruby>模式<rt>mode</rt></ruby>,用于在 Emacs 中运行 GDB。它向 GDB 提供了 Emacs 的所有特性,使用户无需离开编辑器就可以对代码进行调试。
|
||||
|
||||
### 使用 GUD 的前期准备
|
||||
|
||||
如果你正在使用一个 Linux 机器,很可能你已经安装了 GDB 和 gcc,接下来就是要确保已经安装了 Emacs。以下的内容我将假设读者熟悉 GDB 并且至少用它做过基本的调试。如果你未曾接触过 GDB,你可以做个快速入门,这些资料在网上随处可得。
|
||||
|
||||
对于那些 Emacs 新手,我将向你介绍一些基本术语。纵览整篇文章,你将看到诸如 `C-c M-x` 等快捷键。此处 `C` 代表 `Ctrl` 键,`M` 代表 `Alt` 键。`C-c` 代表 `Ctrl` 键和 `c` 键被同时按下。如果你看到 `C-c c`,它代表同时按下 `Ctrl` 键和 `c` 键,释放后紧接着按下 `c` 键。在 Emacs 中,编辑文本的主要区域被称为<ruby>主缓冲区<rt>main buffer</rt></ruby>,而在 Emacs 窗口下方用于输入命令的区域被称为<ruby>迷你缓冲区<rt>mini buffer</rt></ruby>。
|
||||
|
||||
启动 Emacs,并按下 `C-x C-f` 来创建一个新文件。Emacs 将提示你输入一个文件名,此处让我们将文件命名为 `buggyFactorial.cpp`。一旦文件打开,输入如下代码:
|
||||
|
||||
```
|
||||
#include<iostream>
|
||||
#include <assert.h>
|
||||
|
||||
int factorial(int num) {
|
||||
int product = 1;
|
||||
while(num--) {
|
||||
product *= num;
|
||||
}
|
||||
return product;
|
||||
}
|
||||
int main() {
|
||||
int result = factorial(5);
|
||||
assert(result == 120);
|
||||
}
|
||||
```
|
||||
|
||||
使用 `C-x C-s` 快捷键保存文件。文件保存完毕,是时候进行编译了。按下 `M-x`,在弹出的<ruby>提示符<rt>prompt</rt></ruby>后输入 `compile` 并点击回车。然后在提示符后,将内容替换为 `g++ -g buggyFactorial.cpp` 并再次点击回车。
|
||||
|
||||
![图 1: Emacs 迷你缓冲区中编译命令][3]
|
||||
|
||||
这将在 Emacs 中开启另一个缓冲区,显示编译的状态。如果你的代码输入没有错误,你将预期得到如图 2 所示的缓冲区。
|
||||
|
||||
![图 2: 编译状态][4]
|
||||
|
||||
要想隐藏编译缓冲区,首先确保你的光标在编译缓冲区中(你可以不使用鼠标,而是通过 `C-x o` 快捷键将光标从一个缓冲区移动到另一个),然后按下 `C-x 0`。下一步就是运行代码,并观察是否运行良好。按下 `M-!` 快捷键并在迷你缓冲区的提示符后面输入 `./a.out`。
|
||||
|
||||
![图 3: 代码在迷你缓冲区中的输出][5]
|
||||
|
||||
你可以看到迷你缓冲区中显示断言失败。很明显代码中有错误,因为 5 的阶乘是 120。那么让我们现在开始调试吧。
|
||||
|
||||
### 使用 GUD 调式代码
|
||||
|
||||
现在,我们的代码已经编译完成,是时候看看到底哪里出错了。按下 `M-x` 快捷键并在提示符后输入 `gdb`。在接下来的提示符后,输入 `gdb -i=mi a.out`。如果一切顺利,GDB 会在 Emacs 缓冲区中启动,你会看到如图 4 所示的窗口。
|
||||
|
||||
![图 4: Emacs 中的 GDB 缓冲区][6]
|
||||
|
||||
在 `gdb` 提示符后,输入 `break main` 来设置断点,并输入 `r` 来运行程序。程序会开始运行并停在 `main()` 函数处。
|
||||
|
||||
一旦 GDB 到达了 `main` 处设置的断点,就会弹出一个新的缓冲区显示你正在调试的代码。注意左侧的红点,正是你设置断点的位置,同时会有一个小的标志提示你当前代码运行到了哪一行。当前,该标志就在断点处(如图 5)。
|
||||
|
||||
![图 5: GDB 与代码显示在两个分离的窗口][7]
|
||||
|
||||
为了调试 `factorial` 函数,我们需要单步运行。想要达到此目的,你可以在 GBD 提示符使用 GDB 命令 `step`,或者使用 Emacs 快捷键 `C-c C-s`。还有其它一些快捷键,但我更喜欢 GDB 命令。因此我将在本文的后续部分使用它们。
|
||||
|
||||
单步运行时让我们注意一下局部变量中的阶乘值。参考图 6 来设置在 Emacs 帧中显示局部变量值。
|
||||
|
||||
![图 6: 在 Emacs 中使用独立帧显示局部变量][8]
|
||||
|
||||
在 GDB 提示符中进行单步运行并观察局部变量值的变化。在循环的第一次迭代中,我们发现了一个问题。此处乘法的结果应该是 5 而不是 4。
|
||||
|
||||
本文到这里也差不多结束了,读者可以自行探索发现 GUD 模式这片新大陆。GDB 中的所有命令都可以在 GUD 模式中运行。我将此代码的修复留给读者作为一个练习。看看你在调试的过程中,可以做哪一些定制化,来使你的工作流更加简单和高效。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/09/debugging-in-emacs-the-grand-unified-debugger/
|
||||
|
||||
作者:[Vineeth Kartha][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[cycoe](https://github.com/cycoe)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/vineeth-kartha/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Screenshot-from-2019-09-25-15-39-46.png?ssl=1
|
||||
[2]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Screenshot-from-2019-09-25-15-39-46.png?ssl=1
|
||||
[3]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_1.png?ssl=1
|
||||
[4]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_2.png?ssl=1
|
||||
[5]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_3.png?ssl=1
|
||||
[6]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_4.png?ssl=1
|
||||
[7]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_5.png?ssl=1
|
||||
[8]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/09/Figure_6.png?ssl=1
|
@ -0,0 +1,60 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11981-1.html)
|
||||
[#]: subject: (Calculator N+ is an open source scientific calculator for your smartphone)
|
||||
[#]: via: (https://opensource.com/article/19/11/calculator-n-mobile)
|
||||
[#]: author: (Ricardo Berlasso https://opensource.com/users/rgb-es)
|
||||
|
||||
Calculator N+:一款智能手机上的开源科学计算器
|
||||
======
|
||||
|
||||
> 这个 Android 应用可在掌中计算许多高级数学函数。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/10/113543hlb5xu7b5e17ba90.jpg)
|
||||
|
||||
移动电话每天都在变得越来越强大,因此毫不奇怪它们可以击败不太久前的大多数计算机。这也意味着移动手机上的工具每天都在变得越来越强大。
|
||||
|
||||
之前,我写过一篇 [两款 Linux 桌面端可用的科学计算器][2],我接着将介绍 [Calculator N+][3],这是一款很棒的适用于 Android 设备的计算机代数系统(CAS)应用,采用 GPL v3.0 许可证下。
|
||||
|
||||
Calculator N+ 被认为是“适用于 Android 的强大计算器”,但这是一个谦虚的说法。它不仅可以以任意精度工作,还可以显示根数和分数等*很多*功能。
|
||||
|
||||
寻找多项式根?可以。分解因数?可以。导数、积分和极限?可以。数论(模算术、组合学、素因数分解)?可以。
|
||||
|
||||
你还可以求解方程系统、简化表达式(包括三角函数)、转换单位,只要你想到的,它都能做!
|
||||
|
||||
![Calculator N+ graphical interface][4]
|
||||
|
||||
其结果以 LaTeX 输出。左上方的菜单提供了许多强大的功能,只需触摸一下即可使用。同样在该菜单中,你将找到该应用所有功能的帮助文件。在屏幕的右上角,你可以在精确表示法和十进制表示法之间切换。最后,点击屏幕底部的蓝色栏,即可访问应用中的所有函数库。不过要小心!如果你不是数学家、物理学家或工程师,那么这么长的列表会看上去很吓人。
|
||||
|
||||
所有这些功能都来自 [Symja 库][5],这是另一个出色的 GPL 3 项目。
|
||||
|
||||
这两个项目都处于积极开发中,并且每个版本都在不断完善。特别是,Calculator N+ 的 v3.4.6 在用户界面(UI)品质方面取得了重大飞跃。虽然还是存在一些不够好的地方,但是要在智能手机的小巧的用户界面中发挥如此强大的功能是一项艰巨的任务,我认为应用开发人员正在很好地解决其剩余的问题。对他们表示敬意!
|
||||
|
||||
如果你是老师、学生或在理工科领域工作,请试试 Calculator N+。它是免费、无广告、开源的,并可以满足你所有的数学需求。(当然,除了数学考试期间,为防止作弊绝对不允许使用智能手机。)
|
||||
|
||||
可以在 [Google Play 商店][6]找到 Calculator N+,也可以使用 GitHub 页面上的说明[从源代码构建][7]。
|
||||
|
||||
如果你知道用于科学或工程的其他有用的开源应用,请在评论中告知我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/calculator-n-mobile
|
||||
|
||||
作者:[Ricardo Berlasso][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/rgb-es
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/calculator_money_currency_financial_tool.jpg?itok=2QMa1y8c (scientific calculator)
|
||||
[2]: https://linux.cn/article-9643-1.html
|
||||
[3]: https://github.com/tranleduy2000/ncalc
|
||||
[4]: https://opensource.com/sites/default/files/uploads/calculatornplus_sqrt-frac.png (Calculator N+ graphical interface)
|
||||
[5]: https://github.com/axkr/symja_android_library
|
||||
[6]: https://play.google.com/store/apps/details?id=com.duy.calculator.free
|
||||
[7]: https://github.com/tranleduy2000/ncalc/blob/master/README.md
|
@ -0,0 +1,99 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "messon007"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-12035-1.html"
|
||||
[#]: subject: "10 articles to learn Linux your way"
|
||||
[#]: via: "https://opensource.com/article/19/12/learn-linux"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
|
||||
10 篇关于 Linux 的好文章
|
||||
=======
|
||||
|
||||
> 2019 年对于 Linux 来说是个好年份,让我们一起来回顾一下这十篇关于 Linux 的好文章。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/25/115447rrjfuufccumf0oz6.jpg)
|
||||
|
||||
2019 年对于 Linux 来说是个好年份,显然这里的 “Linux” 一词有更多含义: 内核? 桌面? 或是生态? 在此次回顾年度 Linux 好文中,我在选择十大好文时有意采取了更开放的视角。下面就是十大好文(无先后次序之分)。
|
||||
|
||||
### 《Linux 权限入门指南》
|
||||
|
||||
Bryant Son 的《[Linux 权限入门指南][2]》向新用户介绍了文件权限的概念,通过图形和图表的方式来说明每个要点。通常很难以视觉的方式来解释纯粹基于文本的概念,而本文则对可视方式学习的人非常友好。 Bryant 在讲述时也很专注主题。关于文件权限的任何阐述都可能引出几个相关主题(例如所有权和访问控制列表等),但是本文致力于解释一件事并很好地解释它。
|
||||
|
||||
### 《为什么我从 Mac 换到了 Linux》
|
||||
|
||||
Matthew Broberg 在《[为什么我从 Mac 换到了 Linux][3]》中清楚而客观的介绍了他从 MacOS 切换到 Linux 的经历。通常切换平台是很困难的,因此记录决定切换的背后考虑非常重要。我认为 Matt 的文章带有几个目的,但对我来说最重要的两个目的是:通过解答他的问题并提供潜在的解决方案,他请 Linux 社区的人们来支持他;这对于其他正在考虑采用 Linux 的人来说是一个很好的参考。
|
||||
|
||||
### 《在 Linux 上定位 WiFi 速度慢的问题》
|
||||
|
||||
《[在 Linux 上定位 WiFi 速度慢的问题][4]》这篇文章中,David Clinton 对每个人都可能遇到的问题进行了分析,并提供了怎么样一步步解决的思路。这是“偶然的 Linux”技巧的一个很好的例子,但它不仅可以帮助经常遇到问题的人,而且可以向非 Linux 用户展示如何在其他平台上进行问题定位。
|
||||
|
||||
### 《一个非技术人员对 GNOME 项目使用 GitLab 的感受》
|
||||
|
||||
Molly de Blanc 所写的《[一个非技术人员对 GNOME 项目使用 GitLab 的感受][5]》深层次地揭示了开源界的一个典范(GNOME 桌面)如何使用开源界的另一个典范(Git)进行开发。听到一个开放源代码项目对于任何需要做的事情默认为开放源代码解决方案,这总是让我感到振奋。无论如何,这种情况并不常见,然而对于 GNOME 来说,这是项目本身的重要且受欢迎的部分。
|
||||
|
||||
### 《详解 Linux 中的虚拟文件系统》
|
||||
|
||||
Alison Chaiken 在《[详解 Linux 中的虚拟文件系统][6]》中巧妙地解释了对许多用户来说都很难理解的东西。理解文件系统是什么、虚拟文件系统和真实的文件系统是一回事,但从定义上讲,*虚拟的*其实并不是真正的文件系统。Linux 以一种普通用户也能从中受益的方式提供了它们,Alison 的文章以一种易于理解的方式对其进行了阐述。另外,Alison 在文章的后半部分更深入地介绍了如何使用 `bcc` 脚本查看她刚刚讲的虚拟文件系统的相关内容。
|
||||
|
||||
### 《理解文件路径并学会使用它们》
|
||||
|
||||
我认为《[理解文件路径并学会使用它们][7]》很重要,因为这是大多数用户(在任何平台上)似乎都没有学过的概念。这是一个奇怪的现象,因为现在比以往任何时候,人们都越来越多地看到*文件路徑*:几乎所有的互联网网址都包含一个文件路径,该路径告诉你你在域中的确切位置。我常常在想为什么计算机教育不是从互联网开始的,互联网是目前最熟悉的应用程序,并且可以说是使用最频繁的超级计算机,完全可以用它来解释我们每天使用的设备。(我想如果这些设备运行 Linux 会有所帮助,但是我们正在努力。)
|
||||
|
||||
### 《Linux 下的进程间通信:共享存储》
|
||||
|
||||
Marty Kalin 的《[Linux 下的进程间通信:共享存储][8]》从 Linux 的开发者视角解释了 IPC 以及如何在代码中使用它。虽然我只是列入了这篇文章,不过它实际上是一个三篇文章的系列,而它是同类文章中阐述的最好的。很少有文档能够解释 Linux 怎样处理 IPC,更不用说 IPC 是什么,为什么它很重要,或者在编程时该如何使用它。通常这是你在大学读书时关注的话题。现在,你可以在这里阅读所有内容。
|
||||
|
||||
### 《在 Linux 上用 strace 来理解系统调用》
|
||||
|
||||
Gaurav Kamathe 的《[在 Linux 上用 strace 来理解系统调用][9]》具有很强的技术性,我希望我所见过的有关 `strace` 的每次会议演讲都是如此。这是对一个复杂但非常有用的命令的清晰演示。令我惊讶的是,我读了本文才发现自己一直使用的命令不是这个命令,而是 `ltrace`(可以用来查看命令调用了哪些函数)。本文包含了丰富的信息,是开发人员和测试人员的快捷参考手册。
|
||||
|
||||
### 《Linux 桌面发展旅程》
|
||||
|
||||
Jim Hall 的《[Linux 桌面发展旅程][10]》是对 Linux 桌面历史的一次视觉之旅。从 [TWM][11] 开始,经历了 [FVWM][12]、[GNOME][13]、[KDE][14] 等薪火相传。如果你是 Linux 的新手,那么这将是一个出自那个年代的人的有趣的历史课(有截图可以证明这一点)。如果你已经使用 Linux 多年,那么这肯定会唤醒你的记忆。最后,可以肯定的是:仍然可以找到 20 年前屏幕快照的人都是神一样的数据档案管理员。
|
||||
|
||||
### 《用 Linux 创建你自己的视频流服务器》
|
||||
|
||||
Aaron J. Prisk 的 《[用 Linux 创建你自己的视频流服务器][15]》消除了大多数人对我们视为理所当然的服务的误解。由于 YouTube 和 Twitch 之类服务的存在,许多人认为这是向世界广播视频的唯一方式。当然,人们过去常常以为 Windows 和 Mac 是计算机的唯一入口,值得庆幸的是,最终证明这是严重的误解。在本文中,Aaron 建立了一个视频流服务器,甚至还顺便讨论了一下 [OBS][16],以便你可以创建视频。这是一个有趣的周末项目还是新职业的开始?你自己决定。
|
||||
|
||||
### 《塑造 Linux 历史的 10 个时刻》
|
||||
|
||||
Alan Formy-Duval 撰写的《[塑造 Linux 历史的 10 个时刻][17]》试图完成一项艰巨的任务,即从 Linux 的历史中选出 10 件有代表性的事情。当然,这是很难的,因为有如此多重要的时刻,所以我想看看 Alan 是如何通过自己的经历来选择它。例如,什么时候开始意识到 Linux 必然可以发展下去?—— 当 Alan 意识到他维护的所有系统都在运行 Linux 时。用这种方式来解释历史是很美的,因为每个人的重要时刻都会有所不同。 关于 Linux 没有权威性列表,关于 Linux 的文章也没有,关于开源也没有。你可以创建你自己的列表,也可以使你自己成为列表的一部分。
|
||||
|
||||
(LCTT 译注:这里推荐了 11 篇,我数了好几遍,没眼花……)
|
||||
|
||||
### 你想从何学起?
|
||||
|
||||
你还想知道 Linux 的什么内容?请在评论区告诉我们或来文讲述你的 Linux 经验。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/learn-linux
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[messon007](https://github.com/messon007)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_Penguin_Image_520x292_12324207_0714_mm_v1a.png?itok=p7cWyQv9 "Penguins gathered together in the Artic"
|
||||
[2]: https://linux.cn/article-11056-1.html
|
||||
[3]: https://linux.cn/article-11586-1.html
|
||||
[4]: http://opensource.com/article/19/4/troubleshooting-wifi-linux
|
||||
[5]: https://linux.cn/article-11806-1.html
|
||||
[6]: https://linux.cn/article-10884-1.html
|
||||
[7]: https://opensource.com/article/19/8/understanding-file-paths-linux
|
||||
[8]: https://linux.cn/article-10826-1.html
|
||||
[9]: https://linux.cn/article-11545-1.html
|
||||
[10]: https://opensource.com/article/19/8/how-linux-desktop-grown
|
||||
[11]: https://github.com/freedesktop/twm
|
||||
[12]: http://www.fvwm.org/
|
||||
[13]: http://gnome.org
|
||||
[14]: http://kde.org
|
||||
[15]: https://opensource.com/article/19/1/basic-live-video-streaming-server
|
||||
[16]: https://opensource.com/life/15/12/real-time-linux-video-editing-with-obs-studio
|
||||
[17]: https://opensource.com/article/19/4/top-moments-linux-history
|
||||
[18]: https://opensource.com/how-submit-article
|
@ -0,0 +1,63 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (caiichenr)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11999-1.html)
|
||||
[#]: subject: (Prioritizing simplicity in your Python code)
|
||||
[#]: via: (https://opensource.com/article/19/12/zen-python-simplicity-complexity)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
简单是 Python 编程的第一要则
|
||||
======
|
||||
|
||||
> 本文是 Python 之禅特别系列的第二篇,我们将要关注其中第三与第四条原则:简单与复杂。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/15/124150t4wf3wwgdrijx6xx.jpg)
|
||||
|
||||
> "Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y plus rien à retrancher."
|
||||
>
|
||||
> "It seems that perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away."
|
||||
>
|
||||
> “完美并非无可增,而是不可减。”
|
||||
>
|
||||
> —Antoine de Saint-Exupéry, [Terre des Hommes][2], 1939
|
||||
|
||||
编程时最常有的考量是与复杂性的斗争,只想写出让旁人无从下手的繁杂代码,对每个程序员来讲都算不上难事。倘若未能触及代码的简繁取舍,那么 《[Python 之禅][3]》 就有了一角残缺。
|
||||
|
||||
### <ruby>简单胜过复杂<rt>Simple is better than complex</rt></ruby>
|
||||
|
||||
尚有选择余地时,应该选简单的方案。Python 少有*不可为*之事,这意味着设计出巴洛克风格(LCTT 译注:即夸张和不理性)的程序只为解决浅显的问题不仅有可能,甚至很简单。
|
||||
|
||||
正因如此,编程时应当谨记,代码的简单性是最易丢失,却最难复得的。
|
||||
|
||||
这意味着,在可以选用函数来表达时不要去引入额外的类;避免使用强力的第三方库往往有助于你针对迫切的问题场景设计更妥当的简短函数。不过其根本的意图,旨在让你减少对将来的盘算,而去着重解决手头的问题。
|
||||
|
||||
以简单和优美作为指导原则的代码相比那些想要囊括将来一切变数的,在日后要容易修改得多。
|
||||
|
||||
### <ruby>复杂胜过错综复杂<rt>Complex is better than complicated</rt></ruby>
|
||||
|
||||
把握用词的精确含义对于理解这条令人费解的原则是至关重要的。形容某事<ruby>复杂<rt>complex</rt></ruby>,是说它由许多部分组成,着重组成成分之多;而形容某事<ruby>错综复杂<rt>complicated</rt></ruby>,则是指其包含着差异巨大、难以预料的行为,强调的是各组成部分之间的杂乱联系。
|
||||
|
||||
解决困难问题时,往往没有可行的简单方案。此时,最 Python 化的策略是“<ruby>自底向上<rt>bottom-up</rt></ruby>”地构建出简单的工具,之后将其组合用以解决该问题。
|
||||
|
||||
这正是<ruby>对象组合<rt>object composition</rt></ruby>这类技术的闪耀之处,它避免了错综复杂的继承体系,转而由独立的对象把一些方法调用传递给别的独立对象。这些对象都能独立地测试与部署,最终却可以组成一体。
|
||||
|
||||
“自底建造” 的另一例即是<ruby>[单分派泛函数][4]<rt>singledispatch</rt></ruby>的使用,抛弃了错综复杂的对象之后,我们得到是简单、几乎无行为的对象以及独立的行为。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/zen-python-simplicity-complexity
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[caiichenr](https://github.com/caiichenr)
|
||||
校对:[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/read_book_guide_tutorial_teacher_student_apaper.png?itok=_GOufk6N (Person reading a book and digital copy)
|
||||
[2]: https://en.wikipedia.org/wiki/Wind,_Sand_and_Stars
|
||||
[3]: https://www.python.org/dev/peps/pep-0020/
|
||||
[4]: https://opensource.com/article/19/5/python-singledispatch
|
@ -0,0 +1,87 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12011-1.html)
|
||||
[#]: subject: (10 Linux command tutorials for beginners and experts)
|
||||
[#]: via: (https://opensource.com/article/19/12/linux-commands)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
10 篇对初学者和专家都有用的 Linux 命令教程
|
||||
======
|
||||
|
||||
> 在这有关 Linux 命令的十大文章中,了解如何使 Linux 发挥所需的作用。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/19/095932xc64xw7cwqlolale.jpg)
|
||||
|
||||
**很好地**使用 Linux 意味着了解有哪些命令以及它们可以为你执行的功能。
|
||||
|
||||
### 《在 Linux 命令行下使用“原力”》
|
||||
|
||||
<ruby>原力<rt>force</rt></ruby>有光明的一面和黑暗的一面。正确理解这个对于真正掌握它至关重要。Alan Formy-Duval 在他的文章《[在 Linux 命令行下使用“原力”][2]》中,解释了一些流行的、有时是危险的命令的 `-f` 选项(也称为 `--force`)。
|
||||
|
||||
### 《Linux useradd 命令介绍》
|
||||
|
||||
共享帐户是一个坏主意。相反,请使用典型的 `useradd` 命令为不同的人(甚至是不同的角色)分配单独的帐户。作为其经典的 Linux 管理基础系列的一部分,Alan Formy-Duval 提供了《[Linux useradd 命令介绍][3]》,并且像往常一样,他用**朴实明白的语言**对其进行了解释,以便新老管理员都可以理解。
|
||||
|
||||
### 《用 Linux 命令显示硬件信息》
|
||||
|
||||
机器**里面**是什么?有时不使用螺丝刀检查硬件很有用。无论是你正在使用的计算机,还是在商店购买前进行测试的计算机、或者是正在尝试维修的计算机,在《[用 Linux 命令显示硬件信息][4]》中,Howard Fosdick 提供了或流行或晦涩难懂的命令,以帮助你深入了解计算机的硬件信息。
|
||||
|
||||
### 《如何在 Linux 上使用 gocryptfs 加密文件》
|
||||
|
||||
从社会保险号到个人信件再到亲人,我们的文件中包含了许多私人数据。在《[如何在 Linux 上使用 gocryptfs 加密文件][5]》中,Brian "Bex" Exelbierd 解释了如何保持**隐私*的私密性。此外,他展示了一种加密文件的方式,这种方式对你现有的工作流程几乎没有影响。这不是复杂的 PGP 风格的密钥管理和后台密钥代理的难题,这是快速、无缝和安全的文件加密。
|
||||
|
||||
### 《如何使用 rsync 的高级用法进行大型备份》
|
||||
|
||||
在新的一年中,许多人会下定决心要更加努力地进行备份。Alan Formy-Duval 早在几年前就已经做出了解决方案,因为在《[如何使用 rsync 的高级用法进行大型备份][6]》中,他表现出对文件同步命令的极其熟悉。你可能不会马上记住所有语法,但其思路是读取和处理选项、构造备份命令,然后使其自动化。这是使用 `rsync` 的明智方法,也是可靠地执行备份的**唯一**方法。
|
||||
|
||||
### 《在 Linux 命令行使用 more 查看文本文件》
|
||||
|
||||
在 Scott Nesbitt 的文章《[在 Linux 命令行使用 more 查看文本文件][7]》中,古老而良好的默认分页器 `more` 引起了人们的关注。许多人安装和使用 `less`,因为它比 `more` 更灵活。但是,随着越来越多的系统在新出现的容器中实现,有时甚至不存在像 `less` 或 `most` 之类的新颖的豪华工具。了解和使用`more` 很简单,这是常见的默认设置,并且是生产系统最后的调试工具。
|
||||
|
||||
### 《关于 sudo 你可能不知道的》
|
||||
|
||||
`sudo` 命令因其过失而闻名。人们知道 `sudo` 一词,我们大多数人认为我们知道它的作用。我们的观点是正确的,但是正如 Peter Czanik 在他的文章《[关于 sudo 你可能不知道的][8]》中所揭示的那样,该命令所包含的不仅仅是“<ruby>西蒙说的<rt>Simon says</rt></ruby>”(LCTT 译注:国外的一个儿童游戏)。就像这个经典的童年游戏一样,`sudo` 命令功能强大,也容易犯愚蠢的错误 —— 有更多的可能产生可怕都后果,而这是你绝不想遇上的事情!
|
||||
|
||||
### 《怎样用 Bash 编程:语法和工具》
|
||||
|
||||
如果你是 Linux、BSD 或 Mac(以及近来的 Windows)用户,你也许使用过交互式 Bash shell。它是快速的、一次性命令的绝佳 shell,这就是为什么这么多 Linux 用户喜欢将其用作主要用户界面的原因。但是,Bash 不仅仅是个命令提示符。它也是一种编程语言,如果你已经在使用 Bash 命令,那么自动化的道路从未如此简单过。在 David Both 的出色作品《[怎样用 Bash 编程:语法和工具][9]》中对其进行全面了解。
|
||||
|
||||
### 《精通 Linux 的 ls 命令》
|
||||
|
||||
`ls` 命令是那些两个字母的命令之一。单字母命令是针对慢速终端的优化,因为慢速终端的输入的每个字母都会导致明显的延迟,而这对于懒惰的打字员来说也是不错的奖励。一如既往地,Seth Kenlon 清晰实用地解释了你可以怎样《[精通 Linux 的 ls 命令][10]》。最重要的是,在“一切都是文件”的系统中,列出文件至关重要。
|
||||
|
||||
### 《Linux cat 命令入门》
|
||||
|
||||
`cat` 命令(con*cat*enate 的缩写)看似简单。无论是使用它来快速查看文件的内容还是将内容通过管道传输到另一个命令,你都可能没有充分利用 `cat` 的功能。Alan Formy-Duval 的《[Linux cat 命令入门][11]》提供了一些新思路,可以使你没有打开文件的感觉就可以看到文件内容。另外,了解各种有关 `zcat` 的知识,这样你就可以无需解压缩就可以得到压缩文件的内容!这是一件小而简单的事情,但是**这**是使 Linux 很棒的原因。
|
||||
|
||||
### 继续旅程
|
||||
|
||||
不要让这些关于 Linux 命令的 10 篇最佳文章成为你的旅程终点。关于 Linux 及其多才多艺的提示符,还有更多值得去发现,因此,请继续关注以获取更多知识。而且,如果你想让我们介绍一个 Linux 命令,请在评论中告诉我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/linux-commands
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
|
||||
[2]: https://linux.cn/article-10881-1.html
|
||||
[3]: https://linux.cn/article-11756-1.html
|
||||
[4]: https://linux.cn/article-11422-1.html
|
||||
[5]: https://opensource.com/article/19/8/how-encrypt-files-gocryptfs
|
||||
[6]: https://linux.cn/article-10865-1.html
|
||||
[7]: https://linux.cn/article-10531-1.html
|
||||
[8]: https://linux.cn/article-11595-1.html
|
||||
[9]: https://linux.cn/article-11552-1.html
|
||||
[10]: https://linux.cn/article-11159-1.html
|
||||
[11]: https://opensource.com/article/19/2/getting-started-cat-command
|
||||
[12]: https://opensource.com/how-submit-article
|
@ -1,103 +1,103 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11997-1.html)
|
||||
[#]: subject: (How to setup a DNS server with bind)
|
||||
[#]: via: (https://fedoramagazine.org/how-to-setup-a-dns-server-with-bind/)
|
||||
[#]: author: (Curt Warfield https://fedoramagazine.org/author/rcurtiswarfield/)
|
||||
|
||||
How to setup a DNS server with bind
|
||||
简明指南:使用 bind 设置 DNS 服务器
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
The Domain Name System, or DNS, as it’s more commonly known, translates or converts domain names into the IP addresses associated with that domain. DNS is the reason you are able to find your favorite website by name instead of typing an IP address into your browser. This guide shows you how to configure a Master DNS system and one client.
|
||||
<ruby>域名系统<rt>Domain Name System</rt></ruby>,我们更通常称为 DNS 的系统,可以将域名翻译或转换为与该域关联的 IP 地址。DNS 是能够让你通过名称找到自己喜欢的网站而不是在浏览器中输入 IP 地址的原因。本指南将向你展示如何配置一个主 DNS 系统以及客户端。
|
||||
|
||||
Here are system details for the example used in this article:
|
||||
以下是本文示例中使用的系统细节:
|
||||
|
||||
```
|
||||
dns01.fedora.local (192.168.1.160 ) - Master DNS server
|
||||
client.fedora.local (192.168.1.136 ) - Client
|
||||
dns01.fedora.local (192.168.1.160)- 主 DNS 服务器
|
||||
client.fedora.local (192.168.1.136)- 客户端
|
||||
```
|
||||
|
||||
### DNS server configuration
|
||||
### DNS 服务器配置
|
||||
|
||||
Install the bind packages using sudo:
|
||||
使用 `sudo` 安装 bind 包:
|
||||
|
||||
```
|
||||
$ sudo dnf install bind bind-utils -y
|
||||
```
|
||||
|
||||
The _/etc/named.conf_ configuration file is provided by the _bind_ package to allow you to configure the DNS server.
|
||||
bind 包提供了 `/etc/named.conf` 配置文件,来供你配置 DNS 服务器。
|
||||
|
||||
Edit the _/etc/named.conf_ file:
|
||||
编辑 `/etc/named.conf` 文件:
|
||||
|
||||
```
|
||||
sudo vi /etc/named.conf
|
||||
```
|
||||
|
||||
Look for the following line:
|
||||
查找以下行:
|
||||
|
||||
```
|
||||
listen-on port 53 { 127.0.0.1; };
|
||||
```
|
||||
|
||||
Add the IP address of your Master DNS server as follows:
|
||||
添加主 DNS 服务器的 IP 地址,如下所示:
|
||||
|
||||
```
|
||||
listen-on port 53 { 127.0.0.1; 192.168.1.160; };
|
||||
```
|
||||
|
||||
Look for the next line:
|
||||
查找以下行:
|
||||
|
||||
```
|
||||
allow-query { localhost; };
|
||||
```
|
||||
|
||||
Add your local network range. The example system uses IP addresses in the 192.168.1.X range. This is specified as follows:
|
||||
添加本地网络范围。该示例系统使用的 IP 地址在 192.168.1.X 的范围内。指定如下:
|
||||
|
||||
```
|
||||
allow-query { localhost; 192.168.1.0/24; };
|
||||
```
|
||||
|
||||
Specify a forward and reverse zone. Zone files are simply text files that have the DNS information, such as IP addresses and host-names, on your system. The forward zone file makes it possible for the translation of a host-name to its IP address. The reverse zone file does the opposite. It allows a remote system to translate an IP address to the host name.
|
||||
指定转发和反向区域。<ruby>区域文件<rt>Zone file</rt></ruby>就是具有系统上 DNS 信息(例如 IP 地址和主机名)的文本文件。<ruby>转发区域文件<rt>forward zone file</rt></ruby>使得将主机名转换为 IP 地址成为可能。<ruby>反向区域文件<rt>reverse zone file</rt></ruby>则相反。它允许远程系统将 IP 地址转换为主机名。
|
||||
|
||||
Look for the following line at the bottom of the /etc/named.conf file:
|
||||
在 `/etc/named.conf` 文件的底部查找以下行:
|
||||
|
||||
```
|
||||
include "/etc/named.rfc1912.zones";
|
||||
```
|
||||
|
||||
Here, you’ll specify the zone file information _**directly above that line**_ as follows:
|
||||
在此处,你将在**该行的正上方**指定区域文件信息,如下所示:
|
||||
|
||||
```
|
||||
zone "dns01.fedora.local" IN {
|
||||
type master;
|
||||
file "forward.fedora.local";
|
||||
allow-update { none; };
|
||||
type master;
|
||||
file "forward.fedora.local";
|
||||
allow-update { none; };
|
||||
};
|
||||
|
||||
zone "1.168.192.in-addr.arpa" IN {
|
||||
type master;
|
||||
file "reverse.fedora.local";
|
||||
allow-update { none; };
|
||||
type master;
|
||||
file "reverse.fedora.local";
|
||||
allow-update { none; };
|
||||
};
|
||||
```
|
||||
|
||||
The _forward.fedora.local_ and the file _reverse.fedora.local_ are just the names of the zone files you will be creating. They can be called anything you like.
|
||||
`forward.fedora.local` 和 `reverse.fedora.local` 文件是要创建的区域文件的名称。它们可以是任意名字。
|
||||
|
||||
Save and exit.
|
||||
保存并退出。
|
||||
|
||||
#### Create the zone files
|
||||
#### 创建区域文件
|
||||
|
||||
Create the forward and reverse zone files you specified in the /etc/named.conf file:
|
||||
创建你在 `/etc/named.conf` 文件中指定的转发和反向区域文件:
|
||||
|
||||
```
|
||||
$ sudo vi /var/named/forward.fedora.local
|
||||
```
|
||||
|
||||
Add the following lines:
|
||||
添加以下行:
|
||||
|
||||
```
|
||||
$TTL 86400
|
||||
@ -114,13 +114,13 @@ dns01 IN A 192.168.1.160
|
||||
client IN A 192.168.1.136
|
||||
```
|
||||
|
||||
Everything in _**bold**_ is specific to your environment. Save the file and exit. Next, edit the _reverse.fedora.local_ file:
|
||||
所有**粗体**(LCTT 译注:本译文中无法呈现粗体)内容都特定于你的环境。保存文件并退出。接下来,编辑 `reverse.fedora.local` 文件:
|
||||
|
||||
```
|
||||
$ sudo vi /var/named/reverse.fedora.local
|
||||
```
|
||||
|
||||
Add the following lines:
|
||||
添加以下行:
|
||||
|
||||
```
|
||||
$TTL 86400
|
||||
@ -139,9 +139,9 @@ client IN A 192.168.1.136
|
||||
136 IN PTR client.fedora.local.
|
||||
```
|
||||
|
||||
Everything in _**bold**_ is also specific to your environment. Save the file and exit.
|
||||
所有**粗体**(LCTT 译注:本译文中无法呈现粗体)内容都特定于你的环境。保存文件并退出。
|
||||
|
||||
You’ll also need to configure SELinux and add the correct ownership for the configuration files.
|
||||
你还需要配置 SELinux 并为配置文件添加正确的所有权。
|
||||
|
||||
```
|
||||
sudo chgrp named -R /var/named
|
||||
@ -150,22 +150,22 @@ sudo restorecon -rv /var/named
|
||||
sudo restorecon /etc/named.conf
|
||||
```
|
||||
|
||||
Configure the firewall:
|
||||
配置防火墙:
|
||||
|
||||
```
|
||||
sudo firewall-cmd --add-service=dns --perm
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
#### Check the configuration for any syntax errors
|
||||
#### 检查配置是否存在语法错误
|
||||
|
||||
```
|
||||
sudo named-checkconf /etc/named.conf
|
||||
```
|
||||
|
||||
Your configuration is valid if no output or errors are returned.
|
||||
如果没有输出或返回错误,那么你的配置有效。
|
||||
|
||||
Check the forward and reverse zone files.
|
||||
检查转发和反向区域文件。
|
||||
|
||||
```
|
||||
$ sudo named-checkzone forward.fedora.local /var/named/forward.fedora.local
|
||||
@ -173,7 +173,7 @@ $ sudo named-checkzone forward.fedora.local /var/named/forward.fedora.local
|
||||
$ sudo named-checkzone reverse.fedora.local /var/named/reverse.fedora.local
|
||||
```
|
||||
|
||||
You should see a response of OK:
|
||||
你应该看到 “OK” 的响应:
|
||||
|
||||
```
|
||||
zone forward.fedora.local/IN: loaded serial 2011071001
|
||||
@ -183,50 +183,50 @@ zone reverse.fedora.local/IN: loaded serial 2011071001
|
||||
OK
|
||||
```
|
||||
|
||||
#### Enable and start the DNS service
|
||||
#### 启用并启动 DNS 服务
|
||||
|
||||
```
|
||||
$ sudo systemctl enable named
|
||||
$ sudo systemctl start named
|
||||
```
|
||||
|
||||
#### Configuring the resolv.conf file
|
||||
#### 配置 resolv.conf 文件
|
||||
|
||||
Edit the _/etc/resolv.conf_ file:
|
||||
编辑 `/etc/resolv.conf` 文件:
|
||||
|
||||
```
|
||||
$ sudo vi /etc/resolv.conf
|
||||
```
|
||||
|
||||
Look for your current name server line or lines. On the example system, a cable modem/router is serving as the name server and so it currently looks like this:
|
||||
查找你当前的 `nameserver` 行。在示例系统上,使用调制解调器/路由器充当名称服务器,因此当前看起来像这样:
|
||||
|
||||
```
|
||||
nameserver 192.168.1.1
|
||||
```
|
||||
|
||||
This needs to be changed to the IP address of the Master DNS server:
|
||||
这需要更改为主 DNS 服务器的 IP 地址:
|
||||
|
||||
```
|
||||
nameserver 192.168.1.160
|
||||
```
|
||||
|
||||
Save your changes and exit.
|
||||
保存更改并退出。
|
||||
|
||||
Unfortunately there is one caveat to be aware of. NetworkManager overwrites the _/etc/resolv.conf_ file if the system is rebooted or networking gets restarted. This means you will lose all of the changes that you made.
|
||||
不幸的是需要注意一点。如果系统重启或网络重启,那么 NetworkManager 会覆盖 `/etc/resolv.conf` 文件。这意味着你将丢失所做的所有更改。
|
||||
|
||||
To prevent this from happening, make _/etc/resolv.conf_ immutable:
|
||||
为了防止这种情况发生,请将 `/etc/resolv.conf` 设为不可变:
|
||||
|
||||
```
|
||||
$ sudo chattr +i /etc/resolv.conf
|
||||
```
|
||||
|
||||
If you want to set it back and allow it to be overwritten again:
|
||||
如果要重新设置,就需要允许其再次被覆盖:
|
||||
|
||||
```
|
||||
$ sudo chattr -i /etc/resolv.conf
|
||||
```
|
||||
|
||||
#### Testing the DNS server
|
||||
#### 测试 DNS 服务器
|
||||
|
||||
```
|
||||
$ dig fedoramagazine.org
|
||||
@ -266,27 +266,27 @@ $ dig fedoramagazine.org
|
||||
;; MSG SIZE rcvd: 266
|
||||
```
|
||||
|
||||
There are a few things to look at to verify that the DNS server is working correctly. Obviously getting the results back are important, but that by itself doesn’t mean the DNS server is actually doing the work.
|
||||
需要检查几件事以验证 DNS 服务器是否正常运行。显然,取得结果很重要,但这本身并不意味着 DNS 服务器实际上正常工作。
|
||||
|
||||
The QUERY, ANSWER, and AUTHORITY fields at the top should show non-zero as it in does in our example:
|
||||
顶部的 `QUERY`、`ANSWER` 和 `AUTHORITY` 字段应显示为非零,如我们的示例所示:
|
||||
|
||||
```
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 6
|
||||
```
|
||||
|
||||
And the SERVER field should have the IP address of your DNS server:
|
||||
并且 `SERVER` 字段应有你的 DNS 服务器的 IP 地址:
|
||||
|
||||
```
|
||||
;; SERVER: 192.168.1.160#53(192.168.1.160)
|
||||
```
|
||||
|
||||
In case this is the first time you’ve run the _dig_ command, notice how it took 830 milliseconds for the query to complete:
|
||||
如果这是你第一次运行 `dig` 命令,请注意完成查询要花费 830 毫秒的时间:
|
||||
|
||||
```
|
||||
;; Query time: 830 msec
|
||||
```
|
||||
|
||||
If you run it again, the query will run much quicker:
|
||||
如果再次运行它,查询将会更快:
|
||||
|
||||
```
|
||||
$ dig fedoramagazine.org
|
||||
@ -297,37 +297,37 @@ $ dig fedoramagazine.org
|
||||
;; SERVER: 192.168.1.160#53(192.168.1.160)
|
||||
```
|
||||
|
||||
### Client configuration
|
||||
### 客户端配置
|
||||
|
||||
The client configuration will be a lot simpler.
|
||||
客户端配置将简单得多。
|
||||
|
||||
Install the bind utilities:
|
||||
安装 bind 程序:
|
||||
|
||||
```
|
||||
$ sudo dnf install bind-utils -y
|
||||
```
|
||||
|
||||
Edit the /etc/resolv.conf file and configure the Master DNS as the only name server:
|
||||
编辑 `/etc/resolv.conf` 文件,并将主 DNS 配置为唯一的名称服务器:
|
||||
|
||||
```
|
||||
$ sudo vi /etc/resolv.conf
|
||||
```
|
||||
|
||||
This is how it should look:
|
||||
它看起来像这样:
|
||||
|
||||
```
|
||||
nameserver 192.168.1.160
|
||||
```
|
||||
|
||||
Save your changes and exit. Then, make the _/etc/resolv.conf_ file immutable to prevent it from be overwritten and going back to its default settings:
|
||||
保存更改并退出。然后,使 `/etc/resolv.conf` 文件不可变,防止其被覆盖并变回默认设置:
|
||||
|
||||
```
|
||||
$ sudo chattr +i /etc/resolv.conf
|
||||
```
|
||||
|
||||
#### Testing the client
|
||||
#### 测试客户端
|
||||
|
||||
You should get the same results as you did from the DNS server:
|
||||
你应该获得与 DNS 服务器相同的结果:
|
||||
|
||||
```
|
||||
$ dig fedoramagazine.org
|
||||
@ -367,9 +367,9 @@ $ dig fedoramagazine.org
|
||||
;; MSG SIZE rcvd: 266
|
||||
```
|
||||
|
||||
Make sure the SERVER output has the IP Address of your DNS server.
|
||||
确保 `SERVER` 输出的是你 DNS 服务器的 IP 地址。
|
||||
|
||||
Your DNS server is now ready to use and all requests from the client should be going through your DNS server now!
|
||||
你的 DNS 服务器设置完成了,现在所有来自客户端的请求都会经过你的 DNS 服务器了!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -377,8 +377,8 @@ via: https://fedoramagazine.org/how-to-setup-a-dns-server-with-bind/
|
||||
|
||||
作者:[Curt Warfield][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,146 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11960-1.html)
|
||||
[#]: subject: (Syncthing: Open Source P2P File Syncing Tool)
|
||||
[#]: via: (https://itsfoss.com/syncthing/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Syncthing:开源 P2P 文件同步工具
|
||||
======
|
||||
|
||||
> Syncthing 是一个开源的 P2P 文件同步工具,可用于在多个设备(包括 Android 手机)之间同步文件。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/05/094211oy2dosttvoaseovk.jpg)
|
||||
|
||||
通常,我们有 [MEGA][1] 或 Dropbox 之类的云同步解决方案,以便在云上备份我们的文件,同时更易于共享。但是,如果要跨多个设备同步文件而不将其存储在云中怎么办?
|
||||
|
||||
这就是 [Syncthing][2] 派上用场的地方了。
|
||||
|
||||
### Syncthing:一个跨设备同步文件的开源工具
|
||||
|
||||
![][3]
|
||||
|
||||
Syncthing 可让你跨多个设备同步文件(包括对 Android 智能手机的支持)。它主要通过 Linux 上的 Web UI 进行工作,但也提供了 GUI(需要单独安装)。
|
||||
|
||||
然而,Syncthing 完全没有利用云,它是 [P2P][4] 文件同步工具。你的数据不会被发送到中央服务器。而是会在所有设备之间同步。因此,它并不能真正取代 [Linux 上的典型云存储服务][5]。
|
||||
|
||||
要添加远程设备,你只需要设备 ID(或直接扫描二维码),而无需 IP 地址。
|
||||
|
||||
如果你想要远程备份文件,那么你可能应该依靠云。
|
||||
|
||||
![Syncthing GUI][6]
|
||||
|
||||
考虑到所有因素,Syncthing 可以在很多方面派上用场。从技术上讲,你可以安全、私密地在多个系统上访问重要文件,而不必担心有人监视你的数据。
|
||||
|
||||
例如,你可能不想在云上存储一些敏感文件,因此你可以添加其他受信任的设备来同步并保留这些文件的副本。
|
||||
|
||||
即使我对它的描述很简单,但它并不像看到的那么简单。如果你感兴趣的话,我建议你阅读[官方 FAQ][7] 来了解它如何工作的。
|
||||
|
||||
### Syncthing 的特性
|
||||
|
||||
你可能不希望同步工具中有很多选项。它要可靠地同步文件,应该非常简单。
|
||||
|
||||
Syncthing 确实非常简单且易于理解。即使这样,如果你想使用它的所有功能,那么也建议你阅读它的[文档][8]。
|
||||
|
||||
在这里,我将重点介绍 Syncthing 的一些有用特性:
|
||||
|
||||
#### 跨平台支持
|
||||
|
||||
![Syncthing on Android][9]
|
||||
|
||||
作为开源解决方案,它支持 Windows、Linux 和 macOS。
|
||||
|
||||
除此之外,它还支持 Android 智能手机。如果你使用的是 iOS 设备,那么你会感到失望。到目前为止,它还没有支持 iOS 的计划。
|
||||
|
||||
#### 文件版本控制
|
||||
|
||||
![Syncthing File Versioning][10]
|
||||
|
||||
如果替换或删除了旧文件,那么 Syncthing 会利用各种[文件版本控制方法][11]来存档旧文件。
|
||||
|
||||
默认情况下,你不会发现它启用。但是,当你创建一个要同步的文件夹时,你将找到将文件版本控制切换为首选方法的选项。
|
||||
|
||||
#### 易于使用
|
||||
|
||||
作为 P2P 文件同步工具,它无需高级调整即可使用。
|
||||
|
||||
但是,它允许你在需要时配置高级设置。
|
||||
|
||||
#### 安全和隐私
|
||||
|
||||
即使你不与任何云服务提供商共享数据,仍会有一些连接可能会引起窃听者的注意。因此,Syncthing 使用 TLS 保护通信。
|
||||
|
||||
此外,它还有可靠的身份验证方法,以确保仅授予只有你允许的设备/连接能够取得同步/读取数据的权限。
|
||||
|
||||
对于 Android 智能手机,如果你使用 [Orbot 应用][12],你还可以强制将流量通过 Tor。在 Android 中你还有几个不同选择。
|
||||
|
||||
#### 其他功能
|
||||
|
||||
![][13]
|
||||
|
||||
当你探索这个工具时,你会注意到可以同步的文件夹数和可同步的设备数没有限制。
|
||||
|
||||
因此,作为一个有着丰富有用特性的自由开源解决方案,对于在寻找 P2P 同步客户端的 Linux 用户而言是一个令人印象深刻的选择。
|
||||
|
||||
### 在 Linux 上安装 Syncthing
|
||||
|
||||
你可能无法在官网上找到 .deb 或者 .AppImage 文件。但是,你可在 [Snap 商店][14]中找到 snap 包。如果你好奇,你可以阅读在 Linux 上[使用 snap 应用][15]的文章来开始使用。
|
||||
|
||||
你可能无法在软件中心找到它(如果你找到了,那它可能不是最新版本)。
|
||||
|
||||
**注意:**如果你需要一个 GUI 应用而不是浏览器来管理它,它还有一个 [Syncthing-GTK][16]。
|
||||
|
||||
- [Syncthing][2]
|
||||
|
||||
如果你有基于 Debian 的发行版,你也可以利用终端来安装它,这些说明位于[官方下载页面][17]上。
|
||||
|
||||
### 我在 Syncthing 方面的体验
|
||||
|
||||
就个人而言,我把它安装在 Pop!_OS 19.10 上,并在写这篇文章之前用了一会儿。
|
||||
|
||||
我尝试同步文件夹、删除它们、添加重复文件以查看文件版本控制是否工作,等等。它工作良好。
|
||||
|
||||
然而,当我尝试同步它到手机(安卓),同步启动有点晚,它不是很快。因此,如果我们可以选择显式强制同步,那会有所帮助。或者,我错过了什么选项吗?如果是的话,请在评论中让我知道。
|
||||
|
||||
从技术上讲,它使用系统资源来工作,因此,如果你连接了多个设备进行同步,这可能会提高同步速度(上传/下载)。
|
||||
|
||||
总体而言,它工作良好,但我必须说,你不应该依赖它作为唯一的数据备份方案。
|
||||
|
||||
### 总结
|
||||
|
||||
你试过 Syncthing 了吗?如果有的话,你的体验如何?欢迎在下面的评论中分享。
|
||||
|
||||
此外,如果你知道一些不错的替代品,也请让我知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/syncthing/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/install-mega-cloud-storage-linux/
|
||||
[2]: https://syncthing.net/
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/syncthing-screenshot.jpg?ssl=1
|
||||
[4]: https://en.wikipedia.org/wiki/Peer-to-peer
|
||||
[5]: https://itsfoss.com/cloud-services-linux/
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/01/syncthing-gtk.png?ssl=1
|
||||
[7]: https://docs.syncthing.net/users/faq.html
|
||||
[8]: https://docs.syncthing.net/users/index.html
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/01/syncthing-android.jpg?ssl=1
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/syncthing-file-versioning.jpg?ssl=1
|
||||
[11]: https://docs.syncthing.net/users/versioning.html
|
||||
[12]: https://play.google.com/store/apps/details?id=org.torproject.android&hl=en_IN
|
||||
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/01/syncthing-screenshot1.jpg?ssl=1
|
||||
[14]: https://snapcraft.io/syncthing
|
||||
[15]: https://itsfoss.com/install-snap-linux/
|
||||
[16]: https://github.com/syncthing/syncthing-gtk/releases/latest
|
||||
[17]: https://syncthing.net/downloads/
|
@ -0,0 +1,142 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12004-1.html)
|
||||
[#]: subject: (6 things you should be doing with Emacs)
|
||||
[#]: via: (https://opensource.com/article/20/1/emacs-cheat-sheet)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
6 件你应该用 Emacs 做的事
|
||||
======
|
||||
|
||||
> 下面六件事情你可能都没有意识到可以在 Emacs 下完成。此外还有我们的新备忘单,拿去,充分利用 Emacs 的功能吧。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/17/133738wjj66p2safcpc50z.jpg)
|
||||
|
||||
想象一下使用 Python 的 IDLE 界面来编辑文本。你可以将文件加载到内存中,编辑它们,并保存更改。但是你执行的每个操作都由 Python 函数定义。例如,调用 `upper()` 来让一个单词全部大写,调用 `open` 打开文件,等等。文本文档中的所有内容都是 Python 对象,可以进行相应的操作。从用户的角度来看,这与其他文本编辑器的体验一致。对于 Python 开发人员来说,这是一个丰富的 Python 环境,只需在配置文件中添加几个自定义函数就可以对其进行更改和开发。
|
||||
|
||||
这就是 [Emacs][2] 对 1958 年的编程语言 [Lisp][3] 所做的事情。在 Emacs 中,运行应用程序的 Lisp 引擎与输入文本之间无缝结合。对 Emacs 来说,一切都是 Lisp 数据,因此一切都可以通过编程进行分析和操作。
|
||||
|
||||
这造就了一个强大的用户界面(UI)。但是,如果你是 Emacs 的普通用户,你可能对它的能力知之甚少。下面是你可能没有意识到 Emacs 可以做的六件事。
|
||||
|
||||
### 使用 Tramp 模式进行云端编辑
|
||||
|
||||
Emacs 早在网络流行化之前就实现了透明的网络编辑能力了,而且时至今日,它仍然提供了最流畅的远程编辑体验。Emacs 中的 [Tramp 模式][4](以前称为 RPC 模式)代表着 “<ruby>透明的远程(文件)访问,多协议<rt>Transparent Remote (file) Access,Multiple Protocol</rt></ruby>”,这准确说明了它提供的功能:通过最流行的网络协议轻松访问你希望编辑的远程文件。目前最流行、最安全的能用于远程编辑的协议是 [OpenSSH][5],因此 Tramp 使用它作为默认的协议。
|
||||
|
||||
在 Emacs 22.1 或更高版本中已经包含了 Tramp,因此要使用 Tramp,只需使用 Tramp 语法打开一个文件。在 Emacs 的 “File” 菜单中,选择 “Open File”。当在 Emacs 窗口底部的小缓冲区中出现提示时,使用以下语法输入文件名:
|
||||
|
||||
```
|
||||
/ssh:user@example.com:/path/to/file
|
||||
```
|
||||
|
||||
如果需要交互式登录,Tramp 会提示你输入密码。但是,Tramp 直接使用 OpenSSH,所以为了避免交互提示,你可以将主机名、用户名和 SSH 密钥路径添加到你的 `~/.ssh/config` 文件。与 Git 一样,Emacs 首先使用你的 SSH 配置,只有在出现错误时才会停下来询问更多信息。
|
||||
|
||||
Tramp 非常适合编辑并没有放在你的计算机上的文件,它的用户体验与编辑本地文件没有明显的区别。下次,当你 SSH 到服务器启动 Vim 或 Emacs 会话时,请尝试使用 Tramp。
|
||||
|
||||
### 日历
|
||||
|
||||
如果你喜欢文本多过图形界面,那么你一定会很高兴地知道,可以使用 Emacs 以纯文本的方式安排你的日程(或生活),而且你依然可以在移动设备上使用开源的 [Org 模式][6]查看器来获得华丽的通知。
|
||||
|
||||
这个过程需要一些配置,以创建一个方便的方式来与移动设备同步你的日程(我使用 Git,但你可以调用蓝牙、KDE Connect、Nextcloud,或其他文件同步工具),此外你必须在移动设备上安装一个 Org 模式查看器(如 [Orgzly][7])以及 Git 客户程序。但是,一旦你搭建好了这些基础,该流程就会与你常用的(或正在完善的,如果你是新用户)Emacs 工作流完美地集成在一起。你可以在 Emacs 中方便地查阅日程、更新日程,并专注于任务上。议程上的变化将会反映在移动设备上,因此即使在 Emacs 不可用的时候,你也可以保持井然有序。
|
||||
|
||||
![][8]
|
||||
|
||||
感兴趣了?阅读我的关于[使用 Org mode 和 Git 进行日程安排][9]的逐步指南。
|
||||
|
||||
### 访问终端
|
||||
|
||||
有[许多终端模拟器][10]可用。尽管 Emacs 中的 Elisp 终端仿真器不是最强大的通用仿真器,但是它有两个显著的优点:
|
||||
|
||||
1. **打开在 Emacs 缓冲区之中**:我使用 Emacs 的 Elisp shell,因为它在 Emacs 窗口中打开很方便,我经常全屏运行该窗口。这是一个小而重要的优势,只需要输入 `Ctrl+x+o`(或用 Emacs 符号来表示就是 `C-x o`)就能使用终端了,而且它还有一个特别好的地方在于当运行漫长的作业时能够一瞥它的状态报告。
|
||||
2. **在没有系统剪贴板的情况下复制和粘贴特别方便**:无论是因为懒惰不愿将手从键盘移动到鼠标,还是因为在远程控制台运行 Emacs 而无法使用鼠标,在 Emacs 中运行终端有时意味着可以从 Emacs 缓冲区中很快地传输数据到 Bash。
|
||||
|
||||
要尝试 Emacs 终端,输入 `Alt+x`(用 Emacs 符号表示就是 `M-x`),然后输入 `shell`,然后按回车。
|
||||
|
||||
### 使用 Racket 模式
|
||||
|
||||
[Racket][11] 是一种激动人心的新兴 Lisp 方言,拥有动态编程环境、GUI 工具包和充满激情的社区。学习 Racket 的默认编辑器是 DrRacket,它的顶部是定义面板,底部是交互面板。使用该设置,用户可以编写影响 Racket 运行时环境的定义。就像旧的 [Logo Turtle][12] 程序,但是有一个终端而不是仅仅一个海龟。
|
||||
|
||||
![Racket-mode][13]
|
||||
|
||||
*由 PLT 提供的 LGPL 示例代码*
|
||||
|
||||
基于 Lisp 的 Emacs 为资深 Racket 编程人员提供了一个很好的集成开发环境(IDE)。它尚未附带 [Racket 模式][14],但你可以使用 Emacs 包安装程序安装 Racket 模式和辅助扩展。要安装它,按下 `Alt+X`(用 Emacs 符号表示就是 `M-x`),键入 `package-install`,然后按回车。接着输入要安装的包 `racet-mode`,按回车。
|
||||
|
||||
使用 `M-x racket-mode` 进入 Racket 模式。如果你是 Racket 新手,而对 Lisp 或 Emacs 比较熟悉,可以从这份优秀的[图解 Racket][15] 入手。
|
||||
|
||||
## 脚本
|
||||
|
||||
你可能知道,Bash 脚本在自动化和增强 Linux 或 Unix 体验方面很流行。你可能听说过 Python 在这方面也做得很好。但是你知道 Lisp 脚本可以用同样的方式运行吗?有时人们会对 Lisp 到底有多有用感到困惑,因为许多人是通过 Emacs 来了解 Lisp 的,因此有一种潜在的印象,即在 21 世纪运行 Lisp 的惟一方法是在 Emacs 中运行。幸运的是,事实并非如此,Emacs 是一个很好的 IDE,它支持将 Lisp 脚本作为一般的系统可执行文件来运行。
|
||||
|
||||
除了 Elisp 之外,还有两种流行的现代 Lisp 可以很容易地用来作为独立脚本运行。
|
||||
|
||||
1. **Racket**:你可以通过在系统上运行 Racket 来提供运行 Racket 脚本所需的运行时支持,或者你可以使用 `raco exe` 产生一个可执行文件。`raco exe` 命令将代码和运行时支持文件一起打包,以创建可执行文件。然后,`raco distribution` 命令将可执行文件打包成可以在其他机器上工作的发行版。Emacs 有许多 Racket 工具,因此在 Emacs 中创建 Racket 文件既简单又有效。
|
||||
2. **GNU Guile**:[GNU Guile][16](<ruby>GNU 通用智能语言扩展<rt>GNU Ubiquitous Intelligent Language for Extensions</rt></ruby> 的缩写)是 [Scheme][17] 编程语言的一个实现,它可以用于为桌面、互联网、终端等创建应用程序和游戏。Emacs 中的 Scheme 扩展众多,使用任何一个扩展来编写 Scheme 都很容易。例如,这里有一个用 Guile 编写的 “Hello world” 脚本:
|
||||
|
||||
```
|
||||
#!/usr/bin/guile -s
|
||||
!#
|
||||
|
||||
(display "hello world")
|
||||
(newline)
|
||||
```
|
||||
|
||||
用 `guile` 编译并允许它:
|
||||
|
||||
```
|
||||
$ guile ./hello.scheme
|
||||
;;; compiling /home/seth/./hello.scheme
|
||||
;;; compiled [...]/hello.scheme.go
|
||||
hello world
|
||||
$ guile ./hello.scheme
|
||||
hello world
|
||||
```
|
||||
|
||||
### 无需 Emacs 允许 Elisp
|
||||
|
||||
Emacs 可以作为 Elisp 的运行环境,但是你无需按照传统印象中的必须打开 Emacs 来运行 Elisp。`--script` 选项可以让你使用 Emacs 作为引擎来执行 Elisp 脚本,而无需运行 Emacs 图形界面(甚至也无需使用终端)。下面这个例子中,`-Q` 选项让 Emacs 忽略 `.emacs` 文件,从而避免由于执行 Elisp 脚本时产生延迟(若你的脚本依赖于 Emacs 配置中的内容,那么请忽略该选项)。
|
||||
|
||||
```
|
||||
emacs -Q --script ~/path/to/script.el
|
||||
```
|
||||
|
||||
### 下载 Emacs 备忘录
|
||||
|
||||
Emacs 许多重要功能都不是只能通过 Emacs 来实现的;Org 模式是 Emacs 扩展也是一种格式标准,流行的 Lisp 方言大多不依赖于具体的应用,我们甚至可以在没有可见或可交互式 Emacs 实例的情况下编写和运行 Elisp。然后若你对为什么模糊代码和数据之间的界限能够引发创新和效率感到好奇的话,那么 Emacs 是一个很棒的工具。
|
||||
|
||||
幸运的是,现在是 21 世纪,Emacs 有了带有传统菜单的图形界面以及大量的文档,因此学习曲线不再像以前那样。然而,要最大化 Emacs 对你的好处,你需要学习它的快捷键。由于 Emacs 支持的每个任务都是一个 Elisp 函数,Emacs 中的任何功能都可以对应一个快捷键,因此要描述所有这些快捷键是不可能完成的任务。你只要学习使用频率 10 倍于不常用功能的那些快捷键即可。
|
||||
|
||||
我们汇聚了最常用的 Emacs 快捷键成为一份 Emacs 备忘录以便你查询。将它挂在屏幕附近或办公室墙上,把它作为鼠标垫也行。让它触手可及经常翻阅一下。每次翻两下可以让你获得十倍的学习效率。而且一旦开始编写自己的函数,你一定不会后悔获取了这个免费的备忘录副本的!
|
||||
|
||||
- [这里下载 Emacs 备忘录(需注册)](https://opensource.com/downloads/emacs-cheat-sheet)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
via: https://opensource.com/article/20/1/emacs-cheat-sheet
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[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/browser_blue_text_editor_web.png
|
||||
[2]: https://www.gnu.org/software/emacs/
|
||||
[3]: https://en.wikipedia.org/wiki/Lisp_(programming_language)
|
||||
[4]: https://www.gnu.org/software/tramp/
|
||||
[5]: https://www.openssh.com/
|
||||
[6]: https://orgmode.org/
|
||||
[7]: https://f-droid.org/en/packages/com.orgzly/
|
||||
[8]: https://opensource.com/sites/default/files/uploads/orgzly-agenda.jpg
|
||||
[9]: https://linux.cn/article-11320-1.html
|
||||
[10]: https://linux.cn/article-11814-1.html
|
||||
[11]: http://racket-lang.org/
|
||||
[12]: https://en.wikipedia.org/wiki/Logo_(programming_language)#Turtle_and_graphics
|
||||
[13]: https://opensource.com/sites/default/files/racket-mode.jpg
|
||||
[14]: https://www.racket-mode.com/
|
||||
[15]: https://docs.racket-lang.org/quick/index.html
|
||||
[16]: https://www.gnu.org/software/guile/
|
||||
[17]: https://en.wikipedia.org/wiki/Scheme_(programming_language)
|
@ -1,63 +1,63 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11964-1.html)
|
||||
[#]: subject: (Build your own cloud with Fedora 31 and Nextcloud Server)
|
||||
[#]: via: (https://fedoramagazine.org/build-your-own-cloud-with-fedora-31-and-nextcloud-server/)
|
||||
[#]: author: (storyteller https://fedoramagazine.org/author/storyteller/)
|
||||
|
||||
Build your own cloud with Fedora 31 and Nextcloud Server
|
||||
使用 Fedora 31 和 Nextcloud 服务器构建自己的云
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
[Nextcloud][2] is a software suite for storing and syncing your data across multiple devices. You can learn more about Nextcloud Server’s features from [https://github.com/nextcloud/server][3].
|
||||
[Nextcloud][2] 是用于跨多个设备存储和同步数据的软件套件。你可以从 [https://github.com/nextcloud/server][3] 了解有关 Nextcloud 服务器的更多特性信息。
|
||||
|
||||
This article demonstrates how to build a personal cloud using Fedora and Nextcloud in a few simple steps. For this tutorial you will need a dedicated computer or a virtual machine running Fedora 31 server edition and an internet connection.
|
||||
本文通过几个简单的步骤演示了如何使用 Fedora 和 Nextcloud 构建个人云。对于本教程,你将需要一台独立计算机或运行 Fedora 31 服务器版的虚拟机,还需要互联网连接。
|
||||
|
||||
### Step 1: Install the prerequisites
|
||||
### 步骤 1:预先安装条件
|
||||
|
||||
Before installing and configuring Nextcloud, a few prerequisites must be satisfied.
|
||||
在安装和配置 Nextcloud 之前,必须满足一些预先条件。
|
||||
|
||||
First, install Apache web server:
|
||||
首先,安装 Apache Web 服务器:
|
||||
|
||||
```
|
||||
# dnf install httpd
|
||||
```
|
||||
|
||||
Next, install PHP and some additional modules. Make sure that the PHP version being installed meets [Nextcloud’s requirements][4]:
|
||||
接下来,安装 PHP 和一些其他模块。确保所安装的 PHP 版本符合 [Nextcloud 的要求][4]:
|
||||
|
||||
```
|
||||
# dnf install php php-gd php-mbstring php-intl php-pecl-apcu php-mysqlnd php-pecl-redis php-opcache php-imagick php-zip php-process
|
||||
```
|
||||
|
||||
After PHP is installed enable and start the Apache web server:
|
||||
安装 PHP 后,启用并启动 Apache Web 服务器:
|
||||
|
||||
```
|
||||
# systemctl enable --now httpd
|
||||
```
|
||||
|
||||
Next, allow _HTTP_ traffic through the firewall:
|
||||
接下来,允许 HTTP 流量穿过防火墙:
|
||||
|
||||
```
|
||||
# firewall-cmd --permanent --add-service=http
|
||||
# firewall-cmd --reload
|
||||
```
|
||||
|
||||
Next, install the MariaDB server and client:
|
||||
接下来,安装 MariaDB 服务器和客户端:
|
||||
|
||||
```
|
||||
# dnf install mariadb mariadb-server
|
||||
```
|
||||
|
||||
Then enable and start the MariaDB server:
|
||||
然后启用并启动 MariaDB 服务器
|
||||
|
||||
```
|
||||
# systemctl enable --now mariadb
|
||||
```
|
||||
|
||||
Now that MariaDB is running on your server, you can run the _mysql_secure_installation_ command to secure it:
|
||||
现在,MariaDB 正在运行,你可以运行 `mysql_secure_installation` 命令来保护它:
|
||||
|
||||
```
|
||||
# mysql_secure_installation
|
||||
@ -128,7 +128,7 @@ MariaDB installation should now be secure.
|
||||
Thanks for using MariaDB!
|
||||
```
|
||||
|
||||
Next, create a dedicated user and database for your Nextcloud instance:
|
||||
接下来,为你的 Nextcloud 实例创建独立的用户和数据库:
|
||||
|
||||
```
|
||||
# mysql -p
|
||||
@ -139,23 +139,23 @@ Next, create a dedicated user and database for your Nextcloud instance:
|
||||
> exit;
|
||||
```
|
||||
|
||||
### Step 2: Install Nextcloud Server
|
||||
### 步骤 2:安装 Nextcloud 服务器
|
||||
|
||||
Now that the prerequisites for your Nextcloud installation have been satisfied, download and unzip [the Nextcloud archive][5]:
|
||||
现在,你已满足 Nextcloud 安装的预先条件,请下载并解压 [Nextcloud 压缩包][5]:
|
||||
|
||||
```
|
||||
# wget https://download.nextcloud.com/server/releases/nextcloud-17.0.2.zip
|
||||
# unzip nextcloud-17.0.2.zip -d /var/www/html/
|
||||
```
|
||||
|
||||
Next, create a data folder and grant Apache read and write access to the _nextcloud_ directory tree:
|
||||
接下来,创建一个数据文件夹,并授予 Apache 对 `nextcloud` 目录树的读写访问权限:
|
||||
|
||||
```
|
||||
# mkdir /var/www/html/nextcloud/data
|
||||
# chown -R apache:apache /var/www/html/nextcloud
|
||||
```
|
||||
|
||||
SELinux must be configured to work with Nextcloud. The basic commands are those bellow, but a lot more, by features used on nexcloud installation, are posted here: [Nextcloud SELinux configuration][6]
|
||||
SELinux 必须配置为可与 Nextcloud 一起使用。基本命令如下所示,但在 nexcloud 安装中还有很多其他的命令,发布在这里:[Nextcloud SELinux 配置][6]。
|
||||
|
||||
```
|
||||
# semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/nextcloud/config(/.*)?'
|
||||
@ -166,34 +166,32 @@ SELinux must be configured to work with Nextcloud. The basic commands are those
|
||||
# restorecon -Rv '/var/www/html/nextcloud/'
|
||||
```
|
||||
|
||||
### Step 3: Configure N**extclou**d
|
||||
### 步骤 3:配置 Nextcloud
|
||||
|
||||
Nextcloud can be configured using its web interface or from the command line.
|
||||
可以使用它的 Web 界面或在命令行配置 Nextcloud。
|
||||
|
||||
#### Using the web interface
|
||||
#### 使用 Web 界面
|
||||
|
||||
From your favorite browser, access _<http://your\_server\_ip/nextcloud>_ and fill the fields:
|
||||
在你喜欢的浏览器中,访问 <http://your\_server\_ip/nextcloud> 并输入字段:
|
||||
|
||||
![][7]
|
||||
|
||||
#### Using the command line
|
||||
#### 使用命令行
|
||||
|
||||
From the command line, just enter the following, substituting the values you used when you created a dedicated Nextcloud user in MariaDB earlier:
|
||||
在命令行中,只需输入以下内容,使用你之前在 MariaDB 中创建的独立 Nextcloud 用户替换相应的值:
|
||||
|
||||
```
|
||||
# sudo -u apache php occ maintenance:install --data-dir /var/www/html/nextcloud/data/ --database "mysql" --database-name "nextcloud" --database-user "nc_admin" --database-pass "DB_SeCuRe_PaSsWoRd" --admin-user "admin" --admin-pass "Admin_SeCuRe_PaSsWoRd"
|
||||
```
|
||||
|
||||
### Final Notes
|
||||
### 最后几点
|
||||
|
||||
* I used the _http_ protocol, but Nextcloud also works over _https_. I might write a follow-up about securing Nextcloud in a future article.
|
||||
* I disabled SELinux, but your server will be more secure if you configure it.
|
||||
* The recommend PHP memory limit for Nextcloud is 512M. To change it, edit the _memory_limit_ variable in the _/etc/php.ini_ configuration file and restart your _httpd_ service.
|
||||
* By default, the web interface can only be accessed using the _<http://localhost/>_ URL. If you want to allow access using other domain names, [you can do so by editing the _/var/www/html/nextcloud/config/config.php_ file][8]. The * character can be used to bypass the domain name restriction and allow the use of any URL that resolves to one of your server’s IP addresses.
|
||||
* 我使用的是 http 协议,但是 Nextcloud 也可以在 https 上运行。我可能会在以后的文章中写一篇有关保护 Nextcloud 的文章。
|
||||
* 我禁用了 SELinux,但是如果配置它,你的服务器将更加安全。
|
||||
* Nextcloud 的建议 PHP 内存限制为 512M。要更改它,请编辑 `/etc/php.ini` 配置文件中的 `memory_limit` 变量,然后重新启动 httpd 服务。
|
||||
* 默认情况下,只能使用 <http://localhost/> URL 访问 Web 界面。如果要允许使用其他域名访问,[你可编辑 /var/www/html/nextcloud/config/config.php 来进行此操作][8]。`*` 字符可用于绕过域名限制,并允许任何解析为服务器 IP 的 URL 访问。
|
||||
|
||||
|
||||
|
||||
```
|
||||
```
|
||||
'trusted_domains' =>
|
||||
array (
|
||||
0 => 'localhost',
|
||||
@ -201,16 +199,14 @@ From the command line, just enter the following, substituting the values you use
|
||||
),
|
||||
```
|
||||
|
||||
_— Updated on January 28th, 2020 to include SELinux configuration —_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/build-your-own-cloud-with-fedora-31-and-nextcloud-server/
|
||||
|
||||
作者:[storyteller][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,163 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11956-1.html)
|
||||
[#]: subject: (Use Emacs to get social and track your todo list)
|
||||
[#]: via: (https://opensource.com/article/20/1/emacs-social-track-todo-list)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
使用 Emacs 进行社交并跟踪你的待办事项列表
|
||||
======
|
||||
|
||||
> 在 2020 年用开源实现更高生产力的二十种方式的第十九篇文章中,访问 Twitter、Reddit、 交谈、电子邮件 、RSS 和你的待办事项列表。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/04/100911lg2vrv92692b422y.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 使用 Emacs 做(几乎)所有的事情,第 2 部分
|
||||
|
||||
[昨天][2],我谈到了如何在 Emacs 中读取电子邮件、访问电子邮件地址和显示日历。Emacs 功能繁多,你还可以将它用于 Twitter、交谈、待办事项列表等等!
|
||||
|
||||
![在 Emacs 中处理所有事情][3]
|
||||
|
||||
要完成所有这些,你需要安装一些 Emacs 包。和昨天一样,用 `Meta+x package-manager` 打开 Emacs 包管理器(Meta 键在大多数键盘上是 `Alt`,在 MacOS 上是 `Option`)。然后通过 `i` 选择以下带有的软件包,然后输入 `x` 进行安装:
|
||||
|
||||
```
|
||||
nnreddit
|
||||
todotxt
|
||||
twittering-mode
|
||||
```
|
||||
|
||||
安装之后,按下 `Ctrl+x ctrl+f` 打开 `~/.emacs.d/init.el`,并在 `(custom-set-variables` 行前加上:
|
||||
|
||||
```
|
||||
;; Todo.txt
|
||||
(require 'todotxt)
|
||||
(setq todotxt-file (expand-file-name "~/.todo/todo.txt"))
|
||||
|
||||
;; Twitter
|
||||
(require 'twittering-mode)
|
||||
(setq twittering-use-master-password t)
|
||||
(setq twittering-icon-mode t)
|
||||
|
||||
;; Python3 for nnreddit
|
||||
(setq elpy-rpc-python-command "python3")
|
||||
```
|
||||
|
||||
按下 `Ctrl+x Ctrl+s` 保存文件,使用 `Ctrl+x Ctrl+c` 退出 Emacs,然后重启 Emacs。
|
||||
|
||||
#### 使用 twittering-mode 在 Emacs 中发推
|
||||
|
||||
![Emacs 中的 Twitter][4]
|
||||
|
||||
[Twittering-mode][5] 是 Twitter 最好的 Emacs 接口之一。它几乎支持 Twitter 的所有功能,并且键盘快捷键也易于使用。
|
||||
|
||||
首先,输入 `Meta+x twit` 来启动 twittering-mode。它会提供一个 URL 并提示你启动浏览器来访问它,你登录该 URL 后就能获得授权令牌。将令牌复制并粘贴到 Emacs 中,你的 Twitter 时间线就会加载了。你可以使用箭头键滚动,使用 `Tab` 从一个项目移动到另一个项目,并按回车访问光标所在的 URL。如果光标在用户名上,按回车将在 web 浏览器中打开时间轴。如果你在一条推文的文本上,按回车将回复该推文。你可以用 `u` 创建一个新的推文,用 `Ctrl+c+Enter` 转发一些内容,然后用 `d` 发送一条即时消息——它打开的对话框中有关于如何发送、取消和缩短 URL 的说明。
|
||||
|
||||
按 `V` 会打开一个提示让你跳转到其他时间线。输入 `:mentions` 打开你的提及。输入 `:home` 打开你的主时间线,输入用户名将进入该用户的时间线。最后,按 `q` 会退出 twittering-mode 并关闭窗口。
|
||||
|
||||
twitter-mode 还有更多功能,我鼓励你阅读它 GitHub 页面上的[完整功能列表][6]。
|
||||
|
||||
#### 在 Emacs 上使用 Todotxt.el 追踪你的待办事项
|
||||
|
||||
![Emacs 中的 todo.txt][7]
|
||||
|
||||
[Todotxt.el][8] 是一个很棒的 [todo.txt][9] 待办列表管理器接口。它的快捷键几乎无所不包。
|
||||
|
||||
输入 `Meta+x todotxt` 启动它将加载 `todotxt-file` 变量中指定的 `todo.txt` 文件(本文的第一部分中设置了该文件)。在 `todo.txt` 的缓冲区(窗口),你可以按 `a` 添加新任务并和按 `c` 标记它已被完成。你还可以使用 `r` 设置优先级,并使用 `t` 添加项目和上下文。完成事项后只需要按下 `A` 即可将任务移如 `done.txt`。你可以使用 `/` 过滤列表,也可以使用 `l` 刷新完整列表。同样,你可以按 `q` 退出。
|
||||
|
||||
#### 在 Emacs 中使用 ERC 进行交谈
|
||||
|
||||
![使用 ERC 与人交谈 ][10]
|
||||
|
||||
Vim 的缺点之一是很难用它与人交谈。另一方面,Emacs 则将 [ERC][11] 客户端内置到默认发行版中。使用 `Meta+x ERC` 启动 ERC,系统将提示你输入服务器、用户名和密码。你可以使用几天前介绍设置 [BitlBee][12] 时使用的相同信息:服务器为 `localhost`,端口为 `6667`,相同用户名,无需密码。
|
||||
|
||||
ERC 使用起来与其他 IRC 客户端一样。每个频道单独一个缓冲区(窗口),你可以使用 `Ctrl+x ctrl+b` 进行频道间切换,这也可以在 Emacs 中的其他缓冲区之间进行切换。`/quit` 命令将退出 ERC。
|
||||
|
||||
#### 使用 Gnus 阅读电子邮件,Reddit 和 RSS
|
||||
|
||||
![Mail,Reddit,and RSS feeds with Gnus][13]
|
||||
|
||||
我相信昨天在我提及在 Emacs 中阅读邮件时,许多 Emacs 的老用户会问,“怎么没有 [Gnus][14] 呢?”
|
||||
|
||||
这个疑问很合理。Gnus 是一个内置在 Emacs 中的邮件和新闻阅读器,尽管它这个邮件阅读器不支持以 [Notmuch][15] 作为搜索引擎。但是,如果你将其配置来阅读 Reddit 和 RSS feed(稍后你将这样做),那么同时使用它来阅读邮件是个聪明的选择。
|
||||
|
||||
Gnus 是为阅读 Usenet 新闻而创建的,并从此发展而来。因此,它的很多外观和感觉(以及术语)看起来很像 Usenet 的新闻阅读器。
|
||||
|
||||
Gnus 以 `~/.gnus` 作为自己的配置文件。(该配置也可以包含在 `~/.emacs.d/init.el` 中)。使用 `Ctrl+x Ctrl+f` 打开 `~/.gnus`,并添加以下内容:
|
||||
|
||||
|
||||
```
|
||||
;; Required packages
|
||||
(require 'nnir)
|
||||
(require 'nnrss)
|
||||
|
||||
;; Primary Mailbox
|
||||
(setq gnus-select-method
|
||||
'(nnmaildir "Local"
|
||||
(directory "~/Maildir")
|
||||
(nnir-search-engine notmuch)
|
||||
))
|
||||
(add-to-list 'gnus-secondary-select-methods
|
||||
'(nnreddit ""))
|
||||
```
|
||||
|
||||
用 `Ctrl+x Ctrl+s` 保存文件。这分配置告诉 Gnus 从 `~/Maildir` 这个本地邮箱中读取邮件作为主源(参见 `gnus-select-method` 变量),并使用 [nnreddit][16] 插件添加辅源(`gnus-secondary-select-methods` 变量)。你还可以定义多个辅助源,包括 Usenet 新闻(nntp)、IMAP (nnimap)、mbox(nnmbox)和虚拟集合(nnvirtual)。你可以在 [Gnus 手册][17] 中了解更多有关所有选项的信息。
|
||||
|
||||
保存文件后,使用 `Meta+x Gnus` 启动 Gnus。第一次运行将在 Python 虚拟环境中安装 [Reddit 终端查看器][18],Gnus 通过它获取 Reddit 上的文章。然后它会启动浏览器来登录 Reddit。之后,它会扫描并加载你订阅的 Reddit 群组。你会看到一个有新邮件的邮件夹列表和一个有新内容的看板列表。在任一列表上按回车将加载该组中的消息列表。你可以使用箭头键导航并按回车加载和读取消息。在查看消息列表时,按 `q` 将返回到前一个视图,从主窗口按 `q` 将退出 Gnus。在阅读 Reddit 群组时,`a` 会创建一条新消息;在邮件组中,`m` 创建一个新的电子邮件;并且在任何一个视图中按 `r` 回复邮件。
|
||||
|
||||
你还可以向 Gnus 接口中添加 RSS 流,并像阅读邮件和新闻组一样阅读它们。要添加 RSS 流,输入 `G+R` 并填写 RSS 流的 URL。会有提示让你输入 RSS 的标题和描述,这些信息可以从流中提取出来并填充进去。现在输入 `g` 来检查新消息(这将检查所有组中的新消息)。阅读 RSS 流 就像阅读 Reddit 群组和邮件一样,它们使用相同的快捷键。
|
||||
|
||||
Gnus 中有*很多*功能,还有大量的键组合。[Gnus 参考卡][19]为每个视图列出了所有这些键组合(以非常小的字体显示在 5 页纸上)。
|
||||
|
||||
#### 使用 nyan-mode 查看位置
|
||||
|
||||
最后,你可能会一些截屏底部注意到 [Nyan cat][20]。这是 [nyan-mode][21],它指示了你在缓冲区中的位置,因此当你接近文档或缓冲区的底部时,它会变长。你可以使用包管理器安装它,并在 `~/.emacs.d/init.el` 中使用以下代码进行设置:
|
||||
|
||||
```
|
||||
;; Nyan Cat
|
||||
(setq nyan-wavy-trail t)
|
||||
(setq nyan-bar-length 20)
|
||||
(nyan-mode)
|
||||
```
|
||||
|
||||
### Emacs 的基本功能
|
||||
|
||||
这只是 Emacs 所有功能的皮毛。Emacs *非常*强大,是我用来提高工作效率的必要工具之一,无论我是在追踪待办事项、阅读和回复邮件、编辑文本,还是与朋友和同事交流我都用它。这需要一点时间来适应,但是一旦你习惯了,它就会成为你桌面上最有用的工具之一。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/emacs-social-track-todo-list
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_team_mobile_desktop.png?itok=d7sRtKfQ (Team communication, chat)
|
||||
[2]: https://linux.cn/article-11932-1.html
|
||||
[3]: https://opensource.com/sites/default/files/uploads/productivity_19-1.png (All the things with Emacs)
|
||||
[4]: https://opensource.com/sites/default/files/uploads/productivity_19-2.png (Twitter in Emacs)
|
||||
[5]: https://github.com/hayamiz/twittering-mode
|
||||
[6]: https://github.com/hayamiz/twittering-mode#features
|
||||
[7]: https://opensource.com/sites/default/files/uploads/productivity_19-3.png (todo.txt in emacs)
|
||||
[8]: https://github.com/rpdillon/todotxt.el
|
||||
[9]: http://todotxt.org/
|
||||
[10]: https://opensource.com/sites/default/files/uploads/productivity_19-4.png (Chatting with erc)
|
||||
[11]: https://www.gnu.org/software/emacs/manual/html_mono/erc.html
|
||||
[12]: https://linux.cn/article-11856-1.html
|
||||
[13]: https://opensource.com/sites/default/files/uploads/productivity_19-5.png (Mail, Reddit, and RSS feeds with Gnus)
|
||||
[14]: https://www.gnus.org/
|
||||
[15]: https://linux.cn/article-11807-1.html
|
||||
[16]: https://github.com/dickmao/nnreddit
|
||||
[17]: https://www.gnus.org/manual/gnus.html
|
||||
[18]: https://pypi.org/project/rtv/
|
||||
[19]: https://www.gnu.org/software/emacs/refcards/pdf/gnus-refcard.pdf
|
||||
[20]: http://www.nyan.cat/
|
||||
[21]: https://github.com/TeMPOraL/nyan-mode
|
@ -0,0 +1,99 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11961-1.html)
|
||||
[#]: subject: (4 open source productivity tools on my wishlist)
|
||||
[#]: via: (https://opensource.com/article/20/1/open-source-productivity-tools)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||
|
||||
我的愿望清单上的 4 种开源生产力工具
|
||||
======
|
||||
|
||||
> 在 2020 年用开源实现更高生产力的二十种方式的最后一篇文章中,了解开源世界还需要什么。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/05/100642k52u7oydcwnc1c2w.jpg)
|
||||
|
||||
去年,我在 19 天里给你介绍了 19 个新(对你而言)的生产力工具。今年,我换了一种方式:使用你在使用或者还没使用的工具,构建一个使你可以在新一年更加高效的环境。
|
||||
|
||||
### 然而…
|
||||
|
||||
在搜索生产力应用程序时,我找不到想要的所有应用,而且几乎总是会丢失一些读者与我分享的精彩内容。 因此,当我结束本系列文章时,是时候[再次][2]谈论我在本年度系列文章中未能涵盖的一些主题。
|
||||
|
||||
![Desktop with Joplin, Emacs, and Firefox][3]
|
||||
|
||||
#### 在 Vim 中聊天
|
||||
|
||||
我试过了。我真的非常、非常想能够在 Vim 中聊天,但我做不到。我找到的一个软件包 [VimIRC.vim][4] 一直就工作不起来,我试了几天也没用。我探索的另一个选项是 [Irc it][5],这需要我付出更多的[努力去设置][6],超过了我正常可以付出的耐心或时间。我尝试过了,也确实做到了,但对于同处于相同境地的 Vim 用户,对不起,我无法帮到你。
|
||||
|
||||
#### Org 模式
|
||||
|
||||
![Org Mode in Emacs][7]
|
||||
|
||||
我喜欢 [Org 模式][8],并且每天都使用它。关于 Org 模式我可以滔滔不绝的说上几天。它提供了基本的[任务跟踪][9];谷歌[日历][10]同步和 [CalFW][11] 集成;富文本文档、网站和演示文稿;链接到任何事物;等等、等等……
|
||||
|
||||
我希望你会在 2020 年从我这里收到更多有关 Org 模式的信息,因为它真的很酷。
|
||||
|
||||
#### 图形用户界面程序
|
||||
|
||||
在 2019 年的生产力系列中,我共享了很多图形用户界面程序,而今年几乎都是命令行应用程序。有一些很棒的图形程序可以帮助解决我今年谈论的一些问题,例如可以使用 Maildir 邮箱的[邮件][12]程序、用于读取本地日历文件的日历程序、[天气][13]应用程序等等。我甚至尝试了几项对我而言新奇的事物,看它们是否适合这个主题。除了 [twin][14] 之外,我没有感觉到有什么图形用户界面程序是新颖的(对我而言)或值得注意的(同样对我而言)是今年要写的。至于……
|
||||
|
||||
#### 移动应用程序
|
||||
|
||||
越来越多的人将平板电脑(有时与笔记本电脑结合使用)作为主要设备。我将手机用于大多数社交媒体和即时消息传递,并且经常使用平板电脑(好的,老实说,好几个平板电脑)来阅读或浏览网络。可以肯定的是,并不是没有开源移动应用程序,但是它们与我今年的主题不符。开源和移动应用程序正在发生很多变化,我正在仔细地寻找可以帮助我在手机和平板电脑上提高工作效率的事物。
|
||||
|
||||
### 该你了
|
||||
|
||||
非常感谢你阅读今年的系列文章。请你发表评论,告诉我错过的或需要在 2021 年看到的内容。正如我在 [Productivity Alchemy][15] 播客上所说:“哥们,记着:要保持生产力!”
|
||||
|
||||
### 本系列汇总
|
||||
|
||||
1. [使用 Syncthing 在多个设备间同步文件](https://linux.cn/article-11793-1.html)
|
||||
2. [使用 Stow 管理多台机器配置](https://linux.cn/article-11796-1.html)
|
||||
3. [使用 OfflineIMAP 同步邮件](https://linux.cn/article-11804-1.html)
|
||||
4. [使用 Notmuch 组织你的邮件](https://linux.cn/article-11807-1.html)
|
||||
5. [使用 khal 和 vdirsyncer 组织和同步你的日历](https://linux.cn/article-11812-1.html)
|
||||
6. [用于联系人管理的三个开源工具](https://linux.cn/article-11834-1.html)
|
||||
7. [开始使用开源待办事项清单管理器](https://linux.cn/article-11835-1.html)
|
||||
8. [使用这个 Python 程序记录你的活动](https://linux.cn/article-11846-1.html)
|
||||
9. [一个通过 IRC 管理所有聊天的开源聊天工具](https://linux.cn/article-11856-1.html)
|
||||
10. [使用这个 Twitter 客户端在 Linux 终端中发推特](https://linux.cn/article-11858-1.html)
|
||||
11. [在 Linux 终端中阅读 Reddit](https://linux.cn/article-11869-1.html)
|
||||
12. [使用此开源工具在一起收取你的 RSS 订阅源和播客](https://linux.cn/article-11876-1.html)
|
||||
13. [使用这个开源工具获取本地天气预报](https://linux.cn/article-11879-1.html)
|
||||
14. [使用此开源窗口环境一次运行多个控制台](https://linux.cn/article-11892-1.html)
|
||||
15. [使用 tmux 创建你的梦想主控台](https://linux.cn/article-11900-1.html)
|
||||
16. [使用 Vim 发送邮件和检查日历](https://linux.cn/article-11908-1.html)
|
||||
17. [使用 Vim 管理任务列表和访问 Reddit 和 Twitter](https://linux.cn/article-11912-1.html)
|
||||
18. [使用 Emacs 发送电子邮件和检查日历](https://linux.cn/article-11932-1.html)
|
||||
19. [使用 Emacs 进行社交并跟踪你的待办事项列表](https://linux.cn/article-11956-1.html)
|
||||
20. [我的愿望清单上的 4 种开源生产力工具](https://linux.cn/article-11961-1.html)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/1/open-source-productivity-tools
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/world_hands_diversity.png?itok=zm4EDxgE (Two diverse hands holding a globe)
|
||||
[2]: https://opensource.com/article/19/1/productivity-tool-wish-list
|
||||
[3]: https://opensource.com/sites/default/files/uploads/productivity_20-1.png (Desktop with Joplin, Emacs, and Firefox)
|
||||
[4]: https://github.com/vim-scripts/VimIRC.vim
|
||||
[5]: https://tools.suckless.org/ii/
|
||||
[6]: https://www.reddit.com/r/vim/comments/48t7ws/vim_ii_irc_client_xpost_runixporn/d0macnl/
|
||||
[7]: https://opensource.com/sites/default/files/uploads/productivity_20-2.png (Org Mode in Emacs)
|
||||
[8]: https://orgmode.org/
|
||||
[9]: https://opensource.com/article/20/1/open-source-to-do-list
|
||||
[10]: https://opensource.com/article/20/1/open-source-calendar
|
||||
[11]: https://github.com/kiwanami/emacs-calfw
|
||||
[12]: https://opensource.com/article/20/1/organize-email-notmuch
|
||||
[13]: https://opensource.com/article/20/1/open-source-weather-forecast
|
||||
[14]: https://github.com/cosmos72/twin
|
||||
[15]: https://productivityalchemy.com
|
@ -0,0 +1,160 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "messon007"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-12031-1.html"
|
||||
[#]: subject: "DevOps vs Agile: What's the difference?"
|
||||
[#]: via: "https://opensource.com/article/20/2/devops-vs-agile"
|
||||
[#]: author: "Taz Brown https://opensource.com/users/heronthecli"
|
||||
|
||||
DevOps 和敏捷:究竟有什么区别?
|
||||
======
|
||||
|
||||
> 两者之间的区别在于开发完毕之后发生的事情。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/23/200609w2rlzrjjhpf2hzsq.jpg)
|
||||
|
||||
早期,软件开发并没有特定的管理流程。随后出现了<ruby>[瀑布开发流程][2]<rt>Waterfall</rt></ruby>,它提出软件开发活动可以用开发和构建应用所耗费的时间来定义。
|
||||
|
||||
那时候,由于在开发流程中没有审查环节和权衡考虑,常常需要花费很长的时间来开发、测试和部署软件。交付的软件也是带有缺陷和 Bug 的质量较差的软件,而且交付时间也不满足要求。那时候软件项目管理的重点是长期而拖沓的计划。
|
||||
|
||||
瀑布流程与<ruby>[三重约束模型][3]<rt>triple constraint model</rt></ruby>相关,三重约束模型也称为<ruby>项目管理三角形<rt>project management triangle</rt></ruby>。三角形的每一个边代表项目管理三要素的一个要素: **范围、时间和成本**。正如 [Angelo Baretta 写到][4],三重约束模型“认为成本是时间和范围的函数,这三个约束以一种确定的、可预测的方式相互作用。……如果我们想缩短时间表(时间),就必须增加成本。如果我们想增加范围,就必须增加成本或时间。”
|
||||
|
||||
### 从瀑布流程过渡到敏捷开发
|
||||
|
||||
瀑布流程来源于生产和工程领域,这些领域适合线性化的流程:正如房屋封顶之前需要先盖好支撑墙。相似地,软件开发问题被认为可以通过提前做好计划来解决。从头到尾,开发流程均由路线图清晰地定义,沿着路线图就可以得到最终交付的产品。
|
||||
|
||||
最终,瀑布模型被认为对软件开发是不利的而且违反人的直觉,因为通常直到开发流程的最后才能体现出项目的价值,这导致许多项目最终都以失败告终。而且,在项目结束前客户看不到任何可以工作的软件。
|
||||
|
||||
<ruby>敏捷<rt>Agile</rt></ruby>采用了一种不同的方法,它抛弃了规划整个项目,承诺估计的时间点,简单的遵循计划。与瀑布流程相反,它假设和拥抱不确定性。它的理念是以响应变化代替讨论过去,它认为变更是客户需求的一部分。
|
||||
|
||||
### 敏捷价值观
|
||||
|
||||
敏捷由<ruby>敏捷宣言<rt>Agile Manifesto</rt></ruby>代言,敏捷宣言定义了 [12 条原则][5](LCTT 译注:此处没有采用本文原本的简略句式,而是摘录了来自敏捷软件开发宣言官方的[中文译本][14]):
|
||||
|
||||
1. 我们最重要的目标,是通过持续不断地及早交付有价值的软件使客户满意。
|
||||
2. 欣然面对需求变化,即使在开发后期也一样。
|
||||
3. 经常交付可工作的软件,相隔几星期或一两个月,倾向于采取较短的周期。
|
||||
4. 业务人员和开发人员必须相互合作,项目中的每一天都不例外。
|
||||
5. 激发个体的斗志,以他们为核心搭建项目。提供所需的环境和支援,辅以信任,从而达成目标。
|
||||
6. 面对面沟通是传递信息的最佳的也是效率最高的方法。
|
||||
7. 可工作的软件是进度的首要度量标准。
|
||||
8. 敏捷流程倡导可持续的开发,责任人、开发人员和用户要能够共同维持其步调稳定延续。
|
||||
9. 坚持不懈地追求技术卓越和良好设计,敏捷能力由此增强。
|
||||
10. 以简洁为本,它是极力减少不必要工作量的艺术。
|
||||
11. 最好的架构,需求和设计出自自组织团队
|
||||
12. 团队定期地反思如何能提高成效,并依此调整自身的举止表现。
|
||||
|
||||
敏捷的四个[核心价值观][6]是(LCTT 译注:[此处译文][15]同样来自敏捷软件开发宣言官方):
|
||||
|
||||
* **个体和互动** 高于流程和工具
|
||||
* **工作的软件** 高于详尽的文档
|
||||
* **客户合作** 高于合同谈判
|
||||
* **响应变化** 高于遵循计划
|
||||
|
||||
这与瀑布流程死板的计划风格相反。在敏捷流程中,客户是开发团队的一员,而不仅仅是在项目开始时参与项目需求的定义,在项目结束时验收最终的产品。客户帮忙团队完成[验收标准][7],并在整个过程中保持投入。另外,敏捷需要整个组织的变化和持续的改进。开发团队和其他团队一起合作,包括项目管理团队和测试团队。做什么和计划什么时候做由指定的角色领导,并由整个团队同意。
|
||||
|
||||
### 敏捷软件开发
|
||||
|
||||
敏捷软件开发需要自适应的规划、演进式的开发和交付。许多软件开发方法、框架和实践遵从敏捷的理念,包括:
|
||||
|
||||
* Scrum
|
||||
* <ruby>看板<rt>Kanban</rt></ruby>(可视化工作流)
|
||||
* <ruby>极限编程<rt>Xtreme Programming</rt></ruby>(XP)
|
||||
* <ruby>精益方法<rt>Lean</rt></ruby>
|
||||
* DevOps
|
||||
* <ruby>特性驱动开发<rt>Feature-Driven Development</rt></ruby>(FDD)
|
||||
* <ruby>测试驱动开发<rt>Test-Driven Development</rt></ruby>(TDD)
|
||||
* <ruby>水晶方法<rt>Crystal</rt></ruby>
|
||||
* <ruby>动态系统开发方法<rt>Dynamic Systems Development Method</rt></ruby>(DSDM)
|
||||
* <ruby>自适应软件开发<rt>Adaptive Software Development</rt></ruby>(ASD)
|
||||
|
||||
所有这些已经被单独用于或一起用于开发和部署软件。最常用的是 [Scrum][8]、看板(或 Scrumban)和 DevOps。
|
||||
|
||||
[Scrum][9] 是一个框架,采用该框架的团队通常由一个 Scrum 教练、产品经理和开发人员组成,该团队以跨职能、自主的工作方式运作,能够加快软件交付速度从而给客户带来巨大的商业价值。其关注点是[较小增量][10]的快速迭代。
|
||||
|
||||
[看板][11] 是一个敏捷框架,有时也叫工作流管理系统,它能帮助团队可视化他们的工作从而最大化效率(因而变得敏捷)。看板通常由数字或物理展示板来呈现。团队的工作在展示板上随着进度而移动,例如从未启动到进行中,一直到测试中、已完成。看板使得每个团队成员可以随时查看到所有工作的状态。
|
||||
|
||||
### DevOps 价值观
|
||||
|
||||
DevOps 是一种文化,是一种思维状态,是一种软件开发的方式或者基础设施的方式,也是一种构建和部署软件和应用的方式。它假设开发和运维之间没有隔阂,他们一起合作,没有矛盾。
|
||||
|
||||
DevOps 基于其它两个领域的实践: 精益和敏捷。DevOps 不是一个公司内的岗位或角色;它是一个组织或团队对持续交付、持续部署和持续集成的坚持不懈的追求。[Gene Kim][12](Phoenix 项目和 Unicorn 项目的作者)认为,有三种方式定义 DevOps 的理念:
|
||||
|
||||
* 第一种: 流程原则
|
||||
* 第二种: 反馈原则
|
||||
* 第三种: 持续学习原则
|
||||
|
||||
### DevOps 软件开发
|
||||
|
||||
DevOps 不会凭空产生;它是一种灵活的实践,它的本质是一种关于软件开发和 IT 或基础设施实施的共享文化和思维方式。
|
||||
|
||||
当你想到自动化、云、微服务时,你会想到 DevOps。在一次[访谈][13]中,《加速构建和扩张高性能技术组织》的作者 Nicol Forsgren、Jez Humble 和 Gene Kim 这样解释到:
|
||||
|
||||
> * 软件交付能力很重要,它极大地影响到组织的成果,例如利润、市场份额、质量、客户满意度以及组织战略目标的达成。
|
||||
> * 优秀的团队能达到很高的交付量、稳定性和质量;他们并没有为了获得这些属性而进行取舍。
|
||||
> * 你可以通过实施精益、敏捷和 DevOps 中的实践来提升能力。
|
||||
> * 实施这些实践和能力也会影响你的组织文化,并且会进一步对你的软件交付能力和组织能力产生有益的提升。
|
||||
> * 懂得怎样改进能力需要做很多工作。
|
||||
|
||||
### DevOps 和敏捷的对比
|
||||
|
||||
DevOps 和敏捷有相似性,但是它们不完全相同,一些人认为 DevOps 比敏捷更好。为了避免造成混淆,深入地了解它们是很重要的。
|
||||
|
||||
#### 相似之处
|
||||
|
||||
* 毫无疑问,两者都是软件开发技术。
|
||||
* 敏捷已经存在了 20 多年,DevOps 是最近才出现的。
|
||||
* 两者都追求软件的快速开发,它们的理念都基于怎样在不伤害客户或运维利益的情况下快速开发出软件。
|
||||
|
||||
#### 不同之处
|
||||
|
||||
* 两者的差异在于软件开发完成后发生的事情。
|
||||
* 在 DevOps 和敏捷中,都有软件开发、测试和部署的阶段。然而,敏捷流程在这三个阶段之后会终止。相反,DevOps 包括后续持续的运维。因此,DevOps 会持续的监控软件运行情况和进行持续的开发。
|
||||
* 敏捷中,不同的人负责软件的开发、测试和部署。而 DevOps 工程角色负责所有活动,开发即运维,运维即开发。
|
||||
* DevOps 更关注于削减成本,而敏捷则是精益和减少浪费的代名词,侧重于像敏捷项目会计和最小可行产品的概念。
|
||||
* 敏捷专注于并体现了经验主义(适应、透明和检查),而不是预测性措施。
|
||||
|
||||
敏捷 | DevOps
|
||||
--- | ---
|
||||
从客户得到反馈 | 从自己得到反馈
|
||||
较小的发布周期 | 较小的发布周期,立即反馈
|
||||
聚焦于速度 | 聚焦于速度和自动化
|
||||
对业务不是最好 | 对业务最好
|
||||
|
||||
### 总结
|
||||
|
||||
敏捷和 DevOps 是截然不同的,尽管它们的相似之处使人们认为它们是相同的。这对敏捷和 DevOps 都是一种伤害。
|
||||
|
||||
根据我作为一名敏捷专家的经验,我发现对于组织和团队从高层次上了解敏捷和 DevOps 是什么,以及它们如何帮助团队更高效地工作,更快地交付高质量产品从而提高客户满意度非常有价值。
|
||||
|
||||
敏捷和 DevOps 绝不是对抗性的(或至少没有这个意图)。在敏捷革命中,它们更像是盟友而不是敌人。敏捷和 DevOps 可以相互协作一致对外,因此可以在相同的场合共存。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/devops-vs-agile
|
||||
|
||||
作者:[Taz Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[messon007](https://github.com/messon007)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/heronthecli
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/collab-team-pair-programming-code-keyboard.png?itok=kBeRTFL1 "Pair programming"
|
||||
[2]: http://www.agilenutshell.com/agile_vs_waterfall
|
||||
[3]: https://en.wikipedia.org/wiki/Project_management_triangle
|
||||
[4]: https://www.pmi.org/learning/library/triple-constraint-erroneous-useless-value-8024
|
||||
[5]: http://agilemanifesto.org/principles.html
|
||||
[6]: https://agilemanifesto.org/
|
||||
[7]: https://www.productplan.com/glossary/acceptance-criteria/
|
||||
[8]: https://opensource.com/article/19/8/scrum-vs-kanban
|
||||
[9]: https://www.scrum.org/
|
||||
[10]: https://www.scrum.org/resources/what-is-an-increment
|
||||
[11]: https://www.atlassian.com/agile/kanban
|
||||
[12]: https://itrevolution.com/the-unicorn-project/
|
||||
[13]: https://www.infoq.com/articles/book-review-accelerate/
|
||||
[14]: http://agilemanifesto.org/iso/zhchs/principles.html
|
||||
[15]: http://agilemanifesto.org/iso/zhchs/manifesto.html
|
@ -0,0 +1,198 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12007-1.html)
|
||||
[#]: subject: (Basic kubectl and Helm commands for beginners)
|
||||
[#]: via: (https://opensource.com/article/20/2/kubectl-helm-commands)
|
||||
[#]: author: (Jessica Cherry https://opensource.com/users/jrepka)
|
||||
|
||||
适用于初学者的基本 kubectl 和 Helm 命令
|
||||
======
|
||||
|
||||
> 去杂货店“采购”这些命令,你需要用这些 Kubernetes 工具来入门。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/18/113120adp34myy90eb944b.jpg)
|
||||
|
||||
最近,我丈夫告诉我他即将要去参加一个工作面试,面试时他需要在计算机上运行一些基本命令。他对这场面试感到焦虑,但是对于他来说,学习和记住事情的最好方法是将不了解的事物比喻为非常熟悉的事物。因为我们的谈话是在我逛杂货店试图决定当晚要烹饪的食物之后进行的,所以这启发我用一次去杂货店的行程来介绍 `kubectl` 和 `helm` 命令。
|
||||
|
||||
[Helm][2](“舵轮”)是在 Kubernetes(来自希腊语,意思是“舵手” 或 “领航员”)中管理应用程序的工具。你可以轻松地使用你的应用程序信息来部署“<ruby>海图<rt>chart</rt></ruby>”,从而可以在你的 Kubernetes 环境中几分钟之内让它们就绪并预配置好。在学习新知识时,查看示例的“海图”以了解其用法总是很有帮助的,因此,如果有时间,请查看这些成型的“[海图][3]”。(LCTT 译注:Kubernetes 生态中大量使用了和航海有关的比喻,因此本文在翻译时也采用了这些比喻)
|
||||
|
||||
[kubectl][4] 是与 Kubernetes 环境交互的命令行界面,允许你配置和管理集群。它需要一些配置才能在环境中工作,因此请仔细阅读其[文档][5]以了解你需要做什么。
|
||||
|
||||
我会在示例中使用命名空间,你可以在我的文章《[Kubernetes 命名空间入门][6]》中了解它。
|
||||
|
||||
现在我们已经准备好了,让我们开始 `kubectl`和 `helm` 基本命令的购物之旅!
|
||||
|
||||
### 用 Helm 列出清单
|
||||
|
||||
你去商店之前要做的第一件事是什么?好吧,如果你做事有条理,会创建一个“清单”。同样,这是我将解释的第一个基本的 Helm 命令。
|
||||
|
||||
在一个用 Helm 部署的应用程序中,`list` 命令提供有关应用程序当前版本的详细信息。在此示例中,我有一个已部署的应用程序:Jenkins CI/CD 应用程序。运行基本的 `list` 命令总是会显示默认的命名空间。由于我没有在默认的命名空间中部署任何内容,因此不会显示任何内容:
|
||||
|
||||
```
|
||||
$helm list
|
||||
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
|
||||
```
|
||||
|
||||
但是,如果运行带有额外标志的命令,则会显示我的应用程序和信息:
|
||||
|
||||
```
|
||||
$helm list --all-namespaces
|
||||
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
|
||||
jenkins jenkins 1 2020-01-18 16:18:07 EST deployed jenkins-1.9.4 lts
|
||||
```
|
||||
|
||||
最后,我可以指示 `list` 命令只检查我想从中获取信息的命名空间:
|
||||
|
||||
```
|
||||
$helm list --namespace jenkins
|
||||
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
|
||||
jenkins jenkins 1 2020-01-18 16:18:07 EST deployed jenkins-1.9.4 lts
|
||||
```
|
||||
|
||||
现在我有了一个清单,并且知道该清单上有什么,我可以使用 `get` 命令来“获取”我的物品!我会从 Kubernetes 集群开始,看看我能从中获取到什么?
|
||||
|
||||
### 用 Kubectl 获取物品
|
||||
|
||||
`kubectl get` 命令提供了有关 Kubernetes 中许多事物的信息,包括“<ruby>吊舱<rt>Pod</rt></ruby>”、节点和命名空间。同样,如果没有指定命名空间标志,就会使用默认的命名空间。首先,我获取集群中的命名空间以查看正在运行的命名空间:
|
||||
|
||||
```
|
||||
$kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 53m
|
||||
jenkins Active 44m
|
||||
kube-node-lease Active 53m
|
||||
kube-public Active 53m
|
||||
kube-system Active 53m
|
||||
```
|
||||
|
||||
现在我已经知道了在我的环境中运行的有哪些命名空间了,接下来获取节点并查看有多少个节点正在运行:
|
||||
|
||||
```
|
||||
$kubectl get nodes
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
minikube Ready master 55m v1.16.2
|
||||
```
|
||||
|
||||
我有一个节点正在运行,这主要是因为我的 Minikube 运行在一台小型服务器上。要得到在我的这一个节点上运行的“吊舱”可以这样:
|
||||
|
||||
```
|
||||
$kubectl get pods
|
||||
No resources found in default namespace.
|
||||
```
|
||||
|
||||
啊哦,它是空的。我将通过以下方式获取 Jenkins 命名空间中的内容:
|
||||
|
||||
```
|
||||
$kubectl get pods --namespace jenkins
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
jenkins-7fc688c874-mh7gv 1/1 Running 0 40m
|
||||
```
|
||||
|
||||
好消息!这里发现了一个“吊舱”,它还没有重新启动过,已运行了 40 分钟了。好的,如今我知道“吊舱”已经装好,所以我想看看用 Helm 命令可以得到什么。
|
||||
|
||||
### 用 Helm 获取信息
|
||||
|
||||
`helm get` 命令稍微复杂一点,因为这个“获取”命令所需要的不仅仅是一个应用程序名称,而且你可以从应用程序中请求多个内容。我会从获取用于制作该应用程序的值开始,然后展示“获取全部”的操作结果的片段,该操作将提供与该应用程序相关的所有数据。
|
||||
|
||||
```
|
||||
$helm get values jenkins -n jenkins
|
||||
USER-SUPPLIED VALUES:
|
||||
null
|
||||
```
|
||||
|
||||
由于我只安装了最小限度的稳定版,因此配置没有更改。如果我运行“获取全部”命令,我将得到所有的“海图”:
|
||||
|
||||
```
|
||||
$helm get all jenkins -n jenkins
|
||||
```
|
||||
|
||||
![output from helm get all command][7]
|
||||
|
||||
这会产生大量数据,因此我始终建议保留一份 Helm “海图”的副本,以便你可以查看“海图”中的模板。我还创建自己的值来了解自己所拥有的。
|
||||
|
||||
现在,我把所有的商品都放在购物车中了,我会检查一下“描述”它们包含什么的标签。这些示例仅与 `kubectl` 命令有关,它们描述了我通过 Helm 部署的内容。
|
||||
|
||||
### 用 kubectl 查看描述
|
||||
|
||||
正如我使用“获取”命令(该命令可以描述 Kubernetes 中的几乎所有内容)所做的那样,我将示例限定到命名空间、“吊舱”和节点上。由于我知道它们每一个是什么,因此这很容易。
|
||||
|
||||
```
|
||||
$kubectl describe ns jenkins
|
||||
Name: jenkins
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
Status: Active
|
||||
No resource quota.
|
||||
No resource limits.
|
||||
```
|
||||
|
||||
我可以看到我的命名空间的名称,并且它是活动的,没有资源或限额限制。
|
||||
|
||||
`describe pods` 命令会产生大量信息,因此我这里提供的是一小段输出。如果你在不使用“吊舱”名称的情况下运行该命令,它将返回名称空间中所有“吊舱”的信息,这可能会很麻烦。因此,请确保在此命令中始终包含“吊舱”名称。例如:
|
||||
|
||||
```
|
||||
$kubectl describe pods jenkins-7fc688c874-mh7gv --namespace jenkins
|
||||
```
|
||||
|
||||
![output of kubectl-describe-pods][8]
|
||||
|
||||
这会提供容器的状态、管理方式、标签以及“吊舱”中所使用的镜像(还有很多其它信息)。没有在这个简化过的输出中包括的数据有:在 Helm 配置值文件中应用的各种条件下的资源请求和限制、初始化容器和存储卷信息。如果你的应用程序由于资源不足而崩溃,或者是一个需要运行前置脚本进行配置的初始配置容器,或者生成不应该存储于纯文本 YAML 文件中的隐藏密码,则此数据很有用。
|
||||
|
||||
最后,我将使用 `describe node` 命令,当然,它是用来描述节点的。由于本示例只有一个名为 Minikube 的示例,因此我将使用这个名字。如果你的环境中有多个节点,则必须包含你想查找的的节点名称。
|
||||
|
||||
与“吊舱”一样,这个节点的命令会产生大量数据,因此我将仅包括输出片段。
|
||||
|
||||
```
|
||||
$kubectl describe node minikube
|
||||
```
|
||||
|
||||
![output of kubectl describe node][9]
|
||||
|
||||
注意,`describe node` 是更重要的基本命令之一。如此图所示,该命令返回统计信息,该信息指示节点何时资源用尽,并且该数据非常适合在需要扩展时(如果你的环境中没有自动扩展)向你发出警报。此输出片段中未包含的其它内容包括:对所有资源和限制的请求所占的百分比,以及资源的使用期限和分配(例如,对于我的应用程序而言)。
|
||||
|
||||
### 买单
|
||||
|
||||
使用这些命令,我完成了“购物”并得到了我想要的一切。希望这些基本命令也能在你使用 Kubernetes 的日常工作中提供帮助。
|
||||
|
||||
我鼓励你经常使用命令行并学习“帮助”部分中的速记标志,你可以通过运行以下命令来查看这些标志:
|
||||
|
||||
```
|
||||
$helm --help
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```
|
||||
$kubectl -h
|
||||
```
|
||||
|
||||
### 花生酱和果冻
|
||||
|
||||
有些东西像花生酱和果冻一样混在一起。Helm 和 `kubectl` 就有点像那样交错在一起。
|
||||
|
||||
我经常在自己的环境中使用这些工具。因为它们在很多地方都有很多相似之处,所以在使用其中一个之后,我通常需要跟进另一个。例如,我可以进行 Helm 部署,并使用 `kubectl` 观察它是否失败。一起试试它们,看看它们能为你做什么。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/kubectl-helm-commands
|
||||
|
||||
作者:[Jessica Cherry][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jrepka
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003784_02_os.comcareers_os_rh2x.png?itok=jbRfXinl (A person working.)
|
||||
[2]: https://helm.sh/
|
||||
[3]: https://github.com/helm/charts/tree/master/stable
|
||||
[4]: https://kubernetes.io/docs/reference/kubectl/kubectl/
|
||||
[5]: https://kubernetes.io/docs/reference/kubectl/overview/
|
||||
[6]: https://linux.cn/article-11749-1.html
|
||||
[7]: https://opensource.com/sites/default/files/uploads/helm-get-all.png (output from helm get all command)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/kubectl-describe-pods.png (output of kubectl-describe-pods)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/kubectl-describe-node.png (output of kubectl describe node)
|
@ -0,0 +1,152 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11959-1.html)
|
||||
[#]: subject: (Extend the life of your SSD drive with fstrim)
|
||||
[#]: via: (https://opensource.com/article/20/2/trim-solid-state-storage-linux)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss)
|
||||
|
||||
在 Linux 下使用 fstrim 延长 SSD 驱动器的寿命
|
||||
======
|
||||
|
||||
> 这个新的系统服务可以使你的生活更轻松。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/04/121625sl380ga10g56d33h.jpg)
|
||||
|
||||
在过去的十年中,固态驱动器(SSD)带来了一种管理存储的新方法。与上一代的转盘产品相比,SSD 具有无声、更冷却的操作和更快的接口规格等优点。当然,新技术带来了新的维护和管理方法。SSD 具有一种称为 TRIM 的功能。从本质上讲,这是一种用于回收设备上未使用的块的方法,该块可能先前已被写入,但不再包含有效数据,因此可以返回到通用存储池以供重用。Opensource.com 的 Don Watkins 首先在其 2017 年的文章《[Linux 固态驱动器:为 SSD 启用 TRIM][2]》中介绍过 TRIM 的内容。
|
||||
|
||||
如果你一直在 Linux 系统上使用此功能,则你可能熟悉下面描述的两种方法。
|
||||
|
||||
### 老的方式
|
||||
|
||||
#### 丢弃选项
|
||||
|
||||
我最初使用 `mount` 命令的 `discard` 选项启用了此功能。每个文件系统的配置都放在 `/etc/fstab` 文件中。
|
||||
|
||||
```
|
||||
# cat /etc/fstab
|
||||
UUID=3453g54-6628-2346-8123435f /home xfs defaults,discard 0 0
|
||||
```
|
||||
|
||||
丢弃选项可启用自动的在线 TRIM。由于可能会对性能造成负面影响,最近关于这是否是最佳方法一直存在争议。使用此选项会在每次将新数据写入驱动器时启动 TRIM。这可能会引入其他磁盘活动,从而影响存储性能。
|
||||
|
||||
#### Cron 作业
|
||||
|
||||
我从 `fstab` 文件中删除了丢弃选项。然后,我创建了一个 cron 作业来按计划调用该命令。
|
||||
|
||||
```
|
||||
# crontab -l
|
||||
@midnight /usr/bin/trim
|
||||
```
|
||||
|
||||
这是我最近在 Ubuntu Linux 系统上使用的方法,直到我了解到另一种方法。
|
||||
|
||||
### 一个新的 TRIM 服务
|
||||
|
||||
我最近发现有一个用于 TRIM 的 systemd 服务。Fedora 在版本 30 中将其[引入][3],尽管默认情况下在版本 30 和 31 中未启用它,但计划在版本 32 中使用它。如果你使用的是 Fedora 工作站 31,并且你想要开始使用此功能,可以非常轻松地启用它。我还将在下面向你展示如何对其进行测试。该服务并非 Fedora 独有的服务。它是否存在及其地位将因发行版而异。
|
||||
|
||||
#### 测试
|
||||
|
||||
我喜欢先进行测试,以更好地了解幕后情况。我通过打开终端并发出配置服务调用的命令来执行此操作。
|
||||
|
||||
```
|
||||
/usr/sbin/fstrim --fstab --verbose --quiet
|
||||
```
|
||||
|
||||
`fstrim` 的 `-help` 参数将描述这些信息和其他参数。
|
||||
|
||||
```
|
||||
$ sudo /usr/sbin/fstrim --help
|
||||
|
||||
Usage:
|
||||
fstrim [options] <mount point>
|
||||
|
||||
Discard unused blocks on a mounted filesystem.
|
||||
|
||||
Options:
|
||||
-a, --all trim all supported mounted filesystems
|
||||
-A, --fstab trim all supported mounted filesystems from /etc/fstab
|
||||
-o, --offset <num> the offset in bytes to start discarding from
|
||||
-l, --length <num> the number of bytes to discard
|
||||
-m, --minimum <num> the minimum extent length to discard
|
||||
-v, --verbose print number of discarded bytes
|
||||
--quiet suppress error messages
|
||||
-n, --dry-run does everything, but trim
|
||||
|
||||
-h, --help display this help
|
||||
-V, --version display version
|
||||
```
|
||||
|
||||
因此,现在我可以看到这个 systemd 服务已配置为在我的 `/etc/fstab` 文件中的所有受支持的挂载文件系统上运行该修剪操作(`-fstab`),并打印出所丢弃的字节数(`-verbose`),但是抑制了任何可能会发生的错误消息(`–quiet`)。了解这些选项对测试很有帮助。例如,我可以从最安全的方法开始,即空运行。我还将去掉 `-quiet` 参数,以便确定驱动器设置是否发生任何错误。
|
||||
|
||||
```
|
||||
$ sudo /usr/sbin/fstrim --fstab --verbose --dry-run
|
||||
```
|
||||
|
||||
这就会显示 `fstrim` 命令根据在 `/etc/fstab` 文件中找到的文件系统要执行的操作。
|
||||
|
||||
```
|
||||
$ sudo /usr/sbin/fstrim --fstab --verbose
|
||||
```
|
||||
|
||||
现在,这会将 TRIM 操作发送到驱动器,并报告每个文件系统中丢弃的字节数。以下是我最近在新的 NVME SSD 上全新安装 Fedora 之后的示例。
|
||||
|
||||
```
|
||||
/home: 291.5 GiB (313011310592 bytes) trimmed on /dev/mapper/wkst-home
|
||||
/boot/efi: 579.2 MiB (607301632 bytes) trimmed on /dev/nvme0n1p1
|
||||
/boot: 787.5 MiB (825778176 bytes) trimmed on /dev/nvme0n1p2
|
||||
/: 60.7 GiB (65154805760 bytes) trimmed on /dev/mapper/wkst-root
|
||||
```
|
||||
|
||||
#### 启用
|
||||
|
||||
Fedora Linux 实现了一个计划每周运行它的 systemd 计时器服务。要检查其是否存在及当前状态,请运行 `systemctl status`。
|
||||
|
||||
```
|
||||
$ sudo systemctl status fstrim.timer
|
||||
```
|
||||
|
||||
现在,启用该服务。
|
||||
|
||||
```
|
||||
$ sudo systemctl enable fstrim.timer
|
||||
```
|
||||
|
||||
#### 验证
|
||||
|
||||
然后,你可以通过列出所有计时器来验证该计时器是否已启用。
|
||||
|
||||
```
|
||||
$ sudo systemctl list-timers --all
|
||||
```
|
||||
|
||||
会显示出下列行,表明 `fstrim.timer` 存在。注意,该计时器实际上激活了 `fstrim.service` 服务。这是实际调用 `fstrim` 的地方。与时间相关的字段显示为 `n/a`,因为该服务已启用且尚未运行。
|
||||
|
||||
```
|
||||
NEXT LEFT LAST PASSED UNIT ACTIVATES
|
||||
n/a n/a n/a n/a fstrim.timer fstrim.service
|
||||
```
|
||||
|
||||
### 结论
|
||||
|
||||
该服务似乎是在驱动器上运行 TRIM 的最佳方法。这比必须创建自己的 crontab 条目来调用 `fstrim` 命令要简单得多。不必编辑 `fstab` 文件也更安全。观察固态存储技术的发展很有趣,并且我很高兴看到 Linux 似乎正在朝着标准且安全的方向实现它。
|
||||
|
||||
在本文中,学习了固态驱动器与传统硬盘驱动器有何不同以及它的含义...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/trim-solid-state-storage-linux
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/alanfdoss
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_keyboard_desktop.png?itok=I2nGw78_ (Linux keys on the keyboard for a desktop computer)
|
||||
[2]: https://linux.cn/article-8177-1.html
|
||||
[3]: https://fedoraproject.org/wiki/Changes/EnableFSTrimTimer (Fedora Project WIKI: Changes/EnableFSTrimTimer)
|
@ -0,0 +1,112 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11968-1.html)
|
||||
[#]: subject: (How to set up your own fast, private open source mesh network)
|
||||
[#]: via: (https://opensource.com/article/20/2/mesh-network-freemesh)
|
||||
[#]: author: (Spencer Thomason https://opensource.com/users/spencerthomason)
|
||||
|
||||
如何建立自己的快速、私有的开源网状网络(mesh)
|
||||
======
|
||||
|
||||
> 只需要不到 10 分钟的安装时间,就可以用 FreeMesh 搭建一个经济实惠、性能卓越、尊重隐私的网格系统。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/06/234848jaga52a0wx05w0f0.jpg)
|
||||
|
||||
[FreeMesh][2] 系统有望为大众带来完全开源的<ruby>网状网络<rt>mesh network</rt></ruby>(LCTT 译注:也称之为“多跳网络”)。我最近有机会对它进行了测试;它安装迅速,性能非常好 —— 特别是相对它的价格而言。
|
||||
|
||||
### 为什么要网格化和开源?
|
||||
|
||||
使用开源的原因很简单:隐私。有了 FreeMesh,你的数据就是你自己的。它不会跟踪或收集数据。不相信吗?毕竟,你可以轻松检查 —— 它是开源的!而其它大型高科技企业集团提供的一些流行的网状网络解决方案,你是否相信它们会保护你的数据?
|
||||
|
||||
另一个重要因素:更新。FreeMesh 表示,它将致力于定期发布安全性和性能更新。从现在起到 10 年后呢?使用开源解决方案,你可以根据需要自由地更新产品。
|
||||
|
||||
那么为什么要用网状网络呢?在网状网络中,多个无线路由器一起工作以广播单个超大型的无线网络。网状网络中的每个路由器都可与其他路由器智能地通信,以便为你的数据提供最佳的“路径”。FreeMesh 网站上的以下图片突出显示了使用单个无线路由器和网状网络之间的区别。红色网络表示单个无线路由器,绿色网络是网状网络。
|
||||
|
||||
![单路由器网络] [3]
|
||||
|
||||
![网状网络] [4]
|
||||
|
||||
### 采购设备
|
||||
|
||||
要开始使用 FreeMesh,请[订购套件][5]。它提供两种套件:标准套件和 4G LTE。
|
||||
|
||||
顾名思义,4G LTE 套件支持蜂窝数据连接。此功能在消费级网络领域非常罕见,但对某些人来说非常有用。你可以在提供电源和电池的任何地方建立具有完整的快速故障转移功能的便携式网状网络。
|
||||
|
||||
FreeMesh 套件带有一个主路由器和两个节点。路由器和节点使用 802.11ac、802.11r 和 802.11s 标准。随附的固件运行定制版本的 [OpenWrt] [6],这是嵌入式设备的 Linux 发行版。
|
||||
|
||||
FreeMesh 路由器的一些规格非常好:
|
||||
|
||||
* CPU:双核 880MHz MediaTek MT7621AT(双核/四线程!)
|
||||
* 内存:DDR3 512MB
|
||||
* 接口:1 个 GbE WAN、4 个 GbE LAN、1 个 USB 2.0 端口、1 个 microSD 卡插槽、1 个 SIM 插槽
|
||||
* 天线:2 个 5dBi 2.4GHz、2 个 5dBi 5GHz、2 个 3dBi 3G/4G(内置)
|
||||
* 4G LTE 调制解调器:LTE 4 类模块,下行 150Mbps/上行 50Mbps
|
||||
|
||||
### 设置
|
||||
|
||||
设置很容易,FreeMesh 的 [README][7] 提供了简单的说明和图表。首先首先设置主路由器。然后按照以下简单步骤操作:
|
||||
|
||||
1、将第一个节点(蓝色 WAN 端口)连接到主路由器(黄色 LAN 端口)。
|
||||
|
||||
![FreeMesh 设置步骤 1][8]
|
||||
|
||||
2、等待约 30 至 60 秒。设置完成后,节点的 LED 将会闪烁。
|
||||
|
||||
![FreeMesh 设置步骤 2][9]
|
||||
|
||||
3、将节点移到另一个位置。
|
||||
|
||||
仅此而已!节点不需要手动设置。你只需将它们插入主路由器,其余的工作就完成了。你可以以相同的方式添加更多节点;只需重复上述步骤即可。
|
||||
|
||||
### 功能
|
||||
|
||||
FreeMesh 是开箱即用的,它由 OpenWRT 和 LuCI 组合而成。它具有你期望路由器提供的所有功能。是否要安装新功能或软件包?SSH 连入并开始魔改!
|
||||
|
||||
![FreeMesh 网络上的实时负载][10]
|
||||
|
||||
![FreeMesh 网络概览][11]
|
||||
|
||||
![OpenWrt 状态报告][12]
|
||||
|
||||
### 性能如何
|
||||
|
||||
设置完 FreeMesh 系统后,我将节点移动到了房屋周围的各个地方。我使用 [iPerf][13] 测试带宽,它达到了约 150Mbps。WiFi 可能会受到许多环境变量的影响,因此你的结果可能会有所不同。节点与主路由器之间的距离在带宽中也有很大的影响。
|
||||
|
||||
但是,网状网络的真正优势不是高峰速度,而是整个空间的平均速度要好得多。即使在我家很远的地方,我仍然能够用流媒体播放视频并正常工作。我甚至可以在后院工作。在出门之前,我只是将一个节点重新放在窗口前面而已。
|
||||
|
||||
### 结论
|
||||
|
||||
FreeMesh 确实令人信服。它以简单、开源的形式为你提供高性价比和隐私。
|
||||
|
||||
以我的经验,设置非常容易,而且足够快。覆盖范围非常好,远远超过了任何单路由器环境。你可以随意魔改和定制 FreeMesh 设置,但是我觉得没有必要。它提供了我需要的一切。
|
||||
|
||||
如果你正在寻找价格可承受、性能良好且尊重隐私的网格系统,且该系统可以在不到 10 分钟的时间内安装完毕,你可以考虑一下 FreeMesh。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/mesh-network-freemesh
|
||||
|
||||
作者:[Spencer Thomason][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/spencerthomason
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-networking.png?itok=fHmulI9p (people on top of a connected globe)
|
||||
[2]: https://freemeshwireless.com/
|
||||
[3]: https://opensource.com/sites/default/files/uploads/singlerouternetwork.png (Single-router network)
|
||||
[4]: https://opensource.com/sites/default/files/uploads/meshnetwork.png (Mesh network)
|
||||
[5]: https://freemeshwireless.com/#pricing
|
||||
[6]: https://openwrt.org/
|
||||
[7]: https://gitlab.com/slthomason/freemesh/-/blob/master/README.md
|
||||
[8]: https://opensource.com/sites/default/files/uploads/connecttorouter.png (FreeMesh setup step 1)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/setupcomplete.png (FreeMesh setup step 2)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/freemeshrealtimeload.png (Real-time load on FreeMesh network)
|
||||
[11]: https://opensource.com/sites/default/files/uploads/freemeshwirelessoverview.png (Overview of FreeMesh network)
|
||||
[12]: https://opensource.com/sites/default/files/uploads/openwrt.png (OpenWrt status report)
|
||||
[13]: https://opensource.com/article/20/1/internet-speed-tests
|
80
published/202003/20200214 Linux is our love language.md
Normal file
80
published/202003/20200214 Linux is our love language.md
Normal file
@ -0,0 +1,80 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (sndnvaps)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-12022-1.html)
|
||||
[#]: subject: (Linux is our love language)
|
||||
[#]: via: (https://opensource.com/article/20/2/linux-love-language)
|
||||
[#]: author: (Christopher Cherry https://opensource.com/users/chcherry)
|
||||
|
||||
学习 Linux 是我们的爱情语言
|
||||
======
|
||||
|
||||
> 当一个妻子教丈夫一些新技能的时候,他们都学到了比期待更多的东西。
|
||||
|
||||
![](https://img.linux.net.cn/data/attachment/album/202003/22/163819clzuy77dc4d7q8zu.jpg)
|
||||
|
||||
2019 年是我们 Cherry 家学习的一年。我是一个喜欢学习新技术的高级软件工程师,并把学到的内容一起教给了我的丈夫 Chris。通过教给他一些我学到的东西,并让他全程经历我的技术演练文章,我帮助 Chris 学习到了新技术,使他能够将自己的职业生涯更深入地转向技术领域。而我学习到了新的方法,使我的演练和培训材料更易于让读者理解。
|
||||
|
||||
在这篇文章中,我们来讨论一下我们各自和彼此学习到了什么东西,然后探讨这对于我们的未来有何影响。
|
||||
|
||||
### 向学生的提问
|
||||
|
||||
**Jess:** Chris,是什么导致你想深入学习我的领域的技能呢?
|
||||
|
||||
**Chris:** 主要目的是为了让我事业更进一步。作为一个网络工程师的经历告诉我,现在的网络专家已经不像以前一样有价值了,我必须掌握更多的知识。由于网络经常被认为是造成这些天程序中断或出错的原因,我想从开发人员的角度了解更多关于编写应用程序的知识,以便于了解它们如何依赖网络资源。
|
||||
|
||||
**Jess:** 我首先教你什么内容?你从中学到什么?
|
||||
|
||||
**Chris:** 首先是从学习除此安装 Linux 系统开始的,之后又安装了 [Ansible][2]。只要硬件兼容,我用过的每一个 Linux 发行版都很容易安装,但可能会出现个别不兼容的情况。这就意味着我有时候第一手学习到的是如何解决系统安装过程的最初 5 分钟出现的问题了(这个我最喜欢了)。Ansible 给了一个我学习使用软件管理器来安装程序的理由。当程序安装完成后,通过查看 yum 安装的程序,我快速了解了程序管理器是如何处理程序的依赖项的,因此,用 Python 编写的 Ansible 能够在我的系统运行。自此之后,我开始使用 Ansible 来安装各种各样的程序。
|
||||
|
||||
**Jessica:** 你喜欢我这种教学方式不?
|
||||
|
||||
**Chris:** 我们一开始有过争吵,直到我们弄清楚了我喜欢的学习方式,你也知道了应该怎样为我提供最好的学习方式。在一开始的时候,我很难跟上你讲的内容。例如,当你说“一个码头工人集装箱”的时候,我完全不知道你在讲什么。比较早的时候,我的回答就是“这是一个集装箱”,然而当时这对我来说,完全没有意义。当你对这些内容进行一些更深入的讲解后,才让学习更有趣。
|
||||
|
||||
**Jess:** 老实说,这对我来说也是一个重要的教训。在你之前,我从来没有教过在这个技术领域知识比我少的人,所以你帮助我认识到我需要解释更多细节。我也得说声谢谢。
|
||||
|
||||
当你通过这几个学习步骤的时候,你觉得我的这篇测试文章怎样呢?
|
||||
|
||||
**Chris:** 就我个人而言,我认为这很容易,但我错了。在我主要学习的内容中,比如你[介绍的Vagrant][3],它在不同的 Linux 发行版间的变化比我想像的要多。操作系统的变化会影响设置的方式、运行都要求和特定的命令。这看起来比我用的网络设备变化更大。这让我花费更多的精力去查看这些说明是对应我的系统还是其它的系统(有时候很难知道)。在这学习路上,我似乎碰到很多问题。
|
||||
|
||||
**Jess:** 我每天都会遇到各种各样的问题,所以对我来说日常就是用各种方法解决各种问题。
|
||||
|
||||
### 向老师的提问
|
||||
|
||||
**Chris:** Jess,你将来教我的方式会有所改变吗?
|
||||
|
||||
**Jess:** 我想让你像我一样读多一些书。通过翻阅书籍来学习新技术。每天起床后一小时和睡觉前一小时我都会看书,花费一个星期左右我就能看一到两本书。我也会创建为期两周的任务计划来实践我从书本中学习到的技能。这是除了我一天中第一个小时在喝大量咖啡时读到的科技文章之外的。当我考虑到你的职业发展目标的时候,我认为除了我们谈到的优秀博客文章和文章之外,书籍是一个重要的元素。我觉得我的阅读量使我保持进步,如果你也这么做了,你也会很快赶上我的。
|
||||
|
||||
**Chris:** 那么学生有没有教过老师呢?
|
||||
|
||||
**Jess:** 我在你那里学习到耐心。举个例子,当你完成了安装 Ansible 的时候,我问你下一步要怎样操作的时候。你直接回复我,“不知道”,这不是我想让你学习到的内容。所以我改变了策略,现在在逐步安装任何组件之前,我们将详细讨论你想要实现的目标。当我们在写 Vagrant 文章的时候,我们一起进行相应的演示操作,我以创建它时就牢记目标,因此我们就有一些需要马上实现的目标。
|
||||
|
||||
这实际上对我在工作中的培训方式产生了巨大的改变。现在我在大家学习的过程中会问更多问题,并更多地进行手把手讲解。我更愿意坐下来仔细检查,确保有人明白我在说什么和我们在做什么。这是我之前从来没有做过的。
|
||||
|
||||
### 我们一起学到了什么
|
||||
|
||||
做为一对夫妇,在这一年的技术合作中我们的技术都有所增长。
|
||||
|
||||
**Chris:** 我对自己学到的东西感到震惊。通过一年课程学习,我认识了新操作系统、如何使用 API、使用 Ansible 部署 Web 应用和使用 Vagrant 启动虚拟机器。我还学习到了文档可以让生活变得更好,所以我也会尝试去写一写。然而,在这个工作领域,操作并不总是被记录在案,所以我学会了准备好处理棘手的问题,并记录如何解决它们。
|
||||
|
||||
**Jess:** 除了我在教你中学到的知识外,我还专注于学习 Kubernetes 在云环境中的应用知识。这包括部署策略、Kubernetes API 的复杂度、创建我自己的容器,并对环境进行加密处理。我还节省了探索的时间:研究了 serverless 的代码、AI 模型、Python 和以图形方式显示热图。对于我来说,这一年也很充足。
|
||||
|
||||
我们下一个目标是什么?现在还不知道,但我可以向你保证,我们将会继续进行分享它。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/2/linux-love-language
|
||||
|
||||
作者:[Christopher Cherry][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[sndnvaps](https://github.com/sndnvaps)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/chcherry
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/red-love-heart-alone-stone-path.jpg?itok=O3q1nEVz (红心 "你不是孤单的")
|
||||
[2]: https://opensource.com/resources/what-ansible
|
||||
[3]: https://opensource.com/resources/vagrant
|
@ -0,0 +1,89 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11967-1.html)
|
||||
[#]: subject: (PHP Development on Fedora with Eclipse)
|
||||
[#]: via: (https://fedoramagazine.org/php-development-on-fedora-with-eclipse/)
|
||||
[#]: author: (Mehdi Haghgoo https://fedoramagazine.org/author/powergame/)
|
||||
|
||||
使用 Eclipse 在 Fedora 上进行 PHP 开发
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
[Eclipse][2] 是由 Eclipse 基金会开发的功能全面的自由开源 IDE。它诞生于 2001 年。你可以在此 IDE 中编写各种程序,从 C/C++ 和 Java 到 PHP,乃至于 Python、HTML、JavaScript、Kotlin 等等。
|
||||
|
||||
### 安装
|
||||
|
||||
该软件可从 Fedora 的官方仓库中获得。要安装它,请用:
|
||||
|
||||
```
|
||||
sudo dnf install eclipse
|
||||
```
|
||||
|
||||
这将安装基本的 IDE 和 Eclipse 平台,能让你开发 Java 应用。为了将 PHP 开发支持添加到 IDE,请运行以下命令:
|
||||
|
||||
```
|
||||
sudo dnf install eclipse-pdt
|
||||
```
|
||||
|
||||
这将安装 PHP 开发工具,如 PHP 项目向导、PHP 服务器配置,composer 支持等。
|
||||
|
||||
### 功能
|
||||
|
||||
该 IDE 有许多使 PHP 开发更加容易的功能。例如,它有全面的项目向导(你可以在其中为新项目配置许多选项)。它还有如 composer 支持、调试支持、浏览器、终端等内置功能。
|
||||
|
||||
### 示例项目
|
||||
|
||||
现在已经安装了 IDE,让我们创建一个简单的 PHP 项目。进入 “File →New → Project”。在出现的对话框中,选择 “PHP project”。输入项目的名称。你可能还需要更改其他一些选项,例如更改项目的默认位置,启用 JavaScript 以及更改 PHP 版本。请看以下截图。
|
||||
|
||||
![Create A New PHP Project in Eclipse][3]
|
||||
|
||||
你可以单击 “Finish” 按钮创建项目,或按 “Next” 配置其他选项,例如添加包含和构建路径。在大多数情况下,你无需更改这些设置。
|
||||
|
||||
创建项目后,右键单击项目文件夹,然后选择 “New→PHP File” 将新的 PHP 文件添加到项目。在本教程中,我将其命名为 `index.php`,这是每个 PHP 项目中公认的默认文件。
|
||||
|
||||
![add a new PHP file][4]
|
||||
|
||||
接着在新文件中添加代码。
|
||||
|
||||
![Demo PHP code][5]
|
||||
|
||||
在上面的例子中,我在同一页面上使用了 CSS、JavaScript 和 PHP 标记,主要是为了展示 IDE 能够支持所有这些标记。
|
||||
|
||||
页面完成后,你可以将文件移至 Web 服务器文档根目录或在项目目录中创建一个 PHP 开发服务器来查看输出。
|
||||
|
||||
借助 Eclipse 中的内置终端,我们可以直接在 IDE 中启动 PHP 开发服务器。只需单击工具栏上的终端图标(![Terminal Icon][6]),然后单击 “OK”。在新终端中,进入项目目录,然后运行以下命令:
|
||||
|
||||
```
|
||||
php -S localhost:8080 -t . index.php
|
||||
```
|
||||
|
||||
![Terminal output][7]
|
||||
|
||||
现在,打开浏览器并进入 <http://localhost:8080>。如果按照说明正确完成了所有操作,并且代码没有错误,那么你将在浏览器中看到 PHP 脚本的输出。
|
||||
|
||||
![PHP output in Fedora][8]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/php-development-on-fedora-with-eclipse/
|
||||
|
||||
作者:[Mehdi Haghgoo][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/powergame/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2020/02/php-eclipse-816x346.png
|
||||
[2]: https://projects.eclipse.org/projects/eclipse
|
||||
[3]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-01-58-39.png
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-02-02-05-1024x576.png
|
||||
[5]: https://fedoramagazine.org/wp-content/uploads/2020/02/code-1024x916.png
|
||||
[6]: https://fedoramagazine.org/wp-content/uploads/2020/02/Screenshot-from-2020-02-07-03-50-05.png
|
||||
[7]: https://fedoramagazine.org/wp-content/uploads/2020/02/terminal-1024x239.png
|
||||
[8]: https://fedoramagazine.org/wp-content/uploads/2020/02/output.png
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user