mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-03 23:40:14 +08:00
commit
e595f1a77c
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: true
|
18
.github/ISSUE_TEMPLATE/questions.yml
vendored
Normal file
18
.github/ISSUE_TEMPLATE/questions.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
name: Ask Questions | 提问
|
||||||
|
description: Please describe your problem. | 请描述您的问题。
|
||||||
|
labels: ["question"]
|
||||||
|
assignees: []
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Please answer these questions before you submit the desired feature. | 请在您提交期望的功能之前,回答以下这些问题
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Your Questions
|
||||||
|
description: Please describe your problem. | 请描述您的问题。
|
||||||
|
placeholder: I have a question...
|
||||||
|
validations:
|
||||||
|
required: true
|
67
.github/ISSUE_TEMPLATE/topics.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/topics.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
name: 推荐选题
|
||||||
|
description: 推荐一个选题
|
||||||
|
title: "[推荐类型] 文章日期 文章标题"
|
||||||
|
labels: []
|
||||||
|
assignees:
|
||||||
|
- lkxed
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
标题请使用 **`[推荐类型] 文章日期 文章标题`** 格式,选题类型、文章日期和文章标题中间有一个 **空格**。
|
||||||
|
|
||||||
|
完整示例:
|
||||||
|
- [推荐选题] 20220823 The Lost Art of the Makefile
|
||||||
|
- [推荐选题] 20220905 Linus Torvalds Uses Apple MacBook Hardware to Release Linux Kernel 5.19
|
||||||
|
- type: input
|
||||||
|
id: url
|
||||||
|
attributes:
|
||||||
|
label: 原文链接地址
|
||||||
|
description: 填写原文章的链接地址
|
||||||
|
placeholder: https://......
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: 版权协议
|
||||||
|
description: 填写原文章的版权协议
|
||||||
|
multiple: false
|
||||||
|
options:
|
||||||
|
- CC-SA-BY
|
||||||
|
- 其它公域许可证
|
||||||
|
- 已获取作者授权
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: difficulty
|
||||||
|
attributes:
|
||||||
|
label: 文章难度
|
||||||
|
description: 选择文章的难度
|
||||||
|
multiple: false
|
||||||
|
options:
|
||||||
|
- 困难
|
||||||
|
- 一般
|
||||||
|
- 容易
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: category
|
||||||
|
attributes:
|
||||||
|
label: 文章分类
|
||||||
|
description: 选择文章的分类
|
||||||
|
multiple: false
|
||||||
|
options:
|
||||||
|
- 新闻(news)
|
||||||
|
- 观点(talk)
|
||||||
|
- 技术(tech)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reason
|
||||||
|
attributes:
|
||||||
|
label: 推荐理由
|
||||||
|
description: 填写你的推荐理由
|
||||||
|
placeholder:
|
||||||
|
validations:
|
||||||
|
required: false
|
27
.github/workflows/lctt-article-badge.yml
vendored
Normal file
27
.github/workflows/lctt-article-badge.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
name: LCTT Article Badge
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: checkout old pages branch
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: lctt/translateproject
|
||||||
|
path: build
|
||||||
|
ref: gh-pages
|
||||||
|
- name: remove pages .git
|
||||||
|
run: rm -rf ./build/.git
|
||||||
|
- name: run badge
|
||||||
|
run: sh ./scripts/badge.sh;
|
||||||
|
- uses: crazy-max/ghaction-github-pages@v2.2.0
|
||||||
|
with:
|
||||||
|
build_dir: ./build
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
18
.github/workflows/lctt-article-checker.yml
vendored
Normal file
18
.github/workflows/lctt-article-checker.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
name: LCTT Article Checker
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
PULL_REQUEST_ID: ${{ github.event.number }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: "checkout master branch & return to pull request branch"
|
||||||
|
run: CURRENT=$(echo ${{github.ref}} | sed "s|refs/|refs/remotes/|") && git checkout master && git checkout $CURRENT
|
||||||
|
- name: run check
|
||||||
|
run: sh ./scripts/check.sh;
|
28
.github/workflows/lctt-article-status.yml
vendored
Normal file
28
.github/workflows/lctt-article-status.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: LCTT Article Status
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "*/30 * * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: checkout old pages branch
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: lctt/translateproject
|
||||||
|
path: build
|
||||||
|
ref: gh-pages
|
||||||
|
- name: remove pages .git
|
||||||
|
run: rm -rf ./build/.git
|
||||||
|
- name: run status
|
||||||
|
run: sh ./scripts/status.sh;
|
||||||
|
- uses: crazy-max/ghaction-github-pages@v2.2.0
|
||||||
|
with:
|
||||||
|
build_dir: ./build
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
27
.travis.yml
27
.travis.yml
@ -1,27 +0,0 @@
|
|||||||
language: minimal
|
|
||||||
install:
|
|
||||||
- sudo apt-get install jq
|
|
||||||
- git clone --depth=1 -b gh-pages https://github.com/LCTT/TranslateProject/ build && rm -rf build/.git
|
|
||||||
script:
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then sh ./scripts/check.sh; fi'
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then sh ./scripts/badge.sh; fi'
|
|
||||||
- 'if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then sh ./scripts/status.sh; fi'
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
# - status
|
|
||||||
except:
|
|
||||||
- gh-pages
|
|
||||||
git:
|
|
||||||
submodules: false
|
|
||||||
depth: false
|
|
||||||
deploy:
|
|
||||||
provider: pages
|
|
||||||
skip_cleanup: true
|
|
||||||
github_token: $GITHUB_TOKEN
|
|
||||||
local_dir: build
|
|
||||||
on:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
# - status
|
|
42
lctt2022.md
Normal file
42
lctt2022.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
开源贡献者翻译组 LCTT 九岁啦
|
||||||
|
======
|
||||||
|
|
||||||
|
九年前,也是这个上午,我创建了 LCTT 及其第一个项目 [TranslateProject](https://github.com/LCTT/TranslateProject/)。从最初只是有感于 Unix/Linux 上的中文手册页实在太糟糕,希望做一些事情;到最后变成了一个以翻译国外各个开源社区的技术文章和开源资讯/讨论的“流水”式项目,LCTT 已经走过了令我自己都非常吃惊的九年。
|
||||||
|
|
||||||
|
人的一生,几十年而已,能在一件事上持续投入九年时光,这是我从未想过的事情。驻足回望,LCTT 其实并没有完成我最初的想法,这是缺憾;但是 LCTT 就这样变成了另外一种并非在我计划中的样子,或许也有其必然性。现在看来,LCTT 做了一些事情,也有一些存在的意义。我试着总结一下:
|
||||||
|
|
||||||
|
LCTT 的主项目 TranslateProject,选题广泛,参与门槛低,从某种意义上,为初识开源的小伙伴提供一种成为开源贡献者的方式。一些人就是通过这个项目,迈出了成为开源贡献者的第一步,并在日后的学习和工作中,成为了开源爱好者、专业技术人员。
|
||||||
|
|
||||||
|
LCTT 持续翻译了数千篇(截至今日,已经翻译发布了 6395 篇文章),这些文章的专业程度横跨了入门到精通等不同难度,内容方向涉猎了开发、运维、使用和文化等各个方面。虽然,有些文章仅堪一读,但也有不少文章值得收藏、一再细读。我屡屡能从读者那里得到反馈,这些文章对他们提供了很大的帮助,我想这就是 LCTT 的存世价值之一吧。唯独可惜的是,这些文章,没有以很好的方式组织起来,甚憾。
|
||||||
|
|
||||||
|
LCTT 有数百成员(截至今日,成功地在仓库中进行了贡献的贡献者有 311 位),他们的年龄不等,最年轻的有初中的学生、最老的,嗯这个不需要说了;他们的职业各异,比较多的是大学生,也有很多从事技术工作的专业人员,甚至还有完全不从事技术工作的贡献者。但是,他们都有一个共同的身份就是 LCTT 贡献者,因此,他们都有很多开源兄弟姐妹。
|
||||||
|
|
||||||
|
按照惯例,每两年,我会写一篇 LCTT 总结。今年又快到这个时间了,我却有些不知道该如何下笔。恍惚间,我突然想到,LCTT 是一个贡献者组织,是大家的 LCTT,那么,为什么不让大家来为 LCTT 写两句话呢?于是,我在 LCTT 群内发起了号召,请诸位成员写写自己参与 LCTT 的经历、感受或收获,也可以是祝愿、建议。下面,是我收集到的其中一些成员的留言(以留言时的顺序列出):
|
||||||
|
|
||||||
|
- **译者-acyanbird**:Linux 中国是我的开源引路人,让我有机会从零开始参与开源社区,认识到了开源精神,见到了世界的另一个可能性。也借此机会参与不少活动,认识了很多开源人士。目前在组长的帮助下,我也开始自己建立社区,十分感谢您给我这个机会~希望我们都越来越好,有更多的人也来一起参与开源
|
||||||
|
- **译者-mandeler**:LCTT community forever!
|
||||||
|
- **译者-Kira-Pgr**:For a better open source world!
|
||||||
|
- **译者-mengxinayan**:LCTT 不仅可以用来锻炼翻译能力,同时有专人进行校对,能有效找到自身不足。此外还可以用来接触新知新方向,最重要的是可以培养自身英文阅读的习惯。Thanks LCTT!
|
||||||
|
- **译者-aftermath0703**:从 LCTT 我收获到了许多知识,有时间我就会去 GitHub 上读读新的文章,有更多时间我就会去翻译一篇。翻译过程中先自己翻译一遍,再用翻译网站翻译一遍,有偏差的地方相互比对,我觉得这对我的各项英语能力都有很大的帮助。希望 LCTT 蓬勃发展,越办越好!
|
||||||
|
- **译者-MFGJT**:虽然因为工作原因很久没有翻译了,但是还是每天在看微信公众号。感觉到大家都很努力,希望今年有机会继续参加翻译 🌹
|
||||||
|
- **译者-stevending1st**:加入 LCTT 最大的惊叹是核心贡献者能够做到维护一个几百人的贡献者群体,背后是他们巨大的努力。希望能在 LCTT 不断学习,努力提升自己的能力。也祝愿 LCTT 越来越好。
|
||||||
|
- **译者-aREversez**:作为一个学翻译的学生,能参与到 LCTT 这样一个项目,了解更多关于开源与技术的知识,见识更宽阔的世界和更深远的历史,让自己能尽己所能为开源贡献一份力量,实属荣幸之至。希望咱们社区能够一直繁荣下去,传播更加丰富多彩的开源技术与思想!
|
||||||
|
- **译者-mcfd**:LCTT 翻译的许多实用的技术文章,能够简明、易懂地为广大小白答疑解惑,扫除学习、日常中遇到的坑,间接且不断地为开源社区注入生机。清风不解凌云志,明月无声照九州。
|
||||||
|
- **核心-lkxed**:在裸辞考研失败之后,我曾一度陷入迷茫。偶然间读到老王写的《如何以翻译贡献参与开源社区》,决心加入进来。自此,我从一个连 Git 和 GitHub 都搞不大懂的小白,成长为一名熟练的译者,又成长为一名熟练的选题。踏踏实实地做好一件小事,每天如此,不正是对抗焦虑和迷茫的好办法吗?感谢开源,给了我这个成长的机会;感谢 LCTT,领着我敲开了开源的大门;感谢老王,在我困惑时指点迷津。祝愿 LCTT 越办越好,我们一路与你同行!
|
||||||
|
- **核心-bestony**:刚刚专门回到网站上看了一下,我参与 LCTT 已经 8 年了,8 年来,LCTT 见证了我从小透明到半透明,也经历了我人生的三分之一。希望在未来的时间里,我可以和 LCTT 共成长,也可以与 LCTT 共人生。
|
||||||
|
- **核心-Locez**:今天是 LCTT 的生日,也是我的生日,一种奇妙的缘分。LCTT 是我接触 LC,接触开源以后第一个比较正式贡献的项目,对我来说意义比较非凡,重要的是通过这个项目在 LC 以及 LCTT 结识到了热爱分享的大家,特别是老王,viz,bestony 等人,很感谢大家在我学生时代起,就对我的一些耐心引导与帮助。
|
||||||
|
- **译者-robsean**:科教兴国,实干兴邦
|
||||||
|
- **译者-TravinDreek**:作为一位自由软件活动者,我主要从事技术伦理相关文章的翻译。我在 LCTT 的翻译动机,不止在于增进自己对当今技术伦理问题的认识,更在于让人们有机会了解到并利用自由(和开源)软件来应对这些问题。希望 LCTT 今后能在传播 FLOSS 方面起到更大的作用。Happy hacking.
|
||||||
|
- **译者-Wlzzzz-del**:之前备考考研时,偶然接触到 LCTT。为了多了解一些 Linux 知识,同时提高自己的英语水平,因此选择加入了 LCTT,这也是我第一次参与开源项目。虽然因为很多原因,翻译的文章不多,但是 LCTT 发布的文章我都会认真阅读。在未来我希望能多抽出时间来,参与到翻译活动中来。
|
||||||
|
- **译者-Veryzzj**:今年年初在朋友的介绍下认识了 LCTT 并参与到了其中,仔细回想 LCTT 的意义于我是什么?是打破开源项目于我的神秘面纱,是从申领到翻译每一篇收获的成就感,是发布了文章感受到的正反馈,是在翻译群中和大家交流时的友好气氛。正是这些点滴,是我对抗生命无意义感的武器。我们用语言打破边界,也用语言拓宽世界。预祝 LCTT 越来越好!
|
||||||
|
- **译者-Chao-zhi**:加入 LCTT 已经六年了,我已经不记得自己是怎么加入 LCTT 了。但我一直记得我是通过 LCTT 的 wiki 学会使用 GitHub 的。也是通过 LCTT 慢慢了解开源世界的。希望能继续和 LCTT 一起成长。
|
||||||
|
- **核心-MjSeven**:但愿 LCTT 长久,千里共婵娟
|
||||||
|
- **译者-mudongliang**:LCTT 是早期我参与的开源项目,通过这个项目我学会了很多开源知识,熟练使用 Git 使用,为后期在内核项目贡献,奠定了坚实基础 😁
|
||||||
|
- **译者-Northurland**:感谢 LC 治好了我的网友见面恐惧症(笑)。这是我在校园外参与的第一个项目,很感谢组长和 LC 的大家给予我这个机会。希望我们珍视的这个社区在未来能让更多人了解开源、参与开源。
|
||||||
|
|
||||||
|
说实话,LCTT 和 Linux 中国能走到今天,全赖这些贡献者的支持,这让我每每感觉吃力时,都有了不能放弃的理由。
|
||||||
|
|
||||||
|
那么,你是不是也想加入 LCTT 呢?很简单,访问 LCTT 官网:https://linux.cn/lctt/ 即可了解如何成为一名 LCTT 贡献者了。
|
||||||
|
|
||||||
|
最后,感谢大家九年来的支持和信任!顺祝大家中秋节、教师节快乐!
|
||||||
|
|
@ -0,0 +1,93 @@
|
|||||||
|
GCC:优化 Linux、互联网和一切
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/22/122155ujfd62u6zbx3i4b3.jpg)
|
||||||
|
|
||||||
|
软件如果不能被电脑运行,那么它就是无用的。而在处理<ruby>运行时<rt>run-time</rt></ruby>性能的问题上,即使是最有才华的开发人员也会受编译器的支配 —— 因为如果没有可靠的编译器工具链,就无法构建任何重要的东西。<ruby>GNU 编译器集合<rt>GNU Compiler Collection</rt></ruby>(GCC)提供了一个健壮、成熟和高性能的工具,以帮助你充分发挥你代码的潜能。经过数十年成千上万人的开发,GCC 成为了世界上最受尊敬的编译器之一。如果你在构建应用程序是没有使用 GCC,那么你可能错过了最佳解决方案。
|
||||||
|
|
||||||
|
根据 LLVM.org 的说法,GCC 是“如今事实上的标准开源编译器” [^1],也是用来构建完整系统的基础 —— 从内核开始。GCC 支持超过 60 种硬件平台,包括 ARM、Intel、AMD、IBM POWER、SPARC、HP PA-RISC 和 IBM Z,以及各种操作环境,包括 GNU、Linux、Windows、macOS、FreeBSD、NetBSD、OpenBSD、DragonFly BSD、Solaris、AIX、HP-UX 和 RTEMS。它提供了高度兼容的 C/C++ 编译器,并支持流行的 C 库,如 GNU C Library(glibc)、Newlib、musl 和各种 BSD 操作系统中包含的 C 库,以及 Fortran、Ada 和 GO 语言的前端。GCC 还可以作为一个交叉编译器,可以为运行编译器的平台以外的其他平台创建可执行代码。GCC 是紧密集成的 GNU 工具链的核心组件,由 GNU 项目产生,它包括 glibc、Binutils 和 GNU 调试器(GDB)。
|
||||||
|
|
||||||
|
“一直以来我最喜欢的 GNU 工具是 GCC,即<ruby>GNU 编译器集合<rt>GNU Compiler Collection</rt></ruby>。在开发工具非常昂贵的时候,GCC 是第二个 GNU 工具,也是使社区能够编写和构建所有其他工具的工具。这个工具一手改变了这个行业,导致了自由软件运动的诞生,因为一个好的、自由的编译器是一个社区软件的先决条件。”—— Red Hat 开源和标准团队的 Dave Neary。[^2]
|
||||||
|
|
||||||
|
### 优化 Linux
|
||||||
|
|
||||||
|
作为 Linux 内核源代码的默认编译器,GCC 提供了可靠、稳定的性能以及正确构建内核所需的额外扩展。GCC 是流行的 Linux 发行版的标准组件,如 ArchLinux、CentOS、Debian、Fedora、openSUSE 和 Ubuntu 这些发行版中,GCC 通常用来编译支持系统的组件。这包括 Linux 使用的默认库(如 libc、libm、libintl、libssh、libssl、libcrypto、libexpat、libpthread 和 ncurses),这些库依赖于 GCC 来提供可靠性和高性能,并且使应用程序和系统程序可以访问 Linux 内核功能。发行版中包含的许多应用程序包也是用 GCC 构建的,例如 Python、Perl、Ruby、nginx、Apache HTTP 服务器、OpenStack、Docker 和 OpenShift。各个 Linux 发行版使用 GCC 构建的大量代码组成了内核、库和应用程序软件。对于 openSUSE 发行版,几乎 100% 的原生代码都是由 GCC 构建的,包括 6135 个源程序包、5705 个共享库和 38927 个可执行文件。这相当于每周编译 24540 个源代码包。[^3]
|
||||||
|
|
||||||
|
Linux 发行版中包含的 GCC 的基本版本用于创建定义系统<ruby>应用程序二进制接口<rt>Application Binary Interface</rt></ruby>(ABI)的内核和库。<ruby>用户空间<rt>User space</rt></ruby>开发者可以选择下载 GCC 的最新稳定版本,以获得高级功能、性能优化和可用性改进。Linux 发行版提供安装说明或预构建的工具链,用于部署最新版本的 GCC 以及其他 GNU 工具,这些工具有助于提高开发人员的工作效率和缩短部署时间。
|
||||||
|
|
||||||
|
### 优化互联网
|
||||||
|
|
||||||
|
GCC 是嵌入式系统中被广泛采用的核心编译器之一,支持为日益增长的物联网设备开发软件。GCC 提供了许多扩展功能,使其非常适合嵌入式系统软件开发,包括使用编译器的内建函数、#语法、内联汇编和以应用程序为中心的命令行选项进行精细控制。GCC 支持广泛的嵌入式体系结构,包括 ARM、AMCC、AVR、Blackfin、MIPS、RISC-V、Renesas Electronics V850、NXP 和 Freescale Power 处理器,可以生成高效、高质量的代码。GCC提供的交叉编译能力对这个社区至关重要,而预制的交叉编译工具链 [^4] 是一个主要需求。例如,GNU ARM 嵌入式工具链是经过集成和验证的软件包,其中包含 ARM 嵌入式 GCC 编译器、库和其它裸机软件开发所需的工具。这些工具链可用于在 Windows、Linux 和 macOS 主机操作系统上对流行的 ARM Cortex-R 和 Cortex-M 处理器进行交叉编译,这些处理器已装载于数百亿台支持互联网的设备中。[^5]
|
||||||
|
|
||||||
|
GCC 为云计算赋能,为需要直接管理计算资源的软件提供了可靠的开发平台,如数据库和 Web 服务引擎以及备份和安全软件。GCC 完全兼容 C++ 11 和 C++ 14,为 C++ 17 和 C++ 2a 提供实验支持 [^6](LCTT 译注:本文原文发布于 2018 年),可以创建性能优异的对象代码,并提供可靠的调试信息。使用 GCC 的应用程序的一些例子包括:MySQL 数据库管理系统,它需要 Linux 的 GCC [^7];Apache HTTP 服务器,它建议使用 GCC [^8];Bacula,一个企业级网络备份工具,它需要 GCC。[^9]
|
||||||
|
|
||||||
|
### 优化一切
|
||||||
|
|
||||||
|
对于<ruby>高性能计算<rt>High Performance Computing</rt></ruby>(HPC)中使用的科学代码的研究和开发,GCC 提供了成熟的 C、C++ 和 Fortran 前端,以及对 OpenMP 和 OpenACC API的支持,用于基于指令的并行编程。因为 GCC 提供了跨计算环境的可移植性,它使得代码能够更容易地在各种新的和传统的客户机和服务器平台上进行测试。GCC 为 C、C++ 和 Fortran 编译器提供了 OpenMP 4.0 的完整支持,为 C 和 C++ 编译器提供了 OpenMP 4.5 完整支持。对于 OpenACC、 GCC 支持大部分 2.5 规范和性能优化,并且是唯一提供 [OpenACC][1] 支持的非商业、非学术编译器。
|
||||||
|
|
||||||
|
代码性能是这个社区的一个重要参数,GCC 提供了一个坚实的性能基础。Colfax Research 于 2017 年 11 月发表的一篇论文评估了 C++ 编译器在使用 OpenMP 4.x 指令并行化编译代码的速度和编译后代码的运行速度。图 1 描绘了不同编译器编译并使用单个线程运行时计算内核的相对性能。性能值经过了归一化处理,以 G++ 的性能为 1.0。
|
||||||
|
|
||||||
|
![performance][3]
|
||||||
|
|
||||||
|
*图 1 为由不同编译器编译的每个内核的相对性能。(单线程,越高越好)。*
|
||||||
|
|
||||||
|
他的论文总结道:“GNU 编译器在我们的测试中也做得很好。G++ 在六种情况中的三种情况下生成的代码速度是第二快的,并且在编译时间方面是最快的编译器之一。”[^10]
|
||||||
|
|
||||||
|
### 谁在用 GCC?
|
||||||
|
|
||||||
|
在 JetBrains 2018 年的开发者生态状况调查中,在接受调查的 6000 名开发者中,66% 的 C++ 程序员和 73% 的 C 程序员经常使用 GCC。[^11] 以下简要介绍 GCC 的优点,正是这些优点使它在开发人员社区中如此受欢迎。
|
||||||
|
|
||||||
|
* 对于需要为各种新的和遗留的计算平台和操作环境编写代码的开发人员,GCC 提供了对最广泛的硬件和操作环境的支持。硬件供应商提供的编译器主要侧重于对其产品的支持,而其他开源编译器在所支持的硬件和操作系统方面则受到很大限制。[^12]
|
||||||
|
* 有各种各样的基于 GCC 的预构建工具链,这对嵌入式系统开发人员特别有吸引力。这包括 GNU ARM 嵌入式工具链和 Bootlin 网站上提供的 138 个预编译交叉编译器工具链。[^13] 虽然其他开源编译器(如 Clang/LLVM)可以取代现有交叉编译工具链中的 GCC,但这些工具集需要开发者完全重新构建。[^14]
|
||||||
|
* GCC 通过成熟的编译器平台向应用程序开发人员提供可靠、稳定的性能。《在 AMD EPYC 平台上用 GCC 8/9 与 LLVM Clang 6/7 编译器基准测试》这篇文章提供了 49 个基准测试的结果,这些测试的编译器在三个优化级别上运行。使用 `-O3 -march=native` 级别的 GCC 8.2 RC1 在 34% 的时间里排在第一位,而在相同的优化级别 LLVM Clang 6.0 在 20% 的时间里赢得了第二位。[^15]
|
||||||
|
* GCC 为编译调试 [^16] 提供了改进的诊断方法,并为运行时调试提供了准确而有用的信息。GCC 与 GDB 紧密集成,GDB 是一个成熟且功能齐全的工具,它提供“不间断”调试,可以在断点处停止单个线程。
|
||||||
|
* GCC 是一个得到良好支持的平台,它有一个活跃的、有责任感的社区,支持当前版本和以前的两个版本。由于每年都有发布计划,这为一个版本提供了两年的支持。
|
||||||
|
|
||||||
|
### GCC:仍然在继续优化
|
||||||
|
|
||||||
|
GCC 作为一个世界级的编译器继续向前发展。GCC 的最新版本是 8.2,于 2018 年 7 月发布(LCTT 译注:本文原文发表于 2018 年),增加了对即将推出的 Intel CPU、更多 ARM CPU 的硬件支持,并提高了 AMD 的 ZEN CPU 的性能。增加了对 C17 的初步支持,同时也对 C++2A 进行了初步工作。诊断功能继续得到增强,包括更好的发射诊断,改进了定位、定位范围和修复提示,特别是在 C++ 前端。Red Hat 的 David Malcolm 在 2018 年 3 月撰写的博客概述了 GCC 8 中的可用性改进。[^17]
|
||||||
|
|
||||||
|
新的硬件平台继续依赖 GCC 工具链进行软件开发,例如 RISC-V,这是一种自由开放的 ISA,机器学习、人工智能(AI)和物联网细分市场都对其感兴趣。GCC 仍然是 Linux 系统持续开发的关键组件。针对 Intel 架构的 Clear Linux 项目是一个为云、客户端和物联网用例构建的新兴发行版,它提供了一个很好的示例,说明如何使用和改进 GCC 编译器技术来提高基于 Linux 的系统的性能和安全性。GCC 还被用于微软 Azure Sphere 的应用程序开发,这是一个基于 Linux 的物联网应用程序操作系统,最初支持基于 ARM 的联发科 MT3620 处理器。在培养下一代程序员方面,GCC 也是树莓派的 Windows 工具链的核心组件,树莓派是一种运行基于 Debian 的 GNU/Linux 的低成本嵌入式板,用于促进学校和发展中国家的基础计算机科学教学。
|
||||||
|
|
||||||
|
GCC 由 GNU 项目的创始人<ruby>理查德•斯托曼<rt>Richard Stallman</rt></ruby>首次发布 于 1987 年 3 月 22 日,由于它是第一个作为自由软件发布的可移植的 ANSI C 优化编译器,因此它被认为是一个重大突破。GCC 由来自世界各地的程序员组成的社区在指导委员会的指导下维护,以确保对项目进行广泛的、有代表性的监督。GCC 的社区方法是它的优势之一,它形成了一个由开发人员和用户组成的庞大而多样化的社区,他们为项目做出了贡献并提供支持。根据 Open Hub 的说法,“GCC 是世界上最大的开源团队之一,在 Open Hub 上的所有项目团队中排名前 2%。”[^18]
|
||||||
|
|
||||||
|
关于 GCC 的许可问题,人们进行了大量的讨论,其中大多数是混淆而不是启发。GCC 在 GNU 通用公共许可证(GPL)版本 3 或更高版本下发布,但运行时库例外。这是一个左版许可,这意味着衍生作品只能在相同的许可条款下分发。GPLv3 旨在保护 GCC,防止其成为专有软件,并要求对 GCC 代码的更改可以自由公开地进行。对于“最终用户”来说,这个编译器与其他编译器完全相同;使用 GCC 对你为自己的代码所选择的任何许可都没有区别。[^19]
|
||||||
|
|
||||||
|
[^1]: http://clang.llvm.org/features.html#gcccompat
|
||||||
|
[^2]: https://opensource.com/article/18/9/happy-birthday-gnu
|
||||||
|
[^3]: 由 SUSE 基于最近的构建统计提供的信息。在 openSUSE 中还有其他不生成可执行镜像的源码包,这些不包括在统计中。
|
||||||
|
[^4]: https://community.arm.com/tools/b/blog/posts/gnu-toolchain-performance-in-2018
|
||||||
|
[^5]: https://www.arm.com/products/processors/cortex-m
|
||||||
|
[^6]: https://gcc.gnu.org/projects/cxx-status.html#cxx17
|
||||||
|
[^7]: https://mysqlserverteam.com/mysql-8-0-source-code-improvements/
|
||||||
|
[^8]: http://httpd.apache.org/docs/2.4/install.html
|
||||||
|
[^9]: https://blog.bacula.org/what-is-bacula/system-requirements/
|
||||||
|
[^10]: https://colfaxresearch.com/compiler-comparison/
|
||||||
|
[^11]: https://www.jetbrains.com/research/devecosystem-2018/
|
||||||
|
[^12]: http://releases.llvm.org/6.0.0/tools/clang/docs/UsersManual.html
|
||||||
|
[^13]: https://bootlin.com/blog/free-and-ready-to-use-cross-compilation-toolchains/
|
||||||
|
[^14]: https://clang.llvm.org/docs/Toolchain.html
|
||||||
|
[^15]: https://www.phoronix.com/scan.php?page=article&item=gcclang-epyc-summer18&num=1
|
||||||
|
[^16]: https://gcc.gnu.org/wiki/ClangDiagnosticsComparison
|
||||||
|
[^17]: https://developers.redhat.com/blog/2018/03/15/gcc-8-usability-improvements/
|
||||||
|
[^18]: https://www.openhub.net/p/gcc/factoids#FactoidTeamSizeVeryLarge
|
||||||
|
[^19]: https://www.gnu.org/licenses/gcc-exception-3.1-faq.en.html
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.linux.com/blog/2018/10/gcc-optimizing-linux-internet-and-everything
|
||||||
|
|
||||||
|
作者:[Margaret Lewis][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.linux.com/users/margaret-lewis
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.openacc.org/tools
|
||||||
|
[2]: /files/images/gccjpg-0
|
||||||
|
[3]: https://lcom.static.linuxfound.org/sites/lcom/files/gcc_0.jpg?itok=HbGnRqWX "performance"
|
||||||
|
[4]: https://www.linux.com/licenses/category/used-permission
|
148
published/202101/20181123 Three SSH GUI Tools for Linux.md
Normal file
148
published/202101/20181123 Three SSH GUI Tools for Linux.md
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: subject: (Three SSH GUI Tools for Linux)
|
||||||
|
[#]: via: (https://www.linux.com/blog/learn/intro-to-linux/2018/11/three-ssh-guis-linux)
|
||||||
|
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||||
|
[#]: url: (https://linux.cn/article-13010-1.html)
|
||||||
|
|
||||||
|
三种 Linux 下的 SSH 图形界面工具
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://lcom.static.linuxfound.org/sites/lcom/files/ssh.jpg)
|
||||||
|
|
||||||
|
在你作为 Linux 系统管理员的职业生涯中,你可以使用 Secure Shell(SSH)远程访问 Linux 服务器或桌面系统。很有可能,你已经使用过了。在某些情况下,你会通过 SSH 一次性登录多个 Linux 服务器。实际上,SSH 很可能是 Linux 工具箱中最常用的工具之一。因此,你会希望操作尽可能高效。对于许多系统管理员来说,没有什么比命令行更有效的了。但是,有些用户确实更喜欢 GUI 工具,尤其是从一台桌面台式机远程连接到服务器上工作时。
|
||||||
|
|
||||||
|
如果你碰巧喜欢 GUI 工具,那么你肯定想了解一下 Linux 上的一些出色的 SSH 图形界面工具。将其与独特的终端窗口相结合,可以从同一窗口远程访问多台计算机,你便拥有了高效工作所需的一切。让我们看以下这三个工具,找出其中一个(或多个)是否完全适合你的需求。
|
||||||
|
|
||||||
|
我将在 [Elementary OS][1] 上演示这些工具,但是大多数流行的发行版都可以使用它们。
|
||||||
|
|
||||||
|
### PuTTY
|
||||||
|
|
||||||
|
只要是久经沙场的人都知道 [PuTTY][2]。 实际上,PuTTY 是从 Windows 环境通过 SSH 连接到 Linux 服务器的事实标准工具。但是 PuTTY 不仅适用于 Windows。实际上,从其标准存储库中,PuTTY 也可以安装到 Linux 上。 PuTTY 的功能列表包括:
|
||||||
|
|
||||||
|
* 保存会话
|
||||||
|
* 通过 IP 地址或主机名链接
|
||||||
|
* 定义备用 SSH 端口
|
||||||
|
* 链接类型定义
|
||||||
|
* 日志记录
|
||||||
|
* 键盘、响铃、外观、连接等选项
|
||||||
|
* 本地和远程隧道配置
|
||||||
|
* 支持代理
|
||||||
|
* 支持X11 隧道
|
||||||
|
|
||||||
|
PuTTY GUI 主要是一种保存 SSH 会话的方式,因此,你可以更轻松地管理那些你需要不断远程登录、登出的各种 Linux 服务器和桌面台式机。从 PuTTY 连接到 Linux 服务器后,你将拥有一个可以运行的终端窗口。此时,你可能会问自己,为什么不只在终端窗口中工作?对于某些人来说,保存会话的便捷性确实使 PuTTY 值得使用。
|
||||||
|
|
||||||
|
在 Linux 上安装 PuTTY 很简单。例如,你可以在基于 Debian 的发行版上执行命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install -y putty
|
||||||
|
```
|
||||||
|
|
||||||
|
安装后,你可以从桌面菜单运行 PuTTY GUI 或执行命令 `putty`。在“<ruby>PuTTY 配置<rt>PuTTY Configuration</rt></ruby>” 窗口(图 1)中,在 “<ruby>主机名(或 IP 地址)<rt>HostName (or IP address)</rt></ruby>”位置键入主机名或 IP 地址,配置<ruby>端口<rt>Port</rt></ruby>”(如果不是默认值 22),从“<ruby>连接类型<rt>Connection type</rt></ruby>”中选择 “SSH” ,然后单击“<ruby>打开<rt>Open</rt></ruby>”。
|
||||||
|
|
||||||
|
![PuTTY Connection][4]
|
||||||
|
|
||||||
|
*图 1:PuTTY 连接配置窗口。*
|
||||||
|
|
||||||
|
建立连接后,系统将提示你输入远程服务器上的用户凭据(图 2)。
|
||||||
|
|
||||||
|
![log in][7]
|
||||||
|
|
||||||
|
*图 2:使用 PuTTY 登录到远程服务器。*
|
||||||
|
|
||||||
|
要保存会话(以便不必总是键入远程服务器信息),填写 IP 地址(或主机名),配置端口和连接类型,然后(在单击 “<ruby>打开<rt>Open</rt></ruby>” 之前),在 “<ruby>保存会话<rt>Saved Sessions</rt></ruby>” 顶部文本区域中键入链接的名称,然后单击 “<ruby>保存<rt>Save</rt></ruby>”。 这样将保存此会话的配置。若要连接到已保存的会话,请从 “<ruby>已保存的会话<rt>Saved Sessions</rt></ruby>” 窗口中选择它,单击 “<ruby>加载<rt>Load</rt></ruby>”,然后单击 “<ruby>打开<rt>Open</rt></ruby>”。 然后,系统将提示你输入远程服务器上的远程凭据登录远程服务器。
|
||||||
|
|
||||||
|
### EasySSH
|
||||||
|
|
||||||
|
尽管 [EasySSH][8] 没有提供 PuTTY 中提供的大量配置选项,但是(顾名思义)它非常易于使用。 EasySSH 的最佳功能之一是提供标签式界面,因此你可以打开多个 SSH 连接并在它们之间快速切换。 EasySSH 的功能包括:
|
||||||
|
|
||||||
|
* 分组(你可以将选项卡分组以获得更高效的体验)。
|
||||||
|
* 保存用户名/密码。
|
||||||
|
* 外观选项。
|
||||||
|
* 支持本地和远程隧道。
|
||||||
|
|
||||||
|
在 Linux 桌面上安装 EasySSH 很简单,因为可以通过 flatpak 安装该应用程序(这意味着你必须在系统上安装 Flatpak )。 安装 flatpak 后,使用以下命令添加 EasySSH :
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
|
||||||
|
sudo flatpak install flathub com.github.muriloventuroso.easyssh
|
||||||
|
```
|
||||||
|
|
||||||
|
使用以下命令运行 EasySSH :
|
||||||
|
|
||||||
|
```
|
||||||
|
flatpak run com.github.muriloventuroso.easyssh
|
||||||
|
```
|
||||||
|
|
||||||
|
你可以在其中单击左上角的 “+” 按钮打开 EasySSH 应用程序。 在出现的窗口(图 3)中,根据需要配置 SSH 连接。
|
||||||
|
|
||||||
|
![Adding a connection][10]
|
||||||
|
|
||||||
|
*图 3:在 EasySSH 中添加连接很简单。*
|
||||||
|
|
||||||
|
添加连接后,它将显示在主窗口的左侧导航中(图 4)。
|
||||||
|
|
||||||
|
![EasySSH][12]
|
||||||
|
|
||||||
|
*图 4:EasySSH 主窗口。*
|
||||||
|
|
||||||
|
要在 EasySSH 中连接到远程服务器,请从左侧导航中选择它,然后单击 “<ruby>连接<rt>Connect</rt></ruby>” 按钮(图 5)。
|
||||||
|
|
||||||
|
![Connecting][14]
|
||||||
|
|
||||||
|
*图 5:使用 EasySSH 连接到远程服务器。*
|
||||||
|
|
||||||
|
EasySSH 的一个注意事项是你必须在连接配置中保存用户名和密码(否则连接将失败)。这意味着有权访问运行 EasySSH 的桌面的任何人都可以在不知道密码的情况下远程访问你的服务器。因此,你必须始终记得在外出时锁定桌面屏幕(并确保使用强密码)。你最不希望的就是避免服务器受到不必要的登录攻击。
|
||||||
|
|
||||||
|
### Terminator
|
||||||
|
|
||||||
|
Terminator 实际上不是 SSH GUI。相反,Terminator 的功能是作为一个单一窗口,使你可以一次运行多个终端(甚至一组终端)。实际上,你可以打开 Terminator,将窗口垂直和水平拆分(直到拥有所需的所有终端),然后通过标准 SSH 命令连接到所有远程 Linux 服务器(图 6)。
|
||||||
|
|
||||||
|
![Terminator][16]
|
||||||
|
|
||||||
|
*图 6:Terminator 分为三个不同的窗口,每个窗口都连接到不同的 Linux 服务器。*
|
||||||
|
|
||||||
|
要安装 Terminator,请执行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install -y terminator
|
||||||
|
```
|
||||||
|
|
||||||
|
安装后,从桌面菜单或用命令 `terminator` 打开该工具。打开窗口后,你可以在 Terminator 内部右键单击,然后选择 “<ruby>水平分割<rt>Split Horizontally</rt></ruby>” 或 “<ruby>垂直分割<rt>Split Vertically</rt></ruby>”。继续拆分终端,直到你打开所需的终端为止,然后开始远程管理这些服务器。使用 Terminator 的注意事项是它不是标准的 SSH GUI 工具,因为它不会保存你的会话或使你可以快速访问这些服务器。换句话说,你将始终必须手动登录到远程 Linux 服务器。但是,能够并行查看远程 Secure Shell 会话确实使管理多个远程计算机变得容易得多。
|
||||||
|
|
||||||
|
### 少而精的选择
|
||||||
|
|
||||||
|
Linux 没有多少可用的 SSH GUI 工具。为什么呢?因为大多数管理员更喜欢简单地打开终端窗口,并使用标准命令行工具来远程访问服务器。但是,如果需要 GUI 工具,则有两个可靠的选择,和一个使登录多台计算机稍微容易一些的终端。尽管对于那些寻找 SSH GUI 工具的人来说只有少数选择,但是可用的那些肯定值得你花时间,根据需要尝试其中之一。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.linux.com/blog/learn/intro-to-linux/2018/11/three-ssh-guis-linux
|
||||||
|
|
||||||
|
作者:[Jack Wallen][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.linux.com/users/jlwallen
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://elementary.io/
|
||||||
|
[2]: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
|
||||||
|
[3]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_1.jpg
|
||||||
|
[4]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_1.jpg (PuTTY Connection)
|
||||||
|
[5]: https://www.linux.com/licenses/category/used-permission
|
||||||
|
[6]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_2.jpg
|
||||||
|
[7]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_2.jpg (log in)
|
||||||
|
[8]: https://github.com/muriloventuroso/easyssh
|
||||||
|
[9]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_3.jpg
|
||||||
|
[10]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_3.jpg (Adding a connection)
|
||||||
|
[11]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_4.jpg
|
||||||
|
[12]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_4.jpg (EasySSH)
|
||||||
|
[13]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_5.jpg
|
||||||
|
[14]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_5.jpg (Connecting)
|
||||||
|
[15]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_6.jpg
|
||||||
|
[16]: https://lcom.static.linuxfound.org/sites/lcom/files/ssh_guis_6.jpg (Terminator)
|
@ -0,0 +1,219 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (qfzy1233)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13005-1.html)
|
||||||
|
[#]: subject: (Search, Study And Practice Linux Commands On The Fly!)
|
||||||
|
[#]: via: (https://www.ostechnix.com/search-study-and-practice-linux-commands-on-the-fly/)
|
||||||
|
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||||
|
|
||||||
|
光速!搜索、学习和实践 Linux 命令!!
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/01/tldr-720x340.png)
|
||||||
|
|
||||||
|
这一标题可能看起来很粗略且吸睛。请允许我解释一下我在本教程中将要阐释的内容。假设你想下载一个压缩文件,将其解压缩,并从命令行中将文件从一个位置移动到另一个位置。根据上面的场景,我们可能需要至少三个 Linux 命令,一个用于下载文件,一个用于提取下载的文件,一个用于移动文件。如果你是中高级 Linux 用户,你可以通过[一行命令][16]或脚本在几秒钟/分钟内轻松完成这一任务。但是,如果你是一个不懂得太多 Linux 命令的菜鸟你可能就需要一些帮助了。
|
||||||
|
|
||||||
|
当然,谷歌的快速搜索可能会找到很多结果。或者,你可以使用 [手册页][1]。但是有些手册页实在很长,很全面,但缺少有用的示例。当你在特定的标志/选项上寻找特定的信息时,你可能需要向下检索相当长的时间。值得庆幸的是,有一些 [好的手册页替代品][2],它们主要关注于实用的命令。一个很好的选择是 **TLDR 手册**。使用 TLDR 手册,我们可以通过实际示例快速轻松地学习一个 Linux 命令。要使用 TLDR 手册,我们需要 TLDR 客户端。有很多客户。今天我们就来了解一个这样的客户端,名为 **“Tldr++”**。
|
||||||
|
|
||||||
|
Tldr++ 是一个快速和交互式的 Tldr 客户端,用 **Go** 编程语言编写。与其他 Tldr 客户端不同,它是完全交互式的。这意味着,你可以选择一个命令,读取所有示例,并立即运行任何命令,而不必在终端中重新键入或复制/粘贴每个命令。还是不明白?没有问题。请继续阅读,以便动态学习和实践 Linux 命令。
|
||||||
|
|
||||||
|
### 安装 Tldr++
|
||||||
|
|
||||||
|
安装 Tldr++ 非常简单。从 [发布页面][3] 下载 Tldr++ 最新版本。解压它并将 Tldr++ 二进制文件移动到你的 `$PATH` 中。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ wget https://github.com/isacikgoz/tldr/releases/download/v0.5.0/tldr_0.5.0_linux_amd64.tar.gz
|
||||||
|
$ tar xzf tldr_0.5.0_linux_amd64.tar.gz
|
||||||
|
$ sudo mv tldr /usr/local/bin
|
||||||
|
$ sudo chmod +x /usr/local/bin/tldr
|
||||||
|
```
|
||||||
|
|
||||||
|
现在,运行 `tldr` 二进制代码将 TLDR 手册部署到本地系统中。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tldr
|
||||||
|
```
|
||||||
|
|
||||||
|
示例输出:
|
||||||
|
|
||||||
|
```
|
||||||
|
Enumerating objects: 6, done.
|
||||||
|
Counting objects: 100% (6/6), done.
|
||||||
|
Compressing objects: 100% (6/6), done.
|
||||||
|
Total 18157 (delta 0), reused 3 (delta 0), pack-reused 18151
|
||||||
|
Successfully cloned into: /home/sk/.local/share/tldr
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/01/tldr-2.png)
|
||||||
|
|
||||||
|
Tldr++ 可以在 AUR 中使用。如果你使用 Arch Linux 上,你可以使用任何 AUR 助手来安装它,例如 [YaY][4]。确保你已经从系统中删除了任何现有的 TLDR 客户端,并运行以下命令安装 Tldr++。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ yay -S tldr++
|
||||||
|
```
|
||||||
|
|
||||||
|
或者,你也可以像下面描述的那样从源代码进行编译。因为 Tldr++ 是用 Go 语言编写的,所以请确保你 Linux 系统中已经安装了 Go 语言。如果还没有安装,请参考下面的指南。
|
||||||
|
|
||||||
|
- [如何在 Linux 系统中安装 Go 语言](https://www.ostechnix.com/install-go-language-linux/)
|
||||||
|
|
||||||
|
在安装好 Go 语言之后, 运行以下的命令来安装 Tldr++。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ go get -u github.com/isacikgoz/tldr
|
||||||
|
```
|
||||||
|
|
||||||
|
该命令在当前工作目录中下载 `tldr` 代码库中的内容并存储到 `go` 文件夹中。
|
||||||
|
|
||||||
|
现在,运行 `tldr` 二进制代码将 TLDR 手册部署到本地系统中。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ go/bin/tldr
|
||||||
|
```
|
||||||
|
|
||||||
|
示例输出:
|
||||||
|
|
||||||
|
![][6]
|
||||||
|
|
||||||
|
最后,将 `tldr` 二进制文件复制到你的路径中。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo mv tldr /usr/local/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
现在是时候看一些例子了。
|
||||||
|
|
||||||
|
### Tldr++ 用法
|
||||||
|
|
||||||
|
输入不带任何选项的 `tldr` 命令,以字母顺序显示所有命令示例。
|
||||||
|
|
||||||
|
![][7]
|
||||||
|
|
||||||
|
使用 **向上/向下箭头** 来浏览命令,键入任何字母来搜索或键入命令名称来查看相应命令的示例。 `?` 以浏览更多消息,按 `Ctrl+c` 返回/退出。
|
||||||
|
|
||||||
|
要显示特定命令的示例命令,例如 `apt`,可以这样做:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tldr apt
|
||||||
|
```
|
||||||
|
|
||||||
|
![][8]
|
||||||
|
|
||||||
|
从列表中选择任意示例命令并按回车键。在选定的命令前会看到一个 `*` 符号。例如,我选择第一个命令即 `sudo apt update`。现在,它会问你是否继续。如果命令正确,只需键入 `y` 继续,并输入 `sudo` 密码运行所选命令。
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
看到了吗?你不需要在终端中复制/粘贴或键入实际的命令。只需从列表中选择它,并极速运行!
|
||||||
|
|
||||||
|
Tldr 手册中有数百个 Linux 命令示例。你可以每天选择一个或两个命令,并彻底学习它们。每天坚持这样的练习,尽可能多的掌握。
|
||||||
|
|
||||||
|
### 使用 Tldr++ 动态学习和实践 Linux 命令
|
||||||
|
|
||||||
|
现在回到我在第一段中提到的场景。你需要下载一个文件,将其解压缩并将其移动到不同的位置,并使其可执行。让我们看看如何使用 Tldr++ 客户端进行交互。
|
||||||
|
|
||||||
|
#### 第一步 – 从网上下载文件
|
||||||
|
|
||||||
|
要使用命令行下载文件,我们主要使用 `curl` 或 `wget` 命令。让我使用 `wget` 下载文件。要打开 `wget` 命令的 TLDR 页面,只需执行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tldr wget
|
||||||
|
```
|
||||||
|
|
||||||
|
下面是 `wget` 命令的示例。
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/01/wget-tldr.png)
|
||||||
|
|
||||||
|
你可以使用 **向上/向下箭头** 来浏览命令列表。一旦你选择了你所选择的命令,按回车键。这里我选择了第一个命令。
|
||||||
|
|
||||||
|
现在,输入路径来下载文件。
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/01/tldr-3.png)
|
||||||
|
|
||||||
|
然后将要求你确认该命令是否正确。如果命令正确,只需键入 `yes` 或 `y` 就可以开始下载文件。
|
||||||
|
|
||||||
|
![][10]
|
||||||
|
|
||||||
|
我们已经下载了文件。让我们继续解压这个文件。
|
||||||
|
|
||||||
|
#### 第二步 – 解压已下载的文件
|
||||||
|
|
||||||
|
我们下载了 tar.gz 文件。所以我将打开 TLDR 手册的 `tar` 页面。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tldr tar
|
||||||
|
```
|
||||||
|
|
||||||
|
你将看到示例命令列表。浏览这些示例,找出哪个命令适合提取 tar.gz(gzip 格式)文件,按回车键。在我们的例子中,它是第三个命令。
|
||||||
|
|
||||||
|
![][11]
|
||||||
|
|
||||||
|
现在,系统将提示你输入 tar.gz 文件的路径。只需输入路径并按回车键。Tldr++ 支持智能文件提示。这意味着它会在你键入时自动补全文件名。只需按 `TAB` 键自动完成。
|
||||||
|
|
||||||
|
![][12]
|
||||||
|
|
||||||
|
如果将文件下载到其他位置,只需键入完整路径,例如 `/home/sk/Downloads/tldr_0.5.0_linux_amd64.tar.gz`。
|
||||||
|
|
||||||
|
输入要解压的文件的路径后,按回车键,然后输入 `y` 进行确认。
|
||||||
|
|
||||||
|
![][13]
|
||||||
|
|
||||||
|
#### 第三步 – 将文件从一个目录移动到另一个目录
|
||||||
|
|
||||||
|
我们解压了文件。现在我们需要将文件移动到另一个位置。为了将文件从一个位置移动到另一个位置,我们使用 `mv` 命令。所以,让我们打开 TLDR 手册的 `mv` 命令。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tldr mv
|
||||||
|
```
|
||||||
|
|
||||||
|
选择正确的命令将文件从一个位置移动到另一个位置。在我们的例子中,第一个命令可以工作,所以让我们选中它。
|
||||||
|
|
||||||
|
![][14]
|
||||||
|
|
||||||
|
输入要移动的文件路径,并输入目标路径并按回车键。
|
||||||
|
|
||||||
|
![][15]
|
||||||
|
|
||||||
|
**附注:** 输入 `y!` 或 `yes!` 来以 `sudo` 权限运行命令。
|
||||||
|
|
||||||
|
正如你在上面的截图中看到的,我将名为 ``tldr` 的文件移动到 `/usr/local/bin/`。
|
||||||
|
|
||||||
|
要了解更多细节,请参考项目最后给出的 GitHub 页面。
|
||||||
|
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
别误会,毫无疑问 **手册页** 是伟大的!但是,正如我已经说过的,许多手册页都很全面,缺少有用的示例。我不可能记住带有复杂标志的冗长的所有命令。有时,我花了很多时间在手册页上,却还是一窍不通。Tldr 手册帮助我在几分钟内找到了我需要的东西。而且,我们偶尔会使用一些命令,然后就会完全忘记它们。另一方面,Tldr 手册实际上在使用那些使用率很低的命令时很有帮助。Tldr++ 客户端通过智能的用户交互使这个任务变得更容易。试试吧,在下面的评论区告诉我们你对这个工具的看法。
|
||||||
|
|
||||||
|
以上,更多的好的分享将会陆续推出,请继续保持关注!
|
||||||
|
|
||||||
|
祝好!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.ostechnix.com/search-study-and-practice-linux-commands-on-the-fly/
|
||||||
|
|
||||||
|
作者:[SK][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[qfzy1233](https://github.com/qfzy1233)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.ostechnix.com/author/sk/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.ostechnix.com/learn-use-man-pages-efficiently/
|
||||||
|
[2]: https://www.ostechnix.com/3-good-alternatives-man-pages-every-linux-user-know/
|
||||||
|
[3]: https://github.com/isacikgoz/tldr/releases
|
||||||
|
[4]: https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/
|
||||||
|
[5]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||||
|
[6]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-1.png
|
||||||
|
[7]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-11.png
|
||||||
|
[8]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-12.png
|
||||||
|
[9]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-13.png
|
||||||
|
[10]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-4.png
|
||||||
|
[11]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-6.png
|
||||||
|
[12]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-7.png
|
||||||
|
[13]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-8.png
|
||||||
|
[14]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-9.png
|
||||||
|
[15]: http://www.ostechnix.com/wp-content/uploads/2019/01/tldr-10.png
|
||||||
|
[16]: https://ostechnix.com/random-one-liner-linux-commands-part-1/
|
134
published/202101/20190205 5 Streaming Audio Players for Linux.md
Normal file
134
published/202101/20190205 5 Streaming Audio Players for Linux.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13029-1.html)
|
||||||
|
[#]: subject: (5 Streaming Audio Players for Linux)
|
||||||
|
[#]: via: (https://www.linux.com/blog/2019/2/5-streaming-audio-players-linux)
|
||||||
|
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||||
|
|
||||||
|
5 个适用于 Linux 的流式音频播放器
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/18/220035k8mmbl1blmkb97f8.jpg)
|
||||||
|
|
||||||
|
当我工作的时候,我会一直在后台播放音乐。大多数情况下,这些音乐是以黑胶唱片的形式在转盘上旋转。但有时我不想用这种单纯的方法听音乐时,我会选择听流媒体音频应用程序的方式。然而,由于我工作在 Linux 平台上,所以我只可以使用在我的操作系统上运行良好的软件。幸运的是,对于想在 Linux 桌面听流式音频的人来说,有很多工具可以选择。
|
||||||
|
|
||||||
|
事实上,Linux 为音乐流媒体提供了许多可靠的产品,我将重点介绍我最喜欢的五种用于此任务的工具。警告一句,并不是所有的玩意都是开源的。但是如果你不介意在你的开源桌面上运行一个专有的应用程序,你有一些非常棒的选择。让我们来看看有什么可用的。
|
||||||
|
|
||||||
|
### Spotify
|
||||||
|
|
||||||
|
Linux 版的 Spotify 不是那种在你启动就闪退的愚蠢的、半生不熟的应用程序,也没有阉割什么功能。事实上,Spotify 的 Linux 版本与其他平台上的版本完全相同。使用 Spotify 流媒体客户端,你可以收听音乐和播客、创建播放列表、发现新的艺术家等等。Spotify 界面(图 1)非常易于导航和使用。
|
||||||
|
|
||||||
|
![Spotify][2]
|
||||||
|
|
||||||
|
*图 1:Spotify 界面可以很容易地找到新的音乐和旧的收藏。*
|
||||||
|
|
||||||
|
你可以使用 snap(使用 `sudo snap install Spotify` 命令)安装 Spotify,也可以使用以下命令从官方存储库安装 Spotify:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 931FF8E79F0876134EDDBDCCA87FF9DF48BF1C90
|
||||||
|
sudo echo deb http://repository.spotify.com stable non-free | sudo tee /etc/apt/sources.list.d/spotify.list
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install spotify-client
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦安装,你就可以登录你的 Spotify 帐户,这样你就可以开始听好听的音乐,以帮助激励你完成你的工作。如果你已在其他设备上安装了 Spotify(并登录到同一帐户),则可以指定音乐应该流式传输到哪个设备(通过单击 Spotify 窗口右下角附近的“可用设备”图标)。
|
||||||
|
|
||||||
|
### Clementine
|
||||||
|
|
||||||
|
Clementine 是 Linux 平台上最好的音乐播放器之一。Clementine 不仅允许用户播放本地存储的音乐,还可以连接到许多流媒体音频服务,例如:
|
||||||
|
|
||||||
|
* Amazon Cloud Drive
|
||||||
|
* Box
|
||||||
|
* Dropbox
|
||||||
|
* Icecast
|
||||||
|
* Jamendo
|
||||||
|
* Magnatune
|
||||||
|
* RockRadio.com
|
||||||
|
* Radiotunes.com
|
||||||
|
* SomaFM
|
||||||
|
* SoundCloud
|
||||||
|
* Spotify
|
||||||
|
* Subsonic
|
||||||
|
* Vk.com
|
||||||
|
* 或其他有趣的电台
|
||||||
|
|
||||||
|
使用 Clementine 有两个注意事项。首先,你必须使用最新版本(因为某些软件库中可用的构建版本已过时,并且不会安装必要的流式处理插件)。第二,即使是最新的构建版本,一些流媒体服务也不会像预期的那样工作。例如,接入 Spotify 频道时,你只能使用最热门的曲目(而无法使用播放列表,或搜索歌曲的功能)。
|
||||||
|
|
||||||
|
使用 Clementine 互联网流媒体服务时,你会发现其中有很多你从来没有听说过的音乐家和乐队(图 2)。
|
||||||
|
|
||||||
|
![Clementine][5]
|
||||||
|
|
||||||
|
*图 2:Clementine 互联网广播是寻找新音乐的好方法。*
|
||||||
|
|
||||||
|
### Odio
|
||||||
|
|
||||||
|
Odio 是一个跨平台的专有应用程序(可用于 Linux、MacOS 和 Windows),它允许你流式传输各种类型的互联网音乐站。广播的内容是取自 [www.radio-browser.info][6],而应用程序本身在为你呈现流方面做了令人难以置信的工作(图 3)。
|
||||||
|
|
||||||
|
![Odio][8]
|
||||||
|
|
||||||
|
*图 3:Odio 接口是你能找到的最好的接口之一。*
|
||||||
|
|
||||||
|
Odio 让你很容易找到独特的互联网广播电台,甚至可以把你找到并收藏的电台添加到你的库中。目前,在 Linux 上安装 Odio 的唯一方法是通过 Snap。如果你的发行版支持 snap 软件包,请使用以下命令安装此流应用程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo snap install odio
|
||||||
|
```
|
||||||
|
|
||||||
|
安装后,你可以打开应用程序并开始使用它。无需登录(或创建)帐户。Odio 的设置非常有限。实际上,它只提供了在设置窗口中选择暗色主题或亮色主题的选项。然而,尽管它可能功能有限,但 Odio 是在 Linux 上播放互联网广播的最佳选择之一。
|
||||||
|
|
||||||
|
### StreamTuner2
|
||||||
|
|
||||||
|
Streamtuner2 是一个优秀的互联网电台 GUI 工具。使用它,你可以流式播放以下音乐:
|
||||||
|
|
||||||
|
* Internet radio stations
|
||||||
|
* Jameno
|
||||||
|
* MyOggRadio
|
||||||
|
* Shoutcast.com
|
||||||
|
* SurfMusic
|
||||||
|
* TuneIn
|
||||||
|
* Xiph.org
|
||||||
|
* YouTube
|
||||||
|
|
||||||
|
Streamtuner2 提供了一个很好的界面(如果不是有点过时的话),可以很容易地找到和播放你喜爱的音乐。StreamTuner2 的一个警告是,它实际上只是一个用于查找你想要听到的流媒体的 GUI。当你找到一个站点时,双击它打开与流相关的应用程序。这意味着你必须安装必要的应用程序,才能播放流媒体。如果你没有合适的应用程序,你就不能播放流媒体。因此,你将花费大量的时间来确定要为某些流媒体安装哪些应用程序(图 4)。
|
||||||
|
|
||||||
|
![Streamtuner2][10]
|
||||||
|
|
||||||
|
*图4:配置 Streamtuner2 需要一个坚强的心脏。*
|
||||||
|
|
||||||
|
### VLC
|
||||||
|
|
||||||
|
很长一段时间以来,VLC 一直被称为 Linux 最好的媒体播放工具。这是有充分理由的,因为几乎所有你丢给它的东西它都能播放。其中包括流媒体广播电台。虽然你无法让 VLC 连接到 Spotify 这样的网站,但你可以直接访问互联网广播,点击播放列表,而 VLC 毫无疑问可以打开它。考虑到目前有很多互联网广播电台,你在寻找适合自己口味的音乐方面不会有任何问题。VLC 还包括可视化工具、均衡器(图 5)等工具。
|
||||||
|
|
||||||
|
![VLC ][12]
|
||||||
|
|
||||||
|
*图 5:VLC 可视化工具和均衡器特性。*
|
||||||
|
|
||||||
|
VLC 唯一需要注意的是,你必须有一个你希望听到的互联网广播的 URL,因为这个工具本身并不能进行管理。但是有了这些链接,你就找不到比 VLC 更好的媒体播放器了。
|
||||||
|
|
||||||
|
### 这些工具软件怎么来的
|
||||||
|
|
||||||
|
如果这五个工具都不太不适合你的需要,我建议你打开你发行版的应用商店,搜索一个适合你的。有很多工具可以制作流媒体音乐、播客等等,不仅可以在 Linux 上实现,而且很简单。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.linux.com/blog/2019/2/5-streaming-audio-players-linux
|
||||||
|
|
||||||
|
作者:[Jack Wallen][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.linux.com/users/jlwallen
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[2]: https://lcom.static.linuxfound.org/sites/lcom/files/spotify_0.jpg?itok=8-Ym-R61 (Spotify)
|
||||||
|
[3]: https://www.linux.com/licenses/category/used-permission
|
||||||
|
[5]: https://lcom.static.linuxfound.org/sites/lcom/files/clementine_0.jpg?itok=5oODJO3b (Clementine)
|
||||||
|
[6]: http://www.radio-browser.info
|
||||||
|
[8]: https://lcom.static.linuxfound.org/sites/lcom/files/odio.jpg?itok=sNPTSS3c (Odio)
|
||||||
|
[10]: https://lcom.static.linuxfound.org/sites/lcom/files/streamtuner2.jpg?itok=1MSbafWj (Streamtuner2)
|
||||||
|
[12]: https://lcom.static.linuxfound.org/sites/lcom/files/vlc_0.jpg?itok=QEOsq7Ii (VLC )
|
||||||
|
[13]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -0,0 +1,436 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13041-1.html)
|
||||||
|
[#]: subject: (Install Apache, MySQL, PHP \(LAMP\) Stack On Ubuntu 18.04 LTS)
|
||||||
|
[#]: via: (https://www.ostechnix.com/install-apache-mysql-php-lamp-stack-on-ubuntu-18-04-lts/)
|
||||||
|
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||||
|
|
||||||
|
在 Ubuntu 中安装 Apache、MySQL、PHP(LAMP)套件
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/02/lamp-720x340.jpg)
|
||||||
|
|
||||||
|
**LAMP** 套件是一种流行的开源 Web 开发平台,可用于运行和部署动态网站和基于 Web 的应用程序。通常,LAMP 套件由 Apache Web 服务器、MariaDB/MySQL 数据库、PHP/Python/Perl 程序设计(脚本)语言组成。 LAMP 是 **L**inux,**M**ariaDB/**M**YSQL,**P**HP/**P**ython/**P**erl 的缩写。 本教程描述了如何在 Ubuntu 18.04 LTS 服务器中安装 Apache、MySQL、PHP(LAMP 套件)。
|
||||||
|
|
||||||
|
就本教程而言,我们将使用以下 Ubuntu 测试。
|
||||||
|
|
||||||
|
* **操作系统**:Ubuntu 18.04.1 LTS Server Edition
|
||||||
|
* **IP 地址** :192.168.225.22/24
|
||||||
|
|
||||||
|
### 1. 安装 Apache Web 服务器
|
||||||
|
|
||||||
|
首先,利用下面命令更新 Ubuntu 服务器:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
然后,安装 Apache Web 服务器(命令如下):
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt install apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
检查 Apache Web 服务器是否已经运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl status apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果大概是这样的:
|
||||||
|
|
||||||
|
```
|
||||||
|
● apache2.service - The Apache HTTP Server
|
||||||
|
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: en
|
||||||
|
Drop-In: /lib/systemd/system/apache2.service.d
|
||||||
|
└─apache2-systemd.conf
|
||||||
|
Active: active (running) since Tue 2019-02-05 10:48:03 UTC; 1min 5s ago
|
||||||
|
Main PID: 2025 (apache2)
|
||||||
|
Tasks: 55 (limit: 2320)
|
||||||
|
CGroup: /system.slice/apache2.service
|
||||||
|
├─2025 /usr/sbin/apache2 -k start
|
||||||
|
├─2027 /usr/sbin/apache2 -k start
|
||||||
|
└─2028 /usr/sbin/apache2 -k start
|
||||||
|
|
||||||
|
Feb 05 10:48:02 ubuntuserver systemd[1]: Starting The Apache HTTP Server...
|
||||||
|
Feb 05 10:48:03 ubuntuserver apachectl[2003]: AH00558: apache2: Could not reliably
|
||||||
|
Feb 05 10:48:03 ubuntuserver systemd[1]: Started The Apache HTTP Server.
|
||||||
|
```
|
||||||
|
|
||||||
|
祝贺你! Apache 服务已经启动并运行了!!
|
||||||
|
|
||||||
|
#### 1.1 调整防火墙允许 Apache Web 服务器
|
||||||
|
|
||||||
|
默认情况下,如果你已在 Ubuntu 中启用 UFW 防火墙,则无法从远程系统访问 Apache Web 服务器。 必须按照以下步骤开启 `http` 和 `https` 端口。
|
||||||
|
|
||||||
|
首先,使用以下命令列出 Ubuntu 系统上可用的应用程序配置文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo ufw app list
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
Available applications:
|
||||||
|
Apache
|
||||||
|
Apache Full
|
||||||
|
Apache Secure
|
||||||
|
OpenSSH
|
||||||
|
```
|
||||||
|
|
||||||
|
如你所见,Apache 和 OpenSSH 应用程序已安装 UFW 配置文件。你可以使用 `ufw app info "Profile Name"` 命令列出有关每个配置文件及其包含的规则的信息。
|
||||||
|
|
||||||
|
让我们研究一下 “Apache Full” 配置文件。 为此,请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo ufw app info "Apache Full"
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
Profile: Apache Full
|
||||||
|
Title: Web Server (HTTP,HTTPS)
|
||||||
|
Description: Apache v2 is the next generation of the omnipresent Apache web
|
||||||
|
server.
|
||||||
|
|
||||||
|
Ports:
|
||||||
|
80,443/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
如你所见,“Apache Full” 配置文件包含了启用经由端口 **80** 和 **443** 的传输规则:
|
||||||
|
|
||||||
|
现在,运行以下命令配置允许 HTTP 和 HTTPS 传入通信:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo ufw allow in "Apache Full"
|
||||||
|
Rules updated
|
||||||
|
Rules updated (v6)
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你不想允许 HTTP 通信,而只允许 HTTP(80) 通信,请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo ufw app info "Apache"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 测试 Apache Web 服务器
|
||||||
|
|
||||||
|
现在,打开 Web 浏览器并导航到 <http://localhost/> 或 <http://IP-Address/> 来访问 Apache 测试页。
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2016/06/apache-2.png)
|
||||||
|
|
||||||
|
如果看到上面类似的显示内容,那就成功了。 Apache 服务器正在工作!
|
||||||
|
|
||||||
|
### 2. 安装 MySQL
|
||||||
|
|
||||||
|
在 Ubuntu 安装 MySQL 请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt install mysql-server
|
||||||
|
```
|
||||||
|
|
||||||
|
使用以下命令验证 MySQL 服务是否正在运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl status mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
● mysql.service - MySQL Community Server
|
||||||
|
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enab
|
||||||
|
Active: active (running) since Tue 2019-02-05 11:07:50 UTC; 17s ago
|
||||||
|
Main PID: 3423 (mysqld)
|
||||||
|
Tasks: 27 (limit: 2320)
|
||||||
|
CGroup: /system.slice/mysql.service
|
||||||
|
└─3423 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
|
||||||
|
|
||||||
|
Feb 05 11:07:49 ubuntuserver systemd[1]: Starting MySQL Community Server...
|
||||||
|
Feb 05 11:07:50 ubuntuserver systemd[1]: Started MySQL Community Server.
|
||||||
|
```
|
||||||
|
|
||||||
|
MySQL 正在运行!
|
||||||
|
|
||||||
|
#### 2.1 配置数据库管理用户(root)密码
|
||||||
|
|
||||||
|
默认情况下,MySQL root 用户密码为空。你需要通过运行以下脚本使你的 MySQL 服务器安全:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo mysql_secure_installation
|
||||||
|
```
|
||||||
|
|
||||||
|
系统将询问你是否要安装 “VALIDATE PASSWORD plugin(密码验证插件)”。该插件允许用户为数据库配置强密码凭据。如果启用,它将自动检查密码的强度并强制用户设置足够安全的密码。**禁用此插件是安全的**。但是,必须为数据库使用唯一的强密码凭据。如果不想启用此插件,只需按任意键即可跳过密码验证部分,然后继续其余步骤。
|
||||||
|
|
||||||
|
如果回答是 `y`,则会要求你选择密码验证级别。
|
||||||
|
|
||||||
|
```
|
||||||
|
Securing the MySQL server deployment.
|
||||||
|
|
||||||
|
Connecting to MySQL using a blank password.
|
||||||
|
|
||||||
|
VALIDATE PASSWORD PLUGIN can be used to test passwords
|
||||||
|
and improve security. It checks the strength of password
|
||||||
|
and allows the users to set only those passwords which are
|
||||||
|
secure enough. Would you like to setup VALIDATE PASSWORD plugin?
|
||||||
|
|
||||||
|
Press y|Y for Yes, any other key for No y
|
||||||
|
```
|
||||||
|
|
||||||
|
可用的密码验证有 “low(低)”、 “medium(中)” 和 “strong(强)”。只需输入适当的数字(0 表示低,1 表示中,2 表示强密码)并按回车键。
|
||||||
|
|
||||||
|
```
|
||||||
|
There are three levels of password validation policy:
|
||||||
|
|
||||||
|
LOW Length >= 8
|
||||||
|
MEDIUM Length >= 8, numeric, mixed case, and special characters
|
||||||
|
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
|
||||||
|
|
||||||
|
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG:
|
||||||
|
```
|
||||||
|
|
||||||
|
现在,输入 MySQL root 用户的密码。请注意,必须根据上一步中选择的密码策略,为 MySQL root 用户使用密码。如果你未启用该插件,则只需使用你选择的任意强度且唯一的密码即可。
|
||||||
|
|
||||||
|
```
|
||||||
|
Please set the password for root here.
|
||||||
|
|
||||||
|
New password:
|
||||||
|
|
||||||
|
Re-enter new password:
|
||||||
|
|
||||||
|
Estimated strength of the password: 50
|
||||||
|
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
|
||||||
|
```
|
||||||
|
|
||||||
|
两次输入密码后,你将看到密码强度(在此示例情况下为 50)。如果你确定可以,请按 `y` 继续提供的密码。如果对密码长度不满意,请按其他任意键并设置一个强密码。我现在的密码可以,所以我选择了`y`。
|
||||||
|
|
||||||
|
对于其余的问题,只需键入 `y` 并按回车键。这将删除匿名用户、禁止 root 用户远程登录并删除 `test`(测试)数据库。
|
||||||
|
|
||||||
|
```
|
||||||
|
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
|
||||||
|
Success.
|
||||||
|
|
||||||
|
Normally, root should only be allowed to connect from
|
||||||
|
'localhost'. This ensures that someone cannot guess at
|
||||||
|
the root password from the network.
|
||||||
|
|
||||||
|
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
|
||||||
|
Success.
|
||||||
|
|
||||||
|
By default, MySQL comes with a database named 'test' that
|
||||||
|
anyone can access. This is also intended only for testing,
|
||||||
|
and should be removed before moving into a production
|
||||||
|
environment.
|
||||||
|
|
||||||
|
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
|
||||||
|
- Dropping test database...
|
||||||
|
Success.
|
||||||
|
|
||||||
|
- Removing privileges on test database...
|
||||||
|
Success.
|
||||||
|
|
||||||
|
Reloading the privilege tables will ensure that all changes
|
||||||
|
made so far will take effect immediately.
|
||||||
|
|
||||||
|
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
|
||||||
|
Success.
|
||||||
|
|
||||||
|
All done!
|
||||||
|
```
|
||||||
|
|
||||||
|
以上就是为 MySQL root 用户设置密码。
|
||||||
|
|
||||||
|
#### 2.2 更改 MySQL 超级用户的身份验证方法
|
||||||
|
|
||||||
|
默认情况下,Ubuntu 系统的 MySQL root 用户为 MySQL 5.7 版本及更新的版本使用插件 `auth_socket` 设置身份验证。尽管它增强了安全性,但是当你使用任何外部程序(例如 phpMyAdmin)访问数据库服务器时,也会变得更困难。要解决此问题,你需要将身份验证方法从 `auth_socket` 更改为 `mysql_native_password`。为此,请使用以下命令登录到你的 MySQL 提示符下:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
在 MySQL 提示符下运行以下命令,找到所有 MySQL 当前用户帐户的身份验证方法:
|
||||||
|
|
||||||
|
```
|
||||||
|
SELECT user,authentication_string,plugin,host FROM mysql.user;
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
+------------------|-------------------------------------------|-----------------------|-----------+
|
||||||
|
| user | authentication_string | plugin | host |
|
||||||
|
+------------------|-------------------------------------------|-----------------------|-----------+
|
||||||
|
| root | | auth_socket | localhost |
|
||||||
|
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
|
||||||
|
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
|
||||||
|
| debian-sys-maint | *F126737722832701DD3979741508F05FA71E5BA0 | mysql_native_password | localhost |
|
||||||
|
+------------------|-------------------------------------------|-----------------------|-----------+
|
||||||
|
4 rows in set (0.00 sec)
|
||||||
|
```
|
||||||
|
|
||||||
|
![][2]
|
||||||
|
|
||||||
|
如你所见,Mysql root 用户使用 `auth_socket` 插件进行身份验证。
|
||||||
|
|
||||||
|
要将此身份验证更改为 `mysql_native_password` 方法,请在 MySQL 提示符下运行以下命令。 别忘了用你选择的强大唯一的密码替换 `password`。 如果已启用 VALIDATION 插件,请确保已根据当前策略要求使用了强密码。
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
|
||||||
|
```
|
||||||
|
|
||||||
|
使用以下命令更新数据库:
|
||||||
|
|
||||||
|
```
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
```
|
||||||
|
|
||||||
|
使用命令再次检查身份验证方法是否已更改:
|
||||||
|
|
||||||
|
```
|
||||||
|
SELECT user,authentication_string,plugin,host FROM mysql.user;
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
好!MySQL root 用户就可以使用密码进行身份验证来访问 `mysql shell`。
|
||||||
|
|
||||||
|
从 MySQL 提示符下退出:
|
||||||
|
|
||||||
|
```
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 安装 PHP
|
||||||
|
|
||||||
|
安装 PHP 请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt install php libapache2-mod-php php-mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
安装 PHP 后,在 Apache 文档根目录中创建 `info.php` 文件。通常,在大多数基于 Debian 的 Linux 发行版中,Apache 文档根目录为 `/var/www/html/` 或 `/var/www/`。Ubuntu 18.04 LTS 系统下,文档根目录是 `/var/www/html/`。
|
||||||
|
|
||||||
|
在 Apache 根目录中创建 `info.php` 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo vi /var/www/html/info.php
|
||||||
|
```
|
||||||
|
|
||||||
|
在此文件中编辑如下内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
<?php
|
||||||
|
phpinfo();
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
然后按下 `ESC` 键并且输入 `:wq` 保存并退出此文件。重新启动 Apache 服务使更改生效。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.1 测试 PHP
|
||||||
|
|
||||||
|
打开 Web 浏览器,然后导航到 URL <http://IP地址/info.php>。
|
||||||
|
|
||||||
|
你就将看到 PHP 测试页面。
|
||||||
|
|
||||||
|
![](https://www.ostechnix.com/wp-content/uploads/2019/02/php-test-page.png)
|
||||||
|
|
||||||
|
通常,当用户向 Web 服务器发出请求时,Apache 首先会在文档根目录中查找名为 `index.html` 的文件。如果你想将 Apache 更改为 `php` 文件提供服务而不是其他文件,请将 `dir.conf` 配置文件中的 `index.php` 移至第一个位置,如下所示:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo vi /etc/apache2/mods-enabled/dir.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的配置文件(`dir.conf`) 内容如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
<IfModule mod_dir.c>
|
||||||
|
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
|
```
|
||||||
|
|
||||||
|
将 `index.php` 移动到最前面。更改后,`dir.conf` 文件内容看起来如下所示。
|
||||||
|
|
||||||
|
```
|
||||||
|
<IfModule mod_dir.c>
|
||||||
|
DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
|
```
|
||||||
|
|
||||||
|
然后按下 `ESC` 键并且输入 `:wq` 保存并关闭此文件。重新启动 Apache 服务使更改生效。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl restart apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 安装 PHP 模块
|
||||||
|
|
||||||
|
为了增加 PHP 的功能,可以安装一些其他的 PHP 模块。
|
||||||
|
|
||||||
|
要列出可用的 PHP 模块,请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-cache search php- | less
|
||||||
|
```
|
||||||
|
|
||||||
|
输出结果:
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
使用方向键浏览结果。要退出,请输入 `q` 并按下回车键。
|
||||||
|
|
||||||
|
要查找任意 `php` 模块的详细信息,例如 `php-gd`,请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-cache show php-gd
|
||||||
|
```
|
||||||
|
|
||||||
|
安装 PHP 模块请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt install php-gd
|
||||||
|
```
|
||||||
|
|
||||||
|
安装所有的模块(虽然没有必要),请运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-get install php*
|
||||||
|
```
|
||||||
|
|
||||||
|
安装任何 `php` 模块后,请不要忘记重新启动 Apache 服务。要检查模块是否已加载,请在浏览器中打开 `info.php` 文件并检查是否存在。
|
||||||
|
|
||||||
|
接下来,你可能需要安装数据库管理工具,以通过 Web 浏览器轻松管理数据库。如果是这样,请按照以下链接中的说明安装 `phpMyAdmin`。
|
||||||
|
|
||||||
|
祝贺你!我们已经在 Ubuntu 服务器中成功配置了 LAMP 套件。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.ostechnix.com/install-apache-mysql-php-lamp-stack-on-ubuntu-18-04-lts/
|
||||||
|
|
||||||
|
作者:[SK][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.ostechnix.com/author/sk/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||||
|
[2]: http://www.ostechnix.com/wp-content/uploads/2019/02/mysql-1.png
|
||||||
|
[3]: http://www.ostechnix.com/wp-content/uploads/2019/02/mysql-2.png
|
||||||
|
[4]: http://www.ostechnix.com/wp-content/uploads/2016/06/php-modules.png
|
@ -0,0 +1,261 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13052-1.html)
|
||||||
|
[#]: subject: (Make websites more readable with a shell script)
|
||||||
|
[#]: via: (https://opensource.com/article/19/2/make-websites-more-readable-shell-script)
|
||||||
|
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||||
|
|
||||||
|
利用 Shell 脚本让网站更具可读性
|
||||||
|
======
|
||||||
|
|
||||||
|
> 测算网站的文本和背景之间的对比度,以确保站点易于阅读。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/25/231152ce5ufhjtufxj1eeu.jpg)
|
||||||
|
|
||||||
|
如果希望人们发现你的网站实用,那么他们需要能够阅读它。为文本选择的颜色可能会影响网站的可读性。不幸的是,网页设计中的一种流行趋势是在打印输出文本时使用低对比度的颜色,就像在白色背景上的灰色文本。对于 Web 设计师来说,这也许看起来很酷,但对于许多阅读它的人来说确实很困难。
|
||||||
|
|
||||||
|
W3C 提供了《<ruby>Web 内容可访问性指南<rt>Web Content Accessibility Guidelines</rt></ruby>》,其中包括帮助 Web 设计人员选择易于区分文本和背景色的指导。z这就是所谓的“<ruby>对比度<rt>contrast ratio</rt></ruby>”。 W3C 定义的对比度需要进行一些计算:给定两种颜色,首先计算每种颜色的相对亮度,然后计算对比度。对比度在 1 到 21 的范围内(通常写为 1:1 到 21:1)。对比度越高,文本在背景下的突出程度就越高。例如,白色背景上的黑色文本非常醒目,对比度为 21:1。对比度为 1:1 的白色背景上的白色文本不可读。
|
||||||
|
|
||||||
|
[W3C 说,正文][1] 的对比度至少应为 4.5:1,标题至少应为 3:1。但这似乎是最低限度的要求。W3C 还建议正文至少 7:1,标题至少 4.5:1。
|
||||||
|
|
||||||
|
计算对比度可能比较麻烦,因此最好将其自动化。我已经用这个方便的 Bash 脚本做到了这一点。通常,脚本执行以下操作:
|
||||||
|
|
||||||
|
1. 获取文本颜色和背景颜色
|
||||||
|
2. 计算相对亮度
|
||||||
|
3. 计算对比度
|
||||||
|
|
||||||
|
### 获取颜色
|
||||||
|
|
||||||
|
你可能知道显示器上的每种颜色都可以用红色、绿色和蓝色(R、G 和 B)来表示。要计算颜色的相对亮度,脚本需要知道颜色的红、绿和蓝的各个分量。理想情况下,脚本会将这些信息读取为单独的 R、G 和 B 值。 Web 设计人员可能知道他们喜欢的颜色的特定 RGB 代码,但是大多数人不知道不同颜色的 RGB 值。作为一种替代的方法是,大多数人通过 “red” 或 “gold” 或 “maroon” 之类的名称来引用颜色。
|
||||||
|
|
||||||
|
幸运的是,GNOME 的 [Zenity][2] 工具有一个颜色选择器应用程序,可让你使用不同的方法选择颜色,然后用可预测的格式 `rgb(R,G,B)` 返回 RGB 值。使用 Zenity 可以轻松获得颜色值:
|
||||||
|
|
||||||
|
```
|
||||||
|
color=$( zenity --title 'Set text color' --color-selection --color='black' )
|
||||||
|
```
|
||||||
|
|
||||||
|
如果用户(意外地)单击 “Cancel(取消)” 按钮,脚本将假定一种颜色:
|
||||||
|
|
||||||
|
```
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
echo '** color canceled .. assume black'
|
||||||
|
color='rgb(0,0,0)'
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本对背景颜色值也执行了类似的操作,将其设置为 `$background`。
|
||||||
|
|
||||||
|
### 计算相对亮度
|
||||||
|
|
||||||
|
一旦你在 `$color` 中设置了前景色,并在 `$background` 中设置了背景色,下一步就是计算每种颜色的相对亮度。 [W3C 提供了一个算法][3] 用以计算颜色的相对亮度。
|
||||||
|
|
||||||
|
> 对于 sRGB 色彩空间,一种颜色的相对亮度定义为:
|
||||||
|
>
|
||||||
|
> L = 0.2126 * R + 0.7152 * G + 0.0722 * B
|
||||||
|
>
|
||||||
|
> R、G 和 B 定义为:
|
||||||
|
>
|
||||||
|
> if $R_{sRGB}$ <= 0.03928 then R = $R_{sRGB}$/12.92
|
||||||
|
>
|
||||||
|
> else R = (($R_{sRGB}$+0.055)/1.055) $^{2.4}$
|
||||||
|
>
|
||||||
|
> if $G_{sRGB}$ <= 0.03928 then G = $G_{sRGB}$/12.92
|
||||||
|
>
|
||||||
|
> else G = (($G_{sRGB}$+0.055)/1.055) $^{2.4}$
|
||||||
|
>
|
||||||
|
> if $B_{sRGB}$ <= 0.03928 then B = $B_{sRGB}$/12.92
|
||||||
|
>
|
||||||
|
> else B = (($B_{sRGB}$+0.055)/1.055) $^{2.4}$
|
||||||
|
>
|
||||||
|
> $R_{sRGB}$、$G_{sRGB}$ 和 $B_{sRGB}$ 定义为:
|
||||||
|
>
|
||||||
|
> $R_{sRGB}$ = $R_{8bit}$/255
|
||||||
|
>
|
||||||
|
> $G_{sRGB}$ = $G_{8bit}$/255
|
||||||
|
>
|
||||||
|
> $B_{sRGB}$ = $B_{8bit}$/255
|
||||||
|
|
||||||
|
由于 Zenity 以 `rgb(R,G,B)` 的格式返回颜色值,因此脚本可以轻松拉取分隔开的 R、B 和 G 的值以计算相对亮度。AWK 可以使用逗号作为字段分隔符(`-F,`),并使用 `substr()` 字符串函数从 `rgb(R,G,B)` 中提取所要的颜色值:
|
||||||
|
|
||||||
|
```
|
||||||
|
R=$( echo $color | awk -F, '{print substr($1,5)}' )
|
||||||
|
G=$( echo $color | awk -F, '{print $2}' )
|
||||||
|
B=$( echo $color | awk -F, '{n=length($3); print substr($3,1,n-1)}' )
|
||||||
|
```
|
||||||
|
|
||||||
|
*有关使用 AWK 提取和显示数据的更多信息,[查看 AWK 备忘表][4]*
|
||||||
|
|
||||||
|
最好使用 BC 计算器来计算最终的相对亮度。BC 支持计算中所需的简单 `if-then-else`,这使得这一过程变得简单。但是由于 BC 无法使用非整数指数直接计算乘幂,因此需要使用自然对数替代它做一些额外的数学运算:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo "scale=4
|
||||||
|
rsrgb=$R/255
|
||||||
|
gsrgb=$G/255
|
||||||
|
bsrgb=$B/255
|
||||||
|
if ( rsrgb <= 0.03928 ) r = rsrgb/12.92 else r = e( 2.4 * l((rsrgb+0.055)/1.055) )
|
||||||
|
if ( gsrgb <= 0.03928 ) g = gsrgb/12.92 else g = e( 2.4 * l((gsrgb+0.055)/1.055) )
|
||||||
|
if ( bsrgb <= 0.03928 ) b = bsrgb/12.92 else b = e( 2.4 * l((bsrgb+0.055)/1.055) )
|
||||||
|
0.2126 * r + 0.7152 * g + 0.0722 * b" | bc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
这会将一些指令传递给 BC,包括作为相对亮度公式一部分的 `if-then-else` 语句。接下来 BC 打印出最终值。
|
||||||
|
|
||||||
|
### 计算对比度
|
||||||
|
|
||||||
|
利用文本颜色和背景颜色的相对亮度,脚本就可以计算对比度了。 [W3C 确定对比度][5] 是使用以下公式:
|
||||||
|
|
||||||
|
> (L1 + 0.05) / (L2 + 0.05),这里的
|
||||||
|
> L1 是颜色较浅的相对亮度,
|
||||||
|
> L2 是颜色较深的相对亮度。
|
||||||
|
|
||||||
|
给定两个相对亮度值 `$r1` 和 `$r2`,使用 BC 计算器很容易计算对比度:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo "scale=2
|
||||||
|
if ( $r1 > $r2 ) { l1=$r1; l2=$r2 } else { l1=$r2; l2=$r1 }
|
||||||
|
(l1 + 0.05) / (l2 + 0.05)" | bc
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `if-then-else` 语句确定哪个值(`$r1` 或 `$r2`)是较浅还是较深的颜色。BC 执行结果计算并打印结果,脚本可以将其存储在变量中。
|
||||||
|
|
||||||
|
### 最终脚本
|
||||||
|
|
||||||
|
通过以上内容,我们可以将所有内容整合到一个最终脚本。 我使用 Zenity 在文本框中显示最终结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/sh
|
||||||
|
# script to calculate contrast ratio of colors
|
||||||
|
|
||||||
|
# read color and background color:
|
||||||
|
# zenity returns values like 'rgb(255,140,0)' and 'rgb(255,255,255)'
|
||||||
|
|
||||||
|
color=$( zenity --title 'Set text color' --color-selection --color='black' )
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
echo '** color canceled .. assume black'
|
||||||
|
color='rgb(0,0,0)'
|
||||||
|
fi
|
||||||
|
|
||||||
|
background=$( zenity --title 'Set background color' --color-selection --color='white' )
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
echo '** background canceled .. assume white'
|
||||||
|
background='rgb(255,255,255)'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compute relative luminance:
|
||||||
|
|
||||||
|
function luminance()
|
||||||
|
{
|
||||||
|
R=$( echo $1 | awk -F, '{print substr($1,5)}' )
|
||||||
|
G=$( echo $1 | awk -F, '{print $2}' )
|
||||||
|
B=$( echo $1 | awk -F, '{n=length($3); print substr($3,1,n-1)}' )
|
||||||
|
|
||||||
|
echo "scale=4
|
||||||
|
rsrgb=$R/255
|
||||||
|
gsrgb=$G/255
|
||||||
|
bsrgb=$B/255
|
||||||
|
if ( rsrgb <= 0.03928 ) r = rsrgb/12.92 else r = e( 2.4 * l((rsrgb+0.055)/1.055) )
|
||||||
|
if ( gsrgb <= 0.03928 ) g = gsrgb/12.92 else g = e( 2.4 * l((gsrgb+0.055)/1.055) )
|
||||||
|
if ( bsrgb <= 0.03928 ) b = bsrgb/12.92 else b = e( 2.4 * l((bsrgb+0.055)/1.055) )
|
||||||
|
0.2126 * r + 0.7152 * g + 0.0722 * b" | bc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
lum1=$( luminance $color )
|
||||||
|
lum2=$( luminance $background )
|
||||||
|
|
||||||
|
# compute contrast
|
||||||
|
|
||||||
|
function contrast()
|
||||||
|
{
|
||||||
|
echo "scale=2
|
||||||
|
if ( $1 > $2 ) { l1=$1; l2=$2 } else { l1=$2; l2=$1 }
|
||||||
|
(l1 + 0.05) / (l2 + 0.05)" | bc
|
||||||
|
}
|
||||||
|
|
||||||
|
rel=$( contrast $lum1 $lum2 )
|
||||||
|
|
||||||
|
# print results
|
||||||
|
|
||||||
|
( cat<<EOF
|
||||||
|
Color is $color on $background
|
||||||
|
|
||||||
|
Contrast ratio is $rel
|
||||||
|
Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1).
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ ${rel%.*} -ge 4 ] ; then
|
||||||
|
echo "Ok for body text"
|
||||||
|
else
|
||||||
|
echo "Not good for body text"
|
||||||
|
fi
|
||||||
|
if [ ${rel%.*} -ge 3 ] ; then
|
||||||
|
echo "Ok for title text"
|
||||||
|
else
|
||||||
|
echo "Not good for title text"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat<<EOF
|
||||||
|
|
||||||
|
W3C 说明:
|
||||||
|
|
||||||
|
1.4.3 对比度(最小值):文本和文本图像的视觉呈现方式的对比度至少为 4.5:1,但以下情况除外:(AA 级)
|
||||||
|
|
||||||
|
大文本:大文本和大文本图像的对比度至少为 3:1;
|
||||||
|
|
||||||
|
附带说明:作为非活动用户界面组件一部分,纯装饰的,任何人都不可见或图片的一部分包含特定的其他可视内容的文本或文本图像没有对比度要求。
|
||||||
|
|
||||||
|
小示意图:徽标或商标名称中的文本没有最低对比度要求。
|
||||||
|
|
||||||
|
1.4.6 对比度(增强):文本和文本图像的视觉表示具有至少 7:1 的对比度,但以下情况除外:(AAA 级)
|
||||||
|
|
||||||
|
大文本:大文本和大文本图像的对比度至少为 4.5:1;
|
||||||
|
|
||||||
|
附带说明:作为非活动用户界面组件一部分,纯装饰的,任何人都不可见或图片的一部分包含特定的其他可视内容的文本或文本图像没有对比度要求。
|
||||||
|
|
||||||
|
小示意图:徽标或商标名称中的文本没有最低对比度要求。
|
||||||
|
EOF
|
||||||
|
) | zenity --text-info --title='Relative Luminance' --width=800 --height=600
|
||||||
|
```
|
||||||
|
|
||||||
|
最后,我希望提供有关 W3C 建议的参考信息,以提醒自己。
|
||||||
|
|
||||||
|
Zenity 颜色选择器完成了所有解释颜色的艰苦工作,用户可以通过单击色轮或输入值来选择颜色。 Zenity 接受网站上使用的标准十六进制颜色值,例如 `#000000` 或 `#000`或 `rgb(0,0,0)`(所有这些均为黑色)。这是白色背景上的黑色文本的示例计算:
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot1-a.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot1-b.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/relativeluminescence1-result.png)
|
||||||
|
|
||||||
|
Zenity 还识别标准的颜色名称,如“cadetblue”、“orange”或“gold”。在Zenity 中输入颜色名称,然后点击 `Tab` 键,Zenity 会将颜色名称转换为十六进制颜色值,如以下示例中对金色背景上的黑色文本的计算:
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot2-a-name.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot2-a-value.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot2-b-name.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/zenity_screenshot2-b-value.png)
|
||||||
|
|
||||||
|
![](https://opensource.com/sites/default/files/uploads/relativeluminescence2-result.png)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/2/make-websites-more-readable-shell-script
|
||||||
|
|
||||||
|
作者:[Jim Hall][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/jim-hall
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast
|
||||||
|
[2]: https://wiki.gnome.org/Projects/Zenity
|
||||||
|
[3]: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||||
|
[4]: https://opensource.com/article/18/7/cheat-sheet-awk
|
||||||
|
[5]: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
@ -0,0 +1,89 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13023-1.html)
|
||||||
|
[#]: subject: (Do Linux distributions still matter with containers?)
|
||||||
|
[#]: via: (https://opensource.com/article/19/2/linux-distributions-still-matter-containers)
|
||||||
|
[#]: author: (Scott McCarty https://opensource.com/users/fatherlinux)
|
||||||
|
|
||||||
|
容器开发仍然要考虑 Linux 发行版吗?
|
||||||
|
======
|
||||||
|
|
||||||
|
> 容器构建有两大趋势:使用基本镜像和从头开始构建。每个都有工程上的权衡。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/16/223919aubhguedlt8sk8i8.jpg)
|
||||||
|
|
||||||
|
有人说 Linux 发行版不再与容器有关。像 distroless 和 scratch 容器等可替代的方法,似乎是风靡一时。看来,我们在考虑和做出技术决策时,更多的是基于时尚感和即时的情感满足,而不是考虑我们选择的次要影响。我们应该问这样的问题:这些选择将如何影响未来六个月的维护?工程权衡是什么?这种范式转换如何影响我们的大规模构建系统?
|
||||||
|
|
||||||
|
这真让人沮丧。如果我们忘记了工程是一个零和游戏,有可衡量的利弊权衡,有不同方法的成本和收益 —— 这样对我们自己不利,对雇主不利,对最终维护我们的代码的同事不利。最后,我们对所有的维护人员([向维护人员致敬!][1] )都是一种伤害,因为我们不欣赏他们所做的工作。
|
||||||
|
|
||||||
|
### 理解问题所在
|
||||||
|
|
||||||
|
为了理解这个问题,我们必须首先研究为什么我们使用 Linux 发行版。我将把原因分为两大类:内核和其他包。编译内核实际上相当容易。Slackware 和 Gentoo( 我的小心脏还是有点害怕)教会了我们这一点。
|
||||||
|
|
||||||
|
另一方面,对于一个可用的 Linux 系统需要打包大量的开发软件和应用软件,这可能会让人望而生畏。此外,确保数百万个程序包可以一起安装和工作的唯一方法是使用旧的范例:即编译它并将它作为一个工件(即 Linux 发行版)一起发布。那么,为什么 Linux 发行版要将内核和所有包一起编译呢?很简单:确保事情协调一致。
|
||||||
|
|
||||||
|
首先,我们来谈谈内核。内核很特别。在没有编译好的内核的情况下引导 Linux 系统有点困难。它是 Linux 操作系统的核心,也是我们在系统启动时首先依赖的。内核在编译时有很多不同的配置选项,这些选项会对硬件和软件如何在一个内核上运行产生巨大影响。这方面中的第二个问题是,系统软件(如编译器 、C 库和解释器)必须针对内核中内置的选项进行调优。Gentoo 的维基以一种发自内心的方式教我们这一点,它把每个人都变成了一个微型的开发版维护者。
|
||||||
|
|
||||||
|
令人尴尬的是(因为我在过去五年里一直在使用容器),我必须承认我最近才编译过内核。我必须让嵌套的 KVM 在 RHEL7 上工作,这样我才能在笔记本电脑上的 KVM 虚拟机中运行 [OpenShift on OpenStack][2] 虚拟机,以及我的 [Container Development Kit(CDK)][3]。我只想说,当时我在一个全新的 4.X 内核上启动了 RHEL7。和任何优秀的系统管理员一样,我有点担心自己错过了一些重要的配置选项和补丁。当然,我也的确错过了一些东西。比如睡眠模式无法正常工作,我的扩展底座无法正常工作,还有许多其他小的随机错误。但它在我的笔记本电脑上的一个 KVM 虚拟机上,对于 OpenStack 上的 OpenShift 的实时演示来说已经足够好了。来吧,这很有趣,对吧?但我离题了……
|
||||||
|
|
||||||
|
现在,我们来谈谈其他的软件包。虽然内核和相关的系统软件可能很难编译,但从工作负载的角度来看,更大的问题是编译成千上万的包,以提供一个可用的 Linux 系统。每个软件包都需要专业知识。有些软件只需要运行三个命令:`./configure`、`make` 和 `make install`。另一些则需要大量的专业知识,从在 `etc` 中添加用户和配置特定的默认值到运行安装后脚本和添加 systemd 单元文件。对于任何一个人来说,调试好你可能用得到的成千上万种不同软件所需要的一套技能都是令人望而生畏的。但是,如果你想要一个可以随时尝试新软件的可用系统,你必须学会如何编译和安装新软件,然后才能开始学习使用它。这就是没有 Linux 发行版的 Linux。当你放弃使用 Linux 发行版时,那么你就得自己编译软件。
|
||||||
|
|
||||||
|
关键是,你必须将所有内容构建在一起,以确保它能够以任何合理的可靠性级别协同工作,而且构建一个可用的包群需要大量的知识。这是任何一个开发人员或系统管理员都无法合理地学习和保留的知识。我描述的每个问题都适用于你的 [容器主机][4](内核和系统软件)和 [容器镜像][5](系统软件和所有其他包)——请注意:在容器镜像中还包含有编译器 、C 库、解释器和 JVM。
|
||||||
|
|
||||||
|
### 解决方案
|
||||||
|
|
||||||
|
所以你也看到了,其实使用 Linux 发行版就是解决方案。别再看了,给离你最近的软件包维护者(再次向维护人员致敬!)发张电子卡吧(等等,我是不是把我的年龄告诉别人了?)。不过说真的,这些人做了大量的工作,这真的是被低估了。Kubernetes、Istio、Prometheus,还有 Knative:我在看着你们。你们的时代要来了,到时候你们会进入维护模式,被过度使用,被低估。大约七到十年后,我将再次写这篇文章,可能是关于 Kubernetes 的。
|
||||||
|
|
||||||
|
### 容器构建的首要原则
|
||||||
|
|
||||||
|
从零开始构建和从基础镜像构建之间存在权衡。
|
||||||
|
|
||||||
|
#### 从基础镜像构建
|
||||||
|
|
||||||
|
从基础镜像构建的优点是,大多数构建操作只不过是安装或更新包。它依赖于 Linux 发行版中包维护人员所做的大量工作。它还有一个优点,即六个月甚至十年后的修补事件(使用 RHEL)是运维/系统管理员事件 (`yum update`),而不是开发人员事件(这需要通过代码找出某些函数参数不再工作的原因)。
|
||||||
|
|
||||||
|
你想想,应用程序代码依赖于许多库,从 JSON mung 库到对象关系映射器。与 Linux 内核和 Glibc 不同,这些类型的库很少改变 API 兼容性。这意味着三年后你的修补事件可能会变成代码更改事件,而不是 yum 更新事件。因此让他自己深入下去吧。开发人员,如果安全团队找不到防火墙黑客来阻止攻击,你将在凌晨 2 点收到短信。
|
||||||
|
|
||||||
|
从基础镜像构建不是完美的;还有一些缺点,比如所有被拖入的依赖项的大小。这几乎总是会使容器镜像比从头开始构建的镜像更大。另一个缺点是你并不总是能够访问最新的上游代码。这可能会让开发人员感到沮丧,尤其是当你只想使用依赖项中的一部分功能时,但是你仍然不得不将你根本用不着的东西一起打包带走,因为上游的维护人员一直在改变这个库。
|
||||||
|
|
||||||
|
如果你是一个 web 开发人员,正在对我翻白眼,我有一个词可以形容你:DevOps。那意味着你带着寻呼机,我的朋友。
|
||||||
|
|
||||||
|
#### Scratch 构建
|
||||||
|
|
||||||
|
Scratch 构建的优点是镜像非常小。当你不依赖容器中的 Linux 发行版时,你有很多控制权,这意味着你可以根据需要定制所有内容。这是一个最佳模型,在某些用例中是很有效的。另一个优势是你可以访问最新的软件包。你不必等待 Linux 发行版更新任何内容。是你自己在控制,所以你可以自行选择什么时候去费功夫纳入新的软件。
|
||||||
|
|
||||||
|
记住,控制一切都是有代价的。通常,更新到具有新特性的新库会拖如不必要的 API 更改,这意味着修复代码中的不兼容(换句话说,这就像[给牦牛剪毛][6])。在凌晨 2 点应用程序不起作用的时候给牦牛剪毛是不好玩的。幸运的是,使用容器,你可以在下一个工作日回滚并给牦牛剪毛,但它仍会占用你为业务提供新价值、为应用程序提供新功能的时间。欢迎来到系统管理员的生活。
|
||||||
|
|
||||||
|
好吧,也就是说,有些时候,Scratch 构建是有意义的。我完全承认,静态编译的 Golang 程序和 C 程序是 scratch/distorless 构建的两个不错的候选程序。对于这些类型的程序,每个容器构建都是一个编译事件。三年后你仍然需要担心 API 的损坏,但是如果你是一个 Golang 商店,你应该有能力随着时间的推移修复问题。
|
||||||
|
|
||||||
|
### 结论
|
||||||
|
|
||||||
|
基本上,Linux 发行版做了大量工作来节省你在常规 Linux 系统或容器上的时间。维护人员所拥有的知识是巨大的,而且没有得到真正的赞赏。容器的采用使得问题更加严重,因为它被进一步抽象了。
|
||||||
|
|
||||||
|
通过容器主机,Linux 发行版可以让你访问广泛的硬件生态系统,从微型 ARM 系统到 128 核 CPU x86 巨型机箱,再到云服务商的虚拟机。他们提供可工作的容器引擎和开箱即用的容器运行时环境,所以你只需启动你的容器,让其他人担心事情的进展。
|
||||||
|
|
||||||
|
对于容器镜像,Linux 发行版为你的项目提供了对大量软件的轻松访问。即使你从头开始构建,你也可能会看到一个包维护人员是如何构建和运送东西的 —— 一个好的艺术家是一个好的偷学者,所以不要低估这项工作的价值。
|
||||||
|
|
||||||
|
所以,感谢 Fedora、RHEL(Frantisek,你是我的英雄 )、Debian、Gentoo 和其他 Linux 发行版的所有维护人员。我很感激你所做的工作,尽管我是个“容器工人”
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/2/linux-distributions-still-matter-containers
|
||||||
|
|
||||||
|
作者:[Scott McCarty][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/fatherlinux
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://aeon.co/essays/innovation-is-overvalued-maintenance-often-matters-more
|
||||||
|
[2]: https://blog.openshift.com/openshift-on-openstack-delivering-applications-better-together/
|
||||||
|
[3]: https://developers.redhat.com/blog/2018/02/13/red-hat-cdk-nested-kvm/
|
||||||
|
[4]: https://developers.redhat.com/blog/2018/02/22/container-terminology-practical-introduction/#h.8tyd9p17othl
|
||||||
|
[5]: https://developers.redhat.com/blog/2018/02/22/container-terminology-practical-introduction/#h.dqlu6589ootw
|
||||||
|
[6]: https://en.wiktionary.org/wiki/yak_shaving
|
@ -0,0 +1,175 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13012-1.html)
|
||||||
|
[#]: subject: (Printing from the Linux command line)
|
||||||
|
[#]: via: (https://www.networkworld.com/article/3373502/printing-from-the-linux-command-line.html)
|
||||||
|
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||||
|
|
||||||
|
从 Linux 命令行进行打印
|
||||||
|
======
|
||||||
|
|
||||||
|
> 在 Linux 命令行进行打印的内容比单单一个 `lp` 命令多得多,让我们来看一些可用选项。
|
||||||
|
|
||||||
|
![Sherry \(CC BY 2.0\)][1]
|
||||||
|
|
||||||
|
Linux 命令行打印很容易。你可以使用 `lp` 命令来请求打印,并使用 `lpq` 命令来查看队列中有哪些打印作业,但是当你要双面打印或使用纵向模式时,这些会变得有些复杂。你可能还需要做很多其他事情,例如打印多份文档副本或取消打印作业。让我们来看看一些选项,当你从命令行打印时,如何让你的打印输出看起来如你所愿。
|
||||||
|
|
||||||
|
### 显示打印机配置
|
||||||
|
|
||||||
|
要从命令行查看打印机设置,请使用 `lpoptions` 命令。 输出应如下所示:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpoptions
|
||||||
|
copies=1 device-uri=dnssd://HP%20Color%20LaserJet%20CP2025dn%20(F47468)._pdl-datastream._tcp.local/ finishings=3 job-cancel-after=10800 job-hold-until=no-hold job-priority=50 job-sheets=none,none marker-change-time=1553023232 marker-colors=#000000,#00FFFF,#FF00FF,#FFFF00 marker-levels=18,62,62,63 marker-names='Black\ Cartridge\ HP\ CC530A,Cyan\ Cartridge\ HP\ CC531A,Magenta\ Cartridge\ HP\ CC533A,Yellow\ Cartridge\ HP\ CC532A' marker-types=toner,toner,toner,toner number-up=1 printer-commands=none printer-info='HP Color LaserJet CP2025dn (F47468)' printer-is-accepting-jobs=true printer-is-shared=true printer-is-temporary=false printer-location printer-make-and-model='HP Color LaserJet cp2025dn pcl3, hpcups 3.18.7' printer-state=3 printer-state-change-time=1553023232 printer-state-reasons=none printer-type=167964 printer-uri-supported=ipp://localhost/printers/Color-LaserJet-CP2025dn sides=one-sided
|
||||||
|
```
|
||||||
|
|
||||||
|
如果将其空格转换为回车符,输出可能会更人性化,请注意列出了多少设置选项。
|
||||||
|
|
||||||
|
注意:在下面的输出中,一些行被重新链接,以使输出更具可读性。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpoptions | tr " " '\n'
|
||||||
|
copies=1
|
||||||
|
device-uri=dnssd://HP%20Color%20LaserJet%20CP2025dn%20(F47468)._pdl-datastream._tcp.local/
|
||||||
|
finishings=3
|
||||||
|
job-cancel-after=10800
|
||||||
|
job-hold-until=no-hold
|
||||||
|
job-priority=50
|
||||||
|
job-sheets=none,none
|
||||||
|
marker-change-time=1553023232
|
||||||
|
marker-colors=#000000,#00FFFF,#FF00FF,#FFFF00
|
||||||
|
marker-levels=18,62,62,63
|
||||||
|
marker-names='Black\ Cartridge\ HP\ CC530A,
|
||||||
|
Cyan\ Cartridge\ HP\ CC531A,
|
||||||
|
Magenta\ Cartridge\ HP\ CC533A,
|
||||||
|
Yellow\ Cartridge\ HP\ CC532A'
|
||||||
|
marker-types=toner,toner,toner,toner
|
||||||
|
number-up=1
|
||||||
|
printer-commands=none
|
||||||
|
printer-info='HP Color LaserJet CP2025dn (F47468)'
|
||||||
|
printer-is-accepting-jobs=true
|
||||||
|
printer-is-shared=true
|
||||||
|
printer-is-temporary=false
|
||||||
|
printer-location
|
||||||
|
printer-make-and-model='HP Color LaserJet cp2025dn pcl3, hpcups 3.18.7'
|
||||||
|
printer-state=3
|
||||||
|
printer-state-change-time=1553023232
|
||||||
|
printer-state-reasons=none
|
||||||
|
printer-type=167964
|
||||||
|
printer-uri-supported=ipp://localhost/printers/Color-LaserJet-CP2025dn
|
||||||
|
sides=one-sided
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `-v` 选项时,`lpinfo` 命令将列出驱动程序和相关信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpinfo -v
|
||||||
|
network ipp
|
||||||
|
network https
|
||||||
|
network socket
|
||||||
|
network beh
|
||||||
|
direct hp
|
||||||
|
network lpd
|
||||||
|
file cups-brf:/
|
||||||
|
network ipps
|
||||||
|
network http
|
||||||
|
direct hpfax
|
||||||
|
network dnssd://HP%20Color%20LaserJet%20CP2025dn%20(F47468)._pdl-datastream._tcp.local/ <== printer
|
||||||
|
network socket://192.168.0.23 <== printer IP
|
||||||
|
```
|
||||||
|
|
||||||
|
`lpoptions` 命令将显示默认打印机的设置。使用 `-p` 选项指定其中一个可用打印机代号:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpoptions -p LaserJet
|
||||||
|
```
|
||||||
|
|
||||||
|
`lpstat -p` 命令显示打印机的状态,而 `lpstat -p -d` 列出可用打印机列表。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpstat -p -d
|
||||||
|
printer Color-LaserJet-CP2025dn is idle. enabled since Tue 19 Mar 2019 05:07:45 PM EDT
|
||||||
|
system default destination: Color-LaserJet-CP2025dn
|
||||||
|
```
|
||||||
|
|
||||||
|
### 非常有用的命令
|
||||||
|
|
||||||
|
要在默认打印机上打印文档,只需使用 `lp` 命令,后跟要打印的文件名即可。 如果文件名包含空格(在 Linux 系统上很少见),请将该名称放在引号中或开始输入文件名并按 `Tab` 键调用空格的转义标志(如下面的第二个示例所示)。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lp "never leave home angry"
|
||||||
|
$ lp never\ leave\ home\ angry
|
||||||
|
```
|
||||||
|
|
||||||
|
`lpq` 命令显示打印队列:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpq
|
||||||
|
Color-LaserJet-CP2025dn is ready and printing
|
||||||
|
Rank Owner Job File(s) Total Size
|
||||||
|
active shs 234 agenda 2048 bytes
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `-n` 选项时,`lp` 命令可用来指定所需打印输出的份数:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lp -n 11 agenda
|
||||||
|
```
|
||||||
|
|
||||||
|
要取消打印作业,可以使用 `cancel` 或 `lprm` 命令。如果没来得及执行,则可能会看到以下信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cancel 229
|
||||||
|
cancel: cancel-job failed: Job #229 is already completed - can't cancel.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 双面打印
|
||||||
|
|
||||||
|
要以双面模式打印,你可以在 `lp` 命令中使用 `sides` 选项,该选项不但表示了在纸张的正反面进行打印,还表示了从纸张的哪个边开始打印。这个设置代表了你期望以双面纵向文档的正常方式打印。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lp -o sides=two-sided-long-edge Notes.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
如果要所有文档以双面模式打印,则可以使用 `lpoptions` 命令更改 `sides` 设置以修改 `lp` 的设置。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpoptions -o sides=two-sided-short-edge
|
||||||
|
```
|
||||||
|
|
||||||
|
要恢复为单面打印,可以使用如下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lpoptions -o sides=one-sided
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 横向打印
|
||||||
|
|
||||||
|
要以横向模式打印,可以在 `lp` 命令中使用 `landscape` 选项。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ lp -o landscape penguin.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
### CUPS(Unix 通用打印系统)
|
||||||
|
|
||||||
|
Linux 系统上使用的打印系统是基于标准的开源打印系统,称为 **CUPS**,原意是<ruby>Unix 通用打印系统<rt>Common Unix Printing System</rt></ruby>。 它允许计算机充当打印服务器。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.networkworld.com/article/3373502/printing-from-the-linux-command-line.html
|
||||||
|
|
||||||
|
作者:[Sandra Henry-Stocker][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://images.idgesg.net/images/article/2019/03/printouts-paper-100791390-large.jpg
|
||||||
|
[2]: https://www.facebook.com/NetworkWorld/
|
||||||
|
[3]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,264 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13015-1.html)
|
||||||
|
[#]: subject: (Monitor and Manage Docker Containers with Portainer.io \(GUI tool\) – Part-2)
|
||||||
|
[#]: via: (https://www.linuxtechi.com/monitor-manage-docker-containers-portainer-io-part-2/)
|
||||||
|
[#]: author: (Shashidhar Soppin https://www.linuxtechi.com/author/shashidhar/)
|
||||||
|
|
||||||
|
用 Portainer.io 来监控和管理 Docker 容器(2)
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/14/204401knuxjru53n5su6ns.jpg)
|
||||||
|
|
||||||
|
作为[第 1 部分](https://linux.cn/article-12634-1.html)的延续,本第 2 部分将介绍 Portainer 的其余功能。
|
||||||
|
|
||||||
|
### 监控 docker 容器镜像
|
||||||
|
|
||||||
|
```
|
||||||
|
root@linuxtechi ~}$ docker ps -a
|
||||||
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||||
|
9ab9aa72f015 ubuntu "/bin/bash" 14 seconds ago Exited (0) 12 seconds ago suspicious_shannon
|
||||||
|
305369d3b2bb centos "/bin/bash" 24 seconds ago Exited (0) 22 seconds ago admiring_mestorf
|
||||||
|
9a669f3dc4f6 portainer/portainer "/portainer" 7 minutes ago Up 7 minutes 0.0.0.0:9000->9000/tcp trusting_keller
|
||||||
|
```
|
||||||
|
|
||||||
|
包括 `portainer`(docker 容器镜像),所有已退出和当前正在运行的 docker 镜像都会显示出来。下面的 Portainer GUI 屏幕截图显示了相同的情况。
|
||||||
|
|
||||||
|
![Docker_status][1]
|
||||||
|
|
||||||
|
### 监视事件
|
||||||
|
|
||||||
|
单击 portainer 网页中的“Events”选项,如下所示。
|
||||||
|
|
||||||
|
基于 docker 容器活动生成和创建的各种事件将被提取并显示在此页面中.
|
||||||
|
|
||||||
|
![Container-Events-Poratiner-GUI][3]
|
||||||
|
|
||||||
|
现在检查并验证“Events”部分是如何工作的。创建一个新的 docker 容器镜像 `redis`,如下所述,在 docker 命令行检查状态:`docker ps –a`:
|
||||||
|
|
||||||
|
```
|
||||||
|
root@linuxtechi ~}$ docker ps -a
|
||||||
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||||
|
cdbfbef59c31 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp angry_varahamihira
|
||||||
|
9ab9aa72f015 ubuntu "/bin/bash" 10 minutes ago Exited (0) 10 minutes ago suspicious_shannon
|
||||||
|
305369d3b2bb centos "/bin/bash" 11 minutes ago Exited (0) 11 minutes ago admiring_mestorf
|
||||||
|
9a669f3dc4f6 portainer/portainer "/portainer" 17 minutes ago Up 17 minutes 0.0.0.0:9000->9000/tcp trusting_keller
|
||||||
|
```
|
||||||
|
|
||||||
|
单击顶部的“Event List”刷新事件列表,
|
||||||
|
|
||||||
|
![events_updated][5]
|
||||||
|
|
||||||
|
现在事件的页面也更新了这个变化,
|
||||||
|
|
||||||
|
### 主机状态
|
||||||
|
|
||||||
|
下面是 portainer 显示主机状态的屏幕截图。这是一个简单的窗口。这显示了主机 Linux 机器的基本信息,如“CPU”、“主机名”、“操作系统信息”等。这个页面在不需要登录主机命令行的情况下提供了非常有用的信息,以便快速浏览。
|
||||||
|
|
||||||
|
![Host-names-Portainer][7]
|
||||||
|
|
||||||
|
### Portainer 中的仪表板
|
||||||
|
|
||||||
|
到目前为止,我们已经在“Local”部分看到了基于 portainer 的各种特性。现在跳到所选 Docker 容器镜像的“Dashboard”部分。
|
||||||
|
|
||||||
|
在 Portainer 的网页中单击“EndPoint”选项时,会出现以下窗口:
|
||||||
|
|
||||||
|
![End_Point_Settings][9]
|
||||||
|
|
||||||
|
对于主机容器镜像,此仪表板有许多状态和选项。
|
||||||
|
|
||||||
|
#### Stacks
|
||||||
|
|
||||||
|
单击此选项可提供任何堆栈(如果有的话)的状态。因为这里没有堆栈,所以显示为零。
|
||||||
|
|
||||||
|
#### Images
|
||||||
|
|
||||||
|
单击此选项可提供主机中可用的容器镜像。此选项将显示所有活动和退出的容器镜像。
|
||||||
|
|
||||||
|
![Docker-Container-Images-Portainer][11]
|
||||||
|
|
||||||
|
例如,再创建一个“Nginx”容器并刷新此列表以查看更新:
|
||||||
|
|
||||||
|
```
|
||||||
|
root@linuxtechi ~}$ sudo docker run nginx
|
||||||
|
Unable to find image 'nginx:latest' locally
|
||||||
|
latest: Pulling from library/nginx
|
||||||
|
27833a3ba0a5: Pull complete
|
||||||
|
ea005e36e544: Pull complete
|
||||||
|
d172c7f0578d: Pull complete
|
||||||
|
Digest: sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c
|
||||||
|
Status: Downloaded newer image for nginx:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
下面是刷新后的镜像界面:
|
||||||
|
|
||||||
|
![Nginx_Image_creation][13]
|
||||||
|
|
||||||
|
当 Nginx 镜像处于 `stopped`/`killed` 状态时,docker 的容器镜像会改变为 `unused` 状态。
|
||||||
|
|
||||||
|
**注**:你可以看到这里所有的镜像的细节都非常清楚,比如内存使用,创建日期和时间。与命令行选项相比,从这里维护和监视容器将非常容易。
|
||||||
|
|
||||||
|
#### Networks
|
||||||
|
|
||||||
|
此选项用于网络操作。例如分配 IP 地址、创建子网、提供 IP 地址范围、访问控制(管理员和普通用户)。下面的窗口提供了各种可能选项的详细信息。根据你的需要,可以进一步去自行研究这些选项。
|
||||||
|
|
||||||
|
![Conatiner-Network-Portainer][15]
|
||||||
|
|
||||||
|
输入所有各种网络参数后,单击“create network”按钮即可创建网络。
|
||||||
|
|
||||||
|
#### Container
|
||||||
|
|
||||||
|
此选项将提供容器状态。此列表将提供有关活动的和未运行的容器状态的详细信息。此输出类似于 docker ps 命令选项。
|
||||||
|
|
||||||
|
![Containers-Status-Portainer][17]
|
||||||
|
|
||||||
|
在该窗口中,通过选中复选框并选择上述按钮可以根据需要控制容器停止和启动。一个例子如下:
|
||||||
|
|
||||||
|
例如,“CentOS”和“Ubuntu”容器都处于停止状态,现在可以通过选中复选框并点击“Start”按钮来启动它们。
|
||||||
|
|
||||||
|
![start_containers1][19]
|
||||||
|
|
||||||
|
![start_containers2][21]
|
||||||
|
|
||||||
|
**注意:** 因为这两个都是 Linux 容器镜像,所以不会被启动。Portainer 尝试启动,但稍后又停止。试试启动“Nginx”,你会看到它变成了 `running` 状态。
|
||||||
|
|
||||||
|
![start_containers3][23]
|
||||||
|
|
||||||
|
#### Volume
|
||||||
|
|
||||||
|
参见本文章第一部分。
|
||||||
|
|
||||||
|
### Portainer 中的设置选项
|
||||||
|
|
||||||
|
到目前为止,我们已经在“Local”部分看到了基于 portainer 的各种特性。现在跳到所选 Docker 容器图像的“Settings”部分。
|
||||||
|
|
||||||
|
在 Portainer 的网页中单击“Settings”选项时,可以使用以下的配置选项:
|
||||||
|
|
||||||
|
#### Extensions
|
||||||
|
|
||||||
|
这是一个简单的 Portainer CE 订阅程序。详细信息和用途可以从附加的窗口中看到。这主要用于维护相应版本的许可证和订阅。
|
||||||
|
|
||||||
|
![Extensions][25]
|
||||||
|
|
||||||
|
#### Users
|
||||||
|
|
||||||
|
此选项用于添加具有或不具有管理权限的“用户”。下面的示例提供了相同的示例。
|
||||||
|
|
||||||
|
在本例中输入你的想好的用户名比如“shashi”和你选择的密码,然后点击下面的“Create User”按钮。
|
||||||
|
|
||||||
|
![create_user_portainer][27]
|
||||||
|
|
||||||
|
![create_user2_portainer][29]
|
||||||
|
|
||||||
|
![Internal-user-Portainer][31]
|
||||||
|
|
||||||
|
类似地,可以通过选中复选框并点击 “remove” 按钮来删除刚刚创建的用户“shashi”。
|
||||||
|
|
||||||
|
![user_remove_portainer][33]
|
||||||
|
|
||||||
|
#### Endpoints
|
||||||
|
|
||||||
|
此选项用于端点终端管理。终端可以添加和删除,如附加窗口中所示。
|
||||||
|
|
||||||
|
![Endpoint-Portainer-GUI][35]
|
||||||
|
|
||||||
|
新终端“shashi”是使用如下所示的各种默认参数创建的,
|
||||||
|
|
||||||
|
![Endpoint2-Portainer-GUI][37]
|
||||||
|
|
||||||
|
类似地,可以通过单击复选框并单击移除按钮来移除此端点。
|
||||||
|
|
||||||
|
#### Registries
|
||||||
|
|
||||||
|
此选项用于注册管理。由于 docker hub 有各种镜像的注册,因此此功能可用于类似的目的。
|
||||||
|
|
||||||
|
![Registry-Portainer-GUI][39]
|
||||||
|
|
||||||
|
使用默认选项就可以创建“shashi-registry”。
|
||||||
|
|
||||||
|
![Registry2-Portainer-GUI][41]
|
||||||
|
|
||||||
|
同样,如果不需要了,就可以移除它。
|
||||||
|
|
||||||
|
#### Settings
|
||||||
|
|
||||||
|
此选项用于设置以下各种选项,
|
||||||
|
|
||||||
|
* 设置快照间隔
|
||||||
|
* 设置自定义徽标
|
||||||
|
* 创建外部模板
|
||||||
|
* 安全功能,如:为非管理员禁用和启用 bin 挂载,为非管理员禁用/启用权限,启用主机管理功能
|
||||||
|
|
||||||
|
下面的屏幕截图显示了出于演示目的启用和禁用的一些选项。一旦全部完成点击“保存设置”按钮保存所有这些选项。
|
||||||
|
|
||||||
|
![Portainer-GUI-Settings][43]
|
||||||
|
|
||||||
|
现在点开“Authentication settings”就会弹出 LDAP、Internal 和 OAuth(extension)选项,如下所示:
|
||||||
|
|
||||||
|
![Authentication-Portainer-GUI-Settings][45]
|
||||||
|
|
||||||
|
根据我们想要的环境安全特性级别,选择相应的选项。
|
||||||
|
|
||||||
|
以上就是本文的内容,我希望这些介绍 portainer 的文章能帮助你更有效地管理和监视容器。请分享你的反馈和意见。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.linuxtechi.com/monitor-manage-docker-containers-portainer-io-part-2/
|
||||||
|
|
||||||
|
作者:[Shashidhar Soppin][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.linuxtechi.com/author/shashidhar/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Docker_status-1024x423.jpg
|
||||||
|
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Docker_status.jpg
|
||||||
|
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Events-1024x404.jpg
|
||||||
|
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Events.jpg
|
||||||
|
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/05/events_updated-1024x414.jpg
|
||||||
|
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/05/events_updated.jpg
|
||||||
|
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Host_names-1024x408.jpg
|
||||||
|
[8]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Host_names.jpg
|
||||||
|
[9]: https://www.linuxtechi.com/wp-content/uploads/2019/05/End_Point_Settings-1024x471.jpg
|
||||||
|
[10]: https://www.linuxtechi.com/wp-content/uploads/2019/05/End_Point_Settings.jpg
|
||||||
|
[11]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Images-1024x398.jpg
|
||||||
|
[12]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Images.jpg
|
||||||
|
[13]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Nginx_Image_creation-1024x439.jpg
|
||||||
|
[14]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Nginx_Image_creation.jpg
|
||||||
|
[15]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Network-1024x463.jpg
|
||||||
|
[16]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Network.jpg
|
||||||
|
[17]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Containers-1024x364.jpg
|
||||||
|
[18]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Containers.jpg
|
||||||
|
[19]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers1-1024x432.jpg
|
||||||
|
[20]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers1.jpg
|
||||||
|
[21]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers2-1024x307.jpg
|
||||||
|
[22]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers2.jpg
|
||||||
|
[23]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers3-1024x435.jpg
|
||||||
|
[24]: https://www.linuxtechi.com/wp-content/uploads/2019/05/start_containers3.jpg
|
||||||
|
[25]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Extensions-1024x421.jpg
|
||||||
|
[26]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Extensions.jpg
|
||||||
|
[27]: https://www.linuxtechi.com/wp-content/uploads/2019/05/create_user-1024x350.jpg
|
||||||
|
[28]: https://www.linuxtechi.com/wp-content/uploads/2019/05/create_user.jpg
|
||||||
|
[29]: https://www.linuxtechi.com/wp-content/uploads/2019/05/create_user2-1024x372.jpg
|
||||||
|
[30]: https://www.linuxtechi.com/wp-content/uploads/2019/05/create_user2.jpg
|
||||||
|
[31]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Internal-user-Portainer-1024x257.jpg
|
||||||
|
[32]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Internal-user-Portainer.jpg
|
||||||
|
[33]: https://www.linuxtechi.com/wp-content/uploads/2019/05/user_remove-1024x318.jpg
|
||||||
|
[34]: https://www.linuxtechi.com/wp-content/uploads/2019/05/user_remove.jpg
|
||||||
|
[35]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Endpoint-1024x349.jpg
|
||||||
|
[36]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Endpoint.jpg
|
||||||
|
[37]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Endpoint2-1024x379.jpg
|
||||||
|
[38]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Endpoint2.jpg
|
||||||
|
[39]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Registry-1024x420.jpg
|
||||||
|
[40]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Registry.jpg
|
||||||
|
[41]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Registry2-1024x409.jpg
|
||||||
|
[42]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Registry2.jpg
|
||||||
|
[43]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Portainer-GUI-Settings-1024x418.jpg
|
||||||
|
[44]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Portainer-GUI-Settings.jpg
|
||||||
|
[45]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Authentication-Portainer-GUI-Settings-1024x344.jpg
|
||||||
|
[46]: https://www.linuxtechi.com/wp-content/uploads/2019/05/Authentication-Portainer-GUI-Settings.jpg
|
@ -0,0 +1,391 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13037-1.html)
|
||||||
|
[#]: subject: (Integrate online documents editors, into a Python web app using ONLYOFFICE)
|
||||||
|
[#]: via: (https://opensourceforu.com/2019/09/integrate-online-documents-editors-into-a-python-web-app-using-onlyoffice/)
|
||||||
|
[#]: author: (Aashima Sharma https://opensourceforu.com/author/aashima-sharma/)
|
||||||
|
|
||||||
|
利用 ONLYOFFICE 将在线文档编辑器集成到 Python Web 应用程序中
|
||||||
|
======
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
[ONLYOFFICE][3] 是根据 GNU AGPL v.3 许可证条款分发的开源协作办公套件。它包含三个用于文本文档、电子表格和演示文稿的编辑器,并具有以下功能:
|
||||||
|
|
||||||
|
* 查看,编辑和协同编辑 `.docx`、`.xlsx`、`.pptx` 文件。OOXML 作为一种核心格式,可确保与 Microsoft Word、Excel 和 PowerPoint 文件的高度兼容性。
|
||||||
|
* 通过内部转换为 OOXML,编辑其他流行格式(`.odt`、`.rtf`、`.txt`、`.html`、`.ods`、`.csv`、`.odp`)。
|
||||||
|
* 熟悉的选项卡式界面。
|
||||||
|
* 协作工具:两种协同编辑模式(快速和严谨),跟踪更改,评论和集成聊天。
|
||||||
|
* 灵活的访问权限管理:完全访问权限、只读、审阅、表单填写和评论。
|
||||||
|
* 使用 API 构建附加组件。
|
||||||
|
* 250 种可用语言和象形字母表。
|
||||||
|
|
||||||
|
通过 API,开发人员可以将 ONLYOFFICE 编辑器集成到网站和利用程序设计语言编写的应用程序中,并能配置和管理编辑器。
|
||||||
|
|
||||||
|
要集成 ONLYOFFICE 编辑器,我们需要一个集成应用程序来连接编辑器(ONLYOFFICE 文档服务器)和服务。 要在你的界面中使用编辑器,因该授予 ONLYOFFICE 以下权限:
|
||||||
|
|
||||||
|
* 添加并执行自定义代码。
|
||||||
|
* 用于下载和保存文件的匿名访问权限。这意味着编辑器仅与服务器端的服务通信,而不包括客户端的任何用户授权数据(浏览器 cookies)。
|
||||||
|
* 在用户界面添加新按钮(例如,“在 ONLYOFFICE 中打开”、“在 ONLYOFFICE 中编辑”)。
|
||||||
|
* 开启一个新页面,ONLYOFFICE 可以在其中执行脚本以添加编辑器。
|
||||||
|
* 能够指定文档服务器连接设置。
|
||||||
|
|
||||||
|
流行的协作解决方案的成功集成案例有很多,如 Nextcloud、ownCloud、Alfresco、Confluence 和 SharePoint,都是通过 ONLYOFFICE 提供的官方即用型连接器实现的。
|
||||||
|
|
||||||
|
实际的集成案例之一是 ONLYOFFICE 编辑器与以 C# 编写的开源协作平台的集成。该平台具有文档和项目管理、CRM、电子邮件聚合器、日历、用户数据库、博客、论坛、调查、Wiki 和即时通讯程序的功能。
|
||||||
|
|
||||||
|
将在线编辑器与 CRM 和项目模块集成,你可以:
|
||||||
|
|
||||||
|
* 文档关联到 CRM 时机和容器、项目任务和讨论,甚至创建一个单独的文件夹,其中包含与项目相关的文档、电子表格和演示文稿。
|
||||||
|
* 直接在 CRM 或项目模块中创建新的文档、工作表和演示文稿。
|
||||||
|
* 打开和编辑关联的文档,或者下载和删除。
|
||||||
|
* 将联系人从 CSV 文件批量导入到 CRM 中,并将客户数据库导出为 CSV 文件。
|
||||||
|
|
||||||
|
在“邮件”模块中,你可以关联存储在“文档模块”中的文件,或者将指向所需文档的链接插入到邮件正文中。 当 ONLYOFFICE 用户收到带有附件的文档的消息时,他们可以:下载附件、在浏览器中查看文件、打开文件进行编辑或将其保存到“文档模块”。 如上所述,如果格式不同于 OOXML ,则文件将自动转换为 `.docx`、`.xlsx`、`.pptx`,并且其副本也将以原始格式保存。
|
||||||
|
|
||||||
|
在本文中,你将看到 ONLYOFFICE 与最流行的编程语言之一的 Python 编写的文档管理系统的集成过程。 以下步骤将向你展示如何创建所有必要的部分,以使在 DMS(<ruby>文档管理系统<rt>Document Management System</rt></ruby>)界面内的文档中可以进行协同工作成为可能:查看、编辑、协同编辑、保存文件和用户访问管理,并可以作为服务的示例集成到 Python 应用程序中。
|
||||||
|
|
||||||
|
### 1、前置需求
|
||||||
|
|
||||||
|
首先,创建集成过程的关键组件:[ONLYOFFICE 文档服务器][4] 和用 Python 编写的文件管理系统。
|
||||||
|
|
||||||
|
#### 1.1、ONLYOFFICE 文档服务器
|
||||||
|
|
||||||
|
要安装 ONLYOFFICE 文档服务器,你可以从多个安装选项中进行选择:编译 GitHub 上可用的源代码,使用 `.deb` 或 `.rpm` 软件包亦或 Docker 镜像。
|
||||||
|
|
||||||
|
我们推荐使用下面这条命令利用 Docker 映像安装文档服务器和所有必需的依赖。请注意,选择此方法,你需要安装最新的 Docker 版本。
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -itd -p 80:80 onlyoffice/documentserver-de
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2、利用 Python 开发 DMS
|
||||||
|
|
||||||
|
如果已经拥有一个,请检查它是否满足以下条件:
|
||||||
|
|
||||||
|
* 包含需要打开以查看/编辑的保留文件
|
||||||
|
* 允许下载文件
|
||||||
|
|
||||||
|
对于该应用程序,我们将使用 Bottle 框架。我们将使用以下命令将其安装在工作目录中:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install bottle
|
||||||
|
```
|
||||||
|
|
||||||
|
然后我们创建应用程序代码 `main.py` 和模板 `index.tpl`。
|
||||||
|
|
||||||
|
我们将以下代码添加到 `main.py` 文件中:
|
||||||
|
|
||||||
|
```
|
||||||
|
from bottle import route, run, template, get, static_file # connecting the framework and the necessary components
|
||||||
|
@route('/') # setting up routing for requests for /
|
||||||
|
def index():
|
||||||
|
return template('index.tpl') # showing template in response to request
|
||||||
|
|
||||||
|
run(host="localhost", port=8080) # running the application on port 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦我们运行该应用程序,点击 <http://localhost:8080> 就会在浏览器上呈现一个空白页面 。
|
||||||
|
为了使文档服务器能够创建新文档,添加默认文件并在模板中生成其名称列表,我们应该创建一个文件夹 `files` 并将3种类型文件(`.docx`、`.xlsx` 和 `.pptx`)放入其中。
|
||||||
|
|
||||||
|
要读取这些文件的名称,我们使用 `listdir` 组件(模块):
|
||||||
|
|
||||||
|
```
|
||||||
|
from os import listdir
|
||||||
|
```
|
||||||
|
|
||||||
|
现在让我们为文件夹中的所有文件名创建一个变量:
|
||||||
|
|
||||||
|
```
|
||||||
|
sample_files = [f for f in listdir('files')]
|
||||||
|
```
|
||||||
|
|
||||||
|
要在模板中使用此变量,我们需要通过 `template` 方法传递它:
|
||||||
|
|
||||||
|
```
|
||||||
|
def index():
|
||||||
|
return template('index.tpl', sample_files=sample_files)
|
||||||
|
```
|
||||||
|
|
||||||
|
这是模板中的这个变量:
|
||||||
|
|
||||||
|
```
|
||||||
|
% for file in sample_files:
|
||||||
|
<div>
|
||||||
|
<span>{{file}}</span>
|
||||||
|
</div>
|
||||||
|
% end
|
||||||
|
```
|
||||||
|
|
||||||
|
我们重新启动应用程序以查看页面上的文件名列表。
|
||||||
|
|
||||||
|
使这些文件可用于所有应用程序用户的方法如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
@get("/files/<filepath:re:.*\.*>")
|
||||||
|
def show_sample_files(filepath):
|
||||||
|
return static_file(filepath, root="files")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2、查看文档
|
||||||
|
|
||||||
|
所有组件准备就绪后,让我们添加函数以使编辑者可以利用应用接口操作。
|
||||||
|
|
||||||
|
第一个选项使用户可以打开和查看文档。连接模板中的文档编辑器 API :
|
||||||
|
|
||||||
|
```
|
||||||
|
<script type="text/javascript" src="editor_url/web-apps/apps/api/documents/api.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
`editor_url` 是文档编辑器的链接接口。
|
||||||
|
|
||||||
|
打开每个文件以供查看的按钮:
|
||||||
|
|
||||||
|
```
|
||||||
|
<button onclick="view('files/{{file}}')">view</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
现在我们需要添加带有 `id` 的 `div` 标签,打开文档编辑器:
|
||||||
|
|
||||||
|
```
|
||||||
|
<div id="editor"></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
要打开编辑器,必须调用调用一个函数:
|
||||||
|
|
||||||
|
```
|
||||||
|
<script>
|
||||||
|
function view(filename) {
|
||||||
|
if (/docx$/.exec(filename)) {
|
||||||
|
filetype = "text"
|
||||||
|
}
|
||||||
|
if (/xlsx$/.exec(filename)) {
|
||||||
|
filetype = "spreadsheet"
|
||||||
|
}
|
||||||
|
if (/pptx$/.exec(filename)) {
|
||||||
|
filetype = "presentation",
|
||||||
|
title: filename
|
||||||
|
}
|
||||||
|
|
||||||
|
new DocsAPI.DocEditor("editor",
|
||||||
|
{
|
||||||
|
documentType: filetype,
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filename,
|
||||||
|
title: filename
|
||||||
|
},
|
||||||
|
editorConfig: {mode: 'view'}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
DocEditor 函数有两个参数:将在其中打开编辑器的元素 `id` 和带有编辑器设置的 `JSON`。
|
||||||
|
在此示例中,使用了以下必需参数:
|
||||||
|
|
||||||
|
* `documentType` 由其格式标识(`.docx`、`.xlsx`、`.pptx` 用于相应的文本、电子表格和演示文稿)
|
||||||
|
* `document.url` 是你要打开的文件链接。
|
||||||
|
* `editorConfig.mode`。
|
||||||
|
|
||||||
|
我们还可以添加将在编辑器中显示的 `title`。
|
||||||
|
|
||||||
|
接下来,我们可以在 Python 应用程序中查看文档。
|
||||||
|
|
||||||
|
### 3、编辑文档
|
||||||
|
|
||||||
|
首先,添加 “Edit”(编辑)按钮:
|
||||||
|
|
||||||
|
```
|
||||||
|
<button onclick="edit('files/{{file}}')">edit</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
然后创建一个新功能,打开文件进行编辑。类似于查看功能。
|
||||||
|
|
||||||
|
现在创建 3 个函数:
|
||||||
|
|
||||||
|
```
|
||||||
|
<script>
|
||||||
|
var editor;
|
||||||
|
function view(filename) {
|
||||||
|
if (editor) {
|
||||||
|
editor.destroyEditor()
|
||||||
|
}
|
||||||
|
editor = new DocsAPI.DocEditor("editor",
|
||||||
|
{
|
||||||
|
documentType: get_file_type(filename),
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filename,
|
||||||
|
title: filename
|
||||||
|
},
|
||||||
|
editorConfig: {mode: 'view'}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit(filename) {
|
||||||
|
if (editor) {
|
||||||
|
editor.destroyEditor()
|
||||||
|
}
|
||||||
|
editor = new DocsAPI.DocEditor("editor",
|
||||||
|
{
|
||||||
|
documentType: get_file_type(filename),
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filename,
|
||||||
|
title: filename
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_file_type(filename) {
|
||||||
|
if (/docx$/.exec(filename)) {
|
||||||
|
return "text"
|
||||||
|
}
|
||||||
|
if (/xlsx$/.exec(filename)) {
|
||||||
|
return "spreadsheet"
|
||||||
|
}
|
||||||
|
if (/pptx$/.exec(filename)) {
|
||||||
|
return "presentation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
`destroyEditor` 被调用以关闭一个打开的编辑器。
|
||||||
|
|
||||||
|
你可能会注意到,`edit()` 函数中缺少 `editorConfig` 参数,因为默认情况下它的值是:`{"mode":"edit"}`。
|
||||||
|
|
||||||
|
现在,我们拥有了打开文档以在 Python 应用程序中进行协同编辑的所有功能。
|
||||||
|
|
||||||
|
### 4、如何在 Python 应用中利用 ONLYOFFICE 协同编辑文档
|
||||||
|
|
||||||
|
通过在编辑器中设置对同一文档使用相同的 `document.key` 来实现协同编辑。 如果没有此键值,则每次打开文件时,编辑器都会创建编辑会话。
|
||||||
|
|
||||||
|
为每个文档设置唯一键,以使用户连接到同一编辑会话时进行协同编辑。 密钥格式应为以下格式:`filename +"_key"`。下一步是将其添加到当前文档的所有配置中。
|
||||||
|
|
||||||
|
```
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filepath,
|
||||||
|
title: filename,
|
||||||
|
key: filename + '_key'
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5、如何在 Python 应用中利用 ONLYOFFICE 保存文档
|
||||||
|
|
||||||
|
每次我们更改并保存文件时,ONLYOFFICE 都会存储其所有版本。 让我们仔细看看它是如何工作的。 关闭编辑器后,文档服务器将构建要保存的文件版本并将请求发送到 `callbackUrl` 地址。 该请求包含 `document.key`和指向刚刚构建的文件的链接。
|
||||||
|
|
||||||
|
`document.key` 用于查找文件的旧版本并将其替换为新版本。 由于这里没有任何数据库,因此仅使用 `callbackUrl` 发送文件名。
|
||||||
|
|
||||||
|
在 `editorConfig.callbackUrl` 的设置中指定 `callbackUrl` 参数并将其添加到 `edit()` 方法中:
|
||||||
|
|
||||||
|
```
|
||||||
|
function edit(filename) {
|
||||||
|
const filepath = 'files/' + filename;
|
||||||
|
if (editor) {
|
||||||
|
editor.destroyEditor()
|
||||||
|
}
|
||||||
|
editor = new DocsAPI.DocEditor("editor",
|
||||||
|
{
|
||||||
|
documentType: get_file_type(filepath),
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filepath,
|
||||||
|
title: filename,
|
||||||
|
key: filename + '_key'
|
||||||
|
}
|
||||||
|
,
|
||||||
|
editorConfig: {
|
||||||
|
mode: 'edit',
|
||||||
|
callbackUrl: "host_url" + '/callback' + '&filename=' + filename // add file name as a request parameter
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
编写一种方法,在获取到 POST 请求发送到 `/callback` 地址后将保存文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
@post("/callback") # processing post requests for /callback
|
||||||
|
def callback():
|
||||||
|
if request.json['status'] == 2:
|
||||||
|
file = requests.get(request.json['url']).content
|
||||||
|
with open('files/' + request.query['filename'], 'wb') as f:
|
||||||
|
f.write(file)
|
||||||
|
return "{\"error\":0}"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`# status 2` 是已生成的文件,当我们关闭编辑器时,新版本的文件将保存到存储器中。
|
||||||
|
|
||||||
|
### 6、管理用户
|
||||||
|
|
||||||
|
如果应用中有用户,并且你需要查看谁在编辑文档,请在编辑器的配置中输入其标识符(`id`和`name`)。
|
||||||
|
|
||||||
|
在界面中添加选择用户的功能:
|
||||||
|
|
||||||
|
```
|
||||||
|
<select id="user_selector" onchange="pick_user()">
|
||||||
|
<option value="1" selected="selected">JD</option>
|
||||||
|
<option value="2">Turk</option>
|
||||||
|
<option value="3">Elliot</option>
|
||||||
|
<option value="4">Carla</option>
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
如果在标记 `<script>` 的开头添加对函数 `pick_user()` 的调用,负责初始化函数自身 `id` 和 `name` 变量。
|
||||||
|
|
||||||
|
```
|
||||||
|
function pick_user() {
|
||||||
|
const user_selector = document.getElementById("user_selector");
|
||||||
|
this.current_user_name = user_selector.options[user_selector.selectedIndex].text;
|
||||||
|
this.current_user_id = user_selector.options[user_selector.selectedIndex].value;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `editorConfig.user.id` 和 `editorConfig.user.name` 来配置用户设置。将这些参数添加到文件编辑函数中的编辑器配置中。
|
||||||
|
|
||||||
|
```
|
||||||
|
function edit(filename) {
|
||||||
|
const filepath = 'files/' + filename;
|
||||||
|
if (editor) {
|
||||||
|
editor.destroyEditor()
|
||||||
|
}
|
||||||
|
editor = new DocsAPI.DocEditor("editor",
|
||||||
|
{
|
||||||
|
documentType: get_file_type(filepath),
|
||||||
|
document: {
|
||||||
|
url: "host_url" + '/' + filepath,
|
||||||
|
title: filename
|
||||||
|
},
|
||||||
|
editorConfig: {
|
||||||
|
mode: 'edit',
|
||||||
|
callbackUrl: "host_url" + '/callback' + '?filename=' + filename,
|
||||||
|
user: {
|
||||||
|
id: this.current_user_id,
|
||||||
|
name: this.current_user_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用这种方法,你可以将 ONLYOFFICE 编辑器集成到用 Python 编写的应用程序中,并获得用于在文档上进行协同工作的所有必要工具。有关更多集成示例(Java、Node.js、PHP、Ruby),请参考官方的 [API 文档][5]。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensourceforu.com/2019/09/integrate-online-documents-editors-into-a-python-web-app-using-onlyoffice/
|
||||||
|
|
||||||
|
作者:[Aashima Sharma][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensourceforu.com/author/aashima-sharma/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2016/09/Typist-composing-text-in-laptop.jpg?resize=696%2C420&ssl=1 (Typist composing text in laptop)
|
||||||
|
[2]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2016/09/Typist-composing-text-in-laptop.jpg?fit=900%2C543&ssl=1
|
||||||
|
[3]: https://www.onlyoffice.com/en/
|
||||||
|
[4]: https://www.onlyoffice.com/en/developer-edition.aspx
|
||||||
|
[5]: https://api.onlyoffice.com/editors/basic
|
@ -0,0 +1,53 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "sthwhl"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13049-1.html"
|
||||||
|
[#]: subject: "The biggest risk to uptime? Your staff"
|
||||||
|
[#]: via: "https://www.networkworld.com/article/3444762/the-biggest-risk-to-uptime-your-staff.html"
|
||||||
|
[#]: author: "Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/"
|
||||||
|
|
||||||
|
计算机正常运行最大的威胁是什么?是员工
|
||||||
|
======
|
||||||
|
|
||||||
|
> 一项新研究发现,人为失误是引发停机时间的首要原因。你想象一下那是什么场景。
|
||||||
|
|
||||||
|
![](https://images.idgesg.net/images/article/2018/07/9_how-well-do-you-know-your-staff_head-in-sand-100765388-large.jpg)
|
||||||
|
|
||||||
|
之前有一个很老的笑话:“是人都会犯错,但是要真正把事情搞砸,你还缺台计算机。” 现在情况正好相反了,现如今,数据中心设备的可靠性已经得到了极大的提升,反而是使用设备的人员素质没能跟上,从而给计算机正常运行带来了很大的威胁。
|
||||||
|
|
||||||
|
<ruby>正常运行时间协会<rt>Uptime Institute</rt></ruby>对数千名 IT 专业人员一整年发生的故障事件进行了调查,得出结论表示绝大多数的数据中心故障是由于人为错误造成的,人为错误导致的故障率为 70%-75%。
|
||||||
|
|
||||||
|
而且有些故障很严重。调查发现,超过 30% 的 IT 服务与数据中心运营商经历了他们称之为是“严重服务退化”的停机事故。2019 年有 10% 的受访者称他们最近的事故造成的损失超过 100 万美元。
|
||||||
|
|
||||||
|
在正常运行时间协会在 2019 年 4 月的调查中,60% 的受访者认为,对于最近发生的重大停机事件,他们本可以通过更好的管理/流程或配置进行防止。而对于损失超过 100 万美元的故障事件,这一数字跃升至 74%。
|
||||||
|
|
||||||
|
正常运行时间协会认为,导致故障事件发生的最终的错误不一定是员工,而是令人失望的管理。
|
||||||
|
|
||||||
|
“这个行业仍然严重依赖于人工去完成一些最基础和最重要的工作,易受人为错误的影响,这一点无法避免,也许可做的防错/防灾措施很有限。”正常运行时间协会期刊的主编 Kevin Heslin 在一篇[博客文章][4]中写道。
|
||||||
|
|
||||||
|
“然而,对这些故障问题的快速调查发现,故障持续存在的主要原因不是人为失误,而是由于管理失误导致,如针对员工培训投资不足,相关政策执行不力,管理程序老旧,低估一名合格员工的重要性,这一系列的管理问题导致了故障停机。” Heslin 继续写道。
|
||||||
|
|
||||||
|
正常运行时间协会指出,公司的 IT 基础设施越复杂,特别是分布式特性基础设施,可能会越容易增加简单的错误层出不穷而导致业务中断的风险。同时指出公司需要意识到基础设施越复杂所涉及的风险就越大。
|
||||||
|
|
||||||
|
并警告说,在人员配备方面,不要以超过公司吸引和应用资源来管理基础设施的速度扩大关键 IT 能力,并在影响关键任务操作之前意识到任何人员和技能短缺。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.networkworld.com/article/3444762/the-biggest-risk-to-uptime-your-staff.html
|
||||||
|
|
||||||
|
作者:[Andy Patrizio][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[sthwhl](https://github.com/sthwhl)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.networkworld.com/author/Andy-Patrizio/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.networkworld.com/article/3223692/what-is-a-data-centerhow-its-changed-and-what-you-need-to-know.html
|
||||||
|
[2]: https://www.networkworld.com/newsletters/signup.html
|
||||||
|
[3]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE20773&utm_content=sidebar " Take the Intelligent Route with Consumption-Based Storage"
|
||||||
|
[4]: https://journal.uptimeinstitute.com/how-to-avoid-outages-try-harder/
|
||||||
|
[5]: https://www.facebook.com/NetworkWorld/
|
||||||
|
[6]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,71 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13018-1.html)
|
||||||
|
[#]: subject: (Top articles for learning Python in 2020)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/learn-python)
|
||||||
|
[#]: author: (Matthew Broberg https://opensource.com/users/mbbroberg)
|
||||||
|
|
||||||
|
学习 Python 的好文章
|
||||||
|
======
|
||||||
|
|
||||||
|
> 无论你在 Python 编程过程中处于什么阶段,这些 Python 热门文章将会对你有很大帮助。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/15/231657xt8085wtyk5yvsz5.jpg)
|
||||||
|
|
||||||
|
2019 年是 Python 的好年景。根据 [GitHub][2] 和 [Stack Overflow][3] 的受欢迎资源程度来看,它正在成为全球第二大流行语言。(LCTT 译注:原文发表于 2019 年底,但是这里提及的文章并没有过时。)
|
||||||
|
|
||||||
|
> “在我们的调查中,Python 作为增长最快的程序设计语言,在程序设计语言中排名再次上升,今年排在 Java 之前,成为第二大最受欢迎的程序设计语言(仅次于 Rust )。”
|
||||||
|
>
|
||||||
|
> — [Stack Overflow Insights][3]
|
||||||
|
|
||||||
|
同样,Python 的读者人数呈跳跃式激增。以下是按主题分组的 2019 年以来最热门的 Python 文章,供你仔细阅读。
|
||||||
|
|
||||||
|
### 为什么选择 Python ?
|
||||||
|
|
||||||
|
在众多的程序设计语言中,是什么使 Python 成为首选呢?从文章的阅读量来看,那就是因为它的灵活性。正如 Jigyasa Grover 解释的那样,Python 开发人员可以使用 [多种范例][4],包括 Seth Kenlon 教程所展示的流行的 [面向对象程序设计][5]。
|
||||||
|
|
||||||
|
如果你是 Python 的长期用户,并且正在寻找 Python 为什么是完美的程序设计语言的高级例子,那么可以看 Moshe Zadka 的 [喜欢 Python 的 5 大理由][6]。如果这还不够的话,你也可以使用功能强大的工具来尝试,无需编写大量代码,例如 Parul Pandey 关于 [图像处理][7] 的教程。
|
||||||
|
|
||||||
|
### 配置 Python
|
||||||
|
|
||||||
|
随着 Python 的受欢迎程度不断提高,使用它的人越来越多。这些新手中的许多人都是在 Mac 操作系统上进行的,并且正在使用 Moshe 和我写的 [Python3 配置向导][8]。
|
||||||
|
|
||||||
|
安装 Python 之后,接下来就是决定利用什么工具编写代码。关于文本编辑器和集成开发环境(IDE),有很多选择,但是读者似乎更喜欢图形界面,在有关该主题的文章中,Stephan Avenwedde 的关于 [Pythonic][9] 和我关于 [JupyterLab][10] 的文章的读者最多。
|
||||||
|
|
||||||
|
在对程序设计语言充满信心的途径上,开发人员将不得不面对众多选择,来管理程序设计语言的版本和项目依赖。幸运的是,László Kiss Kollár 的文章 [Python 包管理][11] 让其变得更加容易。
|
||||||
|
|
||||||
|
当你准备好配置一个具有所有功能的 IDE,以最大限度地利用这门语言时,请一定尝试一下 [linter Black][12],如 Moshe 说的,保持代码的清洁。
|
||||||
|
|
||||||
|
### 小结
|
||||||
|
|
||||||
|
无论你处在 Python 程序设计的哪个阶段,这些热门 Python 文章都将为你提供帮助。如果没有至少一次对测试重要性的认可,我无法对此进行总结,为此,Moshe 提供了另一篇 [关于 tox][13] 的好文章。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/learn-python
|
||||||
|
|
||||||
|
作者:[Matthew Broberg][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/mbbroberg
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd (Hands on a keyboard with a Python book )
|
||||||
|
[2]: https://octoverse.github.com/#top-languages
|
||||||
|
[3]: https://insights.stackoverflow.com/survey/2019
|
||||||
|
[4]: https://opensource.com/article/19/10/python-programming-paradigms
|
||||||
|
[5]: https://opensource.com/article/19/7/get-modular-python-classes
|
||||||
|
[6]: https://opensource.com/article/19/10/why-love-python
|
||||||
|
[7]: https://linux.cn/article-10679-1.html
|
||||||
|
[8]: https://opensource.com/article/19/5/python-3-default-mac
|
||||||
|
[9]: https://opensource.com/article/19/5/graphically-programming-pythonic
|
||||||
|
[10]: https://opensource.com/article/19/5/jupyterlab-python-developers-magic
|
||||||
|
[11]: https://opensource.com/article/19/4/managing-python-packages
|
||||||
|
[12]: https://linux.cn/article-10864-1.html
|
||||||
|
[13]: https://opensource.com/article/19/5/python-tox
|
||||||
|
[14]: https://opensource.com/how-submit-article
|
@ -0,0 +1,61 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13053-1.html)
|
||||||
|
[#]: subject: (Making trade-offs when writing Python code)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-trade-offs)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
编写 Python 代码时要有所取舍
|
||||||
|
======
|
||||||
|
|
||||||
|
> 本文是 Python 之禅特别系列的一部分,重点此篇着眼于第七、八、九条原则:可读性、特殊情况和实用性。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/26/105645c1looxqxns12loen.jpg)
|
||||||
|
|
||||||
|
软件开发是一门充满了取舍的学科。每一个选择,都有一个同样合理但相反的选择。将一个方法私有化?你在鼓励复制粘贴。将一个方法公开?你在过早地对一个接口做出承诺。
|
||||||
|
|
||||||
|
软件开发者每时每刻都在做艰难的选择。虽然 [Python 之禅][2] 中的所有原则都在一定程度上涵盖了权衡,但下面的原则对一些权衡进行了最艰难、最冷酷的审视。
|
||||||
|
|
||||||
|
### <ruby>可读性很重要<rt>Readability counts</rt></ruby>
|
||||||
|
|
||||||
|
从某种意义上说,这一中间原则确实是整个 Python 之禅的中心。这条原则与编写高效的程序无关。在大多数情况下,它甚至与编写健壮的程序也无关。它讲的是编写出*别人能读懂的程序*。
|
||||||
|
|
||||||
|
阅读代码,就其本质而言,发生在代码被添加到系统中之后。通常,它会发生在很久很久以后。忽略可读性是最简单的选择,因为它对现在没有伤害。无论添加新代码的原因是什么,它都会对现在造成影响,无论是一个令人痛苦的 bug 还是一个被强烈要求的功能。
|
||||||
|
|
||||||
|
如果面对巨大的压力,把可读性扔到一边,只管“解决问题”,而 Python 之禅提醒我们:可读性很重要。编写代码让它适合阅读,无论是对自己还是他人,都是一种慈悲。
|
||||||
|
|
||||||
|
### <ruby>特殊情况不足以违反规则<rt>Special cases aren't special enough to break the rules</rt></ruby>
|
||||||
|
|
||||||
|
总是有各种借口:这个 bug 特别麻烦,先简单处理一下吧;这个功能特别紧急,别管美观了;这种情况下所涉及的领域规则特别复杂,嵌套深点也没关系。
|
||||||
|
|
||||||
|
一旦我们对特例的借口妥协,大坝就会破裂,就丧失了原则;事情就会演变成一个疯狂麦克斯的荒诞症,每个程序员都会为自己试图找到最好的借口。
|
||||||
|
|
||||||
|
纪律需要承诺。只有当事情艰辛、有强烈的诱惑时,才是对一个软件开发人员的考验。总是有合理的借口来破坏规则,这就是为什么必须坚守规矩的原因。纪律就是向例外说不的艺术。没有任何解释可以改变这一点。
|
||||||
|
|
||||||
|
### <ruby>虽然,实用性胜过纯洁性<rt>Although, practicality beats purity</rt></ruby>
|
||||||
|
|
||||||
|
> “如果你只想着击打、弹跳、撞击、触碰敌人,你将无法真正打倒他。”
|
||||||
|
> —— 《宫本武藏:[水之卷][3]》
|
||||||
|
|
||||||
|
归根结底,软件开发是一门实用的学科。它的目标是解决真实的人所面临的实际问题。实用性比纯粹性更重要:首先,我们必须*解决问题*。如果我们只考虑可读性、简单性或美观性,我们将无法真正*解决问题*。
|
||||||
|
|
||||||
|
正如宫本武藏所说的,每一次代码修改的首要目标应该是*解决问题*。这个问题需要我们心心念念地去解决它。如果我们不以解决问题为目标,只想着 Python 之禅,我们就辜负了这些原则。这是 Python 之禅所固有的另一种矛盾。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-trade-offs
|
||||||
|
|
||||||
|
作者:[Moshe Zadka][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[wxy](https://github.com/wxys)
|
||||||
|
校对:[wxy](https://github.com/wxys)
|
||||||
|
|
||||||
|
本文由 [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/devops_confusion_wall_questions.png?itok=zLS7K2JG (Brick wall between two people, a developer and an operations manager)
|
||||||
|
[2]: https://www.python.org/dev/peps/pep-0020/
|
||||||
|
[3]: https://en.wikipedia.org/wiki/The_Book_of_Five_Rings#The_Book_of_Water
|
@ -0,0 +1,57 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13058-1.html)
|
||||||
|
[#]: subject: (How the Zen of Python handles errors)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-errors)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
Python 处理错误的原则
|
||||||
|
======
|
||||||
|
|
||||||
|
> 这是 Python 之禅特别系列的一部分,重点是第十和第十一条原则:沉默的错误(或不沉默)。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/27/223251q261j2ndoccajc16.jpg)
|
||||||
|
|
||||||
|
处理“异常情况”是编程中争论最多的问题之一。这可能是因为风险很大:处理不当的错误值甚至可以使庞大的系统瘫痪。由于“异常情况”从本质上来说,是测试不足的,但发生的频率却令人不快,因此,是否正确处理它们往往可以将一个噩梦般的系统与一个“可以工作”的系统区分开来。
|
||||||
|
|
||||||
|
从 Java 的 `checked` 异常,到 Erlang 的故障隔离,再到 Haskell 的 `Maybe`,不同的语言对错误处理的态度截然不同。
|
||||||
|
|
||||||
|
这两条 [Python 之禅][2]是 Python 对这个话题的冥思。
|
||||||
|
|
||||||
|
### <ruby>错误绝不应该悄悄传递...<rt>Errors should never pass silently…</rt></ruby>
|
||||||
|
|
||||||
|
当 Python 之禅在 Tim Peters 眼里闪烁而出之前,在维基百科被俗称为“维基”之前,第一个维基网站 [C2][3] 就已经存在了,它是一个编程指南的宝库。这些原则大多来自于 [Smalltalk][4] 编程社区。Smalltalk 的思想影响了许多面向对象的语言,包括 Python。
|
||||||
|
|
||||||
|
C2 维基定义了<ruby>武士原则<rt>Samurai Principle</rt></ruby>:“胜利归来,要么不归。”用 Python 人的术语来说,它鼓励摒弃<ruby>哨兵值<rt>sentinel value</rt></ruby>,比如用返回 `None` 或 `-1` 来表示无法完成任务,而是采用引发异常的方式。一个 `None` 是无声的:它看起来像一个值,可以放在一个变量中,然后到处传递。有时,它甚至是一个*有效*的返回值。
|
||||||
|
|
||||||
|
这里的原则是,如果一个函数不能完成它的契约,它应该“高调失败”:引发一个异常。所引发的异常永远不会看起来像是一个可能的值。它将跳过 `returned_value = call_to_function(parameter)` 行,并上升到调用栈中,可能使程序崩溃。
|
||||||
|
|
||||||
|
崩溃的调试是很直接的:有一个堆栈跟踪来指示问题以及调用堆栈。崩溃可能意味着程序的必要条件没有满足,需要人为干预。它可能意味着程序的逻辑有问题。无论是哪种情况,高调失败都比一个隐藏的、“缺失”的值要好。用 `None` 来感染程序的有效数据,直到它被用在某个地方,就如你可能已经知道的,错误信息会说 “**None 没有方法进行拆分**”。
|
||||||
|
|
||||||
|
### <ruby>除非显式消除<rt>Unless explicitly silenced</rt></ruby>
|
||||||
|
|
||||||
|
有时需要显式地捕获异常。我们可能会预见到文件中的某些行格式错误,并希望以特殊的方式来处理它们,也许可以把它们放在一个“需要人来看看的行”的文件中,而不是让整个程序崩溃。
|
||||||
|
|
||||||
|
Python 允许我们用 `except` 来捕获异常。这意味着错误可以被*显式*消除。这种明确性意味着 `except` 行在代码审查中是可见的。质疑为什么应该在这里显式消除异常并从异常中恢复,是有意义的。自问一下我们是否捕获了太多或太少的异常也是有意义的。
|
||||||
|
|
||||||
|
因为这些全都是明确的,所以有人可以阅读代码并了解哪些异常是可以恢复的。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-errors
|
||||||
|
|
||||||
|
作者:[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/checklist_hands_team_collaboration.png?itok=u82QepPk (a checklist for a team)
|
||||||
|
[2]: https://www.python.org/dev/peps/pep-0020/
|
||||||
|
[3]: https://wiki.c2.com/
|
||||||
|
[4]: https://en.wikipedia.org/wiki/Smalltalk
|
@ -0,0 +1,115 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13055-1.html)
|
||||||
|
[#]: subject: (5 Python scripts for automating basic community management tasks)
|
||||||
|
[#]: via: (https://opensource.com/article/20/3/automating-community-management-python)
|
||||||
|
[#]: author: (Rich Bowen https://opensource.com/users/rbowen)
|
||||||
|
|
||||||
|
用于基本社区管理任务自动化的 5 个 Python 脚本
|
||||||
|
======
|
||||||
|
|
||||||
|
> 如果某些事情不得不重复做三遍,尝试使其自动化。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/27/000544aakdc4mnmn6tzj8y.jpg)
|
||||||
|
|
||||||
|
我 [之前写过关于社区管理员的工作][2],如果你问 10 位社区管理员,你会得到 12 个不同的答案。不过,大多数情况下,你做的是社区需要你在任何特定时刻做的事情。而且很多事情可能是重复的。
|
||||||
|
|
||||||
|
当我还是系统管理员时,我遵循一个规则:如果某些事必须做三遍,我会尝试使其自动化。当然,如今,使用诸如 Ansible 这样的强大工具,就有了一整套科学的方法。
|
||||||
|
|
||||||
|
我每天或每周要做的一些事情涉及在一些地方查找内容,然后生成信息的摘要或报告,然后发布到别处。这样的任务是自动化的理想选择。这些并不是什么 [难事][3],当我与同事共享其中一些脚本时,总是至少有一个能证明这是有用的。
|
||||||
|
|
||||||
|
[在 GitHub][4] 上,我有几个每周都要使用的脚本。它们都不是很复杂,但每次都为我节省几分钟。其中一些是用 Perl 写的,因为我快 50 岁了(这些是我早些年写的)。有些是用 Python 写的,因为几年前,我决定要学习 Python。
|
||||||
|
|
||||||
|
以下是概述:
|
||||||
|
|
||||||
|
### tshirts.py
|
||||||
|
|
||||||
|
这个简单的 [tshirts.py 脚本][5]会根据你要定制的活动 T 恤的数量,然后告诉你尺寸分布是什么。它将这些尺寸分布在一条正态曲线(也称为 “钟形曲线”)上,以我的经验,这和一个正常的会议观众的实际需求非常吻合。如果在美国使用,则可能需要将脚本中的值调整的稍大一些;如果在欧洲使用,则可能需要将脚本中的值稍稍缩小一些。你的情况也许不同。
|
||||||
|
|
||||||
|
用法:
|
||||||
|
|
||||||
|
```
|
||||||
|
[rbowen@sasha:community-tools/scripts]$ ./tshirts.py
|
||||||
|
How many shirts? 300
|
||||||
|
For a total of 300 shirts, order:
|
||||||
|
|
||||||
|
30.0 small
|
||||||
|
72.0 medium
|
||||||
|
96.0 large
|
||||||
|
72.0 xl
|
||||||
|
30.0 2xl
|
||||||
|
```
|
||||||
|
|
||||||
|
### followers.py
|
||||||
|
|
||||||
|
[followers.py 脚本][6]为我提供了我关心的 Twitter 账号的关注者数量。
|
||||||
|
|
||||||
|
该脚本只有 14 行,没什么复杂的,但是它可能节省我十分钟的加载网页和查找数字的时间。
|
||||||
|
|
||||||
|
你需要编辑 `feed` 数组以添加你关心的帐户:
|
||||||
|
|
||||||
|
```
|
||||||
|
feeds = [
|
||||||
|
'centosproject',
|
||||||
|
'centos'
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
注意:如果你在英语国家以外的地方运行它,则可能无法正常工作,因为它只是一个简单的屏幕抓取脚本,它读取 HTML 并查找其中包含的特定信息。因此,当输出使用其他语言时,正则表达式可能不匹配。
|
||||||
|
|
||||||
|
用法:
|
||||||
|
|
||||||
|
```
|
||||||
|
[rbowen@sasha:community-tools/scripts]$ ./followers.py
|
||||||
|
centosproject: 11,479 Followers
|
||||||
|
centos: 18,155 Followers
|
||||||
|
```
|
||||||
|
|
||||||
|
### get_meetups
|
||||||
|
|
||||||
|
[get_meetups 脚本][7]S 另一种类别的脚本 —— API脚本。这个特定的脚本使用 [meetup.com][8] 网站的 API 来寻找在特定区域和时间范围内特定主题的聚会,以便我可以将它报告给我的社区。你所依赖的许多服务都提供了 API,因此你的脚本可以查找信息,而无需手动查找网页。学习如何使用这些 API 既令人沮丧又耗时,但是最终将获得可以节省大量时间的技能。
|
||||||
|
|
||||||
|
_免责声明:[meetup.com][8] 已于 2019 年 8 月更改了他们的 API,我还没有将这个脚本更新到新的API,所以它现在实际上并没有工作。在接下来的几周内请关注此版本的修复版本。_
|
||||||
|
|
||||||
|
### centos-announcements.pl
|
||||||
|
|
||||||
|
[centos-announcements.pl 脚本][9]要复杂得多,而且对我的用例来说非常特殊,但你可能有类似的情况。在本例中该脚本查看邮件列表存档(`centos-announce` 邮件列表),并查找具有特定格式的邮件,然后生成这些邮件的报告。报告有两种不同的格式:一种用于我的每月新闻通讯,另一种用于安排 Twitter 信息(借助于 Hootsuite)。
|
||||||
|
|
||||||
|
我使用 Hootsuite 为 Twitter 安排内容,它们具有便捷的 CSV(逗号分隔值)格式,你可以一次批量安排整整一周的推文。从各种数据源(比如:邮件列表、博客、其他网页)自动生成 CSV 格式可以节省大量时间。但是请注意,这可能只应该用于初稿,然后你可以对其进行检查和编辑,以便最终不会自动发布你不想要内容的推文。
|
||||||
|
|
||||||
|
### reporting.pl
|
||||||
|
|
||||||
|
[reporting.pl 脚本][10]也是相当特定的,以满足我的特殊需求,但是这个概念本身是通用的。我每月向 [CentOS SIG][11](特殊兴趣小组)发送邮件,这些邮件计划在给定的月份报告。该脚本只是告诉我本月有哪些 SIG,并记录需要发送给他们的电子邮件。
|
||||||
|
|
||||||
|
但是,因以下两个原因,实际上并未发送该电子邮件。第一,我希望在消息发送之前对其进行编辑。第二,虽然发送电子邮件的脚本在过去很有效,但如今,很可能被当做垃圾邮件而被过滤。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
在这个存储库中还有一些其他脚本,这些脚本或多或少是针对我的特定需求的,但是我希望其中至少有一个脚本对你有用,并且希望这些脚本的多样性能激励你去自动化一些你自己的东西。我也希望看到你的自动化脚本存储库;在评论中链接他们!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/3/automating-community-management-python
|
||||||
|
|
||||||
|
作者:[Rich Bowen][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/rbowen
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/Open%20Pharma.png?itok=GP7zqNZE (shapes of people symbols)
|
||||||
|
[2]: http://drbacchus.com/what-does-a-community-manager-do/
|
||||||
|
[3]: https://6dollarshirts.com/rocket-surgery
|
||||||
|
[4]: https://github.com/rbowen/centos-community-tools/tree/master/scripts
|
||||||
|
[5]: https://github.com/rbowen/centos-community-tools/blob/master/scripts/tshirts.py
|
||||||
|
[6]: https://github.com/rbowen/centos-community-tools/blob/master/scripts/followers.py
|
||||||
|
[7]: https://github.com/rbowen/centos-community-tools/blob/master/scripts/get_meetups
|
||||||
|
[8]: http://meetup.com
|
||||||
|
[9]: https://github.com/rbowen/centos-community-tools/blob/master/scripts/centos-announcements.pl
|
||||||
|
[10]: https://github.com/rbowen/centos-community-tools/blob/master/scripts/sig_reporting/reporting.pl
|
||||||
|
[11]: https://wiki.centos.org/SpecialInterestGroup
|
@ -0,0 +1,453 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13047-1.html)
|
||||||
|
[#]: subject: (A beginner's guide to web scraping with Python)
|
||||||
|
[#]: via: (https://opensource.com/article/20/5/web-scraping-python)
|
||||||
|
[#]: author: (Julia Piaskowski https://opensource.com/users/julia-piaskowski)
|
||||||
|
|
||||||
|
利用 Python 爬取网站的新手指南
|
||||||
|
======
|
||||||
|
|
||||||
|
> 通过基本的 Python 工具获得爬取完整 HTML 网站的实践经验。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/24/093527skakhvc3kalnuxa1.jpg)
|
||||||
|
|
||||||
|
有很多很棒的书可以帮助你学习 Python ,但是谁真正读了这那些大部头呢?(剧透:反正不是我)。
|
||||||
|
|
||||||
|
许多人觉得教学书籍很有用,但我通常不会从头到尾地阅读一本书来学习。我是通过做一个项目,努力的弄清楚一些内容,然后再读另一本书来学习。因此,暂时丢掉书,让我们一起学习 Python。
|
||||||
|
|
||||||
|
接下来是我的第一个 Python 爬取项目的指南。它对 Python 和 HTML 的假定知识要求很低。这篇文章旨在说明如何使用 Python 的 [requests][2] 库访问网页内容,并使用 [BeatifulSoup4][3] 库以及 JSON 和 [pandas][4] 库解析网页内容。我将简要介绍 [Selenium][5] 库,但我不会深入研究如何使用该库——这个主题值得有自己的教程。最终,我希望向你展示一些技巧和小窍门,以减少网页爬取过程中遇到的问题。
|
||||||
|
|
||||||
|
### 安装依赖
|
||||||
|
|
||||||
|
我的 [GitHub 存储库][6] 中提供了本指南的所有资源。如果需要安装 Python3 的帮助,请查看 [Linux][7]、[Windows][8] 和 [Mac][9] 的教程。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 -m venv
|
||||||
|
$ source venv/bin/activate
|
||||||
|
$ pip install requests bs4 pandas
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你喜欢使用 JupyterLab ,则可以使用 [notebook][10] 运行所有代码。[安装 JupyterLab][11] 有很多方法,这是其中一种:
|
||||||
|
|
||||||
|
```
|
||||||
|
# from the same virtual environment as above, run:
|
||||||
|
$ pip install jupyterlab
|
||||||
|
```
|
||||||
|
|
||||||
|
### 为网站抓取项目设定目标
|
||||||
|
|
||||||
|
现在我们已经安装了依赖项,但是爬取网页需要做什么?
|
||||||
|
|
||||||
|
让我们退一步,确保使目标清晰。下面是成功完成网页爬取项目需求列表:
|
||||||
|
|
||||||
|
* 我们收集的信息,是值得我们花大力气去建立一个有效的网页爬取器的。
|
||||||
|
* 我们所下载的信息是可以通过网页爬取器合法和道德地收集的。
|
||||||
|
* 对如何在 HTML 代码中找到目标信息有一定的了解。
|
||||||
|
* 利用恰当的工具:在此情况下,需要使用 BeautifulSoup 库和 requests 库。
|
||||||
|
* 知道(或愿意去学习)如何解析 JSON 对象。
|
||||||
|
* 有足够的 pandas 数据处理技能。
|
||||||
|
|
||||||
|
关于 HTML 的备注:HTML 是运行在互联网上的“猛兽”,但我们最需要了解的是标签的工作方式。标签是一对由尖括号包围关键词(一般成对出现,其内容在两个标签中间)。比如,这是一个假装的标签,称为 `pro-tip`:
|
||||||
|
|
||||||
|
```
|
||||||
|
<pro-tip> All you need to know about html is how tags work </pro-tip>
|
||||||
|
```
|
||||||
|
|
||||||
|
我们可以通过调用标签 `pro-tip` 来访问其中的信息(`All you need to know…`)。本教程将进一步介绍如何查找和访问标签。要进一步了解 HTML 基础知识,请查看 [本文][12]。
|
||||||
|
|
||||||
|
### 网站爬取项目中要找的是什么
|
||||||
|
|
||||||
|
有些数据利用网站爬取采集比利用其他方法更合适。以下是我认为合适项目的准则:
|
||||||
|
|
||||||
|
没有可用于数据(处理)的公共 API。通过 API 抓取结构化数据会容易得多,(所以没有 API )有助于澄清收集数据的合法性和道德性。而有相当数量的结构化数据,并有规律的、可重复的格式,才能证明这种努力的合理性。网页爬取可能会很痛苦。BeautifulSoup(bs4)使操作更容易,但无法避免网站的个别特殊性,需要进行定制。数据的相同格式化不是必须的,但这确实使事情变得更容易。存在的 “边际案例”(偏离规范)越多,爬取就越复杂。
|
||||||
|
|
||||||
|
免责声明:我没有参加过法律培训;以下内容无意作为正式的法律建议。
|
||||||
|
|
||||||
|
关于合法性,访问大量有价值信息可能令人兴奋,但仅仅因为它是可能的,并不意味着应该这样做。
|
||||||
|
|
||||||
|
值得庆幸的是,有一些公共信息可以指导我们的道德规范和网页爬取工具。大多数网站都有与该网站关联的 [robots.txt][13] 文件,指出允许哪些爬取活动,哪些不被允许。它主要用于与搜索引擎(网页抓取工具的终极形态)进行交互。然而,网站上的许多信息都被视为公共信息。因此,有人将 `robots.txt` 文件视为一组建议,而不是具有法律约束力的文档。 `robots.txt` 文件并不涉及数据的道德收集和使用等主题。
|
||||||
|
|
||||||
|
在开始爬取项目之前,问自己以下问题:
|
||||||
|
|
||||||
|
* 我是否在爬取版权材料?
|
||||||
|
* 我的爬取活动会危害个人隐私吗?
|
||||||
|
* 我是否发送了大量可能会使服务器超载或损坏的请求?
|
||||||
|
* 爬取是否会泄露出我不拥有的知识产权?
|
||||||
|
* 是否有规范网站使用的服务条款,我是否遵循了这些条款?
|
||||||
|
* 我的爬取活动会减少原始数据的价值吗?(例如,我是否打算按原样重新打包数据,或者可能从原始来源中抽取网站流量)?
|
||||||
|
|
||||||
|
当我爬取一个网站时,请确保可以对所有这些问题回答 “否”。
|
||||||
|
|
||||||
|
要深入了解这些法律问题,请参阅 2018 年出版的 Krotov 和 Silva 撰写的[《Web 爬取的合法性和道德性》][14] 和 Sellars 的[《二十年 Web 爬取和计算机欺诈与滥用法案》][15]。
|
||||||
|
|
||||||
|
### 现在开始爬取网站
|
||||||
|
|
||||||
|
经过上述评估,我想出了一个项目。我的目标是爬取爱达荷州所有 Family Dollar 商店的地址。 这些商店在农村地区规模很大,因此我想了解有多少家这样的商店。
|
||||||
|
|
||||||
|
起点是 [Family Dollar 的位置页面][16]
|
||||||
|
|
||||||
|
![爱达荷州 Family Dollar 所在地页面][17]
|
||||||
|
|
||||||
|
首先,让我们在 Python 虚拟环境中加载先决条件。此处的代码将被添加到一个 Python 文件(如果你想要个名称,则为 `scraper.py`)或在 JupyterLab 的单元格中运行。
|
||||||
|
|
||||||
|
```
|
||||||
|
import requests # for making standard html requests
|
||||||
|
from bs4 import BeautifulSoup # magical tool for parsing html data
|
||||||
|
import json # for parsing data
|
||||||
|
from pandas import DataFrame as df # premier library for data organization
|
||||||
|
```
|
||||||
|
|
||||||
|
接下来,我们从目标 URL 中请求数据。
|
||||||
|
|
||||||
|
```
|
||||||
|
page = requests.get("https://locations.familydollar.com/id/")
|
||||||
|
soup = BeautifulSoup(page.text, 'html.parser')
|
||||||
|
```
|
||||||
|
|
||||||
|
BeautifulSoup 将 HTML 或 XML 内容转换为复杂树对象。这是我们将使用的几种常见对象类型。
|
||||||
|
|
||||||
|
* `BeautifulSoup` —— 解析的内容
|
||||||
|
* `Tag` —— 标准 HTML 标记,这是你将遇到的 `bs4` 元素的主要类型
|
||||||
|
* `NavigableString` —— 标签内的文本字符串
|
||||||
|
* `Comment` —— NavigableString 的一种特殊类型
|
||||||
|
|
||||||
|
当我们查看 `requests.get()` 输出时,还有更多要考虑的问题。我仅使用 `page.text()` 将请求的页面转换为可读的内容,但是还有其他输出类型:
|
||||||
|
|
||||||
|
* `page.text()` 文本(最常见)
|
||||||
|
* `page.content()` 逐字节输出
|
||||||
|
* `page.json()` JSON 对象
|
||||||
|
* `page.raw()` 原始套接字响应(对你没啥用)
|
||||||
|
|
||||||
|
我只在使用拉丁字母的纯英语网站上操作。 `requests` 中的默认编码设置可以很好地解决这一问题。然而,除了纯英语网站之外,就是更大的互联网世界。为了确保 `requests` 正确解析内容,你可以设置文本的编码:
|
||||||
|
|
||||||
|
```
|
||||||
|
page = requests.get(URL)
|
||||||
|
page.encoding = 'ISO-885901'
|
||||||
|
soup = BeautifulSoup(page.text, 'html.parser')
|
||||||
|
```
|
||||||
|
|
||||||
|
仔细研究 `BeautifulSoup` 标签,我们看到:
|
||||||
|
|
||||||
|
* `bs4` 元素 `tag` 捕获的是一个 HTML 标记。
|
||||||
|
* 它具有名称和属性,可以像字典一样访问:`tag['someAttribute']`。
|
||||||
|
* 如果标签具有相同名称的多个属性,则仅访问第一个实例。
|
||||||
|
* 可通过 `tag.contents` 访问子标签。
|
||||||
|
* 所有标签后代都可以通过 `tag.contents` 访问。
|
||||||
|
* 你始终可以使用以下字符串:`re.compile("your_string")` 访问一个字符串的所有内容,而不是浏览 HTML 树。
|
||||||
|
|
||||||
|
### 确定如何提取相应内容
|
||||||
|
|
||||||
|
警告:此过程可能令人沮丧。
|
||||||
|
|
||||||
|
网站爬取过程中的提取可能是一个令人生畏的充满了误区的过程。我认为解决此问题的最佳方法是从一个有代表性的示例开始然后进行扩展(此原理对于任何编程任务都是适用的)。查看页面的 HTML 源代码至关重要。有很多方法可以做到这一点。
|
||||||
|
|
||||||
|
你可以在终端中使用 Python 查看页面的整个源代码(不建议使用)。运行此代码需要你自担风险:
|
||||||
|
|
||||||
|
```
|
||||||
|
print(soup.prettify())
|
||||||
|
```
|
||||||
|
|
||||||
|
虽然打印出页面的整个源代码可能适用于某些教程中显示的玩具示例,但大多数现代网站的页面上都有大量内容。甚至 404 页面也可能充满了页眉、页脚等代码。
|
||||||
|
|
||||||
|
通常,在你喜欢的浏览器中通过 “查看页面源代码” 来浏览源代码是最容易的(单击右键,然后选择 “查看页面源代码” )。这是找到目标内容的最可靠方法(稍后我将解释原因)。
|
||||||
|
|
||||||
|
![Family Dollar 页面源代码][18]
|
||||||
|
|
||||||
|
在这种情况下,我需要在这个巨大的 HTML 海洋中找到我的目标内容 —— 地址、城市、州和邮政编码。通常,对页面源(`ctrl+F`)的简单搜索就会得到目标位置所在的位置。一旦我实际看到目标内容的示例(至少一个商店的地址),便会找到将该内容与其他内容区分开的属性或标签。
|
||||||
|
|
||||||
|
首先,我需要在爱达荷州 Family Dollar 商店中收集不同城市的网址,并访问这些网站以获取地址信息。这些网址似乎都包含在 `href` 标记中。太棒了!我将尝试使用 `find_all` 命令进行搜索:
|
||||||
|
|
||||||
|
```
|
||||||
|
dollar_tree_list = soup.find_all('href')
|
||||||
|
dollar_tree_list
|
||||||
|
```
|
||||||
|
|
||||||
|
搜索 `href` 不会产生任何结果,该死。这可能是因为 `href` 嵌套在 `itemlist` 类中而失败。对于下一次尝试,请搜索 `item_list`。由于 `class` 是 Python 中的保留字,因此使用 `class_` 来作为替代。`soup.find_all()` 原来是 `bs4` 函数的瑞士军刀。
|
||||||
|
|
||||||
|
```
|
||||||
|
dollar_tree_list = soup.find_all(class_ = 'itemlist')
|
||||||
|
for i in dollar_tree_list[:2]:
|
||||||
|
print(i)
|
||||||
|
```
|
||||||
|
|
||||||
|
有趣的是,我发现搜索一个特定类的方法一般是一种成功的方法。通过找出对象的类型和长度,我们可以了解更多有关对象的信息。
|
||||||
|
|
||||||
|
```
|
||||||
|
type(dollar_tree_list)
|
||||||
|
len(dollar_tree_list)
|
||||||
|
```
|
||||||
|
|
||||||
|
可以使用 `.contents` 从 BeautifulSoup “结果集” 中提取内容。这也是创建单个代表性示例的好时机。
|
||||||
|
|
||||||
|
```
|
||||||
|
example = dollar_tree_list[2] # a representative example
|
||||||
|
example_content = example.contents
|
||||||
|
print(example_content)
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `.attr` 查找该对象内容中存在的属性。注意:`.contents` 通常会返回一个项目的精确的列表,因此第一步是使用方括号符号为该项目建立索引。
|
||||||
|
|
||||||
|
```
|
||||||
|
example_content = example.contents[0]
|
||||||
|
example_content.attrs
|
||||||
|
```
|
||||||
|
|
||||||
|
现在,我可以看到 `href` 是一个属性,可以像字典项一样提取它:
|
||||||
|
|
||||||
|
```
|
||||||
|
example_href = example_content['href']
|
||||||
|
print(example_href)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 整合网站抓取工具
|
||||||
|
|
||||||
|
所有的这些探索为我们提供了前进的路径。这是厘清上面逻辑的一个清理版本。
|
||||||
|
|
||||||
|
```
|
||||||
|
city_hrefs = [] # initialise empty list
|
||||||
|
|
||||||
|
for i in dollar_tree_list:
|
||||||
|
cont = i.contents[0]
|
||||||
|
href = cont['href']
|
||||||
|
city_hrefs.append(href)
|
||||||
|
|
||||||
|
# check to be sure all went well
|
||||||
|
for i in city_hrefs[:2]:
|
||||||
|
print(i)
|
||||||
|
```
|
||||||
|
|
||||||
|
输出的内容是一个关于抓取爱达荷州 Family Dollar 商店 URL 的列表。
|
||||||
|
|
||||||
|
也就是说,我仍然没有获得地址信息!现在,需要抓取每个城市的 URL 以获得此信息。因此,我们使用一个具有代表性的示例重新开始该过程。
|
||||||
|
|
||||||
|
```
|
||||||
|
page2 = requests.get(city_hrefs[2]) # again establish a representative example
|
||||||
|
soup2 = BeautifulSoup(page2.text, 'html.parser')
|
||||||
|
```
|
||||||
|
|
||||||
|
![Family Dollar 地图和代码][19]
|
||||||
|
|
||||||
|
地址信息嵌套在 `type="application/ld+json"` 里。经过大量的地理位置抓取之后,我开始认识到这是用于存储地址信息的一般结构。幸运的是,`soup.find_all()` 开启了利用 `type` 搜索。
|
||||||
|
|
||||||
|
```
|
||||||
|
arco = soup2.find_all(type="application/ld+json")
|
||||||
|
print(arco[1])
|
||||||
|
```
|
||||||
|
|
||||||
|
地址信息在第二个列表成员中!原来如此!
|
||||||
|
|
||||||
|
使用 `.contents` 提取(从第二个列表项中)内容(这是过滤后的合适的默认操作)。同样,由于输出的内容是一个列表,因此我为该列表项建立了索引:
|
||||||
|
|
||||||
|
```
|
||||||
|
arco_contents = arco[1].contents[0]
|
||||||
|
arco_contents
|
||||||
|
```
|
||||||
|
|
||||||
|
喔,看起来不错。此处提供的格式与 JSON 格式一致(而且,该类型的名称中确实包含 “json”)。 JSON 对象的行为就像是带有嵌套字典的字典。一旦你熟悉利用其去工作,它实际上是一种不错的格式(当然,它比一长串正则表达式命令更容易编程)。尽管从结构上看起来像一个 JSON 对象,但它仍然是 `bs4` 对象,需要通过编程方式转换为 JSON 对象才能对其进行访问:
|
||||||
|
|
||||||
|
```
|
||||||
|
arco_json = json.loads(arco_contents)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
type(arco_json)
|
||||||
|
print(arco_json)
|
||||||
|
```
|
||||||
|
|
||||||
|
在该内容中,有一个被调用的 `address` 键,该键要求地址信息在一个比较小的嵌套字典里。可以这样检索:
|
||||||
|
|
||||||
|
```
|
||||||
|
arco_address = arco_json['address']
|
||||||
|
arco_address
|
||||||
|
```
|
||||||
|
|
||||||
|
好吧,请大家注意。现在我可以遍历存储爱达荷州 URL 的列表:
|
||||||
|
|
||||||
|
```
|
||||||
|
locs_dict = [] # initialise empty list
|
||||||
|
|
||||||
|
for link in city_hrefs:
|
||||||
|
locpage = requests.get(link) # request page info
|
||||||
|
locsoup = BeautifulSoup(locpage.text, 'html.parser')
|
||||||
|
# parse the page's content
|
||||||
|
locinfo = locsoup.find_all(type="application/ld+json")
|
||||||
|
# extract specific element
|
||||||
|
loccont = locinfo[1].contents[0]
|
||||||
|
# get contents from the bs4 element set
|
||||||
|
locjson = json.loads(loccont) # convert to json
|
||||||
|
locaddr = locjson['address'] # get address
|
||||||
|
locs_dict.append(locaddr) # add address to list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 用 Pandas 整理我们的网站抓取结果
|
||||||
|
|
||||||
|
我们在字典中装载了大量数据,但是还有一些额外的无用项,它们会使重用数据变得比需要的更为复杂。要执行最终的数据组织,我们需要将其转换为 Pandas 数据框架,删除不需要的列 `@type` 和 `country`,并检查前五行以确保一切正常。
|
||||||
|
|
||||||
|
```
|
||||||
|
locs_df = df.from_records(locs_dict)
|
||||||
|
locs_df.drop(['@type', 'addressCountry'], axis = 1, inplace = True)
|
||||||
|
locs_df.head(n = 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
确保保存结果!!
|
||||||
|
|
||||||
|
```
|
||||||
|
df.to_csv(locs_df, "family_dollar_ID_locations.csv", sep = ",", index = False)
|
||||||
|
```
|
||||||
|
|
||||||
|
我们做到了!所有爱达荷州 Family Dollar 商店都有一个用逗号分隔的列表。多令人兴奋。
|
||||||
|
|
||||||
|
### Selenium 和数据抓取的一点说明
|
||||||
|
|
||||||
|
[Selenium][5] 是用于与网页自动交互的常用工具。为了解释为什么有时必须使用它,让我们来看一个使用 Walgreens 网站的示例。 “检查元素” 提供了浏览器显示内容的代码:
|
||||||
|
|
||||||
|
![Walgreens 位置页面和代码][20]
|
||||||
|
|
||||||
|
虽然 “查看页面源代码” 提供了有关 `requests` 将获得什么内容的代码:
|
||||||
|
|
||||||
|
![Walgreens 源代码][21]
|
||||||
|
|
||||||
|
如果这两个不一致,是有一些插件可以修改源代码 —— 因此,应在将页面加载到浏览器后对其进行访问。`requests` 不能做到这一点,但是 Selenium 可以做到。
|
||||||
|
|
||||||
|
Selenium 需要 Web 驱动程序来检索内容。实际上,它会打开 Web 浏览器,并收集此页面的内容。Selenium 功能强大 —— 它可以通过多种方式与加载的内容进行交互(请阅读文档)。使用 Selenium 获取数据后,继续像以前一样使用 BeautifulSoup:
|
||||||
|
|
||||||
|
```
|
||||||
|
url = "https://www.walgreens.com/storelistings/storesbycity.jsp?requestType=locator&state=ID"
|
||||||
|
driver = webdriver.Firefox(executable_path = 'mypath/geckodriver.exe')
|
||||||
|
driver.get(url)
|
||||||
|
soup_ID = BeautifulSoup(driver.page_source, 'html.parser')
|
||||||
|
store_link_soup = soup_ID.find_all(class_ = 'col-xl-4 col-lg-4 col-md-4')
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 Family Dollar 这种情形,我不需要 Selenium,但是当呈现的内容与源代码不同时,我确实会保留使用 Selenium。
|
||||||
|
|
||||||
|
### 小结
|
||||||
|
|
||||||
|
总之,使用网站抓取来完成有意义的任务时:
|
||||||
|
|
||||||
|
* 耐心一点
|
||||||
|
* 查阅手册(它们非常有帮助)
|
||||||
|
|
||||||
|
如果你对答案感到好奇:
|
||||||
|
|
||||||
|
![Family Dollar 位置图][23]
|
||||||
|
|
||||||
|
美国有很多 Family Dollar 商店。
|
||||||
|
|
||||||
|
完整的源代码是:
|
||||||
|
|
||||||
|
```
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import json
|
||||||
|
from pandas import DataFrame as df
|
||||||
|
|
||||||
|
page = requests.get("https://www.familydollar.com/locations/")
|
||||||
|
soup = BeautifulSoup(page.text, 'html.parser')
|
||||||
|
|
||||||
|
# find all state links
|
||||||
|
state_list = soup.find_all(class_ = 'itemlist')
|
||||||
|
|
||||||
|
state_links = []
|
||||||
|
|
||||||
|
for i in state_list:
|
||||||
|
cont = i.contents[0]
|
||||||
|
attr = cont.attrs
|
||||||
|
hrefs = attr['href']
|
||||||
|
state_links.append(hrefs)
|
||||||
|
|
||||||
|
# find all city links
|
||||||
|
city_links = []
|
||||||
|
|
||||||
|
for link in state_links:
|
||||||
|
page = requests.get(link)
|
||||||
|
soup = BeautifulSoup(page.text, 'html.parser')
|
||||||
|
familydollar_list = soup.find_all(class_ = 'itemlist')
|
||||||
|
for store in familydollar_list:
|
||||||
|
cont = store.contents[0]
|
||||||
|
attr = cont.attrs
|
||||||
|
city_hrefs = attr['href']
|
||||||
|
city_links.append(city_hrefs)
|
||||||
|
# to get individual store links
|
||||||
|
store_links = []
|
||||||
|
|
||||||
|
for link in city_links:
|
||||||
|
locpage = requests.get(link)
|
||||||
|
locsoup = BeautifulSoup(locpage.text, 'html.parser')
|
||||||
|
locinfo = locsoup.find_all(type="application/ld+json")
|
||||||
|
for i in locinfo:
|
||||||
|
loccont = i.contents[0]
|
||||||
|
locjson = json.loads(loccont)
|
||||||
|
try:
|
||||||
|
store_url = locjson['url']
|
||||||
|
store_links.append(store_url)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# get address and geolocation information
|
||||||
|
stores = []
|
||||||
|
|
||||||
|
for store in store_links:
|
||||||
|
storepage = requests.get(store)
|
||||||
|
storesoup = BeautifulSoup(storepage.text, 'html.parser')
|
||||||
|
storeinfo = storesoup.find_all(type="application/ld+json")
|
||||||
|
for i in storeinfo:
|
||||||
|
storecont = i.contents[0]
|
||||||
|
storejson = json.loads(storecont)
|
||||||
|
try:
|
||||||
|
store_addr = storejson['address']
|
||||||
|
store_addr.update(storejson['geo'])
|
||||||
|
stores.append(store_addr)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# final data parsing
|
||||||
|
stores_df = df.from_records(stores)
|
||||||
|
stores_df.drop(['@type', 'addressCountry'], axis = 1, inplace = True)
|
||||||
|
stores_df['Store'] = "Family Dollar"
|
||||||
|
|
||||||
|
df.to_csv(stores_df, "family_dollar_locations.csv", sep = ",", index = False)
|
||||||
|
```
|
||||||
|
|
||||||
|
作者注释:本文改编自 2020 年 2 月 9 日在俄勒冈州波特兰的[我在 PyCascades 的演讲][24]。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/5/web-scraping-python
|
||||||
|
|
||||||
|
作者:[Julia Piaskowski][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/julia-piaskowski
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus_html_code.png?itok=VjUmGsnl (HTML code)
|
||||||
|
[2]: https://requests.readthedocs.io/en/master/
|
||||||
|
[3]: https://beautiful-soup-4.readthedocs.io/en/latest/
|
||||||
|
[4]: https://pandas.pydata.org/
|
||||||
|
[5]: https://www.selenium.dev/
|
||||||
|
[6]: https://github.com/jpiaskowski/pycas2020_web_scraping
|
||||||
|
[7]: https://opensource.com/article/20/4/install-python-linux
|
||||||
|
[8]: https://opensource.com/article/19/8/how-install-python-windows
|
||||||
|
[9]: https://opensource.com/article/19/5/python-3-default-mac
|
||||||
|
[10]: https://github.com/jpiaskowski/pycas2020_web_scraping/blob/master/example/Familydollar_location_scrape-all-states.ipynb
|
||||||
|
[11]: https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html
|
||||||
|
[12]: https://opensource.com/article/20/4/build-websites
|
||||||
|
[13]: https://www.contentkingapp.com/academy/robotstxt/
|
||||||
|
[14]: https://www.researchgate.net/publication/324907302_Legality_and_Ethics_of_Web_Scraping
|
||||||
|
[15]: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3221625
|
||||||
|
[16]: https://locations.familydollar.com/id/
|
||||||
|
[17]: https://opensource.com/sites/default/files/uploads/familydollar1.png (Family Dollar Idaho locations page)
|
||||||
|
[18]: https://opensource.com/sites/default/files/uploads/familydollar2.png (Family Dollar page source code)
|
||||||
|
[19]: https://opensource.com/sites/default/files/uploads/familydollar3.png (Family Dollar map and code)
|
||||||
|
[20]: https://opensource.com/sites/default/files/uploads/walgreens1.png (Walgreens location page and code)
|
||||||
|
[21]: https://opensource.com/sites/default/files/uploads/walgreens2.png (Walgreens source code)
|
||||||
|
[22]: https://www.walgreens.com/storelistings/storesbycity.jsp?requestType=locator\&state=ID
|
||||||
|
[23]: https://opensource.com/sites/default/files/uploads/family_dollar_locations.png (Family Dollar locations map)
|
||||||
|
[24]: https://2020.pycascades.com/talks/adventures-in-babysitting-webscraping-for-python-and-html-novices/
|
@ -0,0 +1,186 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13031-1.html)
|
||||||
|
[#]: subject: (Learn Python by creating a video game)
|
||||||
|
[#]: via: (https://opensource.com/article/20/10/learn-python-ebook)
|
||||||
|
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||||
|
|
||||||
|
通过创建视频游戏来学习 Python
|
||||||
|
======
|
||||||
|
|
||||||
|
> 使用我们的新电子书中的分步说明,以有趣的方式了解 Python。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/18/234525jdrrv6o6gkhkdq1k.jpg)
|
||||||
|
|
||||||
|
Python 是目前最流行的程序设计语言之一。不管是为了工作还是娱乐为目的学习 Python,它都是一门功能强大且非常有用的编程语言。你可以创建应用程序来帮助你完成日常任务,创建你和朋友们喜欢玩的游戏,创建用于处理数据的脚本,创建用于生成或分析信息的应用程序等等。
|
||||||
|
|
||||||
|
无论你计划使用程序设计语言做什么,我们都认为通过创建游戏来学习比通过处理数字或变换字符串来学习更为有趣。然而,如果你完全是一个编程的新手,当你能看到代码在视频游戏等熟悉的环境中工作时,你会更容易理解为什么要用代码做某事。
|
||||||
|
|
||||||
|
你可能不会选择 [Python][2] 作为最好的编程语言(每个人对此都有自己的答案),但它不是一门令人恐惧的编程语言。 Python 可以使用很多关键字(例如 `is` 和 `is not`)代替符号(例如 `=` 和 `!=`)。它还能管理许多低级任务,因此你通常不必担心数据类型和垃圾收集之类的事情。通常,这意味着你马上就可以开始编写代码,而不会像在 [C][3] 或 [Java][4] 那样的复杂编程语言面前遇到挫折。
|
||||||
|
|
||||||
|
为了帮助你学习 Python,我们编写了一本电子书,教你如何使用 Python 创建平台类视频游戏。在制作视频游戏的同时逐步通过课程学习 Python。另外一个好处是,你还将学习编程逻辑、语法、运算符等更多的内容。你可以在学习过程中立即看到结果,因此你学到的所有内容都会得到及时巩固。
|
||||||
|
|
||||||
|
### 一分钟上手 Python
|
||||||
|
|
||||||
|
Python 是一种用途广泛的编程语言,这意味着它(与大多数语言一样)提供了函数来对数字和字符做处理的“简单技巧”。Linux 操作系统用户已经安装了 Python。 Mac 操作系统用户使用的是较旧版本的 Python,但是你可以从 Python.org 网站 [安装最新版本][5]。Windows 操作系统用户可以从这篇 [在 Windows 上安装 Python][6] 的文章中学习如何安装 Python。
|
||||||
|
|
||||||
|
安装完成后,你可以启动交互式 Python Shell 进行算术运算:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3
|
||||||
|
>>> 5+6
|
||||||
|
11
|
||||||
|
>>> 11/2
|
||||||
|
5.5
|
||||||
|
>>> 11//2
|
||||||
|
5
|
||||||
|
>>> 11%2
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
从该示例可以了解,需要一些特殊的符号,但学过数学的人都最熟悉不过了。也许你不喜欢数字,而更喜欢字母:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3
|
||||||
|
>>> string = "hello world"
|
||||||
|
>>> print(string)
|
||||||
|
hello world
|
||||||
|
>>> print(string.upper())
|
||||||
|
HELLO WORLD
|
||||||
|
>>> print(string[0])
|
||||||
|
h
|
||||||
|
>>> print(string[1])
|
||||||
|
e
|
||||||
|
>>> print(string[2])
|
||||||
|
l
|
||||||
|
>>> print(string[3])
|
||||||
|
l
|
||||||
|
>>> print(string[4])
|
||||||
|
o
|
||||||
|
```
|
||||||
|
|
||||||
|
同样,相对地说基础的任务有特殊的符号表示法,但是即使没有说明,你也可能已经发现 `[0]` 和 `[1]` 符号表示法是将数据“切片”并且利用 `print` 函数将其中的数据显示在屏幕上。
|
||||||
|
|
||||||
|
### 五分钟用上 Pygame
|
||||||
|
|
||||||
|
如果你只想使用 Python 来创建一个视频游戏或任何超越基本计算的项目,这可能需要投入大量的学习、努力和时间。幸运的是,Python 诞生已有二十年了,开发者已经开发了代码库来帮助你(相对)轻松地完成典型的程序壮举。[Pygame][7] 是一套用于创建视频游戏的代码模块。它 [不是唯一的这种类库][8],但是它是最古老的(不论好坏),因此在线上有很多文档和示例。
|
||||||
|
|
||||||
|
首先学习 [推荐的 Python 虚拟环境工作流程][9]:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 -m venv mycode/venv
|
||||||
|
$ cd mycode
|
||||||
|
$ source ./venv/bin/activate
|
||||||
|
(venv)$
|
||||||
|
```
|
||||||
|
|
||||||
|
进入虚拟环境后,可以安全地将 Pygame 安装到项目文件夹中:
|
||||||
|
|
||||||
|
```
|
||||||
|
(venv)$ echo "pygame" >> requirements.txt
|
||||||
|
(venv)$ python -m pip install -r requirements.txt
|
||||||
|
[...] Installing collected packages: pygame
|
||||||
|
Successfully installed pygame-x.y.z
|
||||||
|
```
|
||||||
|
|
||||||
|
现在你已经安装了 Pygame,就可以创建一个简单的演示应用程序。它比你想象的要容易。Python 可以进行所谓的面向对象编程(OOP),这是一个漂亮的计算机科学术语,用于描述当代码结构化时,就像你在使用代码创建物理对象一样。然而,程序员并没有受到迷惑。他们知道在编写代码时并不是真的在制造物理对象,但是这样有助于想象,因为这样你就可以了解编程世界的局限性。
|
||||||
|
|
||||||
|
例如,如果你被困在一个荒岛上并想要一杯咖啡,那么你就必须收集一些黏土,做一个杯子,然后烘烤它。如果你足够聪明,先创建一个模具,以便每当需要另一个杯子时,都可以从模板中快速创建一个新杯子。即使每个杯子都来自相同的模板,它们在物理上也是独立的:如果一个杯子破裂,你还会有另一个杯子。你可以通过添加颜色或蚀刻使每个咖啡杯显得独一无二。
|
||||||
|
|
||||||
|
在 Pygame 和许多编程任务中,你都会使用类似的逻辑。在定义之前,它不会出现在你的编程项目中。下面是如何在 Python 和 Pygame 程序中让咖啡杯出现。
|
||||||
|
|
||||||
|
#### 使用 Pygame 进行面向对象编程
|
||||||
|
|
||||||
|
创建一个名为 `main.py` 的文件,并输入以下代码用以启动 Pygame 模块,并使用 Pygame 模板创建一个窗口:
|
||||||
|
|
||||||
|
```
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
screen = pygame.display.set_mode((960,720))
|
||||||
|
```
|
||||||
|
|
||||||
|
就像你可能在现实生活中使用模板来创建对象一样,你也可以使用 Pygame 提供的模板来创建一个<ruby>妖精<rt>sprite</rt></ruby>(这是 Pygame 的视觉游戏对象术语)。在面向对象的编程中,`class` 表示对象的模板。在你的文档中输入以下代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
class Cup(pygame.sprite.Sprite):
|
||||||
|
def __init__(self):
|
||||||
|
pygame.sprite.Sprite.__init__(self)
|
||||||
|
|
||||||
|
# image
|
||||||
|
img = pygame.image.load('coffeecup.png').convert()
|
||||||
|
self.image = img
|
||||||
|
|
||||||
|
# volume
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
self.rect.x = 10
|
||||||
|
self.rect.y = 10
|
||||||
|
```
|
||||||
|
|
||||||
|
该代码块使用 Pygame 的 `sprite` 模板设计一个咖啡杯子妖精。由于 `self.image` 的存在,你的咖啡杯妖精有一个图像,而 `self.rect` 则赋予了它体积(宽度和高度)。这些是 Pygame 期望妖精拥有的属性,但是如果你要创建一个可玩的视频游戏,则可以为其指定任何其他所需的属性,例如健康点和得分。
|
||||||
|
|
||||||
|
到目前为止,你所要做的就是创建一个窗口和一个用于咖啡杯的 _模板_ 。你的游戏实际上还没有一个杯子。
|
||||||
|
|
||||||
|
你的代码的最后一部分必须使用模板来生成杯子并将其添加到游戏世界中。如你所知,计算机运行速度非常快,因此从技术上讲,你到目前为止创建的代码只会运行一毫秒左右。编写图形计算机应用程序时,无论计算机是否认为已完成规定的任务,都必须强制其保持打开状态。程序员使用 _无限循环_ 来执行此操作,该循环在 Python 中由 `while True` 语句表示(`True` 始终为真,因此循环永远不会结束)。
|
||||||
|
|
||||||
|
无限循环可以确保你的应用程序保持打开状态足够长的时间,以使计算机用户可以查看和使用该应用程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
cup = Cup()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
pygame.display.update()
|
||||||
|
screen.blit(cup.image, cup.rect)
|
||||||
|
```
|
||||||
|
|
||||||
|
此代码示例从模板 `Cup` 创建杯子,然后使用 Pygame 函数更新显示。最后,使用 Pygame 的 `blit` 函数在其边框内绘制杯子的图像。
|
||||||
|
|
||||||
|
#### 获取图形
|
||||||
|
|
||||||
|
在成功运行代码之前,你需要为咖啡杯准备一个图形。你可以在 [FreeSVG.org][11] 上找到许多 [公用创作][10] 咖啡杯图形。我用了 [这个][12]。将图形保存在项目目录中,并将其命名为 `coffeecup.png`。
|
||||||
|
|
||||||
|
#### 运行游戏
|
||||||
|
|
||||||
|
启动应用程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
(venv)$ python ./main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
![Pygame 中的咖啡杯][13]
|
||||||
|
|
||||||
|
- [下载 Python 游戏电子书][15]
|
||||||
|
|
||||||
|
Pygame 是一个功能强大的框架,除了在屏幕上绘制咖啡杯之外,你还可以做更多的事情。[下载我们的免费电子书][15] 更好地了解 Pygame 和 Python。
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/10/learn-python-ebook
|
||||||
|
|
||||||
|
作者:[Seth Kenlon][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/seth
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/arcade_game_gaming.jpg?itok=84Rjk_32 (Arcade games)
|
||||||
|
[2]: https://www.python.org/
|
||||||
|
[3]: https://opensource.com/article/20/8/c-programming-cheat-sheet
|
||||||
|
[4]: https://opensource.com/resources/java
|
||||||
|
[5]: https://www.python.org/downloads/mac-osx
|
||||||
|
[6]: https://opensource.com/article/19/8/how-install-python-windows
|
||||||
|
[7]: https://www.pygame.org/news
|
||||||
|
[8]: https://opensource.com/article/18/4/easy-2d-game-creation-python-and-arcade
|
||||||
|
[9]: https://opensource.com/article/20/9/venv-python
|
||||||
|
[10]: https://opensource.com/article/20/1/what-creative-commons
|
||||||
|
[11]: http://freesvg.org
|
||||||
|
[12]: https://freesvg.org/1548870028
|
||||||
|
[13]: https://opensource.com/sites/default/files/uploads/pygame-cup.jpg (Coffee cup in Pygame)
|
||||||
|
[14]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[15]: https://opensource.com/downloads/python-gaming-ebook
|
@ -0,0 +1,252 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "larryzju"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13006-1.html"
|
||||||
|
[#]: subject: "How to use Kubernetes resource quotas"
|
||||||
|
[#]: via: "https://opensource.com/article/20/12/kubernetes-resource-quotas"
|
||||||
|
[#]: author: "Mike Calizo https://opensource.com/users/mcalizo"
|
||||||
|
|
||||||
|
Kubernetes 资源配额使用指南
|
||||||
|
======
|
||||||
|
|
||||||
|
> 资源配额控制应用的 CPU 或内存使用情况,防止资源被过量使用或被抢占。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/12/125309xr0kskdrqv33vn4q.jpg)
|
||||||
|
|
||||||
|
当 Kubernetes 集群运行过一段时间或者在被开发者大量使用后,[Kubernetes][2] 资源(例如 CPU 和内存)的控制的问题就会显现出来。而在大多情况下只有集群出问题后,我们才会意识到资源控制的重要性。
|
||||||
|
|
||||||
|
Kubernetes 部署过程如果没有能充分考虑到将来的扩展性,资源类问题将会非常常见,此类问题与集群的管理和部署团队的经验有关。
|
||||||
|
|
||||||
|
如果不加以合理控制,一个暴力的应用或者开发者可能影响到共享该集群的所有业务,大家因此会相互埋怨、指责并保护性地抢占资源。这对于集群管理和开发人员都是非常难以处理的场景。
|
||||||
|
|
||||||
|
在 Kubernetes 环境中控制应用的计算资源使用有多种方式。大部分情况下,我们可以使用“资源控制”和“限制范围”。注意存储管理不在我们讨论范围之内,存储管理可以通过<ruby>持久卷<rt>Persistent Volume</rt></ruby> 件,以实现针对不同的存储控制需求。
|
||||||
|
|
||||||
|
资源配额是一种控制 Kubernetes 计算资源的方法。本文告诉你如何使用该功能来管理开发人员行为并控制应用的资源使用。
|
||||||
|
|
||||||
|
### 什么是资源配额
|
||||||
|
|
||||||
|
简而言之,[资源配额][3] 提供了限制每个命名空间资源消耗的约束条件,它们只能在命名空间级别上应用,这意味着它们可以应用于计算资源,并限制命名空间内的对象数量。
|
||||||
|
|
||||||
|
Kubernetes资源配额通过 `ResourceQuota` 对象来为每个命名空间设置资源配额,对以下对象类型的 CPU 和内存进行限制:
|
||||||
|
|
||||||
|
* <ruby>吊舱<rt>Pod</rt></ruby>
|
||||||
|
* <ruby>服务<rt>Service</rt></ruby>
|
||||||
|
* <ruby>机密信息<rt>Secret</rt></ruby>
|
||||||
|
* <ruby>持久卷断言<rt>Persistent Volume Claim</rt></ruby>(PVC)
|
||||||
|
* <ruby>配置映射<rt>ConfigMap</rt></ruby>
|
||||||
|
|
||||||
|
Kubernetes 通过 `request` 和 `limit` 两个参数对 CPU 和内存进行限制(参考 [LimitRange][4] 文档)。前者表示容器最小被保证资源,后者表示容器最大可用资源。实际上最大可用资源还受限于其它容器的实际使用情况。
|
||||||
|
|
||||||
|
下一张图片解释了配额中 `request` 和 `limit` 的区别:
|
||||||
|
|
||||||
|
![Requests and limits in Kubernetes resource quotas][5]
|
||||||
|
|
||||||
|
下面我们就通过一个例子来说明如何设置资源配额来创建约束,将应用程序限制在某些资源上,它还展示了实现资源配额以获得对 Kubernetes 的控制的有用性。
|
||||||
|
|
||||||
|
### 准备环境
|
||||||
|
|
||||||
|
首先你需要一个 Kubernetes 环境。以下是我使用 Kubernetes 环境:
|
||||||
|
|
||||||
|
* [Minikube][7] v1.14.2
|
||||||
|
* Fedora 33 操作系统
|
||||||
|
* 互联网接入
|
||||||
|
|
||||||
|
如果你想在 Linux 机器上通过 Minikube 搭建 Kubernetes 测试环境,可以参考 Bryant Son 的《[Minikube 入门][7]》 一文。Window 或者 macOS 用户可以参考[这篇文章][8]。
|
||||||
|
|
||||||
|
### 设置资源配额
|
||||||
|
|
||||||
|
这里我们仅展示 CPU 配额设置步骤,配置内存配额或两者的组合与之类似。
|
||||||
|
|
||||||
|
在生产环境中,CPU 是最需要被控制的资源,尤其是在多应用的场景下特别需要注意防止某些应用消耗太多 CPU 而影响到其它应用。
|
||||||
|
|
||||||
|
首先我们创建一个命名空间,在其中设置 CPU 配额:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create namespace quota-test
|
||||||
|
namespace/quota-test created
|
||||||
|
```
|
||||||
|
|
||||||
|
准备 `cpu-quota.yaml` 文件,内容如下:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ResourceQuota
|
||||||
|
metadata:
|
||||||
|
name: test-cpu-quota
|
||||||
|
spec:
|
||||||
|
hard:
|
||||||
|
requests.cpu: "100m"
|
||||||
|
limits.cpu: "200m"
|
||||||
|
```
|
||||||
|
|
||||||
|
应用 CPU 配额到 Kubernetes 集群:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl apply -f cpu-qouta.yaml
|
||||||
|
resourcequota/test-cpu-quota created
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `kubectl describe` 检查配额配置情况:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
|
||||||
|
Name: test-cpu-quota
|
||||||
|
Namespace: quota-test
|
||||||
|
Resource Used Hard
|
||||||
|
-------- ---- ----
|
||||||
|
limits.cpu 0 200m
|
||||||
|
requests.cpu 0 100m
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `Used resources` 列中显示了当前情况,该列值会随着<ruby>吊舱<rt>Pod</rt></ruby>的部署而变化。
|
||||||
|
|
||||||
|
下面是我们来验证限额管理的场景。我们将在同一命名空间下部署三个不同的吊舱,为它们配置以不同的资源限制如下:
|
||||||
|
|
||||||
|
* PodA:第一个被实例化,使用 50% 可用 CPU 资源
|
||||||
|
* PodB:第二个被实例化,使用其余 50% 可用 CPU 资源
|
||||||
|
* PodC:没有可用 CPU 资源,因此不会被部署
|
||||||
|
|
||||||
|
#### 部署吊舱
|
||||||
|
|
||||||
|
PodA:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create -n quota-test -f - << EOF
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: poda
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: quota-test
|
||||||
|
image: busybox
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "50m"
|
||||||
|
limits:
|
||||||
|
cpu: "100m"
|
||||||
|
restartPolicy: Never
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
部署 PodA 后,再次查看配额描述信息中的 `Used CPU` 信息:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
|
||||||
|
Name: test-cpu-quota
|
||||||
|
Namespace: quota-test
|
||||||
|
Resource Used Hard
|
||||||
|
-------- ---- ----
|
||||||
|
limits.cpu 100m 200m
|
||||||
|
requests.cpu 50m 100m
|
||||||
|
```
|
||||||
|
|
||||||
|
PodB:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create -n quota-test -f - << EOF
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: podb
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: quota-test
|
||||||
|
image: busybox
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "50m"
|
||||||
|
limits:
|
||||||
|
cpu: "100m"
|
||||||
|
restartPolicy: Never
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
再次查看 CPU 资源使用,此时 PodB 启动后 CPU 限制已经达到上限:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
|
||||||
|
Name: test-cpu-quota
|
||||||
|
Namespace: quota-test
|
||||||
|
Resource Used Hard
|
||||||
|
-------- ---- ----
|
||||||
|
limits.cpu 200m 200m
|
||||||
|
requests.cpu 100m 100m
|
||||||
|
```
|
||||||
|
|
||||||
|
PodC:
|
||||||
|
|
||||||
|
试着创建 PodC,此时 CPU 配额已经被 PodA 和 PodB 用尽:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl create -n quota-test -f - << EOF
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: podc
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: quota-test
|
||||||
|
image: busybox
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "5m"
|
||||||
|
limits:
|
||||||
|
cpu: "10m"
|
||||||
|
restartPolicy: Never
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
正我们期望,第三个 Pod 无法被启动,配额限制了吊舱的创建:
|
||||||
|
|
||||||
|
```
|
||||||
|
Error from server (Forbidden): error when creating "STDIN": pods "podc" is forbidden: exceeded quota: test-cpu-quota, requested: limits.cpu=10m,requests.cpu=5m, used: limits.cpu=200m,requests.cpu=100m, limited: limits.cpu=200m,requests.cpu=100m
|
||||||
|
```
|
||||||
|
|
||||||
|
如我们的例子所示,定义合理的资源配额限制开发者行为对 Kubernetes 管理十分重要。
|
||||||
|
|
||||||
|
### 清理
|
||||||
|
|
||||||
|
删除刚才创建的命名空间 `quota-test`:
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl delete -n quota-test
|
||||||
|
```
|
||||||
|
|
||||||
|
### 规划资源配额
|
||||||
|
|
||||||
|
Kubernetes 中提供多种方式来控制资源的抢占和使用,合理的规划和配置配额、限制范围和其它原生参数对保持集群的稳定性十分必要。
|
||||||
|
|
||||||
|
你应该十分谨慎地控制计算资源的资源配额,特别是关键业务的生产应用环境。
|
||||||
|
|
||||||
|
在规划资源配额时,开发人员的参与很重要,需要他们预估并给出最合理的资源使用值。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/12/kubernetes-resource-quotas
|
||||||
|
|
||||||
|
作者:[Mike Calizo][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[larryzju](https://github.com/larryzju)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/mcalizo
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_secret_ingredient_520x292.png?itok=QbKzJq-N "Jars with food inside on a shelf"
|
||||||
|
[2]: https://kubernetes.io/
|
||||||
|
[3]: https://kubernetes.io/docs/concepts/policy/resource-quotas
|
||||||
|
[4]: https://kubernetes.io/docs/concepts/policy/limit-range/
|
||||||
|
[5]: https://opensource.com/sites/default/files/uploads/resourcequota_requests-limits.png "Requests and limits in Kubernetes resource quotas"
|
||||||
|
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[7]: https://opensource.com/article/18/10/getting-started-minikube
|
||||||
|
[8]: https://www.liquidweb.com/kb/how-to-install-minikube/
|
@ -0,0 +1,228 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (mengxinayan)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13069-1.html)
|
||||||
|
[#]: subject: (Understanding 52-bit virtual address support in the Arm64 kernel)
|
||||||
|
[#]: via: (https://opensource.com/article/20/12/52-bit-arm64-kernel)
|
||||||
|
[#]: author: (Bhupesh Sharma https://opensource.com/users/bhsharma)
|
||||||
|
|
||||||
|
理解 ARM64 内核中对 52 位虚拟地址的支持
|
||||||
|
======
|
||||||
|
|
||||||
|
> 随着 64 位硬件的引入,增加了处理更大地址空间的需求。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/30/170448rynbm9b6nmb90403.jpg)
|
||||||
|
|
||||||
|
当 64 位硬件变得可用之后,处理更大地址空间(大于 2^32 字节)的需求变得显而易见。现如今一些公司已经提供 64TiB 或更大内存的服务器,x86_64 架构和 arm64 架构现在允许寻址的地址空间大于 2^48 字节(可以使用默认的 48 位地址支持)。
|
||||||
|
|
||||||
|
x86_64 架构通过让硬件和软件启用五级页表以支持这些用例。它允许寻址的地址空间等于 2^57 字节(详情见 [x86:在 4.12 内核中启用 5 级页表][2])。它突破了过去虚拟地址空间 128PiB 和物理地址空间 4PiB 的上限。
|
||||||
|
|
||||||
|
arm64 架构通过引入两个新的体系结构 —— ARMv8.2 LVA(更大的虚拟寻址) 和 ARMv8.2 LPA(更大的物理地址寻址) —— 拓展来实现相同的功能。这允许使用 4PiB 的虚拟地址空间和 4PiB 的物理地址空间(即分别为 2^52 位)。
|
||||||
|
|
||||||
|
随着新的 arm64 CPU 中支持了 ARMv8.2 体系结构拓展,同时现在开源软件也支持了这两种新的硬件拓展。
|
||||||
|
|
||||||
|
从 Linux 5.4 内核开始, arm64 架构中的 52 位(大)虚拟地址(VA)和物理地址(PA)得到支持。尽管[内核文档][3]描述了这些特性和新的内核运行时对旧的 CPU(硬件层面不支持 52 位虚拟地址拓展)和新的 CPU(硬件层面支持 52 位虚拟地址拓展)的影响,但对普通用户而言,理解这些并且如何 “选择使用” 52 位的地址空间可能会很复杂。
|
||||||
|
|
||||||
|
因此,我会在本文中介绍下面这些比较新的概念:
|
||||||
|
|
||||||
|
1. 在增加了对这些功能的支持后,内核的内存布局如何“翻转”到 Arm64 架构
|
||||||
|
2. 对用户态应用的影响,尤其是对提供调试支持的程序(例如:kexec-tools、 makedumpfile 和 crash-utility)
|
||||||
|
3. 如何通过指定大于 48 位的 mmap 参数,使用户态应用“选择”从 52 位地址空间接受 VA?
|
||||||
|
|
||||||
|
### ARMv8.2 架构的 LVA 和 LPA 拓展
|
||||||
|
|
||||||
|
ARMv8.2 架构提供两种重要的拓展:大虚拟寻址(LVA)和大物理寻址(LPA)。
|
||||||
|
|
||||||
|
当使用 64 KB 转换粒度时,ARMv8.2-LVA 为每个翻译表基地址寄存器提供了一个更大的 52 位虚拟地址空间。
|
||||||
|
|
||||||
|
在 ARMv8.2-LVA 中允许:
|
||||||
|
|
||||||
|
* 当使用 64 KB 转换粒度时,中间物理地址(IPA)和物理地址空间拓展为 52 位。
|
||||||
|
* 如果使用 64 KB 转换粒度来实现对 52 位物理地址的支持,那么一级块将会覆盖 4TB 的地址空间。
|
||||||
|
|
||||||
|
_需要注意的是这些特性仅在 AArch64 架构中支持。_
|
||||||
|
|
||||||
|
目前下列的 Arm64 Cortex-A 处理器支持 ARMv8.2 拓展:
|
||||||
|
|
||||||
|
* Cortex-A55
|
||||||
|
* Cortex-A75
|
||||||
|
* Cortex-A76
|
||||||
|
|
||||||
|
更多细节请参考 [Armv8 架构参考手册][4]。
|
||||||
|
|
||||||
|
### Arm64 的内核内存布局
|
||||||
|
|
||||||
|
伴随着 ARMv8.2 拓展增加了对 LVA 地址的支持(仅当以页大小为 64 KB 运行时可用),在第一级转换中,描述符的数量会增加。
|
||||||
|
|
||||||
|
用户地址将 63-48 位位置为 0,然而内核地址将这些位设置为 1。TTBRx 的选择由虚拟地址的 63 位决定。`swapper_pg_dir` 仅包含内核(全局)映射,然而 `pgd` 仅包含用户(非全局)的映射。`swapper_pg_dir` 地址会写入 TTBR1,且永远不会写入 TTBR0。
|
||||||
|
|
||||||
|
**页面大小为 64 KB 和三个级别的(具有 52 位硬件支持)的 AArch64 架构下 Linux 内存布局如下:**
|
||||||
|
|
||||||
|
```
|
||||||
|
开始 结束 大小 用途
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
0000000000000000 000fffffffffffff 4PB 用户
|
||||||
|
fff0000000000000 fff7ffffffffffff 2PB 内核逻辑内存映射
|
||||||
|
fff8000000000000 fffd9fffffffffff 1440TB [间隙]
|
||||||
|
fffda00000000000 ffff9fffffffffff 512TB Kasan 阴影区
|
||||||
|
ffffa00000000000 ffffa00007ffffff 128MB bpf jit 区域
|
||||||
|
ffffa00008000000 ffffa0000fffffff 128MB 模块
|
||||||
|
ffffa00010000000 fffff81ffffeffff ~88TB vmalloc 区
|
||||||
|
fffff81fffff0000 fffffc1ffe58ffff ~3TB [保护区域]
|
||||||
|
fffffc1ffe590000 fffffc1ffe9fffff 4544KB 固定映射
|
||||||
|
fffffc1ffea00000 fffffc1ffebfffff 2MB [保护区域]
|
||||||
|
fffffc1ffec00000 fffffc1fffbfffff 16MB PCI I/O 空间
|
||||||
|
fffffc1fffc00000 fffffc1fffdfffff 2MB [保护区域]
|
||||||
|
fffffc1fffe00000 ffffffffffdfffff 3968GB vmemmap
|
||||||
|
ffffffffffe00000 ffffffffffffffff 2MB [保护区域]
|
||||||
|
```
|
||||||
|
|
||||||
|
**4 KB 页面的转换查询表如下:**
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
|
||||||
|
+--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
| | | | | |
|
||||||
|
| | | | | v
|
||||||
|
| | | | | [11:0] 页内偏移量
|
||||||
|
| | | | +-> [20:12] L3 索引
|
||||||
|
| | | +-----------> [29:21] L2 索引
|
||||||
|
| | +---------------------> [38:30] L1 索引
|
||||||
|
| +-------------------------------> [47:39] L0 索引
|
||||||
|
+-------------------------------------------------> [63] TTBR0/1
|
||||||
|
```
|
||||||
|
|
||||||
|
**64 KB 页面的转换查询表如下:**
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
|
||||||
|
+--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
| | | | |
|
||||||
|
| | | | v
|
||||||
|
| | | | [15:0] 页内偏移量
|
||||||
|
| | | +----------> [28:16] L3 索引
|
||||||
|
| | +--------------------------> [41:29] L2 索引
|
||||||
|
| +-------------------------------> [47:42] L1 索引 (48 位)
|
||||||
|
| [51:42] L1 索引 (52 位)
|
||||||
|
+-------------------------------------------------> [63] TTBR0/1
|
||||||
|
```
|
||||||
|
|
||||||
|
![][5]
|
||||||
|
|
||||||
|
### 内核对 52 位虚拟地址的支持
|
||||||
|
|
||||||
|
因为支持 LVA 的较新的内核应该可以在旧的 CPU(硬件不支持 LVA 拓展)和新的 CPU(硬件支持 LVA 拓展)上都正常运行,因此采用的设计方法是使用单个二进制文件来支持 52 位(如果硬件不支持该特性,则必须在刚开始启动时能回退到 48 位)。也就是说,为了满足 52 位的虚拟地址以及固定大小的 `PAGE_OFFSET`,`VMEMMAP` 必须设置得足够大。
|
||||||
|
|
||||||
|
这样的设计方式要求内核为了新的虚拟地址空间而支持下面的变量:
|
||||||
|
|
||||||
|
```
|
||||||
|
VA_BITS 常量 *最大的* 虚拟地址空间大小
|
||||||
|
|
||||||
|
vabits_actual 变量 *实际的* 虚拟地址空间大小
|
||||||
|
```
|
||||||
|
|
||||||
|
因此,尽管 `VA_BITS` 设置了最大的虚拟地址空间大小,但实际上支持的虚拟地址空间大小由 `vabits_actual` 确定(具体取决于启动时的切换)。
|
||||||
|
|
||||||
|
#### 翻转内核内存布局
|
||||||
|
|
||||||
|
保持一个单一内核二进制文件的设计方法要求内核的 `.text` 位于高位地址中,因此它们对于 48/52 位虚拟地址是不变的。因为内核地址检测器(KASAN)区域仅占整个内核虚拟地址空间的一小部分,因此对于 48 位或 52 位的虚拟地址空间,KASAN 区域的末尾也必须在内核虚拟地址空间的上半部分。(从 48 位切换到 52 位,KASAN 区域的末尾是不变的,且依赖于 `~0UL`,而起始地址将“增长”到低位地址)
|
||||||
|
|
||||||
|
为了优化 `phys_to_virt()` 和 `virt_to_phys()`,页偏移量将被保持在 `0xFFF0000000000000` (对应于 52 位),这消除了读取额外变量的需求。在早期启动时将会计算 `physvirt` 和 `vmemmap` 偏移量以启用这个逻辑。
|
||||||
|
|
||||||
|
考虑下面的物理和虚拟 RAM 地址空间的转换:
|
||||||
|
|
||||||
|
```
|
||||||
|
/*
|
||||||
|
* 内核线性地址开始于虚拟地址空间的底部
|
||||||
|
* 测试区域开始处的最高位已经是一个足够的检查,并且避免了担心标签的麻烦
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define virt_to_phys(addr) ({ \
|
||||||
|
if (!(((u64)addr) & BIT(vabits_actual - 1))) \
|
||||||
|
(((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
|
||||||
|
})
|
||||||
|
|
||||||
|
#define phys_to_virt(addr) ((unsigned long)((addr) - PHYS_OFFSET) | PAGE_OFFSET)
|
||||||
|
|
||||||
|
在上面的代码中:
|
||||||
|
PAGE_OFFSET — 线性映射的虚拟地址的起始位置位于 TTBR1 地址空间
|
||||||
|
PHYS_OFFSET — 物理地址的起始位置以及 vabits_actual — *实际的*虚拟地址空间大小
|
||||||
|
```
|
||||||
|
|
||||||
|
### 对用于调试内核的用户态程序的影响
|
||||||
|
|
||||||
|
有几个用户空间应用程序可以用于调试正在运行的/活动中的内核或者分析系统崩溃时的 vmcore 转储(例如确定内核奔溃的根本原因):kexec-tools、makedumpfile 和 crash-utility。
|
||||||
|
|
||||||
|
当用它们来调试 Arm64 内核时,因为 Arm64 内核内存映射被“翻转”,因此也会对它们产生影响。这些应用程序还需要遍历转换表以确定与虚拟地址相应的物理地址(类似于内核中的完成方式)。
|
||||||
|
|
||||||
|
相应地,在将“翻转”引入内核内存映射之后,由于上游破坏了用户态应用程序,因此必须对其进行修改。
|
||||||
|
|
||||||
|
我已经提议了对三个受影响的用户态应用程序的修复;有一些已经被上游接受,但其他仍在等待中:
|
||||||
|
|
||||||
|
* [提议 makedumpfile 上游的修复][6]
|
||||||
|
* [提议 kexec-tools 上游的修复][7]
|
||||||
|
* [已接受的 crash-utility 的修复][8]
|
||||||
|
|
||||||
|
除非在用户空间应用程序进行了这些修改,否则它们将仍然无法调试运行/活动中的内核或分析系统崩溃时的 vmcore 转储。
|
||||||
|
|
||||||
|
### 52 位用户态虚拟地址
|
||||||
|
|
||||||
|
为了保持与依赖 ARMv8.0 虚拟地址空间的最大为 48 位的用户空间应用程序的兼容性,在默认情况下内核会将虚拟地址从 48 位范围返回给用户空间。
|
||||||
|
|
||||||
|
通过指定大于 48 位的 mmap 提示参数,用户态程序可以“选择”从 52 位空间接收虚拟地址。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```
|
||||||
|
.mmap_high_addr.c
|
||||||
|
----
|
||||||
|
|
||||||
|
maybe_high_address = mmap(~0UL, size, prot, flags,...);
|
||||||
|
```
|
||||||
|
|
||||||
|
通过启用以下的内核配置选项,还可以构建一个从 52 位空间返回地址的调试内核:
|
||||||
|
|
||||||
|
```
|
||||||
|
CONFIG_EXPERT=y && CONFIG_ARM64_FORCE_52BIT=y
|
||||||
|
```
|
||||||
|
|
||||||
|
_请注意此选项仅用于调试应用程序,不应在实际生产中使用。_
|
||||||
|
|
||||||
|
### 结论
|
||||||
|
|
||||||
|
总结一下:
|
||||||
|
|
||||||
|
1. 内核版本从 5.14 开始,新的 Armv8.2 硬件拓展 LVA 和 LPA 在内核中得到良好支持。
|
||||||
|
2. 像 kexec-tools 和 makedumpfile 被用来调试内核的用户态应用程序现在无法支持新拓展,仍在等待上游接受修补。
|
||||||
|
3. 过去的用户态应用程序依赖于 Arm64 内核提供的 48 位虚拟地址将继续原样工作,而较新的用户态应用程序通构指定超过 48 位更大的 mmap 提示参数来 “选择加入”已接受来自 52 位的虚拟地址。
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
_这篇文章参考了 [AArch64 架构下的 Linux 内存布局][9] 和 [Linux 5.9.12 内核文档][10]。它们均为 GPLv2.0 许可。_
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/12/52-bit-arm64-kernel
|
||||||
|
|
||||||
|
作者:[Bhupesh Sharma][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/bhsharma
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/puzzle_computer_solve_fix_tool.png?itok=U0pH1uwj (Puzzle pieces coming together to form a computer screen)
|
||||||
|
[2]: https://lwn.net/Articles/716916/
|
||||||
|
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/memory.rst
|
||||||
|
[4]: https://developer.arm.com/documentation/ddi0487/latest/
|
||||||
|
[5]: https://opensource.com/sites/default/files/arm64-multi-level-translation_0.png (arm64 Multi-level Translation)
|
||||||
|
[6]: http://lists.infradead.org/pipermail/kexec/2020-September/021372.html
|
||||||
|
[7]: http://lists.infradead.org/pipermail/kexec/2020-September/021333.html
|
||||||
|
[8]: https://github.com/crash-utility/crash/commit/1c45cea02df7f947b4296c1dcaefa1024235ef10
|
||||||
|
[9]: https://www.kernel.org/doc/html/latest/arm64/memory.html
|
||||||
|
[10]: https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/asm/memory.h
|
@ -0,0 +1,122 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13009-1.html)
|
||||||
|
[#]: subject: (5 reasons to use the Atom text editor)
|
||||||
|
[#]: via: (https://opensource.com/article/20/12/atom)
|
||||||
|
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||||
|
|
||||||
|
使用 Atom 文本编辑器的 5 个理由
|
||||||
|
======
|
||||||
|
|
||||||
|
> Atom 是一个全面的环境,可以完成从基本到复杂的任务,适合从初学者到老用户。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/13/122223fnsn53dpzllwlclp.jpg)
|
||||||
|
|
||||||
|
现在漂亮的开源文本编辑器很常见,有 Adobe 的 [Brackets][2]、微软的 [VSCode][3] 和 GitHub 的 [Atom][4]。这些似乎都提供了类似的体验:现代化的界面、易于安装的插件,以及背后的一个大厂商支持。而且它们其实都很不错。那么 Atom 与其他超现代的文本编辑器有什么不同呢?与经典的老式编辑器如 [Vim][5] 或 [Emacs][6] 有何区别呢?
|
||||||
|
|
||||||
|
![Atom terminal with white text on dark grey background][7]
|
||||||
|
|
||||||
|
我用过很多文本编辑器,并且经过反思,我不得不承认,所有的文本编辑器基本上都差不多。在判断一个编辑器的功效时,只要它能做一件事:编辑文字,就能满足 80% 的要求。另外的 20% 则是额外的便利、额外的小玩意和花哨的功能。它们是很好的东西,但几乎不是必不可少的。
|
||||||
|
|
||||||
|
不过我经常回到 Atom,因为作为一个开源的用户,只要我愿意,我就可以奢侈地有很多应用使用。以下是我喜欢 Atom 的原因。
|
||||||
|
|
||||||
|
### 新手友好
|
||||||
|
|
||||||
|
我最喜欢 Atom 的一点是,它让人感觉很“正常”。我可以把 Atom 安装在任何人的电脑上,他们很快就可以开始输入了。没有新的键盘快捷键需要学习,没有严重偏离用户界面的惯例。如果我花几分钟时间向他们展示一些应用的强大功能,那么他们很快就会有能力安装新的插件,发现他们喜欢的有用功能。
|
||||||
|
|
||||||
|
它的独特之处在于让人感到与众不同,但又足够“安全”,足以让人相信(也确实如此)他们可以使用它。这是一条很难走的路线,但 Atom 做到了,我很欣赏它。
|
||||||
|
|
||||||
|
### 强大的扩展
|
||||||
|
|
||||||
|
当你启动应用就已经满足了大多数需求时,开源文本编辑器的一个主要“卖点”就是它的扩展。我习惯使用的编辑器是 [GNU Emacs][8],它的扩展功能多到令人瞠目结舌,可以提供从电子邮件客户端到视频游戏的所有功能。要做到这一点很难,老实说,我还没有看到其它能做到的编辑器。不过这说明了扩展是多么重要,而 Atom 有一套不错的插件。
|
||||||
|
|
||||||
|
有一些扩展可以为语言和格式添加语法高亮、添加动态格式检查、以及集成调试器、运行时环境、视频和音乐播放器控件等等。实际上,你可以让 Atom 成为你桌面的控制中心,你很少需要离开它。
|
||||||
|
|
||||||
|
### 语言和语法支持
|
||||||
|
|
||||||
|
我是 [Docbook][9] 的忠实粉丝。顺便说一下,也是它的简化前端 Asciidoc 的粉丝。当我评估一个编辑器时,Docbook 模式和 Asciidoc 支持是我的两个主要指标。虽然对 XML 的支持比较常见,但与特定模式的集成可能是一个高难度的任务,而且 Asciidoc 相对小众。Atom 的社区为我最喜欢的格式提供了很好的支持。
|
||||||
|
|
||||||
|
当然,我已经提到了 Atom 一般来说有很好的扩展,但无论你在输入什么语言,语法高亮都是一个重要的功能。再次感谢充满活力的社区,在 Atom 的软件包仓库中,丰富的语法高亮选项的是它的优点之一。
|
||||||
|
|
||||||
|
### 简单定制主题
|
||||||
|
|
||||||
|
Atom 让你制作自己的风格就像设计网站的风格一样简单,所以如果你会使用 CSS,你可以制作你自己的 Atom 主题。要创建你自己的主题,找到<ruby>软件包<rt>Package</rt></ruby>菜单。如果你没有看到<ruby>软件包<rt>Package</rt></ruby>菜单,先按 `Alt` 键,露出顶部菜单栏。在<ruby>软件包<rt>Package</rt></ruby>菜单中,将鼠标悬停在<ruby>软件包生成器<rt>Package Generator</rt></ruby> 上,然后选择<ruby>Generate Atom Syntax Theme<rt>生成 Atom 语法主题</rt></ruby>。这将打开一个新的项目,默认名为 “my-theme-syntax”。你可以把它命名为任何你想要的名字,但根据 Atom 惯例,它应该以 `-syntax` 结尾。
|
||||||
|
|
||||||
|
在你的新主题项目中,找到这些文件:`base.less`、`colors.less` 和 `syntax-variables.less`。这些文件定义了当语法激活时,特殊的关键字,甚至是背景和前景的颜色是如何显示的。因为它们都是从一个通用模板中继承的值,所以很容易修改。比如说:
|
||||||
|
|
||||||
|
```
|
||||||
|
// Syntax styles
|
||||||
|
|
||||||
|
.syntax--comment {
|
||||||
|
color: @light-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.syntax--keyword {
|
||||||
|
color: @purple;
|
||||||
|
|
||||||
|
&.syntax--control {
|
||||||
|
color: @purple;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.syntax--operator {
|
||||||
|
color: @syntax-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.syntax--other.syntax--special-method {
|
||||||
|
color: @blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.syntax--other.syntax--unit {
|
||||||
|
color: @orange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
以两个破折号结尾的值,如 `.syntax--keyword`,是语法高亮引擎识别的对象。当然,如果你想进一步开发你的自定义设置,你甚至可以创建你自己的语法定义(尽管这比 CSS 主题更费劲)。在 [flight-manual.atom.io][10] 上可以阅读所有关于修改 Atom 的方法。
|
||||||
|
|
||||||
|
### 灵活的工作流
|
||||||
|
|
||||||
|
Atom 有很多功能,默认情况下仅激活其中一部分。这意味着你可以决定你喜欢的工作方式,是否激活新的扩展并使用它们从根本上改变 Atom,还是只打开 Atom 的偏好并进行小的调整。你可以用 Atom 来写一本小说,也可以用它来写 Python 代码或技术文档或其他任何东西。
|
||||||
|
|
||||||
|
即使是它的 Git 集成也没有坚持让你使用可能会想到的显而易见的仓库(Github 赞助了 Atom)。它没有任何限制,而且它对每个人都同样有用,不管受众是谁。
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
在 Linux、Windows 和 macOS 上,你可以 [从它的网站安装 Atom][11]。
|
||||||
|
|
||||||
|
另外,在 Linux 上,你可以从 [Flathub][12] 中,以 Flatpak 安装 Atom。
|
||||||
|
|
||||||
|
如果你想自己构建 Atom,你也可以 [从 Github 上的源码编译它][13]。
|
||||||
|
|
||||||
|
### 尝试 Atom
|
||||||
|
|
||||||
|
Atom 可以成为你的下一个文本编辑器、记事本和 IDE。它易于使用、易于配置、易于扩展,并提供了良好的用户体验。今天就下载 Atom,试试吧。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/12/atom
|
||||||
|
|
||||||
|
作者:[Seth Kenlon][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[geekpi](https://github.com/geekpi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/seth
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/science_experiment_beaker_lab.png?itok=plKWRhlU (Science lab with beakers)
|
||||||
|
[2]: https://opensource.com/article/20/12/brackets
|
||||||
|
[3]: https://opensource.com/article/20/12/%C2%A0https://opensource.com/article/20/6/open-source-alternatives-vs-code
|
||||||
|
[4]: https://opensource.com/article/17/5/atom-text-editor-packages-writers
|
||||||
|
[5]: https://opensource.com/article/20/12/vi-text-editor
|
||||||
|
[6]: https://opensource.com/article/20/12/emacs
|
||||||
|
[7]: https://opensource.com/sites/default/files/uploads/atom-31_days-atom-opensource.png (Atom terminal with white text on dark grey background)
|
||||||
|
[8]: https://opensource.com/article/20/2/who-cares-about-emacs
|
||||||
|
[9]: https://opensource.com/article/17/9/docbook
|
||||||
|
[10]: https://flight-manual.atom.io/
|
||||||
|
[11]: https://atom.io
|
||||||
|
[12]: https://flathub.org/apps/details/io.atom.Atom
|
||||||
|
[13]: https://github.com/atom
|
148
published/202101/20201230 Choose between Btrfs and LVM-ext4.md
Normal file
148
published/202101/20201230 Choose between Btrfs and LVM-ext4.md
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13043-1.html)
|
||||||
|
[#]: subject: (Choose between Btrfs and LVM-ext4)
|
||||||
|
[#]: via: (https://fedoramagazine.org/choose-between-btrfs-and-lvm-ext4/)
|
||||||
|
[#]: author: (Troy Curtis Jr https://fedoramagazine.org/author/troycurtisjr/)
|
||||||
|
|
||||||
|
Btrfs 和 LVM-ext4 该如何选择?
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/23/133137m2wfkiq8ykyvwyhv.jpg)
|
||||||
|
|
||||||
|
[Fedora 33][4] 在其各类桌面版本中引入了新的默认文件系统 [Btrfs][5]。多年以来,Fedora 一直在 <ruby>[逻辑卷管理][7]<rt>Logical Volume Manager</rt></ruby>(LVM) 卷之上使用 [ext4][6],引入 Brtfs 对 Fedora 来说是一个很大的转变。更改默认文件系统需要 [令人信服的原因][8]。虽然 Btrfs 是令人兴奋的下一代文件系统,但 LVM 上的 ext4 是成熟而稳定的。本指南旨在探索各自的高级特性,使得更容易在 Btrfs 和 LVM-ext4 之间进行选择。
|
||||||
|
|
||||||
|
### 先说结论
|
||||||
|
|
||||||
|
最简单的建议是坚持使用默认值。全新安装的 Fedora 33 环境默认为 Btrfs,升级之前的 Fedora 版本将继续使用最初安装的设置,通常是 LVM-ext4。对于现有的 Fedora 用户来说,获取 Btrfs 的最简单方式是全新安装。然而,全新安装比简单升级更具破坏性。除非有特殊需要,否则这种干扰可能是不必要的。Fedora 开发团队仔细考虑了这两个默认值,因此对任何一个选择都要有信心。
|
||||||
|
|
||||||
|
### 那么其他文件系统呢?
|
||||||
|
|
||||||
|
现在有很多 [Linux 系统的文件系统][9]。在加上卷管理器、加密方法和存储机制的组合后,这一数字呈爆炸式增长。那么,为什么要关注 btrfs 和 LVM-ext4 呢?对于 Fedora 的用户来说,这两种设置可能是最常见的。在 Fedora 11 中,LVM 之上的 ext4 成为了默认磁盘布局,在此之前则使用的是 ext3。
|
||||||
|
|
||||||
|
既然 Btrfs 是 Fedora 33 的默认设置,那么绝大多数现有用户会考虑是应该原地踏步还是向前跳跃。面对全新安装的 Fedora 33 环境,有经验的 Linux 用户可能会想知道是使用这个新的文件系统,还是退回到他们熟悉的文件系统。因此,在众多可能的存储选项中,许多 Fedora 用户会想知道如何在 Btrfs 和 LVM-ext4 之间进行选择。
|
||||||
|
|
||||||
|
### 两者的共性
|
||||||
|
|
||||||
|
尽管两个文件系统之间存在核心差异,但 Btrfs 和 LVM-ext4 实际上有很多共同之处。两者都是成熟且经过充分测试的存储技术。从 Fedora Core 的早期开始,就一直在使用 LVM,而 ext4 在 [2009 年成为 Fedora 11 的默认设置][10]。Btrfs 在 2009 年并入 Linux 主线内核,并且 [Facebook 广泛使用了该文件系统][11]。SUSE Linux Enterprise 12 [在 2014 年使其成为默认文件系统][12]。因此,它在生产环境中也有着长久的运行时间。
|
||||||
|
|
||||||
|
这两个系统都能很好地防止因意外停电而导致的文件系统损坏,尽管它们的实现方式不同。它们支持的配置包括使用单盘设置和跨越多个设备,并且这两种配置都能够创建近乎即时的快照。有各种工具可以帮助管理这两种系统,包括命令行和图形界面。这两种解决方案在家用台式机和高端服务器上都同样有效。
|
||||||
|
|
||||||
|
### LVM-ext4 的优势
|
||||||
|
|
||||||
|
![LVM 上 ext4 的结构][13]
|
||||||
|
|
||||||
|
[ext4 文件系统][14] 专注于高性能和可伸缩性,没有太多额外的花哨之处。它能有效地防止长时间后的碎片化,并当碎片化出现后提供了 [很好的工具][15]。ext4 之所以坚如磐石,是因为它构建在前代的 ext3 文件系统之上,带来了多年的系统内测试和错误修复。
|
||||||
|
|
||||||
|
LVM-ext4 环境中的大多数高级功能都来自 LVM 本身。LVM 位于文件系统的“下方”,这意味着它支持任何文件系统。<ruby>逻辑卷<rt>Logical volume</rt></ruby>(LV)是通用的块设备,因此 [虚拟机可以直接使用它们][16]。这种灵活性使得每个逻辑卷都可以使用合适的文件系统,用合适的选项应对各种情况。这种分层方法还遵循了“小工具协同工作”的 Unix 哲学。
|
||||||
|
|
||||||
|
从硬件抽象出来的<ruby>[卷组][17]<rt>volume group</rt></ruby>(VG)允许 LVM 创建灵活的逻辑卷。每个逻辑卷都提取自同一个存储池,但具有自己的设置。调整卷的大小比调整物理分区的大小容易得多,因为没有数据有序放置的限制。LVM <ruby>[物理卷][18]<rt>physical volume</rt></ruby>(PV)可以是任意数量的分区,甚至可以在系统运行时在设备之间移动。
|
||||||
|
|
||||||
|
LVM 支持只读和读写的 [快照][19],这使得从活动系统创建一致的备份变得很容易。每个快照都有一个定义的大小,更改源卷或快照卷将占用其中的空间。又或者,逻辑卷也可以是<ruby>[稀疏配置池][20]<rt>thinly provisioned pool</rt></ruby>的一部分。这允许快照自动使用池中的数据,而不是使用在创建卷时定义的固定大小的块。
|
||||||
|
|
||||||
|
#### 有多个磁盘驱动器的 LVM
|
||||||
|
|
||||||
|
当有多个设备时,LVM 才真正大放异彩。它原生支持大多数 [RAID 级别][21],每个逻辑卷可以具有不同的 RAID 级别。LVM 将自动为 RAID 配置选择适当的物理设备,或者用户可以直接指定它。基本的 RAID 支持包括用于性能的数据条带化([RAID0][22])和用于冗余的镜像([RAID1][23])。逻辑卷也可以使用 [RAID5][24]、[RAID6][25] 和 [RAID10][26] 等高级设置。LVM RAID 支持已经成熟,因为 LVM 在底层使用的 [设备映射器(dm)][27] 和 [多设备(md)][28] 内核支持, 与 [mdadm][29] 使用的一样。
|
||||||
|
|
||||||
|
对于具有快速和慢速驱动器的系统,逻辑卷也可以是 [缓存卷][30]。经典示例是 SSD 和传统磁盘驱动器的组合。缓存卷使用较快的驱动器来存储更频繁访问的数据(或用作写缓存),而慢速的驱动器则用于处理大量数据。
|
||||||
|
|
||||||
|
LVM 中大量稳定的功能以及 ext4 的可靠性在既往的使用中早已被证明了。当然,功能越多就越复杂。在配置 LVM 时,要找到合适的功能选项是很有挑战性的。对于单驱动器的台式机系统,LVM 的功能(例如 RAID 和缓存卷)不适用。但是,逻辑卷比物理分区更灵活,快照也很有用。对于正常的桌面使用,LVM 的复杂性会成为典型的用户可能遇到的问题恢复的障碍。
|
||||||
|
|
||||||
|
### Btrfs 的优势
|
||||||
|
|
||||||
|
![Btrfs 结构][31]
|
||||||
|
|
||||||
|
从前几代文件系统中学到的经验指导了构建到 [Btrfs][5] 的功能设计。与 ext4 不同,它可以直接跨越多个设备,因此它具有通常仅在卷管理器中才能找到的功能。它还具有 Linux 文件系统空间中独有的功能([ZFS][32] 具有相似的功能集,但[不要指望它在 Linux 内核中出现][33])。
|
||||||
|
|
||||||
|
#### Btrfs 的主要功能
|
||||||
|
|
||||||
|
也许最重要的功能是对所有数据进行<ruby>校验和<rt>checksumming</rt></ruby>。校验和与<ruby>[写时复制][37]<rt>copy-on-write</rt></ruby>(COW)一起,提供了在意外断电后确保文件系统完整性的 [关键方法][34]。更独特的是,校验和可以检测数据本身中的错误。悄然的数据损坏(有时也称为 [bitrot][35])比大多数人意识到的更常见。如果没有主动验证,损坏最终可能会传播到所有可用的备份中。这使得用户没有有效的副本。通过透明地校验所有数据,Btrfs 能够立即检测到任何此类损坏。启用正确的 [dup 或 raid 选项][36],文件系统也可以透明地修复损坏。
|
||||||
|
|
||||||
|
写时复制也是 Btrfs 的基本功能,因为它在提供文件系统完整性和即时子卷快照方面至关重要。从公共子卷创建快照后,快照会自动共享底层数据。另外,事后的<ruby>[重复数据删除][38]<rt>deduplication</rt></ruby> 使用相同的技术来消除相同的数据块。单个文件可以通过使用 `cp` 的 [reflink 选项][39] 来使用 COW 功能。reflink 副本对于复制大型文件(例如虚拟机镜像)特别有用,这些文件往往随着时间的推移具有大部分相同的数据。
|
||||||
|
|
||||||
|
Btrfs 支持跨越多个设备,而无需卷管理器。多设备支持可提供数据镜像功能以实现冗余和条带化以提高性能。此外,还实验性地支持更高级的 RAID 级别,例如 [RAID 5][24] 和 [RAID 6][25]。与标准 RAID 设置不同,Btrfs 的 RAID1 实际上允许奇数个设备。例如,它可以使用 3 个设备,即使它们的大小不同。
|
||||||
|
|
||||||
|
所有 RAID 和 dup 选项都是在文件系统级别指定的。因此,各个子卷不能使用不同的选项。请注意,使用多设备的 RAID1 选项意味着即使一个设备发生故障,卷中的所有数据都是可用的,并且校验功能可以保持数据本身的完整性。这超出了当前典型的 RAID 设置所能提供的范围。
|
||||||
|
|
||||||
|
#### 附加功能
|
||||||
|
|
||||||
|
Btrfs 还支持快速简便的远程备份。子卷快照可以 [发送到远程系统][40] 进行存储。通过利用文件系统中固有的 COW 元数据,这些传输通过仅发送先前发送的快照中的增量更改而非常有效。诸如 [snapper][41] 之类的用户应用程序使管理这些快照变得容易。
|
||||||
|
|
||||||
|
另外,Btrfs 卷可以具有 [透明压缩][42] 功能,并且 [chattr +c][43] 可以标记进行压缩的单个文件或目录。压缩不仅可以减少数据消耗的空间,还可以通过减少写入操作量来帮助延长 SSD 的寿命。压缩当然会带来额外的 CPU 开销,但是有很多选项就可以权衡取舍。
|
||||||
|
|
||||||
|
Btrfs 集成了文件系统和卷管理器功能,这意味着总体维护比 LVM-ext4 更简单。当然,这种集成的灵活性较低,但是对于大多数台式机甚至服务器而言,设置已足够。
|
||||||
|
|
||||||
|
### LVM 上使用 Btrfs
|
||||||
|
|
||||||
|
Btrfs 可以 [就地转换 ext3/ext4 文件系统][44]。就地转换意味着无需将数据复制出来然后再复制回去。数据块本身甚至都不需要修改。因此,对于现有的 LVM-ext4 系统,一种选择是将 LVM 保留在原处,然后简单地将 ext4 转换为 Btrfs。虽然可行且受支持,但有一些原因使它不是最佳选择。
|
||||||
|
|
||||||
|
Btrfs 的吸引力之一是与卷管理器集成的文件系统所带来的更轻松的管理。要是在 LVM 之上运行,对于系统维护,仍然要对额外的卷管理器进行一些设置。同样,LVM 设置通常具有多个固定大小的逻辑卷,并具有独立文件系统。虽然 Btrfs 支持给定的计算机上的多个卷,但是许多不错的功能都需要单一卷具有多个子卷。如果每个 LVM 卷都有一个独立的 Btrfs 卷,则用户仍然需要手动管理固定大小的 LVM 卷。虽然能够收缩挂载的 Btrfs 文件系统的能力确实使处理固定大小的卷的工作变得更轻松。通过在线收缩功能,就无需启动 [实时镜像][45] 了。
|
||||||
|
|
||||||
|
在使用 Btrfs 的多设备支持时,必须仔细考虑逻辑卷的物理位置。对于 Btrfs 而言,每个逻辑卷都是一个单独的物理设备,如果实际情况并非如此,则某些数据可用性功能可能会做出错误的决定。例如,如果单个驱动器发生故障,对数据使用 RAID1 通常可以提供保护。如果实际逻辑卷在同一物理设备上,则没有冗余。
|
||||||
|
|
||||||
|
如果强烈需要某些特定的 LVM 功能,例如原始块设备或高速缓存的逻辑卷,则在 LVM 之上运行 Btrfs 是有意义的。在这种配置下,Btrfs 仍然提供其大多数优点,例如校验和和易于发送的增量快照。尽管使用 LVM 会产生一些操作开销,但 Btrfs 的这种开销并不比任何其他文件系统大。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
当尝试在 Btrfs 和 LVM-ext4 之间进行选择时,没有一个正确的答案。每个用户都有独特的要求,并且同一用户可能拥有具有不同需求的不同系统。看一下每个配置的功能集,并确定是否有令人心动的功能。如果没有,坚持默认值没有错。选择这两种设置都有很好的理由。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/choose-between-btrfs-and-lvm-ext4/
|
||||||
|
|
||||||
|
作者:[Troy Curtis Jr][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://fedoramagazine.org/author/troycurtisjr/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://fedoramagazine.org/wp-content/uploads/2020/12/btrfs-lvm-ext4-816x345.jpg
|
||||||
|
[2]: https://unsplash.com/@raulpetri?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||||
|
[3]: https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||||
|
[4]: https://fedoramagazine.org/announcing-fedora-33/
|
||||||
|
[5]: https://btrfs.wiki.kernel.org/index.php/Main_Page
|
||||||
|
[6]: https://ext4.wiki.kernel.org/index.php/Main_Page
|
||||||
|
[7]: https://man7.org/linux/man-pages/man8/lvm.8.html
|
||||||
|
[8]: https://fedoraproject.org/wiki/Changes/BtrfsByDefault
|
||||||
|
[9]: https://man7.org/linux/man-pages/man5/filesystems.5.html
|
||||||
|
[10]: https://docs.fedoraproject.org/en-US/Fedora/11/html/Release_Notes/index.html#sect-Release_Notes-Fedora_11_Overview
|
||||||
|
[11]: https://facebookmicrosites.github.io/btrfs/docs/btrfs-facebook.html
|
||||||
|
[12]: https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12/#fate-317221
|
||||||
|
[13]: https://fedoramagazine.org/wp-content/uploads/2020/12/ext4-on-LVM.jpg
|
||||||
|
[14]: https://opensource.com/article/18/4/ext4-filesystem
|
||||||
|
[15]: https://man7.org/linux/man-pages/man8/e4defrag.8.html
|
||||||
|
[16]: https://libvirt.org/storage.html#StorageBackendLogical
|
||||||
|
[17]: https://www.redhat.com/sysadmin/create-volume-group
|
||||||
|
[18]: https://www.redhat.com/sysadmin/create-physical-volume
|
||||||
|
[19]: https://tldp.org/HOWTO/LVM-HOWTO/snapshotintro.html
|
||||||
|
[20]: https://man7.org/linux/man-pages/man7/lvmthin.7.html
|
||||||
|
[21]: https://rhea.dev/articles/2018-08/LVM-RAID-on-Fedora
|
||||||
|
[22]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_0
|
||||||
|
[23]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1
|
||||||
|
[24]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_5
|
||||||
|
[25]: https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_6
|
||||||
|
[26]: https://en.wikipedia.org/wiki/Non-standard_RAID_levels#Linux_MD_RAID_10
|
||||||
|
[27]: https://man7.org/linux/man-pages/man8/dmsetup.8.html
|
||||||
|
[28]: https://man7.org/linux/man-pages/man4/md.4.html
|
||||||
|
[29]: https://fedoramagazine.org/managing-raid-arrays-with-mdadm/
|
||||||
|
[30]: https://man7.org/linux/man-pages/man7/lvmcache.7.html
|
||||||
|
[31]: https://fedoramagazine.org/wp-content/uploads/2020/12/Btrfs-Volume.jpg
|
||||||
|
[32]: https://en.wikipedia.org/wiki/ZFS
|
||||||
|
[33]: https://itsfoss.com/linus-torvalds-zfs/
|
||||||
|
[34]: https://btrfs.wiki.kernel.org/index.php/FAQ#Can_I_have_nodatacow_.28or_chattr_.2BC.29_but_still_have_checksumming.3F
|
||||||
|
[35]: https://arstechnica.com/information-technology/2014/01/bitrot-and-atomic-cows-inside-next-gen-filesystems/
|
||||||
|
[36]: https://man7.org/linux/man-pages/man8/mkfs.btrfs.8.html#DUP_PROFILES_ON_A_SINGLE_DEVICE
|
||||||
|
[37]: https://en.wikipedia.org/wiki/Copy-on-write
|
||||||
|
[38]: https://btrfs.wiki.kernel.org/index.php/Deduplication
|
||||||
|
[39]: https://btrfs.wiki.kernel.org/index.php/UseCases#How_do_I_copy_a_large_file_and_utilize_COW_to_keep_it_from_actually_being_copied.3F
|
||||||
|
[40]: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/
|
||||||
|
[41]: http://snapper.io/
|
||||||
|
[42]: https://btrfs.wiki.kernel.org/index.php/Compression
|
||||||
|
[43]: https://www.man7.org/linux/man-pages/man1/chattr.1.html
|
||||||
|
[44]: https://btrfs.wiki.kernel.org/index.php/Conversion_from_Ext3
|
||||||
|
[45]: https://fedoramagazine.org/reclaim-hard-drive-space-with-lvm/
|
306
published/202101/20201231 Build your own text editor in Java.md
Normal file
306
published/202101/20201231 Build your own text editor in Java.md
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (robsean)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13038-1.html)
|
||||||
|
[#]: subject: (Build your own text editor in Java)
|
||||||
|
[#]: via: (https://opensource.com/article/20/12/write-your-own-text-editor)
|
||||||
|
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||||
|
|
||||||
|
使用 Java 构建你自己的文本编辑器
|
||||||
|
======
|
||||||
|
|
||||||
|
> 有时候,除你自己外,没有人能制作你所梦想的工具。以下是如何开始构建你自己的文本编辑器。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/21/134710uzumn6ej36u7t79j.jpg)
|
||||||
|
|
||||||
|
有很多文本编辑器。有运行在终端中、运行在 GUI 中、运行在浏览器和浏览器引擎中的。有很多是还不错,有一些则是极好的。但是有时候,毫无疑问,最令人满意的就是你自己构建的编辑器。
|
||||||
|
|
||||||
|
毫无疑问:构建一个真正优秀的文本编辑器比表面上看上去要困难得多。但话说回来,建立一个基本的文本编辑器也不像你担心的那样难。事实上,大多数编程工具包已经为你准备好了文本编辑器的大部分组件。围绕文本编辑的组件,例如菜单条,文件选择对话框等等,是很容易落到实处。因此,虽然是中级的编程课程,但构建一个基本的文本编辑器是出乎意料的有趣和简明。你可能会发现自己渴望使用一个自己构造的工具,而且你使用得越多,你可能会有更多的灵感来增加它的功能,从而更多地学习你正在使用的编程语言。
|
||||||
|
|
||||||
|
为了使这个练习切合实际,最好选择一种具有令人满意的 GUI 工具箱的语言。有很多种选择,包括 Qt 、FLTK 或 GTK ,但是一定要先评审一下它的文档,以确保它有你所期待的功能。对于这篇文章来说,我使用 Java 以及其内置的 Swing 小部件集。如果你想使用一种不同的语言或者一种不同的工具集,这篇文章在如何帮你处理这种问题的方面也仍然是有用的。
|
||||||
|
|
||||||
|
不管你选择哪一种,在任何主要的工具箱中编写一个文本编辑器都是惊人的相似。如果你是 Java 新手,需要更多关于开始的信息,请先阅读我的 [猜谜游戏文章][2] 。
|
||||||
|
|
||||||
|
### 工程设置
|
||||||
|
|
||||||
|
通常,我使用并推荐像 [Netbeans][3] 或 Eclipse 这样的 IDE,但我发现,当学习一种新的语言时,手工做一些工作是很有帮助的,这样你就能更好地理解使用 IDE 时被隐藏起来的东西。在这篇文章中,我假设你正在使用文本编辑器和终端进行编程。
|
||||||
|
|
||||||
|
在开始前,为你自己的工程创建一个工程目录。在工程文件夹中,创建一个名称为 `src` 的目录来容纳你的源文件。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mkdir -p myTextEditor/src
|
||||||
|
$ cd myTextEditor
|
||||||
|
```
|
||||||
|
|
||||||
|
在你的 `src` 目录中创建一个名称为 `TextEdit.java` 的空白的文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ touch src/TextEditor.java
|
||||||
|
```
|
||||||
|
|
||||||
|
在你最喜欢的文本编辑器中打开这个空白的文件(我的意思是除你自己编写之外的最喜欢的一款文本编辑器),然后准备好编码吧!
|
||||||
|
|
||||||
|
### 包和导入
|
||||||
|
|
||||||
|
为确保你的 Java 应用程序有一个唯一的标识符,你必须声明一个 `package` 名称。典型的格式是使用一个反向的域名,如果你真的有一个域名的话,这就特别容易了。如果你没有域名的话,你可以使用 `local` 作为最顶层。像 Java 和很多语言一样,行以分号结尾。
|
||||||
|
|
||||||
|
在命名你的 Java 的 `package` 后,你必须告诉 Java 编译器(`javac`)使用哪些库来构建你的代码。事实上,这通常是你边编写代码边添加的内容,因为你很少事先知道你自己所需要的库。然而,这里有一些库是显而易见的。例如,你知道这个文本编辑器是基于 Swing GUI 工具箱的,因此,导入 `javax.swing.JFrame` 和`javax.swing.UIManager` 和其它相关的特定库。
|
||||||
|
|
||||||
|
```
|
||||||
|
package com.example.textedit;
|
||||||
|
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
```
|
||||||
|
|
||||||
|
对于这个练习的目标,你可以提前预知你所需要的所有的库。在真实的生活中,不管你喜欢哪一种语言,你都将在研究如何解决一些问题的时候发现库,然后,你将它导入到你的代码中,并使用它。不需要担心 —— 如果你忘记包含一个库,你的编译器或解释器将警告你!
|
||||||
|
|
||||||
|
### 主窗口
|
||||||
|
|
||||||
|
这是一个单窗口应用程序,因此这个应用程序的主类是一个 `JFrame` ,其附带有一个捕捉菜单事件的 `ActionListener` 。在 Java 中,当你使用一个现有的小部件元素时,你可以使用你的代码“扩展”它。这个主窗口需要三个字段:窗口本身(一个 `JFrame` 的实例)、一个用于文件选择器返回值的标识符和文本编辑器本身(`JTextArea`)。
|
||||||
|
|
||||||
|
```
|
||||||
|
public final class TextEdit extends JFrame implements ActionListener {
|
||||||
|
private static JTextArea area;
|
||||||
|
private static JFrame frame;
|
||||||
|
private static int returnValue = 0;
|
||||||
|
```
|
||||||
|
|
||||||
|
令人惊奇的是,这数行代码完成了实现一个基本文本编辑器的 80% 的工作,因为 `JtextArea` 是 Java 的文本输入字段。剩下的 80 行代码大部分用于处理辅助功能,比如保存和打开文件。
|
||||||
|
|
||||||
|
### 构建一个菜单
|
||||||
|
|
||||||
|
`JMenuBar` 小部件被设计到 JFrame 的顶部,它为你提供你想要的很多菜单项。Java 不是一种
|
||||||
|
拖放式的编程语言,因此,对于你所添加的每一个菜单,你都还必须编写一个函数。为保持这个工程的可控性,我提供了四个函数:创建一个新的文件,打开一个现有的文件,保存文本到一个文件,和关闭应用程序。
|
||||||
|
|
||||||
|
在大多数流行的工具箱中,创建一个菜单的过程基本相同。首先,你创建菜单条本身,然后创建一个顶级菜单(例如 “File” ),再然后创建子菜单项(例如,“New”、“Save” 等)。
|
||||||
|
|
||||||
|
```
|
||||||
|
public TextEdit() { run(); }
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
frame = new JFrame("Text Edit");
|
||||||
|
|
||||||
|
// Set the look-and-feel (LNF) of the application
|
||||||
|
// Try to default to whatever the host system prefers
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||||
|
Logger.getLogger(TextEdit.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set attributes of the app window
|
||||||
|
area = new JTextArea();
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.add(area);
|
||||||
|
frame.setSize(640, 480);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
// Build the menu
|
||||||
|
JMenuBar menu_main = new JMenuBar();
|
||||||
|
|
||||||
|
JMenu menu_file = new JMenu("File");
|
||||||
|
|
||||||
|
JMenuItem menuitem_new = new JMenuItem("New");
|
||||||
|
JMenuItem menuitem_open = new JMenuItem("Open");
|
||||||
|
JMenuItem menuitem_save = new JMenuItem("Save");
|
||||||
|
JMenuItem menuitem_quit = new JMenuItem("Quit");
|
||||||
|
|
||||||
|
menuitem_new.addActionListener(this);
|
||||||
|
menuitem_open.addActionListener(this);
|
||||||
|
menuitem_save.addActionListener(this);
|
||||||
|
menuitem_quit.addActionListener(this);
|
||||||
|
|
||||||
|
menu_main.add(menu_file);
|
||||||
|
|
||||||
|
menu_file.add(menuitem_new);
|
||||||
|
menu_file.add(menuitem_open);
|
||||||
|
menu_file.add(menuitem_save);
|
||||||
|
menu_file.add(menuitem_quit);
|
||||||
|
|
||||||
|
frame.setJMenuBar(menu_main);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
现在,所有剩余的工作是实施菜单项所描述的功能。
|
||||||
|
|
||||||
|
### 编程菜单动作
|
||||||
|
|
||||||
|
你的应用程序响应菜单选择,是因为你的 `JFrame` 有一个附属于它的 `ActionListener` 。在 Java 中,当你实施一个事件处理程序时,你必须“重写”其内建的函数。这只是听起来可怕。你不是在重写 Java;你只是在实现已经被定义但尚未实施事件处理程序的函数。
|
||||||
|
|
||||||
|
在这种情况下,你必须重写 `actionPerformed`方法。因为在 “File” 菜单中的所有条目都与处理文件有关,所以在我的代码中很早就定义了一个 `JFileChooser` 。代码其它部分被划分到一个 `if` 语句的子语句中,这起来像接收到什么事件就相应地执行什么动作。每个子语句都与其它的子语句完全不同,因为每个项目都标示着一些完全唯一的东西。最相似的是 “Open” 和 “Save”,因为它们都使用 `JFileChooser` 选择文件系统中的一个位置来获取或放置数据。
|
||||||
|
|
||||||
|
“New” 菜单会在没有警告的情况下清理 JTextArea ,“Quit” 菜单会在没有警告的情况下关闭应用程序。这两个 “功能” 都是不安全的,因此你应该想对这段代码进行一点改善,这是一个很好的开始。在内容还没有被保存前,一个友好的警告是任何一个好的文本编辑器都必不可少的一个功能,但是在这里为了简单,这是未来的一个功能。
|
||||||
|
|
||||||
|
```
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String ingest = null;
|
||||||
|
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
||||||
|
jfc.setDialogTitle("Choose destination.");
|
||||||
|
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||||
|
|
||||||
|
String ae = e.getActionCommand();
|
||||||
|
if (ae.equals("Open")) {
|
||||||
|
returnValue = jfc.showOpenDialog(null);
|
||||||
|
if (returnValue == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File f = new File(jfc.getSelectedFile().getAbsolutePath());
|
||||||
|
try{
|
||||||
|
FileReader read = new FileReader(f);
|
||||||
|
Scanner scan = new Scanner(read);
|
||||||
|
while(scan.hasNextLine()){
|
||||||
|
String line = scan.nextLine() + "\n";
|
||||||
|
ingest = ingest + line;
|
||||||
|
}
|
||||||
|
area.setText(ingest);
|
||||||
|
}
|
||||||
|
catch ( FileNotFoundException ex) { ex.printStackTrace(); }
|
||||||
|
}
|
||||||
|
// 保存
|
||||||
|
} else if (ae.equals("Save")) {
|
||||||
|
returnValue = jfc.showSaveDialog(null);
|
||||||
|
try {
|
||||||
|
File f = new File(jfc.getSelectedFile().getAbsolutePath());
|
||||||
|
FileWriter out = new FileWriter(f);
|
||||||
|
out.write(area.getText());
|
||||||
|
out.close();
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
Component f = null;
|
||||||
|
JOptionPane.showMessageDialog(f,"File not found.");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Component f = null;
|
||||||
|
JOptionPane.showMessageDialog(f,"Error.");
|
||||||
|
}
|
||||||
|
} else if (ae.equals("New")) {
|
||||||
|
area.setText("");
|
||||||
|
} else if (ae.equals("Quit")) { System.exit(0); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
从技术上来说,这就是这个文本编辑器的全部。当然,并没有真正做什么,除此之外,在这里仍然有测试和打包步骤,因此仍然有很多时间来发现缺少的必需品。假设你没有注意到提示:在这段代码中 _肯定_ 缺少一些东西。你现在知道缺少的是什么吗?(在 [猜谜游戏文章][4] 中被大量的提到。)
|
||||||
|
|
||||||
|
### 测试
|
||||||
|
|
||||||
|
你现在可以测试你的应用程序。从终端中启动你所编写的文本编辑器:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ java ./src/TextEdit.java
|
||||||
|
error: can’t find main(String[]) method in class: com.example.textedit.TextEdit
|
||||||
|
```
|
||||||
|
|
||||||
|
它看起来像在代码中没有获得 `main` 方法。这里有一些方法来修复这个问题:你可以在 `TextEdit.java` 中创建一个 `main` 方法,并让它运行一个 `TextEdit` 类实例,或者你可以创建一个单独的包含 `main` 方法的文件。两种方法都可以工作,但从大型工程的预期来看,使用后者更为明智,因此,使用单独的文件与其一起工作使之成为一个完整的应用程序的方法是值得使用的。
|
||||||
|
|
||||||
|
在 `src` 中创建一个 `Main.java` 文件,并在最喜欢的编辑器中打开:
|
||||||
|
|
||||||
|
```
|
||||||
|
package com.example.textedit;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TextEdit runner = new TextEdit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
你可以再次尝试,但是现在有两个相互依赖的文件要运行,因此你必须编译代码。Java 使用 `javac` 编译器,并且你可以使用 `-d` 选项来设置目标目录:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ javac src/*java -d .
|
||||||
|
```
|
||||||
|
|
||||||
|
这会在你的软件包名称 `com/example/textedit` 后创建一个准确地模型化的新的目录结构。这个新的类路径包含文件 `Main.class` 和 `TextEdit.class` ,这两个文件构成了你的应用程序。你可以使用 `java` 并通过引用你的 Main 类的位置和 _名称_(非文件名称)来运行它们:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ java info/slackermedia/textedit/Main`
|
||||||
|
```
|
||||||
|
|
||||||
|
你的文本编辑器打开了,你可以在其中输入文字,打开文件,甚至保存你的工作。
|
||||||
|
|
||||||
|
![带有单个下拉菜单的白色文本编辑器框,有 File、New、Open、Save 和 Quit 菜单][5]
|
||||||
|
|
||||||
|
### 以 Java 软件包的形式分享你的工作
|
||||||
|
|
||||||
|
虽然一些程序员似乎看起来认可以各种各样的源文件的形式分发软件包,并鼓励其他人来学习如何运行它,但是,Java 让打包应用程序变得真地很容易,以至其他人可以很容易的运行它。你已经有了必备的大部分结构体,但是你仍然需要一些元数据到一个 `Manifest.txt` 文件中:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ echo "Manifest-Version: 1.0" > Manifest.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
用于打包的 `jar` 命令,与 [tar][6] 命令非常相似,因此很多选项对你来说可能会很熟悉。要创建一个 JAR 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ jar cvfme TextEdit.jar
|
||||||
|
Manifest.txt
|
||||||
|
com.example.textedit.Main
|
||||||
|
com/example/textedit/*.class
|
||||||
|
```
|
||||||
|
|
||||||
|
根据命令的语法,你可以推测出它会创建一个新的名称为 `TextEdit.jar` 的 JAR 文件,它所需要的清单数据位于 `Manifest.txt` 中。它的主类被定义为软件包名称的一个扩展,并且类自身是 `com/example/textedit/Main.class` 。
|
||||||
|
|
||||||
|
你可以查看 JAR 文件的内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ jar tvf TextEdit.jar
|
||||||
|
0 Wed Nov 25 META-INF/
|
||||||
|
105 Wed Nov 25 META-INF/MANIFEST.MF
|
||||||
|
338 Wed Nov 25 com/example/textedit/textedit/Main.class
|
||||||
|
4373 Wed Nov 25 com/example/textedit/textedit/TextEdit.class
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你想看看你的元数据是如何被集成到 `MANIFEST.MF` 文件中的,你甚至可以使用 `xvf` 选项来提取它。
|
||||||
|
|
||||||
|
使用 `java` 命令来运行你的 JAR 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ java -jar TextEdit.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
你甚至可以 [创建一个桌面文件][7] ,这样,在单击应用程序菜单中的图标时,应用程序就会启动。
|
||||||
|
|
||||||
|
### 改进它
|
||||||
|
|
||||||
|
在当前状态下,这是一个非常基本的文本编辑器,最适合做快速笔记或简短自述文档。一些改进(比如添加垂直滚动条)只要稍加研究就能快速简单地完成,而另一些改进(比如实现一个广泛的偏好系统)则需要真正的工作。
|
||||||
|
|
||||||
|
但如果你一直在想学一种新的语言,这可能是一个完美的自我学习实用工程。创建一个文本编辑器,如你所见,它在代码方面并不难对付,它在一定范围是可控的。如果你经常使用文本编辑器,那么编写你自己的文本编辑器可能会使你满意和乐趣。因此打开你最喜欢的文本编辑器(你写的那个),开始添加功能吧!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/12/write-your-own-text-editor
|
||||||
|
|
||||||
|
作者:[Seth Kenlon][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://opensource.com/users/seth
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||||
|
[2]: https://opensource.com/article/20/12/learn-java
|
||||||
|
[3]: https://opensource.com/article/20/12/netbeans
|
||||||
|
[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+component
|
||||||
|
[5]: https://opensource.com/sites/default/files/uploads/this-time-its-personal-31_days_yourself-opensource.png (White text editor box with single drop down menu with options File, New, Open, Save, and Quit)
|
||||||
|
[6]: https://opensource.com/article/17/7/how-unzip-targz-file
|
||||||
|
[7]: https://opensource.com/article/18/1/how-install-apps-linux
|
78
published/202101/20210101 Resize images using Python.md
Normal file
78
published/202101/20210101 Resize images using Python.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13003-1.html)
|
||||||
|
[#]: subject: (Resize images using Python)
|
||||||
|
[#]: via: (https://opensource.com/life/15/2/resize-images-python)
|
||||||
|
[#]: author: (Dayo Ntwari https://opensource.com/users/dayontwari)
|
||||||
|
|
||||||
|
使用 Python 调整图像大小
|
||||||
|
======
|
||||||
|
|
||||||
|
> 快速解释如何在 Python 中调整图像大小,同时保持相同的长宽比。
|
||||||
|
|
||||||
|
![Python in a tree][1]
|
||||||
|
|
||||||
|
我喜欢 [Python][2],而且我已经学了一段时间了。前段时间,我写了一个 Python 脚本,在这个脚本中,我需要调整一堆图片的大小,同时保持长宽比(比例)不变。于是我四处寻找,发现了 [Pillow][3],这是一个 Python 图像库,也是一个叫做 PIL 的旧库的“友好复刻”。
|
||||||
|
|
||||||
|
要安装 Pillow,请使用 Python 的 `pip` 模块:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 -m pip install Pillow
|
||||||
|
```
|
||||||
|
|
||||||
|
### 按宽度缩放
|
||||||
|
|
||||||
|
这是一个使用 Pillow 模块来调整图片大小的基本脚本:
|
||||||
|
|
||||||
|
```
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
basewidth = 300
|
||||||
|
img = Image.open('fullsized_image.jpg')
|
||||||
|
wpercent = (basewidth / float(img.size[0]))
|
||||||
|
hsize = int((float(img.size[1]) * float(wpercent)))
|
||||||
|
img = img.resize((basewidth, hsize), Image.ANTIALIAS)
|
||||||
|
img.save('resized_image.jpg')
|
||||||
|
```
|
||||||
|
|
||||||
|
这几行 Python 代码使用 Pillow 将一张图片 (`fullsized_image.jpg`) 调整为 300 像素的宽度,宽度在变量 `basewidth` 中设置,高度则与新的宽度成比例。比例高度的计算方法是:确定 300 像素占原宽度 (`img.size[0]`) 的百分比,然后将原高度(`img.size[1]`) 乘以该百分比。所得的高度值保存在变量 `hsize` 中。
|
||||||
|
|
||||||
|
如果你需要不同的图片宽度,你可以将 `basewidth` 改为任何其他数字。另外,请注意,因为我想保留全尺寸的图片 (`fullsized_image.jpg`),因此我将调整后的图片以一个不同的名称 `resized_image.jpg` 保存。当然,你不必这么做。如果你想,你可以使用相同的文件名将调整后的图片覆盖全尺寸的图片。
|
||||||
|
|
||||||
|
### 按高度缩放
|
||||||
|
|
||||||
|
如果高度是固定的,而宽度是按比例变化的,那也基本差不多,你只需要把东西换一下:
|
||||||
|
|
||||||
|
```
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
baseheight = 560
|
||||||
|
img = Image.open('fullsized_image.jpg')
|
||||||
|
hpercent = (baseheight / float(img.size[1]))
|
||||||
|
wsize = int((float(img.size[0]) * float(hpercent)))
|
||||||
|
img = img.resize((wsize, baseheight), Image.ANTIALIAS)
|
||||||
|
img.save('resized_image.jpg')
|
||||||
|
```
|
||||||
|
|
||||||
|
注意 `basewidth` 现在换成了 `baseheight`,因为高度是固定的。在第三行中,我们在计算高度百分比,所以我们需要 `img.size[1]` 而不是 `img.size[0]`。`size` 属性是一个元组,包含宽度和高度,单位是像素,`size[0]` 指的是第一个元组元素,也就是宽度,`size[1]` 是第二个元素,也就是高度。第 4 行也有这样的切换,`size[0]` 代表宽度,`size[1]` 代表高度。
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/life/15/2/resize-images-python
|
||||||
|
|
||||||
|
作者:[Dayo Ntwari][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/dayontwari
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life-python.jpg?itok=F2PYP2wT (Python in a tree)
|
||||||
|
[2]: http://python.org/ (Python Programming Language – Official Website)
|
||||||
|
[3]: https://pypi.org/project/Pillow/ (Python Imaging Library)
|
||||||
|
[4]: https://dayontwari.wordpress.com/2015/01/06/how-to-resize-images-with-python/
|
@ -1,22 +1,22 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: (wxy)
|
[#]: translator: (wxy)
|
||||||
[#]: reviewer: (wxy)
|
[#]: reviewer: (wxy)
|
||||||
[#]: publisher: ( )
|
[#]: publisher: (wxy)
|
||||||
[#]: url: ( )
|
[#]: url: (https://linux.cn/article-13046-1.html)
|
||||||
[#]: subject: (4 lines of code to improve your Ansible play)
|
[#]: subject: (4 lines of code to improve your Ansible play)
|
||||||
[#]: via: (https://opensource.com/article/21/1/improve-ansible-play)
|
[#]: via: (https://opensource.com/article/21/1/improve-ansible-play)
|
||||||
[#]: author: (Jeff Warncia https://opensource.com/users/jeffwarncia)
|
[#]: author: (Jeff Warncia https://opensource.com/users/jeffwarncia)
|
||||||
|
|
||||||
4 行代码提高你的 Ansible 剧本
|
改进你的 Ansible 剧本的 4 行代码
|
||||||
======
|
======
|
||||||
|
|
||||||
> 只要付出一点点努力,你就可以帮助下一个人,不只是绘制出安全路径,还可以留下危险的警告。
|
> 只要付出一点点努力,你就可以帮助下一个人,不只是绘制出安全路径,还可以留下危险的警告。
|
||||||
|
|
||||||
![一个人编程][1]
|
![](https://img.linux.net.cn/data/attachment/album/202101/23/225612fowskoyyk1gtwtog.jpg)
|
||||||
|
|
||||||
在博客圈里,人们对基础架构即代码、持续集成/持续交付(CI/CD)管道、代码审查和测试制度赞不绝口,但人们很容易忘记,这种精心设计的象牙塔只是一种理想,而不是现实。虽然不完美的系统困扰着我们,但我们必须交付一些东西。
|
在博客圈里,人们对基础架构即代码、持续集成/持续交付(CI/CD)管道、代码审查和测试制度赞不绝口,但人们很容易忘记,这种精心设计的象牙塔只是一种理想,而不是现实。虽然不完美的系统困扰着我们,但我们必须交付一些东西。
|
||||||
|
|
||||||
在系统自动化的过程中,很少有比那些通过粘合 API 创建的象牙塔更脆弱的塔。这是一个脆弱的世界。要让它“工作起来”,交付它,然后继续前进,压力是巨大的。
|
在系统自动化的过程中,很少有比那些通过粘合 API 创建的象牙塔更脆弱的塔。这是一个脆弱的世界。要让它“工作起来”,交付它,然后继续前进,压力巨大。
|
||||||
|
|
||||||
### 要解决的问题
|
### 要解决的问题
|
||||||
|
|
||||||
@ -53,7 +53,7 @@
|
|||||||
_query: "name={{ vlan_parent_view_name }}"
|
_query: "name={{ vlan_parent_view_name }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
最终,它进行了一个 REST 调用。这将“返回” 一个 JSON,按照惯例,为了便于在角色外访问,我把它填充进了`_otherthing_search_result` 中,。`search_for.yml` 的实现是抽象的,它总是返回一个包含零或多个结果的字典。
|
最终,它进行了一个 REST 调用。这将“返回” 一个 JSON,按照惯例,为了便于在角色外访问,我把它填充进了 `_otherthing_search_result` 中,。`search_for.yml` 的实现是抽象的,它总是返回一个包含零或多个结果的字典。
|
||||||
|
|
||||||
正如我读过的几乎所有真实世界的 Ansible 代码所证明的那样,大多数 Ansible 开发者将会继续前进,好像一切都很好,并且可以直接访问预期的单个结果:
|
正如我读过的几乎所有真实世界的 Ansible 代码所证明的那样,大多数 Ansible 开发者将会继续前进,好像一切都很好,并且可以直接访问预期的单个结果:
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ _“好吧,不要这样做。这是一个没有哑巴的场所。不要那么
|
|||||||
|
|
||||||
而如果我出门了呢?如果我把代码交给了一个运维团队,也许是一个实习生通过 [Tower][3] 来运行,把 `vlan_view_name` 手动输入到表单之类的东西呢?那第 30 行出的问题是对他们没有帮助的。
|
而如果我出门了呢?如果我把代码交给了一个运维团队,也许是一个实习生通过 [Tower][3] 来运行,把 `vlan_view_name` 手动输入到表单之类的东西呢?那第 30 行出的问题是对他们没有帮助的。
|
||||||
|
|
||||||
你说,加注释吧! 嗯,是的。我可以在代码中写一些梗概,以帮助下周或下个月的开发人员。这对运行代码的人没有帮助,他的工作刚刚失败,当然对于企业也无济于事。
|
你说,加注释吧! 嗯,是的。我可以在代码中写一些梗概,以帮助下周或下个月的开发人员。这对运行代码的人没有帮助,他的“工作”刚刚失败,当然对于企业也无济于事。
|
||||||
|
|
||||||
记住,我们此刻无所不能。在写代码或者跳过写代码的时候,我们是站在实力和知识的立场上进行的。我们花了几个小时,甚至几天的时间,研究了文档、现实、其他 bug、其他问题,我们留下了代码、注释,甚至可能还有文档。我们写的代码是分享成功的,而成功正是我们用户想要的。但是在这种学习中也有很多失败的地方,我们也可以留下这些。
|
记住,我们此刻无所不能。在写代码或者跳过写代码的时候,我们是站在实力和知识的立场上进行的。我们花了几个小时,甚至几天的时间,研究了文档、现实、其他 bug、其他问题,我们留下了代码、注释,甚至可能还有文档。我们写的代码是分享成功的,而成功正是我们用户想要的。但是在这种学习中也有很多失败的地方,我们也可以留下这些。
|
||||||
|
|
150
published/202101/20210106 Learn C by writing a simple game.md
Normal file
150
published/202101/20210106 Learn C by writing a simple game.md
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (qfzy1233)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13013-1.html)
|
||||||
|
[#]: subject: (Learn C by writing a simple game)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/learn-c)
|
||||||
|
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||||
|
|
||||||
|
通过编写一个简单的游戏学习 C 语言
|
||||||
|
======
|
||||||
|
|
||||||
|
> 当你学习一门新的编程语言时,这个“猜数字”游戏是一个很好的入门程序。下面是如何用 C 语言来编写它。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/13/232713lh91stdahcxfyfhe.jpg)
|
||||||
|
|
||||||
|
我在小学时就开始 [自学编程][2]。我的第一个程序是在 Apple II 上编写的,但最终,我还是通过看书和编程练习学会了 C 语言。练习编程的最佳方法是编写示例程序,它能帮助你练习新知识。
|
||||||
|
|
||||||
|
在我学习一种新的编程语言时,我喜欢编写一个简单的“猜数字”游戏来练习。电脑从 1 到 100 中随机挑选一个数字,你必须通过猜测来算出来。在另一篇文章中,我展示了如何用 Bash 语言编写这个[“猜数字”游戏][3],我的同事也写了一些文章,介绍如何用 [Java][4]、[Julia][5] 和其他计算机语言编写它。
|
||||||
|
|
||||||
|
“猜数字”游戏的伟大之处在于它践行了几个编程概念:如何使用变量、如何比较值、如何打印输出以及如何读取输入。
|
||||||
|
|
||||||
|
整个夏天,我录制了[一个系列视频][6],教人们如何用 [C 语言][7]编写程序。从那以后,我听到了很多人都在跟着它学习 C 语言编程的消息。所以,我想接着用 C 语言写一个“猜数字”的游戏。
|
||||||
|
|
||||||
|
### 去取一个随机数
|
||||||
|
|
||||||
|
从写一个函数来选择一个随机数字来开始“猜数字”游戏。在编写函数时,优秀的程序员会尽量使它们具有灵活性,这样他们就可以重用它们来解决略有不同的问题。因此,与其硬编码函数来选择 1 到 100 之间的一个随机数,不如编写函数来选择 1 到某个整数 `maxval` 之间的一个随机数:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
randnum(int maxval)
|
||||||
|
{
|
||||||
|
/* pick a random number from 1 to maxval */
|
||||||
|
|
||||||
|
int randval;
|
||||||
|
|
||||||
|
getrandom(&randval, sizeof(int), GRND_NONBLOCK);
|
||||||
|
|
||||||
|
/* could be negative, so ensure it's positive */
|
||||||
|
|
||||||
|
if (randval < 0) {
|
||||||
|
return (-1 * randval % maxval + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (randval % maxval + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
该函数使用 Linux 的系统调用 `getrandom` 来生成一系列随机数。你可以在手册页中了解关于这个系统调用的更多信息,但请注意,`getrandom` 将用随机的 0 和 1 填充变量。这意味着最终值可以是正的,也可以是负的,因此你需要在之后进行测试,以确保 `randnum` 函数的结果是正值。
|
||||||
|
|
||||||
|
### 编写程序
|
||||||
|
|
||||||
|
你可以用这个函数来写你的“猜数字”程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
randnum(int maxval)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
int number;
|
||||||
|
int guess;
|
||||||
|
|
||||||
|
number = randnum(100);
|
||||||
|
|
||||||
|
puts("Guess a number between 1 and 100");
|
||||||
|
|
||||||
|
do {
|
||||||
|
scanf("%d", &guess);
|
||||||
|
|
||||||
|
if (guess < number) {
|
||||||
|
puts("Too low");
|
||||||
|
}
|
||||||
|
else if (guess > number) {
|
||||||
|
puts("Too high");
|
||||||
|
}
|
||||||
|
} while (guess != number);
|
||||||
|
|
||||||
|
puts("That's right!");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
程序首先使用 `randnum` 函数从 1 到 100 之间选择一个随机数。在向用户输出一个提示后,程序进入一个 `do-while` 循环,以便用户可以猜测数字。
|
||||||
|
|
||||||
|
在循环的每次迭代中,程序测试用户的猜测的数值。如果用户的猜测小于随机数,程序将输出“Too low”,如果猜测大于随机数,程序将输出“Too high”。循环继续,直到用户的猜测与随机数相同。
|
||||||
|
|
||||||
|
当循环退出时,程序输出 “That's right!”,然后立即结束:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gcc -o guess -Wall guess.c
|
||||||
|
|
||||||
|
$ ./guess
|
||||||
|
Guess a number between 1 and 100
|
||||||
|
50
|
||||||
|
Too high
|
||||||
|
30
|
||||||
|
Too low
|
||||||
|
40
|
||||||
|
Too low
|
||||||
|
45
|
||||||
|
Too high
|
||||||
|
42
|
||||||
|
Too low
|
||||||
|
43
|
||||||
|
Too low
|
||||||
|
44
|
||||||
|
That's right!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 尝试动手
|
||||||
|
|
||||||
|
在学习一门新的编程语言时,这个“猜数字”游戏是一个很好的入门程序,因为它以一种非常直接的方式练习了几个常见的编程概念。通过用不同的编程语言实现这个简单的游戏,你可以演示一些核心概念,并比较每种语言的细节。
|
||||||
|
|
||||||
|
你有最喜欢的编程语言吗?你会如何用它来编写“猜数字”游戏呢?关注本系列文章,查看你可能感兴趣的其他编程语言的示例。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/learn-c
|
||||||
|
|
||||||
|
作者:[Jim Hall][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[qfzy1233](https://github.com/qfzy1233)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/jim-hall
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||||
|
[2]: https://opensource.com/article/20/8/learn-open-source
|
||||||
|
[3]: https://linux.cn/article-12962-1.html
|
||||||
|
[4]: https://opensource.com/article/20/12/learn-java
|
||||||
|
[5]: https://opensource.com/article/20/12/julia
|
||||||
|
[6]: https://opensource.com/article/20/8/teaching-c
|
||||||
|
[7]: https://opensource.com/article/20/8/c-programming-cheat-sheet
|
||||||
|
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/puts.html
|
||||||
|
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html
|
@ -0,0 +1,89 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13016-1.html)
|
||||||
|
[#]: subject: (My 3 favorite open source productivity apps)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/open-source-productivity-apps)
|
||||||
|
[#]: author: (Taz Brown https://opensource.com/users/heronthecli)
|
||||||
|
|
||||||
|
我最喜欢的 3 个开源生产力应用
|
||||||
|
======
|
||||||
|
|
||||||
|
> 简化你的敏捷工作流程,提高你的工作效率。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/14/215039op8zl611f8p76vrf.jpg)
|
||||||
|
|
||||||
|
生产力应用确实可以让你的工作流程变得更加轻松。在本文中,我将分享一些我用来简化工作流程、提高整体生产力的开源应用。本文中所有的生产力应用都是免费的 Linux 生产力应用。
|
||||||
|
|
||||||
|
### Tomboy/Gnote
|
||||||
|
|
||||||
|
[Tomboy][2] 是一款可以在 Linux、Windows 和 macOS 上使用的简单记事本应用。它是 GNU LGPLv2 下许可的开源软件。
|
||||||
|
|
||||||
|
Tomboy 使用起来非常简单。你写下一张纸条,选择是否将它贴在桌面上,完成后就可以删除它。
|
||||||
|
|
||||||
|
![Tomboy and Gnote][3]
|
||||||
|
|
||||||
|
它(以及它的克隆版 [Gnote][5])是一个很好的快速记笔记的小程序。很多时候,当我在做某件事情的时候,会有一些想法或思路想要回忆。Tomboy 可以让我快速创建一个笔记,在我忘记之前把我的想法记下来。然后我就可以把这些想法转移到一个更长久的地方。
|
||||||
|
|
||||||
|
### Joplin
|
||||||
|
|
||||||
|
[Joplin][6] 是一个开源的记事和待办事项应用。它是跨平台的,可以在 Linux、Windows、macOS、iOS 和 Android 上使用,并且采用 MIT 许可开源。
|
||||||
|
|
||||||
|
![Joplin][7]
|
||||||
|
|
||||||
|
它可以使用 Dropbox、OneDrive、Nextcloud 等云同步服务进行同步。它很容易安装,可能就在你的 Linux 仓库里。当你在桌面上安装它时,它一个应用中实际包含了两个:你会得到一个标准的图形用户界面 (GUI),或者打开一个终端,在那里使用 Joplin。
|
||||||
|
|
||||||
|
桌面版有一个非常漂亮的界面。笔记被组织在笔记本中,这基本上使它们成为你的手册页。而且因为笔记是 Markdown 格式的,所以它们会被渲染,你可以实时编辑它们。我喜欢使用 Markdown,因为它让我写笔记的速度很快。你也可以导出或导入 Joplin 笔记。
|
||||||
|
|
||||||
|
### Evolution
|
||||||
|
|
||||||
|
[Evolution][9] 是一款开源的个人信息管理应用,它与 Outlook 非常相似,但我认为更适合我使用。它具有电子邮件、工作、笔记、链接、日历和地址簿功能。它是 LGPL 和其他[许可证][10]下的开源软件。
|
||||||
|
|
||||||
|
![GNOME Evolution][11]
|
||||||
|
|
||||||
|
我在运行 Fedora 的台式电脑上使用它。它的效率很高,绝对能帮助我度过繁忙的一天。它让我能够使用 Linux 开展业务;我还能要求什么呢?
|
||||||
|
|
||||||
|
要在 Fedora 中使用它,打开一个终端并输入以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo dnf remove evolution
|
||||||
|
sudo dnf update
|
||||||
|
sudo dnf install evolution
|
||||||
|
sudo dnf install evolution-ews
|
||||||
|
```
|
||||||
|
|
||||||
|
### 我的常用工具
|
||||||
|
|
||||||
|
这些工具是我的主力军,我已经依赖了一段时间。使用它们超越了它们的基本功能,使我更有效率、更有效果、更有生产力。作为一名技术产品经理和敏捷专家,我很自豪,我仍然使用 Linux 和其他开源软件,即使我工作的公司不这样做。
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
_本文原载于 [Course Hero][13],经授权转载。_
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/open-source-productivity-apps
|
||||||
|
|
||||||
|
作者:[Taz Brown][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/heronthecli
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/team_dev_email_chat_video_work_wfm_desk_520.png?itok=6YtME4Hj (Working on a team, busy worklife)
|
||||||
|
[2]: https://wiki.gnome.org/Apps/Tomboy
|
||||||
|
[3]: https://opensource.com/sites/default/files/uploads/tomboy-gnote.png (Tomboy and Gnote)
|
||||||
|
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[5]: https://wiki.gnome.org/Apps/Gnote
|
||||||
|
[6]: https://joplinapp.org/
|
||||||
|
[7]: https://opensource.com/sites/default/files/uploads/joplin_0.jpg (Joplin)
|
||||||
|
[8]: https://github.com/laurent22/joplin
|
||||||
|
[9]: https://wiki.gnome.org/Apps/Evolution
|
||||||
|
[10]: https://gitlab.gnome.org/GNOME/evolution/-/blob/master/COPYING
|
||||||
|
[11]: https://opensource.com/sites/default/files/uploads/evolution.png (GNOME Evolution)
|
||||||
|
[12]: https://help.gnome.org/users/evolution/stable/intro-main-window.html.en
|
||||||
|
[13]: https://www.coursehero.com/file/74086904/Personal-productivity-using-open-source-software-tools/
|
73
published/202101/20210108 Why I like the FED text editor.md
Normal file
73
published/202101/20210108 Why I like the FED text editor.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13019-1.html)
|
||||||
|
[#]: subject: (Why I like the FED text editor)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/fed-editor)
|
||||||
|
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||||
|
|
||||||
|
我为什么喜欢 FED 文本编辑器
|
||||||
|
======
|
||||||
|
|
||||||
|
> FED 编辑器让我可以轻松有效地对我的 FreeDOS 项目进行编码。学习如何充分利用这个灵活的 Linux、Windows 和 DOS 编辑器。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/16/114344hgra9oq4q45mgz9r.jpg)
|
||||||
|
|
||||||
|
当我不[在我的 Linux 桌面上工作][2]的时候,我通常是在为一个旧版的 16 位系统写代码。[FreeDOS][3] 是一个开源的 DOS 兼容操作系统,你可以用它来玩经典的 DOS 游戏,运行旧版的商业软件,或者开发嵌入式系统。任何在 MS-DOS 上运行的程序在 FreeDOS 上也应该可以运行。
|
||||||
|
|
||||||
|
我是和 DOS 一起长大的。我家的第一台个人电脑是一台 Apple II 兼容机,但我们最终升级到了一台运行 DOS 的 IBM PC。从 1980 年代早期到 1993 年我[发现 Linux][4] 这段时间,我做了十多年的 DOS 用户。
|
||||||
|
|
||||||
|
Linux 和开源软件所提供的自由度给我留下了深刻的印象。所以当微软在 1994 年宣布 DOS 的终结,以及即将推出的 Windows 95 时,我决定编写自己的开源 DOS。这就是 [FreeDOS 的开始][4]。
|
||||||
|
|
||||||
|
这么多年过去了,我还在继续研究 FreeDOS。它是一个很好的业余兴趣系统,在这里我可以运行我最喜欢的 DOS 应用和游戏。是的,我仍然在为 FreeDOS 写代码。
|
||||||
|
|
||||||
|
我最喜欢的 DOS 编程编辑器是 FED 编辑器。FED 是一个极简的文本编辑器,没有太多的视觉效果。这种精简的方法帮助我充分利用了 DOS 中标准的 80x25 屏幕。当编辑一个文件时,FED 会在屏幕底部显示一行状态行,让你在剩下的 24 行来编写你的代码。FED 还支持彩色语法高亮显示,以不同的颜色显示代码的不同部分,使你更容易发现错别字,以免它们变成错误。
|
||||||
|
|
||||||
|
![Writing a Solitaire game with FED][5]
|
||||||
|
|
||||||
|
*用 FED 写一个纸牌游戏*
|
||||||
|
|
||||||
|
当你需要菜单时,按下键盘上的 `Alt` 键,FED 就会在最上面一行显示一个菜单。FED 也支持键盘快捷键,但要注意默认值。例如,`Ctrl-C` 会关闭文件,`Ctrl-V` 会改变视图。如果你不喜欢这些默认键,你可以在 **Config** 菜单中更改键位映射。
|
||||||
|
|
||||||
|
![Tap the Alt key to bring up the menu][6]
|
||||||
|
|
||||||
|
*按下 Alt 键弹出菜单*
|
||||||
|
|
||||||
|
如果你不喜欢默认的白底黑字显示,你可以在 **Config** 菜单下更改颜色。我更喜欢蓝底白字的正文,关键词用亮白色,注释用亮蓝色,特殊字符用青色,数字用绿色。FED 可以很容易地设置你想要的颜色。
|
||||||
|
|
||||||
|
![My preferred colors when programming on DOS][7]
|
||||||
|
|
||||||
|
*我在 DOS 上编程时喜欢的颜色*
|
||||||
|
|
||||||
|
FED 也是一个折叠式文本编辑器,这意味着它可以折叠或展开我的部分代码,以便我可以看到更多的文件。在函数名上按下 `Ctrl-F`,FED 会折叠整个函数。折叠在其他代码上也可以使用。我也使用折叠来隐藏 `for` 和 `while` 循环或其他流程控制,如 `if` 和 `switch` 块。
|
||||||
|
|
||||||
|
![Folding a function lets you see more of the file][8]
|
||||||
|
|
||||||
|
*折叠函数可以让你看到更多的文件*
|
||||||
|
|
||||||
|
Shawn Hargreaves 从 1994 年至 2004 年编写并维护 FED。Robert Riebisch 从那时起就开始维护 FED。FED 在 GNU GPL 许可下发布,支持 DOS、Linux 和 Windows。
|
||||||
|
|
||||||
|
你可以在 <https://www.bttr-software.de/products/fed/> 下载 FED。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/fed-editor
|
||||||
|
|
||||||
|
作者:[Jim Hall][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/jim-hall
|
||||||
|
[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://opensource.com/article/19/9/business-creators-open-source-tools
|
||||||
|
[3]: https://opensource.com/article/19/6/freedos-anniversary
|
||||||
|
[4]: https://opensource.com/article/17/5/how-i-got-started-linux-jim-hall-freedos
|
||||||
|
[5]: https://opensource.com/sites/default/files/1-fed.png
|
||||||
|
[6]: https://opensource.com/sites/default/files/2-fed.png
|
||||||
|
[7]: https://opensource.com/sites/default/files/3-fed.png
|
||||||
|
[8]: https://opensource.com/sites/default/files/4-fed.png
|
@ -0,0 +1,112 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13026-1.html)
|
||||||
|
[#]: subject: (Homura: A WINE-based Game Launcher for BSD)
|
||||||
|
[#]: via: (https://itsfoss.com/homura-game-launcher-bsd/)
|
||||||
|
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||||
|
|
||||||
|
Homura:基于 WINE 的 BSD 游戏启动器
|
||||||
|
======
|
||||||
|
|
||||||
|
BSD 不只是用于服务器。人们也将其用于桌面,并执行通常任务,包括休闲游戏。为了帮助实现这一点,我们将看看一个能让你在 FreeBSD 上运行 Windows 游戏的应用。
|
||||||
|
|
||||||
|
### 什么是 Homura?
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
[Homura][2] 是一个能让你在 FreeBSD 上玩 Windows 游戏的工具。它的灵感来自于 [Lutris][3]。它允许你安装和管理多个 Windows 游戏和游戏商店启动器。它主要使用 Wine,但也附带了一些修复和变通的方法来让游戏工作。
|
||||||
|
|
||||||
|
Homura 的创建者 [Alexander Vereeken][4] 说,他创建这个应用是因为“当我开始使用 FreeBSD 时,没有能用的可以在 Wine 中安装游戏或启动器的程序,所以我自己创建了一个”。当时,Wine 是唯一的选择。Linux 版本的 Steam 并不存在。
|
||||||
|
|
||||||
|
![Homura install list][5]
|
||||||
|
|
||||||
|
以下是你可以用 Homura 安装的清单:
|
||||||
|
|
||||||
|
* Anarchy Online
|
||||||
|
* Arc
|
||||||
|
* Bethesda 启动器
|
||||||
|
* 暴雪启动器
|
||||||
|
* 暗黑破坏神 II
|
||||||
|
* Discord
|
||||||
|
* 龙歌 OL
|
||||||
|
* GOG
|
||||||
|
* 建造乌托邦
|
||||||
|
* 英雄联盟
|
||||||
|
* Origin 启动器
|
||||||
|
* PokeMMO
|
||||||
|
* 精灵宝可梦 绿铀
|
||||||
|
* RuneScape
|
||||||
|
* Steam
|
||||||
|
* 地铁跑酷
|
||||||
|
* Teamspeak
|
||||||
|
* 猴岛大冒险 2
|
||||||
|
* UC 浏览器
|
||||||
|
* 育碧
|
||||||
|
* 战游游戏中心
|
||||||
|
* Itch.io
|
||||||
|
|
||||||
|
Homura 是以动画 [Madoka Magica][6] 中的一个角色命名的。在创建者转移到 GitLab 之前,它最初托管在 GitHub 上。目前它被托管在 Codeberg 上。希望它现在还能留在那里。
|
||||||
|
|
||||||
|
![Homura][7]
|
||||||
|
|
||||||
|
### 在 BSD 上安装 Homura 游戏启动器
|
||||||
|
|
||||||
|
你可以用这个命令从 FreeBSD 仓库中安装 Homura:
|
||||||
|
|
||||||
|
```
|
||||||
|
pkg install games/homura
|
||||||
|
```
|
||||||
|
|
||||||
|
你也可以使用这个命令从 ports 构建并安装它:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd /usr/ports/games/homura/ && make install clean
|
||||||
|
```
|
||||||
|
|
||||||
|
安装完成后,你可以从菜单中选择 Homura,或在命令行中输入 `Homura` 来运行它。(在终端中名字必须大写开头,否则将无法运行。)
|
||||||
|
|
||||||
|
如果你通过 Homura 安装 Steam,你需要从 Homura 启动它。如果你想从操作系统的菜单中启动它,它当前不会显示在那里。
|
||||||
|
|
||||||
|
Steam 的库和商店标签由内置的 Web 浏览器显示。由于某些原因,这在 FreeBSD 上是不行的。但如果你从 Homura 的菜单中启动 Steam,它将使用列表模式,工作没有问题。
|
||||||
|
|
||||||
|
### 体验
|
||||||
|
|
||||||
|
我在 GhostBSD 上安装了 Homura,并用它来安装 Steam。之后,我安装了几个游戏来测试它。并不是所有的游戏都能正常运行,主要是因为它们试图使用或安装一个不可用的 Windows 专用软件。然而,我能够玩我最喜欢的游戏之一,微软的“国家的崛起”,没有任何问题。(我的测试变成了几个小时的游戏。)
|
||||||
|
|
||||||
|
![Homura Main Menu][8]
|
||||||
|
|
||||||
|
我也尝试安装 GOG 启动器。由于某些原因,它对我不起作用。加载页面会弹出,但什么都不会发生。我打算提交一个议题。我没有测试过任何安装程序/启动器,因为我没有使用它们。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
并不是所有的东西都能顺利地与 Homura 一起使用,但我可以玩一些我最喜欢的游戏。
|
||||||
|
|
||||||
|
![Rise of Nation on BSD][9]
|
||||||
|
|
||||||
|
这款应用是一个典型的用户有了需求,并决定去填补它的案例。通过这样做,他让其他人的生活变得更轻松。希望这个应用能让人们更容易地开始使用 FreeBSD 作为他们的操作系统。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/homura-game-launcher-bsd/
|
||||||
|
|
||||||
|
作者:[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://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/homura.jpg?resize=800%2C450&ssl=1
|
||||||
|
[2]: https://codeberg.org/Alexander88207/Homura
|
||||||
|
[3]: https://lutris.net/
|
||||||
|
[4]: https://codeberg.org/Alexander88207
|
||||||
|
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/homura-install.jpg?resize=800%2C421&ssl=1
|
||||||
|
[6]: https://madoka.fandom.com/wiki/Puella_Magi_Madoka_Magica
|
||||||
|
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/homura-about.jpg?resize=800%2C411&ssl=1
|
||||||
|
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/homura-main-menu.jpg?resize=500%2C776&ssl=1
|
||||||
|
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/rise-of-nation-bsd.jpg?resize=800%2C450&ssl=1
|
||||||
|
[10]: https://%0Areddit.com/r/linuxusersgroup
|
@ -0,0 +1,211 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13020-1.html)
|
||||||
|
[#]: subject: (Deploy Ceph in a Raspberry Pi cluster)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/ceph-raspberry-pi)
|
||||||
|
[#]: author: (AJ Canlas https://opensource.com/users/ajscanlas)
|
||||||
|
|
||||||
|
在树莓派集群中部署 Ceph
|
||||||
|
======
|
||||||
|
|
||||||
|
> 使用 ceph-ansible 安装 Ceph 存储,并将其部署在树莓派集群中。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/16/135445mquduh2idu2pft22.jpg)
|
||||||
|
|
||||||
|
[Ceph][2] 是一个开源软件存储平台,它在统一的存储集群中提供对象、块和文件系统存储。我第一次使用 Ceph 是在 [OpenStack 中集成它][3]的时候。一开始,我很困惑,既然存储设备广泛存在,为什么要使用 Ceph。但在使用了三年多之后,这个平台的稳定性和完整性一再证明了它的价值。
|
||||||
|
|
||||||
|
本文将告诉你如何使用 [ceph-ansible][4](Ceph 官方支持的 Ansible playbook)安装 Ceph,并将其部署在树莓派集群中。
|
||||||
|
|
||||||
|
**材料:**
|
||||||
|
|
||||||
|
1. 树莓派 4B 4GB 型号四台。
|
||||||
|
2. 四张 32GB 的 microSD 卡(用于启动操作系统)
|
||||||
|
3. 四个树莓派外壳,带风扇和散热片(非常重要)
|
||||||
|
4. 四个树莓派充电器
|
||||||
|
5. 6 个 32GB U 盘(用于 Ceph OSD 节点)
|
||||||
|
|
||||||
|
**架构:**
|
||||||
|
|
||||||
|
![Project architecture][5]
|
||||||
|
|
||||||
|
关于配置:
|
||||||
|
|
||||||
|
* 前端和后端网络都在同一个子网中
|
||||||
|
* [Ceph Monitor][7] 软件使用 4GB 内存的树莓派 4B。
|
||||||
|
* [Ceph OSD][8] 节点使用相同的树莓派型号,但有两个 U 盘用于 OSD 磁盘
|
||||||
|
|
||||||
|
### 使用 ceph-ansible 部署 Ceph
|
||||||
|
|
||||||
|
使用 Ceph 的 Ansible 仓库可以让部署变得顺畅简单
|
||||||
|
|
||||||
|
#### 1、复制 ssh 密钥到所有服务器
|
||||||
|
|
||||||
|
我在所有的服务器上都有一个名为 `cephadmin` 的共同用户(在此背景下,每个树莓派都是一台服务器)。`cephadmin` 用户配置了无密码的 `sudo`,以方便工作。
|
||||||
|
|
||||||
|
使用 `ssh-keygen` 生成密钥后,使用 `ssh-copy-id` 部署所有密钥。
|
||||||
|
|
||||||
|
我使用了一个 Bash `for` 循环,因为我使用的是一致并递增的主机名:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ for i in {0..3}; \
|
||||||
|
do ssh-copy-id cephadmin@rpi4b4-$i; \
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
你需要每个接受并输入密码,但你可以用 `expect` 来自动完成。
|
||||||
|
|
||||||
|
#### 2、克隆 ceph-ansible 并安装依赖
|
||||||
|
|
||||||
|
安装 Git 来克隆仓库:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install git -y
|
||||||
|
```
|
||||||
|
|
||||||
|
克隆 ceph-ansible 仓库:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone https://github.com/ceph/ceph-ansible.git
|
||||||
|
$ cd ceph-ansible/
|
||||||
|
```
|
||||||
|
|
||||||
|
我使用的是 CentOS 7 的 AArch64 构建,所以在继续之前,我必须安装一些所需的包。
|
||||||
|
|
||||||
|
首先安装 Python `pip`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install python3-pip -y
|
||||||
|
```
|
||||||
|
|
||||||
|
接着是 ceph-ansible 需要的包:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install python3-devel libffi-devel openssl-devel -y
|
||||||
|
```
|
||||||
|
|
||||||
|
最后,ceph-ansible 需要的依赖:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pip3 install -r requirements.txt --user
|
||||||
|
```
|
||||||
|
|
||||||
|
我收到了这个错误:
|
||||||
|
|
||||||
|
```
|
||||||
|
You are linking against OpenSSL 1.0.2, which is no longer supported by the OpenSSL project.
|
||||||
|
To use this version of cryptography you need to upgrade to a newer version of OpenSSL. For
|
||||||
|
this version only you can also set the environment variable
|
||||||
|
CRYPTOGRAPHY_ALLOW_OPENSSL_102 to allow OpenSSL 1.0.2.
|
||||||
|
```
|
||||||
|
|
||||||
|
这可能与架构有关,因为我无法在 CentOS 7 虚拟机中复现该错误。
|
||||||
|
|
||||||
|
部署时,将 `CRYPTOGRAPHY_ALLOW_OPENSSL_102` 导出为 `True`,这样 Ansible 就可以运行了。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ export CRYPTOGRAPHY_ALLOW_OPENSSL_102=True
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3、配置 ceph-ansible 进行部署
|
||||||
|
|
||||||
|
现在你可以使用 ceph-ansible 部署 Ceph 了。
|
||||||
|
|
||||||
|
复制 `site.yml.sample` 到 `site.yml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mv site.yml.sample site.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `group_vars` 目录下创建 `all.yml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat << EOF >> group_vars/all.yml
|
||||||
|
ceph_origin: repository
|
||||||
|
ceph_repository: community
|
||||||
|
ceph_repository_type: cdn
|
||||||
|
ceph_stable_release: nautilus
|
||||||
|
monitor_interface: wlan0
|
||||||
|
public_network: "192.168.100.0/24"
|
||||||
|
cluster_network: "192.168.100.0/24"
|
||||||
|
dashboard_enabled: false
|
||||||
|
configure_firewall: false
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `group_vars` 目录下创建 `osds.yml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat << EOF >> group_vars/all.yml
|
||||||
|
osd_scenario: collocated
|
||||||
|
devices:
|
||||||
|
- /dev/sda
|
||||||
|
- /dev/sdb
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
创建一个 `inventory` 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat << EOF >> inventory
|
||||||
|
[mons]
|
||||||
|
rpi4b4-0
|
||||||
|
|
||||||
|
[osds]
|
||||||
|
rpi4b4-1
|
||||||
|
rpi4b4-2
|
||||||
|
rpi4b4-3
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
在写这篇文章的时候,ceph-ansible 仓库里有一个 bug(根据这个 [bug 工单][9])。你可以通过编辑角色的第 85 行和第 86 行来减轻这个 bug。
|
||||||
|
|
||||||
|
```
|
||||||
|
- (wait_for_all_osds_up.stdout | from_json)["osdmap"]["num_osds"] | int > 0
|
||||||
|
- (wait_for_all_osds_up.stdout | from_json)["osdmap"]["num_osds"] == (wait_for_all_osds_up.stdout | from_json)["osdmap"]["num_up_osds"]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4、部署 Ceph
|
||||||
|
|
||||||
|
用你的 `inventory` 文件运行 Ansible 剧本:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible-playbook -i inventory site.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
15-20 分钟后,你应该看到这个结果:
|
||||||
|
|
||||||
|
![Ceph deployment][10]
|
||||||
|
|
||||||
|
### 下面的步骤
|
||||||
|
|
||||||
|
之前,我在另一个树莓派集群中[手动部署][11]了一个 OpenStack 集群。我希望能将其与这个集群整合在一起。我也在研究用 [TripleO][12] 部署。
|
||||||
|
|
||||||
|
树莓派、Ansible 和 OpenStack 的可能性是无穷的。开始做你自己的实验,并在评论中告诉我结果如何。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/ceph-raspberry-pi
|
||||||
|
|
||||||
|
作者:[AJ Canlas][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/ajscanlas
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberrypi_board_vector_red.png?itok=yaqYjYqI (Vector, generic Raspberry Pi board)
|
||||||
|
[2]: https://ceph.io/
|
||||||
|
[3]: https://opensource.com/business/15/1/introduction-ceph-storage-openstack
|
||||||
|
[4]: https://docs.ceph.com/projects/ceph-ansible/en/latest/index.html#
|
||||||
|
[5]: https://opensource.com/sites/default/files/uploads/architecture_0_0.png (Project architecture)
|
||||||
|
[6]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[7]: https://docs.ceph.com/en/latest/glossary/#term-Ceph-Monitor
|
||||||
|
[8]: https://docs.ceph.com/en/latest/glossary/#term-OSD
|
||||||
|
[9]: https://tracker.ceph.com/issues/43430
|
||||||
|
[10]: https://opensource.com/sites/default/files/uploads/ceph.png (Ceph deployment)
|
||||||
|
[11]: https://opensource.com/article/20/12/openstack-raspberry-pi
|
||||||
|
[12]: https://wiki.openstack.org/wiki/TripleO
|
@ -0,0 +1,78 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13033-1.html)
|
||||||
|
[#]: subject: (Improve your productivity with this lightweight Linux desktop)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/elementary-linux)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
ElementaryOS:使用这个轻量级 Linux 桌面提高你的工作效率
|
||||||
|
======
|
||||||
|
|
||||||
|
> ElementaryOS 提供了一个快速、轻量、高效的桌面,让你在新的一年里保持工作效率。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/19/235403miy29qe6rqvv2vl3.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列报道了各个应用程序。今年,我们将在 2021 年寻求帮助的策略之外,还将关注一站式解决方案。欢迎来到 2021 年 21 天生产力的第一天。
|
||||||
|
|
||||||
|
当寻求提高生产率的工具时,很容易将几乎能用但不能完全很好地发挥作用的应用集合在一起。在过去的几年里,我们已经谈到了单个的电子邮件应用、日历应用、记事本应用等等。不过,总会有些麻烦。要么需要自定义脚本,要么需要复杂的导出/导入步骤才能使一个工具工作。
|
||||||
|
|
||||||
|
[ElementaryOS][2] 是一个完整的桌面,具有美观、实用、高效的环境。
|
||||||
|
|
||||||
|
![Linux ElementaryOS Desktop][3]
|
||||||
|
|
||||||
|
*ElementaryOS 桌面 (Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
ElementaryOS 是一个基于流行的 Ubuntu Linux 发行版的“按需付费”开源项目。对于过去安装过 Ubuntu 的人来说,初始设置和安装会非常熟悉。然而,一旦登录,体验就会很不一样。
|
||||||
|
|
||||||
|
ElementaryOS 使用 [Gala 窗口管理器][5]和 Pantheon shell。这两个都是专门为 Elementary 开发的。安装后,桌面非常精简,它只提供了少量的轻量级应用。这些应用包括 Web 浏览器、终端、邮件客户端和日历客户端。它还有一个应用中心,允许你安装 Elementary 团队策划的免费和商业应用。
|
||||||
|
|
||||||
|
![Linux ElementaryOS Mail and calendar][6]
|
||||||
|
|
||||||
|
*ElementaryOS 的邮件和日历应用(Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
[邮件][7]和[日历][8]这两个应用看起来很熟悉,因为这两个应用已经被其他发行版使用了一段时间。邮件是作为 [Geary][9] 的复刻分支开始的,而日历在其他地方则被称为 [Maya][10]。两者的设置非常简单。两款应用默认仅使用用户名/密码认证,所以需要双因素认证的用户需要一些额外的步骤。两者的界面都异常轻巧快速。
|
||||||
|
|
||||||
|
![Linux ElementaryOS app center][11]
|
||||||
|
|
||||||
|
*应用中心(Kevin Sonney,[CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
ElementaryOS 默认不包含待办事项或记事本应用。这时,应用中心就可以发挥作用了。在应用中心中,有大量的应用可以填补空白。其中有两款应用真的很出色。第一个是 [Planner][12],一款简洁、轻量级的待办事项管理器。它支持多个列表、计划和重复性任务、项目和子项目。它还可以与流行的在线应用 [Todoist][13] 同步,但这不是必需的。
|
||||||
|
|
||||||
|
应用中心的第二款应用是 [Notes-Up][14],这是一款使用 Markdown 写富文本格式的笔记应用。它允许用户在多个笔记本中创建多个笔记,并且有“查看”和“编辑”选项,这样你就可以预览最终文档的样子。同样,这款应用快速、轻量而且非常简约,与 ElementaryOS 的整体外观和感觉保持一致。
|
||||||
|
|
||||||
|
![ElementaryOS Planner and Notes-up][15]
|
||||||
|
|
||||||
|
*Planner 和 Notes-up (Kevin Sonney,[CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
如果你不喜欢默认应用,Elementary 基于 Ubuntu LTS,因此如果你需要使用其他应用,整个 Ubuntu 应用生态系统都可以使用。不过总的来说,ElementaryOS 默认提供了一个快速、轻量、高效的桌面,让你在新的一年里保持高效。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/elementary-linux
|
||||||
|
|
||||||
|
作者:[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/lenovo-thinkpad-laptop-concentration-focus-windows-office.png?itok=-8E2ihcF (Woman using laptop concentrating)
|
||||||
|
[2]: https://elementary.io/
|
||||||
|
[3]: https://opensource.com/sites/default/files/pictures/elementaryos-desktop.png (ElementaryOS Desktop)
|
||||||
|
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[5]: https://github.com/elementary/gala
|
||||||
|
[6]: https://opensource.com/sites/default/files/pictures/elementaryos-mail-calendar.png (Linux ElementaryOS Mail and calendar)
|
||||||
|
[7]: https://github.com/elementary/mail
|
||||||
|
[8]: https://github.com/elementary/calendar
|
||||||
|
[9]: https://wiki.gnome.org/Apps/Geary
|
||||||
|
[10]: https://launchpad.net/maya
|
||||||
|
[11]: https://opensource.com/sites/default/files/pictures/elementaryos-app-center_0.png (Linux ElementaryOS app center)
|
||||||
|
[12]: https://appcenter.elementary.io/com.github.alainm23.planner/
|
||||||
|
[13]: https://todoist.com/
|
||||||
|
[14]: https://github.com/Philip-Scott/Notes-up
|
||||||
|
[15]: https://opensource.com/sites/default/files/pictures/planner-notes-up.png (ElementaryOS Planner and Notes-up)
|
@ -0,0 +1,59 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13044-1.html)
|
||||||
|
[#]: subject: (3 email rules to live by in 2021)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/email-rules)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
2021 年要遵守的 3 条电子邮件规则
|
||||||
|
======
|
||||||
|
|
||||||
|
> 电子邮件不是即时通讯。通过遵循这些规则来防止电子邮件不断地打断你的工作。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/23/141931hsgz7762jn960nmh.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个应用程序。今年,我们除了关注有助于 2021 年的策略外,还将关注一体化解决方案。欢迎来到“2021 年 21 天生产力”的第二天。
|
||||||
|
|
||||||
|
和许多人一样,我对电子邮件也是爱恨交加。电子邮件是早期互联网、企业局域网和拨号 BBS 生态系统中最早的通信手段之一。电子邮件过去是、现在仍然是电子通信的主要手段之一。它被用于商业通信、商务、通知、协作和一堆有用的东西。
|
||||||
|
|
||||||
|
![Mutt 电子邮件客户端][2]
|
||||||
|
|
||||||
|
*Mutt 邮件客户端, [CC BY-SA 4.0][3] by Kevin Sonney*
|
||||||
|
|
||||||
|
很多人对电子邮件有着不正确的认识。电子邮件不是一个即时通讯平台。有时候,当一个人发送一条信息,几乎立刻就会出现在世界的另一端,然后在几分钟内就会有回应,这看起来就像是电子邮件是即时通讯。正因为如此,我们可能会陷入一种思维定势,即我们需要随时激活电子邮件程序,一旦有东西进来,我们需要马上看一下,然后马上回复。
|
||||||
|
|
||||||
|
电子邮件的设计原则是:一个人发送一条信息,收件人会在方便的时候回复。是的,有高优先级和紧急邮件的标志,我们的电子邮件程序也有通知来告诉我们新邮件何时到达,但它们真的不是为了给今天的许多人造成压力。
|
||||||
|
|
||||||
|
![太多的电子邮件][4]
|
||||||
|
|
||||||
|
*太!多!电子邮件了! [CC BY-SA 4.0][3] by Kevin Sonney*
|
||||||
|
|
||||||
|
一般说来,一个人每受到一次干扰,至少需要 15 分钟的时间让他们的思维过程重新集中到被打断的任务上。在工作场所(以及在家里!),电子邮件成为了这些中断之一已经是一种普遍现象。它不需要这样,也不是设计成这样的。我采用了一些规则来防止电子邮件成为让我无法完成任务的干扰。
|
||||||
|
|
||||||
|
**规则 1**:电子邮件不是一个警报平台。在技术领域,人们通常会配置监控和警报平台,将所有的通知发送到电子邮件。在过去的 15 年里,我几乎在每一个工作场所都遇到过这种情况,我会先花了几个月的时间来改变它。有很多好的平台和服务来管理警报。电子邮件不是其中之一。
|
||||||
|
|
||||||
|
**规则 2**:至少不要指望在 24 小时内得到答复。我们有多少人接到过电话,问我们是否收到电子邮件,并问我们是否有任何问题?我就遇到过。尽量在工作场所或与你经常发邮件的人设定一个期望值,回复有时会很快,有时不会。如果事情真的很紧急,他们应该使用其他的沟通方式。
|
||||||
|
|
||||||
|
**规则 3**:每隔几个小时检查一次电子邮件,而不是不断地检查。我承认这一条很难,但它能给我带来最安心的感觉。当我在工作或试图专注于写作等事情时,我会关闭我的电子邮件程序(或浏览器标签),并忽略它,直到我完成。没有通知,没有 20 条新邮件正在等待的指示,没有干扰。当我开始这样做的时候,我花了一些努力来克服我的 FOMO(害怕错过),但随着时间的推移,这已经变得容易了。我发现,当我再次打开我的电子邮件时,我可以专注于它,而不是担心我可以做什么,或应该做什么来代替。
|
||||||
|
|
||||||
|
希望这三条规则能像帮助我一样帮助你。在接下来的日子里,我会有更多可以帮助我处理电子邮件的方法分享给你。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/email-rules
|
||||||
|
|
||||||
|
作者:[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/newsletter_email_mail_web_browser.jpg?itok=Lo91H9UH (email or newsletters via inbox and browser)
|
||||||
|
[2]: https://opensource.com/sites/default/files/pictures/mutt-email-client.png (Mutt email client)
|
||||||
|
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[4]: https://opensource.com/sites/default/files/pictures/so-many-emails.png (So many emails)
|
@ -0,0 +1,104 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13067-1.html)
|
||||||
|
[#]: subject: (Super Productivity: A Super Cool Open Source To-Do List App with GitHub Integration)
|
||||||
|
[#]: via: (https://itsfoss.com/super-productivity/)
|
||||||
|
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||||
|
|
||||||
|
超级生产力:一款集成了 GitHub 的超酷开源待办事项列表应用
|
||||||
|
======
|
||||||
|
|
||||||
|
> “超级生产力”是一款很棒的开源待办事项应用,可以帮助你管理任务、跟踪事务和管理时间。
|
||||||
|
|
||||||
|
无论你做什么,提高工作效率是大多数人的共同目标。通常,你总会尝试各种[待办事项列表应用][1]或者[记事应用][2]来帮助自己组织和提醒事情,从而高效地跟上工作进度。
|
||||||
|
|
||||||
|
当然,你可以看看那些清单,根据自己的喜好去尝试其中的一些。在这里,我遇到了一些独特的东西,如果你想要一个具有可靠的用户界面、GitHub/GitLab 集成以及一系列基本功能的桌面待办事项应用,你也许可以尝试一下。
|
||||||
|
|
||||||
|
<ruby>超级生产力<rt>Super Productivity</rt></ruby>看起来是一个令人印象深刻的待办事项列表应用,并提供一些独特的功能。在本文中,我将让你简单了解它的一切。
|
||||||
|
|
||||||
|
### 超级生产力:一个简单的而有吸引力的开源待办事项应用程序
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
“超级生产力”是一款开源应用,它由 [Johannes Millan][4] 在 GitHub 上积极维护。
|
||||||
|
|
||||||
|
对我来说,用户体验是最重要的,“超级生产力”提供的用户界面给我留下了十分深刻的印象。
|
||||||
|
|
||||||
|
它还提供了一堆基本功能以及一些有趣的选项。让我们来看看它们。
|
||||||
|
|
||||||
|
### “超级生产力”的功能
|
||||||
|
|
||||||
|
![][5]
|
||||||
|
|
||||||
|
* 添加待办事项、说明
|
||||||
|
* 追踪花费在任务和休息上的时间
|
||||||
|
* 项目管理(与 JIRA、GitHub 和 GitLab 整合)
|
||||||
|
* 安排任务的能力
|
||||||
|
* 语言选择选项
|
||||||
|
* 同步到 Dropbox、Google Drive 或任何其他 WebDAV 存储位置
|
||||||
|
* 导入/导出功能
|
||||||
|
* 自动备份功能
|
||||||
|
* 能够调整定时器和计数器的行为
|
||||||
|
* 黑暗模式
|
||||||
|
* 在任务中添加附件
|
||||||
|
* 完全免费的重复任务
|
||||||
|
* 跨平台支持
|
||||||
|
|
||||||
|
除了我提到的功能外,你还会发现更多详细的设置和调整配置。
|
||||||
|
|
||||||
|
尤其是与 [JIRA][6]、[GitHub][7] 和 [GitLab][8] 的整合。你可以自动分配要进行的工作任务,而不需要检查你的电子邮件以了解问题跟踪器或议题的最近更新。
|
||||||
|
|
||||||
|
与我目前使用过的许多收费版的待办事项 Web 服务相比,你会惊讶地发现许多有用的功能完全免费。
|
||||||
|
|
||||||
|
### 在 Linux 上安装“超级生产力”
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
它有各种安装方式。我下载了 AppImage 文件测试了一下。但是,你也可以得到基于 Debian 的发行版的 deb 包。
|
||||||
|
|
||||||
|
它也可以作为一个 [snap][10] 来安装。你可以在 [GitHub 的发布部分][11]中找到所有的包。
|
||||||
|
|
||||||
|
如果你感兴趣,可以查看它的 [GitHub 页面][12]来了解它的更多信息。
|
||||||
|
|
||||||
|
- [下载超级生产力](https://github.com/johannesjo/super-productivity/releases)
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
我发现“超级生产力”的用户体验非常棒。所提供的功能非常有用,考虑到你可以获得一些你通常从收费版的待办事项 Web 服务中才能获得的高级功能,它可以成为大多数用户的完美替代品。
|
||||||
|
|
||||||
|
你可以简单地使用 Google Drive、Dropbox 或任何其他 WebDAV 存储位置同步数据。
|
||||||
|
|
||||||
|
它也可以取代像 [ActivityWatch][13] 这样的服务,帮助你追踪你工作任务和保持闲置的时间。所以,它可以成为你提高生产力的一体化解决方案!
|
||||||
|
|
||||||
|
听起来很不错,对吧?
|
||||||
|
|
||||||
|
你对“超级生产力”有什么看法?请在下面的评论区告诉我你的想法。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/super-productivity/
|
||||||
|
|
||||||
|
作者:[Ankush Das][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/ankush/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://itsfoss.com/to-do-list-apps-linux/
|
||||||
|
[2]: https://itsfoss.com/note-taking-apps-linux/
|
||||||
|
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/super-productivity.jpg?resize=800%2C569&ssl=1
|
||||||
|
[4]: https://github.com/johannesjo
|
||||||
|
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/super-productivity-2.jpg?resize=800%2C575&ssl=1
|
||||||
|
[6]: https://www.atlassian.com/software/jira
|
||||||
|
[7]: https://github.com/
|
||||||
|
[8]: https://about.gitlab.com
|
||||||
|
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/super-productivity-1.jpg?resize=800%2C574&ssl=1
|
||||||
|
[10]: https://snapcraft.io/superproductivity
|
||||||
|
[11]: https://github.com/johannesjo/super-productivity/releases
|
||||||
|
[12]: https://github.com/johannesjo/super-productivity
|
||||||
|
[13]: https://itsfoss.com/activitywatch/
|
@ -0,0 +1,160 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13036-1.html)
|
||||||
|
[#]: subject: (How to get Battery status notification when a battery is full or low)
|
||||||
|
[#]: via: (https://www.2daygeek.com/linux-low-full-charge-discharge-battery-notification/)
|
||||||
|
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||||
|
|
||||||
|
如何在电池充满或低电量时获得电池状态通知
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/20/231310avo3kzv67vkm3tz7.jpg)
|
||||||
|
|
||||||
|
对于类 Unix 用户来说,Linux 笔记本是不错的选择,但它经常会耗尽电池。我试过很多 Linux 操作系统,但没有像 Windows 那样电池寿命长。
|
||||||
|
|
||||||
|
充电时间长了会对电池造成损害,所以在电池 100% 充满时要拔掉电源线。电池充电或放电时没有默认的应用程序来通知,需要安装第三方应用来通知你。
|
||||||
|
|
||||||
|
为此,我通常会安装 [Battery Monitor][1],但它已经被废弃,所以我创建了一个 shell 脚本来获取通知。
|
||||||
|
|
||||||
|
笔记本电池充放电状态可以通过以下两个命令来识别。
|
||||||
|
|
||||||
|
使用 `acpi` 命令。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ acpi -b
|
||||||
|
Battery 0: Discharging, 71%, 00:58:39 remaining
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `upower` 命令。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -w 'state|percentage' | awk '{print $2}'
|
||||||
|
discharging
|
||||||
|
64%
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方法 1:当电池电量高于 95% 或低于 20% 时,用 Shell 脚本发送警报
|
||||||
|
|
||||||
|
这个脚本在启动时在后台运行,每分钟检查一次电池状态,然后在电池电量超过 95% 或放电时电量低于 20% 时发送通知。
|
||||||
|
|
||||||
|
警报会直到你的电池电量超过 20% 或低于 95% 时才会停止。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo vi /opt/scripts/battery-status.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
battery_level=`acpi -b | grep -P -o '[0-9]+(?=%)'`
|
||||||
|
if [ $battery_level -ge 95 ]; then
|
||||||
|
notify-send "Battery Full" "Level: ${battery_level}%"
|
||||||
|
paplay /usr/share/sounds/freedesktop/stereo/suspend-error.oga
|
||||||
|
elif [ $battery_level -le 20 ]; then
|
||||||
|
notify-send --urgency=CRITICAL "Battery Low" "Level: ${battery_level}%"
|
||||||
|
paplay /usr/share/sounds/freedesktop/stereo/suspend-error.oga
|
||||||
|
fi
|
||||||
|
sleep 60
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本完成后,设置可执行权限:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo chmod +x /opt/scripts/battery-status.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
最后,将该脚本添加到用户配置文件的底部。对于全局范围来说,你需要在 `/etc/profile` 文件中添加该脚本。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ vi /home/magi/.profile
|
||||||
|
|
||||||
|
/opt/scripts/battery-status.sh &
|
||||||
|
```
|
||||||
|
|
||||||
|
[重启你的 Linux 系统][2]来检查这点。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方法 2:当电池充电(高于 95%)或放电(低于 20%)时发送通知的 Shell 脚本
|
||||||
|
|
||||||
|
这个脚本与上面的脚本类似,但它是由交流适配器负责。
|
||||||
|
|
||||||
|
如果你插上了交流适配器,而且电池的电量超过 95%,它就会发出一个带有声音的通知,但是这个通知不会停止,直到你拔掉交流适配器。
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
如果你拔掉交流适配器,你将永远不会再看到通知,直到你的电池电量下降到 20%。
|
||||||
|
|
||||||
|
![][5]
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo vi /opt/scripts/battery-status-1.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
export DISPLAY=:0.0
|
||||||
|
battery_level=`acpi -b | grep -P -o '[0-9]+(?=%)'`
|
||||||
|
if on_ac_power; then
|
||||||
|
if [ $battery_level -ge 95 ]; then
|
||||||
|
notify-send "Battery Full" "Level: ${battery_level}% "
|
||||||
|
paplay /usr/share/sounds/freedesktop/stereo/suspend-error.oga
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ $battery_level -le 20 ]; then
|
||||||
|
notify-send --urgency=CRITICAL "Battery Low" "Level: ${battery_level}%"
|
||||||
|
paplay /usr/share/sounds/freedesktop/stereo/suspend-error.oga
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
sleep 60
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本完成后,设置执行权限:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo chmod +x /opt/scripts/battery-status-1.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
最后将脚本添加到用户配置文件的底部。对于全局范围来说,你需要在 `/etc/profile` 文件中添加该脚本。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ vi /home/magi/.profile
|
||||||
|
|
||||||
|
/opt/scripts/battery-status-1.sh &
|
||||||
|
```
|
||||||
|
|
||||||
|
重启系统来检查:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
参考: [stackexchange][4]
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.2daygeek.com/linux-low-full-charge-discharge-battery-notification/
|
||||||
|
|
||||||
|
作者:[Magesh Maruthamuthu][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[geekpi](https://github.com/geekpi)
|
||||||
|
校对:[校对者ID](https://github.com/校对者ID)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.2daygeek.com/author/magesh/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.2daygeek.com/category/battery-monitor/
|
||||||
|
[2]: https://www.2daygeek.com/6-commands-to-shutdown-halt-poweroff-reboot-the-linux-system/
|
||||||
|
[3]: https://i0.wp.com/www.2daygeek.com/wp-content/uploads/2021/01/linux-low-full-battery-notification-2.png?w=1046&ssl=1
|
||||||
|
[4]: https://unix.stackexchange.com/questions/60778/how-can-i-get-an-alert-when-my-battery-is-about-to-die-in-linux-mint
|
||||||
|
[5]: https://i1.wp.com/www.2daygeek.com/wp-content/uploads/2021/01/linux-low-full-battery-notification-3.png?w=1029&ssl=1
|
78
published/202101/20210115 3 plain text note-taking tools.md
Normal file
78
published/202101/20210115 3 plain text note-taking tools.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13056-1.html)
|
||||||
|
[#]: subject: (3 plain text note-taking tools)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/plain-text)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
3 个纯文本记事工具
|
||||||
|
======
|
||||||
|
|
||||||
|
> 记笔记很重要,而纯文本是一种简单、中性的方式。这里有三个工具,你可以在不失去纯文本的简易和便携性的前提下,给你的笔记加点东西。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/27/153329o0waw16448hq0avf.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第五天。
|
||||||
|
|
||||||
|
纯文本是最具弹性的文档格式。纯文本文档体积小,可以在机器之间快速传输,并且可以在*任意*设备上阅读。因此,在纯文本文档中做笔记是很有意义的。
|
||||||
|
|
||||||
|
然而,纯文本也仅是纯文本。我们生活在一个富文本世界中,我们仍然需要标题、列表以及区分一个章节和另一个章节的方法。幸运的是,我们有几种方法可以添加这些元素,而不需要在纯文本文档中添加复杂的标记。
|
||||||
|
|
||||||
|
### Markdown
|
||||||
|
|
||||||
|
![Markdown][2]
|
||||||
|
|
||||||
|
*Markdown (Kevin Sonney, [CC BY-SA 4.0][3])*
|
||||||
|
|
||||||
|
由 Aaron Schwartz 和 John Gruber 创建的 [Markdown][4],是我如今每天使用最多的格式。从读写 README 文件、文档、记笔记,甚至源代码注释,Markdown 让我可以在不牺牲轻松阅读文档的能力的情况下添加格式。
|
||||||
|
|
||||||
|
此外,Markdown 还有几个“扩展版本”,以允许那些不属于原始设计的项目。特别是,[GitHub 风格的 Markdown][5] 由于其在同名的源码控制网站中的使用而异常流行。
|
||||||
|
|
||||||
|
许多文件编辑器都支持 Markdown 高亮显示,不需要额外的附加组件或工作。
|
||||||
|
|
||||||
|
### AsciiDoc
|
||||||
|
|
||||||
|
![AsciiDoc][6]
|
||||||
|
|
||||||
|
*AsciiDoc (Kevin Sonney, [CC BY-SA 4.0][3])*
|
||||||
|
|
||||||
|
由 Stuart Rackham 创建的 [AsciiDoc][7] 是向纯文本文档添加富文本元素的另一种方式。AsciiDoc 有许多生成文档、书籍和论文的功能。然而,这并不意味着它不能被用来做笔记。有很多环境(特别是在教育和研究领域),能够快速将笔记转换为更“正式”的格式是很有帮助的。
|
||||||
|
|
||||||
|
AsciiDoc 也有很多工具可以将文本转换为其他格式进行协作。还有一些附加组件可以从不同的源导入数据,并将其放入最终的文档中,或者处理特殊的格式,如 MathML 或 LaTeX。
|
||||||
|
|
||||||
|
### Org 模式
|
||||||
|
|
||||||
|
![ORG-Mode][8]
|
||||||
|
|
||||||
|
*ORG-Mode (Kevin Sonney, [CC BY-SA 4.0][3])*
|
||||||
|
|
||||||
|
说到文本格式,我不能不提 [Org 模式][9]。它最初是为 [GNU Emacs][10] 设计的,现在已经成为笔记、待办事项、文档等常用的纯文本格式之一。Org 模式可以在包括 [Vim][11] 在内的众多文本编辑器中编写和使用。Org 模式简单、易学,是我最喜欢的笔记文本格式之一。
|
||||||
|
|
||||||
|
最后,选择 Markdown、AsciiDoc 或 Org 模式作为纯文本笔记,是确保它们可以在任何地方被阅读和更新的一种方式。如果你和我一样,你会发现自己在做纸质笔记的时候,也会使用同样的语法!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/plain-text
|
||||||
|
|
||||||
|
作者:[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/typewriter-hands.jpg?itok=oPugBzgv (Typewriter with hands)
|
||||||
|
[2]: https://opensource.com/sites/default/files/pictures/markdown.png (Markdown)
|
||||||
|
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[4]: https://opensource.com/article/19/9/introduction-markdown
|
||||||
|
[5]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown
|
||||||
|
[6]: https://opensource.com/sites/default/files/pictures/asciidoc.png (AsciiDoc)
|
||||||
|
[7]: https://asciidoc.org/
|
||||||
|
[8]: https://opensource.com/sites/default/files/pictures/org-mode.png (ORG-Mode)
|
||||||
|
[9]: https://orgmode.org/
|
||||||
|
[10]: https://www.gnu.org/software/emacs/
|
||||||
|
[11]: https://opensource.com/article/19/1/productivity-tool-org-mode
|
@ -0,0 +1,76 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13059-1.html)
|
||||||
|
[#]: subject: (How to use KDE's productivity suite, Kontact)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/kde-kontact)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
如何使用 KDE 的生产力套件 Kontact
|
||||||
|
======
|
||||||
|
|
||||||
|
> KDE 很棒,但当你使用这个统一个人信息管理器 Kontact 时,它才真正发挥了作用。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/28/094146fyx79l7zwbwej7ym.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第六天。
|
||||||
|
|
||||||
|
在很久很久以前,当编译内核还是获取 WiFi 驱动的唯一途径时,图形环境主要是用来运行网页浏览器和打开大量终端窗口。其外观和感觉是由程序作者选择使用的各种工具箱组成的大杂烩。然后,在 1996 年 [Matthias Ettrich][2] 提出并随后发布了第一个版本的 [KDE][3]。它是基于当时专有的 [Qt][4] 工具箱(后来成为自由而开源的)。这个版本引发了 Linux 上的桌面革命,同一时期出现的还有使用当时的自由开源软件 GTK 工具包所创建的 [GNOME 桌面][5] 。不管是 KDE 还是 GNOME,Linux 从一个*只有电脑操作人员使用的 Linux 操作系统*变成了一个人人都能使用的强大桌面环境。
|
||||||
|
|
||||||
|
![Fedora KDE Spin Default Desktop][6]
|
||||||
|
|
||||||
|
*Fedora KDE 版的默认桌面 (Kevin Sonney, [CC BY-SA 4.0][7])*
|
||||||
|
|
||||||
|
KDE Plasma 5 是最新的 KDE 版本,它的功能非常丰富,可以提高你的工作效率。它包括了 Konqueror 网页浏览器、Dolphin 文件管理器和 Konsole 终端模拟器,所有这些都为这个桌面环境提供了一个很好的坚实基础,但是 KDE 真正提高生产力的方法是这个统一个人信息管理器:[Kontact][8]。
|
||||||
|
|
||||||
|
Kontact 为其他几个 KDE 程序提供了一个单一的界面,包括:KMail(电子邮件)、KOrganizer(日历、待办事项和日记)、KAddressBook(地址簿)、KNotes(笔记)、Akregator(RSS/ATOM 订阅阅读器)等。第一次启动时,Kontact 会引导你完成电子邮件提供商的设置,它支持本地和远程邮件配置。然后,Kontact 会进入一个仪表板,默认情况下,该仪表板会显示最近的电子邮件、日历事件、计划任务和最近的笔记。
|
||||||
|
|
||||||
|
![Kontact Summary screen][9]
|
||||||
|
|
||||||
|
*Kontact 概览页面 (Kevin Sonney, [CC BY-SA 4.0][7])*
|
||||||
|
|
||||||
|
设置“流程”看起来有点奇怪,因为在内置的本地账户之外没有配置统一的单一账户。在 Kontact(通过 KMail)引导你完成邮件设置后,你就可以进入日历页面添加你的日历,这里也配置了待办事项和日记应用(对于某些提供商,还可以配置通讯录)。
|
||||||
|
|
||||||
|
邮件和日历组件非常简单明了,可以如你期望地正常工作。待办事项页面和日记是与日历绑定的,这对于一些不完全支持所有日历类型的日历提供商来说可能是个问题(Google,我说的是你)。如果你使用的是这些提供商中的一个,你将需要为日记和待办事项创建一个特定的本地日历。
|
||||||
|
|
||||||
|
![Kontact Calendar][10]
|
||||||
|
|
||||||
|
*Kontact Calendar (Kevin Sonney, [CC BY-SA 4.0][7])*
|
||||||
|
|
||||||
|
待办事项列表有很多功能。虽然它可以作为一个简单的任务清单与提醒,它也支持一些轻量级的项目管理功能。它有一个完成百分比的滑块,可以从主列表视图中更新,这样你就可以跟踪进度。它能够附加文件和分配 1-10 的优先级。最后,它可以像其他日历约会一样将用户添加到任务中。
|
||||||
|
|
||||||
|
创建一个日记条目本质上是在日历上给自己创建一个笔记。它是一段形式自由的文本,就像写在实体笔记本和计划手册的某一天上那样。如果你要记录工作,写下每天的日记,或只是需要个地方记录会议记录,这个功能是非常*方便*的(本系列后面有更多关于这个的内容)。
|
||||||
|
|
||||||
|
![Kontact Journal][11]
|
||||||
|
|
||||||
|
*Kontact Journal (Kevin Sonney, [CC BY-SA 4.0][7])*
|
||||||
|
|
||||||
|
构成 Kontact 的这些程序非常强大,如果你愿意的话,也可以作为单独的应用运行。Kontact 通过给你提供一个集中的地方,在一个应用内找到你所有的信息,从而提升了它们的实用性。
|
||||||
|
|
||||||
|
大多数发行版都允许你在没有 KDE 的情况下安装 Kontact 和它所使用的组件,但当它作为 KDE 桌面的一部分使用时,它才会真正发挥其作用。KDE 在 Fedora KDE 版、KUbuntu、KDE Neon(基于 Ubuntu LTS)和其他几个发行版中都是默认桌面。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/kde-kontact
|
||||||
|
|
||||||
|
作者:[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/team_dev_email_chat_video_work_wfm_desk_520.png?itok=6YtME4Hj (Working on a team, busy worklife)
|
||||||
|
[2]: https://en.wikipedia.org/wiki/Matthias_Ettrich
|
||||||
|
[3]: https://kde.org/
|
||||||
|
[4]: https://en.wikipedia.org/wiki/Qt_(software)
|
||||||
|
[5]: https://www.gnome.org/
|
||||||
|
[6]: https://opensource.com/sites/default/files/pictures/fedora-kde-spin-default-desktop.png (Fedora KDE Spin Default Desktop)
|
||||||
|
[7]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[8]: https://kontact.kde.org/
|
||||||
|
[9]: https://opensource.com/sites/default/files/pictures/kontact-summary-screen_0.png (Kontact Summary screen)
|
||||||
|
[10]: https://opensource.com/sites/default/files/pictures/kontact-calendar.png (Kontact Calendar)
|
||||||
|
[11]: https://opensource.com/sites/default/files/pictures/kontact-journal.png (Kontact Journal)
|
@ -0,0 +1,92 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13050-1.html)
|
||||||
|
[#]: subject: (Haruna Video Player: An Open-Source Qt-based MPV GUI Front-end for Linux)
|
||||||
|
[#]: via: (https://itsfoss.com/haruna-video-player/)
|
||||||
|
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||||
|
|
||||||
|
Haruna 视频播放器:一个 MPV GUI 前端
|
||||||
|
======
|
||||||
|
|
||||||
|
> 一个基于 Qt 的 Linux 视频播放器,它可作为 mpv 的前端,并能使用 youtube-dl。
|
||||||
|
|
||||||
|
### Haruna 视频播放器:一个基于 Qt 的免费视频播放器
|
||||||
|
|
||||||
|
![Haruna Video Player][1]
|
||||||
|
|
||||||
|
如果你还不知道 [mpv][2],它是一个基于命令行的自由开源的媒体播放器。好吧,它有一个[简约的 MPV GUI][3],但核心是命令行。
|
||||||
|
|
||||||
|
你可能还会找到几个[开源视频播放器][4],它们基本上就是 mpv 的 GUI 前端。
|
||||||
|
|
||||||
|
Haruna 视频播放器就是其中之一,同时还可以[使用 youtube-dl][5]。你可以轻松播放本地媒体文件以及 YouTube 内容。
|
||||||
|
|
||||||
|
让我给你介绍一下这个播放器提供的功能。
|
||||||
|
|
||||||
|
### Haruna 视频播放器的功能
|
||||||
|
|
||||||
|
![][6]
|
||||||
|
|
||||||
|
你可能会发现它与其他一些视频播放器有些不同。以下是你可以从 Haruna 视频播放器 获得的:
|
||||||
|
|
||||||
|
* 能够直接使用 URL 播放 YouTube 视频
|
||||||
|
* 支持播放列表,并且你可以轻松控制它们
|
||||||
|
* 能够根据字幕中的某些词语自动跳过
|
||||||
|
* 控制播放速度
|
||||||
|
* 使用 [youtube-dl][7] 改变播放格式(音频/视频)
|
||||||
|
* 大量的键盘快捷键
|
||||||
|
* 轻松地从视频中截屏
|
||||||
|
* 添加主要和次要字幕的选项
|
||||||
|
* 改变截图的文件格式
|
||||||
|
* 支持硬件解码
|
||||||
|
* 色彩调整以提高你的观看质量。
|
||||||
|
* 能够调整鼠标和键盘的快捷键,以便能够快速浏览和做你想做的事情
|
||||||
|
* 调整 UI(字体、主题)
|
||||||
|
|
||||||
|
### 在 Linux 上安装 Haruna 视频播放器
|
||||||
|
|
||||||
|
![][8]
|
||||||
|
|
||||||
|
不幸的是(或者不是,取决于你的偏好),你只能[使用 Flatpak][9] 安装它。你可以使用 [Flatpak 包][10]在任何 Linux 发行版上安装它。
|
||||||
|
|
||||||
|
如果你使用的是基于 Arch 的系统,你也可以在 [AUR][11] 中找到它。
|
||||||
|
|
||||||
|
但是,如果你不喜欢这样,你可以查看 [GitHub][12] 上的源代码,看看你是否可以像普通的 Gentoo 用户一样自己构建它。
|
||||||
|
|
||||||
|
- [Haruna 视频播放器][12]
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
Haruna 视频播放器是一款简单实用的在 [libmpv][13] 之上的 GUI。能够在系统上播放 YouTube 视频以及各种文件格式绝对是很多用户所希望的。
|
||||||
|
|
||||||
|
用户界面很容易上手,它也提供了一些重要的自定义选项。
|
||||||
|
|
||||||
|
你尝试过这款视频播放器了吗?在下面的评论中让我知道你对它的看法。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/haruna-video-player/
|
||||||
|
|
||||||
|
作者:[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/2021/01/haruna-video-player-dark.jpg?resize=800%2C512&ssl=1
|
||||||
|
[2]: https://mpv.io/
|
||||||
|
[3]: https://itsfoss.com/mpv-video-player/
|
||||||
|
[4]: https://itsfoss.com/video-players-linux/
|
||||||
|
[5]: https://itsfoss.com/download-youtube-linux/
|
||||||
|
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/haruna-video-player-1.png?resize=800%2C503&ssl=1
|
||||||
|
[7]: https://github.com/ytdl-org/youtube-dl
|
||||||
|
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/haruna-player-garuda-linux.png?resize=800%2C506&ssl=1
|
||||||
|
[9]: https://itsfoss.com/flatpak-guide/
|
||||||
|
[10]: https://flathub.org/apps/details/com.georgefb.haruna
|
||||||
|
[11]: https://itsfoss.com/aur-arch-linux/
|
||||||
|
[12]: https://github.com/g-fb/haruna
|
||||||
|
[13]: https://github.com/mpv-player/mpv/tree/master/libmpv
|
@ -0,0 +1,70 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13062-1.html)
|
||||||
|
[#]: subject: (Organize your task list using labels)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/labels)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
使用标签组织你的任务列表
|
||||||
|
======
|
||||||
|
|
||||||
|
> 文件夹的用途是存储信息和任务。使用标签来帮助你更好地组织这些文件夹中的内容。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/29/150011k9sz3n0q99mmkems.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列报道了诸如 Notmuch 和 Syncthing 之类的开源的组织应用程序。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第九天。
|
||||||
|
|
||||||
|
我用我的电子邮件、待办列表和笔记来做这件事,有一天我决定我要把这些“组织起来”,重新安排我保存东西的方式和位置。有时我发现了一个新的程序,我必须(再次)从头开始配置。有时,当前的方法已经花了很多时间,与我使用系统的时间相比,我花了更多的时间在保持存储顺序最新。我去年测试一些待办列表软件时,最后一个软件让我有了一个非常重要的认识。
|
||||||
|
|
||||||
|
![List of labels][4]
|
||||||
|
|
||||||
|
*所有事情都有存放的地方(Kevin Sonney, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
让我打个比方。一个任务(或电子邮件或笔记)就像你在一次活动中收到的那件很酷的 T 恤。它是黑色的,有一个很棒的图案,后面有一个标签,上面写着尺寸,领口有一个标签,上面写着洗涤说明。到了该收起来的时候,它该放在哪里呢?是和黑色的 T 恤放在一起吗?是和类似主题的衬衫放在一起吗?是按尺码放吗?是按需要洗涤的方式?还是按材质?
|
||||||
|
|
||||||
|
一件 T 恤只能放在*一*个地方,即使它可以有多种特质。我们需要以同样的方式对待任务、电子邮件和笔记。大型[电子邮件提供商][6]已经允许我们把一个标签当作一个文件夹。一封邮件(或一个文档或一个任务)可以同时在两个文件夹中!或者三个!甚至 11 个!
|
||||||
|
|
||||||
|
![Guitar volume 11][7]
|
||||||
|
|
||||||
|
*它高达 11 个(Seth Kenlon, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
我必须明智地决定不再这样做。文件夹不是标签,标签也不是文件夹。这让我找到了我目前整理待办事项清单(和笔记,以及电子邮件)的规则:
|
||||||
|
|
||||||
|
1. 一个任务只应该在一个文件夹里。文件夹是以“大事”来命名的,比如一个地方或组织。我目前有三个文件夹来存放任务。“工作”、“家庭”和 “爱好”。当我专注于其中一个领域时,我知道我在看什么任务。
|
||||||
|
2. 一个任务可以有任意个我需要的标签。我尽量保持在三个左右或更少。
|
||||||
|
3. 一个任务应该有一个明确的意义。也许是你要写的程序的名字。也许是一些通用的东西,比如“要读的书”或“账单”。但如果你记不起 “4rg8sn5” 就是“要支付的账单”,这就对你没有帮助。
|
||||||
|
|
||||||
|
利用这些规则,如果我有一个“写第 9 天文章”的任务,它就会进入”爱好“文件夹,我给它打上 “OSDC”、“文章”、“2021” 的标签。如果我想在我的 [Elementary Planner][8] 中看到我所有的 2021 年的任务,我可以搜索这个标签。任务最终会出现在 “OSDC” 的搜索中,其中可能还包括一个对文章发表评论的待办事项,一个开始规划 2022 年系列的待办事项,还有一个跟进我认为有好文章想法的人。
|
||||||
|
|
||||||
|
我的“工作”文件夹里的东西通常是按项目标记的。“完成管理 CLI 文档”可能会被分为 “github”、“prod” 和 “admin”。“docs” 标签包含了“工作”和”爱好“文件夹中的项目,因为写文档是这两个文件夹都需要做的事情。
|
||||||
|
|
||||||
|
![Linux Elementary planner][9]
|
||||||
|
|
||||||
|
*文件夹和标签(Kevin Sonney, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
将“标签”和“文件夹”进行心理分离,帮助我将任务进行分组和分类,而不至于过度。这也意味着我可以更快地找到事情,花更少的时间去维护我的待办事项清单,而花更多的时间去做清单上的事情。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/labels
|
||||||
|
|
||||||
|
作者:[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/kanban_trello_organize_teams_520.png?itok=ObNjCpxt (Kanban-style organization action)
|
||||||
|
[2]: https://opensource.com/article/20/1/organize-email-notmuch
|
||||||
|
[3]: https://opensource.com/article/20/1/sync-files-syncthing
|
||||||
|
[4]: https://opensource.com/sites/default/files/pictures/day9-image1.png (List of labels)
|
||||||
|
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[6]: https://opensource.com/alternatives/gmail
|
||||||
|
[7]: https://opensource.com/sites/default/files/pictures/guitar-11.jpg (Guitar volume 11)
|
||||||
|
[8]: https://opensource.com/article/21/1/elementary-linux
|
||||||
|
[9]: https://opensource.com/sites/default/files/pictures/elementary-planner.png (Linux Elementary planner)
|
@ -0,0 +1,70 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13070-1.html)
|
||||||
|
[#]: subject: (Why keeping a journal improves productivity)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/open-source-journal)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
为什么写日记能提高效率
|
||||||
|
======
|
||||||
|
|
||||||
|
> 写日记有着悠久的历史。这里有三个开源工具,可以帮助你写日记变得更轻松。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/31/082622p6wgh7szzuvevug4.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第十天。
|
||||||
|
|
||||||
|
在我的小学时代,商业互联网还没有出现,老师经常会给我们班级布置一个让我们写日记的作业。有时会针对一些特定的内容,例如特定格式的虫子列表和说明,或者是公民课的每周新闻摘要。
|
||||||
|
|
||||||
|
几个世纪以来,人们一直在写日记。它们是一种方便的信息保存方式。它们有很多形式,比如意大利的 [Zibaldone][2]、[备忘录][3],或者记录今天做了什么的事件日记。
|
||||||
|
|
||||||
|
![Notebook folders][4]
|
||||||
|
|
||||||
|
*(Kevin Sonney, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
为什么我们要写某种日记呢?第一个原因是为了让我们不至于把所有的事情都记在脑子里。我们中没有多少人有<ruby>[遗觉记忆][6]<rt>Eidetic memory</rt></ruby>,维护运行日记或一组笔记可以让我们更容易地参考我们之前做的一些事情。日记也更容易分享,因为它们可以在聊天、邮件中复制/粘贴。正如 [Robert Boyce][7] 的名言:“知识就是力量。知识共享使力量倍增。”知识的共享是开源的一个内在组成部分。
|
||||||
|
|
||||||
|
![Today's journal][8]
|
||||||
|
|
||||||
|
*今天的日记 (Kevin Sonney, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
在写事件日记的时候,有一个很关键的点就是要快速、简单、方便。最简单的方法是打开文档,添加一行当前日期和备注,然后保存。
|
||||||
|
|
||||||
|
有几个程序或附加软件可以让这一切变得更简单。[GNote 的 Note of the Day 插件][9]会自动创建一个以日期为标题的笔记,可以用来保存当天的内容。
|
||||||
|
|
||||||
|
Emacs Org 模式有一个热键组合,可以“捕捉”事物并将其放入文档中。结合 [org-journal][10] 附加组件,这将在文档中创建当天的条目。
|
||||||
|
|
||||||
|
Kontact 的 KNotes 组件会自动将日期和时间添加到新笔记中。
|
||||||
|
|
||||||
|
![Finding a note][11]
|
||||||
|
|
||||||
|
*查找笔记 (Kevin Sonney, [CC BY-SA 4.0][5])*
|
||||||
|
|
||||||
|
写日记或记录事情是一种方便的方法,可以记录做了什么和怎么做的。它的作用不仅仅是“我做了什么”,它还可以包括阅读的书籍、吃过的食物、去过的地方,以及一大堆对未来有用的信息。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/open-source-journal
|
||||||
|
|
||||||
|
作者:[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/note-taking.jpeg?itok=fiF5EBEb (Note taking hand writing)
|
||||||
|
[2]: https://en.wikipedia.org/wiki/Zibaldone
|
||||||
|
[3]: https://en.wikipedia.org/wiki/Commonplace_book
|
||||||
|
[4]: https://opensource.com/sites/default/files/pictures/day10-image1.png (Notebook folders)
|
||||||
|
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[6]: https://en.wikipedia.org/wiki/Eidetic_memory
|
||||||
|
[7]: https://en.wikipedia.org/wiki/Robert_Boyce
|
||||||
|
[8]: https://opensource.com/sites/default/files/pictures/day10-image2.png (Today's journal)
|
||||||
|
[9]: https://help.gnome.org/users/gnote/unstable/addin-noteoftheday.html.en
|
||||||
|
[10]: https://github.com/bastibe/org-journal
|
||||||
|
[11]: https://opensource.com/sites/default/files/pictures/day10-image3.png (Finding a note)
|
@ -0,0 +1,89 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (AnyISalIn)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13063-1.html)
|
||||||
|
[#]: subject: (How to implement a DevOps toolchain)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/devops-tool-chain)
|
||||||
|
[#]: author: (Tereza Denkova https://opensource.com/users/tereza-denkova)
|
||||||
|
|
||||||
|
如何实现 DevOps 工具链
|
||||||
|
======
|
||||||
|
|
||||||
|
> 一套完整启用的 DevOps 工具链可推动你的创新计划,实现快速部署并节约成本。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202101/29/153905o35h8u9zy5k58bll.jpg)
|
||||||
|
|
||||||
|
不同规模和不同行业组织都致力于为提高软件交付的速度和质量提供解决方案。这不仅保证了他们的生存,还令他们在全球市场取得了成功。DevOps 可以帮助他们规划出一条最佳路线。
|
||||||
|
|
||||||
|
DevOps 是一个系统,通过引入不同的工具链连接不同工作流程,以便及时交付项目并降低所需的开销。
|
||||||
|
|
||||||
|
在我工作的 IT 服务公司 [Accedia][2],我们会帮助客户落地一套完整的 DevOps 工具链,这套工具链能帮助他们达到甚至超越他们的业务目标。在这篇文章,我会分享目前为止从 DevOps 项目中汲取的经验。
|
||||||
|
|
||||||
|
### DevOps 工具链是什么?
|
||||||
|
|
||||||
|
一套完善的 DevOps 工具链可以在不同阶段中使用不同的 DevOps 工具来解决特定的业务带来的挑战。一条工具链能保证前端和后端开发者、质量测试人员、客户都能够从中获得收益。构建工具链的目的是为了自动化开发和部署过程,以确保快速、可靠、预算友好地交付与创新。
|
||||||
|
|
||||||
|
我们发现成功构建一套 DevOps 工具链不是一个简单的事情。它需要实验和不断的完善,保证必要的流程是完全自动化的。
|
||||||
|
|
||||||
|
### 为什么你需要 DevOps 工具链
|
||||||
|
|
||||||
|
DevOps 工具链自动化了工作流中的所有技术元素。它能让不同团队在一个平台上进行工作,因此可以使你专注于业务战略以推动组织走向未来。
|
||||||
|
|
||||||
|
我们总结了五个实现 DevOps 工具链所带来的好处。你可以让管理层相信,是值得为 DevOps 工具链的开发投入资源和时间的。
|
||||||
|
|
||||||
|
1. **更快、更高效的生产部署**:DevOps 工具自动化了大部分软件开发进程。这会使产品开发专注于创新,交付更加敏捷,更领先于竞争对手。
|
||||||
|
2. **预算和时间优化**:将手动的任务转变为自动化会使你的组织节省时间和资源。当没有人为的错误和时间管理不足带来的额外支出,预算自然会得到优化。
|
||||||
|
3. **高效的开发**:DevOps 工具链会减少开发工作中不必要的延时,提高开发效率。前端、后端、质量测试人员的工作是一致的,所以没有人需要协调不同团队之间人员的交付。
|
||||||
|
4. **更快的部署意味着更高的质量**:DevOps 工具链保证了缺陷能够很快被解决,并且迅速完成高质量的部署进程。怎么样?它可以生成有针对性的告警,并将重要的事件通知给你的团队。这会让你主动地发现并解决潜在的问题,从而规避故障的不断的升级从而导致的客户服务不可用。
|
||||||
|
5. **及时事件管理**:DevOps 工具链有助于优化事件管理记录。它能够识别 IT 事件并且逐渐升级事件级别,通知给指定团队的成员,直到问题被解决。这意味着消息的接受和处理会更加的迅速,因为它们发送给了正确的目标。
|
||||||
|
|
||||||
|
### DevOps 工具链的实践
|
||||||
|
|
||||||
|
对我的团队来说,DevOps 并不新鲜。我们已经敏捷开发很长时间了,并且我们总是热衷于探索最优的工作流。在我们的实践中,往往都是应用复杂性增加从而带来了自动化的需求。
|
||||||
|
|
||||||
|
这是我们为一个客户配置的工具链。这个项目包含了移动运营方案,连接了金融交易的所有参与者 (卖方、买方、银行)。这个客户需要动态响应用户反馈并且将故障时间缩短到最小,从而来提高用户体验。我的团队设计了一套工具链用于自动化应用的维护和部署新功能。
|
||||||
|
|
||||||
|
![Accedia's DevOps toolchain][3]
|
||||||
|
|
||||||
|
*(Accedia, [CC BY-NC-SA 4.0][4])*
|
||||||
|
|
||||||
|
1. 首先,我们团队编写了自动化测试,可以立即识别应用程序的变更。
|
||||||
|
2. 当新版本已经准备就绪的时候,代码将被提交到 Gitlab 中。
|
||||||
|
3. 通过 Gitlab,提交会自动触发 Jenkins 构建。
|
||||||
|
4. 在 **持续集成中**,新的代码版本通过 [Chai][5] 和 [Mocha][6] 进行了测试,以检测是否运行正常。
|
||||||
|
5. 当测试通过,**持续部署阶段** 将会开始并创建一个可用的 Docker 镜像并上传到 Sonatype 的 [Nexus][7]。(这是 Sonatype 公司的的一个开源工具)
|
||||||
|
6. 最后,新版本应用会通过 Nexus 下载并且部署到线上环境中,例如 [Docker][8] 容器 (**持续部署阶段**)
|
||||||
|
|
||||||
|
简而言之,每当有人在仓库中创建一个新的提交,又或者团队上传新的代码版本、功能、升级、缺陷修复等,应用程序包都会自动更新并且交付给客户。
|
||||||
|
|
||||||
|
这套系统拥有良好的事故控制能力以保证快速部署,但不以牺牲质量为代价。它对于用户的反馈是动态的,意味着新功能和旧功能的和更新只需要之前一半的时间,同时将故障时间降低到最低。
|
||||||
|
|
||||||
|
### 把它封装起来
|
||||||
|
|
||||||
|
一套完整并且正确实施的 DevOps 工具链可以从始至终推动你的创新计划并且加速部署。
|
||||||
|
|
||||||
|
根据你的需求,你的工具链可能看起来和这些不一样,但是我希望我们的工作流能够让你了解如何将自动化作为一种解决方案。
|
||||||
|
|
||||||
|
-------------------------------------------------- -----------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/devops-tool-chain
|
||||||
|
|
||||||
|
作者:[Tereza Denkova][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[AnyISalIn](https://github.com/AnyISalIn)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/tereza-denkova
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tools_osyearbook2016_sysadmin_cc.png?itok=Y1AHCKI4 (Wratchet set tools)
|
||||||
|
[2]: https://accedia.com/services/operations/devops/
|
||||||
|
[3]: https://opensource.com/sites/default/files/uploads/devopstoolchain.png (Accedia's DevOps toolchain)
|
||||||
|
[4]: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
[5]: https://www.chaijs.com/
|
||||||
|
[6]: https://mochajs.org/
|
||||||
|
[7]: https://www.sonatype.com/nexus/repository-oss
|
||||||
|
[8]: https://opensource.com/resources/what-docker
|
||||||
|
[9]: https://accedia.com/blog/5-good-reasons-why-you-need-a-devops-toolchain/
|
@ -0,0 +1,161 @@
|
|||||||
|
[#]: collector: (Chao-zhi)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13136-1.html)
|
||||||
|
[#]: subject: (Typeset your docs with LaTeX and TeXstudio on Fedora)
|
||||||
|
[#]: via: (https://fedoramagazine.org/typeset-latex-texstudio-fedora/)
|
||||||
|
[#]: author: (Julita Inca Chiroque https://fedoramagazine.org/author/yulytas/)
|
||||||
|
|
||||||
|
使用 LaTeX 和 TeXstudio 排版文档
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/latex-texstudio-945x400.jpg)
|
||||||
|
|
||||||
|
LaTeX 是一个服务于高质量排版的[文档准备系统][1]。通常用于大量的技术和科学文档的排版。不过,你也可以使用 LaTex 排版各种形式的文档。教师可以编辑他们的考试和教学大纲,学生可以展示他们的论文和报告。这篇文章让你尝试使用 TeXstudio。TeXstudio 是一个便于编辑 LaTeX 文档的软件。
|
||||||
|
|
||||||
|
### 启动 TeXstudio
|
||||||
|
|
||||||
|
如果你使用的是 Fedora Workstation,请启动软件管理,然后输入 TeXstudio 以搜索该应用程序。然后选择安装并添加 TeXstudio 到你的系统。你可以从软件管理中启动这个程序,或者像以往一样在概览中启动这个软件。
|
||||||
|
|
||||||
|
或者,如果你使用终端,请输入 `texstudio`。如果未安装该软件包,系统将提示你安装它。键入 `y` 开始安装。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ texstudio
|
||||||
|
bash: texstudio: command not found...
|
||||||
|
Install package 'texstudio' to provide command 'texstudio'? [N/y] y
|
||||||
|
```
|
||||||
|
|
||||||
|
### 你的第一份文档
|
||||||
|
|
||||||
|
LaTeX 命令通常以反斜杠 `\` 开头,命令参数用大括号 `{}` 括起来。首先声明 `documentclass` 的类型。这个例子向你展示了该文档的类是一篇文章。
|
||||||
|
|
||||||
|
然后,在声明 `documentclass` 之后,用 `begin` 和 `end` 标记文档的开始和结束。在这些命令之间,写一段类似以下的内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass{article}
|
||||||
|
\begin{document}
|
||||||
|
The Fedora Project is a project sponsored by Red Hat primarily to co-ordinate the development of the Linux-based Fedora operating system, operating with the vision that the project "creates a world where free culture is welcoming and widespread, collaboration is commonplace, and people control their content and devices". The Fedora Project was founded on 22 September 2003 when Red Hat decided to split Red Hat Linux into Red Hat Enterprise Linux (RHEL) and a community-based operating system, Fedora.
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/Screenshot-from-2017-10-05-20-19-15.png)
|
||||||
|
|
||||||
|
### 使用间距
|
||||||
|
|
||||||
|
要创建段落分隔符,请在文本之间保留一个或多个换行符。下面是一个包含四个段落的示例:
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/Screenshot-from-2017-10-18-14-24-42.png)
|
||||||
|
|
||||||
|
从该示例中可以看出,多个换行符不会在段落之间创建额外的空格。但是,如果你确实需要留出额外的空间,请使用 `hspace` 和 `vspace` 命令。这两个命令分别添加水平和垂直空间。下面是一些示例代码,显示了段落周围的附加间距:
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass{article}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\hspace{2.5cm} The four essential freedoms
|
||||||
|
|
||||||
|
\vspace{0.6cm}
|
||||||
|
A program is free software if the program's users have the 4 essential freedoms:
|
||||||
|
|
||||||
|
The freedom to run the program as you wish, for any purpose (freedom 0).\vspace{0.2cm}
|
||||||
|
The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this.\vspace{0.2cm}
|
||||||
|
|
||||||
|
The freedom to redistribute copies so you can help your neighbour (freedom 2).\vspace{0.2cm}
|
||||||
|
|
||||||
|
The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this.
|
||||||
|
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
如果需要,你也可以使用 `noindent` 命令来避免缩进。这里是上面 LaTeX 源码的结果:
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/Screenshot-from-2017-10-18-17-24-53.png)
|
||||||
|
|
||||||
|
### 使用列表和格式
|
||||||
|
|
||||||
|
如果把自由软件的四大基本自由列为一个清单,这个例子看起来会更好。通过在列表的开头使用`\begin{itemize}`,在末尾使用 `\end{itemize}` 来设置列表结构。在每个项目前面加上 `\item` 命令。
|
||||||
|
|
||||||
|
额外的格式也有助于使文本更具可读性。用于格式化的有用命令包括粗体、斜体、下划线、超大、大、小和 textsc 以帮助强调文本:
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass{article}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\hspace{2cm} {\huge The four essential freedoms}
|
||||||
|
|
||||||
|
\vspace{0.6cm}
|
||||||
|
\noindent {\large A program is free software if the program's users have the 4 essential freedoms}:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \vspace{0.2cm}
|
||||||
|
\noindent \textbf{The freedom to run} the program as you wish, for any purpose \textit{(freedom 0)}. \vspace{0.2cm}
|
||||||
|
\item \noindent \textbf{The freedom to study} how the program works, and change it so it does your computing as you wish \textit{(freedom 1)}. Access to the source code is a precondition for this.\vspace{0.2cm}
|
||||||
|
|
||||||
|
\item \noindent \textbf{The freedom to redistribute} copies so you can help your neighbour \textit{(freedom 2)}.\vspace{0.2cm}
|
||||||
|
|
||||||
|
\item \noindent \textbf{The freedom to distribute copies of your modified versions} to others \textit{(freedom 3)}. \tiny{By doing this you can give the whole community a chance to benefit from your changes.\underline{\textsc{ Access to the source code is a precondition for this.}}}
|
||||||
|
\end{itemize}
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/Screenshot-from-2017-10-18-17-21-30.png)
|
||||||
|
|
||||||
|
### 添加列、图像和链接
|
||||||
|
|
||||||
|
列、图像和链接有助于为文本添加更多信息。LaTeX 包含一些高级功能的函数作为宏包。`\usepackage` 命令加载宏包以便你可以使用这些功能。
|
||||||
|
|
||||||
|
例如,要使用图像,可以使用命令 `\usepackage{graphicx}`。或者,要设置列和链接,请分别使用 `\usepackage{multicol}` 和 `\usepackage{hyperref}`。
|
||||||
|
|
||||||
|
`\includegraphics` 命令将图像内联放置在文档中。(为简单起见,请将图形文件包含在与 LaTeX 源文件相同的目录中。)
|
||||||
|
|
||||||
|
下面是一个使用所有这些概念的示例。它还使用下载的两个 PNG 图片。试试你自己的图片,看看它们是如何工作的。
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass{article}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{multicol}
|
||||||
|
\usepackage{hyperref}
|
||||||
|
\begin{document}
|
||||||
|
\textbf{GNU}
|
||||||
|
\vspace{1cm}
|
||||||
|
|
||||||
|
GNU is a recursive acronym for "GNU's Not Unix!", chosen because GNU's design is Unix-like, but differs from Unix by being free software and containing no Unix code.
|
||||||
|
|
||||||
|
Richard Stallman, the founder of the project, views GNU as a "technical means to a social end". Stallman has written about "the social aspects of software and how Free Software can create community and social justice." in his "Free Society" book.
|
||||||
|
\vspace{1cm}
|
||||||
|
|
||||||
|
\textbf{Some Projects}
|
||||||
|
|
||||||
|
\begin{multicols}{2}
|
||||||
|
Fedora
|
||||||
|
\url{https://getfedora.org}
|
||||||
|
\includegraphics[width=1cm]{fedora.png}
|
||||||
|
|
||||||
|
GNOME
|
||||||
|
\url{https://getfedora.org}
|
||||||
|
\includegraphics[width=1cm]{gnome.png}
|
||||||
|
\end{multicols}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2017/07/Screenshot-from-2017-10-18-20-32-32.png)
|
||||||
|
|
||||||
|
这里的功能只触及 LaTeX 功能的表面。你可以在该项目的[帮助和文档站点][3]了解更多关于它们的信息。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/typeset-latex-texstudio-fedora/
|
||||||
|
|
||||||
|
作者:[Julita Inca Chiroque][a]
|
||||||
|
选题:[Chao-zhi][b]
|
||||||
|
译者:[Chao-zhi][b]
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://fedoramagazine.org/author/yulytas/
|
||||||
|
[b]: https://github.com/Chao-zhi
|
||||||
|
[1]:http://www.latex-project.org/about/
|
||||||
|
[2]:https://fedoramagazine.org/fedora-aarch64-on-the-solidrun-honeycomb-lx2k/
|
||||||
|
[3]:https://www.latex-project.org/help/
|
@ -0,0 +1,59 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (XYenChi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13130-1.html)
|
||||||
|
[#]: subject: (When the web grew up: A browser story)
|
||||||
|
[#]: via: (https://opensource.com/article/19/3/when-web-grew)
|
||||||
|
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||||
|
|
||||||
|
Web 的成长,就是一篇浏览器的故事
|
||||||
|
======
|
||||||
|
|
||||||
|
> 互联网诞生之时我的个人故事。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/18/161753qb8tytkc6bnxbavn.jpg)
|
||||||
|
|
||||||
|
最近,我和大家 [分享了][1] 我在 1994 年获得英国文学和神学学位离开大学后,如何在一个人们还不知道 Web 服务器是什么的世界里成功找到一份运维 Web 服务器的工作。我说的“世界”,并不仅仅指的是我工作的机构,而是泛指所有地方。Web 那时当真是全新的 —— 人们还正尝试理出头绪。
|
||||||
|
|
||||||
|
那并不是说我工作的地方(一家学术出版社)特别“懂” Web。这是个大部分人还在用 28.8K 猫(调制解调器,俗称“猫”)访问网页的世界。我还记得我拿到 33.6K 猫时有多激动。至少上下行速率不对称的日子已经过去了,[^1] 以前 1200/300 的带宽描述特别常见。这意味着(在同一家机构的)印刷人员制作的设计复杂、色彩缤纷、纤毫毕现的文档是完全不可能放在 Web 上的。我不能允许在网站的首页出现大于 40k 的 GIF 图片,这对我们的许多访问者来说是很难接受的。大于大约 60k 图片的会作为独立的图片,以缩略图链接过去。
|
||||||
|
|
||||||
|
如果说市场部只有这一点不喜欢,那是绝对是轻描淡写了。更糟的是布局问题。“浏览器决定如何布局文档,”我一遍又一遍地解释,“你可以使用标题或者段落,但是文档在页面上如何呈现并不取决于文档,而是取决于渲染器!”他们想控制这些,想要不同颜色的背景。后来明白了那些不能实现。我觉得我就像是参加了第一次讨论层叠样式表(CSS)的 W3C 会议,并进行了激烈地争论。关于文档编写者应控制布局的建议真令人厌恶。[^2] CSS 花了一些时间才被人们采用,与此同时,关心这些问题的人搭上了 PDF 这种到处都是安全问题的列车。
|
||||||
|
|
||||||
|
如何呈现文档不是唯一的问题。作为一个实体书出版社,对于市场部来说,拥有一个网站的全部意义在于,让客户(或者说潜在的客户)不仅知道一本书的内容,而且知道买这本书需要花多少钱。但这有一个问题,你看,互联网,包括快速发展的万维网,是开放的,是所有都免费的自由之地,没有人会在意钱;事实上,在那里谈钱是要回避和避免的。
|
||||||
|
|
||||||
|
我和主流“网民”的看法一致,认为没必要把价格信息放在线上。我老板,以及机构里相当多的人都持相反的意见。他们觉得消费者应该能够看到书要花多少钱。他们也觉得我的银行经理也会想看到我的账户里每个月进了多少钱,如果我不认同他们的观点的话,那我的收入就可能堪忧。
|
||||||
|
|
||||||
|
幸运的是,在我被炒鱿鱼之前,我已经自己认清了一些 —— 可能是在我开始迈入 Web 的几星期之后,Web 已经发生变化,有其他人公布他们的产品价格信息。这些新来者通常被那些从早期就开始运行 Web 服务器的老派人士所看不起,[^3] 但很明显,风向是往那边吹的。然而,这并不意味着我们的网站就赢得了战争。作为一个学术出版社,我们和大学共享一个域名(在 “ac.uk” 下)。大学不太相信发布价格信息是合适的,直到出版社的一些资深人士指出,普林斯顿大学出版社正在这样做,如果我们不做……看起来是不是有点傻?
|
||||||
|
|
||||||
|
有趣的事情还没完。在我担任站点管理员(“webmaster@…”)的短短几个月后,我们和其他很多网站一样开始看到了一种令人担忧的趋势。某些访问者可以轻而易举地让我们的 Web 服务器跪了。这些访问者使用了新的网页浏览器:网景浏览器(Netscape)。网景浏览器实在太恶劣了,它居然是多线程的。
|
||||||
|
|
||||||
|
这为什么是个问题呢?在网景浏览器之前,所有的浏览器都是单线程。它们一次只进行一个连接,所以即使一个页面有五张 GIF 图,[^4] 也会先请求 HTML 基本文件进行解析,然后下载第一张 GIF,完成,接着第二张,完成,如此类推。事实上,GIF 的顺序经常出错,使得页面加载得非常奇怪,但这也是常规思路。而粗暴的网景公司的人决定,它们可以同时打开多个连接到 Web 服务器,比如说,可以同时请求所有的 GIF!为什么这是个问题呢?好吧,问题就在于大多数 Web 服务器都是单线程的。它们不是设计来一次进行多个连接的。确实,我们运行的 HTTP 服务的软件(MacHTTP)是单线程的。尽管我们花钱购买了它(最初是共享软件),但我们用的这版无法同时处理多个请求。
|
||||||
|
|
||||||
|
互联网上爆发了大量讨论。这些网景公司的人以为他们是谁,能改变世界的运作方式?它应该如何工作?大家分成了不同阵营,就像所有的技术争论一样,双方都用各种技术热词互丢。问题是,网景浏览器不仅是多线程的,它也比其他的浏览器更好。非常多 Web 服务器代码维护者,包括 MacHTTP 作者 Chuck Shotton 在内,开始坐下来认真地在原有代码基础上更新了多线程测试版。几乎所有人立马转向测试版,它们变得稳定了,最终,浏览器要么采用了这种技术,变成多线程,要么就像所有过时产品一样销声匿迹了。[^6]
|
||||||
|
|
||||||
|
对我来说,这才是 Web 真正成长起来的时候。既不是网页展示的价格,也不是设计者能定义你能在网页上看到什么,[^8] 而是浏览器变得更易用,以及成千上万的浏览者向数百万浏览者转变的网络效应,使天平向消费者而不是生产者倾斜。在我的旅程中,还有更多故事,我将留待下次再谈。但从这时起,我的雇主开始看我们的月报,然后是周报、日报,并意识到这将是一件大事,真的需要关注。
|
||||||
|
|
||||||
|
[^1]: 它们又是怎么回来的?
|
||||||
|
[^2]: 你可能不会惊讶,我还是在命令行里最开心。
|
||||||
|
[^3]: 大约六个月前。
|
||||||
|
[^4]: 莽撞,没错,但它确实发生了 [^5]
|
||||||
|
[^5]: 噢,不,是 GIF 或 BMP,JPEG 还是个好主意,但还没有用上。
|
||||||
|
[^6]: 没有真正的沉寂:总有一些坚持他们的首选解决方案具有技术上的优势,并哀叹互联网的其他人都是邪恶的死硬爱好者。 [^7]
|
||||||
|
[^7]: 我不是唯一一个说“我还在用 Lynx”的人。
|
||||||
|
[^8]: 我会指出,为那些有各种无障碍需求的人制造严重而持续的问题。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/3/when-web-grew
|
||||||
|
|
||||||
|
作者:[Mike Bursell][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[XYenChi](https://github.com/XYenChi)
|
||||||
|
校对:[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/article/18/11/how-web-was-won
|
@ -0,0 +1,69 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (ShuyRoy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13109-1.html)
|
||||||
|
[#]: subject: (Intel formally launches Optane for data center memory caching)
|
||||||
|
[#]: via: (https://www.networkworld.com/article/3387117/intel-formally-launches-optane-for-data-center-memory-caching.html#tk.rss_all)
|
||||||
|
[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/)
|
||||||
|
|
||||||
|
英特尔 Optane:用于数据中心内存缓存
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/12/111720yq1rvxcncjdsjb0g.jpg)
|
||||||
|
|
||||||
|
> 英特尔推出了包含 3D Xpoint 内存技术的 Optane 持久内存产品线。英特尔的这个解决方案介乎于 DRAM 和 NAND 中间,以此来提升性能。
|
||||||
|
|
||||||
|
![Intel][1]
|
||||||
|
|
||||||
|
英特尔在 2019 年 4 月的[大规模数据中心活动][2]中正式推出 Optane 持久内存产品线。它已经问世了一段时间,但是目前的 Xeon 服务器处理器还不能充分利用它。而新的 Xeon8200 和 9200 系列可以充分利用 Optane 持久内存的优势。
|
||||||
|
|
||||||
|
由于 Optane 是英特尔的产品(与美光合作开发),所以意味着 AMD 和 ARM 的服务器处理器不能够支持它。
|
||||||
|
|
||||||
|
正如[我之前所说的][3],OptaneDC 持久内存采用与美光合作研发的 3D Xpoint 内存技术。3D Xpoint 是一种比 SSD 更快的非易失性内存,速度几乎与 DRAM 相近,而且它具有 NAND 闪存的持久性。
|
||||||
|
|
||||||
|
第一个 3D Xpoint 产品是被称为英特尔“尺子”的 SSD,因为它们被设计成细长的样子,很像尺子的形状。它们被设计这样是为了适合 1u 的服务器机架。在发布的公告中,英特尔推出了新的利用四芯或者 QLC 3D NAND 内存的英特尔 SSD D5-P4325 [尺子][7] SSD,可以在 1U 的服务器机架上放 1PB 的存储。
|
||||||
|
|
||||||
|
OptaneDC 持久内存的可用容量最初可以通过使用 128GB 的 DIMM 达到 512GB。英特尔数据中心集团执行副总裁及总经理 Navin Shenoy 说:“OptaneDC 持久内存可达到的容量是 DRAM 的 2 到 4 倍。”
|
||||||
|
|
||||||
|
他说:“我们希望服务器系统的容量可以扩展到每个插槽 4.5TB 或者 8 个插槽 36TB,这是我们第一代 Xeon 可扩展芯片的 3 倍。”
|
||||||
|
|
||||||
|
### 英特尔Optane内存的使用和速度
|
||||||
|
|
||||||
|
Optane 有两种不同的运行模式:内存模式和应用直连模式。内存模式是将 DRAM 放在 Optane 内存之上,将 DRAM 作为 Optane 内存的缓存。应用直连模式是将 DRAM 和 OptaneDC 持久内存一起作为内存来最大化总容量。并不是每个工作负载都适合这种配置,所以应该在对延迟不敏感的应用程序中使用。正如英特尔推广的那样,Optane 的主要使用情景是内存模式。
|
||||||
|
|
||||||
|
几年前,当 3D Xpoint 最初发布时,英特尔宣称 Optane 的速度是 NAND 的 1000 倍,耐用是 NAND 的 1000 倍,密度潜力是 DRAM 的 10 倍。这虽然有点夸张,但这些因素确实很令人着迷。
|
||||||
|
|
||||||
|
在 256B 的连续 4 个缓存行中使用 Optane 内存可以达到 8.3GB/秒的读速度和 3.0GB/秒的写速度。与 SATA SSD 的 500MB/秒左右的读/写速度相比,可以看到性能有很大提升。请记住,Optane 充当内存,所以它会缓存被频繁访问的 SSD 中的内容。
|
||||||
|
|
||||||
|
这是了解 OptaneDC 的关键。它能将非常大的数据集存储在离内存非常近的位置,因此具有很低延迟的 CPU 可以最小化访问较慢的存储子系统的访问延迟,无论存储是 SSD 还是 HDD。现在,它提供了一种可能性,即把多个 TB 的数据放在非常接近 CPU 的地方,以实现更快的访问。
|
||||||
|
|
||||||
|
### Optane 内存的一个挑战
|
||||||
|
|
||||||
|
唯一真正的挑战是 Optane 插进内存所在的 DIMM 插槽。现在有些主板的每个 CPU 有多达 16 个 DIMM 插槽,但是这仍然是客户和设备制造商之间需要平衡的电路板空间:Optane 还是内存。有一些 Optane 驱动采用了 PCIe 接口进行连接,可以减轻主板上内存的拥挤。
|
||||||
|
|
||||||
|
3D Xpoint 由于它写数据的方式,提供了比传统的 NAND 闪存更高的耐用性。英特尔承诺 Optane 提供 5 年保修期,而很多 SSD 只提供 3 年保修期。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.networkworld.com/article/3387117/intel-formally-launches-optane-for-data-center-memory-caching.html#tk.rss_all
|
||||||
|
|
||||||
|
作者:[Andy Patrizio][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[RiaXu](https://github.com/ShuyRoy)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.networkworld.com/author/Andy-Patrizio/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://images.idgesg.net/images/article/2018/06/intel-optane-persistent-memory-100760427-large.jpg
|
||||||
|
[2]: https://www.networkworld.com/article/3386142/intel-unveils-an-epic-response-to-amds-server-push.html
|
||||||
|
[3]: https://www.networkworld.com/article/3279271/intel-launches-optane-the-go-between-for-memory-and-storage.html
|
||||||
|
[4]: https://www.networkworld.com/article/3290421/why-nvme-users-weigh-benefits-of-nvme-accelerated-flash-storage.html
|
||||||
|
[5]: https://www.networkworld.com/article/3242807/data-center/top-10-data-center-predictions-idc.html#nww-fsb
|
||||||
|
[6]: https://www.networkworld.com/newsletters/signup.html#nww-fsb
|
||||||
|
[7]: https://www.theregister.co.uk/2018/02/02/ruler_and_miniruler_ssd_formats_look_to_banish_diskstyle_drives/
|
||||||
|
[8]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fpaths%2Fapple-certified-technical-trainer-10-11
|
||||||
|
[9]: https://www.facebook.com/NetworkWorld/
|
||||||
|
[10]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,305 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (chensanle)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13107-1.html)
|
||||||
|
[#]: subject: (Tmux Command Examples To Manage Multiple Terminal Sessions)
|
||||||
|
[#]: via: (https://www.ostechnix.com/tmux-command-examples-to-manage-multiple-terminal-sessions/)
|
||||||
|
[#]: author: (sk https://www.ostechnix.com/author/sk/)
|
||||||
|
|
||||||
|
基于 Tmux 的多会话终端管理示例
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/11/101058ffso6wzzw94wm2ng.jpg)
|
||||||
|
|
||||||
|
我们已经了解到如何通过 [GNU Screen][2] 进行多会话管理。今天,我们将要领略另一个著名的管理会话的命令行实用工具 **Tmux**。类似 GNU Screen,Tmux 是一个帮助我们在单一终端窗口中创建多个会话,同一时间内同时运行多个应用程序或进程的终端复用工具。Tmux 自由、开源并且跨平台,支持 Linux、OpenBSD、FreeBSD、NetBSD 以及 Mac OS X。本文将讨论 Tmux 在 Linux 系统下的高频用法。
|
||||||
|
|
||||||
|
### Linux 下安装 Tmux
|
||||||
|
|
||||||
|
Tmux 可以在绝大多数的 Linux 官方仓库下获取。
|
||||||
|
|
||||||
|
在 Arch Linux 或它的变种系统下,执行下列命令来安装:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo pacman -S tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
Debian、Ubuntu 或 Linux Mint:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-get install tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
Fedora:
|
||||||
|
```
|
||||||
|
$ sudo dnf install tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
RHEL 和 CentOS:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
SUSE/openSUSE:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo zypper install tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
以上,我们已经完成 Tmux 的安装。之后我们继续看看一些 Tmux 示例。
|
||||||
|
|
||||||
|
### Tmux 命令示例: 多会话管理
|
||||||
|
|
||||||
|
Tmux 默认所有命令的前置命令都是 `Ctrl+b`,使用前牢记这个快捷键即可。
|
||||||
|
|
||||||
|
> **注意**:**Screen** 的前置命令都是 `Ctrl+a`.
|
||||||
|
|
||||||
|
#### 创建 Tmux 会话
|
||||||
|
|
||||||
|
在终端中运行如下命令创建 Tmux 会话并附着进入:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
抑或,
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux new
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦进入 Tmux 会话,你将看到一个 **沉在底部的绿色的边栏**,如下图所示。
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
*创建 Tmux 会话*
|
||||||
|
|
||||||
|
这个绿色的边栏能很容易提示你当前是否身处 Tmux 会话当中。
|
||||||
|
|
||||||
|
#### 退出 Tmux 会话
|
||||||
|
|
||||||
|
退出当前 Tmux 会话仅需要使用 `Ctrl+b` 和 `d`。无需同时触发这两个快捷键,依次按下 `Ctrl+b` 和 `d` 即可。
|
||||||
|
|
||||||
|
退出当前会话后,你将能看到如下输出:
|
||||||
|
|
||||||
|
```
|
||||||
|
[detached (from session 0)]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 创建有名会话
|
||||||
|
|
||||||
|
如果使用多个会话,你很可能会混淆运行在多个会话中的应用程序。这种情况下,我们需要会话并赋予名称。譬如需要 web 相关服务的会话,就创建一个名称为 “webserver”(或任意一个其他名称) 的 Tmux 会话。
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux new -s webserver
|
||||||
|
```
|
||||||
|
|
||||||
|
这里是新的 Tmux 有名会话:
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
*拥有自定义名称的 Tmux 会话*
|
||||||
|
|
||||||
|
如你所见上述截图,这个 Tmux 会话的名称已经被标注为 “webserver”。如此,你可以在多个会话中,轻易的区分应用程序的所在。
|
||||||
|
|
||||||
|
退出会话,轻按 `Ctrl+b` 和 `d`。
|
||||||
|
|
||||||
|
#### 查看 Tmux 会话清单
|
||||||
|
|
||||||
|
查看 Tmux 会话清单,执行:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux ls
|
||||||
|
```
|
||||||
|
|
||||||
|
示例输出:
|
||||||
|
|
||||||
|
![][5]
|
||||||
|
|
||||||
|
*列出 Tmux 会话*
|
||||||
|
|
||||||
|
如你所见,我们开启了两个 Tmux 会话。
|
||||||
|
|
||||||
|
#### 创建非附着会话
|
||||||
|
|
||||||
|
有时候,你可能想要简单创建会话,但是并不想自动切入该会话。
|
||||||
|
|
||||||
|
创建一个非附着会话,并赋予名称 “ostechnix”,运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux new -s ostechnix -d
|
||||||
|
```
|
||||||
|
|
||||||
|
上述命令将会创建一个名为 “ostechnix” 的会话,但是并不会附着进入。
|
||||||
|
|
||||||
|
你可以通过使用 `tmux ls` 命令验证:
|
||||||
|
|
||||||
|
![][6]
|
||||||
|
|
||||||
|
*创建非附着会话*
|
||||||
|
|
||||||
|
#### 附着进入 Tmux 会话
|
||||||
|
|
||||||
|
通过如下命令,你可以附着进入最后一个被创建的会话:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux attach
|
||||||
|
```
|
||||||
|
|
||||||
|
抑或,
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux a
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你想附着进入任意一个指定的有名会话,譬如 “ostechnix”,运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux attach -t ostechnix
|
||||||
|
```
|
||||||
|
|
||||||
|
或者,简写为:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux a -t ostechnix
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 关闭 Tmux 会话
|
||||||
|
|
||||||
|
当你完成或者不再需要 Tmux 会话,你可以通过如下命令关闭:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux kill-session -t ostechnix
|
||||||
|
```
|
||||||
|
|
||||||
|
当身处该会话时,使用 `Ctrl+b` 以及 `x`。点击 `y` 来关闭会话。
|
||||||
|
|
||||||
|
可以通过 `tmux ls` 命令验证。
|
||||||
|
|
||||||
|
关闭所有 Tmux 服务下的所有会话,运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux kill-server
|
||||||
|
```
|
||||||
|
|
||||||
|
谨慎!这将终止所有 Tmux 会话,并不会产生任何警告,即便会话存在运行中的任务。
|
||||||
|
|
||||||
|
如果不存在活跃的 Tmux 会话,将看到如下输出:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tmux ls
|
||||||
|
no server running on /tmp/tmux-1000/default
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 切割 Tmux 窗口
|
||||||
|
|
||||||
|
切割窗口成多个小窗口,在 Tmux 中,这个叫做 “Tmux 窗格”。每个窗格中可以同时运行不同的程序,并同时与所有的窗格进行交互。每个窗格可以在不影响其他窗格的前提下可以调整大小、移动位置和控制关闭。我们可以以水平、垂直或者二者混合的方式切割屏幕。
|
||||||
|
|
||||||
|
##### 水平切割窗格
|
||||||
|
|
||||||
|
欲水平切割窗格,使用 `Ctrl+b` 和 `"`(半个双引号)。
|
||||||
|
|
||||||
|
![][7]
|
||||||
|
|
||||||
|
*水平切割 Tmux 窗格*
|
||||||
|
|
||||||
|
可以使用组合键进一步切割面板。
|
||||||
|
|
||||||
|
##### 垂直切割窗格
|
||||||
|
|
||||||
|
垂直切割面板,使用 `Ctrl+b` 和 `%`。
|
||||||
|
|
||||||
|
![][8]
|
||||||
|
|
||||||
|
*垂直切割 Tmux 窗格*
|
||||||
|
|
||||||
|
##### 水平、垂直混合切割窗格
|
||||||
|
|
||||||
|
我们也可以同时采用水平和垂直的方案切割窗格。看看如下截图:
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
*切割 Tmux 窗格*
|
||||||
|
|
||||||
|
首先,我通过 `Ctrl+b` `"` 水平切割,之后通过 `Ctrl+b` `%` 垂直切割下方的窗格。
|
||||||
|
|
||||||
|
如你所见,每个窗格下我运行了不同的程序。
|
||||||
|
|
||||||
|
##### 切换窗格
|
||||||
|
|
||||||
|
通过 `Ctrl+b` 和方向键(上下左右)切换窗格。
|
||||||
|
|
||||||
|
##### 发送命令给所有窗格
|
||||||
|
|
||||||
|
之前的案例中,我们在每个窗格中运行了三个不同命令。其实,也可以发送相同的命令给所有窗格。
|
||||||
|
|
||||||
|
为此,使用 `Ctrl+b` 然后键入如下命令,之后按下回车:
|
||||||
|
|
||||||
|
```
|
||||||
|
:setw synchronize-panes
|
||||||
|
```
|
||||||
|
|
||||||
|
现在在任意窗格中键入任何命令。你将看到相同命令影响了所有窗格。
|
||||||
|
|
||||||
|
##### 交换窗格
|
||||||
|
|
||||||
|
使用 `Ctrl+b` 和 `o` 交换窗格。
|
||||||
|
|
||||||
|
##### 展示窗格号
|
||||||
|
|
||||||
|
使用 `Ctrl+b` 和 `q` 展示窗格号。
|
||||||
|
|
||||||
|
##### 终止窗格
|
||||||
|
|
||||||
|
要关闭窗格,直接键入 `exit` 并且按下回车键。或者,按下 `Ctrl+b` 和 `x`。你会看到确认信息。按下 `y` 关闭窗格。
|
||||||
|
|
||||||
|
![][10]
|
||||||
|
|
||||||
|
*关闭窗格*
|
||||||
|
|
||||||
|
##### 放大和缩小 Tmux 窗格
|
||||||
|
|
||||||
|
我们可以将 Tmux 窗格放大到当前终端窗口的全尺寸,以获得更好的文本可视性,并查看更多的内容。当你需要更多的空间或专注于某个特定的任务时,这很有用。在完成该任务后,你可以将 Tmux 窗格缩小(取消放大)到其正常位置。更多详情请看以下链接。
|
||||||
|
|
||||||
|
- [如何缩放 Tmux 窗格以提高文本可见度?](https://ostechnix.com/how-to-zoom-tmux-panes-for-better-text-visibility/)
|
||||||
|
|
||||||
|
#### 自动启动 Tmux 会话
|
||||||
|
|
||||||
|
当通过 SSH 与远程系统工作时,在 Tmux 会话中运行一个长期运行的进程总是一个好的做法。因为,它可以防止你在网络连接突然中断时失去对运行进程的控制。避免这个问题的一个方法是自动启动 Tmux 会话。更多详情,请参考以下链接。
|
||||||
|
|
||||||
|
- [通过 SSH 登录远程系统时自动启动 Tmux 会话](https://ostechnix.com/autostart-tmux-session-on-remote-system-when-logging-in-via-ssh/)
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
这个阶段下,你已经获得了基本的 Tmux 技能来进行多会话管理,更多细节,参阅 man 页面。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ man tmux
|
||||||
|
```
|
||||||
|
|
||||||
|
GNU Screen 和 Tmux 工具都能透过 SSH 很好的管理远程服务器。学习 Screen 和 Tmux 命令,像个行家一样,彻底通过这些工具管理远程服务器。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.ostechnix.com/tmux-command-examples-to-manage-multiple-terminal-sessions/
|
||||||
|
|
||||||
|
作者:[sk][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[chensanle](https://github.com/chensanle)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.ostechnix.com/author/sk/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.ostechnix.com/wp-content/uploads/2019/06/Tmux-720x340.png
|
||||||
|
[2]: https://www.ostechnix.com/screen-command-examples-to-manage-multiple-terminal-sessions/
|
||||||
|
[3]: https://www.ostechnix.com/wp-content/uploads/2019/06/Tmux-session.png
|
||||||
|
[4]: https://www.ostechnix.com/wp-content/uploads/2019/06/Named-Tmux-session.png
|
||||||
|
[5]: https://www.ostechnix.com/wp-content/uploads/2019/06/List-Tmux-sessions.png
|
||||||
|
[6]: https://www.ostechnix.com/wp-content/uploads/2019/06/Create-detached-sessions.png
|
||||||
|
[7]: https://www.ostechnix.com/wp-content/uploads/2019/06/Horizontal-split.png
|
||||||
|
[8]: https://www.ostechnix.com/wp-content/uploads/2019/06/Vertical-split.png
|
||||||
|
[9]: https://www.ostechnix.com/wp-content/uploads/2019/06/Split-Panes.png
|
||||||
|
[10]: https://www.ostechnix.com/wp-content/uploads/2019/06/Kill-panes.png
|
@ -0,0 +1,72 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (scvoet)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13115-1.html)
|
||||||
|
[#]: subject: (Where are all the IoT experts going to come from?)
|
||||||
|
[#]: via: (https://www.networkworld.com/article/3404489/where-are-all-the-iot-experts-going-to-come-from.html)
|
||||||
|
[#]: author: (Fredric Paul https://www.networkworld.com/author/Fredric-Paul/)
|
||||||
|
|
||||||
|
物联网专家都从何而来?
|
||||||
|
======
|
||||||
|
|
||||||
|
> 物联网(IoT)的快速发展催生了对跨职能专家进行培养的需求,这些专家可以将传统的网络和基础设施专业知识与数据库和报告技能相结合。
|
||||||
|
|
||||||
|
![Kevin \(CC0\)][1]
|
||||||
|
|
||||||
|
如果物联网(IoT)要实现其宏伟的诺言,它将需要大量聪明、熟练、**训练有素**的工人军团来实现这一切。而现在,这些人将从何而来尚不清楚。
|
||||||
|
|
||||||
|
这就是我为什么有兴趣同资产优化软件公司 [AspenTech][2] 的产品管理、研发高级总监 Keith Flynn 通邮件的原因,他说,当处理大量属于物联网范畴的新技术时,你需要能够理解如何配置技术和解释数据的人。Flynn 认为,现有的教育机构对物联网特定课程的需求越来越大,这同时也给了以物联网为重点,提供了完善课程的新私立学院机会。
|
||||||
|
|
||||||
|
Flynn 跟我说,“在未来,物联网项目将与如今普遍的数据管理和自动化项目有着巨大的不同……未来需要更全面的技能和交叉交易能力,这样我们才会说同一种语言。”
|
||||||
|
|
||||||
|
Flynn 补充说,随着物联网每年增长 30%,将不再依赖于几个特定的技能,“从传统的部署技能(如网络和基础设施)到数据库和报告技能,坦白说,甚至是基础数据科学,都将需要一起理解和使用。”
|
||||||
|
|
||||||
|
### 召集所有物联网顾问
|
||||||
|
|
||||||
|
Flynn 预测,“受过物联网教育的人的第一个大机会将会是在咨询领域,随着咨询公司对行业趋势的适应或淘汰……有受过物联网培训的员工将有助于他们在物联网项目中的定位,并在新的业务线中提出要求——物联网咨询。”
|
||||||
|
|
||||||
|
对初创企业和小型公司而言,这个问题尤为严重。“组织越大,他们越有可能雇佣到不同技术类别的人”Flynn 这样说到,“但对于较小的组织和较小的物联网项目来说,你则需要一个能同时兼顾的人。”
|
||||||
|
|
||||||
|
两者兼而有之?还是**一应俱全?**物联网“需要将所有知识和技能组合在一起”,Flynn 说到,“并不是所有技能都是全新的,只是在此之前从来没有被归纳在一起或放在一起教授过。”
|
||||||
|
|
||||||
|
### 未来的物联网专家
|
||||||
|
|
||||||
|
Flynn 表示,真正的物联网专业技术是从基础的仪器仪表和电气技能开始的,这能帮助工人发明新的无线发射器或提升技术,以提高电池寿命和功耗。
|
||||||
|
|
||||||
|
“IT 技能,如网络、IP 寻址、子网掩码、蜂窝和卫星也是物联网的关键需求”,Flynn 说。他还认为物联网需要数据库管理技能和云管理和安全专业知识,“特别是当高级过程控制(APC)将传感器数据直接发送到数据库和数据湖等事情成为常态时。”
|
||||||
|
|
||||||
|
### 物联网专家又从何而来?
|
||||||
|
|
||||||
|
Flynn 说,标准化的正规教育课程将是确保毕业生或证书持有者掌握一套正确技能的最佳途径。他甚至还列出了一个样本课程。“按时间顺序开始,从基础知识开始,比如 [电气仪表] 和测量。然后讲授网络知识,数据库管理和云计算课程都应在此之后开展。这个学位甚至可以循序渐进至现有的工程课程中,这可能需要两年时间……来完成物联网部分的学业。”
|
||||||
|
|
||||||
|
虽然企业培训也能发挥作用,但实际上却是“说起来容易做起来难”,Flynn 这样警告,“这些培训需要针对组织的具体努力而推动。”
|
||||||
|
|
||||||
|
当然,现在市面上已经有了 [大量的在线物联网培训课程和证书课程][5]。但追根到底,这一工作全都依赖于工人自身的推断。
|
||||||
|
|
||||||
|
“在这个世界上,随着科技不断改变行业,提升技能是非常重要的”,Flynn 说,“如果这种提升技能的推动力并不是来源于你的雇主,那么在线课程和认证将会是提升你自己很好的一个方式。我们只需要创建这些课程……我甚至可以预见组织将与提供这些课程的高等教育机构合作,让他们的员工更好地开始。当然,物联网课程的挑战在于它需要不断发展以跟上科技的发展。”
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.networkworld.com/article/3404489/where-are-all-the-iot-experts-going-to-come-from.html
|
||||||
|
|
||||||
|
作者:[Fredric Paul][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Percy (@scvoet)](https://github.com/scvoet)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://www.networkworld.com/author/Fredric-Paul/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://images.idgesg.net/images/article/2018/07/programmer_certification-skills_code_devops_glasses_student_by-kevin-unsplash-100764315-large.jpg
|
||||||
|
[2]: https://www.aspentech.com/
|
||||||
|
[3]: https://www.networkworld.com/article/3276025/careers/20-hot-jobs-ambitious-it-pros-should-shoot-for.html
|
||||||
|
[4]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fpaths%2Fupgrading-your-technology-career
|
||||||
|
[5]: https://www.google.com/search?client=firefox-b-1-d&q=iot+training
|
||||||
|
[6]: https://www.networkworld.com/article/3254185/internet-of-things/tips-for-securing-iot-on-your-network.html#nww-fsb
|
||||||
|
[7]: https://www.networkworld.com/article/2287045/internet-of-things/wireless-153629-10-most-powerful-internet-of-things-companies.html#nww-fsb
|
||||||
|
[8]: https://www.networkworld.com/article/3243928/internet-of-things/what-is-the-industrial-iot-and-why-the-stakes-are-so-high.html#nww-fsb
|
||||||
|
[9]: https://www.networkworld.com/newsletters/signup.html#nww-fsb
|
||||||
|
[10]: https://www.facebook.com/NetworkWorld/
|
||||||
|
[11]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,98 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13096-1.html)
|
||||||
|
[#]: subject: (EndeavourOS Aims to Fill the Void Left by Antergos in Arch Linux World)
|
||||||
|
[#]: via: (https://itsfoss.com/endeavouros/)
|
||||||
|
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||||
|
|
||||||
|
EndeavourOS:填补 Antergos 在 ArchLinux 世界留下的空白
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/07/225558rdb85bmm6uumro71.jpg)
|
||||||
|
|
||||||
|
我相信我们的大多数读者都知道 [Antergos 项目的终结][2]。在这一消息宣布之后,Antergos 社区的成员创建了几个发行版来继承 Antergos。今天,我们将着眼于 Antergos 的“精神继承人”之一:[EndeavourOS][3]。
|
||||||
|
|
||||||
|
### EndeavourOS 不是 Antergos 的分支
|
||||||
|
|
||||||
|
在我们开始之前,我想非常明确地指出,EndeavourOS 并不是一个 Antergos 的复刻版本。开发者们以 Antergos 为灵感,创建了一个基于 Arch 的轻量级发行版。
|
||||||
|
|
||||||
|
![Endeavouros First Boot][4]
|
||||||
|
|
||||||
|
根据 [这个项目网站][5] 的说法,EndeavourOS 的诞生是因为 Antergos 社区的人们想要保持 Antergos 的精神。他们的目标很简单:“让 Arch 拥有一个易于使用的安装程序和一个友好、有帮助的社区,在掌握系统的过程中能够有一个社区可以依靠。”
|
||||||
|
|
||||||
|
与许多基于 Arch 的发行版不同,EndeavourOS 打算像 [原生 Arch][5] 那样使用,“所以没有一键式安装你喜欢的应用程序的解决方案,也没有一堆你最终不需要的预装应用程序。”对于大多数人来说,尤其是那些刚接触 Linux 和 Arch 的人,会有一个学习曲线,但 EndeavourOS 的目标是建立一个大型友好的社区,鼓励人们提出问题并了解他们的系统。
|
||||||
|
|
||||||
|
![Endeavouros Installing][6]
|
||||||
|
|
||||||
|
### 正在进行的工作
|
||||||
|
|
||||||
|
EndeavourOS 在 [2019 年 5 月 23 日首次宣布成立][8] 随后 [在 7 月 15 日发布第一个版本][7]。不幸的是,这意味着开发人员无法将他们计划的所有功能全部整合进来。(LCTT 译注:本文原文发表于 2019 年,而现在,EndeavourOS 还在持续活跃着。)
|
||||||
|
|
||||||
|
例如,他们想要一个类似于 Antergos 的在线安装,但却遇到了[当前选项的问题][9]。“Cnchi 运行在 Antergos 生态系统之外会造成严重的问题,需要彻底重写才能发挥作用。RebornOS 的 Fenix 安装程序还没有完全成型,需要更多时间才能正常运行。”于是现在,EndeavourOS 将会和 [Calamares 安装程序 ][10] 一起发布。
|
||||||
|
|
||||||
|
EndeavourOS 会提供 [比 Antergos 少的东西][9]:它的存储库比 Antergos 小,尽管他们会附带一些 AUR 包。他们的目标是提供一个接近 Arch 却不是原生 Arch 的系统。
|
||||||
|
|
||||||
|
![Endeavouros Updating With Kalu][12]
|
||||||
|
|
||||||
|
开发者[进一步声明 ][13]:
|
||||||
|
|
||||||
|
> “Linux,特别是 Arch,核心精神是自由选择,我们提供了一个基本的安装,让你在一个精细的层面上方便地探索各项选择。我们永远不会强行为你作决定,比如为你安装 GUI 应用程序,如 Pamac,甚至采用沙盒解决方案,如 Flatpak 或 Snaps。想安装成什么样子完全取决于你,这是我们与 Antergos 或 Manjaro 的主要区别,但与 Antergos 一样,如果你安装的软件包遇到问题,我们会尽力帮助你。”
|
||||||
|
|
||||||
|
### 体验 EndeavourOS
|
||||||
|
|
||||||
|
我在 [VirtualBox][14] 中安装了 EndeavourOS,并且研究了一番。当我第一次启动时,我看到一个窗口,里面有关于安装的 EndeavourOS 网站的链接。它还有一个安装按钮和一个手动分区工具。Calamares 安装程序的安装过程非常顺利。
|
||||||
|
|
||||||
|
在我重新启动到新安装的 EndeavourOS 之后,迎接我的是一个彩色主题的 XFCE 桌面。我还收到了一堆通知消息。我使用过的大多数基于 Arch 的发行版都带有一个 GUI 包管理器,比如 [pamac][15] 或 [octopi][16],以进行系统更新。EndeavourOS 配有 [kalu][17](kalu 是 “Keeping Arch Linux Up-to-date” 的缩写)。它可以更新软件包、可以看 Archlinux 新闻、可以更新 AUR 包等等。一旦它检查到有更新,它就会显示通知消息。
|
||||||
|
|
||||||
|
我浏览了一下菜单,看看默认安装了什么。默认的安装并不多,连办公套件都没有。他们想让 EndeavourOS 成为一块空白画布,让任何人都可以创建他们想要的系统。他们正朝着正确的方向前进。
|
||||||
|
|
||||||
|
![Endeavouros Desktop][18]
|
||||||
|
|
||||||
|
### 总结思考
|
||||||
|
|
||||||
|
EndeavourOS 还很年轻。第一个稳定版本都没有发布多久。它缺少一些东西,最重要的是一个在线安装程序。这就是说,我们无法估计他能够走到哪一步。(LCTT 译注:本文发表于 2019 年)
|
||||||
|
|
||||||
|
虽然它不是 Antergos 的精确复刻,但 EndeavourOS 希望复制 Antergos 最重要的部分——热情友好的社区。很多时候,Linux 社区对初学者似乎是不受欢迎甚至是完全敌对的。我看到越来越多的人试图与这种消极情绪作斗争,并将更多的人引入 Linux。随着 EndeavourOS 团队把焦点放在社区建设上,我相信一个伟大的发行版将会诞生。
|
||||||
|
|
||||||
|
如果你当前正在使用 Antergos,有一种方法可以让你[不用重装系统就切换到 EndeavourOS][20]
|
||||||
|
|
||||||
|
如果你想要一个 Antergos 的精确复刻,我建议你去看看 [RebornOS][21]。他们目前正在开发一个名为 Fenix 的 Cnchi 安装程序的替代品。
|
||||||
|
|
||||||
|
你试过 EndeavourOS 了吗?你的感受如何?
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/endeavouros/
|
||||||
|
|
||||||
|
作者:[John Paul][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[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://i1.wp.com/itsfoss.com/wp-content/uploads/2019/08/endeavouros-logo.png?ssl=1
|
||||||
|
[2]: https://itsfoss.com/antergos-linux-discontinued/
|
||||||
|
[3]: https://endeavouros.com/
|
||||||
|
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/08/endeavouros-first-boot.png?resize=800%2C600&ssl=1
|
||||||
|
[5]: https://endeavouros.com/info-2/
|
||||||
|
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/08/endeavouros-installing.png?resize=800%2C600&ssl=1
|
||||||
|
[7]: https://endeavouros.com/endeavouros-first-stable-release-has-arrived/
|
||||||
|
[8]: https://forum.antergos.com/topic/11780/endeavour-antergos-community-s-next-stage
|
||||||
|
[9]: https://endeavouros.com/what-to-expect-on-the-first-release/
|
||||||
|
[10]: https://calamares.io/
|
||||||
|
[11]: https://itsfoss.com/veltos-linux/
|
||||||
|
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/08/endeavouros-updating-with-kalu.png?resize=800%2C600&ssl=1
|
||||||
|
[13]: https://endeavouros.com/second-week-after-the-stable-release/
|
||||||
|
[14]: https://itsfoss.com/install-virtualbox-ubuntu/
|
||||||
|
[15]: https://aur.archlinux.org/packages/pamac-aur/
|
||||||
|
[16]: https://octopiproject.wordpress.com/
|
||||||
|
[17]: https://github.com/jjk-jacky/kalu
|
||||||
|
[18]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/08/endeavouros-desktop.png?resize=800%2C600&ssl=1
|
||||||
|
[19]: https://itsfoss.com/clear-linux/
|
||||||
|
[20]: https://forum.endeavouros.com/t/how-to-switch-from-antergos-to-endevouros/105/2
|
||||||
|
[21]: https://rebornos.org/
|
@ -0,0 +1,72 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (stevenzdg988)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13082-1.html)
|
||||||
|
[#]: subject: (The importance of consistency in your Python code)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-consistency)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
Python 代码一致性的重要性
|
||||||
|
======
|
||||||
|
|
||||||
|
> 本文是 Python 之禅特殊系列的一部分,重点是第十二、十三和十四原则:模糊性和明确性的作用。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/03/231758po1lcicxmxyjxlba.jpg)
|
||||||
|
|
||||||
|
最小惊喜原则是设计用户界面时的一个 [准则][2]。它是说,当用户执行某项操作时,程序执行的事情应该使用户尽量少地感到意外。这和孩子们喜欢一遍又一遍地读同一本书的原因是一样的:没有什么比能够预测并让预测成真更让人欣慰的了。
|
||||||
|
|
||||||
|
在开发 [ABC 语言][3](Python 的灵感来源)的过程中,一个重要的见解是,编程设计是用户界面,需要使用与 UI 设计者相同的工具来设计。值得庆幸的是,从那以后,越来越多的语言采用了 UI 设计中的<ruby>可承受性<rt>affordance</rt></ruby>和<ruby>人体工程学<rt>ergonomics</rt></ruby>的概念,即使它们的应用并不严格。
|
||||||
|
|
||||||
|
这就引出了 [Python 之禅][4] 中的三个原则。
|
||||||
|
|
||||||
|
### <ruby>面对歧义,要拒绝猜测的诱惑<rt>In the face of ambiguity, refuse the temptation to guess</rt></ruby>
|
||||||
|
|
||||||
|
`1 + "1"` 的结果应该是什么? `"11"` 和 `2` 都是猜测。这种表达方式是*歧义的*:无论如何做都会让一些人感到惊讶。
|
||||||
|
|
||||||
|
一些语言选择猜测。在 JavaScript 中,结果为 `"11"`。在 Perl 中,结果为 `2`。在 C 语言中,结果自然是空字符串。面对歧义,JavaScript、Perl 和 C 都在猜测。
|
||||||
|
|
||||||
|
在 Python 中,这会引发 `TypeError`:这不是能忽略的错误。捕获 `TypeError` 是非典型的:它通常将终止程序或至少终止当前任务(例如,在大多数 Web 框架中,它将终止对当前请求的处理)。
|
||||||
|
|
||||||
|
Python 拒绝猜测 `1 + "1"` 的含义。程序员必须以明确的意图编写代码:`1 + int("1")`,即 `2`;或者 `str(1) + "1"`,即 `"11"`;或 `"1"[1:]`,这将是一个空字符串。通过拒绝猜测,Python 使程序更具可预测性。
|
||||||
|
|
||||||
|
### <ruby>尽量找一种,最好是唯一一种明显的解决方案<rt>There should be one—and preferably only one—obvious way to do it</rt></ruby>
|
||||||
|
|
||||||
|
预测也会出现偏差。给定一个任务,你能预知要实现该任务的代码吗?当然,不可能完美地预测。毕竟,编程是一项具有创造性的任务。
|
||||||
|
|
||||||
|
但是,不必有意提供多种冗余方式来实现同一目标。从某种意义上说,某些解决方案或许 “更好” 或 “更 <ruby>Python 化<rt>Pythonic</rt></ruby>”。
|
||||||
|
|
||||||
|
对 Python 美学欣赏部分是因为,可以就哪种解决方案更好进行健康的辩论。甚至可以持不同观点而继续编程。甚至为使其达成一致,接受不同意的观点也是可以的。但在这一切之下,必须有一种这样的认识,即正确的解决方案终将会出现。我们必须希望,通过商定实现目标的最佳方法,而最终达成真正的一致。
|
||||||
|
|
||||||
|
### <ruby>虽然这种方式一开始可能并不明显(除非你是荷兰人)<rt>Although that way may not be obvious at first (unless you're Dutch)</rt></ruby>
|
||||||
|
|
||||||
|
这是一个重要的警告:首先,实现任务的最佳方法往往*不*明显。观念在不断发展。Python 也在进化。逐块读取文件的最好方法,可能要等到 Python 3.8 时使用 [walrus 运算符][5](`:=`)。
|
||||||
|
|
||||||
|
逐块读取文件这样常见的任务,在 Python 存在近 *30年* 的历史中并没有 “唯一的最佳方法”。
|
||||||
|
|
||||||
|
当我在 1998 年从 Python 1.5.2 开始使用 Python 时,没有一种逐行读取文件的最佳方法。多年来,知道字典中是否有某个键的最佳方法是使用关键字 `.haskey`,直到 `in` 操作符出现才发生改变。
|
||||||
|
|
||||||
|
只是要意识到找到实现目标的一种(也是唯一一种)方法可能需要 30 年的时间来尝试其它方法,Python 才可以不断寻找这些方法。这种历史观认为,为了做一件事用上 30 年是可以接受的,但对于美国这个存在仅 200 多年的国家来说,人们常常会感到不习惯。
|
||||||
|
|
||||||
|
从 Python 之禅的这一部分来看,荷兰人,无论是 Python 的创造者 [Guido van Rossum][6] 还是著名的计算机科学家 [Edsger W. Dijkstra][7],他们的世界观是不同的。要理解这一部分,某种程度的欧洲人对时间的感受是必不可少的。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-consistency
|
||||||
|
|
||||||
|
作者:[Moshe Zadka][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/moshez
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_other11x_cc.png?itok=I_kCDYj0 (Two animated computers waving one missing an arm)
|
||||||
|
[2]: https://www.uxpassion.com/blog/the-principle-of-least-surprise/
|
||||||
|
[3]: https://en.wikipedia.org/wiki/ABC_(programming_language)
|
||||||
|
[4]: https://www.python.org/dev/peps/pep-0020/
|
||||||
|
[5]: https://www.python.org/dev/peps/pep-0572/#abstract
|
||||||
|
[6]: https://en.wikipedia.org/wiki/Guido_van_Rossum
|
||||||
|
[7]: http://en.wikipedia.org/wiki/Edsger_W._Dijkstra
|
@ -0,0 +1,45 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13103-1.html)
|
||||||
|
[#]: subject: (The Zen of Python: Why timing is everything)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-timeliness)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
Python 之禅:时机最重要
|
||||||
|
======
|
||||||
|
|
||||||
|
> 这是 Python 之禅特别系列的一部分,重点是第十五和第十六条原则:现在与将来。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/09/231557dkuzz22ame4ja2jj.jpg)
|
||||||
|
|
||||||
|
Python 一直在不断发展。Python 社区对特性请求的渴求是无止境的,对现状也总是不满意的。随着 Python 越来越流行,这门语言的变化会影响到更多的人。
|
||||||
|
|
||||||
|
确定什么时候该进行变化往往很难,但 [Python 之禅][2] 给你提供了指导。
|
||||||
|
|
||||||
|
### <ruby>现在有总比永远没有好<rt>Now is better than never</rt></ruby>
|
||||||
|
|
||||||
|
总有一种诱惑,就是要等到事情完美才去做,虽然,它们永远没有完美的一天。当它们看起来已经“准备”得足够好了,那就大胆采取行动吧,去做出改变吧。无论如何,变化总是发生在*某个*现在:拖延的唯一作用就是把它移到未来的“现在”。
|
||||||
|
|
||||||
|
### <ruby>虽然将来总比现在好<rt>Although never is often better than right now</rt></ruby>
|
||||||
|
|
||||||
|
然而,这并不意味着应该急于求成。从测试、文档、用户反馈等方面决定发布的标准。在变化就绪之前的“现在”,并不是一个好时机。
|
||||||
|
|
||||||
|
这不仅对 Python 这样的流行语言是个很好的经验,对你个人的小开源项目也是如此。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-timeliness
|
||||||
|
|
||||||
|
作者:[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/desk_clock_job_work.jpg?itok=Nj4fuhl6 (Clock, pen, and notepad on a desk)
|
||||||
|
[2]: https://www.python.org/dev/peps/pep-0020/
|
@ -0,0 +1,47 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13116-1.html)
|
||||||
|
[#]: subject: (How to tell if implementing your Python code is a good idea)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-implementation)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
如何判断你的 Python 代码实现是否合适?
|
||||||
|
======
|
||||||
|
|
||||||
|
> 这是 Python 之禅特别系列的一部分,重点介绍第十七和十八条原则:困难和容易。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/14/120518rjkwvjs76p9d1911.jpg)
|
||||||
|
|
||||||
|
一门语言并不是抽象存在的。每一个语言功能都必须用代码来实现。承诺一些功能是很容易的,但实现起来就会很麻烦。复杂的实现意味着更多潜在的 bug,甚至更糟糕的是,会带来日复一日的维护负担。
|
||||||
|
|
||||||
|
对于这个难题,[Python 之禅][2] 中有答案。
|
||||||
|
|
||||||
|
### <ruby>如果一个实现难以解释,那就是个坏思路<rt>If the implementation is hard to explain, it's a bad idea</rt></ruby>
|
||||||
|
|
||||||
|
编程语言最重要的是可预测性。有时我们用抽象的编程模型来解释某个结构的语义,而这些模型与实现并不完全对应。然而,最好的释义就是*解释该实现*。
|
||||||
|
|
||||||
|
如果该实现很难解释,那就意味着这条路行不通。
|
||||||
|
|
||||||
|
### <ruby>如果一个实现易于解释,那它可能是一个好思路<rt>If the implementation is easy to explain, it may be a good idea</rt></ruby>
|
||||||
|
|
||||||
|
仅仅因为某事容易,并不意味着它值得。然而,一旦解释清楚,判断它是否是一个好思路就容易得多。
|
||||||
|
|
||||||
|
这也是为什么这个原则的后半部分故意含糊其辞的原因:没有什么可以肯定一定是好的,但总是可以讨论一下。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-implementation
|
||||||
|
|
||||||
|
作者:[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/devops_confusion_wall_questions.png?itok=zLS7K2JG (Brick wall between two people, a developer and an operations manager)
|
||||||
|
[2]: https://www.python.org/dev/peps/pep-0020/
|
@ -0,0 +1,58 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13123-1.html)
|
||||||
|
[#]: subject: (Namespaces are the shamash candle of the Zen of Python)
|
||||||
|
[#]: via: (https://opensource.com/article/19/12/zen-python-namespaces)
|
||||||
|
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||||
|
|
||||||
|
命名空间是 Python 之禅的精髓
|
||||||
|
======
|
||||||
|
|
||||||
|
> 这是 Python 之禅特别系列的一部分,重点是一个额外的原则:命名空间。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/16/105800d64ceaeertt4u4ee.jpg)
|
||||||
|
|
||||||
|
著名的<ruby>光明节<rt>Hanukkah</rt></ruby>有八个晚上的庆祝活动。然而,光明节的灯台有九根蜡烛:八根普通的蜡烛和总是偏移的第九根蜡烛。它被称为 “shamash” 或 “shamos”,大致可以翻译为“仆人”或“看门人”的意思。
|
||||||
|
|
||||||
|
shamos 是点燃所有其它蜡烛的蜡烛:它是唯一一支可以用火的蜡烛,而不仅仅是观看。当我们结束 Python 之禅系列时,我看到命名空间提供了类似的作用。
|
||||||
|
|
||||||
|
### Python 中的命名空间
|
||||||
|
|
||||||
|
Python 使用命名空间来处理一切。虽然简单,但它们是稀疏的数据结构 —— 这通常是实现目标的最佳方式。
|
||||||
|
|
||||||
|
> *命名空间* 是一个从名字到对象的映射。
|
||||||
|
>
|
||||||
|
> —— [Python.org][2]
|
||||||
|
|
||||||
|
模块是命名空间。这意味着正确地预测模块语义通常只需要熟悉 Python 命名空间的工作方式。类是命名空间,对象是命名空间。函数可以访问它们的本地命名空间、父命名空间和全局命名空间。
|
||||||
|
|
||||||
|
这个简单的模型,即用 `.` 操作符访问一个对象,而这个对象又通常(但并不总是)会进行某种字典查找,这使得 Python 很难优化,但很容易解释。
|
||||||
|
|
||||||
|
事实上,一些第三方模块也采取了这个准则,并以此来运行。例如,[variants][3] 包把函数变成了“相关功能”的命名空间。这是一个很好的例子,说明 [Python 之禅][4] 是如何激发新的抽象的。
|
||||||
|
|
||||||
|
### 结语
|
||||||
|
|
||||||
|
感谢你和我一起参加这次以光明节为灵感的 [我最喜欢的语言][5] 的探索。
|
||||||
|
|
||||||
|
静心参禅,直至悟道。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/19/12/zen-python-namespaces
|
||||||
|
|
||||||
|
作者:[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/computer_code_programming_laptop.jpg?itok=ormv35tV (Person programming on a laptop on a building)
|
||||||
|
[2]: https://docs.python.org/3/tutorial/classes.html
|
||||||
|
[3]: https://pypi.org/project/variants/
|
||||||
|
[4]: https://www.python.org/dev/peps/pep-0020/
|
||||||
|
[5]: https://opensource.com/article/19/10/why-love-python
|
@ -0,0 +1,344 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "MjSeven"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13142-1.html"
|
||||||
|
[#]: subject: "Ansible Automation Tool Installation, Configuration and Quick Start Guide"
|
||||||
|
[#]: via: "https://www.2daygeek.com/install-configure-ansible-automation-tool-linux-quick-start-guide/"
|
||||||
|
[#]: author: "Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/"
|
||||||
|
|
||||||
|
Ansible 自动化工具安装、配置和快速入门指南
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/22/124803cgryrgxqezjllfqg.jpg)
|
||||||
|
|
||||||
|
市面上有很多自动化工具。我可以举几个例子,例如 Puppet、Chef、CFEngine、Foreman、Katello、Saltstock、Space Walk,它们被许多组织广泛使用。
|
||||||
|
|
||||||
|
### 自动化工具可以做什么?
|
||||||
|
|
||||||
|
自动化工具可以自动执行例行任务,无需人工干预,从而使 Linux 管理员的工作变得更加轻松。这些工具允许用户执行配置管理,应用程序部署和资源调配。
|
||||||
|
|
||||||
|
### 为什么喜欢 Ansible?
|
||||||
|
|
||||||
|
Ansible 是一种无代理的自动化工具,使用 SSH 执行所有任务,但其它工具需要在客户端节点上安装代理。
|
||||||
|
|
||||||
|
### 什么是 Ansible?
|
||||||
|
|
||||||
|
Ansible 是一个开源、易于使用的功能强大的 IT 自动化工具,通过 SSH 在客户端节点上执行任务。
|
||||||
|
|
||||||
|
它是用 Python 构建的,这是当今世界上最流行、最强大的编程语言之一。两端都需要使用 Python 才能执行所有模块。
|
||||||
|
|
||||||
|
它可以配置系统、部署软件和安排高级 IT 任务,例如连续部署或零停机滚动更新。你可以通过 Ansible 轻松执行任何类型的自动化任务,包括简单和复杂的任务。
|
||||||
|
|
||||||
|
在开始之前,你需要了解一些 Ansible 术语,这些术语可以帮助你更好的创建任务。
|
||||||
|
|
||||||
|
### Ansible 如何工作?
|
||||||
|
|
||||||
|
Ansible 通过在客户端节点上推送称为 ansible 模块的小程序来工作,这些模块临时存储在客户端节点中,通过 JSON 协议与 Ansible 服务器进行通信。
|
||||||
|
|
||||||
|
Ansible 通过 SSH 运行这些模块,并在完成后将其删除。
|
||||||
|
|
||||||
|
模块是用 Python 或 Perl 等编写的一些脚本。
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
*控制节点,用于控制剧本的全部功能,包括客户端节点(主机)。*
|
||||||
|
|
||||||
|
* <ruby>控制节点<rt>Control node</rt></ruby>:使用 Ansible 在受控节点上执行任务的主机。你可以有多个控制节点,但不能使用 Windows 系统主机当作控制节点。
|
||||||
|
* <ruby>受控节点<rt>Managed node</rt></ruby>:控制节点配置的主机列表。
|
||||||
|
* <ruby>清单<rt>Inventory</rt></ruby>:控制节点管理的一个主机列表,这些节点在 `/etc/ansible/hosts` 文件中配置。它包含每个节点的信息,比如 IP 地址或其主机名,还可以根据需要对这些节点进行分组。
|
||||||
|
* <ruby>模块<rt>Module</rt></ruby>:每个模块用于执行特定任务,目前有 3387 个模块。
|
||||||
|
* <ruby>点对点<rt>ad-hoc</rt></ruby>:它允许你一次性运行一个任务,它使用 `/usr/bin/ansible` 二进制文件。
|
||||||
|
* <ruby>任务<rt>Task</rt></ruby>:每个<ruby>动作<rt>Play</rt></ruby>都有一个任务列表。任务按顺序执行,在受控节点中一次执行一个任务。
|
||||||
|
* <ruby>剧本<rt>Playbook</rt></ruby>:你可以使用剧本同时执行多个任务,而使用点对点只能执行一个任务。剧本使用 YAML 编写,易于阅读。将来,我们将会写一篇有关剧本的文章,你可以用它来执行复杂的任务。
|
||||||
|
|
||||||
|
### 测试环境
|
||||||
|
|
||||||
|
此环境包含一个控制节点(`server.2g.lab`)和三个受控节点(`node1.2g.lab`、`node2.2g.lab`、`node3.2g.lab`),它们均在虚拟环境中运行,操作系统分别为:
|
||||||
|
|
||||||
|
| System Purpose | Hostname | IP Address | OS |
|
||||||
|
|----------------------|---------------|-------------|---------------|
|
||||||
|
| Ansible Control Node | server.2g.lab | 192.168.1.7 | Manjaro 18 |
|
||||||
|
| Managed Node1 | node1.2g.lab | 192.168.1.6 | CentOS7 |
|
||||||
|
| Managed Node2 | node2.2g.lab | 192.168.1.5 | CentOS8 |
|
||||||
|
| Managed Node3 | node3.2g.lab | 192.168.1.9 | Ubuntu 18.04 |
|
||||||
|
| User: daygeek |
|
||||||
|
|
||||||
|
### 前置条件
|
||||||
|
|
||||||
|
* 在 Ansible 控制节点和受控节点之间启用无密码身份验证。
|
||||||
|
* 控制节点必须是 Python 2(2.7 版本) 或 Python 3(3.5 或更高版本)。
|
||||||
|
* 受控节点必须是 Python 2(2.6 或更高版本) 或 Python 3(3.5 或更高版本)。
|
||||||
|
* 如果在远程节点上启用了 SELinux,则在 Ansible 中使用任何与复制、文件、模板相关的功能之前,还需要在它们上安装 `libselinux-python`。
|
||||||
|
|
||||||
|
### 如何在控制节点上安装 Ansible
|
||||||
|
|
||||||
|
对于 Fedora/RHEL 8/CentOS 8 系统,使用 [DNF 命令][2] 来安装 Ansible。
|
||||||
|
|
||||||
|
注意:你需要在 RHEL/CentOS 系统上启用 [EPEL 仓库][3],因为 Ansible 软件包在发行版官方仓库中不可用。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo dnf install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][4] 或 [APT 命令][5] 来安装 Ansible。
|
||||||
|
|
||||||
|
配置下面的 PPA 以便在 Ubuntu 上安装最新稳定版本的 Ansible。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt install software-properties-common
|
||||||
|
$ sudo apt-add-repository --yes --update ppa:ansible/ansible
|
||||||
|
$ sudo apt install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 Debian 系统,配置以下源列表:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" | sudo tee -a /etc/apt/sources.list.d/ansible.list
|
||||||
|
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 Arch Linux 系统,使用 [Pacman 命令][6] 来安装 Ansible:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo pacman -S ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 RHEL/CentOS 系统,使用 [YUM 命令][7] 来安装 Ansible:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 openSUSE 系统,使用 [Zypper 命令][8] 来安装 Ansible:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo zypper install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
或者,你可以使用 [Python PIP 包管理工具][9] 来安装:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
|
||||||
|
$ sudo python get-pip.py
|
||||||
|
$ sudo pip install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
在控制节点上检查安装的 Ansible 版本:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible --version
|
||||||
|
|
||||||
|
ansible 2.9.2
|
||||||
|
config file = /etc/ansible/ansible.cfg
|
||||||
|
configured module search path = ['/home/daygeek/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
|
||||||
|
ansible python module location = /usr/lib/python3.8/site-packages/ansible
|
||||||
|
executable location = /usr/bin/ansible
|
||||||
|
python version = 3.8.1 (default, Jan 8 2020, 23:09:20) [GCC 9.2.0]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 如何在受控节点上安装 Python?
|
||||||
|
|
||||||
|
使用以下命令在受控节点上安装 python:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo yum install -y python
|
||||||
|
$ sudo dnf install -y python
|
||||||
|
$ sudo zypper install -y python
|
||||||
|
$ sudo pacman -S python
|
||||||
|
$ sudo apt install -y python
|
||||||
|
```
|
||||||
|
|
||||||
|
### 如何在 Linux 设置 SSH 密钥身份验证(无密码身份验证)
|
||||||
|
|
||||||
|
使用以下命令创建 ssh 密钥,然后将其复制到远程计算机。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ssh-keygen
|
||||||
|
$ ssh-copy-id daygeek@node1.2g.lab
|
||||||
|
$ ssh-copy-id daygeek@node2.2g.lab
|
||||||
|
$ ssh-copy-id daygeek@node3.2g.lab
|
||||||
|
```
|
||||||
|
|
||||||
|
具体参考这篇文章《[在 Linux 上设置 SSH 密钥身份验证(无密码身份验证)][10]》。
|
||||||
|
|
||||||
|
### 如何创建 Ansible 主机清单
|
||||||
|
|
||||||
|
在 `/etc/ansible/hosts` 文件中添加要管理的节点列表。如果没有该文件,则可以创建一个新文件。以下是我的测试环境的主机清单文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo vi /etc/ansible/hosts
|
||||||
|
|
||||||
|
[web]
|
||||||
|
node1.2g.lab
|
||||||
|
node2.2g.lab
|
||||||
|
|
||||||
|
[app]
|
||||||
|
node3.2g.lab
|
||||||
|
```
|
||||||
|
|
||||||
|
让我们看看是否可以使用以下命令查找所有主机。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible all --list-hosts
|
||||||
|
|
||||||
|
hosts (3):
|
||||||
|
node1.2g.lab
|
||||||
|
node2.2g.lab
|
||||||
|
node3.2g.lab
|
||||||
|
```
|
||||||
|
|
||||||
|
对单个组运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web --list-hosts
|
||||||
|
|
||||||
|
hosts (2):
|
||||||
|
node1.2g.lab
|
||||||
|
node2.2g.lab
|
||||||
|
```
|
||||||
|
|
||||||
|
### 如何使用点对点命令执行任务
|
||||||
|
|
||||||
|
一旦完成主机清单验证检查后,你就可以上路了。干的漂亮!
|
||||||
|
|
||||||
|
**语法:**
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible [pattern] -m [module] -a "[module options]"
|
||||||
|
|
||||||
|
Details:
|
||||||
|
========
|
||||||
|
ansible: A command
|
||||||
|
pattern: Enter the entire inventory or a specific group
|
||||||
|
-m [module]: Run the given module name
|
||||||
|
-a [module options]: Specify the module arguments
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 Ping 模块对主机清单中的所有节点执行 ping 操作:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible all -m ping
|
||||||
|
|
||||||
|
node3.2g.lab | SUCCESS => {
|
||||||
|
"ansible_facts": {
|
||||||
|
"discovered_interpreter_python": "/usr/bin/python"
|
||||||
|
},
|
||||||
|
"changed": false,
|
||||||
|
"ping": "pong"
|
||||||
|
}
|
||||||
|
node1.2g.lab | SUCCESS => {
|
||||||
|
"ansible_facts": {
|
||||||
|
"discovered_interpreter_python": "/usr/bin/python"
|
||||||
|
},
|
||||||
|
"changed": false,
|
||||||
|
"ping": "pong"
|
||||||
|
}
|
||||||
|
node2.2g.lab | SUCCESS => {
|
||||||
|
"ansible_facts": {
|
||||||
|
"discovered_interpreter_python": "/usr/libexec/platform-python"
|
||||||
|
},
|
||||||
|
"changed": false,
|
||||||
|
"ping": "pong"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
所有系统都返回了成功,但什么都没有改变,只返回了 `pong` 代表成功。
|
||||||
|
|
||||||
|
你可以使用以下命令获取可用模块的列表。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible-doc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
当前有 3387 个内置模块,它们会随着 Ansible 版本的递增而增加:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible-doc -l | wc -l
|
||||||
|
3387
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 command 模块对主机清单中的所有节点执行命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible all -m command -a "uptime"
|
||||||
|
|
||||||
|
node3.2g.lab | CHANGED | rc=0 >>
|
||||||
|
18:05:07 up 1:21, 3 users, load average: 0.12, 0.06, 0.01
|
||||||
|
node1.2g.lab | CHANGED | rc=0 >>
|
||||||
|
06:35:06 up 1:21, 4 users, load average: 0.01, 0.03, 0.05
|
||||||
|
node2.2g.lab | CHANGED | rc=0 >>
|
||||||
|
18:05:07 up 1:25, 3 users, load average: 0.01, 0.01, 0.00
|
||||||
|
```
|
||||||
|
|
||||||
|
对指定组执行 command 模块。
|
||||||
|
|
||||||
|
检查 app 组主机的内存使用情况:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible app -m command -a "free -m"
|
||||||
|
|
||||||
|
node3.2g.lab | CHANGED | rc=0 >>
|
||||||
|
total used free shared buff/cache available
|
||||||
|
Mem: 1993 1065 91 6 836 748
|
||||||
|
Swap: 1425 0 1424
|
||||||
|
```
|
||||||
|
|
||||||
|
要对 web 组运行 `hostnamectl` 命令,使用以下格式:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m command -a "hostnamectl"
|
||||||
|
|
||||||
|
node1.2g.lab | CHANGED | rc=0 >>
|
||||||
|
Static hostname: CentOS7.2daygeek.com
|
||||||
|
Icon name: computer-vm
|
||||||
|
Chassis: vm
|
||||||
|
Machine ID: 002f47b82af248f5be1d67b67e03514c
|
||||||
|
Boot ID: dc38f9b8089d4b2d9304e526e00c6a8f
|
||||||
|
Virtualization: kvm
|
||||||
|
Operating System: CentOS Linux 7 (Core)
|
||||||
|
CPE OS Name: cpe:/o:centos:centos:7
|
||||||
|
Kernel: Linux 3.10.0-957.el7.x86_64
|
||||||
|
Architecture: x86-64
|
||||||
|
node2.2g.lab | CHANGED | rc=0 >>
|
||||||
|
Static hostname: node2.2g.lab
|
||||||
|
Icon name: computer-vm
|
||||||
|
Chassis: vm
|
||||||
|
Machine ID: e39e3a27005d44d8bcbfcab201480b45
|
||||||
|
Boot ID: 27b46a09dde546da95ace03420fe12cb
|
||||||
|
Virtualization: oracle
|
||||||
|
Operating System: CentOS Linux 8 (Core)
|
||||||
|
CPE OS Name: cpe:/o:centos:centos:8
|
||||||
|
Kernel: Linux 4.18.0-80.el8.x86_64
|
||||||
|
Architecture: x86-64
|
||||||
|
```
|
||||||
|
|
||||||
|
参考:[Ansible 文档][11]。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.2daygeek.com/install-configure-ansible-automation-tool-linux-quick-start-guide/
|
||||||
|
|
||||||
|
作者:[Magesh Maruthamuthu][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[MjSeven](https://github.com/MjSeven)
|
||||||
|
校对:[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/wp-content/uploads/2020/01/ansible-architecture-2daygeek.png
|
||||||
|
[2]: https://www.2daygeek.com/linux-dnf-command-examples-manage-packages-fedora-centos-rhel-systems/
|
||||||
|
[3]: https://www.2daygeek.com/install-enable-epel-repository-on-rhel-centos-oracle-linux/
|
||||||
|
[4]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||||
|
[5]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||||
|
[6]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||||
|
[7]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||||
|
[8]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||||
|
[9]: https://www.2daygeek.com/install-pip-manage-python-packages-linux/
|
||||||
|
[10]: https://www.2daygeek.com/configure-setup-passwordless-ssh-key-based-authentication-linux/
|
||||||
|
[11]: https://docs.ansible.com/ansible/latest/user_guide/index.html
|
@ -0,0 +1,294 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "MjSeven"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13163-1.html"
|
||||||
|
[#]: subject: "Ansible Ad-hoc Command Quick Start Guide with Examples"
|
||||||
|
[#]: via: "https://www.2daygeek.com/ansible-ad-hoc-command-quick-start-guide-with-examples/"
|
||||||
|
[#]: author: "Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/"
|
||||||
|
|
||||||
|
Ansible 点对点命令快速入门指南示例
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/28/221449b8ldh7v4ll8dw774.jpg)
|
||||||
|
|
||||||
|
之前,我们写了一篇有关 [Ansible 安装和配置][1] 的文章。在那个教程中只包含了一些使用方法的示例。如果你是 Ansible 新手,建议你阅读上篇文章。一旦你熟悉了,就可以继续阅读本文了。
|
||||||
|
|
||||||
|
默认情况下,Ansible 仅使用 5 个并行进程。如果要在多个主机上执行任务,需要通过添加 `-f [进程数]` 选项来手动设置进程数。
|
||||||
|
|
||||||
|
### 什么是<ruby>点对点<rt>ad-hoc</rt></ruby>命令?
|
||||||
|
|
||||||
|
点对点命令用于在一个或多个受控节点上自动执行任务。它非常简单,但是不可重用。它使用 `/usr/bin/ansible` 二进制文件执行所有操作。
|
||||||
|
|
||||||
|
点对点命令最适合运行一次的任务。例如,如果要检查指定用户是否可用,你可以使用一行命令而无需编写剧本。
|
||||||
|
|
||||||
|
#### 为什么你要了解点对点命令?
|
||||||
|
|
||||||
|
点对点命令证明了 Ansible 的简单性和强大功能。从 2.9 版本开始,它支持 3389 个模块,因此你需要了解和学习要定期使用的 Ansible 模块列表。
|
||||||
|
|
||||||
|
如果你是一个 Ansible 新手,可以借助点对点命令轻松地练习这些模块及参数。
|
||||||
|
|
||||||
|
你在这里学习到的概念将直接移植到剧本中。
|
||||||
|
|
||||||
|
**点对点命令的一般语法:**
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible [模式] -m [模块] -a "[模块选项]"
|
||||||
|
```
|
||||||
|
|
||||||
|
点对点命令包含四个部分,详细信息如下:
|
||||||
|
|
||||||
|
| 部分 | 描述 |
|
||||||
|
|----------|-----------------------------------|
|
||||||
|
| `ansible`| 命令 |
|
||||||
|
| 模式 | 输入清单或指定组 |
|
||||||
|
| 模块 | 运行指定的模块名称 |
|
||||||
|
| 模块选项 | 指定模块参数 |
|
||||||
|
|
||||||
|
#### 如何使用 Ansible 清单文件
|
||||||
|
|
||||||
|
如果使用 Ansible 的默认清单文件 `/etc/ansible/hosts`,你可以直接调用它。否则你可以使用 `-i` 选项指定 Ansible 清单文件的路径。
|
||||||
|
|
||||||
|
#### 什么是模式以及如何使用它?
|
||||||
|
|
||||||
|
Ansible 模式可以代指某个主机、IP 地址、清单组、一组主机或者清单中的所有主机。它允许你对它们运行命令和剧本。模式非常灵活,你可以根据需要使用它们。
|
||||||
|
|
||||||
|
例如,你可以排除主机、使用通配符或正则表达式等等。
|
||||||
|
|
||||||
|
下表描述了常见的模式以及用法。但是,如果它不能满足你的需求,你可以在 `ansible-playbook` 中使用带有 `-e` 参数的模式中的变量。
|
||||||
|
|
||||||
|
| 描述 | 模式 | 目标 |
|
||||||
|
|-----|------|-----|
|
||||||
|
| 所有主机 | `all`(或 `*`) | 对清单中的所有服务器运行 Ansible |
|
||||||
|
| 一台主机 | `host1` | 只针对给定主机运行 Ansible |
|
||||||
|
| 多台主机 | `host1:host2`(或 `host1,host2`)| 对上述多台主机运行 Ansible |
|
||||||
|
| 一组 | `webservers` | 在 `webservers` 群组中运行 Ansible |
|
||||||
|
| 多组 | `webservers:dbservers` | `webservers` 中的所有主机加上 `dbservers` 中的所有主机 |
|
||||||
|
| 排除组 | `webservers:!atlanta` | `webservers` 中除 `atlanta` 以外的所有主机 |
|
||||||
|
| 组之间的交集 | `webservers:&staging` | `webservers` 中也在 `staging` 的任何主机 |
|
||||||
|
|
||||||
|
#### 什么是 Ansible 模块,它干了什么?
|
||||||
|
|
||||||
|
模块,也称为“任务插件”或“库插件”,它是一组代码单元,可以直接或通过剧本在远程主机上执行指定任务。
|
||||||
|
|
||||||
|
Ansible 在远程目标节点上执行指定模块并收集其返回值。
|
||||||
|
|
||||||
|
每个模块都支持多个参数,可以满足用户的需求。除少数模块外,几乎所有模块都采用 `key=value` 参数。你可以一次添加带有空格的多个参数,而 `command` 或 `shell` 模块会直接运行你输入的字符串。
|
||||||
|
|
||||||
|
我们将添加一个包含最常用的“模块选项”参数的表。
|
||||||
|
|
||||||
|
列出所有可用的模块,运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible-doc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
运行以下命令来阅读指定模块的文档:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible-doc [模块]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1)如何在 Linux 上使用 Ansible 列出目录的内容
|
||||||
|
|
||||||
|
可以使用 Ansible `command` 模块来完成这项操作,如下所示。我们列出了 `node1.2g.lab` 和 `nod2.2g.lab`* 远程服务器上 `daygeek` 用户主目录的内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m command -a "ls -lh /home/daygeek"
|
||||||
|
|
||||||
|
node1.2g.lab | CHANGED | rc=0 >>
|
||||||
|
total 12K
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Desktop
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Documents
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Downloads
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Music
|
||||||
|
-rwxr-xr-x. 1 daygeek daygeek 159 Mar 4 2019 passwd-up.sh
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Pictures
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Public
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Templates
|
||||||
|
-rwxrwxr-x. 1 daygeek daygeek 138 Mar 10 2019 user-add.sh
|
||||||
|
-rw-rw-r--. 1 daygeek daygeek 18 Mar 10 2019 user-list1.txt
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Feb 15 2019 Videos
|
||||||
|
|
||||||
|
node2.2g.lab | CHANGED | rc=0 >>
|
||||||
|
total 0
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Desktop
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Documents
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Downloads
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Music
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Pictures
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Public
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Templates
|
||||||
|
drwxr-xr-x. 2 daygeek daygeek 6 Nov 9 09:55 Videos
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2)如何在 Linux 使用 Ansible 管理文件
|
||||||
|
|
||||||
|
Ansible 的 `copy` 模块将文件从本地系统复制到远程系统。使用 Ansible `command` 模块将文件移动或复制到远程计算机。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m copy -a "src=/home/daygeek/backup/CentOS7.2daygeek.com-20191025.tar dest=/home/u1" --become
|
||||||
|
|
||||||
|
node1.2g.lab | CHANGED => {
|
||||||
|
"ansible_facts": {
|
||||||
|
"discovered_interpreter_python": "/usr/bin/python"
|
||||||
|
},
|
||||||
|
"changed": true,
|
||||||
|
"checksum": "ad8aadc0542028676b5fe34c94347829f0485a8c",
|
||||||
|
"dest": "/home/u1/CentOS7.2daygeek.com-20191025.tar",
|
||||||
|
"gid": 0,
|
||||||
|
"group": "root",
|
||||||
|
"md5sum": "ee8e778646e00456a4cedd5fd6458cf5",
|
||||||
|
"mode": "0644",
|
||||||
|
"owner": "root",
|
||||||
|
"secontext": "unconfined_u:object_r:user_home_t:s0",
|
||||||
|
"size": 30720,
|
||||||
|
"src": "/home/daygeek/.ansible/tmp/ansible-tmp-1579726582.474042-118186643704900/source",
|
||||||
|
"state": "file",
|
||||||
|
"uid": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
node2.2g.lab | CHANGED => {
|
||||||
|
"ansible_facts": {
|
||||||
|
"discovered_interpreter_python": "/usr/libexec/platform-python"
|
||||||
|
},
|
||||||
|
"changed": true,
|
||||||
|
"checksum": "ad8aadc0542028676b5fe34c94347829f0485a8c",
|
||||||
|
"dest": "/home/u1/CentOS7.2daygeek.com-20191025.tar",
|
||||||
|
"gid": 0,
|
||||||
|
"group": "root",
|
||||||
|
"md5sum": "ee8e778646e00456a4cedd5fd6458cf5",
|
||||||
|
"mode": "0644",
|
||||||
|
"owner": "root",
|
||||||
|
"secontext": "unconfined_u:object_r:user_home_t:s0",
|
||||||
|
"size": 30720,
|
||||||
|
"src": "/home/daygeek/.ansible/tmp/ansible-tmp-1579726582.4793239-237229399335623/source",
|
||||||
|
"state": "file",
|
||||||
|
"uid": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
我们可以运行以下命令进行验证:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m command -a "ls -lh /home/u1" --become
|
||||||
|
|
||||||
|
node1.2g.lab | CHANGED | rc=0 >>
|
||||||
|
total 36K
|
||||||
|
-rw-r--r--. 1 root root 30K Jan 22 14:56 CentOS7.2daygeek.com-20191025.tar
|
||||||
|
-rw-r--r--. 1 root root 25 Dec 9 03:31 user-add.sh
|
||||||
|
|
||||||
|
node2.2g.lab | CHANGED | rc=0 >>
|
||||||
|
total 36K
|
||||||
|
-rw-r--r--. 1 root root 30K Jan 23 02:26 CentOS7.2daygeek.com-20191025.tar
|
||||||
|
-rw-rw-r--. 1 u1 u1 18 Jan 23 02:21 magi.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
要将文件从一个位置复制到远程计算机上的另一个位置,使用以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m command -a "cp /home/u2/magi/ansible-1.txt /home/u2/magi/2g" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
移动文件,使用以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m command -a "mv /home/u2/magi/ansible.txt /home/u2/magi/2g" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `u1` 用户目录下创建一个名为 `ansible.txt` 的新文件,运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m file -a "dest=/home/u1/ansible.txt owner=u1 group=u1 state=touch" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `u1` 用户目录下创建一个名为 `magi` 的新目录,运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m file -a "dest=/home/u1/magi mode=755 owner=u2 group=u2 state=directory" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
将 `u1` 用户目录下的 `ansible.txt`* 文件权限更改为 `777`,运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m file -a "dest=/home/u1/ansible.txt mode=777" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
删除 `u1` 用户目录下的 `ansible.txt` 文件,运行以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m file -a "dest=/home/u2/magi/ansible-1.txt state=absent" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
使用以下命令删除目录,它将递归删除指定目录:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m file -a "dest=/home/u2/magi/2g state=absent" --become
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3)用户管理
|
||||||
|
|
||||||
|
你可以使用 Ansible 轻松执行用户管理活动。例如创建、删除用户以及向一个组添加用户。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible all -m user -a "name=foo password=[crypted password here]"
|
||||||
|
```
|
||||||
|
|
||||||
|
运行以下命令删除用户:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible all -m user -a "name=foo state=absent"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4)管理包
|
||||||
|
|
||||||
|
使用合适的 Ansible 包管理器模块可以轻松地管理安装包。例如,我们将使用 `yum` 模块来管理 CentOS 系统上的软件包。
|
||||||
|
|
||||||
|
安装最新的 Apache(httpd):
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m yum -a "name=httpd state=latest"
|
||||||
|
```
|
||||||
|
|
||||||
|
卸载 Apache(httpd) 包:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m yum -a "name=httpd state=absent"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5)管理服务
|
||||||
|
|
||||||
|
使用以下 Ansible 模块命令可以在 Linux 上管理任何服务。
|
||||||
|
|
||||||
|
停止 httpd 服务:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m service -a "name=httpd state=stopped"
|
||||||
|
```
|
||||||
|
|
||||||
|
启动 httpd 服务:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m service -a "name=httpd state=started"
|
||||||
|
```
|
||||||
|
|
||||||
|
重启 httpd 服务:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ansible web -m service -a "name=httpd state=restarted"
|
||||||
|
```
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.2daygeek.com/ansible-ad-hoc-command-quick-start-guide-with-examples/
|
||||||
|
|
||||||
|
作者:[Magesh Maruthamuthu][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[MjSeven](https://github.com/MjSeven)
|
||||||
|
校对:[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://linux.cn/article-13142-1.html
|
@ -0,0 +1,244 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13099-1.html)
|
||||||
|
[#]: subject: (Getting Started With Pacman Commands in Arch-based Linux Distributions)
|
||||||
|
[#]: via: (https://itsfoss.com/pacman-command/)
|
||||||
|
[#]: author: (Dimitrios Savvopoulos https://itsfoss.com/author/dimitrios/)
|
||||||
|
|
||||||
|
Arch Linux 的 pacman 命令入门
|
||||||
|
======
|
||||||
|
|
||||||
|
> 这本初学者指南向你展示了在 Linux 中可以使用 pacman 命令做什么,如何使用它们来查找新的软件包,安装和升级新的软件包,以及清理你的系统。
|
||||||
|
|
||||||
|
[pacman][1] 包管理器是 [Arch Linux][2] 和其他主要发行版如 Red Hat 和 Ubuntu/Debian 之间的主要区别之一。它结合了简单的二进制包格式和易于使用的 [构建系统][3]。`pacman` 的目标是方便地管理软件包,无论它是来自 [官方库][4] 还是用户自己构建的软件库。
|
||||||
|
|
||||||
|
如果你曾经使用过 Ubuntu 或基于 debian 的发行版,那么你可能使用过 `apt-get` 或 `apt` 命令。`pacman` 在 Arch Linux 中是同样的命令。如果你 [刚刚安装了 Arch Linux][5],在安装 Arch Linux 后,首先要做的 [几件事][6] 之一就是学习使用 `pacman` 命令。
|
||||||
|
|
||||||
|
在这个初学者指南中,我将解释一些基本的 `pacman` 命令的用法,你应该知道如何用这些命令来管理你的基于 Archlinux 的系统。
|
||||||
|
|
||||||
|
### Arch Linux 用户应该知道的几个重要的 pacman 命令
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/09/111411uqadijqdd8afgk56.jpg)
|
||||||
|
|
||||||
|
与其他包管理器一样,`pacman` 可以将包列表与软件库同步,它能够自动解决所有所需的依赖项,以使得用户可以通过一个简单的命令下载和安装软件。
|
||||||
|
|
||||||
|
#### 通过 pacman 安装软件
|
||||||
|
|
||||||
|
你可以用以下形式的代码来安装一个或者多个软件包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -S 软件包名1 软件包名2 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
![安装一个包][8]
|
||||||
|
|
||||||
|
`-S` 选项的意思是<ruby>同步<rt>synchronization</rt></ruby>,它的意思是 `pacman` 在安装之前先与软件库进行同步。
|
||||||
|
|
||||||
|
`pacman` 数据库根据安装的原因将安装的包分为两组:
|
||||||
|
|
||||||
|
* **显式安装**:由 `pacman -S` 或 `-U` 命令直接安装的包
|
||||||
|
* **依赖安装**:由于被其他显式安装的包所 [依赖][9],而被自动安装的包。
|
||||||
|
|
||||||
|
#### 卸载已安装的软件包
|
||||||
|
|
||||||
|
卸载一个包,并且删除它的所有依赖。
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -R 软件包名
|
||||||
|
```
|
||||||
|
|
||||||
|
![移除一个包][10]
|
||||||
|
|
||||||
|
删除一个包,以及其不被其他包所需要的依赖项:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Rs 软件包名
|
||||||
|
```
|
||||||
|
|
||||||
|
如果需要这个依赖的包已经被删除了,这条命令可以删除所有不再需要的依赖项:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Qdtq | pacman -Rs -
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 升级软件包
|
||||||
|
|
||||||
|
`pacman` 提供了一个简单的办法来 [升级 Arch Linux][11]。你只需要一条命令就可以升级所有已安装的软件包。这可能需要一段时间,这取决于系统的新旧程度。
|
||||||
|
|
||||||
|
以下命令可以同步存储库数据库,*并且* 更新系统的所有软件包,但不包括不在软件库中的“本地安装的”包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Syu
|
||||||
|
```
|
||||||
|
|
||||||
|
* `S` 代表同步
|
||||||
|
* `y` 代表更新本地存储库
|
||||||
|
* `u` 代表系统更新
|
||||||
|
|
||||||
|
也就是说,同步到中央软件库(主程序包数据库),刷新主程序包数据库的本地副本,然后执行系统更新(通过更新所有有更新版本可用的程序包)。
|
||||||
|
|
||||||
|
![系统更新][12]
|
||||||
|
|
||||||
|
> 注意!
|
||||||
|
>
|
||||||
|
> 对于 Arch Linux 用户,在系统升级前,建议你访问 [Arch-Linux 主页][2] 查看最新消息,以了解异常更新的情况。如果系统更新需要人工干预,主页上将发布相关的新闻。你也可以订阅 [RSS 源][13] 或 [Arch 的声明邮件][14]。
|
||||||
|
>
|
||||||
|
> 在升级基础软件(如 kernel、xorg、systemd 或 glibc) 之前,请注意查看相应的 [论坛][15],以了解大家报告的各种问题。
|
||||||
|
>
|
||||||
|
> 在 Arch 和 Manjaro 等滚动发行版中不支持**部分升级**。这意味着,当新的库版本被推送到软件库时,软件库中的所有包都需要根据库版本进行升级。例如,如果两个包依赖于同一个库,则仅升级一个包可能会破坏依赖于该库的旧版本的另一个包。
|
||||||
|
|
||||||
|
#### 用 Pacman 查找包
|
||||||
|
|
||||||
|
`pacman` 使用 `-Q` 选项查询本地包数据库,使用 `-S` 选项查询同步数据库,使用 `-F` 选项查询文件数据库。
|
||||||
|
|
||||||
|
`pacman` 可以在数据库中搜索包,包括包的名称和描述:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Ss 字符串1 字符串2 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
![查找一个包][16]
|
||||||
|
|
||||||
|
查找已经被安装的包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Qs 字符串1 字符串2 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
根据文件名在远程软包中查找它所属的包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -F 字符串1 字符串2 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
查看一个包的依赖树:
|
||||||
|
|
||||||
|
```
|
||||||
|
pactree 软件包名
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 清除包缓存
|
||||||
|
|
||||||
|
`pacman` 将其下载的包存储在 `/var/cache/Pacman/pkg/` 中,并且不会自动删除旧版本或卸载的版本。这有一些优点:
|
||||||
|
|
||||||
|
1. 它允许 [降级][17] 一个包,而不需要通过其他来源检索以前的版本。
|
||||||
|
2. 已卸载的软件包可以轻松地直接从缓存文件夹重新安装。
|
||||||
|
|
||||||
|
但是,有必要定期清理缓存以防止文件夹增大。
|
||||||
|
|
||||||
|
[pacman contrib][19] 包中提供的 [paccache(8)][18] 脚本默认情况下会删除已安装和未安装包的所有缓存版本,但最近 3 个版本除外:
|
||||||
|
|
||||||
|
```
|
||||||
|
paccache -r
|
||||||
|
```
|
||||||
|
|
||||||
|
![清除缓存][20]
|
||||||
|
|
||||||
|
要删除当前未安装的所有缓存包和未使用的同步数据库,请执行:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Sc
|
||||||
|
```
|
||||||
|
|
||||||
|
要从缓存中删除所有文件,请使用清除选项两次,这是最激进的方法,不会在缓存文件夹中留下任何内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -Scc
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 安装本地或者第三方的包
|
||||||
|
|
||||||
|
安装不是来自远程存储库的“本地”包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -U 本地软件包路径.pkg.tar.xz
|
||||||
|
```
|
||||||
|
|
||||||
|
安装官方存储库中未包含的“远程”软件包:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -U http://www.example.com/repo/example.pkg.tar.xz
|
||||||
|
```
|
||||||
|
|
||||||
|
### 额外内容:用 pacman 排除常见错误
|
||||||
|
|
||||||
|
下面是使用 `pacman` 管理包时可能遇到的一些常见错误。
|
||||||
|
|
||||||
|
#### 提交事务失败(文件冲突)
|
||||||
|
|
||||||
|
如果你看到以下报错:
|
||||||
|
|
||||||
|
```
|
||||||
|
error: could not prepare transaction
|
||||||
|
error: failed to commit transaction (conflicting files)
|
||||||
|
package: /path/to/file exists in filesystem
|
||||||
|
Errors occurred, no packages were upgraded.
|
||||||
|
```
|
||||||
|
|
||||||
|
这是因为 `pacman` 检测到文件冲突,不会为你覆盖文件。
|
||||||
|
|
||||||
|
解决这个问题的一个安全方法是首先检查另一个包是否拥有这个文件(`pacman-Qo 文件路径`)。如果该文件属于另一个包,请提交错误报告。如果文件不属于另一个包,请重命名“存在于文件系统中”的文件,然后重新发出更新命令。如果一切顺利,文件可能会被删除。
|
||||||
|
|
||||||
|
你可以显式地运行 `pacman -S –overwrite 要覆盖的文件模式**,强制 `pacman` 覆盖与 给模式匹配的文件,而不是手动重命名并在以后删除属于该包的所有文件。
|
||||||
|
|
||||||
|
#### 提交事务失败(包无效或损坏)
|
||||||
|
|
||||||
|
在 `/var/cache/pacman/pkg/` 中查找 `.part` 文件(部分下载的包),并将其删除。这通常是由在 `pacman.conf` 文件中使用自定义 `XferCommand` 引起的。
|
||||||
|
|
||||||
|
#### 初始化事务失败(无法锁定数据库)
|
||||||
|
|
||||||
|
当 `pacman` 要修改包数据库时,例如安装包时,它会在 `/var/lib/pacman/db.lck` 处创建一个锁文件。这可以防止 `pacman` 的另一个实例同时尝试更改包数据库。
|
||||||
|
|
||||||
|
如果 `pacman` 在更改数据库时被中断,这个过时的锁文件可能仍然保留。如果你确定没有 `pacman` 实例正在运行,那么请删除锁文件。
|
||||||
|
|
||||||
|
检查进程是否持有锁定文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
lsof /var/lib/pacman/db.lck
|
||||||
|
```
|
||||||
|
|
||||||
|
如果上述命令未返回任何内容,则可以删除锁文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
rm /var/lib/pacman/db.lck
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你发现 `lsof` 命令输出了使用锁文件的进程的 PID,请先杀死这个进程,然后删除锁文件。
|
||||||
|
|
||||||
|
我希望你喜欢我对 `pacman` 基础命令的介绍。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/pacman-command/
|
||||||
|
|
||||||
|
作者:[Dimitrios Savvopoulos][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://itsfoss.com/author/dimitrios/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.archlinux.org/pacman/
|
||||||
|
[2]: https://www.archlinux.org/
|
||||||
|
[3]: https://wiki.archlinux.org/index.php/Arch_Build_System
|
||||||
|
[4]: https://wiki.archlinux.org/index.php/Official_repositories
|
||||||
|
[5]: https://itsfoss.com/install-arch-linux/
|
||||||
|
[6]: https://itsfoss.com/things-to-do-after-installing-arch-linux/
|
||||||
|
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/essential-pacman-commands.jpg?ssl=1
|
||||||
|
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/04/sudo-pacman-S.png?ssl=1
|
||||||
|
[9]: https://wiki.archlinux.org/index.php/Dependency
|
||||||
|
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/04/sudo-pacman-R.png?ssl=1
|
||||||
|
[11]: https://itsfoss.com/update-arch-linux/
|
||||||
|
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/04/sudo-pacman-Syu.png?ssl=1
|
||||||
|
[13]: https://www.archlinux.org/feeds/news/
|
||||||
|
[14]: https://mailman.archlinux.org/mailman/listinfo/arch-announce/
|
||||||
|
[15]: https://bbs.archlinux.org/
|
||||||
|
[16]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/04/sudo-pacman-Ss.png?ssl=1
|
||||||
|
[17]: https://wiki.archlinux.org/index.php/Downgrade
|
||||||
|
[18]: https://jlk.fjfi.cvut.cz/arch/manpages/man/paccache.8
|
||||||
|
[19]: https://www.archlinux.org/packages/?name=pacman-contrib
|
||||||
|
[20]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/04/sudo-paccache-r.png?ssl=1
|
@ -0,0 +1,170 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13129-1.html)
|
||||||
|
[#]: subject: (A new way to build cross-platform UIs for Linux ARM devices)
|
||||||
|
[#]: via: (https://opensource.com/article/20/5/linux-arm-ui)
|
||||||
|
[#]: author: (Bruno Muniz https://opensource.com/users/brunoamuniz)
|
||||||
|
|
||||||
|
一种为 Linux ARM 设备构建跨平台 UI 的新方法
|
||||||
|
======
|
||||||
|
|
||||||
|
> AndroidXML 和 TotalCross 的运用为树莓派和其他设备创建 UI 提供了更简单的方法。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/18/123715oomfuuz94ioi41ii.jpg)
|
||||||
|
|
||||||
|
为应用程序创建良好的用户体验(UX)是一项艰巨的任务,尤其是在开发嵌入式应用程序时。今天,有两种图形用户界面(GUI)工具通常用于开发嵌入式软件:它们要么涉及复杂的技术,要么非常昂贵。
|
||||||
|
|
||||||
|
然而,我们已经创建了一个概念验证(PoC),它提供了一种新的方法来使用现有的、成熟的工具为运行在桌面、移动、嵌入式设备和低功耗 ARM 设备上的应用程序构建用户界面(UI)。我们的方法是使用 Android Studio 绘制 UI;使用 [TotalCross][2] 在设备上呈现 Android XML;采用被称为 [KnowCode][4] 的新 [TotalCross API][3];以及使用 [树莓派 4][5] 来执行应用程序。
|
||||||
|
|
||||||
|
### 选择 Android Studio
|
||||||
|
|
||||||
|
可以使用 TotalCross API 为应用程序构建一个美观的响应式用户体验,但是在 Android Studio 中创建 UI 缩短了制作原型和实际应用程序之间的时间。
|
||||||
|
|
||||||
|
有很多工具可以用来为应用程序构建 UI,但是 [Android Studio][6] 是全世界开发者最常使用的工具。除了它被大量采用以外,这个工具的使用也非常直观,而且它对于创建简单和复杂的应用程序都非常强大。在我看来,唯一的缺点是使用该工具所需的计算机性能,它比其他集成开发环境 (IDE) 如 VSCode 或其开源替代方案 [VSCodium][7] 要庞大得多。
|
||||||
|
|
||||||
|
通过思考这些问题,我们创建了一个概念验证,使用 Android Studio 绘制 UI,并使用 TotalCross 直接在设备上运行 AndroidXML。
|
||||||
|
|
||||||
|
### 构建 UI
|
||||||
|
|
||||||
|
对于我们的 PoC,我们想创建一个家用电器应用程序来控制温度和其他东西,并在 Linux ARM 设备上运行。
|
||||||
|
|
||||||
|
![Home appliance application to control thermostat][8]
|
||||||
|
|
||||||
|
我们想为树莓派开发我们的应用程序,所以我们使用 Android 的 [ConstraintLayout][10] 来构建 848x480(树莓派的分辨率)的固定屏幕大小的 UI,不过你可以用其他布局构建响应性 UI。
|
||||||
|
|
||||||
|
Android XML 为 UI 创建增加了很多灵活性,使得为应用程序构建丰富的用户体验变得容易。在下面的 XML 中,我们使用了两个主要组件:[ImageView][11] 和 [TextView][12]。
|
||||||
|
|
||||||
|
```
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView6"
|
||||||
|
android:layout_width="273dp"
|
||||||
|
android:layout_height="291dp"
|
||||||
|
android:background="@drawable/Casa"
|
||||||
|
tools:layout_editor_absoluteX="109dp"
|
||||||
|
tools:layout_editor_absoluteY="95dp" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/insideTempEdit"
|
||||||
|
android:layout_width="94dp"
|
||||||
|
android:layout_height="92dp"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:text="20"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="#000000"
|
||||||
|
android:textSize="67dp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:layout_editor_absoluteX="196dp"
|
||||||
|
tools:layout_editor_absoluteY="246dp" />
|
||||||
|
```
|
||||||
|
|
||||||
|
TextView 元素用于向用户显示一些数据,比如建筑物内的温度。大多数 ImageView 都用作用户与 UI 交互的按钮,但它们也需要实现屏幕上组件提供的事件。
|
||||||
|
|
||||||
|
### 用 TotalCross 整合
|
||||||
|
|
||||||
|
这个 PoC 中的第二项技术是 TotalCross。我们不想在设备上使用 Android 的任何东西,因为:
|
||||||
|
|
||||||
|
1。我们的目标是为 Linux ARM 提供一个出色的 UI。
|
||||||
|
2。我们希望在设备上实现低占用。
|
||||||
|
3。我们希望应用程序在低计算能力的低端硬件设备上运行(例如,没有 GPU、 低 RAM 等)。
|
||||||
|
|
||||||
|
首先,我们使用 [VSCode 插件][13] 创建了一个空的 TotalCross 项目。接下来,我们保存了 `drawable` 文件夹中的图像副本和 `xml` 文件夹中的 Android XML 文件副本,这两个文件夹都位于 `resources` 文件夹中:
|
||||||
|
|
||||||
|
![Home Appliance file structure][14]
|
||||||
|
|
||||||
|
为了使用 TotalCross 模拟器运行 XML 文件,我们添加了一个名为 KnowCode 的新 TotalCross API 和一个主窗口来加载 XML。下面的代码使用 API 加载和呈现 XML:
|
||||||
|
|
||||||
|
```
|
||||||
|
public void initUI() {
|
||||||
|
XmlScreenAbstractLayout xmlCont = XmlScreenFactory.create("xml / homeApplianceXML.xml");
|
||||||
|
swap(xmlCont);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
就这样!只需两个命令,我们就可以使用 TotalCross 运行 Android XML 文件。以下是 XML 如何在 TotalCross 的模拟器上执行:
|
||||||
|
|
||||||
|
![TotalCross simulator running temperature application][15]
|
||||||
|
|
||||||
|
完成这个 PoC 还有两件事要做:添加一些事件来提供用户交互,并在树莓派上运行它。
|
||||||
|
|
||||||
|
### 添加事件
|
||||||
|
|
||||||
|
KnowCode API 提供了一种通过 ID(`getControlByID`) 获取 XML 元素并更改其行为的方法,如添加事件、更改可见性等。
|
||||||
|
|
||||||
|
例如,为了使用户能够改变家中或其他建筑物的温度,我们在 UI 底部放置了加号和减号按钮,并在每次单击按钮时都会出现“单击”事件,使温度升高或降低一度:
|
||||||
|
|
||||||
|
```
|
||||||
|
Button plus = (Button) xmlCont.getControlByID("@+id/plus");
|
||||||
|
Label insideTempLabel = (Label) xmlCont.getControlByID("@+id/insideTempLabel");
|
||||||
|
plus.addPressListener(new PressListener() {
|
||||||
|
@Override
|
||||||
|
public void controlPressed(ControlEvent e) {
|
||||||
|
try {
|
||||||
|
String tempString = insideTempLabel.getText();
|
||||||
|
int temp;
|
||||||
|
temp = Convert.toInt(tempString);
|
||||||
|
insideTempLabel.setText(Convert.toString(++temp));
|
||||||
|
} catch (InvalidNumberException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 在树莓派 4 上测试
|
||||||
|
|
||||||
|
最后一步!我们在一台设备上运行了应用程序并检查了结果。我们只需要打包应用程序并在目标设备上部署和运行它。[VNC][19] 也可用于检查设备上的应用程序。
|
||||||
|
|
||||||
|
整个应用程序,包括资源(图像等)、Android XML、TotalCross 和 Knowcode API,在 Linux ARM 上大约是 8MB。
|
||||||
|
|
||||||
|
下面是应用程序的演示:
|
||||||
|
|
||||||
|
![Application demo][20]
|
||||||
|
|
||||||
|
在本例中,该应用程序仅为 Linux ARM 打包,但同一应用程序可以作为 Linux 桌面应用程序运行,在Android 设备 、Windows、windows CE 甚至 iOS 上运行。
|
||||||
|
|
||||||
|
所有示例源代码和项目都可以在 [HomeApplianceXML GitHub][21] 存储库中找到。
|
||||||
|
|
||||||
|
### 现有工具的新玩法
|
||||||
|
|
||||||
|
为嵌入式应用程序创建 GUI 并不需要像现在这样困难。这种概念证明为如何轻松地完成这项任务提供了新的视角,不仅适用于嵌入式系统,而且适用于所有主要的操作系统,所有这些系统都使用相同的代码库。
|
||||||
|
|
||||||
|
我们的目标不是为设计人员或开发人员创建一个新的工具来构建 UI 应用程序;我们的目标是为使用现有的最佳工具提供新的玩法。
|
||||||
|
|
||||||
|
你对这种新的应用程序开发方式有何看法?在下面的评论中分享你的想法。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/5/linux-arm-ui
|
||||||
|
|
||||||
|
作者:[Bruno Muniz][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/brunoamuniz
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_desk_home_laptop_browser.png?itok=Y3UVpY0l (Digital images of a computer desktop)
|
||||||
|
[2]: https://totalcross.com/
|
||||||
|
[3]: https://yourapp.totalcross.com/knowcode-app
|
||||||
|
[4]: https://github.com/TotalCross/KnowCodeXML
|
||||||
|
[5]: https://www.raspberrypi.org/
|
||||||
|
[6]: https://developer.android.com/studio
|
||||||
|
[7]: https://vscodium.com/
|
||||||
|
[8]: https://opensource.com/sites/default/files/uploads/homeapplianceapp.png (Home appliance application to control thermostat)
|
||||||
|
[9]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[10]: https://codelabs.developers.google.com/codelabs/constraint-layout/index.html#0
|
||||||
|
[11]: https://developer.android.com/reference/android/widget/ImageView
|
||||||
|
[12]: https://developer.android.com/reference/android/widget/TextView
|
||||||
|
[13]: https://medium.com/totalcross-community/totalcross-plugin-for-vscode-4f45da146a0a
|
||||||
|
[14]: https://opensource.com/sites/default/files/uploads/homeappliancexml.png (Home Appliance file structure)
|
||||||
|
[15]: https://opensource.com/sites/default/files/uploads/totalcross-simulator_0.png (TotalCross simulator running temperature application)
|
||||||
|
[16]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+button
|
||||||
|
[17]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+label
|
||||||
|
[18]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||||
|
[19]: https://tigervnc.org/
|
||||||
|
[20]: https://opensource.com/sites/default/files/uploads/application.gif (Application demo)
|
||||||
|
[21]: https://github.com/TotalCross/HomeApplianceXML
|
@ -0,0 +1,201 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13104-1.html)
|
||||||
|
[#]: subject: (Top Arch-based User Friendly Linux Distributions That are Easier to Install and Use Than Arch Linux Itself)
|
||||||
|
[#]: via: (https://itsfoss.com/arch-based-linux-distros/)
|
||||||
|
[#]: author: (Dimitrios Savvopoulos https://itsfoss.com/author/dimitrios/)
|
||||||
|
|
||||||
|
9 个易用的基于 Arch 的用户友好型 Linux 发行版
|
||||||
|
======
|
||||||
|
|
||||||
|
在 Linux 社区中,[Arch Linux][1] 有一群狂热的追随者。这个轻量级的发行版以 DIY 的态度提供了最前沿的更新。
|
||||||
|
|
||||||
|
但是,Arch 的目标用户是那些更有经验的用户。因此,它通常被认为是那些技术不够(或耐心不够)的人所无法触及的。
|
||||||
|
|
||||||
|
事实上,只是最开始的步骤,[安装 Arch Linux 就足以把很多人吓跑][2]。与大多数其他发行版不同,Arch Linux 没有一个易于使用的图形安装程序。安装过程中涉及到的磁盘分区,连接到互联网,挂载驱动器和创建文件系统等只用命令行工具来操作。
|
||||||
|
|
||||||
|
对于那些不想经历复杂的安装和设置的人来说,有许多用户友好的基于 Arch 的发行版。
|
||||||
|
|
||||||
|
在本文中,我将向你展示一些 Arch 替代发行版。这些发行版附带了图形安装程序、图形包管理器和其他工具,比它们的命令行版本更容易使用。
|
||||||
|
|
||||||
|
### 更容易设置和使用的基于 Arch 的 Linux 发行版
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/10/112812sc42txp4eexco44x.jpg)
|
||||||
|
|
||||||
|
请注意,这不是一个排名列表。这些数字只是为了计数的目的。排第二的发行版不应该被认为比排第七的发行版好。
|
||||||
|
|
||||||
|
#### 1、Manjaro Linux
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
[Manjaro][5] 不需要任何介绍。它是几年来最流行的 Linux 发行版之一,它值得拥有。
|
||||||
|
|
||||||
|
Manjaro 提供了 Arch Linux 的所有优点,同时注重用户友好性和可访问性。Manjaro 既适合新手,也适合有经验的 Linux 用户。
|
||||||
|
|
||||||
|
**对于新手**,它提供了一个用户友好的安装程序,系统本身也设计成可以在你[最喜爱的桌面环境 ][6](DE)或窗口管理器中直接“开箱即用”。
|
||||||
|
|
||||||
|
**对于更有经验的用户**,Manjaro 还提供多种功能,以满足每个个人的口味和喜好。[Manjaro Architect][7] 提供了安装各种 Manjaro 风格的选项,并为那些想要完全自由地塑造系统的人提供了各种桌面环境、文件系统([最近推出的 ZFS][8]) 和引导程序的选择。
|
||||||
|
|
||||||
|
Manjaro 也是一个滚动发布的前沿发行版。然而,与 Arch 不同的是,Manjaro 首先测试更新,然后将其提供给用户。稳定在这里也很重要。
|
||||||
|
|
||||||
|
#### 2、ArcoLinux
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
[ArcoLinux][10](以前称为 ArchMerge)是一个基于 Arch Linux 的发行版。开发团队提供了三种变体。ArcoLinux、ArcoLinuxD 和 ArcoLinuxB。
|
||||||
|
|
||||||
|
ArcoLinux 是一个功能齐全的发行版,附带有 [Xfce 桌面][11]、[Openbox][12] 和 [i3 窗口管理器][13]。
|
||||||
|
|
||||||
|
**ArcoLinuxD** 是一个精简的发行版,它包含了一些脚本,可以让高级用户安装任何桌面和应用程序。
|
||||||
|
|
||||||
|
**ArcoLinuxB** 是一个让用户能够构建自定义发行版的项目,同时还开发了几个带有预配置桌面的社区版本,如 Awesome、bspwm、Budgie、Cinnamon、Deepin、GNOME、MATE 和 KDE Plasma。
|
||||||
|
|
||||||
|
ArcoLinux 还提供了各种视频教程,因为它非常注重学习和获取 Linux 技能。
|
||||||
|
|
||||||
|
#### 3、Archlabs Linux
|
||||||
|
|
||||||
|
![][14]
|
||||||
|
|
||||||
|
[ArchLabs Linux][15] 是一个轻量级的滚动版 Linux 发行版,基于最精简的 Arch Linux,带有 [Openbox][16] 窗口管理器。[ArchLabs][17] 在观感设计中受到 [BunsenLabs][18] 的影响和启发,主要考虑到中级到高级用户的需求。
|
||||||
|
|
||||||
|
#### 4、Archman Linux
|
||||||
|
|
||||||
|
![][19]
|
||||||
|
|
||||||
|
[Archman][20] 是一个独立的项目。Arch Linux 发行版对于没有多少 Linux 经验的用户来说通常不是理想的操作系统。要想在最小的挫折感下让事情变得更有意义,必须要有相当的背景知识。Archman Linux 的开发人员正试图改变这种评价。
|
||||||
|
|
||||||
|
Archman 的开发是基于对开发的理解,包括用户反馈和体验组件。根据团队过去的经验,将用户的反馈和要求融合在一起,确定路线图并完成构建工作。
|
||||||
|
|
||||||
|
#### 5、EndeavourOS
|
||||||
|
|
||||||
|
![][21]
|
||||||
|
|
||||||
|
当流行的基于 Arch 的发行版 [Antergos 在 2019 结束][22] 时,它留下了一个友好且非常有用的社区。Antergos 项目结束的原因是因为该系统对于开发人员来说太难维护了。
|
||||||
|
|
||||||
|
在宣布结束后的几天内,一些有经验的用户通过创建一个新的发行版来填补 Antergos 留下的空白,从而维护了以前的社区。这就是 [EndeavourOS][23] 的诞生。
|
||||||
|
|
||||||
|
[EndeavourOS][24] 是轻量级的,并且附带了最少数量的预装应用程序。一块近乎空白的画布,随时可以个性化。
|
||||||
|
|
||||||
|
#### 6、RebornOS
|
||||||
|
|
||||||
|
![][25]
|
||||||
|
|
||||||
|
[RebornOS][26] 开发人员的目标是将 Linux 的真正威力带给每个人,一个 ISO 提供了 15 个桌面环境可供选择,并提供无限的定制机会。
|
||||||
|
|
||||||
|
RebornOS 还声称支持 [Anbox][27],它可以在桌面 Linux 上运行 Android 应用程序。它还提供了一个简单的内核管理器 GUI 工具。
|
||||||
|
|
||||||
|
再加上 [Pacman][28]、[AUR][29],以及定制版本的 Cnchi 图形安装程序,Arch Linux 终于可以让最没有经验的用户也能够使用了。
|
||||||
|
|
||||||
|
#### 7、Chakra Linux
|
||||||
|
|
||||||
|
![][30]
|
||||||
|
|
||||||
|
一个社区开发的 GNU/Linux 发行版,它的亮点在 KDE 和 Qt 技术。[Chakra Linux][31] 不在特定日期安排发布,而是使用“半滚动发布”系统。
|
||||||
|
|
||||||
|
这意味着 Chakra Linux 的核心包被冻结,只在修复安全问题时才会更新。这些软件包是在最新版本经过彻底测试后更新的,然后再转移到永久软件库(大约每六个月更新一次)。
|
||||||
|
|
||||||
|
除官方软件库外,用户还可以安装 Chakra 社区软件库 (CCR) 的软件包,该库为官方存储库中未包含的软件提供用户制作的 PKGINFOs 和 [PKGBUILD][32] 脚本,其灵感来自于 Arch 用户软件库(AUR)。
|
||||||
|
|
||||||
|
#### 8、Artix Linux
|
||||||
|
|
||||||
|
![Artix Mate Edition][33]
|
||||||
|
|
||||||
|
[Artix Linux][34] 也是一个基于 Arch Linux 的滚动发行版,它使用 [OpenRC][35]、[runit][36] 或 [s6][37] 作为初始化工具而不是 [systemd][38]。
|
||||||
|
|
||||||
|
Artix Linux 有自己的软件库,但作为一个基于 `pacman` 的发行版,它可以使用 Arch Linux 软件库或任何其他衍生发行版的软件包,甚至可以使用明确依赖于 systemd 的软件包。也可以使用 [Arch 用户软件库][29](AUR)。
|
||||||
|
|
||||||
|
#### 9、BlackArch Linux
|
||||||
|
|
||||||
|
![][39]
|
||||||
|
|
||||||
|
BlackArch 是一个基于 Arch Linux 的 [渗透测试发行版][40],它提供了大量的网络安全工具。它是专门为渗透测试人员和安全研究人员创建的。该软件库包含 2400 多个[黑客和渗透测试工具 ][41],可以单独安装,也可以分组安装。BlackArch Linux 兼容现有的 Arch Linux 包。
|
||||||
|
|
||||||
|
### 想要真正的原版 Arch Linux 吗?可以使用图形化 Arch 安装程序简化安装
|
||||||
|
|
||||||
|
如果你想使用原版的 Arch Linux,但又被它困难的安装所难倒。幸运的是,你可以下载一个带有图形安装程序的 Arch Linux ISO。
|
||||||
|
|
||||||
|
Arch 安装程序基本上是 Arch Linux ISO 的一个相对容易使用的基于文本的安装程序。它比裸奔的 Arch 安装容易得多。
|
||||||
|
|
||||||
|
#### Anarchy Installer
|
||||||
|
|
||||||
|
![][42]
|
||||||
|
|
||||||
|
[Anarchy installer][43] 打算为新手和有经验的 Linux 用户提供一种简单而无痛苦的方式来安装 ArchLinux。在需要的时候安装,在需要的地方安装,并且以你想要的方式安装。这就是 Anarchy 的哲学。
|
||||||
|
|
||||||
|
启动安装程序后,将显示一个简单的 [TUI 菜单][44],列出所有可用的安装程序选项。
|
||||||
|
|
||||||
|
#### Zen Installer
|
||||||
|
|
||||||
|
![][45]
|
||||||
|
|
||||||
|
[Zen Installer][46] 为安装 Arch Linux 提供了一个完整的图形(点击式)环境。它支持安装多个桌面环境 、AUR 以及 Arch Linux 的所有功能和灵活性,并且易于图形化安装。
|
||||||
|
|
||||||
|
ISO 将引导一个临场环境,然后在你连接到互联网后下载最新稳定版本的安装程序。因此,你将始终获得最新的安装程序和更新的功能。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
对于许多用户来说,基于 Arch 的发行版会是一个很好的无忧选择,而像 Anarchy 这样的图形化安装程序至少离原版的 Arch Linux 更近了一步。
|
||||||
|
|
||||||
|
在我看来,[Arch Linux 的真正魅力在于它的安装过程][2],对于 Linux 爱好者来说,这是一个学习的机会,而不是麻烦。Arch Linux 及其衍生产品有很多东西需要你去折腾,但是在折腾的过程中你就会进入到开源软件的世界,这里是神奇的新世界。下次再见!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/arch-based-linux-distros/
|
||||||
|
|
||||||
|
作者:[Dimitrios Savvopoulos][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://itsfoss.com/author/dimitrios/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://www.archlinux.org/
|
||||||
|
[2]: https://itsfoss.com/install-arch-linux/
|
||||||
|
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/06/arch-based-linux-distributions.png?ssl=1
|
||||||
|
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/05/manjaro-20.jpg?ssl=1
|
||||||
|
[5]: https://manjaro.org/
|
||||||
|
[6]: https://itsfoss.com/best-linux-desktop-environments/
|
||||||
|
[7]: https://itsfoss.com/manjaro-architect-review/
|
||||||
|
[8]: https://itsfoss.com/manjaro-20-release/
|
||||||
|
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/05/arcolinux.png?ssl=1
|
||||||
|
[10]: https://arcolinux.com/
|
||||||
|
[11]: https://www.xfce.org/
|
||||||
|
[12]: http://openbox.org/wiki/Main_Page
|
||||||
|
[13]: https://i3wm.org/
|
||||||
|
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/06/Archlabs.jpg?ssl=1
|
||||||
|
[15]: https://itsfoss.com/archlabs-review/
|
||||||
|
[16]: https://en.wikipedia.org/wiki/Openbox
|
||||||
|
[17]: https://archlabslinux.com/
|
||||||
|
[18]: https://www.bunsenlabs.org/
|
||||||
|
[19]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/06/Archman.png?ssl=1
|
||||||
|
[20]: https://archman.org/en/
|
||||||
|
[21]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/05/04_endeavouros_slide.jpg?ssl=1
|
||||||
|
[22]: https://itsfoss.com/antergos-linux-discontinued/
|
||||||
|
[23]: https://itsfoss.com/endeavouros/
|
||||||
|
[24]: https://endeavouros.com/
|
||||||
|
[25]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/06/RebornOS.png?ssl=1
|
||||||
|
[26]: https://rebornos.org/
|
||||||
|
[27]: https://anbox.io/
|
||||||
|
[28]: https://itsfoss.com/pacman-command/
|
||||||
|
[29]: https://itsfoss.com/aur-arch-linux/
|
||||||
|
[30]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/06/Chakra_Goedel_Screenshot.png?ssl=1
|
||||||
|
[31]: https://www.chakralinux.org/
|
||||||
|
[32]: https://wiki.archlinux.org/index.php/PKGBUILD
|
||||||
|
[33]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/06/Artix_MATE_edition.png?ssl=1
|
||||||
|
[34]: https://artixlinux.org/
|
||||||
|
[35]: https://en.wikipedia.org/wiki/OpenRC
|
||||||
|
[36]: https://en.wikipedia.org/wiki/Runit
|
||||||
|
[37]: https://en.wikipedia.org/wiki/S6_(software)
|
||||||
|
[38]: https://en.wikipedia.org/wiki/Systemd
|
||||||
|
[39]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/06/BlackArch.png?ssl=1
|
||||||
|
[40]: https://itsfoss.com/linux-hacking-penetration-testing/
|
||||||
|
[41]: https://itsfoss.com/best-kali-linux-tools/
|
||||||
|
[42]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/05/anarchy.jpg?ssl=1
|
||||||
|
[43]: https://anarchyinstaller.org/
|
||||||
|
[44]: https://en.wikipedia.org/wiki/Text-based_user_interface
|
||||||
|
[45]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2020/05/zen.jpg?ssl=1
|
||||||
|
[46]: https://sourceforge.net/projects/revenge-installer/
|
260
published/202102/20200615 LaTeX Typesetting - Part 1 (Lists).md
Normal file
260
published/202102/20200615 LaTeX Typesetting - Part 1 (Lists).md
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "rakino"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13112-1.html"
|
||||||
|
[#]: subject: "LaTeX Typesetting – Part 1 (Lists)"
|
||||||
|
[#]: via: "https://fedoramagazine.org/latex-typesetting-part-1/"
|
||||||
|
[#]: author: "Earl Ramirez https://fedoramagazine.org/author/earlramirez/"
|
||||||
|
|
||||||
|
LaTeX 排版(1):列表
|
||||||
|
======
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
本系列基于前文《[在 Fedora 上用 LaTex 和 TeXstudio 排版你的文档][2]》和《[LaTeX 基础][3]》,本文即系列的第一部分,是关于 LaTeX 列表的。
|
||||||
|
|
||||||
|
### 列表类型
|
||||||
|
|
||||||
|
LaTeX 中的列表是封闭的环境,列表中的每个项目可以取一行文字到一个完整的段落。在 LaTeX 中有三种列表类型:
|
||||||
|
|
||||||
|
* `itemize`:<ruby>无序列表<rt>unordered list</rt></ruby>/<ruby>项目符号列表<rt>bullet list</rt></ruby>
|
||||||
|
* `enumerate`:<ruby>有序列表<rt>ordered list</rt></ruby>
|
||||||
|
* `description`:<ruby>描述列表<rt>descriptive list</rt></ruby>
|
||||||
|
|
||||||
|
### 创建列表
|
||||||
|
|
||||||
|
要创建一个列表,需要在每个项目前加上控制序列 `\item`,并在项目清单前后分别加上控制序列 `\begin{<类型>}` 和 `\end`{<类型>}`(将其中的 `<类型>` 替换为将要使用的列表类型),如下例:
|
||||||
|
|
||||||
|
#### itemize(无序列表)
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{itemize}
|
||||||
|
\item Fedora
|
||||||
|
\item Fedora Spin
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
#### enumerate(有序列表)
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Fedora CoreOS
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\item Fedora Spin
|
||||||
|
\end{enumerate}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][5]
|
||||||
|
|
||||||
|
#### description(描述列表)
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{description}
|
||||||
|
\item[Fedora 6] Code name Zod
|
||||||
|
\item[Fedora 8] Code name Werewolf
|
||||||
|
\end{description}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][6]
|
||||||
|
|
||||||
|
### 列表项目间距
|
||||||
|
|
||||||
|
可以通过在导言区加入 `\usepackage{enumitem}` 来自定义默认的间距,宏包 `enumitem` 启用了选项 `noitemsep` 和控制序列 `\itemsep`,可以在列表中使用它们,如下例所示:
|
||||||
|
|
||||||
|
#### 使用选项 noitemsep
|
||||||
|
|
||||||
|
将选项 `noitemsep` 封闭在方括号内,并同下文所示放在控制序列 `\begin` 之后,该选项将移除默认的间距。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{itemize}[noitemsep]
|
||||||
|
\item Fedora
|
||||||
|
\item Fedora Spin
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][7]
|
||||||
|
|
||||||
|
#### 使用控制序列 \itemsep
|
||||||
|
|
||||||
|
控制序列 `\itemsep` 必须以一个数字作为后缀,用以表示列表项目之间应该有多少空间。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{itemize} \itemsep0.75pt
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\item Fedora CoreOS
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][8]
|
||||||
|
|
||||||
|
### 嵌套列表
|
||||||
|
|
||||||
|
LaTeX 最多最多支持四层嵌套列表,如下例:
|
||||||
|
|
||||||
|
#### 嵌套无序列表
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{itemize}[noitemsep]
|
||||||
|
\item Fedora Versions
|
||||||
|
\begin{itemize}
|
||||||
|
\item Fedora 8
|
||||||
|
\item Fedora 9
|
||||||
|
\begin{itemize}
|
||||||
|
\item Werewolf
|
||||||
|
\item Sulphur
|
||||||
|
\begin{itemize}
|
||||||
|
\item 2007-05-31
|
||||||
|
\item 2008-05-13
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
\item Fedora Spin
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][9]
|
||||||
|
|
||||||
|
#### 嵌套有序列表
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{enumerate}[noitemsep]
|
||||||
|
\item Fedora Versions
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Fedora 8
|
||||||
|
\item Fedora 9
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Werewolf
|
||||||
|
\item Sulphur
|
||||||
|
\begin{enumerate}
|
||||||
|
\item 2007-05-31
|
||||||
|
\item 2008-05-13
|
||||||
|
\end{enumerate}
|
||||||
|
\end{enumerate}
|
||||||
|
\end{enumerate}
|
||||||
|
\item Fedora Spin
|
||||||
|
\item Fedora Silverblue
|
||||||
|
\end{enumerate}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][10]
|
||||||
|
|
||||||
|
### 每种列表类型的列表样式名称
|
||||||
|
|
||||||
|
**enumerate(有序列表)** | **itemize(无序列表)**
|
||||||
|
---|---
|
||||||
|
`\alph*` (小写字母) | `$\bullet$` (●)
|
||||||
|
`\Alph*` (大写字母) | `$\cdot$` (•)
|
||||||
|
`\arabic*` (阿拉伯数字) | `$\diamond$` (◇)
|
||||||
|
`\roman*` (小写罗马数字) | `$\ast$` (✲)
|
||||||
|
`\Roman*` (大写罗马数字) | `$\circ$` (○)
|
||||||
|
| `$-$` (-)
|
||||||
|
|
||||||
|
### 按嵌套深度划分的默认样式
|
||||||
|
|
||||||
|
**嵌套深度** | **enumerate(有序列表)** | **itemize(无序列表)**
|
||||||
|
---|---|---
|
||||||
|
1 | 阿拉伯数字 | (●)
|
||||||
|
2 | 小写字母 | (-)
|
||||||
|
3 | 小写罗马数字 | (✲)
|
||||||
|
4 | 大写字母 | (•)
|
||||||
|
|
||||||
|
### 设置列表样式
|
||||||
|
|
||||||
|
下面的例子列举了无序列表的不同样式。
|
||||||
|
|
||||||
|
```
|
||||||
|
% 无序列表样式
|
||||||
|
\begin{itemize}
|
||||||
|
\item[$\ast$] Asterisk
|
||||||
|
\item[$\diamond$] Diamond
|
||||||
|
\item[$\circ$] Circle
|
||||||
|
\item[$\cdot$] Period
|
||||||
|
\item[$\bullet$] Bullet (default)
|
||||||
|
\item[--] Dash
|
||||||
|
\item[$-$] Another dash
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
![][11]
|
||||||
|
|
||||||
|
有三种设置列表样式的方式,下面将按照优先级从高到低的顺序分别举例。
|
||||||
|
|
||||||
|
#### 方式一:为各项目单独设置
|
||||||
|
|
||||||
|
将需要的样式名称封闭在方括号内,并放在控制序列 `\item` 之后,如下例:
|
||||||
|
|
||||||
|
```
|
||||||
|
% 方式一
|
||||||
|
\begin{itemize}
|
||||||
|
\item[$\ast$] Asterisk
|
||||||
|
\item[$\diamond$] Diamond
|
||||||
|
\item[$\circ$] Circle
|
||||||
|
\item[$\cdot$] period
|
||||||
|
\item[$\bullet$] Bullet (default)
|
||||||
|
\item[--] Dash
|
||||||
|
\item[$-$] Another dash
|
||||||
|
\end{itemize}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方式二:为整个列表设置
|
||||||
|
|
||||||
|
将需要的样式名称以 `label=` 前缀并封闭在方括号内,放在控制序列 `\begin` 之后,如下例:
|
||||||
|
|
||||||
|
```
|
||||||
|
% 方式二
|
||||||
|
\begin{enumerate}[label=\Alph*.]
|
||||||
|
\item Fedora 32
|
||||||
|
\item Fedora 31
|
||||||
|
\item Fedora 30
|
||||||
|
\end{enumerate}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方式三:为整个文档设置
|
||||||
|
|
||||||
|
该方式将改变整个文档的默认样式。使用 `\renewcommand` 来设置项目标签的值,下例分别为四个嵌套深度的项目标签设置了不同的样式。
|
||||||
|
|
||||||
|
```
|
||||||
|
% 方式三
|
||||||
|
\renewcommand{\labelitemi}{$\ast$}
|
||||||
|
\renewcommand{\labelitemii}{$\diamond$}
|
||||||
|
\renewcommand{\labelitemiii}{$\bullet$}
|
||||||
|
\renewcommand{\labelitemiv}{$-$}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
LaTeX 支持三种列表,而每种列表的风格和间距都是可以自定义的。在以后的文章中,我们将解释更多的 LaTeX 元素。
|
||||||
|
|
||||||
|
关于 LaTeX 列表的延伸阅读可以在这里找到:[LaTeX List Structures][12]
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/latex-typesetting-part-1/
|
||||||
|
|
||||||
|
作者:[Earl Ramirez][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://fedoramagazine.org/author/earlramirez/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://fedoramagazine.org/wp-content/uploads/2020/06/latex-series-816x345.png
|
||||||
|
[2]: https://fedoramagazine.org/typeset-latex-texstudio-fedora
|
||||||
|
[3]: https://fedoramagazine.org/fedora-classroom-latex-101-beginners
|
||||||
|
[4]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-1.png
|
||||||
|
[5]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-2.png
|
||||||
|
[6]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-3.png
|
||||||
|
[7]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-4.png
|
||||||
|
[8]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-5.png
|
||||||
|
[9]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-7.png
|
||||||
|
[10]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-8.png
|
||||||
|
[11]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-9.png
|
||||||
|
[12]: https://en.wikibooks.org/wiki/LaTeX/List_Structures
|
342
published/202102/20200629 LaTeX typesetting part 2 (tables).md
Normal file
342
published/202102/20200629 LaTeX typesetting part 2 (tables).md
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13146-1.html)
|
||||||
|
[#]: subject: (LaTeX typesetting part 2 \(tables\))
|
||||||
|
[#]: via: (https://fedoramagazine.org/latex-typesetting-part-2-tables/)
|
||||||
|
[#]: author: (Earl Ramirez https://fedoramagazine.org/author/earlramirez/)
|
||||||
|
|
||||||
|
LaTex 排版 (2):表格
|
||||||
|
======
|
||||||
|
|
||||||
|
![][1]
|
||||||
|
|
||||||
|
LaTeX 提供了许多工具来创建和定制表格,在本系列中,我们将使用 `tabular` 和 `tabularx` 环境来创建和定制表。
|
||||||
|
|
||||||
|
### 基础表格
|
||||||
|
|
||||||
|
要创建表,只需指定环境 `\begin{tabular}{列选项}`:
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{c|c}
|
||||||
|
Release &Codename \\ \hline
|
||||||
|
Fedora Core 1 &Yarrow \\
|
||||||
|
Fedora Core 2 &Tettnang \\
|
||||||
|
Fedora Core 3 &Heidelberg \\
|
||||||
|
Fedora Core 4 &Stentz \\
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Basic Table][2]
|
||||||
|
|
||||||
|
在上面的示例中,花括号中的 ”{c|c}” 表示文本在列中的位置。下表总结了位置参数及其说明。
|
||||||
|
|
||||||
|
参数 | 位置
|
||||||
|
|:---:|:---
|
||||||
|
`c` | 将文本置于中间
|
||||||
|
`l` | 将文本左对齐
|
||||||
|
`r` | 将文本右对齐
|
||||||
|
`p{宽度}` | 文本对齐单元格顶部
|
||||||
|
`m{宽度}` | 文本对齐单元格中间
|
||||||
|
`b{宽度}` | 文本对齐单元格底部
|
||||||
|
|
||||||
|
> `m{宽度}` 和 `b{宽度}` 都要求在最前面指定数组包。
|
||||||
|
|
||||||
|
使用上面的例子,让我们来详细讲解使用的要点,并描述你将在本系列中看到的更多选项:
|
||||||
|
|
||||||
|
选项 | 意义
|
||||||
|
|:-:|:-|
|
||||||
|
`&` | 定义每个单元格,这个符号仅用于第二列
|
||||||
|
`\\` | 这将终止该行并开始一个新行
|
||||||
|
`|` | 指定表格中的垂直线(可选)
|
||||||
|
`\hline` | 指定表格中的水平线(可选)
|
||||||
|
`*{数量}{格式}` | 当你有许多列时,可以使用这个,并且是限制重复的有效方法
|
||||||
|
`||` | 指定表格中垂直双线
|
||||||
|
|
||||||
|
### 定制表格
|
||||||
|
|
||||||
|
学会了这些选项,让我们使用这些选项创建一个表。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{*{3}{|l|}}
|
||||||
|
\hline
|
||||||
|
\textbf{Version} &\textbf{Code name} &\textbf{Year released} \\
|
||||||
|
\hline
|
||||||
|
Fedora 6 &Zod &2006 \\ \hline
|
||||||
|
Fedora 7 &Moonshine &2007 \\ \hline
|
||||||
|
Fedora 8 &Werewolf &2007 \\
|
||||||
|
\hline
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Customise Table][3]
|
||||||
|
|
||||||
|
### 管理长文本
|
||||||
|
|
||||||
|
如果列中有很多文本,那么它的格式就不好处理,看起来也不好看。
|
||||||
|
|
||||||
|
下面的示例显示了文本的格式长度,我们将在导言区中使用 `blindtext`,以便生成示例文本。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|l|}\hline
|
||||||
|
Summary &Description \\ \hline
|
||||||
|
Test &\blindtext \\
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Default Formatting][4]
|
||||||
|
|
||||||
|
正如你所看到的,文本超出了页面宽度;但是,有几个选项可以克服这个问题。
|
||||||
|
|
||||||
|
* 指定列宽,例如 `m{5cm}`
|
||||||
|
* 利用 `tablarx` 环境,这需要在导言区中引用 `tablarx` 宏包。
|
||||||
|
|
||||||
|
#### 使用列宽管理长文本
|
||||||
|
|
||||||
|
通过指定列宽,文本将被折行为如下示例所示的宽度。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|m{14cm}|} \hline
|
||||||
|
Summary &Description \\ \hline
|
||||||
|
Test &\blindtext \\ \hline
|
||||||
|
\end{tabular}\vspace{3mm}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Column Width][5]
|
||||||
|
|
||||||
|
#### 使用 tabularx 管理长文本
|
||||||
|
|
||||||
|
在我们利用表格之前,我们需要在导言区中加上它。`tabularx` 方法见以下示例:`\begin{tabularx}{宽度}{列选项}`。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabularx}{\textwidth}{|l|X|} \hline
|
||||||
|
Summary & Tabularx Description\\ \hline
|
||||||
|
Text &\blindtext \\ \hline
|
||||||
|
\end{tabularx}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Tabularx][6]
|
||||||
|
|
||||||
|
请注意,我们需要处理长文本的列在花括号中指定了大写 `X`。
|
||||||
|
|
||||||
|
### 合并行合并列
|
||||||
|
|
||||||
|
有时需要合并行或列。本节描述了如何完成。要使用 `multirow` 和 `multicolumn`,请将 `multirow` 添加到导言区。
|
||||||
|
|
||||||
|
#### 合并行
|
||||||
|
|
||||||
|
`multirow` 采用以下参数 `\multirow{行的数量}{宽度}{文本}`,让我们看看下面的示例。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|l|}\hline
|
||||||
|
Release &Codename \\ \hline
|
||||||
|
Fedora Core 4 &Stentz \\ \hline
|
||||||
|
\multirow{2}{*}{MultiRow} &Fedora 8 \\
|
||||||
|
&Werewolf \\ \hline
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![MultiRow][7]
|
||||||
|
|
||||||
|
在上面的示例中,指定了两行,`*` 告诉 LaTeX 自动管理单元格的大小。
|
||||||
|
|
||||||
|
#### 合并列
|
||||||
|
|
||||||
|
`multicolumn` 参数是 `{multicolumn{列的数量}{单元格选项}{位置}{文本}`,下面的示例演示合并列。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|l|l|}\hline
|
||||||
|
Release &Codename &Date \\ \hline
|
||||||
|
Fedora Core 4 &Stentz &2005 \\ \hline
|
||||||
|
\multicolumn{3}{|c|}{Mulit-Column} \\ \hline
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Multi-Column][8]
|
||||||
|
|
||||||
|
### 使用颜色
|
||||||
|
|
||||||
|
可以为文本、单个单元格或整行指定颜色。此外,我们可以为每一行配置交替的颜色。
|
||||||
|
|
||||||
|
在给表添加颜色之前,我们需要在导言区引用 `\usepackage[table]{xcolor}`。我们还可以使用以下颜色参考 [LaTeX Color][9] 或在颜色前缀后面添加感叹号(从 0 到 100 的阴影)来定义颜色。例如,`gray!30`。
|
||||||
|
|
||||||
|
```
|
||||||
|
\definecolor{darkblue}{rgb}{0.0, 0.0, 0.55}
|
||||||
|
\definecolor{darkgray}{rgb}{0.66, 0.66, 0.66}
|
||||||
|
```
|
||||||
|
|
||||||
|
下面的示例演示了一个具有各种颜色的表,`\rowcolors` 采用以下选项 `\rowcolors{起始行颜色}{偶数行颜色}{奇数行颜色}`。
|
||||||
|
|
||||||
|
```
|
||||||
|
\rowcolors{2}{darkgray}{gray!20}
|
||||||
|
\begin{tabular}{c|c}
|
||||||
|
Release &Codename \\ \hline
|
||||||
|
Fedora Core 1 &Yarrow \\
|
||||||
|
Fedora Core 2 &Tettnang \\
|
||||||
|
Fedora Core 3 &Heidelberg \\
|
||||||
|
Fedora Core 4 &Stentz \\
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Alt colour table][10]
|
||||||
|
|
||||||
|
除了上面的例子,`\rowcolor` 可以用来指定每一行的颜色,这个方法在有合并行时效果最好。以下示例显示将 `\rowColors` 与合并行一起使用的影响以及如何解决此问题。
|
||||||
|
|
||||||
|
![Impact on multi-row][11]
|
||||||
|
|
||||||
|
你可以看到,在合并行中,只有第一行能显示颜色。想要解决这个问题,需要这样做:
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|l|}\hline
|
||||||
|
\rowcolor{darkblue}\textsc{\color{white}Release} &\textsc{\color{white}Codename} \\ \hline
|
||||||
|
\rowcolor{gray!10}Fedora Core 4 &Stentz \\ \hline
|
||||||
|
\rowcolor{gray!40}&Fedora 8 \\
|
||||||
|
\rowcolor{gray!40}\multirow{-2}{*}{Multi-Row} &Werewolf \\ \hline
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Multi-row][12]
|
||||||
|
|
||||||
|
让我们讲解一下为解决合并行替换颜色问题而实施的更改。
|
||||||
|
|
||||||
|
* 第一行从合并行上方开始
|
||||||
|
* 行数从 `2` 更改为 `-2`,这意味着从上面的行开始读取
|
||||||
|
* `\rowcolor` 是为每一行指定的,更重要的是,多行必须具有相同的颜色,这样才能获得所需的结果。
|
||||||
|
|
||||||
|
关于颜色的最后一个注意事项是,要更改列的颜色,需要创建新的列类型并定义颜色。下面的示例说明了如何定义新的列颜色。
|
||||||
|
|
||||||
|
```
|
||||||
|
\newcolumntype{g}{>{\columncolor{darkblue}}l}
|
||||||
|
```
|
||||||
|
|
||||||
|
我们把它分解一下:
|
||||||
|
|
||||||
|
* `\newcolumntype{g}`:将字母 `g` 定义为新列
|
||||||
|
* `{>{\columncolor{darkblue}}l}`:在这里我们选择我们想要的颜色,并且 `l` 告诉列左对齐,这可以用 `c` 或 `r` 代替。
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{g|l}
|
||||||
|
\textsc{Release} &\textsc{Codename} \\ \hline
|
||||||
|
Fedora Core 4 &Stentz \\
|
||||||
|
&Fedora 8 \\
|
||||||
|
\multirow{-2}{*}{Multi-Row} &Werewolf \\
|
||||||
|
\end{tabular}\
|
||||||
|
```
|
||||||
|
|
||||||
|
![Column Colour][13]
|
||||||
|
|
||||||
|
### 横向表
|
||||||
|
|
||||||
|
有时,你的表可能有许多列,纵向排列会很不好看。在导言区加入 `rotating` 包,你将能够创建一个横向表。下面的例子说明了这一点。
|
||||||
|
|
||||||
|
对于横向表,我们将使用 `sidewaystable` 环境并在其中添加表格环境,我们还指定了其他选项。
|
||||||
|
|
||||||
|
* `\centering` 可以将表格放置在页面中心
|
||||||
|
* `\caption{}` 为表命名
|
||||||
|
* `\label{}` 这使我们能够引用文档中的表
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{sidewaystable}
|
||||||
|
\centering
|
||||||
|
\caption{Sideways Table}
|
||||||
|
\label{sidetable}
|
||||||
|
\begin{tabular}{ll}
|
||||||
|
\rowcolor{darkblue}\textsc{\color{white}Release} &\textsc{\color{white}Codename} \\
|
||||||
|
\rowcolor{gray!10}Fedora Core 4 &Stentz \\
|
||||||
|
\rowcolor{gray!40} &Fedora 8 \\
|
||||||
|
\rowcolor{gray!40}\multirow{-2}{*}{Multi-Row} &Werewolf \\
|
||||||
|
\end{tabular}\vspace{3mm}
|
||||||
|
\end{sidewaystable}
|
||||||
|
```
|
||||||
|
|
||||||
|
![Sideways Table][14]
|
||||||
|
|
||||||
|
### 列表和表格
|
||||||
|
|
||||||
|
要将列表包含到表中,可以使用 `tabularx`,并将列表包含在指定的列中。另一个办法是使用表格格式,但必须指定列宽。
|
||||||
|
|
||||||
|
#### 用 tabularx 处理列表
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabularx}{\textwidth}{|l|X|} \hline
|
||||||
|
Fedora Version &Editions \\ \hline
|
||||||
|
Fedora 32 &\begin{itemize}[noitemsep]
|
||||||
|
\item CoreOS
|
||||||
|
\item Silverblue
|
||||||
|
\item IoT
|
||||||
|
\end{itemize} \\ \hline
|
||||||
|
\end{tabularx}\vspace{3mm}
|
||||||
|
```
|
||||||
|
|
||||||
|
![List in tabularx][15]
|
||||||
|
|
||||||
|
#### 用 tabular 处理列表
|
||||||
|
|
||||||
|
```
|
||||||
|
\begin{tabular}{|l|m{6cm}|}\hline
|
||||||
|
Fedora Version &amp;amp;Editions \\\ \hline
|
||||||
|
Fedora 32 &amp;amp;\begin{itemize}[noitemsep]
|
||||||
|
\item CoreOS
|
||||||
|
\item Silverblue
|
||||||
|
\item IoT
|
||||||
|
\end{itemize} \\\ \hline
|
||||||
|
\end{tabular}
|
||||||
|
```
|
||||||
|
|
||||||
|
![List in tabular][16]
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
LaTeX 提供了许多使用 `tablar` 和 `tablarx` 自定义表的方法,你还可以在表环境 (`\begin\table`) 中添加 `tablar` 和 `tablarx` 来添加表的名称和定位表。
|
||||||
|
|
||||||
|
### LaTeX 宏包
|
||||||
|
|
||||||
|
所需的宏包有如下这些:
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{fullpage}
|
||||||
|
\usepackage{blindtext} % add demo text
|
||||||
|
\usepackage{array} % used for column positions
|
||||||
|
\usepackage{tabularx} % adds tabularx which is used for text wrapping
|
||||||
|
\usepackage{multirow} % multi-row and multi-colour support
|
||||||
|
\usepackage[table]{xcolor} % add colour to the columns
|
||||||
|
\usepackage{rotating} % for landscape/sideways tables
|
||||||
|
```
|
||||||
|
|
||||||
|
### 额外的知识
|
||||||
|
|
||||||
|
这是一堂关于表的小课,有关表和 LaTex 的更多高级信息,请访问 [LaTex Wiki][17]
|
||||||
|
|
||||||
|
![][13]
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/latex-typesetting-part-2-tables/
|
||||||
|
|
||||||
|
作者:[Earl Ramirez][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://fedoramagazine.org/author/earlramirez/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://fedoramagazine.org/wp-content/uploads/2020/06/latex-series-816x345.png
|
||||||
|
[2]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-13.png
|
||||||
|
[3]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-23.png
|
||||||
|
[4]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-10.png
|
||||||
|
[5]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-11.png
|
||||||
|
[6]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-12.png
|
||||||
|
[7]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-15.png
|
||||||
|
[8]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-16.png
|
||||||
|
[9]: https://latexcolor.com
|
||||||
|
[10]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-17.png
|
||||||
|
[11]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-18.png
|
||||||
|
[12]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-19.png
|
||||||
|
[13]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-24.png
|
||||||
|
[14]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-20.png
|
||||||
|
[15]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-21.png
|
||||||
|
[16]: https://fedoramagazine.org/wp-content/uploads/2020/06/image-22.png
|
||||||
|
[17]: https://en.wikibooks.org/wiki/LaTeX/Tables
|
@ -0,0 +1,283 @@
|
|||||||
|
[#]: collector: (Chao-zhi)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13154-1.html)
|
||||||
|
[#]: subject: (LaTeX typesetting,Part 3: formatting)
|
||||||
|
[#]: via: (https://fedoramagazine.org/latex-typesetting-part-3-formatting/)
|
||||||
|
[#]: author: (Earl Ramirez https://fedoramagazine.org/author/earlramirez/)
|
||||||
|
|
||||||
|
LaTeX 排版(3):排版
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/26/113031wattha0hojj4f4ej.png)
|
||||||
|
|
||||||
|
本 [系列][1] 介绍了 LaTeX 中的基本格式。[第 1 部分][2] 介绍了列表。[第 2 部分][3] 阐述了表格。在第 3 部分中,你将了解 LaTeX 的另一个重要特性:细腻灵活的文档排版。本文介绍如何自定义页面布局、目录、标题部分和页面样式。
|
||||||
|
|
||||||
|
### 页面维度
|
||||||
|
|
||||||
|
当你第一次编写 LaTeX 文档时,你可能已经注意到默认边距比你想象的要大一些。页边距与指定的纸张类型有关,例如 A4、letter 和 documentclass(article、book、report) 等等。要修改页边距,有几个选项,最简单的选项之一是使用 [fullpage][4] 包。
|
||||||
|
|
||||||
|
> 该软件包设置页面的主体,可以使主体几乎占满整个页面。
|
||||||
|
>
|
||||||
|
> —— FULLPAGE PACKAGE DOCUMENTATION
|
||||||
|
|
||||||
|
另一个选择是使用 [geometry][5] 包。在探索 `geometry` 包如何操纵页边距之前,请首先查看如下所示的页面尺寸。
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image.png)
|
||||||
|
|
||||||
|
1. 1 英寸 + `\hoffset`
|
||||||
|
2. 1 英寸 + `\voffset`
|
||||||
|
3. `\oddsidemargin` = 31pt
|
||||||
|
4. `\topmargin` = 20pt
|
||||||
|
5. `\headheight` = 12pt
|
||||||
|
6. `\headsep` = 25pt
|
||||||
|
7. `\textheight` = 592pt
|
||||||
|
8. `\textwidth` = 390pt
|
||||||
|
9. `\marginparsep` = 35pt
|
||||||
|
10. `\marginparwidth` = 35pt
|
||||||
|
11. `\footskip` = 30pt
|
||||||
|
|
||||||
|
要使用 `geometry` 包将边距设置为 1 英寸,请使用以下示例
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{geometry}
|
||||||
|
\geometry{a4paper, margin=1in}
|
||||||
|
```
|
||||||
|
|
||||||
|
除上述示例外,`geometry` 命令还可以修改纸张尺寸和方向。要更改纸张尺寸,请使用以下示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage[a4paper, total={7in, 8in}]{geometry}
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-2-1024x287.png)
|
||||||
|
|
||||||
|
要更改页面方向,需要将横向(`landscape`)添加到 `geometery` 选项中,如下所示:
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{geometery}
|
||||||
|
\geometry{a4paper, landscape, margin=1.5in
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-9.png)
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
默认情况下,目录的标题为 “contents”。有时,你想将标题更改为 “Table of Content”,更改目录和章节第一节之间的垂直间距,或者只更改文本的颜色。
|
||||||
|
|
||||||
|
若要更改文本,请在导言区中添加以下行,用所需语言替换英语(`english`):
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage[english]{babel}
|
||||||
|
\addto\captionsenglish{
|
||||||
|
\renewcommand{\contentsname}
|
||||||
|
{\bfseries{Table of Contents}}}
|
||||||
|
```
|
||||||
|
|
||||||
|
要操纵目录与图、小节和章节列表之间的虚拟间距,请使用 `tocloft` 软件包。本文中使用的两个选项是 `cftbeforesecskip` 和 `cftaftertoctitleskip`。
|
||||||
|
|
||||||
|
> tocloft 包提供了控制目录、图表列表和表格列表的排版方法。
|
||||||
|
>
|
||||||
|
> —— TOCLOFT PACKAGE DOUCMENTATION
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{tocloft}
|
||||||
|
\setlength\ctfbeforesecskip{2pt}
|
||||||
|
\setlength\cftaftertoctitleskip{30pt}
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-3.png)
|
||||||
|
|
||||||
|
*默认目录*
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-4.png)
|
||||||
|
|
||||||
|
*定制目录*
|
||||||
|
|
||||||
|
### 边框
|
||||||
|
|
||||||
|
在文档中使用包 [hyperref][6] 时,目录中的 LaTeX 章节列表和包含 `\url` 的引用都有边框,如下图所示。
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-5.png)
|
||||||
|
|
||||||
|
要删除这些边框,请在导言区中包括以下内容,你将看到目录中没有任何边框。
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{hyperref}
|
||||||
|
\hypersetup{ pdfborder = {0 0 0}}
|
||||||
|
```
|
||||||
|
|
||||||
|
要修改标题部分的字体、样式或颜色,请使用程序包 [titlesec][7]。在本例中,你将更改节、子节和三级子节的字体大小、字体样式和字体颜色。首先,在导言区中增加以下内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{titlesec}
|
||||||
|
\titleformat*{\section}{\Huge\bfseries\color{darkblue}}
|
||||||
|
\titleformat*{\subsection}{\huge\bfseries\color{darkblue}}
|
||||||
|
\titleformat*{\subsubsection}{\Large\bfseries\color{darkblue}}
|
||||||
|
```
|
||||||
|
|
||||||
|
仔细看看代码,`\titleformat*{\section}` 指定要使用的节的深度。上面的示例最多使用第三个深度。`{\Huge\bfseries\color{darkblue}}` 部分指定字体大小、字体样式和字体颜色。
|
||||||
|
|
||||||
|
### 页面样式
|
||||||
|
|
||||||
|
要自定义的页眉和页脚,请使用 [fancyhdr][8]。此示例使用此包修改页面样式、页眉和页脚。下面的代码简要描述了每个选项的作用。
|
||||||
|
|
||||||
|
```
|
||||||
|
\pagestyle{fancy} %for header to be on each page
|
||||||
|
\fancyhead[L]{} %keep left header blank
|
||||||
|
\fancyhead[C]{} %keep centre header blank
|
||||||
|
\fancyhead[R]{\leftmark} %add the section/chapter to the header right
|
||||||
|
\fancyfoot[L]{Static Content} %add static test to the left footer
|
||||||
|
\fancyfoot[C]{} %keep centre footer blank
|
||||||
|
\fancyfoot[R]{\thepage} %add the page number to the right footer
|
||||||
|
\setlength\voffset{-0.25in} %space between page border and header (1in + space)
|
||||||
|
\setlength\headheight{12pt} %height of the actual header.
|
||||||
|
\setlength\headsep{25pt} %separation between header and text.
|
||||||
|
\renewcommand{\headrulewidth}{2pt} % add header horizontal line
|
||||||
|
\renewcommand{\footrulewidth}{1pt} % add footer horizontal line
|
||||||
|
```
|
||||||
|
|
||||||
|
结果如下所示:
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-7.png)
|
||||||
|
|
||||||
|
*页眉*
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-8.png)
|
||||||
|
|
||||||
|
*页脚*
|
||||||
|
|
||||||
|
### 小贴士
|
||||||
|
|
||||||
|
#### 集中导言区
|
||||||
|
|
||||||
|
如果要编写许多 TeX 文档,可以根据文档类别创建一个包含所有导言区的 `.tex` 文件并引用此文件。例如,我使用结构 `.tex` 如下所示。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat article_structure.tex
|
||||||
|
\usepackage[english]{babel}
|
||||||
|
\addto\captionsenglish{
|
||||||
|
\renewcommand{\contentsname}
|
||||||
|
{\bfseries{\color{darkblue}Table of Contents}}
|
||||||
|
} % Relable the contents
|
||||||
|
%\usepackage[margin=0.5in]{geometry} % specifies the margin of the document
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage{graphicx} % allows you to add graphics to the document
|
||||||
|
\usepackage{hyperref} % permits redirection of URL from a PDF document
|
||||||
|
\usepackage{fullpage} % formate the content to utilise the full page
|
||||||
|
%\usepackage{a4wide}
|
||||||
|
\usepackage[export]{adjustbox} % to force image position
|
||||||
|
%\usepackage[section]{placeins} % to have multiple images in a figure
|
||||||
|
\usepackage{tabularx} % for wrapping text in a table
|
||||||
|
%\usepackage{rotating}
|
||||||
|
\usepackage{multirow}
|
||||||
|
\usepackage{subcaption} % to have multiple images in a figure
|
||||||
|
%\usepackage{smartdiagram} % initialise smart diagrams
|
||||||
|
\usepackage{enumitem} % to manage the spacing between lists and enumeration
|
||||||
|
\usepackage{fancyhdr} %, graphicx} %for header to be on each page
|
||||||
|
\pagestyle{fancy} %for header to be on each page
|
||||||
|
%\fancyhf{}
|
||||||
|
\fancyhead[L]{}
|
||||||
|
\fancyhead[C]{}
|
||||||
|
\fancyhead[R]{\leftmark}
|
||||||
|
\fancyfoot[L]{Static Content} %\includegraphics[width=0.02\textwidth]{virgin_voyages.png}}
|
||||||
|
\fancyfoot[C]{} % clear center
|
||||||
|
\fancyfoot[R]{\thepage}
|
||||||
|
\setlength\voffset{-0.25in} %Space between page border and header (1in + space)
|
||||||
|
\setlength\headheight{12pt} %Height of the actual header.
|
||||||
|
\setlength\headsep{25pt} %Separation between header and text.
|
||||||
|
\renewcommand{\headrulewidth}{2pt} % adds horizontal line
|
||||||
|
\renewcommand{\footrulewidth}{1pt} % add horizontal line (footer)
|
||||||
|
%\renewcommand{\oddsidemargin}{2pt} % adjuct the margin spacing
|
||||||
|
%\renewcommand{\pagenumbering}{roman} % change the numbering style
|
||||||
|
%\renewcommand{\hoffset}{20pt}
|
||||||
|
%\usepackage{color}
|
||||||
|
\usepackage[table]{xcolor}
|
||||||
|
\hypersetup{ pdfborder = {0 0 0}} % removes the red boarder from the table of content
|
||||||
|
%\usepackage{wasysym} %add checkbox
|
||||||
|
%\newcommand\insq[1]{%
|
||||||
|
% \Square\ #1\quad%
|
||||||
|
%} % specify the command to add checkbox
|
||||||
|
%\usepackage{xcolor}
|
||||||
|
%\usepackage{colortbl}
|
||||||
|
%\definecolor{Gray}{gray}{0.9} % create new colour
|
||||||
|
%\definecolor{LightCyan}{rgb}{0.88,1,1} % create new colour
|
||||||
|
%\usepackage[first=0,last=9]{lcg}
|
||||||
|
%\newcommand{\ra}{\rand0.\arabic{rand}}
|
||||||
|
%\newcolumntype{g}{>{\columncolor{LightCyan}}c} % create new column type g
|
||||||
|
%\usesmartdiagramlibrary{additions}
|
||||||
|
%\setcounter{figure}{0}
|
||||||
|
\setcounter{secnumdepth}{0} % sections are level 1
|
||||||
|
\usepackage{csquotes} % the proper was of using double quotes
|
||||||
|
%\usepackage{draftwatermark} % Enable watermark
|
||||||
|
%\SetWatermarkText{DRAFT} % Specify watermark text
|
||||||
|
%\SetWatermarkScale{5} % Toggle watermark size
|
||||||
|
\usepackage{listings} % add code blocks
|
||||||
|
\usepackage{titlesec} % Manipulate section/subsection
|
||||||
|
\titleformat{\section}{\Huge\bfseries\color{darkblue}} % update sections to bold with the colour blue \titleformat{\subsection}{\huge\bfseries\color{darkblue}} % update subsections to bold with the colour blue
|
||||||
|
\titleformat*{\subsubsection}{\Large\bfseries\color{darkblue}} % update subsubsections to bold with the colour blue
|
||||||
|
\usepackage[toc]{appendix} % Include appendix in TOC
|
||||||
|
\usepackage{xcolor}
|
||||||
|
\usepackage{tocloft} % For manipulating Table of Content virtical spacing
|
||||||
|
%\setlength\cftparskip{-2pt}
|
||||||
|
\setlength\cftbeforesecskip{2pt} %spacing between the sections
|
||||||
|
\setlength\cftaftertoctitleskip{30pt} % space between the first section and the text ``Table of Contents''
|
||||||
|
\definecolor{navyblue}{rgb}{0.0,0.0,0.5}
|
||||||
|
\definecolor{zaffre}{rgb}{0.0, 0.08, 0.66}
|
||||||
|
\definecolor{white}{rgb}{1.0, 1.0, 1.0}
|
||||||
|
\definecolor{darkblue}{rgb}{0.0, 0.2, 0.6}
|
||||||
|
\definecolor{darkgray}{rgb}{0.66, 0.66, 0.66}
|
||||||
|
\definecolor{lightgray}{rgb}{0.83, 0.83, 0.83}
|
||||||
|
%\pagenumbering{roman}
|
||||||
|
```
|
||||||
|
|
||||||
|
在你的文章中,请参考以下示例中所示的方法引用 `structure.tex` 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass[a4paper,11pt]{article}
|
||||||
|
\input{/path_to_structure.tex}}
|
||||||
|
\begin{document}
|
||||||
|
......
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 添加水印
|
||||||
|
|
||||||
|
要在 LaTeX 文档中启用水印,请使用 [draftwatermark][9] 软件包。下面的代码段和图像演示了如何在文档中添加水印。默认情况下,水印颜色为灰色,可以将其修改为所需的颜色。
|
||||||
|
|
||||||
|
```
|
||||||
|
\usepackage{draftwatermark}
|
||||||
|
\SetWatermarkText{\color{red}Classified} %add watermark text
|
||||||
|
\SetWatermarkScale{4} %specify the size of the text
|
||||||
|
```
|
||||||
|
|
||||||
|
![](https://fedoramagazine.org/wp-content/uploads/2020/07/image-10.png)
|
||||||
|
|
||||||
|
### 结论
|
||||||
|
|
||||||
|
在本系列中,你了解了 LaTeX 提供的一些基本但丰富的功能,这些功能可用于自定义文档以满足你的需要或将文档呈现给的受众。LaTeX 海洋中,还有许多软件包需要大家自行去探索。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://fedoramagazine.org/latex-typesetting-part-3-formatting/
|
||||||
|
|
||||||
|
作者:[Earl Ramirez][a]
|
||||||
|
选题:[Chao-zhi][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://fedoramagazine.org/author/earlramirez/
|
||||||
|
[b]: https://github.com/Chao-zhi
|
||||||
|
[1]:https://fedoramagazine.org/tag/latex/
|
||||||
|
[2]:https://linux.cn/article-13112-1.html
|
||||||
|
[3]:https://linux.cn/article-13146-1.html
|
||||||
|
[4]:https://www.ctan.org/pkg/fullpage
|
||||||
|
[5]:https://www.ctan.org/geometry
|
||||||
|
[6]:https://www.ctan.org/pkg/hyperref
|
||||||
|
[7]:https://www.ctan.org/pkg/titlesec
|
||||||
|
[8]:https://www.ctan.org/pkg/fancyhdr
|
||||||
|
[9]:https://www.ctan.org/pkg/draftwatermark
|
@ -0,0 +1,126 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13110-1.html)
|
||||||
|
[#]: subject: (Give Your GNOME Desktop a Tiling Makeover With Material Shell GNOME Extension)
|
||||||
|
[#]: via: (https://itsfoss.com/material-shell/)
|
||||||
|
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||||
|
|
||||||
|
使用 Material Shell 扩展将你的 GNOME 桌面打造成平铺式风格
|
||||||
|
======
|
||||||
|
|
||||||
|
平铺式窗口的特性吸引了很多人的追捧。也许是因为它很好看,也许是因为它能提高 [Linux 快捷键][1] 玩家的效率。又或者是因为使用不同寻常的平铺式窗口是一种新奇的挑战。
|
||||||
|
|
||||||
|
![Tiling Windows in Linux | Image Source][2]
|
||||||
|
|
||||||
|
从 i3 到 [Sway][3],Linux 桌面拥有各种各样的平铺式窗口管理器。配置一个平铺式窗口管理器需要一个陡峭的学习曲线。
|
||||||
|
|
||||||
|
这就是为什么像 [Regolith 桌面][4] 这样的项目会存在,给你预先配置好的平铺桌面,让你可以更轻松地开始使用平铺窗口。
|
||||||
|
|
||||||
|
让我给你介绍一个类似的项目 —— Material Shell。它可以让你用上平铺式桌面,甚至比 [Regolith][5] 还简单。
|
||||||
|
|
||||||
|
### Material Shell 扩展:将 GNOME 桌面转变成平铺式窗口管理器
|
||||||
|
|
||||||
|
[Material Shell][6] 是一个 GNOME 扩展,这就是它最好的地方。这意味着你不需要注销并登录其他桌面环境。你只需要启用或关闭这个扩展就可以自如的切换你的工作环境。
|
||||||
|
|
||||||
|
我会列出 Material Shell 的各种特性,但是也许视频更容易让你理解:
|
||||||
|
|
||||||
|
- [video](https://youtu.be/Wc5mbuKrGDE)
|
||||||
|
|
||||||
|
这个项目叫做 Material Shell 是因为它遵循 [Material Design][8] 原则。因此这个应用拥有一个美观的界面。这就是它最重要的一个特性。
|
||||||
|
|
||||||
|
#### 直观的界面
|
||||||
|
|
||||||
|
Material Shell 添加了一个左侧面板,以便快速访问。在此面板上,你可以在底部找到系统托盘,在顶部找到搜索和工作区。
|
||||||
|
|
||||||
|
所有新打开的应用都会添加到当前工作区中。你也可以创建新的工作区并切换到该工作区,以将正在运行的应用分类。其实这就是工作区最初的意义。
|
||||||
|
|
||||||
|
在 Material Shell 中,每个工作区都可以显示为具有多个应用程序的行列,而不是包含多个应用程序的程序框。
|
||||||
|
|
||||||
|
#### 平铺式窗口
|
||||||
|
|
||||||
|
在工作区中,你可以一直在顶部看到所有打开的应用程序。默认情况下,应用程序会像在 GNOME 桌面中那样铺满整个屏幕。你可以使用右上角的布局改变器来改变布局,将其分成两半、多列或多个应用网格。
|
||||||
|
|
||||||
|
这段视频一目了然的显示了以上所有功能:
|
||||||
|
|
||||||
|
- [video](https://player.vimeo.com/video/460050750?dnt=1&app_id=122963)
|
||||||
|
|
||||||
|
#### 固定布局和工作区
|
||||||
|
|
||||||
|
Material Shell 会记住你打开的工作区和窗口,这样你就不必重新组织你的布局。这是一个很好的特性,因为如果你对应用程序的位置有要求的话,它可以节省时间。
|
||||||
|
|
||||||
|
#### 热建/快捷键
|
||||||
|
|
||||||
|
像任何平铺窗口管理器一样,你可以使用键盘快捷键在应用程序和工作区之间切换。
|
||||||
|
|
||||||
|
* `Super+W` 切换到上个工作区;
|
||||||
|
* `Super+S` 切换到下个工作区;
|
||||||
|
* `Super+A` 切换到左边的窗口;
|
||||||
|
* `Super+D` 切换到右边的窗口;
|
||||||
|
* `Super+1`、`Super+2` … `Super+0` 切换到某个指定的工作区;
|
||||||
|
* `Super+Q` 关闭当前窗口;
|
||||||
|
* `Super+[鼠标拖动]` 移动窗口;
|
||||||
|
* `Super+Shift+A` 将当前窗口左移;
|
||||||
|
* `Super+Shift+D` 将当前窗口右移;
|
||||||
|
* `Super+Shift+W` 将当前窗口移到上个工作区;
|
||||||
|
* `Super+Shift+S` 将当前窗口移到下个工作区。
|
||||||
|
|
||||||
|
### 安装 Material Shell
|
||||||
|
|
||||||
|
> 警告!
|
||||||
|
>
|
||||||
|
> 对于大多数用户来说,平铺式窗口可能会导致混乱。你最好先熟悉如何使用 GNOME 扩展。如果你是 Linux 新手或者你害怕你的系统发生翻天覆地的变化,你应当避免使用这个扩展。
|
||||||
|
|
||||||
|
Material Shell 是一个 GNOME 扩展。所以,请 [检查你的桌面环境][9],确保你运行的是 GNOME 3.34 或者更高的版本。
|
||||||
|
|
||||||
|
除此之外,我注意到在禁用 Material Shell 之后,它会导致 Firefox 的顶栏和 Ubuntu 的坞站消失。你可以在 GNOME 的“扩展”应用程序中禁用/启用 Ubuntu 的坞站扩展来使其变回原来的样子。我想这些问题也应该在系统重启后消失,虽然我没试过。
|
||||||
|
|
||||||
|
我希望你知道 [如何使用 GNOME 扩展][10]。最简单的办法就是 [在浏览器中打开这个链接][11],安装 GNOME 扩展浏览器插件,然后启用 Material Shell 扩展即可。
|
||||||
|
|
||||||
|
![][12]
|
||||||
|
|
||||||
|
如果你不喜欢这个扩展,你也可以在同样的链接中禁用它。或者在 GNOME 的“扩展”应用程序中禁用它。
|
||||||
|
|
||||||
|
![][13]
|
||||||
|
|
||||||
|
### 用不用平铺式?
|
||||||
|
|
||||||
|
我使用多个电脑屏幕,我发现 Material Shell 不适用于多个屏幕的情况。这是开发者将来可以改进的地方。
|
||||||
|
|
||||||
|
除了这个毛病以外,Material Shell 是个让你开始使用平铺式窗口的好东西。如果你尝试了 Material Shell 并且喜欢它,请 [在 GitHub 上给它一个星标或赞助它][14] 来鼓励这个项目。
|
||||||
|
|
||||||
|
由于某些原因,平铺窗户越来越受欢迎。最近发布的 [Pop OS 20.04][15] 也增加了平铺窗口的功能。有一个类似的项目叫 PaperWM,也是这样做的。
|
||||||
|
|
||||||
|
但正如我前面提到的,平铺布局并不适合所有人,它可能会让很多人感到困惑。
|
||||||
|
|
||||||
|
你呢?你是喜欢平铺窗口还是喜欢经典的桌面布局?
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://itsfoss.com/material-shell/
|
||||||
|
|
||||||
|
作者:[Abhishek Prakash][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[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-shortcuts/
|
||||||
|
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/09/linux-ricing-example-800x450.jpg?resize=800%2C450&ssl=1
|
||||||
|
[3]: https://itsfoss.com/sway-window-manager/
|
||||||
|
[4]: https://itsfoss.com/regolith-linux-desktop/
|
||||||
|
[5]: https://regolith-linux.org/
|
||||||
|
[6]: https://material-shell.com
|
||||||
|
[7]: https://www.youtube.com/c/itsfoss?sub_confirmation=1
|
||||||
|
[8]: https://material.io/
|
||||||
|
[9]: https://itsfoss.com/find-desktop-environment/
|
||||||
|
[10]: https://itsfoss.com/gnome-shell-extensions/
|
||||||
|
[11]: https://extensions.gnome.org/extension/3357/material-shell/
|
||||||
|
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/09/install-material-shell.png?resize=800%2C307&ssl=1
|
||||||
|
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2020/09/material-shell-gnome-extension.png?resize=799%2C497&ssl=1
|
||||||
|
[14]: https://github.com/material-shell/material-shell
|
||||||
|
[15]: https://itsfoss.com/pop-os-20-04-review/
|
@ -0,0 +1,124 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13137-1.html)
|
||||||
|
[#]: subject: (Navigating your Linux files with ranger)
|
||||||
|
[#]: via: (https://www.networkworld.com/article/3583890/navigating-your-linux-files-with-ranger.html)
|
||||||
|
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||||
|
|
||||||
|
用 ranger 在 Linux 文件的海洋中导航
|
||||||
|
=====
|
||||||
|
|
||||||
|
> ranger 是一个很好的工具,它为你的 Linux 文件提供了一个多级视图,并允许你使用方向键和一些方便的命令进行浏览和更改。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/20/121918g5hqhjfcjyffh3lt.jpg)
|
||||||
|
|
||||||
|
`ranger` 是一款独特且非常方便的文件系统导航器,它允许你在 Linux 文件系统中移动,进出子目录,查看文本文件内容,甚至可以在不离开该工具的情况下对文件进行修改。
|
||||||
|
|
||||||
|
它运行在终端窗口中,并允许你按下方向键进行导航。它提供了一个多级的文件显示,让你很容易看到你在哪里、在文件系统中移动、并选择特定的文件。
|
||||||
|
|
||||||
|
要安装 `ranger`,请使用标准的安装命令(例如,`sudo apt install ranger`)。要启动它,只需键入 `ranger`。它有一个很长的、非常详细的手册页面,但开始使用 `ranger` 非常简单。
|
||||||
|
|
||||||
|
### ranger 的显示方式
|
||||||
|
|
||||||
|
你需要马上习惯的最重要的一件事就是 `ranger` 的文件显示方式。一旦你启动了 `ranger`,你会看到四列数据。第一列是你启动 `ranger` 的位置的上一级。例如,如果你从主目录开始,`ranger` 将在第一列中列出所有的主目录。第二列将显示你的主目录(或者你开始的目录)中的目录和文件的第一屏内容。
|
||||||
|
|
||||||
|
这里的关键是超越你可能有的任何习惯,将每一行显示的细节看作是相关的。第二列中的所有条目与第一列中的单个条目相关,第四列中的内容与第二列中选定的文件或目录相关。
|
||||||
|
|
||||||
|
与一般的命令行视图不同的是,目录将被列在第一位(按字母数字顺序),文件将被列在第二位(也是按字母数字顺序)。从你的主目录开始,显示的内容可能是这样的:
|
||||||
|
|
||||||
|
```
|
||||||
|
shs@dragonfly /home/shs/backups <== current selection
|
||||||
|
bugfarm backups 0 empty
|
||||||
|
dory bin 59
|
||||||
|
eel Buttons 15
|
||||||
|
nemo Desktop 0
|
||||||
|
shark Documents 0
|
||||||
|
shs Downloads 1
|
||||||
|
^ ^ ^ ^
|
||||||
|
| | | |
|
||||||
|
homes directories # files listing
|
||||||
|
in selected in each of files in
|
||||||
|
home directory selected directory
|
||||||
|
```
|
||||||
|
|
||||||
|
`ranger` 显示的最上面一行告诉你在哪里。在这个例子中,当前目录是 `/home/shs/backups`。我们看到高亮显示的是 `empty`,因为这个目录中没有文件。如果我们按下方向键选择 `bin`,我们会看到一个文件列表:
|
||||||
|
|
||||||
|
```
|
||||||
|
shs@dragonfly /home/shs/bin <== current selection
|
||||||
|
bugfarm backups 0 append
|
||||||
|
dory bin 59 calcPower
|
||||||
|
eel Buttons 15 cap
|
||||||
|
nemo Desktop 0 extract
|
||||||
|
shark Documents 0 finddups
|
||||||
|
shs Downloads 1 fix
|
||||||
|
^ ^ ^ ^
|
||||||
|
| | | |
|
||||||
|
homes directories # files listing
|
||||||
|
in selected in each of files in
|
||||||
|
home directory selected directory
|
||||||
|
```
|
||||||
|
|
||||||
|
每一列中高亮显示的条目显示了当前的选择。使用右方向键可移动到更深的目录或查看文件内容。
|
||||||
|
|
||||||
|
如果你继续按下方向键移动到列表的文件部分,你会注意到第三列将显示文件大小(而不是文件的数量)。“当前选择”行也会显示当前选择的文件名,而最右边的一列则会尽可能地显示文件内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
shs@dragonfly /home/shs/busy_wait.c <== current selection
|
||||||
|
bugfarm BushyRidge.zip 170 K /*
|
||||||
|
dory busy_wait.c 338 B * program that does a busy wait
|
||||||
|
eel camper.jpg 5.55 M * it's used to show ASLR, and that's it
|
||||||
|
nemo check_lockscreen 80 B */
|
||||||
|
shark chkrootkit-output 438 B #include <stdio.h>
|
||||||
|
^ ^ ^ ^
|
||||||
|
| | | |
|
||||||
|
homes files sizes file content
|
||||||
|
```
|
||||||
|
|
||||||
|
在该显示的底行会显示一些文件和目录的详细信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
-rw-rw-r—- shs shs 338B 2019-01-05 14:44 1.52G, 365G free 67/488 11%
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你选择了一个目录并按下回车键,你将进入该目录。然后,在你的显示屏中最左边的一列将是你的主目录的内容列表,第二列将是该目录内容的文件列表。然后你可以检查子目录的内容和文件的内容。
|
||||||
|
|
||||||
|
按左方向键可以向上移动一级。
|
||||||
|
|
||||||
|
按 `q` 键退出 `ranger`。
|
||||||
|
|
||||||
|
### 做出改变
|
||||||
|
|
||||||
|
你可以按 `?` 键,在屏幕底部弹出一条帮助行。它看起来应该是这样的:
|
||||||
|
|
||||||
|
```
|
||||||
|
View [m]an page, [k]ey bindings, [c]commands or [s]ettings? (press q to abort)
|
||||||
|
```
|
||||||
|
|
||||||
|
按 `c` 键,`ranger` 将提供你可以在该工具内使用的命令信息。例如,你可以通过输入 `:chmod` 来改变当前文件的权限,后面跟着预期的权限。例如,一旦选择了一个文件,你可以输入 `:chmod 700` 将权限设置为 `rwx------`。
|
||||||
|
|
||||||
|
输入 `:edit` 可以在 `nano` 中打开该文件,允许你进行修改,然后使用 `nano` 的命令保存文件。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
使用 `ranger` 的方法比本篇文章所描述的更多。该工具提供了一种非常不同的方式来列出 Linux 系统上的文件并与之交互,一旦你习惯了它的多级的目录和文件列表方式,并使用方向键代替 `cd` 命令来移动,就可以很轻松地在 Linux 的文件中导航。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.networkworld.com/article/3583890/navigating-your-linux-files-with-ranger.html
|
||||||
|
|
||||||
|
作者:[Sandra Henry-Stocker][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://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://unsplash.com/photos/mHC0qJ7l-ls
|
||||||
|
[2]: https://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
[3]: https://www.networkworld.com/newsletters/signup.html
|
||||||
|
[4]: https://www.facebook.com/NetworkWorld/
|
||||||
|
[5]: https://www.linkedin.com/company/network-world
|
297
published/202102/20201013 My first day using Ansible.md
Normal file
297
published/202102/20201013 My first day using Ansible.md
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "MjSeven"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13079-1.html"
|
||||||
|
[#]: subject: "My first day using Ansible"
|
||||||
|
[#]: via: "https://opensource.com/article/20/10/first-day-ansible"
|
||||||
|
[#]: author: "David Both https://opensource.com/users/dboth"
|
||||||
|
|
||||||
|
使用 Ansible 的第一天
|
||||||
|
======
|
||||||
|
|
||||||
|
> 一名系统管理员分享了如何使用 Ansible 在网络中配置计算机并把其带入实际工作的信息和建议。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/03/105826sn41jj0i8evu19nn.jpg)
|
||||||
|
|
||||||
|
无论是第一次还是第五十次,启动并运行一台新的物理或虚拟计算机都非常耗时,而且需要大量的工作。多年来,我一直使用我创建的一系列脚本和 RPM 来安装所需的软件包,并为我喜欢的工具配置各种选项。这种方法效果很好,简化了我的工作,而且还减少了在键盘上输入命令的时间。
|
||||||
|
|
||||||
|
我一直在寻找更好的工作方式。近几年来,我一直在听到并且读到有关 [Ansible][2] 的信息,它是一个自动配置和管理系统的强大工具。Ansible 允许系统管理员在一个或多个<ruby>剧本<rt>playbook</rt></ruby>中为每个主机指定一个特定状态,然后执行各种必要的任务,使主机进入该状态。这包括安装或删除各种资源,例如 RPM 或 Apt 软件包、配置文件和其它文件、用户、组等等。
|
||||||
|
|
||||||
|
因为一些琐事,我推迟了很长一段时间学习如何使用它。直到最近,我遇到了一个我认为 Ansible 可以轻松解决的问题。
|
||||||
|
|
||||||
|
这篇文章并不会完整地告诉你如何入门 Ansible,相反,它只是对我遇到的问题和我在一些隐秘的地方发现的信息的做了一些记录。我在各种在线讨论和问答小组中找到的有关 Ansible 的许多信息都是错误的。错误范围包括明显的老旧信息(没有任何日期或来源的迹象),还有一些是完全错误的信息。
|
||||||
|
|
||||||
|
本文所介绍的内容是有用的,尽管可能还有其它方法可以完成相同的事情,但我使用的是 Ansible 2.9.13 和 [Python][3] 3.8.5。
|
||||||
|
|
||||||
|
### 我的问题
|
||||||
|
|
||||||
|
我所有的最佳学习经历都始于我需要解决的问题,这次也不例外。
|
||||||
|
|
||||||
|
我一直在做一个小项目,修改 [Midnight Commander][4] 文件管理器的配置文件,并将它们推送到我网络上的各种系统中进行测试。尽管我有一个脚本可以自动执行这个操作,但它仍然需要使用命令行循环来提供我想要推送新代码的系统名称。我对配置文件进行了大量的更改,这使我必须频繁推送新的配置文件。但是,就在我以为我的新配置刚刚好时,我发现了一个问题,所以我需要在修复后再进行一次推送。
|
||||||
|
|
||||||
|
这种环境使得很难跟踪哪些系统有新文件,哪些没有。我还有几个主机需要区别对待。我对 Ansible 的一点了解表明,它可能能够满足我的全部或大部分工作。
|
||||||
|
|
||||||
|
### 开始
|
||||||
|
|
||||||
|
我读过许多有关 Ansible 的好文章和书籍,但从来没有在“我必须现在就把这个做好!”的情况下读过。而现在 —— 好吧,就是现在!
|
||||||
|
|
||||||
|
在重读这些文档时,我发现它们主要是在讨论如何从 GitHub 开始安装并使用 Ansible,这很酷。但是我真的只是想尽快开始,所以我使用 DNF 和 Fedora 仓库中的版本在我的 Fedora 工作站上安装了它,非常简单。
|
||||||
|
|
||||||
|
但是后来我开始寻找文件位置,并尝试确定需要修改哪些配置文件、将我的剧本保存在什么位置,甚至一个剧本怎么写以及它的作用,我脑海中有一大堆(到目前为止)悬而未决的问题。
|
||||||
|
|
||||||
|
因此,不不需要进一步描述我的困难的情况下,以下是我发现的东西以及促使我继续前进的东西。
|
||||||
|
|
||||||
|
### 配置
|
||||||
|
|
||||||
|
Ansible 的配置文件保存在 `/etc/ansible` 中,这很有道理,因为 `/etc/` 是系统程序应该保存配置文件的地方。我需要使用的两个文件是 `ansible.cfg` 和 `hosts`。
|
||||||
|
|
||||||
|
#### ansible.cfg
|
||||||
|
|
||||||
|
在进行了从文档和线上找到的一些实践练习之后,我遇到了一些有关弃用某些较旧的 Python 文件的警告信息。因此,我在 `ansible.cfg` 中将 `deprecation_warnings` 设置为 `false`,这样那些愤怒的红色警告消息就不会出现了:
|
||||||
|
|
||||||
|
```
|
||||||
|
deprecation_warnings = False
|
||||||
|
```
|
||||||
|
|
||||||
|
这些警告很重要,所以我稍后将重新回顾它们,并弄清楚我需要做什么。但是现在,它们不会再扰乱屏幕,也不会让我混淆实际上需要关注的错误。
|
||||||
|
|
||||||
|
#### hosts 文件
|
||||||
|
|
||||||
|
与 `/etc/hosts` 文件不同,`hosts` 文件也被称为<ruby>清单<rt>inventory</rt></ruby>文件,它列出了网络上的主机。此文件允许将主机分组到相关集合中,例如“servers”、“workstations”和任何你所需的名称。这个文件包含帮助和大量示例,所以我在这里就不详细介绍了。但是,有些事情你必须知道。
|
||||||
|
|
||||||
|
主机也可以列在组之外,但是组对于识别具有一个或多个共同特征的主机很有帮助。组使用 INI 格式,所以服务器组看起来像这样:
|
||||||
|
|
||||||
|
```
|
||||||
|
[servers]
|
||||||
|
server1
|
||||||
|
server2
|
||||||
|
......
|
||||||
|
```
|
||||||
|
|
||||||
|
这个文件中必须有一个主机名,这样 Ansible 才能对它进行操作。即使有些子命令允许指定主机名,但除非主机名在 `hosts` 文件中,否则命令会失败。一个主机也可以放在多个组中。因此,除了 `[servers]` 组之外,`server1` 也可能是 `[webservers]` 组的成员,还可以是 `[ubuntu]` 组的成员,这样以区别于 Fedora 服务器。
|
||||||
|
|
||||||
|
Ansible 很智能。如果 `all` 参数用作主机名,Ansible 会扫描 `hosts` 文件并在它列出的所有主机上执行定义的任务。Ansible 只会尝试在每个主机上工作一次,不管它出现在多少个组中。这也意味着不需要定义 `all` 组,因为 Ansible 可以确定文件中的所有主机名,并创建自己唯一的主机名列表。
|
||||||
|
|
||||||
|
另一件需要注意的事情是单个主机的多个条目。我在 DNS 文件中使用 `CNAME` 记录来创建别名,这些别名指向某些主机的 [A 记录][5],这样,我可以将一个主机称为 `host1` 或 `h1` 或 `myhost`。如果你在 `hosts` 文件中为同一主机指定多个主机名,则 Ansible 将尝试在所有这些主机名上执行其任务,它无法知道它们指向同一主机。好消息是,这并不会影响整体结果;它只是多花了一点时间,因为 Ansible 会在次要主机名上工作,它会确定所有操作均已执行。
|
||||||
|
|
||||||
|
### Ansible 实情
|
||||||
|
|
||||||
|
我阅读过 Ansible 的大多数材料都谈到了 Ansible <ruby>[实情][6]<rt>facts</rt></ruby>,它是与远程系统相关的数据,包括操作系统、IP 地址、文件系统等等。这些信息可以通过其它方式获得,如 `lshw`、`dmidecode` 或 `/proc` 文件系统等。但是 Ansible 会生成一个包含此信息的 JSON 文件。每次 Ansible 运行时,它都会生成这些实情数据。在这个数据流中,有大量的信息,都是以键值对形式出现的:`<"variable-name": "value">`。所有这些变量都可以在 Ansible 剧本中使用,理解大量可用信息的最好方法是实际显示一下:
|
||||||
|
|
||||||
|
```
|
||||||
|
# ansible -m setup <hostname> | less
|
||||||
|
```
|
||||||
|
|
||||||
|
明白了吗?你想知道的有关主机硬件和 Linux 发行版的所有内容都在这里,它们都可以在剧本中使用。我还没有达到需要使用这些变量的地步,但是我相信在接下来的几天中会用到。
|
||||||
|
|
||||||
|
### 模块
|
||||||
|
|
||||||
|
上面的 `ansible` 命令使用 `-m` 选项来指定 `setup` 模块。Ansible 已经内置了许多模块,所以你对这些模块不需要使用 `-m`。也可以安装许多下载的模块,但是内置模块可以完成我目前项目所需的一切。
|
||||||
|
|
||||||
|
### 剧本
|
||||||
|
|
||||||
|
<ruby>剧本<rt>playbook</rt></ruby>几乎可以放在任何地方。因为我需要以 root 身份运行,所以我将它放在了 `/root/ansible` 下。当我运行 Ansible 时,只要这个目录是当前的工作目录(PWD),它就可以找到我的剧本。Ansible 还有一个选项,用于在运行时指定不同的剧本和位置。
|
||||||
|
|
||||||
|
剧本可以包含注释,但是我看到的文章或书籍很少提及此。但作为一个相信记录一切的系统管理员,我发现使用注释很有帮助。这并不是说在注释中做和任务名称同样的事情,而是要确定任务组的目的,并确保我以某种方式或顺序记录我做这些事情的原因。当我可能忘记最初的想法时,这可以帮助以后解决调试问题。
|
||||||
|
|
||||||
|
剧本只是定义主机所需状态的任务集合。在剧本的开头指定主机名或清单组,并定义 Ansible 将在其上运行剧本的主机。
|
||||||
|
|
||||||
|
以下是我的一个剧本示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
################################################################################
|
||||||
|
# This Ansible playbook updates Midnight commander configuration files. #
|
||||||
|
################################################################################
|
||||||
|
- name: Update midnight commander configuration files
|
||||||
|
hosts: all
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: ensure midnight commander is the latest version
|
||||||
|
dnf:
|
||||||
|
name: mc
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: create ~/.config/mc directory for root
|
||||||
|
file:
|
||||||
|
path: /root/.config/mc
|
||||||
|
state: directory
|
||||||
|
mode: 0755
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: create ~/.config/mc directory for dboth
|
||||||
|
file:
|
||||||
|
path: /home/dboth/.config/mc
|
||||||
|
state: directory
|
||||||
|
mode: 0755
|
||||||
|
owner: dboth
|
||||||
|
group: dboth
|
||||||
|
|
||||||
|
- name: copy latest personal skin
|
||||||
|
copy:
|
||||||
|
src: /root/ansible/UpdateMC/files/MidnightCommander/DavidsGoTar.ini
|
||||||
|
dest: /usr/share/mc/skins/DavidsGoTar.ini
|
||||||
|
mode: 0644
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: copy latest mc ini file
|
||||||
|
copy:
|
||||||
|
src: /root/ansible/UpdateMC/files/MidnightCommander/ini
|
||||||
|
dest: /root/.config/mc/ini
|
||||||
|
mode: 0644
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: copy latest mc panels.ini file
|
||||||
|
copy:
|
||||||
|
src: /root/ansible/UpdateMC/files/MidnightCommander/panels.ini
|
||||||
|
dest: /root/.config/mc/panels.ini
|
||||||
|
mode: 0644
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
<截断>
|
||||||
|
```
|
||||||
|
|
||||||
|
剧本从它自己的名字和它将要操作的主机开始,在本文中,所有主机都在我的 `hosts` 文件中。`tasks` 部分列出了使主机达到所需状态的特定任务。这个剧本从使用 DNF 更新 Midnight Commander 开始(如果它不是最新的版本的话)。下一个任务确保创建所需的目录(如果它们不存在),其余任务将文件复制到合适的位置,这些 `file` 和 `copy` 任务还可以为目录和文件设置所有权和文件模式。
|
||||||
|
|
||||||
|
剧本细节超出了本文的范围,但是我对这个问题使用了一点蛮力。还有其它方法可以确定哪些用户需要更新文件,而不是对每个用户的每个文件使用一个任务。我的下一个目标是简化这个剧本,使用一些更先进的技术。
|
||||||
|
|
||||||
|
运行剧本很容易,只需要使用 `ansible-playbook` 命令。`.yml` 扩展名代表 YAML,我看到过它的几种不同含义,但我认为它是“<ruby>另一种标记语言<rt>Yet Another Markup Language</rt></ruby>”,尽管有些人声称 YAML 不是这种语言。
|
||||||
|
|
||||||
|
这个命令将会运行剧本,它会更新 Midnight Commander 文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
# ansible-playbook -f 10 UpdateMC.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
`-f` 选项指定 Ansible 使用 10 个线程来执行操作。这可以大大加快整个任务的完成速度,特别是在多台主机上工作时。
|
||||||
|
|
||||||
|
### 输出
|
||||||
|
|
||||||
|
剧本运行时会列出每个任务和执行结果。`ok` 代表任务管理的机器状态已经完成,因为在任务中定义的状态已经为真,所以 Ansible 不需要执行任何操作。
|
||||||
|
|
||||||
|
`changed` 表示 Ansible 已经执行了指定的任务。在这种情况下,任务中定义的机器状态不为真,所以执行指定的操作使其为真。在彩色终端上,`TASK` 行会以彩色显示。我的终端配色为“amber-on-black”,`TASK` 行显示为琥珀色,`changed` 是棕色,`ok` 为绿色,错误是红色。
|
||||||
|
|
||||||
|
下面的输出是我最终用于在新主机执行安装后配置的剧本:
|
||||||
|
|
||||||
|
```
|
||||||
|
PLAY [Post-installation updates, package installation, and configuration]
|
||||||
|
|
||||||
|
TASK [Gathering Facts]
|
||||||
|
ok: [testvm2]
|
||||||
|
|
||||||
|
TASK [Ensure we have connectivity]
|
||||||
|
ok: [testvm2]
|
||||||
|
|
||||||
|
TASK [Install all current updates]
|
||||||
|
changed: [testvm2]
|
||||||
|
|
||||||
|
TASK [Install a few command line tools]
|
||||||
|
changed: [testvm2]
|
||||||
|
|
||||||
|
TASK [copy latest personal Midnight Commander skin to /usr/share]
|
||||||
|
changed: [testvm2]
|
||||||
|
|
||||||
|
TASK [create ~/.config/mc directory for root]
|
||||||
|
changed: [testvm2]
|
||||||
|
|
||||||
|
TASK [Copy the most current Midnight Commander configuration files to /root/.config/mc]
|
||||||
|
changed: [testvm2] => (item=/root/ansible/PostInstallMain/files/MidnightCommander/DavidsGoTar.ini)
|
||||||
|
changed: [testvm2] => (item=/root/ansible/PostInstallMain/files/MidnightCommander/ini)
|
||||||
|
changed: [testvm2] => (item=/root/ansible/PostInstallMain/files/MidnightCommander/panels.ini)
|
||||||
|
|
||||||
|
TASK [create ~/.config/mc directory in /etc/skel]
|
||||||
|
changed: [testvm2]
|
||||||
|
|
||||||
|
<截断>
|
||||||
|
```
|
||||||
|
|
||||||
|
### cowsay
|
||||||
|
|
||||||
|
如果你的计算机上安装了 [cowsay][7] 程序,你会发现 `TASK` 的名字出现在奶牛的语音泡泡中:
|
||||||
|
|
||||||
|
```
|
||||||
|
____________________________________
|
||||||
|
< TASK [Ensure we have connectivity] >
|
||||||
|
------------------------------------
|
||||||
|
\ ^__^
|
||||||
|
\ (oo)\\_______
|
||||||
|
(__)\ )\/\
|
||||||
|
||----w |
|
||||||
|
|| ||
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你没有这个有趣的程序,你可以使用发行版的包管理器安装 Cowsay 程序。如果你有这个程序但不想要它,可以通过在 `/etc/ansible/ansible.cfg` 文件中设置 `nocows=1` 将其禁用。
|
||||||
|
|
||||||
|
我喜欢这头奶牛,它很有趣,但是它会占用我的一部分屏幕。因此,在它开始妨碍我使用时,我就把它禁用了。
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
与我的 Midnight Commander 任务一样,经常需要安装和维护各种类型的文件。创建用于存储剧本的目录树的“最佳实践”和系统管理员一样多,至少与编写有关 Ansible 书和文章的作者数量一样多。
|
||||||
|
|
||||||
|
我选择了一个对我有意义的简单结构:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/root/ansible
|
||||||
|
└── UpdateMC
|
||||||
|
├── files
|
||||||
|
│ └── MidnightCommander
|
||||||
|
│ ├── DavidsGoTar.ini
|
||||||
|
│ ├── ini
|
||||||
|
│ └── panels.ini
|
||||||
|
└── UpdateMC.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
你可以使用任何结构。但是请注意,其它系统管理员可能需要使用你设置的剧本来工作,所以目录应该具有一定程度的逻辑。当我使用 RPM 和 Bash 脚本执行安装任务后,我的文件仓库有点分散,绝对没有任何逻辑结构。当我为许多管理任务创建剧本时,我将介绍一个更有逻辑的结构来管理我的目录。
|
||||||
|
|
||||||
|
### 多次运行剧本
|
||||||
|
|
||||||
|
根据需要或期望多次运行剧本是安全的。只有当主机状态与任务中指定的状态不匹配时,才会执行每个任务。这使得很容易从先前的剧本运行中遇到的错误中恢复。因为当剧本遇到错误时,它将停止运行。
|
||||||
|
|
||||||
|
在测试我的第一个剧本时,我犯了很多错误并改正了它们。假设我的修正正确,那么剧本每次运行,都会跳过那些状态已与指定状态匹配的任务,执行不匹配状态的任务。当我的修复程序起作用时,之前失败的任务就会成功完成,并且会执行此任务之后的任务 —— 直到遇到另一个错误。
|
||||||
|
|
||||||
|
这使得测试变得容易。我可以添加新任务,并且在运行剧本时,只有新任务会被执行,因为它们是唯一与测试主机期望状态不匹配的任务。
|
||||||
|
|
||||||
|
### 一些思考
|
||||||
|
|
||||||
|
有些任务不适合用 Ansible,因为有更好的方法可以实现特定的计算机状态。我想到的场景是使 VM 返回到初始状态,以便可以多次使用它来执行从已知状态开始的测试。让 VM 进入特定状态,然后对此时的计算机状态进行快照要容易得多。还原到该快照与 Ansible 将主机返回到之前状态相比,通常还原到快照通常会更容易且更快。在研究文章或测试新代码时,我每天都会做几次这样的事情。
|
||||||
|
|
||||||
|
在完成用于更新 Midnight Commander 的剧本之后,我创建了一个新的剧本,用于在新安装的 Fedora 主机上执行安装任务。我已经取得了不错的进步,剧本比我第一个的更加复杂,但没有那么粗暴。
|
||||||
|
|
||||||
|
在使用 Ansible 的第一天,我创建了一个解决问题的剧本,我还开始编写第二个剧本,它将解决安装后配置的大问题,在这个过程中我学到了很多东西。
|
||||||
|
|
||||||
|
尽管我真的很喜欢使用 [Bash][8] 脚本来管理任务,但是我发现 Ansible 可以完成我想要的一切,并且可以使系统保持在我所需的状态。只用了一天,我就成为了 Ansible 的粉丝。
|
||||||
|
|
||||||
|
### 资源
|
||||||
|
|
||||||
|
我找到的最完整、最有用的参考文档是 Ansible 网站上的[用户指南][9]。本文仅供参考,不作为入门文档。
|
||||||
|
|
||||||
|
多年来,我们已经发布了许多[有关 Ansible 的文章][10],我发现其中大多数对我的需求很有帮助。Enable Sysadmin 网站上也有很多对我有帮助 [Ansible 文章][11]。你可以通过查看本周(2020 年 10 月 13 日至 14 日)的 [AnsibleFest][12] 了解更多信息。该活动完全是线上的,可以免费注册。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/10/first-day-ansible
|
||||||
|
|
||||||
|
作者:[David Both][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[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/dboth
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_linux11x_cc.png?itok=XMDOouJR "People work on a computer server with devices"
|
||||||
|
[2]: https://www.ansible.com/
|
||||||
|
[3]: https://www.python.org/
|
||||||
|
[4]: https://midnight-commander.org/
|
||||||
|
[5]: https://en.wikipedia.org/wiki/List_of_DNS_record_types
|
||||||
|
[6]: https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html#ansible-facts
|
||||||
|
[7]: https://en.wikipedia.org/wiki/Cowsay
|
||||||
|
[8]: https://opensource.com/downloads/bash-cheat-sheet
|
||||||
|
[9]: https://docs.ansible.com/ansible/latest/user_guide/index.html
|
||||||
|
[10]: https://opensource.com/tags/ansible
|
||||||
|
[11]: https://www.redhat.com/sysadmin/topics/ansible
|
||||||
|
[12]: https://www.ansible.com/ansiblefest
|
150
published/202102/20201103 How the Kubernetes scheduler works.md
Normal file
150
published/202102/20201103 How the Kubernetes scheduler works.md
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (MZqk)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13155-1.html)
|
||||||
|
[#]: subject: (How the Kubernetes scheduler works)
|
||||||
|
[#]: via: (https://opensource.com/article/20/11/kubernetes-scheduler)
|
||||||
|
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
|
||||||
|
|
||||||
|
Kubernetes 调度器是如何工作的
|
||||||
|
=====
|
||||||
|
|
||||||
|
> 了解 Kubernetes 调度器是如何发现新的吊舱并将其分配到节点。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/26/123446popgvrc0vppptvtk.jpg)
|
||||||
|
|
||||||
|
[Kubernetes][2] 已经成为容器和容器化工作负载的标准编排引擎。它提供一个跨公有云和私有云环境的通用和开源的抽象层。
|
||||||
|
|
||||||
|
对于那些已经熟悉 Kuberbetes 及其组件的人,他们的讨论通常围绕着如何尽量发挥 Kuberbetes 的功能。但当你刚刚开始学习 Kubernetes 时,尝试在生产环境中使用前,明智的做法是从一些关于 Kubernetes 相关组件(包括 [Kubernetes 调度器][3]) 开始学习,如下抽象视图中所示:
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
Kubernetes 也分为控制平面和工作节点:
|
||||||
|
|
||||||
|
1. **控制平面:** 也称为主控,负责对集群做出全局决策,以及检测和响应集群事件。控制平面组件包括:
|
||||||
|
* etcd
|
||||||
|
* kube-apiserver
|
||||||
|
* kube-controller-manager
|
||||||
|
* 调度器
|
||||||
|
2. **工作节点:** 也称节点,这些节点是工作负载所在的位置。它始终和主控联系,以获取工作负载运行所需的信息,并与集群外部进行通讯和连接。工作节点组件包括:
|
||||||
|
* kubelet
|
||||||
|
* kube-proxy
|
||||||
|
* CRI
|
||||||
|
|
||||||
|
我希望这个背景信息可以帮助你理解 Kubernetes 组件是如何关联在一起的。
|
||||||
|
|
||||||
|
### Kubernetes 调度器是如何工作的
|
||||||
|
|
||||||
|
Kubernetes <ruby>[吊舱][5]<rt>pod</rt></ruby> 由一个或多个容器组成组成,共享存储和网络资源。Kubernetes 调度器的任务是确保每个吊舱分配到一个节点上运行。
|
||||||
|
|
||||||
|
(LCTT 译注:容器技术领域大量使用了航海比喻,pod 一词,意为“豆荚”,在航海领域指“吊舱” —— 均指盛装多个物品的容器。常不翻译,考虑前后文,可译做“吊舱”。)
|
||||||
|
|
||||||
|
在更高层面下,Kubernetes 调度器的工作方式是这样的:
|
||||||
|
|
||||||
|
1. 每个需要被调度的吊舱都需要加入到队列
|
||||||
|
2. 新的吊舱被创建后,它们也会加入到队列
|
||||||
|
3. 调度器持续地从队列中取出吊舱并对其进行调度
|
||||||
|
|
||||||
|
[调度器源码][6](`scheduler.go`)很大,约 9000 行,且相当复杂,但解决了重要问题:
|
||||||
|
|
||||||
|
#### 等待/监视吊舱创建的代码
|
||||||
|
|
||||||
|
监视吊舱创建的代码始于 `scheduler.go` 的 8970 行,它持续等待新的吊舱:
|
||||||
|
|
||||||
|
```
|
||||||
|
// Run begins watching and scheduling. It waits for cache to be synced, then starts a goroutine and returns immediately.
|
||||||
|
|
||||||
|
func (sched *Scheduler) Run() {
|
||||||
|
if !sched.config.WaitForCacheSync() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 负责对吊舱进行排队的代码
|
||||||
|
|
||||||
|
负责对吊舱进行排队的功能是:
|
||||||
|
|
||||||
|
```
|
||||||
|
// queue for pods that need scheduling
|
||||||
|
podQueue *cache.FIFO
|
||||||
|
```
|
||||||
|
|
||||||
|
负责对吊舱进行排队的代码始于 `scheduler.go` 的 7360 行。当事件处理程序触发,表明新的吊舱显示可用时,这段代码将新的吊舱加入队列中:
|
||||||
|
|
||||||
|
```
|
||||||
|
func (f *ConfigFactory) getNextPod() *v1.Pod {
|
||||||
|
for {
|
||||||
|
pod := cache.Pop(f.podQueue).(*v1.Pod)
|
||||||
|
if f.ResponsibleForPod(pod) {
|
||||||
|
glog.V(4).Infof("About to try and schedule pod %v", pod.Name)
|
||||||
|
return pod
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 处理错误代码
|
||||||
|
|
||||||
|
在吊舱调度中不可避免会遇到调度错误。以下代码是处理调度程序错误的方法。它监听 `podInformer` 然后抛出一个错误,提示此吊舱尚未调度并被终止:
|
||||||
|
|
||||||
|
```
|
||||||
|
// scheduled pod cache
|
||||||
|
podInformer.Informer().AddEventHandler(
|
||||||
|
cache.FilteringResourceEventHandler{
|
||||||
|
FilterFunc: func(obj interface{}) bool {
|
||||||
|
switch t := obj.(type) {
|
||||||
|
case *v1.Pod:
|
||||||
|
return assignedNonTerminatedPod(t)
|
||||||
|
default:
|
||||||
|
runtime.HandleError(fmt.Errorf("unable to handle object in %T: %T", c, obj))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
换句话说,Kubernetes 调度器负责如下:
|
||||||
|
|
||||||
|
* 将新创建的吊舱调度至具有足够空间的节点上,以满足吊舱的资源需求。
|
||||||
|
* 监听 kube-apiserver 和控制器是否创建新的吊舱,然后调度它至集群内一个可用的节点。
|
||||||
|
* 监听未调度的吊舱,并使用 `/binding` 子资源 API 将吊舱绑定至节点。
|
||||||
|
|
||||||
|
例如,假设正在部署一个需要 1 GB 内存和双核 CPU 的应用。因此创建应用吊舱的节点上需有足够资源可用,然后调度器会持续运行监听是否有吊舱需要调度。
|
||||||
|
|
||||||
|
### 了解更多
|
||||||
|
|
||||||
|
要使 Kubernetes 集群工作,你需要使以上所有组件一起同步运行。调度器有一段复杂的的代码,但 Kubernetes 是一个很棒的软件,目前它仍是我们在讨论或采用云原生应用程序时的首选。
|
||||||
|
|
||||||
|
学习 Kubernetes 需要精力和时间,但是将其作为你的专业技能之一能为你的职业生涯带来优势和回报。有很多很好的学习资源可供使用,而且 [官方文档][7] 也很棒。如果你有兴趣了解更多,建议从以下内容开始:
|
||||||
|
|
||||||
|
* [Kubernetes the hard way][8]
|
||||||
|
* [Kubernetes the hard way on bare metal][9]
|
||||||
|
* [Kubernetes the hard way on AWS][10]
|
||||||
|
|
||||||
|
你喜欢的 Kubernetes 学习方法是什么?请在评论中分享吧。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/20/11/kubernetes-scheduler
|
||||||
|
|
||||||
|
作者:[Mike Calizo][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[MZqk](https://github.com/MZqk)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/mcalizo
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_modules_networking_hardware_parts.png?itok=rPpVj92- (Parts, modules, containers for software)
|
||||||
|
[2]: https://kubernetes.io/
|
||||||
|
[3]: https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
|
||||||
|
[4]: https://lh4.googleusercontent.com/egB0SSsAglwrZeWpIgX7MDF6u12oxujfoyY6uIPa8WLqeVHb8TYY_how57B4iqByELxvitaH6-zjAh795wxAB8zenOwoz2YSMIFRqHsMWD9ohvUTc3fNLCzo30r7lUynIHqcQIwmtRo
|
||||||
|
[5]: https://kubernetes.io/docs/concepts/workloads/pods/
|
||||||
|
[6]: https://github.com/kubernetes/kubernetes/blob/e4551d50e57c089aab6f67333412d3ca64bc09ae/plugin/pkg/scheduler/scheduler.go
|
||||||
|
[7]: https://kubernetes.io/docs/home/
|
||||||
|
[8]: https://github.com/kelseyhightower/kubernetes-the-hard-way
|
||||||
|
[9]: https://github.com/Praqma/LearnKubernetes/blob/master/kamran/Kubernetes-The-Hard-Way-on-BareMetal.md
|
||||||
|
[10]: https://github.com/Praqma/LearnKubernetes/blob/master/kamran/Kubernetes-The-Hard-Way-on-AWS.md
|
@ -0,0 +1,69 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (Chao-zhi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13090-1.html)
|
||||||
|
[#]: subject: (7 Bash tutorials to enhance your command line skills in 2021)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/bash)
|
||||||
|
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
|
||||||
|
|
||||||
|
7 个 Bash 教程,提高你的命令行技能(2021 版)
|
||||||
|
======
|
||||||
|
|
||||||
|
> Bash 是大多数 Linux 系统上的默认命令行 shell。所以你为什么不试着学习如何最大限度地利用它呢?
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/06/001837cujo0ql3utfobrrj.jpg)
|
||||||
|
|
||||||
|
Bash 是大多数 Linux 系统上的默认命令行 shell。所以你为什么不试着学习如何最大限度地利用它呢?今年,我们推荐了许多很棒的文章来帮助你充分利用 Bash shell 的强大功能。以下是一些关于 Bash 阅读次数最多的文章:
|
||||||
|
|
||||||
|
### 《通过重定向在 Linux 终端任意读写数据》
|
||||||
|
|
||||||
|
输入和输出重定向是任何编程或脚本语言的基础功能。从技术上讲,只要你与电脑互动,它就会自然而然地发生。输入从 stdin(标准输入,通常是你的键盘或鼠标)读取,输出到 stdout(标准输出,一般是文本或数据流),而错误被发送到 stderr(标准错误,一般和标准输出是一个位置)。了解这些数据流的存在,使你能够在使用 Bash 等 shell 时控制信息的去向。Seth Kenlon [分享][2]了这些很棒的技巧,可以让你在不需要大量鼠标移动和按键的情况下从一个地方获取数据。你可能不经常使用重定向,但学习使用它可以为你节省大量不必要的打开文件和复制粘贴数据的时间。
|
||||||
|
|
||||||
|
### 《系统管理员 Bash 脚本入门》
|
||||||
|
|
||||||
|
Bash 是自由开源软件,所以任何人都可以安装它,不管他们运行的是 Linux、BSD、OpenIndiana、Windows 还是 macOS。Seth Kenlon [帮助][3]你学习如何使用 Bash 的命令和特性,使其成为最强大的 shell 之一。
|
||||||
|
|
||||||
|
### 《针对大型文件系统可以试试此 Bash 脚本》
|
||||||
|
|
||||||
|
你是否曾经想列出一个目录中的所有文件,只显示其中的文件,不包括其他内容?或者只显示目录?如果你有,那么 Nick Clifton 的[文章][4]可能正是你正在寻找的。Nick 分享了一个漂亮的 Bash 脚本,它可以列出目录、文件、链接或可执行文件。该脚本使用 `find` 命令进行搜索,然后运行 `ls` 显示详细信息。对于管理大型 Linux 系统的人来说,这是一个漂亮的解决方案。
|
||||||
|
|
||||||
|
### 《用 Bash 工具对你的 Linux 系统配置进行快照》
|
||||||
|
|
||||||
|
你可能想与他人分享你的 Linux 配置,原因有很多。你可能需要帮助排除系统上的一个问题,或者你对自己创建的环境非常自豪,想向其他开源爱好者展示它。Don Watkins 向我们[展示][5]了 screenFetch 和 Neofetch 来捕获和分享你的系统配置。
|
||||||
|
|
||||||
|
### 《6 个方便的 Git 脚本》
|
||||||
|
|
||||||
|
Git 已经成为一个无处不在的代码管理系统。了解如何管理 Git 存储库可以简化你的开发体验。Bob Peterson [分享][6]了 6 个 Bash 脚本,它们将使你在使用 Git 存储库时更加轻松。`gitlog` 打印当前补丁的简略列表,并与主版本相对照。这个脚本的不同版本可以显示补丁的 SHA1 id 或在一组补丁中搜索字符串。
|
||||||
|
|
||||||
|
### 《改进你 Bash 脚本的 5 种方法》
|
||||||
|
|
||||||
|
系统管理员通常编写各种或长或短的 Bash 脚本,以完成各种任务。Alan Formy-Duval [解释][7]了如何使 Bash 脚本更简单、更健壮、更易于阅读和调试。我们可能会考虑到我们需要使用诸如 Python、C 或 Java 之类的语言来实现更高的功能,但其实也不一定需要。因为 Bash 脚本语言就已经非常强大。要最大限度地发挥它的效用,还有很多东西要学。
|
||||||
|
|
||||||
|
### 《我珍藏的 Bash 秘籍》
|
||||||
|
|
||||||
|
Katie McLaughlin 帮助你提高你的工作效率,用别名和其他快捷方式解决你经常忘记的事情。当你整天与计算机打交道时,找到可重复的命令并标记它们以方便以后使用是非常美妙的。Katie [总结][8]了一些有用的 Bash 特性和帮助命令,可以节省你的时间。
|
||||||
|
|
||||||
|
这些 Bash 小技巧将一个已经很强大的 shell 提升到一个全新的级别。也欢迎分享你自己的建议。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/bash
|
||||||
|
|
||||||
|
作者:[Jim Hall][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[Chao-zhi](https://github.com/Chao-zhi)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/jim-hall
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/terminal_command_linux_desktop_code.jpg?itok=p5sQ6ODE (Terminal command prompt on orange background)
|
||||||
|
[2]: https://linux.cn/article-12385-1.html
|
||||||
|
[3]: https://opensource.com/article/20/4/bash-sysadmins-ebook
|
||||||
|
[4]: https://linux.cn/article-12025-1.html
|
||||||
|
[5]: https://opensource.com/article/20/1/screenfetch-neofetch
|
||||||
|
[6]: https://linux.cn/article-11797-1.html
|
||||||
|
[7]: https://opensource.com/article/20/1/improve-bash-scripts
|
||||||
|
[8]: https://linux.cn/article-11841-1.html
|
@ -0,0 +1,229 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "MjSeven"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13126-1.html"
|
||||||
|
[#]: subject: "How to Create and Manage Archive Files in Linux"
|
||||||
|
[#]: via: "https://training.linuxfoundation.org/announcements/how-to-create-and-manage-archive-files-in-linux/"
|
||||||
|
[#]: author: "Matt Zand,Kevin Downs https://training.linuxfoundation.org/announcements/how-to-create-and-manage-archive-files-in-linux/"
|
||||||
|
|
||||||
|
如何在 Linux 中创建和管理归档文件
|
||||||
|
======
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/17/121000c7282pf7mv2sc78m.jpg)
|
||||||
|
|
||||||
|
简而言之,归档是一个包含一系列文件和(或)目录的单一文件。归档文件通常用于在本地或互联网上传输,或作为一个一系列文件和目录的备份副本,从而允许你使用一个文件来工作(如果压缩,则其大小会小于所有文件的总和)。同样的,归档也用于软件应用程序打包。为了方便传输,可以很容易地压缩这个单一文件,而存档中的文件会保留原始结构和权限。
|
||||||
|
|
||||||
|
我们可以使用 `tar` 工具来创建、列出和提取归档中的文件。用 `tar` 生成的归档通常称为“tar 文件”、“tar 归档”或者“压缩包”(因为所有已归档的文件被合成了一个文件)。
|
||||||
|
|
||||||
|
本教程会展示如何使用 `tar` 创建、列出和提取归档中的内容。这三个操作都会使用两个公共选项 `-f` 和 `-v`:使用 `-f` 指定归档文件的名称,使用 `-v`(“冗余”)选项使 `tar` 在处理文件时输出文件名。虽然 `-v` 选项不是必需的,但是它可以让你观察 `tar` 操作的过程。
|
||||||
|
|
||||||
|
在本教程的下面部分中,会涵盖 3 个主题:1、创建一个归档文件;2、列出归档文件内容;3、提取归档文件内容。另外我们会回答归档文件管理的 6 个实际问题来结束本教程。你从本教程学到的内容对于执行与[网络安全][1]和[云技术][2]相关的任务至关重要。
|
||||||
|
|
||||||
|
### 1、创建一个归档文件
|
||||||
|
|
||||||
|
要使用 `tar` 创建一个归档文件,使用 `-c`(“创建”)选项,然后用 `-f` 选项指定要创建的归档文件名。通常的做法是使用带有 `.tar` 扩展名的名称,例如 `my-backup.tar`。注意,除非另有特别说明,否则本文其余部分中使用的所有命令和参数都以小写形式使用。记住,在你的终端上输入本文的命令时,无需输入每个命令行开头的 `$` 提示符。
|
||||||
|
|
||||||
|
输入要归档的文件名作为参数;如果要创建一个包含所有文件及其子目录的归档文件,提供目录名称作为参数。
|
||||||
|
|
||||||
|
要归档 `project` 目录内容,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -cvf project.tar project
|
||||||
|
```
|
||||||
|
|
||||||
|
这个命令将创建一个名为 `project.tar` 的归档文件,包含 `project` 目录的所有内容,而原目录 `project` 将保持不变。
|
||||||
|
|
||||||
|
使用 `-z` 选项可以对归档文件进行压缩,这样产生的输出与创建未压缩的存档然后用 `gzip` 压缩是一样的,但它省去了额外的步骤。
|
||||||
|
|
||||||
|
要从 `project` 目录创建一个 `project.tar.gz` 的压缩包,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -zcvf project.tar.gz project
|
||||||
|
```
|
||||||
|
|
||||||
|
这个命令将创建一个 `project.tar.gz` 的压缩包,包含 `project` 目录的所有内容,而原目录 `project` 将保持不变。
|
||||||
|
|
||||||
|
**注意:** 在使用 `-z` 选项时,你应该使用 `.tar.gz` 扩展名而不是 `.tar` 扩展名,这样表示已压缩。虽然不是必须的,但这是一个很好的实践。
|
||||||
|
|
||||||
|
gzip 不是唯一的压缩形式,还有 bzip2 和 xz。当我们看到扩展名为 `.xz` 的文件时,我们知道该文件是使用 `xz` 压缩的,扩展名为 `.bz2` 的文件是用 `bzip2` 压缩的。随着 bzip2 不再维护,我们将远离它而关注 xz。使用 `xz` 压缩时,需要花费更长的时间。然而,等待通常是值得的,因为压缩效果要好的多,这意味着压缩包通常比使用其它压缩形式要小。更好的是,不同压缩形式之间的解压缩或提取文件并没有太大区别。下面我们将看到一个使用 `tar` 压缩文件时如何使用 xz 的示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -Jcvf project.tar.xz project
|
||||||
|
```
|
||||||
|
|
||||||
|
我们只需将 `gzip` 的 `-z` 选项转换为 `xz` 的大写 `-J` 即可。以下是一些输出,显示压缩形式之间的差异:
|
||||||
|
|
||||||
|
![][3]
|
||||||
|
|
||||||
|
![][4]
|
||||||
|
|
||||||
|
如你所见,`xz` 的压缩时间最长。但是,它在减小文件大小方面做的最好,所以值得等待。文件越大,压缩效果也越好。
|
||||||
|
|
||||||
|
### 2、列出归档文件的内容
|
||||||
|
|
||||||
|
要列出 tar 归档文件的内容但不提取,使用 `-t` 选项。
|
||||||
|
|
||||||
|
要列出 `project.tar` 的内容,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -tvf project.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
这个命令列出了 `project.tar` 归档的内容。`-v` 和 `-t` 选项一起使用会输出每个文件的权限和修改时间,以及文件名。这与 `ls` 命令使用 `-l` 选项时使用的格式相同。
|
||||||
|
|
||||||
|
要列出 `project.tar.gz` 压缩包的内容,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -tzvf project.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3、从归档中提取内容
|
||||||
|
|
||||||
|
要提取(解压)tar 归档文件中的内容,使用 `-x`(“提取”)选项。
|
||||||
|
|
||||||
|
要提取 `project.tar` 归档的内容,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -xvf project.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
这个命令会将 `project.tar` 归档的内容提取到当前目录。
|
||||||
|
|
||||||
|
如果一个归档文件被压缩,通常来说它的扩展名为 `.tar.gz` 或 `.tgz`,请包括 "-z" 选项。
|
||||||
|
|
||||||
|
要提取 `project.tar.gz` 压缩包的内容,输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -zxvf project.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**: 如果当前目录中有文件或子目录与归档文件中的内容同名,那么在提取归档文件时,这些文件或子目录将被覆盖。如果你不知道归档中包含哪些文件,请考虑先查看归档文件的内容。
|
||||||
|
|
||||||
|
在提取归档内容之前列出其内容的另一个原因是,确定归档中的内容是否包含在目录中。如果没有,而当前目录中包含许多不相关的文件,那么你可能将它们与归档中提取的文件混淆。
|
||||||
|
|
||||||
|
要将文件提取到它们自己的目录中,新建一个目录,将归档文件移到该目录,然后你就可以在新目录中提取文件。
|
||||||
|
|
||||||
|
### FAQ
|
||||||
|
|
||||||
|
现在我们已经学习了如何创建归档文件并列出和提取其内容,接下来我们可以继续讨论 Linux 专业人员经常被问到的 9 个实用问题。
|
||||||
|
|
||||||
|
#### 可以在不解压缩的情况下添加内容到压缩包中吗?
|
||||||
|
|
||||||
|
很不幸,一旦文件将被压缩,就无法向其添加内容。你需要解压缩或提取其内容,然后编辑或添加内容,最后再次压缩文件。如果文件很小,这个过程不会花费很长时间,否则请等待一会。
|
||||||
|
|
||||||
|
#### 可以在不解压缩的情况下删除归档文件中的内容吗?
|
||||||
|
|
||||||
|
这取决压缩时使用的 tar 版本。较新版本的 `tar` 支持 `-delete` 选项。
|
||||||
|
|
||||||
|
例如,假设归档文件中有 `file1` 和 `file2`,可以使用以下命令将它们从 `file.tar` 中删除:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -vf file.tar –delete file1 file2
|
||||||
|
```
|
||||||
|
|
||||||
|
删除目录 `dir1`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -f file.tar –delete dir1/*
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 压缩和归档之间有什么区别?
|
||||||
|
|
||||||
|
查看归档和压缩之间差异最简单的方法是查看其解压大小。归档文件时,会将多个文件合并为一个。所以,如果我们归档 10 个 100kb 文件,则最终会得到一个 100kb 大小的文件。而如果压缩这些文件,则最终可能得到一个只有几 kb 或接近 100kb 的文件。
|
||||||
|
|
||||||
|
#### 如何压缩归档文件?
|
||||||
|
|
||||||
|
如上所说,你可以使用带有 `cvf` 选项的 `tar` 命令来创建和归档文件。要压缩归档文件,有两个选择:通过压缩程序(例如 `gzip`)运行归档文件,或在使用 `tar` 命令时使用压缩选项。最常见的压缩标志 `-z` 表示 `gzip`,`-j` 表示 `bzip`,`-J` 表示 `xz`。例如:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gzip file.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
或者,我们可以在使用 `tar` 命令时使用压缩标志,以下命令使用 `gzip` 标志 `z`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -cvzf file.tar /some/directory
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 如何一次创建多个目录和/或文件的归档?
|
||||||
|
|
||||||
|
一次要归档多个文件,这种情况并不少见。一次归档多个文件和目录并不像你想的那么难,你只需要提供多个文件或目录作为 tar 的参数即可:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -cvzf file.tar file1 file2 file3
|
||||||
|
```
|
||||||
|
|
||||||
|
或者
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar -cvzf file.tar /some/directory1 /some/directory2
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 创建归档时如何跳过目录和/或文件?
|
||||||
|
|
||||||
|
你可能会遇到这样的情况:要归档一个目录或文件,但不是所有文件,这种情况下可以使用 `--exclude` 选项:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ tar –exclude ‘/some/directory’ -cvf file.tar /home/user
|
||||||
|
```
|
||||||
|
|
||||||
|
在示例中,`/home/user` 目录中除了 `/some/directory` 之外都将被归档。将 `--exclude` 选项放在源和目标之前,并用单引号将要排除的文件或目录引起来,这一点很重要。
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
`tar` 命令对展示不需要的文件创建备份或压缩文件很有用。在更改文件之前备份它们是一个很好的做法。如果某些东西在更改后没有按预期正常工作,你始终可以还原到旧文件。压缩不再使用的文件有助于保持系统干净,并降低磁盘空间使用率。还有其它实用程序可以归档或压缩,但是 `tar` 因其多功能、易用性和受欢迎程度而独占鳌头。
|
||||||
|
|
||||||
|
### 资源
|
||||||
|
|
||||||
|
如果你想了解有关 Linux 的更多信息,强烈建议阅读以下文章和教程:
|
||||||
|
|
||||||
|
* [Linux 文件系统架构和管理综述][5]
|
||||||
|
* [Linux 文件和目录系统工作原理的全面回顾][6]
|
||||||
|
* [所有 Linux 系统发行版的综合列表][7]
|
||||||
|
* [特殊用途 Linux 发行版的综合列表][8]
|
||||||
|
* [Linux 系统管理指南 - 制作和管理备份操作的最佳实践][9]
|
||||||
|
* [Linux 系统管理指南 - Linux 虚拟内存和磁盘缓冲区缓存概述][10]
|
||||||
|
* [Linux 系统管理指南 - 监控 Linux 的最佳实践][11]
|
||||||
|
* [Linux 系统管理指南 - Linux 启动和关闭的最佳实践][12]
|
||||||
|
|
||||||
|
### 关于作者
|
||||||
|
|
||||||
|
**Matt Zand** 是一位创业者,也是 3 家科技创业公司的创始人: [DC Web Makers][13]、[Coding Bootcamps][14] 和 [High School Technology Services][15]。他也是 [使用 Hyperledger Fabric 进行智能合约开发][16] 一书的主要作者。他为 Hyperledger、以太坊和 Corda R3 平台编写了 100 多篇关于区块链开发的技术文章和教程。在 DC Web Makers,他领导了一个区块链专家团队,负责咨询和部署企业去中心化应用程序。作为首席架构师,他为编码训练营设计和开发了区块链课程和培训项目。他拥有马里兰大学工商管理硕士学位。在区块链开发和咨询之前,他曾担任一些初创公司的高级网页和移动应用程序开发和顾问、天使投资人和业务顾问。你可以通过以下这个网址和他取得联系: <https://www.linkedin.com/in/matt-zand-64047871>。
|
||||||
|
|
||||||
|
**Kevin Downs** 是 Red Hat 认证的系统管理员和 RHCSA。他目前在 IBM 担任系统管理员,负责管理数百台运行在不同 Linux 发行版上的服务器。他是[编码训练营][17]的首席 Linux 讲师,并且他会讲授 [5 个自己的课程][18]。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://www.linux.com/news/how-to-create-and-manage-archive-files-in-linux-2/
|
||||||
|
|
||||||
|
作者:[LF Training][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[MjSeven](https://github.com/MjSeven)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://training.linuxfoundation.org/announcements/how-to-create-and-manage-archive-files-in-linux/
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://learn.coding-bootcamps.com/p/essential-practical-guide-to-cybersecurity-for-system-admin-and-developers
|
||||||
|
[2]: https://learn.coding-bootcamps.com/p/introduction-to-cloud-technology
|
||||||
|
[3]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/Linux1-300x94.png
|
||||||
|
[4]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/Linux2-300x110.png
|
||||||
|
[5]: https://blockchain.dcwebmakers.com/blog/linux-os-file-system-architecture-and-management.html
|
||||||
|
[6]: https://coding-bootcamps.com/linux/filesystem/index.html
|
||||||
|
[7]: https://myhsts.org/tutorial-list-of-all-linux-operating-system-distributions.php
|
||||||
|
[8]: https://coding-bootcamps.com/list-of-all-special-purpose-linux-distributions.html
|
||||||
|
[9]: https://myhsts.org/tutorial-system-admin-best-practices-for-managing-backup-operations.php
|
||||||
|
[10]: https://myhsts.org/tutorial-how-linux-virtual-memory-and-disk-buffer-cache-work.php
|
||||||
|
[11]: https://myhsts.org/tutorial-system-admin-best-practices-for-monitoring-linux-systems.php
|
||||||
|
[12]: https://myhsts.org/tutorial-best-practices-for-performing-linux-boots-and-shutdowns.php
|
||||||
|
[13]: https://blockchain.dcwebmakers.com/
|
||||||
|
[14]: http://coding-bootcamps.com/
|
||||||
|
[15]: https://myhsts.org/
|
||||||
|
[16]: https://www.oreilly.com/library/view/hands-on-smart-contract/9781492086116/
|
||||||
|
[17]: https://coding-bootcamps.com/
|
||||||
|
[18]: https://learn.coding-bootcamps.com/courses/author/758905
|
||||||
|
[19]: https://training.linuxfoundation.org/announcements/how-to-create-and-manage-archive-files-in-linux/
|
||||||
|
[20]: https://training.linuxfoundation.org/
|
@ -0,0 +1,125 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (mengxinayan)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13132-1.html)
|
||||||
|
[#]: subject: (10 ways to get started with open source in 2021)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/getting-started-open-source)
|
||||||
|
[#]: author: (Lauren Maffeo https://opensource.com/users/lmaffeo)
|
||||||
|
|
||||||
|
2021 年开始使用开源的 10 种方式
|
||||||
|
======
|
||||||
|
|
||||||
|
> 如果你刚开始接触开源,那么下面的 2020 年十篇好文章有助于指导你的发展之路。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/19/110943di1i609a9spys1i1.jpg)
|
||||||
|
|
||||||
|
我们存在的意义是为了向世界宣传开源的一切,从新工具到框架拓展到社区。我们的目标是让想要使用开源或为开源做贡献的人更容易参与其中。
|
||||||
|
|
||||||
|
入门开源可能很难,所以我们定期分享如何参与其中的提示和建议。如果你想要学习 Python,帮助抗击 COVID-19,或者加入 K8s 设置,我们将为你服务。
|
||||||
|
|
||||||
|
为了帮助你开始,我们总结了 2020 年发布的 10 篇最流行的开源入门文章。希望它们能激发你在 2021 年学习一些新知识。
|
||||||
|
|
||||||
|
### 《利用 Python 爬取网站的新手指南》
|
||||||
|
|
||||||
|
你是否想通过实践而不是阅读来学习 Python?在本教程中,Julia Piaskowski 将会指导你完成她的第一个[Python 网页爬取项目][2]。她具体展示了如何使用 Python 的 `requests` 库访问网页内容。
|
||||||
|
|
||||||
|
Julia 详细介绍了每一步,从安装 Python3 到使用 Pandas 来清理 Web 抓取结果。她利用了大量截图解释了如何以最终目标为目的进行爬取。
|
||||||
|
|
||||||
|
有关爬取相关内容的部分特别有用;当遇到困难处时,她会详细解释。但是,与本文的其余部分一样,她会指导你完成每个步骤。
|
||||||
|
|
||||||
|
### 《在 Linux 上使用 SSH 进行远程连接的初学者指南》
|
||||||
|
|
||||||
|
如果你之前从未使用过安全 shell(SSH),那么你在第一次使用时可能会感到困惑。在本教程中,Seth Kenlon 展示了[如何为两台计算机之间配置 SSH 连接][3],以及如何不使用密码而安全地进行连接。
|
||||||
|
|
||||||
|
Seth 解释了建立 SSH 连接的每个步骤,从你应该了解的四个关键术语到在每个主机上激活 SSH 的步骤。他还提供了有关查找计算机 IP 地址、创建 SSH 密钥以及对远程计算机的远程访问权限的建议。
|
||||||
|
|
||||||
|
### 《五步学会任何编程语言》
|
||||||
|
|
||||||
|
如果你已经掌握了一种编程语言,你就能[学习所有的语言][4]。这是 Seth Kenlon 编写本文的前提,他认为了解一些基本编程逻辑便可以跨语言拓展。
|
||||||
|
|
||||||
|
Seth 分享了程序员在学习一种新的编程语言或编码方式时所需要的五种东西。语法、内置函数和解析器是这五种之一,他对每一种都附上了行动步骤。
|
||||||
|
|
||||||
|
那么将它们统一起来的关键方式是?一旦了解了代码工作原理,你就可以跨语言拓展。对你来说,没有什么是太难学的。
|
||||||
|
|
||||||
|
### 《为 COVID-19 贡献开源医疗项目》
|
||||||
|
|
||||||
|
你是否知道一家意大利医院通过 3D 打印机设备挽救了 COVID-19 患者的生命?这是开源贡献者为 2020 年 COVID-19 大流行[建立的众多解决方案之一][5]。
|
||||||
|
|
||||||
|
在本文中,Joshua Pearce 分享了针对 COVID-19 的开源志愿服务项目。虽然 Open Air 是最大的项目,但 Joshua 解释了如何为开源呼吸机的维基工作,编写开源 COVID-19 医疗供应要求,测试开源氧气浓缩机原型等。
|
||||||
|
|
||||||
|
### 《GNOME 入门建议》
|
||||||
|
|
||||||
|
GNOME 是最受欢迎的 Linux 桌面之一,但是它适合你吗?本文分享了[来自 GNOME 用户的建议][6],以及有关此主题的文章。
|
||||||
|
|
||||||
|
想要在配置桌面上寻找一些灵感吗?本文包含了有关 GNOME 扩展入门,将 Dash 安装到 Dock,使用 GNOME Tweak 工具等的链接。
|
||||||
|
|
||||||
|
不过,你仍然可能会认为 GNOME 不适合你——不用担心,最后你将找到指向其他 Linux 桌面和窗口管理器的链接。
|
||||||
|
|
||||||
|
### 《现在开始为开源做贡献的 3 个理由》
|
||||||
|
|
||||||
|
截至到 2020 年 6 月,Github 托管了超过 180,000 个公共仓库。现如今加入开源社区比过去更容易,但这是否意味着你应该加入开源?在本文中,Jason Blais [分享了三个投身开源的原因][7]。
|
||||||
|
|
||||||
|
为开源做贡献可以增强你的信心、简历和专业网络。Jason 还解释了如何利用有用的信息,从如何在领英个人资料中添加开源信息,到如何将这些贡献转变为付费角色。最后还列出了供初学者参与的出色项目。
|
||||||
|
|
||||||
|
### 《作为 Linux 系统管理员为开源做贡献的 4 种方法》
|
||||||
|
|
||||||
|
系统管理员是开源的无名英雄。他们在代码背后做了大量工作,这些代码非常有价值,但通常是看不见的。
|
||||||
|
|
||||||
|
在本文中,Elizabeth K. Joseph 介绍了她如何以 Linux 系统管理员的身份[来改善开源项目][8]。用户支持、托管项目资源、寻找新的网站环境是让社区比她发现时变得更好的几种方式。
|
||||||
|
|
||||||
|
也许最重要的贡献是什么?文档!Elizabeth 在开源领域的起步是她为使用的项目重写了快速入门指南。向你经常使用的项目提交错误和补丁报告是参与其中的理想方法。
|
||||||
|
|
||||||
|
### 《为 Slack 的开源替代品做出贡献的 6 种方法》
|
||||||
|
|
||||||
|
Mattermost 是一个很受欢迎的平台,适合那些想要一个开源消息传递系统的团队的平台。其活跃、充满活力的社区是让用户保持忠诚度的关键因素,尤其是对那些具有 Go、React 和 DevOps 经验的用户。
|
||||||
|
|
||||||
|
如果你想[为 Mattermost 做出贡献][9],Jason Blais 具体介绍了如何参与其中。将本文视为你的入门文档:Blais 分享了你要采取的步骤,并介绍了你可以做出的六种贡献。
|
||||||
|
|
||||||
|
无论你是要构建一个集成还是本地化你的语言,本文都将介绍如何进行。
|
||||||
|
|
||||||
|
### 《如何为 Kubernetes 做贡献》
|
||||||
|
|
||||||
|
当我走进 2018 年温哥华青年开源峰会时,还很年轻,对 Kubernetes 一无所知。主题演讲结束后,我离开会场后依然是一个有所改变而依然困惑的女人。毫不夸张地说,Kubernetes 已经彻底改变了开源,这并不夸张:很难找到一个更受欢迎、更有影响力的项目。
|
||||||
|
|
||||||
|
如果你想做出贡献,那么 IBM 工程师 Tara Gu 介绍了[她是如何开始的][10]。本文介绍了她在 All Things Open 2019 会议上的闪电演讲的回顾以及包括她亲自演讲的视频。还记得吗?
|
||||||
|
|
||||||
|
### 《任何人如何在工作中为开源软件做出贡献》
|
||||||
|
|
||||||
|
需求是发明之母,尤其是在开源领域。许多人针对自己遇到的问题构建开源解决方案。但是如果开发人员在没有收集目标用户反馈的情况下通过构建产品而错过了目标,会发生什么呢?
|
||||||
|
|
||||||
|
在企业中,产品和设计团队通常会填补这一空白。如果开源团队中不存在这样的角色,开发人员应该怎么做?
|
||||||
|
|
||||||
|
在本文中,Catherine Robson 介绍了开源团队如何从目标用户那里[收集反馈][11]。它为希望与开发人员分享他们的工作经验,从而将他们的反馈贡献到开源项目的人们而编写。
|
||||||
|
|
||||||
|
Catherine 概述的步骤将帮助你与开源团队分享你的见解,并在帮助团队开发更好的产品方面发挥关键作用。
|
||||||
|
|
||||||
|
### 你想要学习什么?
|
||||||
|
|
||||||
|
你想了解开源入门哪些方面的知识?请在评论中分享你对文章主题的建议。同时如果你有故事可以分享,以帮助他人开始使用开源软件,请考虑[撰写文章][12]。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/getting-started-open-source
|
||||||
|
|
||||||
|
作者:[Lauren Maffeo][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/lmaffeo
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/career_journey_road_gps_path_map_520.png?itok=PpL6jJgY (Looking at a map for career journey)
|
||||||
|
[2]: https://linux.cn/article-13047-1.html
|
||||||
|
[3]: https://opensource.com/article/20/9/ssh
|
||||||
|
[4]: https://linux.cn/article-12842-1.html
|
||||||
|
[5]: https://opensource.com/article/20/3/volunteer-covid19
|
||||||
|
[6]: https://opensource.com/article/20/6/gnome-users
|
||||||
|
[7]: https://opensource.com/article/20/6/why-contribute-open-source
|
||||||
|
[8]: https://opensource.com/article/20/7/open-source-sysadmin
|
||||||
|
[9]: https://opensource.com/article/20/7/mattermost
|
||||||
|
[10]: https://opensource.com/article/20/1/contributing-kubernetes-all-things-open-2019
|
||||||
|
[11]: https://opensource.com/article/20/10/open-your-job
|
||||||
|
[12]: https://opensource.com/how-submit-article
|
119
published/202102/20210119 Set up a Linux cloud on bare metal.md
Normal file
119
published/202102/20210119 Set up a Linux cloud on bare metal.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13161-1.html)
|
||||||
|
[#]: subject: (Set up a Linux cloud on bare metal)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/cloud-image-virt-install)
|
||||||
|
[#]: author: (Sumantro Mukherjee https://opensource.com/users/sumantro)
|
||||||
|
|
||||||
|
在裸机上建立 Linux 云实例
|
||||||
|
======
|
||||||
|
|
||||||
|
> 在 Fedora 上用 virt-install 创建云镜像。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/28/130111cx5pux33bt74o36g.jpg)
|
||||||
|
|
||||||
|
虚拟化是使用最多的技术之一。Fedora Linux 使用 [Cloud Base 镜像][2] 来创建通用虚拟机(VM),但设置 Cloud Base 镜像的方法有很多。最近,用于调配虚拟机的 `virt-install` 命令行工具增加了对 `cloud-init` 的支持,因此现在可以使用它在本地配置和运行云镜像。
|
||||||
|
|
||||||
|
本文介绍了如何在裸机上设置一个基本的 Fedora 云实例。同样的步骤可以用于任何 raw 或Qcow2 Cloud Base 镜像。
|
||||||
|
|
||||||
|
### 什么是 --cloud-init?
|
||||||
|
|
||||||
|
`virt-install` 命令使用 `libvirt` 创建一个 KVM、Xen 或 [LXC][3] 客户机。`--cloud-init` 选项使用一个本地文件(称为 “nocloud 数据源”),所以你不需要网络连接来创建镜像。在第一次启动时,`nocloud` 方法会从 iso9660 文件系统(`.iso` 文件)中获取访客机的用户数据和元数据。当你使用这个选项时,`virt-install` 会为 root 用户账户生成一个随机的(临时)密码,提供一个串行控制台,以便你可以登录并更改密码,然后在随后的启动中禁用 `--cloud-init` 选项。
|
||||||
|
|
||||||
|
### 设置 Fedora Cloud Base 镜像
|
||||||
|
|
||||||
|
首先,[下载一个 Fedora Cloud Base(for OpenStack)镜像][2]。
|
||||||
|
|
||||||
|
![Fedora Cloud 网站截图][4]
|
||||||
|
|
||||||
|
然后安装 `virt-install` 命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo dnf install virt-install
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦 `virt-install` 安装完毕并下载了 Fedora Cloud Base 镜像,请创建一个名为`cloudinit-user-data.yaml` 的小型 YAML 文件,其中包含 `virt-install` 将使用的一些配置行:
|
||||||
|
|
||||||
|
```
|
||||||
|
#cloud-config
|
||||||
|
password: 'r00t'
|
||||||
|
chpasswd: { expire: false }
|
||||||
|
```
|
||||||
|
|
||||||
|
这个简单的云配置可以设置默认的 `fedora` 用户的密码。如果你想使用会过期的密码,可以将其设置为登录后过期。
|
||||||
|
|
||||||
|
创建并启动虚拟机:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virt-install --name local-cloud18012709 \
|
||||||
|
--memory 2000 --noreboot \
|
||||||
|
--os-variant detect=on,name=fedora-unknown \
|
||||||
|
--cloud-init user-data="/home/r3zr/cloudinit-user-data.yaml" \
|
||||||
|
--disk=size=10,backing_store="/home/r3zr/Downloads/Fedora-Cloud-Base-33-1.2.x86_64.qcow2"
|
||||||
|
```
|
||||||
|
|
||||||
|
在这个例子中,`local-cloud18012709` 是虚拟机的名称,内存设置为 2000MiB,磁盘大小(虚拟硬盘)设置为 10GB,`--cloud-init` 和 `backing_store` 分别带有你创建的 YAML 配置文件和你下载的 Qcow2 镜像的绝对路径。
|
||||||
|
|
||||||
|
### 登录
|
||||||
|
|
||||||
|
在创建镜像后,你可以用用户名 `fedora` 和 YAML 文件中设置的密码登录(在我的例子中,密码是 `r00t`,但你可能用了别的密码)。一旦你第一次登录,请更改你的密码。
|
||||||
|
|
||||||
|
要关闭虚拟机的电源,执行 `sudo poweroff` 命令,或者按键盘上的 `Ctrl+]`。
|
||||||
|
|
||||||
|
### 启动、停止和销毁虚拟机
|
||||||
|
|
||||||
|
`virsh` 命令用于启动、停止和销毁虚拟机。
|
||||||
|
|
||||||
|
要启动任何停止的虚拟机:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virsh start <vm-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
要停止任何运行的虚拟机:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virsh shutdown <vm-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
要列出所有处于运行状态的虚拟机:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virsh list
|
||||||
|
```
|
||||||
|
|
||||||
|
要销毁虚拟机:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virsh destroy <vm-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
![销毁虚拟机][6]
|
||||||
|
|
||||||
|
### 快速而简单
|
||||||
|
|
||||||
|
`virt-install` 命令与 `--cloud-init` 选项相结合,可以快速轻松地创建云就绪镜像,而无需担心是否有云来运行它们。无论你是在为重大部署做准备,还是在学习容器,都可以试试`virt-install --cloud-init`。
|
||||||
|
|
||||||
|
在云计算工作中,你有喜欢的工具吗?请在评论中告诉我们。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/cloud-image-virt-install
|
||||||
|
|
||||||
|
作者:[Sumantro Mukherjee][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/sumantro
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-cloud.png?itok=vz0PIDDS (Sky with clouds and grass)
|
||||||
|
[2]: https://alt.fedoraproject.org/cloud/
|
||||||
|
[3]: https://www.redhat.com/sysadmin/exploring-containers-lxc
|
||||||
|
[4]: https://opensource.com/sites/default/files/uploads/fedoracloud.png (Fedora Cloud website)
|
||||||
|
[5]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[6]: https://opensource.com/sites/default/files/uploads/destroyvm.png (Destroying a VM)
|
@ -0,0 +1,286 @@
|
|||||||
|
[#]: collector: "lujun9972"
|
||||||
|
[#]: translator: "amwps290"
|
||||||
|
[#]: reviewer: "wxy"
|
||||||
|
[#]: publisher: "wxy"
|
||||||
|
[#]: url: "https://linux.cn/article-13087-1.html"
|
||||||
|
[#]: subject: "Learn JavaScript by writing a guessing game"
|
||||||
|
[#]: via: "https://opensource.com/article/21/1/learn-javascript"
|
||||||
|
[#]: author: "Mandy Kendall https://opensource.com/users/mkendall"
|
||||||
|
|
||||||
|
通过编写一个简单的游戏学习 JavaScript
|
||||||
|
======
|
||||||
|
|
||||||
|
> 通过使用一个简单的游戏来练习一些基本的 JavaScript 概念,迈出创建交互性动态 Web 内容的第一步。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/05/151531z6fzqx8vk8tdan81.jpg)
|
||||||
|
|
||||||
|
可以肯定地说,没有 [JavaScript][2],大多数现代 Web 都将不存在。它是三种标准 Web 技术(以及 HTML 和 CSS )之一,它使任何人都可以创建我们在万维网体验中所期待的交互式、动态内容。从 [React][3] 这样的框架到 [D3][4] 这样的数据可视化库,很难想象没有它的 Web。
|
||||||
|
|
||||||
|
现在有很多东西要学习,开始学习这种流行语言的好方法是编写一个简单的应用程序以熟悉某些概念。 最近,一些人写了关于如何通过编写简单的猜谜游戏来学习自己喜欢的语言的文章,因此这是一个很好的起点!
|
||||||
|
|
||||||
|
### 现在开始吧
|
||||||
|
|
||||||
|
JavaScript 有许多种风格,但我将从最基本的开始,通常称为 “普通 JavaScript”。 JavaScript 主要是一种客户端脚本语言,因此它可以在任何标准浏览器中运行,而无需安装任何程序。你只需要一个代码编辑器([Brackets][5] 就是一个不错的选择)和一个 Web 浏览器。
|
||||||
|
|
||||||
|
### HTML 用户界面
|
||||||
|
|
||||||
|
JavaScript 在 Web 浏览器中运行,并与其他标准 Web 技术 HTML 和 CSS 交互。要创建此游戏,你首先需要使用 HTML(超文本标记语言)来创建供玩家使用的简单界面。如果你不清楚,HTML 是一种标记语言,用于为 Web 内容提供结构。
|
||||||
|
|
||||||
|
首先,先创建一个 HTML 文件。该文件应具有 `.html` 扩展名,以使浏览器知道它是 HTML 文档。你可以将文件命名为 `guessingGame.html`。
|
||||||
|
|
||||||
|
在此文件中使用一些基本的 HTML 标签来显示游戏的标题、玩法说明,供玩家用来输入和提交其猜测的交互式元素以及用于向玩家提供反馈的占位符:
|
||||||
|
|
||||||
|
```
|
||||||
|
<!DOCTYPE>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title> JavaScript Guessing Game </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Guess the Number!</h1>
|
||||||
|
<p>I am thinking of a number between 1 and 100. Can you guess what it is?</p>
|
||||||
|
|
||||||
|
<label for="guess">My Guess</label>
|
||||||
|
<input type="number" id="guess">
|
||||||
|
<input type="submit" id="submitGuess" value="Check My Guess">
|
||||||
|
|
||||||
|
<p id="feedback"></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
`<h1>` 和 `<p>` 元素使浏览器知道在页面上显示什么类型的文本。标签对 `<h1></h1>` 表示标签之间的文本(`Guess the Number!`)是标题。后面的一组 `<p>` 标签表示带有说明的短文本是一个段落。此代码块末尾的空 `<p>` 标签用作占位符,用于根据用户的输入提供一些反馈。
|
||||||
|
|
||||||
|
### `<script>` 标签
|
||||||
|
|
||||||
|
在网页中包含 JavaScript 的方法有很多种,但是对于像这样的简短脚本,可以使用一组 `<script>` 标签并将 JavaScript 直接写在 HTML 文件中。 这些 `<script>` 标签应位于 HTML 文件末尾附近的 `</body>` 标签之前。
|
||||||
|
|
||||||
|
现在,你可以开始在这两个脚本标签之间编写 JavaScript。 最终文件如下所示:
|
||||||
|
|
||||||
|
```
|
||||||
|
<!DOCTYPE>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title> JavaScript Guessing Game </title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Guess the Number!</h1>
|
||||||
|
<p>I am thinking of a number between 1 and 100. Can you guess what it is?</p>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<label for="guess">My Guess</label>
|
||||||
|
<input type="number" id="guess">
|
||||||
|
<input type="submit" id="submitGuess" value="Check My Guess">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p id="feedback"></p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const randomNumber = Math.floor(Math.random() * 100) + 1
|
||||||
|
console.log('Random Number', randomNumber)
|
||||||
|
|
||||||
|
function checkGuess() {
|
||||||
|
let myGuess = guess.value
|
||||||
|
if (myGuess === randomNumber) {
|
||||||
|
feedback.textContent = "You got it right!"
|
||||||
|
} else if (myGuess > randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
|
||||||
|
} else if (myGuess < randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
submitGuess.addEventListener('click', checkGuess)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
要在浏览器中运行此文件,请双击文件或打开你喜欢的浏览器,点击菜单,然后选择**文件->打开文件**。(如果使用 Brackets 软件,也可以使用角落处的闪电图标在浏览器中打开文件)。
|
||||||
|
|
||||||
|
### 生成伪随机数
|
||||||
|
|
||||||
|
猜谜游戏的第一步是为玩家生成一个数字供玩家猜测。JavaScript 包含几个内置的全局对象,可帮助你编写代码。要生成随机数,请使用 `Math` 对象。
|
||||||
|
|
||||||
|
JavaScript中的 [Math][17] 具有处理和数学相关的属性和功能。你将使用两个数学函数来生成随机数,供你的玩家猜测。
|
||||||
|
|
||||||
|
[Math.random()][18],会将生成一个介于 0 和 1 之间的伪随机数。(`Math.random` 包含 0 但不包含 1。这意味着该函数可以生成 0 ,永远不会产生 1)
|
||||||
|
|
||||||
|
对于此游戏,请将随机数设置在 1 到 100 之间以缩小玩家的选择范围。取刚刚生成的小数,然后乘以 100,以产生一个介于 0 到……甚至不是 100 之间的小数。至此,你将需要其他步骤来解决这个问题。
|
||||||
|
|
||||||
|
现在,你的数字仍然是小数,但你希望它是一个整数。为此,你可以使用属于 `Math` 对象的另一个函数 [Math.floor()][19]。`Math.floor()` 的目的是返回小于或等于你作为参数指定的数字的最大整数,这意味着它会四舍五入为最接近的整数:
|
||||||
|
|
||||||
|
```
|
||||||
|
Math.floor(Math.random() * 100)
|
||||||
|
```
|
||||||
|
|
||||||
|
这样你将得到 0 到 99 之间的整数,这不是你想要的范围。你可以在最后一步修复该问题,即在结果中加 1。瞧!现在,你有一个(有点)随机生成的数字,介于 1 到 100 之间:
|
||||||
|
|
||||||
|
```
|
||||||
|
Math.floor(Math.random() * 100) + 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 变量
|
||||||
|
|
||||||
|
现在,你需要存储随机生成的数字,以便可以将其与玩家的猜测进行比较。为此,你可以将其存储到一个 **变量**。
|
||||||
|
|
||||||
|
JavaScript 具有不同类型的变量,你可以选择这些类型,具体取决于你要如何使用该变量。对于此游戏,请使用 `const` 和 `let`。
|
||||||
|
|
||||||
|
* `let` 用于指示变量在整个程序中可以改变。
|
||||||
|
* `const` 用于指示变量不应该被修改。
|
||||||
|
|
||||||
|
`const` 和 `let` 还有很多要说的,但现在知道这些就足够了。
|
||||||
|
|
||||||
|
随机数在游戏中仅生成一次,因此你将使用 `const` 变量来保存该值。你想给变量起一个清楚地表明要存储什么值的名称,因此将其命名为 `randomNumber`:
|
||||||
|
|
||||||
|
```
|
||||||
|
const randomNumber
|
||||||
|
```
|
||||||
|
|
||||||
|
有关命名的注意事项:JavaScript 中的变量和函数名称以驼峰形式编写。如果只有一个单词,则全部以小写形式书写。如果有多个单词,则第一个单词均为小写,其他任何单词均以大写字母开头,且单词之间没有空格。
|
||||||
|
|
||||||
|
### 打印到控制台
|
||||||
|
|
||||||
|
通常,你不想向任何人显示随机数,但是开发人员可能想知道生成的数字以使用它来帮助调试代码。 使用 JavaScript,你可以使用另一个内置函数 [console.log()][20] 将数字输出到浏览器的控制台。
|
||||||
|
|
||||||
|
大多数浏览器都包含开发人员工具,你可以通过按键盘上的 `F12` 键来打开它们。从那里,你应该看到一个 **控制台** 标签。打印到控制台的所有信息都将显示在此处。由于到目前为止编写的代码将在浏览器加载后立即运行,因此,如果你查看控制台,你应该会看到刚刚生成的随机数!
|
||||||
|
|
||||||
|
![Javascript game with console][21]
|
||||||
|
|
||||||
|
### 函数
|
||||||
|
|
||||||
|
接下来,你需要一种方法来从数字输入字段中获得玩家的猜测,将其与你刚刚生成的随机数进行比较,并向玩家提供反馈,让他们知道他们是否正确猜到了。为此,编写一个函数。 **函数** 是执行一定任务的代码块。函数是可以重用的,这意味着如果你需要多次运行相同的代码,则可以调用函数,而不必重写执行任务所需的所有步骤。
|
||||||
|
|
||||||
|
根据你使用的 JavaScript 版本,有许多不同的方法来编写或声明函数。由于这是该语言的基础入门,因此请使用基本函数语法声明函数。
|
||||||
|
|
||||||
|
以关键字 `function` 开头,然后起一个函数名。好的做法是使用一个描述该函数的功能的名称。在这个例子中,你正在检查玩家的猜测的数,因此此函数的名字可以是 `checkGuess`。在函数名称之后,写上一组小括号,然后写上一组花括号。 你将在以下花括号之间编写函数的主体:
|
||||||
|
|
||||||
|
```
|
||||||
|
function checkGuess() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用 DOM
|
||||||
|
|
||||||
|
JavaScript 的目的之一是与网页上的 HTML 交互。它通过文档对象模型(DOM)进行此操作,DOM 是 JavaScript 用于访问和更改网页信息的对象。现在,你需要从 HTML 中获取数字输入字段中玩家的猜测。你可以使用分配给 HTML 元素的 `id` 属性(在这种情况下为 `guess`)来做到这一点:
|
||||||
|
|
||||||
|
```
|
||||||
|
<input type="number" id="guess">
|
||||||
|
```
|
||||||
|
|
||||||
|
JavaScript 可以通过访问玩家输入到数字输入字段中的数来获取其值。你可以通过引用元素的 ID 并在末尾添加 `.value` 来实现。这次,使用 `let` 定义的变量来保存用户的猜测值:
|
||||||
|
|
||||||
|
```
|
||||||
|
let myGuess = guess.value
|
||||||
|
```
|
||||||
|
|
||||||
|
玩家在数字输入字段中输入的任何数字都将被分配给 `checkGuess` 函数中的 `myGuess` 变量。
|
||||||
|
|
||||||
|
### 条件语句
|
||||||
|
|
||||||
|
下一步是将玩家的猜测与游戏产生的随机数进行比较。你还想给玩家反馈,让他们知道他们的猜测是太高,太低还是正确。
|
||||||
|
|
||||||
|
你可以使用一系列条件语句来决定玩家将收到的反馈。**条件语句** 在运行代码块之前检查是否满足条件。如果不满足条件,则代码停止,继续检查下一个条件,或者继续执行其余代码,而无需执行条件块中的代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
if (myGuess === randomNumber){
|
||||||
|
feedback.textContent = "You got it right!"
|
||||||
|
}
|
||||||
|
else if(myGuess > randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
|
||||||
|
}
|
||||||
|
else if(myGuess < randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
第一个条件块使用比较运算符 `===` 将玩家的猜测与游戏生成的随机数进行比较。比较运算符检查右侧的值,将其与左侧的值进行比较,如果匹配则返回布尔值 `true`,否则返回布尔值 `false`。
|
||||||
|
|
||||||
|
如果数字匹配(猜对了!),为了让玩家知道。通过将文本添加到具有 `id` 属性 `feedback` 的 `<p>` 标记中来操作 DOM。就像上面的 `guess.value` 一样,除了不是从 DOM 获取信息,而是更改其中的信息。`<p>` 元素没有像 `<input>` 元素那样的值,而是具有文本,因此请使用 `.textContent` 访问元素并设置要显示的文本:
|
||||||
|
|
||||||
|
```
|
||||||
|
feedback.textContent = "You got it right!"
|
||||||
|
```
|
||||||
|
|
||||||
|
当然,玩家很有可能在第一次尝试时就猜错了,因此,如果 `myGuess` 和 `randomNumber` 不匹配,请给玩家一个线索,以帮助他们缩小猜测范围。如果第一个条件失败,则代码将跳过该 `if` 语句中的代码块,并检查下一个条件是否为 `true`。 这使你进入 `else if` 块:
|
||||||
|
|
||||||
|
```
|
||||||
|
else if(myGuess > randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你将其作为句子阅读,则可能是这样的:“如果玩家的猜测等于随机数,请让他们知道他们猜对了。否则,请检查玩家的猜测是否大于 `randomNumber`,如果是,则显示玩家的猜测并告诉他们太高了。”
|
||||||
|
|
||||||
|
最后一种可能性是玩家的猜测低于随机数。 要检查这一点,再添加一个 `else if` 块:
|
||||||
|
|
||||||
|
```
|
||||||
|
else if(myGuess < randomNumber) {
|
||||||
|
feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 用户事件和事件监听器
|
||||||
|
|
||||||
|
如果你看上面的代码,则会看到某些代码在页面加载时自动运行,但有些则不会。你想在玩游戏之前生成随机数,但是你不想在玩家将数字输入到数字输入字段并准备检查它之前检查其猜测。
|
||||||
|
|
||||||
|
生成随机数并将其打印到控制台的代码不在函数的范围内,因此它将在浏览器加载脚本时自动运行。 但是,要使函数内部的代码运行,你必须对其进行调用。
|
||||||
|
|
||||||
|
调用函数有几种方法。在此,你希望该函数在用户单击 “Check My Guess” 按钮时运行。单击按钮将创建一个用户事件,然后 JavaScript 可以 “监听” 这个事件,以便知道何时需要运行函数。
|
||||||
|
|
||||||
|
代码的最后一行将事件侦听器添加到按钮上,以在单击按钮时调用函数。当它“听到”该事件时,它将运行分配给事件侦听器的函数:
|
||||||
|
|
||||||
|
```
|
||||||
|
submitGuess.addEventListener('click', checkGuess)
|
||||||
|
```
|
||||||
|
|
||||||
|
就像访问 DOM 元素的其他实例一样,你可以使用按钮的 ID 告诉 JavaScript 与哪个元素进行交互。 然后,你可以使用内置的 `addEventListener` 函数来告诉 JavaScript 要监听的事件。
|
||||||
|
|
||||||
|
你已经看到了带有参数的函数,但花点时间看一下它是如何工作的。参数是函数执行其任务所需的信息。并非所有函数都需要参数,但是 `addEventListener` 函数需要两个参数。它采用的第一个参数是将为其监听的用户事件的名称。用户可以通过多种方式与 DOM 交互,例如键入、移动鼠标,键盘上的 `TAB` 键和粘贴文本。在这种情况下,你正在监听的用户事件是单击按钮,因此第一个参数将是 `click`。
|
||||||
|
|
||||||
|
`addEventListener`的第二个所需的信息是用户单击按钮时要运行的函数的名称。 这里我们需要 `checkGuess` 函数。
|
||||||
|
|
||||||
|
现在,当玩家按下 “Check My Guess” 按钮时,`checkGuess` 函数将获得他们在数字输入字段中输入的值,将其与随机数进行比较,并在浏览器中显示反馈,以使玩家知道他们猜的怎么样。 太棒了!你的游戏已准备就绪。
|
||||||
|
|
||||||
|
### 学习 JavaScript 以获取乐趣和收益
|
||||||
|
|
||||||
|
这一点点的平凡无奇的 JavaScript 只是这个庞大的生态系统所提供功能的一小部分。这是一种值得花时间投入学习的语言,我鼓励你继续挖掘并学习更多。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/learn-javascript
|
||||||
|
|
||||||
|
作者:[Mandy Kendall][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[amwps290](https://github.com/amwps290)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/mkendall
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_javascript.jpg?itok=60evKmGl "Javascript code close-up with neon graphic overlay"
|
||||||
|
[2]: https://opensource.com/tags/javascript
|
||||||
|
[3]: https://opensource.com/article/20/11/reactjs-tutorial
|
||||||
|
[4]: https://opensource.com/article/18/9/open-source-javascript-chart-libraries
|
||||||
|
[5]: https://opensource.com/article/20/12/brackets
|
||||||
|
[6]: http://december.com/html/4/element/html.html
|
||||||
|
[7]: http://december.com/html/4/element/head.html
|
||||||
|
[8]: http://december.com/html/4/element/meta.html
|
||||||
|
[9]: http://december.com/html/4/element/title.html
|
||||||
|
[10]: http://december.com/html/4/element/body.html
|
||||||
|
[11]: http://december.com/html/4/element/h1.html
|
||||||
|
[12]: http://december.com/html/4/element/p.html
|
||||||
|
[13]: http://december.com/html/4/element/label.html
|
||||||
|
[14]: http://december.com/html/4/element/input.html
|
||||||
|
[15]: http://december.com/html/4/element/form.html
|
||||||
|
[16]: http://december.com/html/4/element/script.html
|
||||||
|
[17]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math
|
||||||
|
[18]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
|
||||||
|
[19]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor
|
||||||
|
[20]: https://developer.mozilla.org/en-US/docs/Web/API/Console/log
|
||||||
|
[21]: https://opensource.com/sites/default/files/javascript-game-with-console.png "Javascript game with console"
|
@ -0,0 +1,70 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13077-1.html)
|
||||||
|
[#]: subject: (How Nextcloud is the ultimate open source productivity suite)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/nextcloud-productivity)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
Nextcloud 是如何成为终极开源生产力套件的
|
||||||
|
======
|
||||||
|
|
||||||
|
> Nextcloud 可以取代你用于协作、组织和任务管理的许多在线应用。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/02/121553uhl3pjljjkhj0h8p.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第十一天。
|
||||||
|
|
||||||
|
基于 Web 的服务几乎可以在任何地方访问你的数据,它们每小时可以支持数百万用户。不过对于我们中的一些人来说,由于各种原因,运行自己的服务比使用大公司的服务更可取。也许我们的工作是受监管的或有明确安全要求。也许我们有隐私方面的考虑,或者只是喜欢能够自己构建、运行和修复事物。不管是什么情况,[Nextcloud][2] 都可以提供你所需要的大部分服务,但是是在你自己的硬件上。
|
||||||
|
|
||||||
|
![NextCloud Dashboard displaying service options][3]
|
||||||
|
|
||||||
|
*Nextcloud 控制面板(Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
大多数时候,当我们想到 Nextcloud 时,我们会想到文件共享和同步,类似于 Dropbox、OneDrive 和 Google Drive 等商业产品。然而,如今,它是一个完整的生产力套件,拥有电子邮件客户端、日历、任务和笔记本。
|
||||||
|
|
||||||
|
有几种方法可以安装和运行 Nextcloud。你可以把它安装到裸机服务器上、在 Docker 容器中运行,或者作为虚拟机运行。如果可以考虑,还有一些托管服务将为你运行 Nextcloud。最后,有适用于所有主流操作系统的应用,包括移动应用,以便随时访问。
|
||||||
|
|
||||||
|
![Nextcloud virtual machine][5]
|
||||||
|
|
||||||
|
*Nextcloud 虚拟机(Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
默认情况下,Nextcloud 会安装文件共享和其他一些相关应用(或附加组件)。你可以在管理界面中找到“应用”页面,这里允许你安装单个附加组件和一些预定义的相关应用捆绑。对我而言,我选择了 “Groupware Bundle”,其中包括“邮件”、“日历”、“联系人”和 “Deck”。“Deck” 是一个轻量级的看板,用于处理任务。我也安装了“记事本”和“任务”应用。
|
||||||
|
|
||||||
|
Nextcloud “邮件” 是一个非常直白的 IMAP 邮件客户端。虽然 Nextcloud 没有将 IMAP 或 SMTP 服务器作为软件包的一部分,但你可以很容易地在操作系统中添加一个或使用远程服务。“日历”应用是相当标准的,也允许你订阅远程日历。有一个缺点是,远程日历(例如,来自大型云提供商)是只读的,所以你可以查看但不能修改它们。
|
||||||
|
|
||||||
|
![NextCoud App Interface][6]
|
||||||
|
|
||||||
|
*Nextcloud 应用界面 (Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
“记事本” 是一个简单的文本记事本,允许你创建和更新简短的笔记、日记和相关的东西。“任务” 是一款待办事项应用,支持多个列表、任务优先级、完成百分比以及其他一些用户期待的标准功能。如果你安装了 “Deck”,它的任务卡也会被列出来。每个看板都会显示自己的列表,所以你可以使用 “Deck” 或 “任务” 来跟踪完成的内容。
|
||||||
|
|
||||||
|
“Deck” 本身就是一个看板应用,将任务以卡片的形式呈现在流程中。如果你喜欢看板流程,它是一个追踪进度的优秀应用。
|
||||||
|
|
||||||
|
![Taking notes][7]
|
||||||
|
|
||||||
|
*做笔记 (Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
Nextcloud 中所有的应用都原生支持通过标准协议进行共享。与一些类似的解决方案不同,它的分享并不是为了完成功能列表中的一项而加上去的。分享是 Nextcloud 存在的主要原因之一,所以使用起来非常简单。你还可以将链接分享到社交媒体、通过电子邮件分享等。你可以用一个 Nextcloud 取代多个在线服务,它在任何地方都可以访问,以协作为先。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/nextcloud-productivity
|
||||||
|
|
||||||
|
作者:[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/team_dev_email_chat_video_work_wfm_desk_520.png?itok=6YtME4Hj (Working on a team, busy worklife)
|
||||||
|
[2]: https://nextcloud.com/
|
||||||
|
[3]: https://opensource.com/sites/default/files/day11-image1_0.png
|
||||||
|
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[5]: https://opensource.com/sites/default/files/pictures/nextcloud-vm.png (Nextcloud virtual machine)
|
||||||
|
[6]: https://opensource.com/sites/default/files/pictures/nextcloud-app-interface.png (NextCoud App Interface)
|
||||||
|
[7]: https://opensource.com/sites/default/files/day11-image3.png (Taking notes in Nextcloud)
|
@ -0,0 +1,60 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13073-1.html)
|
||||||
|
[#]: subject: (3 tips for automating your email filters)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/email-filter)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
3 个自动化电子邮件过滤器的技巧
|
||||||
|
======
|
||||||
|
|
||||||
|
> 通过这些简单的建议,减少你的电子邮件并让你的生活更轻松。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/01/103638ozdejmy6eycm6omx.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第十二天。
|
||||||
|
|
||||||
|
如果有一件事是我喜欢的,那就是自动化。只要有机会,我就会把小任务进行自动化。早起打开鸡舍的门?我买了一扇门,可以在日出和日落时开门和关门。每天从早到晚实时监控鸡群?用 Node-RED 和 [OBS-Websockets][2] 稍微花点时间,就能搞定。
|
||||||
|
|
||||||
|
我们还有电子邮件。几天前,我写过关于处理邮件的文章,也写过关于标签和文件夹的文章。只要做一点前期的工作,你就可以在邮件进来的时候,你就可以自动摆脱掉大量管理邮件的开销。
|
||||||
|
|
||||||
|
![Author has 480 filters][3]
|
||||||
|
|
||||||
|
*是的,我有很多过滤器。(Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
有两种主要方式来过滤你的电子邮件:在服务端或者客户端上。我更喜欢在服务端上做,因为我不断地在尝试新的和不同的电子邮件客户端。(不,真的,我光这个星期就已经使用了五个不同的客户端。我可能有问题。)
|
||||||
|
|
||||||
|
无论哪种方式,我都喜欢用电子邮件过滤规则做几件事,以使我的电子邮件更容易浏览,并保持我的收件箱不混乱。
|
||||||
|
|
||||||
|
1. 将不紧急的邮件移到“稍后阅读”文件夹中。对我而言,这包括来自社交网络、新闻简报和邮件列表的通知。
|
||||||
|
2. 按列表或主题给消息贴上标签。我属于几个组织,虽然它们经常会被放在“稍后阅读”文件夹中,但我会添加第二个或第三个标签,以说明该来源或项目的内容,以帮助搜索时找到相关的东西。
|
||||||
|
3. 不要把规则搞得太复杂。这个想法让我困难了一段时间。我想把邮件发送到某个文件夹的所有可能情况都加到一个规则里。如果有什么问题或需要添加或删除的东西,有一个大规则只是让它更难修复。
|
||||||
|
|
||||||
|
![Unsubscribe from email][5]
|
||||||
|
|
||||||
|
*点击它,点击它就行!(Kevin Sonney, [CC BY-SA 4.0][4])*
|
||||||
|
|
||||||
|
说了这么多,还有一件事我一直在做,它有助于减少我花在电子邮件上的时间:退订邮件。两年前我感兴趣的那个邮件列表已经不感兴趣了,所以就不订阅了。产品更新通讯是我去年停止使用的商品?退订!这一直在积极解放我。我每年都会试着评估几次列表中的邮件信息是否(仍然)有用。
|
||||||
|
|
||||||
|
过滤器和规则可以是非常强大的工具,让你的电子邮件保持集中,减少花在它们身上的时间。而点击取消订阅按钮是一种解放。试试就知道了!
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/email-filter
|
||||||
|
|
||||||
|
作者:[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/innovation_lightbulb_gears_devops_ansible.png?itok=TSbmp3_M (gears and lightbulb to represent innovation)
|
||||||
|
[2]: https://opensource.com/article/20/6/obs-websockets-streaming
|
||||||
|
[3]: https://opensource.com/sites/default/files/day12-image1_0.png
|
||||||
|
[4]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[5]: https://opensource.com/sites/default/files/day12-image2_0.png
|
@ -0,0 +1,635 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (wxy)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13074-1.html)
|
||||||
|
[#]: subject: (Explore binaries using this full-featured Linux tool)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/linux-radare2)
|
||||||
|
[#]: author: (Gaurav Kamathe https://opensource.com/users/gkamathe)
|
||||||
|
|
||||||
|
全功能的二进制文件分析工具 Radare2 指南
|
||||||
|
======
|
||||||
|
|
||||||
|
> Radare2 是一个为二进制分析定制的开源工具。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/01/112611baw4gpqlch10ps1c.jpg)
|
||||||
|
|
||||||
|
在《[Linux 上分析二进制文件的 10 种方法][2]》中,我解释了如何使用 Linux 上丰富的原生工具集来分析二进制文件。但如果你想进一步探索你的二进制文件,你需要一个为二进制分析定制的工具。如果你是二进制分析的新手,并且大多使用的是脚本语言,这篇文章《[GNU binutils 里的九种武器][3]》可以帮助你开始学习编译过程和什么是二进制。
|
||||||
|
|
||||||
|
### 为什么我需要另一个工具?
|
||||||
|
|
||||||
|
如果现有的 Linux 原生工具也能做类似的事情,你自然会问为什么需要另一个工具。嗯,这和你用手机做闹钟、做笔记、做相机、听音乐、上网、偶尔打电话和接电话的原因是一样的。以前,使用单独的设备和工具处理这些功能 —— 比如拍照的实体相机,记笔记的小记事本,起床的床头闹钟等等。对用户来说,有一个设备来做多件(但相关的)事情是*方便的*。另外,杀手锏就是独立功能之间的*互操作性*。
|
||||||
|
|
||||||
|
同样,即使许多 Linux 工具都有特定的用途,但在一个工具中捆绑类似(和更好)的功能是非常有用的。这就是为什么我认为 [Radare2][4] 应该是你需要处理二进制文件时的首选工具。
|
||||||
|
|
||||||
|
根据其 [GitHub 简介][5],Radare2(也称为 r2)是一个“类 Unix 系统上的逆向工程框架和命令行工具集”。它名字中的 “2” 是因为这个版本从头开始重写的,使其更加模块化。
|
||||||
|
|
||||||
|
### 为什么选择 Radare2?
|
||||||
|
|
||||||
|
有大量(非原生的)Linux 工具可用于二进制分析,为什么要选择 Radare2 呢?我的理由很简单。
|
||||||
|
|
||||||
|
首先,它是一个开源项目,有一个活跃而健康的社区。如果你正在寻找新颖的功能或提供着 bug 修复的工具,这很重要。
|
||||||
|
|
||||||
|
其次,Radare2 可以在命令行上使用,而且它有一个功能丰富的图形用户界面(GUI)环境,叫做 Cutter,适合那些对 GUI 比较熟悉的人。作为一个长期使用 Linux 的用户,我对习惯于在 shell 上输入。虽然熟悉 Radare2 的命令稍微有一点学习曲线,但我会把它比作 [学习 Vim][6]。你可以先学习基本的东西,一旦你掌握了它们,你就可以继续学习更高级的东西。很快,它就变成了肌肉记忆。
|
||||||
|
|
||||||
|
第三,Radare2 通过插件可以很好的支持外部工具。例如,最近开源的 [Ghidra][7] 二进制分析和<ruby>逆向工具<rt>reversing tool</rt></ruby>很受欢迎,因为它的反编译器功能是逆向软件的关键要素。你可以直接从 Radare2 控制台安装 Ghidra 反编译器并使用,这很神奇,让你两全其美。
|
||||||
|
|
||||||
|
### 开始使用 Radare2
|
||||||
|
|
||||||
|
要安装 Radare2,只需克隆其存储库并运行 `user.sh` 脚本。如果你的系统上还没有一些预备软件包,你可能需要安装它们。一旦安装完成,运行 `r2 -v` 命令来查看 Radare2 是否被正确安装:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone https://github.com/radareorg/radare2.git
|
||||||
|
$ cd radare2
|
||||||
|
$ ./sys/user.sh
|
||||||
|
|
||||||
|
# version
|
||||||
|
|
||||||
|
$ r2 -v
|
||||||
|
radare2 4.6.0-git 25266 @ linux-x86-64 git.4.4.0-930-g48047b317
|
||||||
|
commit: 48047b3171e6ed0480a71a04c3693a0650d03543 build: 2020-11-17__09:31:03
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获取二进制测试样本
|
||||||
|
|
||||||
|
现在 `r2` 已经安装好了,你需要一个样本二进制程序来试用它。你可以使用任何系统二进制文件(`ls`、`bash` 等),但为了使本教程的内容简单,请编译以下 C 程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat adder.c
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int adder(int num) {
|
||||||
|
return num + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int res, num1 = 100;
|
||||||
|
res = adder(num1);
|
||||||
|
printf("Number now is : %d\n", res);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gcc adder.c -o adder
|
||||||
|
$ file adder
|
||||||
|
adder: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9d4366f7160e1ffb46b14466e8e0d70f10de2240, not stripped
|
||||||
|
$ ./adder
|
||||||
|
Number now is : 101
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 加载二进制文件
|
||||||
|
|
||||||
|
要分析二进制文件,你必须在 Radare2 中加载它。通过提供文件名作为 `r2` 命令的一个命令行参数来加载它。你会进入一个独立的 Radare2 控制台,这与你的 shell 不同。要退出控制台,你可以输入 `Quit` 或 `Exit` 或按 `Ctrl+D`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2 ./adder
|
||||||
|
-- Learn pancake as if you were radare!
|
||||||
|
[0x004004b0]> quit
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 分析二进制
|
||||||
|
|
||||||
|
在你探索二进制之前,你必须让 `r2` 为你分析它。你可以通过在 `r2` 控制台中运行 `aaa` 命令来实现:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2 ./adder
|
||||||
|
-- Sorry, radare2 has experienced an internal error.
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> aaa
|
||||||
|
[x] Analyze all flags starting with sym. and entry0 (aa)
|
||||||
|
[x] Analyze function calls (aac)
|
||||||
|
[x] Analyze len bytes of instructions for references (aar)
|
||||||
|
[x] Check for vtables
|
||||||
|
[x] Type matching analysis for all functions (aaft)
|
||||||
|
[x] Propagate noreturn information
|
||||||
|
[x] Use -AA or aaaa to perform additional experimental analysis.
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
这意味着每次你选择一个二进制文件进行分析时,你必须在加载二进制文件后输入一个额外的命令 `aaa`。你可以绕过这一点,在命令后面跟上 `-A` 来调用 `r2`;这将告诉 `r2` 为你自动分析二进制:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2 -A ./adder
|
||||||
|
[x] Analyze all flags starting with sym. and entry0 (aa)
|
||||||
|
[x] Analyze function calls (aac)
|
||||||
|
[x] Analyze len bytes of instructions for references (aar)
|
||||||
|
[x] Check for vtables
|
||||||
|
[x] Type matching analysis for all functions (aaft)
|
||||||
|
[x] Propagate noreturn information
|
||||||
|
[x] Use -AA or aaaa to perform additional experimental analysis.
|
||||||
|
-- Already up-to-date.
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获取一些关于二进制的基本信息
|
||||||
|
|
||||||
|
在开始分析一个二进制文件之前,你需要一些背景信息。在许多情况下,这可以是二进制文件的格式(ELF、PE 等)、二进制的架构(x86、AMD、ARM 等),以及二进制是 32 位还是 64 位。方便的 `r2` 的 `iI` 命令可以提供所需的信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> iI
|
||||||
|
arch x86
|
||||||
|
baddr 0x400000
|
||||||
|
binsz 14724
|
||||||
|
bintype elf
|
||||||
|
bits 64
|
||||||
|
canary false
|
||||||
|
class ELF64
|
||||||
|
compiler GCC: (GNU) 8.3.1 20190507 (Red Hat 8.3.1-4)
|
||||||
|
crypto false
|
||||||
|
endian little
|
||||||
|
havecode true
|
||||||
|
intrp /lib64/ld-linux-x86-64.so.2
|
||||||
|
laddr 0x0
|
||||||
|
lang c
|
||||||
|
linenum true
|
||||||
|
lsyms true
|
||||||
|
machine AMD x86-64 architecture
|
||||||
|
maxopsz 16
|
||||||
|
minopsz 1
|
||||||
|
nx true
|
||||||
|
os linux
|
||||||
|
pcalign 0
|
||||||
|
pic false
|
||||||
|
relocs true
|
||||||
|
relro partial
|
||||||
|
rpath NONE
|
||||||
|
sanitiz false
|
||||||
|
static false
|
||||||
|
stripped false
|
||||||
|
subsys linux
|
||||||
|
va true
|
||||||
|
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 导入和导出
|
||||||
|
|
||||||
|
通常情况下,当你知道你要处理的是什么样的文件后,你就想知道二进制程序使用了什么样的标准库函数,或者了解程序的潜在功能。在本教程中的示例 C 程序中,唯一的库函数是 `printf`,用来打印信息。你可以通过运行 `ii` 命令看到这一点,它显示了该二进制所有导入的库:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> ii
|
||||||
|
[Imports]
|
||||||
|
nth vaddr bind type lib name
|
||||||
|
―――――――――――――――――――――――――――――――――――――
|
||||||
|
1 0x00000000 WEAK NOTYPE _ITM_deregisterTMCloneTable
|
||||||
|
2 0x004004a0 GLOBAL FUNC printf
|
||||||
|
3 0x00000000 GLOBAL FUNC __libc_start_main
|
||||||
|
4 0x00000000 WEAK NOTYPE __gmon_start__
|
||||||
|
5 0x00000000 WEAK NOTYPE _ITM_registerTMCloneTable
|
||||||
|
```
|
||||||
|
|
||||||
|
该二进制也可以有自己的符号、函数或数据。这些函数通常显示在 `Exports` 下。这个测试的二进制导出了两个函数:`main` 和 `adder`。其余的函数是在编译阶段,当二进制文件被构建时添加的。加载器需要这些函数来加载二进制文件(现在不用太关心它们):
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> iE
|
||||||
|
[Exports]
|
||||||
|
|
||||||
|
nth paddr vaddr bind type size lib name
|
||||||
|
――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
||||||
|
82 0x00000650 0x00400650 GLOBAL FUNC 5 __libc_csu_fini
|
||||||
|
85 ---------- 0x00601024 GLOBAL NOTYPE 0 _edata
|
||||||
|
86 0x00000658 0x00400658 GLOBAL FUNC 0 _fini
|
||||||
|
89 0x00001020 0x00601020 GLOBAL NOTYPE 0 __data_start
|
||||||
|
90 0x00000596 0x00400596 GLOBAL FUNC 15 adder
|
||||||
|
92 0x00000670 0x00400670 GLOBAL OBJ 0 __dso_handle
|
||||||
|
93 0x00000668 0x00400668 GLOBAL OBJ 4 _IO_stdin_used
|
||||||
|
94 0x000005e0 0x004005e0 GLOBAL FUNC 101 __libc_csu_init
|
||||||
|
95 ---------- 0x00601028 GLOBAL NOTYPE 0 _end
|
||||||
|
96 0x000004e0 0x004004e0 GLOBAL FUNC 5 _dl_relocate_static_pie
|
||||||
|
97 0x000004b0 0x004004b0 GLOBAL FUNC 47 _start
|
||||||
|
98 ---------- 0x00601024 GLOBAL NOTYPE 0 __bss_start
|
||||||
|
99 0x000005a5 0x004005a5 GLOBAL FUNC 55 main
|
||||||
|
100 ---------- 0x00601028 GLOBAL OBJ 0 __TMC_END__
|
||||||
|
102 0x00000468 0x00400468 GLOBAL FUNC 0 _init
|
||||||
|
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 哈希信息
|
||||||
|
|
||||||
|
如何知道两个二进制文件是否相似?你不能只是打开一个二进制文件并查看里面的源代码。在大多数情况下,二进制文件的哈希值(md5sum、sha1、sha256)是用来唯一识别它的。你可以使用 `it` 命令找到二进制的哈希值:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> it
|
||||||
|
md5 7e6732f2b11dec4a0c7612852cede670
|
||||||
|
sha1 d5fa848c4b53021f6570dd9b18d115595a2290ae
|
||||||
|
sha256 13dd5a492219dac1443a816ef5f91db8d149e8edbf26f24539c220861769e1c2
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数
|
||||||
|
|
||||||
|
代码按函数分组;要列出二进制中存在的函数,请运行 `afl` 命令。下面的列表显示了 `main` 函数和 `adder` 函数。通常,以 `sym.imp` 开头的函数是从标准库(这里是 glibc)中导入的:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> afl
|
||||||
|
0x004004b0 1 46 entry0
|
||||||
|
0x004004f0 4 41 -> 34 sym.deregister_tm_clones
|
||||||
|
0x00400520 4 57 -> 51 sym.register_tm_clones
|
||||||
|
0x00400560 3 33 -> 32 sym.__do_global_dtors_aux
|
||||||
|
0x00400590 1 6 entry.init0
|
||||||
|
0x00400650 1 5 sym.__libc_csu_fini
|
||||||
|
0x00400658 1 13 sym._fini
|
||||||
|
0x00400596 1 15 sym.adder
|
||||||
|
0x004005e0 4 101 loc..annobin_elf_init.c
|
||||||
|
0x004004e0 1 5 loc..annobin_static_reloc.c
|
||||||
|
0x004005a5 1 55 main
|
||||||
|
0x004004a0 1 6 sym.imp.printf
|
||||||
|
0x00400468 3 27 sym._init
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 交叉引用
|
||||||
|
|
||||||
|
在 C 语言中,`main` 函数是一个程序开始执行的地方。理想情况下,其他函数都是从 `main` 函数调用的,在退出程序时,`main` 函数会向操作系统返回一个退出状态。这在源代码中是很明显的,然而,二进制程序呢?如何判断 `adder` 函数的调用位置呢?
|
||||||
|
|
||||||
|
你可以使用 `axt` 命令,后面加上函数名,看看 `adder` 函数是在哪里调用的;如下图所示,它是从 `main` 函数中调用的。这就是所谓的<ruby>交叉引用<rt>cross-referencing</rt></ruby>。但什么调用 `main` 函数本身呢?从下面的 `axt main` 可以看出,它是由 `entry0` 调用的(关于 `entry0` 的学习我就不说了,留待读者练习)。
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> axt sym.adder
|
||||||
|
main 0x4005b9 [CALL] call sym.adder
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> axt main
|
||||||
|
entry0 0x4004d1 [DATA] mov rdi, main
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 寻找定位
|
||||||
|
|
||||||
|
在处理文本文件时,你经常通过引用行号和行或列号在文件内移动;在二进制文件中,你需要使用地址。这些是以 `0x` 开头的十六进制数字,后面跟着一个地址。要找到你在二进制中的位置,运行 `s` 命令。要移动到不同的位置,使用 `s` 命令,后面跟上地址。
|
||||||
|
|
||||||
|
函数名就像标签一样,内部用地址表示。如果函数名在二进制中(未剥离的),可以使用函数名后面的 `s` 命令跳转到一个特定的函数地址。同样,如果你想跳转到二进制的开始,输入 `s 0`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> s
|
||||||
|
0x4004b0
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> s main
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> s
|
||||||
|
0x4005a5
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> s sym.adder
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> s
|
||||||
|
0x400596
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> s 0
|
||||||
|
[0x00000000]>
|
||||||
|
[0x00000000]> s
|
||||||
|
0x0
|
||||||
|
[0x00000000]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 十六进制视图
|
||||||
|
|
||||||
|
通常情况下,原始二进制没有意义。在十六进制模式下查看二进制及其等效的 ASCII 表示法会有帮助:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> s main
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> px
|
||||||
|
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
|
||||||
|
0x004005a5 5548 89e5 4883 ec10 c745 fc64 0000 008b UH..H....E.d....
|
||||||
|
0x004005b5 45fc 89c7 e8d8 ffff ff89 45f8 8b45 f889 E.........E..E..
|
||||||
|
0x004005c5 c6bf 7806 4000 b800 0000 00e8 cbfe ffff ..x.@...........
|
||||||
|
0x004005d5 b800 0000 00c9 c30f 1f40 00f3 0f1e fa41 .........@.....A
|
||||||
|
0x004005e5 5749 89d7 4156 4989 f641 5541 89fd 4154 WI..AVI..AUA..AT
|
||||||
|
0x004005f5 4c8d 2504 0820 0055 488d 2d04 0820 0053 L.%.. .UH.-.. .S
|
||||||
|
0x00400605 4c29 e548 83ec 08e8 57fe ffff 48c1 fd03 L).H....W...H...
|
||||||
|
0x00400615 741f 31db 0f1f 8000 0000 004c 89fa 4c89 t.1........L..L.
|
||||||
|
0x00400625 f644 89ef 41ff 14dc 4883 c301 4839 dd75 .D..A...H...H9.u
|
||||||
|
0x00400635 ea48 83c4 085b 5d41 5c41 5d41 5e41 5fc3 .H...[]A\A]A^A_.
|
||||||
|
0x00400645 9066 2e0f 1f84 0000 0000 00f3 0f1e fac3 .f..............
|
||||||
|
0x00400655 0000 00f3 0f1e fa48 83ec 0848 83c4 08c3 .......H...H....
|
||||||
|
0x00400665 0000 0001 0002 0000 0000 0000 0000 0000 ................
|
||||||
|
0x00400675 0000 004e 756d 6265 7220 6e6f 7720 6973 ...Number now is
|
||||||
|
0x00400685 2020 3a20 2564 0a00 0000 0001 1b03 3b44 : %d........;D
|
||||||
|
0x00400695 0000 0007 0000 0000 feff ff88 0000 0020 ...............
|
||||||
|
[0x004005a5]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 反汇编
|
||||||
|
|
||||||
|
如果你使用的是编译后的二进制文件,则无法查看源代码。编译器将源代码转译成 CPU 可以理解和执行的机器语言指令;其结果就是二进制或可执行文件。然而,你可以查看汇编指令(的助记词)来理解程序正在做什么。例如,如果你想查看 `main` 函数在做什么,你可以使用 `s main` 寻找 `main` 函数的地址,然后运行 `pdf` 命令来查看反汇编的指令。
|
||||||
|
|
||||||
|
要理解汇编指令,你需要参考体系结构手册(这里是 x86),它的应用二进制接口(ABI,或调用惯例),并对堆栈的工作原理有基本的了解:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> s main
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> s
|
||||||
|
0x4005a5
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> pdf
|
||||||
|
; DATA XREF from entry0 @ 0x4004d1
|
||||||
|
┌ 55: int main (int argc, char **argv, char **envp);
|
||||||
|
│ ; var int64_t var_8h @ rbp-0x8
|
||||||
|
│ ; var int64_t var_4h @ rbp-0x4
|
||||||
|
│ 0x004005a5 55 push rbp
|
||||||
|
│ 0x004005a6 4889e5 mov rbp, rsp
|
||||||
|
│ 0x004005a9 4883ec10 sub rsp, 0x10
|
||||||
|
│ 0x004005ad c745fc640000. mov dword [var_4h], 0x64 ; 'd' ; 100
|
||||||
|
│ 0x004005b4 8b45fc mov eax, dword [var_4h]
|
||||||
|
│ 0x004005b7 89c7 mov edi, eax
|
||||||
|
│ 0x004005b9 e8d8ffffff call sym.adder
|
||||||
|
│ 0x004005be 8945f8 mov dword [var_8h], eax
|
||||||
|
│ 0x004005c1 8b45f8 mov eax, dword [var_8h]
|
||||||
|
│ 0x004005c4 89c6 mov esi, eax
|
||||||
|
│ 0x004005c6 bf78064000 mov edi, str.Number_now_is__:__d ; 0x400678 ; "Number now is : %d\n" ; const char *format
|
||||||
|
│ 0x004005cb b800000000 mov eax, 0
|
||||||
|
│ 0x004005d0 e8cbfeffff call sym.imp.printf ; int printf(const char *format)
|
||||||
|
│ 0x004005d5 b800000000 mov eax, 0
|
||||||
|
│ 0x004005da c9 leave
|
||||||
|
└ 0x004005db c3 ret
|
||||||
|
[0x004005a5]>
|
||||||
|
```
|
||||||
|
|
||||||
|
这是 `adder` 函数的反汇编结果:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004005a5]> s sym.adder
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> s
|
||||||
|
0x400596
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> pdf
|
||||||
|
; CALL XREF from main @ 0x4005b9
|
||||||
|
┌ 15: sym.adder (int64_t arg1);
|
||||||
|
│ ; var int64_t var_4h @ rbp-0x4
|
||||||
|
│ ; arg int64_t arg1 @ rdi
|
||||||
|
│ 0x00400596 55 push rbp
|
||||||
|
│ 0x00400597 4889e5 mov rbp, rsp
|
||||||
|
│ 0x0040059a 897dfc mov dword [var_4h], edi ; arg1
|
||||||
|
│ 0x0040059d 8b45fc mov eax, dword [var_4h]
|
||||||
|
│ 0x004005a0 83c001 add eax, 1
|
||||||
|
│ 0x004005a3 5d pop rbp
|
||||||
|
└ 0x004005a4 c3 ret
|
||||||
|
[0x00400596]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字符串
|
||||||
|
|
||||||
|
查看二进制中存在哪些字符串可以作为二进制分析的起点。字符串是硬编码到二进制中的,通常会提供重要的提示,可以让你将重点转移到分析某些区域。在二进制中运行 `iz` 命令来列出所有的字符串。这个测试二进制中只有一个硬编码的字符串:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> iz
|
||||||
|
[Strings]
|
||||||
|
nth paddr vaddr len size section type string
|
||||||
|
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
||||||
|
0 0x00000678 0x00400678 20 21 .rodata ascii Number now is : %d\n
|
||||||
|
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 交叉引用字符串
|
||||||
|
|
||||||
|
和函数一样,你可以交叉引用字符串,看看它们是从哪里被打印出来的,并理解它们周围的代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> ps @ 0x400678
|
||||||
|
Number now is : %d
|
||||||
|
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> axt 0x400678
|
||||||
|
main 0x4005c6 [DATA] mov edi, str.Number_now_is__:__d
|
||||||
|
[0x004004b0]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 可视模式
|
||||||
|
|
||||||
|
当你的代码很复杂,有多个函数被调用时,很容易迷失方向。如果能以图形或可视化的方式查看哪些函数被调用,根据某些条件采取了哪些路径等,会很有帮助。在移动到感兴趣的函数后,可以通过 `VV` 命令来探索 `r2` 的可视化模式。例如,对于 `adder` 函数:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004004b0]> s sym.adder
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> VV
|
||||||
|
```
|
||||||
|
|
||||||
|
![Radare2 Visual mode][8]
|
||||||
|
|
||||||
|
*(Gaurav Kamathe, [CC BY-SA 4.0][9])*
|
||||||
|
|
||||||
|
### 调试器
|
||||||
|
|
||||||
|
到目前为止,你一直在做的是静态分析 —— 你只是在看二进制文件中的东西,而没有运行它,有时你需要执行二进制文件,并在运行时分析内存中的各种信息。`r2` 的内部调试器允许你运行二进制文件、设置断点、分析变量的值、或者转储寄存器的内容。
|
||||||
|
|
||||||
|
用 `-d` 标志启动调试器,并在加载二进制时添加 `-A` 标志进行分析。你可以通过使用 `db <function-name>` 命令在不同的地方设置断点,比如函数或内存地址。要查看现有的断点,使用 `dbi` 命令。一旦你放置了断点,使用 `dc` 命令开始运行二进制文件。你可以使用 `dbt` 命令查看堆栈,它可以显示函数调用。最后,你可以使用 `drr` 命令转储寄存器的内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2 -d -A ./adder
|
||||||
|
Process with PID 17453 started...
|
||||||
|
= attach 17453 17453
|
||||||
|
bin.baddr 0x00400000
|
||||||
|
Using 0x400000
|
||||||
|
asm.bits 64
|
||||||
|
[x] Analyze all flags starting with sym. and entry0 (aa)
|
||||||
|
[x] Analyze function calls (aac)
|
||||||
|
[x] Analyze len bytes of instructions for references (aar)
|
||||||
|
[x] Check for vtables
|
||||||
|
[x] Type matching analysis for all functions (aaft)
|
||||||
|
[x] Propagate noreturn information
|
||||||
|
[x] Use -AA or aaaa to perform additional experimental analysis.
|
||||||
|
-- git checkout hamster
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> db main
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> db sym.adder
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> dbi
|
||||||
|
0 0x004005a5 E:1 T:0
|
||||||
|
1 0x00400596 E:1 T:0
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> afl | grep main
|
||||||
|
0x004005a5 1 55 main
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> afl | grep sym.adder
|
||||||
|
0x00400596 1 15 sym.adder
|
||||||
|
[0x7f77b0a28030]>
|
||||||
|
[0x7f77b0a28030]> dc
|
||||||
|
hit breakpoint at: 0x4005a5
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> dbt
|
||||||
|
0 0x4005a5 sp: 0x0 0 [main] main sym.adder+15
|
||||||
|
1 0x7f77b0687873 sp: 0x7ffe35ff6858 0 [??] section..gnu.build.attributes-1345820597
|
||||||
|
2 0x7f77b0a36e0a sp: 0x7ffe35ff68e8 144 [??] map.usr_lib64_ld_2.28.so.r_x+65034
|
||||||
|
[0x004005a5]> dc
|
||||||
|
hit breakpoint at: 0x400596
|
||||||
|
[0x00400596]> dbt
|
||||||
|
0 0x400596 sp: 0x0 0 [sym.adder] rip entry.init0+6
|
||||||
|
1 0x4005be sp: 0x7ffe35ff6838 0 [main] main+25
|
||||||
|
2 0x7f77b0687873 sp: 0x7ffe35ff6858 32 [??] section..gnu.build.attributes-1345820597
|
||||||
|
3 0x7f77b0a36e0a sp: 0x7ffe35ff68e8 144 [??] map.usr_lib64_ld_2.28.so.r_x+65034
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> dr
|
||||||
|
rax = 0x00000064
|
||||||
|
rbx = 0x00000000
|
||||||
|
rcx = 0x7f77b0a21738
|
||||||
|
rdx = 0x7ffe35ff6948
|
||||||
|
r8 = 0x7f77b0a22da0
|
||||||
|
r9 = 0x7f77b0a22da0
|
||||||
|
r10 = 0x0000000f
|
||||||
|
r11 = 0x00000002
|
||||||
|
r12 = 0x004004b0
|
||||||
|
r13 = 0x7ffe35ff6930
|
||||||
|
r14 = 0x00000000
|
||||||
|
r15 = 0x00000000
|
||||||
|
rsi = 0x7ffe35ff6938
|
||||||
|
rdi = 0x00000064
|
||||||
|
rsp = 0x7ffe35ff6838
|
||||||
|
rbp = 0x7ffe35ff6850
|
||||||
|
rip = 0x00400596
|
||||||
|
rflags = 0x00000202
|
||||||
|
orax = 0xffffffffffffffff
|
||||||
|
[0x00400596]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 反编译器
|
||||||
|
|
||||||
|
能够理解汇编是二进制分析的前提。汇编语言总是与二进制建立和预期运行的架构相关。一行源代码和汇编代码之间从来没有 1:1 的映射。通常,一行 C 源代码会产生多行汇编代码。所以,逐行读取汇编代码并不是最佳的选择。
|
||||||
|
|
||||||
|
这就是反编译器的作用。它们试图根据汇编指令重建可能的源代码。这与用于创建二进制的源代码绝不完全相同,它是基于汇编的源代码的近似表示。另外,要考虑到编译器进行的优化,它会生成不同的汇编代码以加快速度,减小二进制的大小等,会使反编译器的工作更加困难。另外,恶意软件作者经常故意混淆代码,让恶意软件的分析人员望而却步。
|
||||||
|
|
||||||
|
Radare2 通过插件提供反编译器。你可以安装任何 Radare2 支持的反编译器。使用 `r2pm -l` 命令可以查看当前插件。使用 `r2pm install` 命令来安装一个示例的反编译器 `r2dec`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2pm -l
|
||||||
|
$
|
||||||
|
$ r2pm install r2dec
|
||||||
|
Cloning into 'r2dec'...
|
||||||
|
remote: Enumerating objects: 100, done.
|
||||||
|
remote: Counting objects: 100% (100/100), done.
|
||||||
|
remote: Compressing objects: 100% (97/97), done.
|
||||||
|
remote: Total 100 (delta 18), reused 27 (delta 1), pack-reused 0
|
||||||
|
Receiving objects: 100% (100/100), 1.01 MiB | 1.31 MiB/s, done.
|
||||||
|
Resolving deltas: 100% (18/18), done.
|
||||||
|
Install Done For r2dec
|
||||||
|
gmake: Entering directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
|
||||||
|
[CC] duktape/duktape.o
|
||||||
|
[CC] duktape/duk_console.o
|
||||||
|
[CC] core_pdd.o
|
||||||
|
[CC] core_pdd.so
|
||||||
|
gmake: Leaving directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
|
||||||
|
$
|
||||||
|
$ r2pm -l
|
||||||
|
r2dec
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
### 反编译器视图
|
||||||
|
|
||||||
|
要反编译一个二进制文件,在 `r2` 中加载二进制文件并自动分析它。在本例中,使用 `s sym.adder` 命令移动到感兴趣的 `adder` 函数,然后使用 `pdda` 命令并排查看汇编和反编译后的源代码。阅读这个反编译后的源代码往往比逐行阅读汇编更容易:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ r2 -A ./adder
|
||||||
|
[x] Analyze all flags starting with sym. and entry0 (aa)
|
||||||
|
[x] Analyze function calls (aac)
|
||||||
|
[x] Analyze len bytes of instructions for references (aar)
|
||||||
|
[x] Check for vtables
|
||||||
|
[x] Type matching analysis for all functions (aaft)
|
||||||
|
[x] Propagate noreturn information
|
||||||
|
[x] Use -AA or aaaa to perform additional experimental analysis.
|
||||||
|
-- What do you want to debug today?
|
||||||
|
[0x004004b0]>
|
||||||
|
[0x004004b0]> s sym.adder
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> s
|
||||||
|
0x400596
|
||||||
|
[0x00400596]>
|
||||||
|
[0x00400596]> pdda
|
||||||
|
; assembly | /* r2dec pseudo code output */
|
||||||
|
| /* ./adder @ 0x400596 */
|
||||||
|
| #include <stdint.h>
|
||||||
|
|
|
||||||
|
; (fcn) sym.adder () | int32_t adder (int64_t arg1) {
|
||||||
|
| int64_t var_4h;
|
||||||
|
| rdi = arg1;
|
||||||
|
0x00400596 push rbp |
|
||||||
|
0x00400597 mov rbp, rsp |
|
||||||
|
0x0040059a mov dword [rbp - 4], edi | *((rbp - 4)) = edi;
|
||||||
|
0x0040059d mov eax, dword [rbp - 4] | eax = *((rbp - 4));
|
||||||
|
0x004005a0 add eax, 1 | eax++;
|
||||||
|
0x004005a3 pop rbp |
|
||||||
|
0x004005a4 ret | return eax;
|
||||||
|
| }
|
||||||
|
[0x00400596]>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置设置
|
||||||
|
|
||||||
|
随着你对 Radare2 的使用越来越熟悉,你会想改变它的配置,以适应你的工作方式。你可以使用 `e` 命令查看 `r2` 的默认配置。要设置一个特定的配置,在 `e` 命令后面添加 `config = value`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[0x004005a5]> e | wc -l
|
||||||
|
593
|
||||||
|
[0x004005a5]> e | grep syntax
|
||||||
|
asm.syntax = intel
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> e asm.syntax = att
|
||||||
|
[0x004005a5]>
|
||||||
|
[0x004005a5]> e | grep syntax
|
||||||
|
asm.syntax = att
|
||||||
|
[0x004005a5]>
|
||||||
|
```
|
||||||
|
|
||||||
|
要使配置更改永久化,请将它们放在 `r2` 启动时读取的名为 `.radare2rc` 的启动文件中。这个文件通常在你的主目录下,如果没有,你可以创建一个。一些示例配置选项包括:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cat ~/.radare2rc
|
||||||
|
e asm.syntax = att
|
||||||
|
e scr.utf8 = true
|
||||||
|
eco solarized
|
||||||
|
e cmd.stack = true
|
||||||
|
e stack.size = 256
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
### 探索更多
|
||||||
|
|
||||||
|
你已经看到了足够多的 Radare2 功能,对这个工具有了一定的了解。因为 Radare2 遵循 Unix 哲学,即使你可以从它的主控台做各种事情,它也会在下面使用一套独立的二进制来完成它的任务。
|
||||||
|
|
||||||
|
探索下面列出的独立二进制文件,看看它们是如何工作的。例如,用 `iI` 命令在控制台看到的二进制信息也可以用 `rabin2 <binary>` 命令找到:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd bin/
|
||||||
|
$
|
||||||
|
$ ls
|
||||||
|
prefix r2agent r2pm rabin2 radiff2 ragg2 rarun2 rasm2
|
||||||
|
r2 r2-indent r2r radare2 rafind2 rahash2 rasign2 rax2
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
你觉得 Radare2 怎么样?请在评论中分享你的反馈。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/linux-radare2
|
||||||
|
|
||||||
|
作者:[Gaurav Kamathe][a]
|
||||||
|
选题:[lujun9972][b]
|
||||||
|
译者:[wxy](https://github.com/wxy)
|
||||||
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
||||||
|
[a]: https://opensource.com/users/gkamathe
|
||||||
|
[b]: https://github.com/lujun9972
|
||||||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/binary_code_computer_screen.png?itok=7IzHK1nn (Binary code on a computer screen)
|
||||||
|
[2]: https://linux.cn/article-12187-1.html
|
||||||
|
[3]: https://linux.cn/article-11441-1.html
|
||||||
|
[4]: https://rada.re/n/
|
||||||
|
[5]: https://github.com/radareorg/radare2
|
||||||
|
[6]: https://opensource.com/article/19/3/getting-started-vim
|
||||||
|
[7]: https://ghidra-sre.org/
|
||||||
|
[8]: https://opensource.com/sites/default/files/uploads/radare2_visual-mode_0.png (Radare2 Visual mode)
|
||||||
|
[9]: https://creativecommons.org/licenses/by-sa/4.0/
|
@ -0,0 +1,63 @@
|
|||||||
|
[#]: collector: (lujun9972)
|
||||||
|
[#]: translator: (geekpi)
|
||||||
|
[#]: reviewer: (wxy)
|
||||||
|
[#]: publisher: (wxy)
|
||||||
|
[#]: url: (https://linux.cn/article-13080-1.html)
|
||||||
|
[#]: subject: (Use Joplin to find your notes faster)
|
||||||
|
[#]: via: (https://opensource.com/article/21/1/notes-joplin)
|
||||||
|
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
|
||||||
|
|
||||||
|
使用 Joplin 更快地找到你的笔记
|
||||||
|
======
|
||||||
|
|
||||||
|
> 在多个手写和数字平台上整理笔记是一个严峻的挑战。这里有一个小技巧,可以更好地组织你的笔记,并快速找到你需要的东西。
|
||||||
|
|
||||||
|
![](https://img.linux.net.cn/data/attachment/album/202102/03/120141dkiqil1vlqiz6wql.jpg)
|
||||||
|
|
||||||
|
在前几年,这个年度系列涵盖了单个的应用。今年,我们除了关注 2021 年的策略外,还将关注一体化解决方案。欢迎来到 2021 年 21 天生产力的第十五天。
|
||||||
|
|
||||||
|
保持生产力也意味着(在某种程度上)要有足够的组织能力,以便找到笔记并在需要时参考它们。这不仅是对我自己的挑战,也是与我交谈的很多人的挑战。
|
||||||
|
|
||||||
|
多年来,我在应用中单独或使用数字笔记、纸质笔记、便签、数字便签、Word 文档、纯文本文件以及一堆我忘记的其他格式的组合。这不仅让寻找笔记变得困难,而且知道把它们放在哪里是一个更大的挑战。
|
||||||
|
|
||||||
|
![Stacks of paper notes on a desk][2]
|
||||||
|
|
||||||
|
*一堆笔记 (Jessica Cherry, [CC BY-SA 4.0][3])*
|
||||||
|
|
||||||
|
还有就是做笔记最重要的一点:如果你以后找不到它,笔记就没有任何价值。知道含有你所需信息的笔记存在于你保存笔记的*某处*,根本没有任何帮助。
|
||||||
|
|
||||||
|
我是如何为自己解决这个问题的呢?正如他们所说,这是一个过程,我希望这也是一个对其他人有效的过程。
|
||||||
|
|
||||||
|
我首先看了看自己所做的笔记种类。不同的主题需要用不同的方式保存吗?由于我为我的播客手写笔记,而几乎所有其他的东西都使用纯文本笔记,我需要两种不同的方式来维护它们。对于手写的笔记,我把它们都放在一个文件夹里,方便我参考。
|
||||||
|
|
||||||
|
![Man holding a binder full of notes][4]
|
||||||
|
|
||||||
|
*三年多的笔记 (Kevin Sonney, [CC BY-SA 4.0][3])*
|
||||||
|
|
||||||
|
为了保存我的数字笔记,我需要将它们全部集中到一个地方。这个工具需要能够从多种设备上访问,具有有用的搜索功能,并且能够导出或共享我的笔记。在尝试了很多很多不同的选项之后,我选择了 [Joplin][5]。Joplin 可以让我用 Markdown 写笔记,有一个相当不错的搜索功能,有适用于所有操作系统(包括手机)的应用,并支持几种不同的设备同步方式。另外,它还有文件夹*和*标签,因此我可以按照对我有意义的方式将笔记分组。
|
||||||
|
|
||||||
|
![Organized Joplin notes management page][6]
|
||||||
|
|
||||||
|
*我的 Joplin*
|
||||||
|
|
||||||
|
我花了一些时间才把所有的东西都放在我想要的地方,但最后,这真的是值得的。现在,我可以找到我所做的笔记,而不是让它们散落在我的办公室、不同的机器和各种服务中。
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
via: https://opensource.com/article/21/1/notes-joplin
|
||||||
|
|
||||||
|
作者:[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/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
|
||||||
|
[2]: https://opensource.com/sites/default/files/day15-image1.jpg
|
||||||
|
[3]: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
[4]: https://opensource.com/sites/default/files/day15-image2.png
|
||||||
|
[5]: https://joplinapp.org/
|
||||||
|
[6]: https://opensource.com/sites/default/files/day15-image3.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