mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-21 02:10:11 +08:00
commit
c648ceb420
294
published/20161106 Myths about -dev-urandom.md
Normal file
294
published/20161106 Myths about -dev-urandom.md
Normal file
@ -0,0 +1,294 @@
|
||||
关于 /dev/urandom 的流言终结
|
||||
======
|
||||
|
||||
有很多关于 `/dev/urandom` 和 `/dev/random` 的流言在坊间不断流传。然而流言终究是流言。
|
||||
|
||||
> 本篇文章里针对的都是近来的 Linux 操作系统,其它类 Unix 操作系统不在讨论范围内。
|
||||
|
||||
**`/dev/urandom` 不安全。加密用途必须使用 `/dev/random`**
|
||||
|
||||
*事实*:`/dev/urandom` 才是类 Unix 操作系统下推荐的加密种子。
|
||||
|
||||
**`/dev/urandom` 是<ruby>伪随机数生成器<rt>pseudo random number generator</rt></ruby>(PRND),而 `/dev/random` 是“真”随机数生成器。**
|
||||
|
||||
*事实*:它们两者本质上用的是同一种 CSPRNG (一种密码学伪随机数生成器)。它们之间细微的差别和“真”“不真”随机完全无关。(参见:“Linux 随机数生成器的构架”一节)
|
||||
|
||||
**`/dev/random` 在任何情况下都是密码学应用更好地选择。即便 `/dev/urandom` 也同样安全,我们还是不应该用它。**
|
||||
|
||||
*事实*:`/dev/random` 有个很恶心人的问题:它是阻塞的。(参见:“阻塞有什么问题?”一节)(LCTT 译注:意味着请求都得逐个执行,等待前一个请求完成)
|
||||
|
||||
**但阻塞不是好事吗!`/dev/random` 只会给出电脑收集的信息熵足以支持的随机量。`/dev/urandom` 在用完了所有熵的情况下还会不断吐出不安全的随机数给你。**
|
||||
|
||||
*事实*:这是误解。就算我们不去考虑应用层面后续对随机种子的用法,“用完信息熵池”这个概念本身就不存在。仅仅 256 位的熵就足以生成计算上安全的随机数很长、很长的一段时间了。(参见:“那熵池快空了的情况呢?”一节)
|
||||
|
||||
问题的关键还在后头:`/dev/random` 怎么知道有系统会*多少*可用的信息熵?接着看!
|
||||
|
||||
**但密码学家老是讨论重新选种子(re-seeding)。这难道不和上一条冲突吗?**
|
||||
|
||||
*事实*:你说的也没错!某种程度上吧。确实,随机数生成器一直在使用系统信息熵的状态重新选种。但这么做(一部分)是因为别的原因。(参见:“重新选种”一节)
|
||||
|
||||
这样说吧,我没有说引入新的信息熵是坏的。更多的熵肯定更好。我只是说在熵池低的时候阻塞是没必要的。
|
||||
|
||||
**好,就算你说的都对,但是 `/dev/(u)random` 的 man 页面和你说的也不一样啊!到底有没有专家同意你说的这堆啊?**
|
||||
|
||||
*事实*:其实 man 页面和我说的不冲突。它看似好像在说 `/dev/urandom` 对密码学用途来说不安全,但如果你真的理解这堆密码学术语你就知道它说的并不是这个意思。(参见:“random 和 urandom 的 man 页面”一节)
|
||||
|
||||
man 页面确实说在一些情况下推荐使用 `/dev/random` (我觉得也没问题,但绝对不是说必要的),但它也推荐在大多数“一般”的密码学应用下使用 `/dev/urandom` 。
|
||||
|
||||
虽然诉诸权威一般来说不是好事,但在密码学这么严肃的事情上,和专家统一意见是很有必要的。
|
||||
|
||||
所以说呢,还确实有一些*专家*和我的一件事一致的:`/dev/urandom` 就应该是类 UNIX 操作系统下密码学应用的首选。显然的,是他们的观点说服了我而不是反过来的。(参见:“正道”一节)
|
||||
|
||||
------
|
||||
|
||||
难以相信吗?觉得我肯定错了?读下去看我能不能说服你。
|
||||
|
||||
我尝试不讲太高深的东西,但是有两点内容必须先提一下才能让我们接着论证观点。
|
||||
|
||||
首当其冲的,*什么是随机性*,或者更准确地:我们在探讨什么样的随机性?(参见:“真随机”一节)
|
||||
|
||||
另外一点很重要的是,我*没有尝试以说教的态度*对你们写这段话。我写这篇文章是为了日后可以在讨论起的时候指给别人看。比 140 字长(LCTT 译注:推特长度)。这样我就不用一遍遍重复我的观点了。能把论点磨炼成一篇文章本身就很有助于将来的讨论。(参见:“你是在说我笨?!”一节)
|
||||
|
||||
并且我非常乐意听到不一样的观点。但我只是认为单单地说 `/dev/urandom` 坏是不够的。你得能指出到底有什么问题,并且剖析它们。
|
||||
|
||||
### 你是在说我笨?!
|
||||
|
||||
绝对没有!
|
||||
|
||||
事实上我自己也相信了 “`/dev/urandom` 是不安全的” 好些年。这几乎不是我们的错,因为那么德高望重的人在 Usenet、论坛、推特上跟我们重复这个观点。甚至*连 man 手册*都似是而非地说着。我们当年怎么可能鄙视诸如“信息熵太低了”这种看上去就很让人信服的观点呢?(参见:“random 和 urandom 的 man 页面”一节)
|
||||
|
||||
整个流言之所以如此广为流传不是因为人们太蠢,而是因为但凡有点关于信息熵和密码学概念的人都会觉得这个说法很有道理。直觉似乎都在告诉我们这流言讲的很有道理。很不幸直觉在密码学里通常不管用,这次也一样。
|
||||
|
||||
### 真随机
|
||||
|
||||
随机数是“真正随机”是什么意思?
|
||||
|
||||
我不想搞的太复杂以至于变成哲学范畴的东西。这种讨论很容易走偏因为对于随机模型大家见仁见智,讨论很快变得毫无意义。
|
||||
|
||||
在我看来“真随机”的“试金石”是量子效应。一个光子穿过或不穿过一个半透镜。或者观察一个放射性粒子衰变。这类东西是现实世界最接近真随机的东西。当然,有些人也不相信这类过程是真随机的,或者这个世界根本不存在任何随机性。这个就百家争鸣了,我也不好多说什么了。
|
||||
|
||||
密码学家一般都会通过不去讨论什么是“真随机”来避免这种哲学辩论。他们更关心的是<ruby>不可预测性<rt>unpredictability</rt></ruby>。只要没有*任何*方法能猜出下一个随机数就可以了。所以当你以密码学应用为前提讨论一个随机数好不好的时候,在我看来这才是最重要的。
|
||||
|
||||
无论如何,我不怎么关心“哲学上安全”的随机数,这也包括别人嘴里的“真”随机数。
|
||||
|
||||
### 两种安全,一种有用
|
||||
|
||||
但就让我们退一步说,你有了一个“真”随机变量。你下一步做什么呢?
|
||||
|
||||
你把它们打印出来然后挂在墙上来展示量子宇宙的美与和谐?牛逼!我支持你。
|
||||
|
||||
但是等等,你说你要*用*它们?做密码学用途?额,那这就废了,因为这事情就有点复杂了。
|
||||
|
||||
事情是这样的,你的真随机、量子力学加护的随机数即将被用进不理想的现实世界算法里去。
|
||||
|
||||
因为我们使用的几乎所有的算法都并不是<ruby>信息论安全性<rt>information-theoretic security </rt></ruby>的。它们“只能”提供**计算意义上的安全**。我能想到为数不多的例外就只有 Shamir 密钥分享和<ruby>一次性密码本<rt>One-time pad</rt></ruby>(OTP)算法。并且就算前者是名副其实的(如果你实际打算用的话),后者则毫无可行性可言。
|
||||
|
||||
但所有那些大名鼎鼎的密码学算法,AES、RSA、Diffie-Hellman、椭圆曲线,还有所有那些加密软件包,OpenSSL、GnuTLS、Keyczar、你的操作系统的加密 API,都仅仅是计算意义上安全的。
|
||||
|
||||
那区别是什么呢?信息论安全的算法肯定是安全的,绝对是,其它那些的算法都可能在理论上被拥有无限计算力的穷举破解。我们依然愉快地使用它们是因为全世界的计算机加起来都不可能在宇宙年龄的时间里破解,至少现在是这样。而这就是我们文章里说的“不安全”。
|
||||
|
||||
除非哪个聪明的家伙破解了算法本身 —— 在只需要更少量计算力、在今天可实现的计算力的情况下。这也是每个密码学家梦寐以求的圣杯:破解 AES 本身、破解 RSA 本身等等。
|
||||
|
||||
所以现在我们来到了更底层的东西:随机数生成器,你坚持要“真随机”而不是“伪随机”。但是没过一会儿你的真随机数就被喂进了你极为鄙视的伪随机算法里了!
|
||||
|
||||
真相是,如果我们最先进的哈希算法被破解了,或者最先进的分组加密算法被破解了,你得到的这些“哲学上不安全”的随机数甚至无所谓了,因为反正你也没有安全的应用方法了。
|
||||
|
||||
所以把计算性上安全的随机数喂给你的仅仅是计算性上安全的算法就可以了,换而言之,用 `/dev/urandom`。
|
||||
|
||||
### Linux 随机数生成器的构架
|
||||
|
||||
#### 一种错误的看法
|
||||
|
||||
你对内核的随机数生成器的理解很可能是像这样的:
|
||||
|
||||
![image: mythical structure of the kernel's random number generator][1]
|
||||
|
||||
“真正的随机性”,尽管可能有点瑕疵,进入操作系统然后它的熵立刻被加入内部熵计数器。然后经过“矫偏”和“漂白”之后它进入内核的熵池,然后 `/dev/random` 和 `/dev/urandom` 从里面生成随机数。
|
||||
|
||||
“真”随机数生成器,`/dev/random`,直接从池里选出随机数,如果熵计数器表示能满足需要的数字大小,那就吐出数字并且减少熵计数。如果不够的话,它会阻塞程序直至有足够的熵进入系统。
|
||||
|
||||
这里很重要一环是 `/dev/random` 几乎只是仅经过必要的“漂白”后就直接把那些进入系统的随机性吐了出来,不经扭曲。
|
||||
|
||||
而对 `/dev/urandom` 来说,事情是一样的。除了当没有足够的熵的时候,它不会阻塞,而会从一直在运行的伪随机数生成器(当然,是密码学安全的,CSPRNG)里吐出“低质量”的随机数。这个 CSPRNG 只会用“真随机数”生成种子一次(或者好几次,这不重要),但你不能特别相信它。
|
||||
|
||||
在这种对随机数生成的理解下,很多人会觉得在 Linux 下尽量避免 `/dev/urandom` 看上去有那么点道理。
|
||||
|
||||
因为要么你有足够多的熵,你会相当于用了 `/dev/random`。要么没有,那你就会从几乎没有高熵输入的 CSPRNG 那里得到一个低质量的随机数。
|
||||
|
||||
看上去很邪恶是吧?很不幸的是这种看法是完全错误的。实际上,随机数生成器的构架更像是下面这样的。
|
||||
|
||||
#### 更好地简化
|
||||
|
||||
##### Linux 4.8 之前
|
||||
|
||||
![image: actual structure of the kernel's random number generator before Linux 4.8][2]
|
||||
|
||||
你看到最大的区别了吗?CSPRNG 并不是和随机数生成器一起跑的,它在 `/dev/urandom` 需要输出但熵不够的时候进行填充。CSPRNG 是整个随机数生成过程的内部组件之一。从来就没有什么 `/dev/random` 直接从池里输出纯纯的随机性。每个随机源的输入都在 CSPRNG 里充分混合和散列过了,这一切都发生在实际变成一个随机数,被 `/dev/urandom` 或者 `/dev/random` 吐出去之前。
|
||||
|
||||
另外一个重要的区别是这里没有熵计数器的任何事情,只有预估。一个源给你的熵的量并不是什么很明确能直接得到的数字。你得预估它。注意,如果你太乐观地预估了它,那 `/dev/random` 最重要的特性——只给出熵允许的随机量——就荡然无存了。很不幸的,预估熵的量是很困难的。
|
||||
|
||||
> 这是个很粗糙的简化。实际上不仅有一个,而是三个熵池。一个主池,另一个给 `/dev/random`,还有一个给 `/dev/urandom`,后两者依靠从主池里获取熵。这三个池都有各自的熵计数器,但二级池(后两个)的计数器基本都在 0 附近,而“新鲜”的熵总在需要的时候从主池流过来。同时还有好多混合和回流进系统在同时进行。整个过程对于这篇文档来说都过于复杂了,我们跳过。
|
||||
|
||||
Linux 内核只使用事件的到达时间来预估熵的量。根据模型,它通过多项式插值来预估实际的到达时间有多“出乎意料”。这种多项式插值的方法到底是不是好的预估熵量的方法本身就是个问题。同时硬件情况会不会以某种特定的方式影响到达时间也是个问题。而所有硬件的取样率也是个问题,因为这基本上就直接决定了随机数到达时间的颗粒度。
|
||||
|
||||
说到最后,至少现在看来,内核的熵预估还是不错的。这也意味着它比较保守。有些人会具体地讨论它有多好,这都超出我的脑容量了。就算这样,如果你坚持不想在没有足够多的熵的情况下吐出随机数,那你看到这里可能还会有一丝紧张。我睡的就很香了,因为我不关心熵预估什么的。
|
||||
|
||||
最后要明确一下:`/dev/random` 和 `/dev/urandom` 都是被同一个 CSPRNG 饲喂的。只有它们在用完各自熵池(根据某种预估标准)的时候,它们的行为会不同:`/dev/random` 阻塞,`/dev/urandom` 不阻塞。
|
||||
|
||||
##### Linux 4.8 以后
|
||||
|
||||
![image: actual structure of the kernel's random number generator from Linux 4.8 onward][3]
|
||||
|
||||
在 Linux 4.8 里,`/dev/random` 和 `/dev/urandom` 的等价性被放弃了。现在 `/dev/urandom` 的输出不来自于熵池,而是直接从 CSPRNG 来。
|
||||
|
||||
*我们很快会理解*为什么这不是一个安全问题。(参见:“CSPRNG 没问题”一节)
|
||||
|
||||
### 阻塞有什么问题?
|
||||
|
||||
你有没有需要等着 `/dev/random` 来吐随机数?比如在虚拟机里生成一个 PGP 密钥?或者访问一个在生成会话密钥的网站?
|
||||
|
||||
这些都是问题。阻塞本质上会降低可用性。换而言之你的系统不干你让它干的事情。不用我说,这是不好的。要是它不干活你干嘛搭建它呢?
|
||||
|
||||
> 我在工厂自动化里做过和安全相关的系统。猜猜看安全系统失效的主要原因是什么?操作问题。就这么简单。很多安全措施的流程让工人恼火了。比如时间太长,或者太不方便。你要知道人很会找捷径来“解决”问题。
|
||||
|
||||
但其实有个更深刻的问题:人们不喜欢被打断。它们会找一些绕过的方法,把一些诡异的东西接在一起仅仅因为这样能用。一般人根本不知道什么密码学什么乱七八糟的,至少正常的人是这样吧。
|
||||
|
||||
为什么不禁止调用 `random()`?为什么不随便在论坛上找个人告诉你用写奇异的 ioctl 来增加熵计数器呢?为什么不干脆就把 SSL 加密给关了算了呢?
|
||||
|
||||
到头来如果东西太难用的话,你的用户就会被迫开始做一些降低系统安全性的事情——你甚至不知道它们会做些什么。
|
||||
|
||||
我们很容易会忽视可用性之类的重要性。毕竟安全第一对吧?所以比起牺牲安全,不可用、难用、不方便都是次要的?
|
||||
|
||||
这种二元对立的想法是错的。阻塞不一定就安全了。正如我们看到的,`/dev/urandom` 直接从 CSPRNG 里给你一样好的随机数。用它不好吗!
|
||||
|
||||
### CSPRNG 没问题
|
||||
|
||||
现在情况听上去很惨淡。如果连高质量的 `/dev/random` 都是从一个 CSPRNG 里来的,我们怎么敢在高安全性的需求上使用它呢?
|
||||
|
||||
实际上,“看上去随机”是现存大多数密码学基础组件的基本要求。如果你观察一个密码学哈希的输出,它一定得和随机的字符串不可区分,密码学家才会认可这个算法。如果你生成一个分组加密,它的输出(在你不知道密钥的情况下)也必须和随机数据不可区分才行。
|
||||
|
||||
如果任何人能比暴力穷举要更有效地破解一个加密,比如它利用了某些 CSPRNG 伪随机的弱点,那这就又是老一套了:一切都废了,也别谈后面的了。分组加密、哈希,一切都是基于某个数学算法,比如 CSPRNG。所以别害怕,到头来都一样。
|
||||
|
||||
### 那熵池快空了的情况呢?
|
||||
|
||||
毫无影响。
|
||||
|
||||
加密算法的根基建立在攻击者不能预测输出上,只要最一开始有足够的随机性(熵)就行了。“足够”的下限可以是 256 位,不需要更多了。
|
||||
|
||||
介于我们一直在很随意的使用“熵”这个概念,我用“位”来量化随机性希望读者不要太在意细节。像我们之前讨论的那样,内核的随机数生成器甚至没法精确地知道进入系统的熵的量。只有一个预估。而且这个预估的准确性到底怎么样也没人知道。
|
||||
|
||||
### 重新选种
|
||||
|
||||
但如果熵这么不重要,为什么还要有新的熵一直被收进随机数生成器里呢?
|
||||
|
||||
> djb [提到][4] 太多的熵甚至可能会起到反效果。
|
||||
|
||||
首先,一般不会这样。如果你有很多随机性可以拿来用,用就对了!
|
||||
|
||||
但随机数生成器时不时要重新选种还有别的原因:
|
||||
|
||||
想象一下如果有个攻击者获取了你随机数生成器的所有内部状态。这是最坏的情况了,本质上你的一切都暴露给攻击者了。
|
||||
|
||||
你已经凉了,因为攻击者可以计算出所有未来会被输出的随机数了。
|
||||
|
||||
但是,如果不断有新的熵被混进系统,那内部状态会再一次变得随机起来。所以随机数生成器被设计成这样有些“自愈”能力。
|
||||
|
||||
但这是在给内部状态引入新的熵,这和阻塞输出没有任何关系。
|
||||
|
||||
### random 和 urandom 的 man 页面
|
||||
|
||||
这两个 man 页面在吓唬程序员方面很有建树:
|
||||
|
||||
> 从 `/dev/urandom` 读取数据不会因为需要更多熵而阻塞。这样的结果是,如果熵池里没有足够多的熵,取决于驱动使用的算法,返回的数值在理论上有被密码学攻击的可能性。发动这样攻击的步骤并没有出现在任何公开文献当中,但这样的攻击从理论上讲是可能存在的。如果你的应用担心这类情况,你应该使用 `/dev/random`。
|
||||
|
||||
>> 实际上已经有 `/dev/random` 和 `/dev/urandom` 的 Linux 内核 man 页面的更新版本。不幸的是,随便一个网络搜索出现我在结果顶部的仍然是旧的、有缺陷的版本。此外,许多 Linux 发行版仍在发布旧的 man 页面。所以不幸的是,这一节需要在这篇文章中保留更长的时间。我很期待删除这一节!
|
||||
|
||||
没有“公开的文献”描述,但是 NSA 的小卖部里肯定卖这种攻击手段是吧?如果你真的真的很担心(你应该很担心),那就用 `/dev/random` 然后所有问题都没了?
|
||||
|
||||
然而事实是,可能某个什么情报局有这种攻击,或者某个什么邪恶黑客组织找到了方法。但如果我们就直接假设这种攻击一定存在也是不合理的。
|
||||
|
||||
而且就算你想给自己一个安心,我要给你泼个冷水:AES、SHA-3 或者其它什么常见的加密算法也没有“公开文献记述”的攻击手段。难道你也不用这几个加密算法了?这显然是可笑的。
|
||||
|
||||
我们在回到 man 页面说:“使用 `/dev/random`”。我们已经知道了,虽然 `/dev/urandom` 不阻塞,但是它的随机数和 `/dev/random` 都是从同一个 CSPRNG 里来的。
|
||||
|
||||
如果你真的需要信息论安全性的随机数(你不需要的,相信我),那才有可能成为唯一一个你需要等足够熵进入 CSPRNG 的理由。而且你也不能用 `/dev/random`。
|
||||
|
||||
man 页面有毒,就这样。但至少它还稍稍挽回了一下自己:
|
||||
|
||||
> 如果你不确定该用 `/dev/random` 还是 `/dev/urandom` ,那你可能应该用后者。通常来说,除了需要长期使用的 GPG/SSL/SSH 密钥以外,你总该使用`/dev/urandom` 。
|
||||
|
||||
>> 该手册页的[当前更新版本](http://man7.org/linux/man-pages/man4/random.4.html)毫不含糊地说:
|
||||
|
||||
>> `/dev/random` 接口被认为是遗留接口,并且 `/dev/urandom` 在所有用例中都是首选和足够的,除了在启动早期需要随机性的应用程序;对于这些应用程序,必须替代使用 `getrandom(2)`,因为它将阻塞,直到熵池初始化完成。
|
||||
|
||||
行。我觉得没必要,但如果你真的要用 `/dev/random` 来生成 “长期使用的密钥”,用就是了也没人拦着!你可能需要等几秒钟或者敲几下键盘来增加熵,但这没什么问题。
|
||||
|
||||
但求求你们,不要就因为“你想更安全点”就让连个邮件服务器要挂起半天。
|
||||
|
||||
### 正道
|
||||
|
||||
本篇文章里的观点显然在互联网上是“小众”的。但如果问一个真正的密码学家,你很难找到一个认同阻塞 `/dev/random` 的人。
|
||||
|
||||
比如我们看看 [Daniel Bernstein][5](即著名的 djb)的看法:
|
||||
|
||||
> 我们密码学家对这种胡乱迷信行为表示不负责。你想想,写 `/dev/random` man 页面的人好像同时相信:
|
||||
>
|
||||
> * (1) 我们不知道如何用一个 256 位长的 `/dev/random` 的输出来生成一个无限长的随机密钥串流(这是我们需要 `/dev/urandom` 吐出来的),但与此同时
|
||||
> * (2) 我们却知道怎么用单个密钥来加密一条消息(这是 SSL,PGP 之类干的事情)
|
||||
>
|
||||
> 对密码学家来说这甚至都不好笑了
|
||||
|
||||
或者 [Thomas Pornin][6] 的看法,他也是我在 stackexchange 上见过最乐于助人的一位:
|
||||
|
||||
> 简单来说,是的。展开说,答案还是一样。`/dev/urandom` 生成的数据可以说和真随机完全无法区分,至少在现有科技水平下。使用比 `/dev/urandom` “更好的“随机性毫无意义,除非你在使用极为罕见的“信息论安全”的加密算法。这肯定不是你的情况,不然你早就说了。
|
||||
>
|
||||
> urandom 的 man 页面多多少少有些误导人,或者干脆可以说是错的——特别是当它说 `/dev/urandom` 会“用完熵”以及 “`/dev/random` 是更好的”那几句话;
|
||||
|
||||
或者 [Thomas Ptacek][7] 的看法,他不设计密码算法或者密码学系统,但他是一家名声在外的安全咨询公司的创始人,这家公司负责很多渗透和破解烂密码学算法的测试:
|
||||
|
||||
> 用 urandom。用 urandom。用 urandom。用 urandom。用 urandom。
|
||||
|
||||
### 没有完美
|
||||
|
||||
`/dev/urandom` 不是完美的,问题分两层:
|
||||
|
||||
在 Linux 上,不像 FreeBSD,`/dev/urandom` 永远不阻塞。记得安全性取决于某个最一开始决定的随机性?种子?
|
||||
|
||||
Linux 的 `/dev/urandom` 会很乐意给你吐点不怎么随机的随机数,甚至在内核有机会收集一丁点熵之前。什么时候有这种情况?当你系统刚刚启动的时候。
|
||||
|
||||
FreeBSD 的行为更正确点:`/dev/random` 和 `/dev/urandom` 是一样的,在系统启动的时候 `/dev/random` 会阻塞到有足够的熵为止,然后它们都再也不阻塞了。
|
||||
|
||||
> 与此同时 Linux 实行了一个新的<ruby>系统调用<rt>syscall</rt></ruby>,最早由 OpenBSD 引入叫 `getentrypy(2)`,在 Linux 下这个叫 `getrandom(2)`。这个系统调用有着上述正确的行为:阻塞到有足够的熵为止,然后再也不阻塞了。当然,这是个系统调用,而不是一个字节设备(LCTT 译注:不在 `/dev/` 下),所以它在 shell 或者别的脚本语言里没那么容易获取。这个系统调用 自 Linux 3.17 起存在。
|
||||
|
||||
在 Linux 上其实这个问题不太大,因为 Linux 发行版会在启动的过程中保存一点随机数(这发生在已经有一些熵之后,因为启动程序不会在按下电源的一瞬间就开始运行)到一个种子文件中,以便系统下次启动的时候读取。所以每次启动的时候系统都会从上一次会话里带一点随机性过来。
|
||||
|
||||
显然这比不上在关机脚本里写入一些随机种子,因为这样的显然就有更多熵可以操作了。但这样做显而易见的好处就是它不用关心系统是不是正确关机了,比如可能你系统崩溃了。
|
||||
|
||||
而且这种做法在你真正第一次启动系统的时候也没法帮你随机,不过好在 Linux 系统安装程序一般会保存一个种子文件,所以基本上问题不大。
|
||||
|
||||
虚拟机是另外一层问题。因为用户喜欢克隆它们,或者恢复到某个之前的状态。这种情况下那个种子文件就帮不到你了。
|
||||
|
||||
但解决方案依然和用 `/dev/random` 没关系,而是你应该正确的给每个克隆或者恢复的镜像重新生成种子文件。
|
||||
|
||||
### 太长不看
|
||||
|
||||
别问,问就是用 `/dev/urandom` !
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2uo.de/myths-about-urandom/
|
||||
|
||||
作者:[Thomas Hühn][a]
|
||||
译者:[Moelf](https://github.com/Moelf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.2uo.de/
|
||||
[1]:https://www.2uo.de/_media/wiki:structure-no.png
|
||||
[2]:https://www.2uo.de/_media/wiki:structure-yes.png
|
||||
[3]:https://www.2uo.de/_media/wiki:structure-new.png
|
||||
[4]:http://blog.cr.yp.to/20140205-entropy.html
|
||||
[5]:http://www.mail-archive.com/cryptography@randombit.net/msg04763.html
|
||||
[6]:http://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key/3939#3939
|
||||
[7]:http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
|
@ -0,0 +1,279 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10850-1.html)
|
||||
[#]: subject: (Build a game framework with Python using the module Pygame)
|
||||
[#]: via: (https://opensource.com/article/17/12/game-framework-python)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
使用 Python 和 Pygame 模块构建一个游戏框架
|
||||
======
|
||||
|
||||
> 这系列的第一篇通过创建一个简单的骰子游戏来探究 Python。现在是来从零制作你自己的游戏的时间。
|
||||
|
||||

|
||||
|
||||
在我的[这系列的第一篇文章][1] 中, 我已经讲解如何使用 Python 创建一个简单的、基于文本的骰子游戏。这次,我将展示如何使用 Python 模块 Pygame 来创建一个图形化游戏。它将需要几篇文章才能来得到一个确实做成一些东西的游戏,但是到这系列的结尾,你将更好地理解如何查找和学习新的 Python 模块和如何从其基础上构建一个应用程序。
|
||||
|
||||
在开始前,你必须安装 [Pygame][2]。
|
||||
|
||||
### 安装新的 Python 模块
|
||||
|
||||
有几种方法来安装 Python 模块,但是最通用的两个是:
|
||||
|
||||
* 从你的发行版的软件存储库
|
||||
* 使用 Python 的软件包管理器 `pip`
|
||||
|
||||
两个方法都工作的很好,并且每一个都有它自己的一套优势。如果你是在 Linux 或 BSD 上开发,可以利用你的发行版的软件存储库来自动和及时地更新。
|
||||
|
||||
然而,使用 Python 的内置软件包管理器可以给予你控制更新模块时间的能力。而且,它不是特定于操作系统的,这意味着,即使当你不是在你常用的开发机器上时,你也可以使用它。`pip` 的其它的优势是允许本地安装模块,如果你没有正在使用的计算机的管理权限,这是有用的。
|
||||
|
||||
### 使用 pip
|
||||
|
||||
如果 Python 和 Python3 都安装在你的系统上,你想使用的命令很可能是 `pip3`,它用来区分 Python 2.x 的 `pip` 的命令。如果你不确定,先尝试 `pip3`。
|
||||
|
||||
`pip` 命令有些像大多数 Linux 软件包管理器一样工作。你可以使用 `search` 搜索 Python 模块,然后使用 `install` 安装它们。如果你没有你正在使用的计算机的管理权限来安装软件,你可以使用 `--user` 选项来仅仅安装模块到你的家目录。
|
||||
|
||||
```
|
||||
$ pip3 search pygame
|
||||
[...]
|
||||
Pygame (1.9.3) - Python Game Development
|
||||
sge-pygame (1.5) - A 2-D game engine for Python
|
||||
pygame_camera (0.1.1) - A Camera lib for PyGame
|
||||
pygame_cffi (0.2.1) - A cffi-based SDL wrapper that copies the pygame API.
|
||||
[...]
|
||||
$ pip3 install Pygame --user
|
||||
```
|
||||
|
||||
Pygame 是一个 Python 模块,这意味着它仅仅是一套可以使用在你的 Python 程序中的库。换句话说,它不是一个像 [IDLE][3] 或 [Ninja-IDE][4] 一样可以让你启动的程序。
|
||||
|
||||
### Pygame 新手入门
|
||||
|
||||
一个电子游戏需要一个背景设定:故事发生的地点。在 Python 中,有两种不同的方法来创建你的故事背景:
|
||||
|
||||
* 设置一种背景颜色
|
||||
* 设置一张背景图片
|
||||
|
||||
你的背景仅是一张图片或一种颜色。你的电子游戏人物不能与在背景中的东西相互作用,因此,不要在后面放置一些太重要的东西。它仅仅是设置装饰。
|
||||
|
||||
### 设置你的 Pygame 脚本
|
||||
|
||||
要开始一个新的 Pygame 工程,先在计算机上创建一个文件夹。游戏的全部文件被放在这个目录中。在你的工程文件夹内部保持所需要的所有的文件来运行游戏是极其重要的。
|
||||
|
||||

|
||||
|
||||
一个 Python 脚本以文件类型、你的姓名,和你想使用的许可证开始。使用一个开放源码许可证,以便你的朋友可以改善你的游戏并与你一起分享他们的更改:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
# by Seth Kenlon
|
||||
|
||||
## GPLv3
|
||||
# This program is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
然后,你告诉 Python 你想使用的模块。一些模块是常见的 Python 库,当然,你想包括一个你刚刚安装的 Pygame 模块。
|
||||
|
||||
```
|
||||
import pygame # 加载 pygame 关键字
|
||||
import sys # 让 python 使用你的文件系统
|
||||
import os # 帮助 python 识别你的操作系统
|
||||
```
|
||||
|
||||
由于你将用这个脚本文件做很多工作,在文件中分成段落是有帮助的,以便你知道在哪里放代码。你可以使用块注释来做这些,这些注释仅在看你的源文件代码时是可见的。在你的代码中创建三个块。
|
||||
|
||||
```
|
||||
'''
|
||||
Objects
|
||||
'''
|
||||
|
||||
# 在这里放置 Python 类和函数
|
||||
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
|
||||
# 在这里放置一次性的运行代码
|
||||
|
||||
'''
|
||||
Main Loop
|
||||
'''
|
||||
|
||||
# 在这里放置游戏的循环代码指令
|
||||
```
|
||||
|
||||
接下来,为你的游戏设置窗口大小。注意,不是每一个人都有大计算机屏幕,所以,最好使用一个适合大多数人的计算机的屏幕大小。
|
||||
|
||||
这里有一个方法来切换全屏模式,很多现代电子游戏都会这样做,但是,由于你刚刚开始,简单起见仅设置一个大小即可。
|
||||
|
||||
```
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
worldx = 960
|
||||
worldy = 720
|
||||
```
|
||||
|
||||
在脚本中使用 Pygame 引擎前,你需要一些基本的设置。你必须设置帧频,启动它的内部时钟,然后开始 (`init`)Pygame 。
|
||||
|
||||
```
|
||||
fps = 40 # 帧频
|
||||
ani = 4 # 动画循环
|
||||
clock = pygame.time.Clock()
|
||||
pygame.init()
|
||||
```
|
||||
|
||||
现在你可以设置你的背景。
|
||||
|
||||
### 设置背景
|
||||
|
||||
在你继续前,打开一个图形应用程序,为你的游戏世界创建一个背景。在你的工程目录中的 `images` 文件夹内部保存它为 `stage.png` 。
|
||||
|
||||
这里有一些你可以使用的自由图形应用程序。
|
||||
|
||||
* [Krita][5] 是一个专业级绘图素材模拟器,它可以被用于创建漂亮的图片。如果你对创建电子游戏艺术作品非常感兴趣,你甚至可以购买一系列的[游戏艺术作品教程][6]。
|
||||
* [Pinta][7] 是一个基本的,易于学习的绘图应用程序。
|
||||
* [Inkscape][8] 是一个矢量图形应用程序。使用它来绘制形状、线、样条曲线和贝塞尔曲线。
|
||||
|
||||
你的图像不必很复杂,你可以以后回去更改它。一旦有了它,在你文件的 Setup 部分添加这些代码:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png').convert())
|
||||
backdropbox = world.get_rect()
|
||||
```
|
||||
|
||||
如果你仅仅用一种颜色来填充你的游戏的背景,你需要做的就是:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
```
|
||||
|
||||
你也必须定义颜色以使用。在你的 Setup 部分,使用红、绿、蓝 (RGB) 的值来创建一些颜色的定义。
|
||||
|
||||
```
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
|
||||
BLUE = (25,25,200)
|
||||
BLACK = (23,23,23 )
|
||||
WHITE = (254,254,254)
|
||||
```
|
||||
|
||||
至此,你理论上可以启动你的游戏了。问题是,它可能仅持续了一毫秒。
|
||||
|
||||
为证明这一点,保存你的文件为 `your-name_game.py`(用你真实的名称替换 `your-name`)。然后启动你的游戏。
|
||||
|
||||
如果你正在使用 IDLE,通过选择来自 “Run” 菜单的 “Run Module” 来运行你的游戏。
|
||||
|
||||
如果你正在使用 Ninja,在左侧按钮条中单击 “Run file” 按钮。
|
||||
|
||||

|
||||
|
||||
你也可以直接从一个 Unix 终端或一个 Windows 命令提示符中运行一个 Python 脚本。
|
||||
|
||||
```
|
||||
$ python3 ./your-name_game.py
|
||||
```
|
||||
|
||||
如果你正在使用 Windows,使用这命令:
|
||||
|
||||
```
|
||||
py.exe your-name_game.py
|
||||
```
|
||||
|
||||
启动它,不过不要期望很多,因为你的游戏现在仅仅持续几毫秒。你可以在下一部分中修复它。
|
||||
|
||||
### 循环
|
||||
|
||||
除非另有说明,一个 Python 脚本运行一次并仅一次。近来计算机的运行速度是非常快的,所以你的 Python 脚本运行时间会少于 1 秒钟。
|
||||
|
||||
为强制你的游戏来处于足够长的打开和活跃状态来让人看到它(更不要说玩它),使用一个 `while` 循环。为使你的游戏保存打开,你可以设置一个变量为一些值,然后告诉一个 `while` 循环只要变量保持未更改则一直保存循环。
|
||||
|
||||
这经常被称为一个“主循环”,你可以使用术语 `main` 作为你的变量。在你的 Setup 部分的任意位置添加代码:
|
||||
|
||||
```
|
||||
main = True
|
||||
```
|
||||
|
||||
在主循环期间,使用 Pygame 关键字来检查键盘上的按键是否已经被按下或释放。添加这些代码到你的主循环部分:
|
||||
|
||||
```
|
||||
'''
|
||||
Main loop
|
||||
'''
|
||||
while main == True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit(); sys.exit()
|
||||
main = False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
```
|
||||
|
||||
也是在你的循环中,刷新你世界的背景。
|
||||
|
||||
如果你使用一个图片作为背景:
|
||||
|
||||
```
|
||||
world.blit(backdrop, backdropbox)
|
||||
```
|
||||
|
||||
如果你使用一种颜色作为背景:
|
||||
|
||||
```
|
||||
world.fill(BLUE)
|
||||
```
|
||||
|
||||
最后,告诉 Pygame 来重新刷新屏幕上的所有内容,并推进游戏的内部时钟。
|
||||
|
||||
```
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
保存你的文件,再次运行它来查看你曾经创建的最无趣的游戏。
|
||||
|
||||
退出游戏,在你的键盘上按 `q` 键。
|
||||
|
||||
在这系列的 [下一篇文章][9] 中,我将向你演示,如何加强你当前空空如也的游戏世界,所以,继续学习并创建一些将要使用的图形!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/12/game-framework-python
|
||||
|
||||
作者:[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://linux.cn/article-9071-1.html
|
||||
[2]: http://www.pygame.org/wiki/about
|
||||
[3]: https://en.wikipedia.org/wiki/IDLE
|
||||
[4]: http://ninja-ide.org/
|
||||
[5]: http://krita.org
|
||||
[6]: https://gumroad.com/l/krita-game-art-tutorial-1
|
||||
[7]: https://pinta-project.com/pintaproject/pinta/releases
|
||||
[8]: http://inkscape.org
|
||||
[9]: https://opensource.com/article/17/12/program-game-python-part-3-spawning-player
|
163
published/20171215 How to add a player to your Python game.md
Normal file
163
published/20171215 How to add a player to your Python game.md
Normal file
@ -0,0 +1,163 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (cycoe)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10858-1.html)
|
||||
[#]: subject: (How to add a player to your Python game)
|
||||
[#]: via: (https://opensource.com/article/17/12/game-python-add-a-player)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何在你的 Python 游戏中添加一个玩家
|
||||
======
|
||||
> 这是用 Python 从头开始构建游戏的系列文章的第三部分。
|
||||
|
||||

|
||||
|
||||
在 [这个系列的第一篇文章][1] 中,我解释了如何使用 Python 创建一个简单的基于文本的骰子游戏。在第二部分中,我向你们展示了如何从头开始构建游戏,即从 [创建游戏的环境][2] 开始。但是每个游戏都需要一名玩家,并且每个玩家都需要一个可操控的角色,这也就是我们接下来要在这个系列的第三部分中需要做的。
|
||||
|
||||
在 Pygame 中,玩家操控的图标或者化身被称作<ruby>妖精<rt>sprite</rt></ruby>。如果你现在还没有任何可用于玩家妖精的图像,你可以使用 [Krita][3] 或 [Inkscape][4] 来自己创建一些图像。如果你对自己的艺术细胞缺乏自信,你也可以在 [OpenClipArt.org][5] 或 [OpenGameArt.org][6] 搜索一些现成的图像。如果你还未按照上一篇文章所说的单独创建一个 `images` 文件夹,那么你需要在你的 Python 项目目录中创建它。将你想要在游戏中使用的图片都放 `images` 文件夹中。
|
||||
|
||||
为了使你的游戏真正的刺激,你应该为你的英雄使用一张动态的妖精图片。这意味着你需要绘制更多的素材,并且它们要大不相同。最常见的动画就是走路循环,通过一系列的图像让你的妖精看起来像是在走路。走路循环最快捷粗糙的版本需要四张图像。
|
||||
|
||||

|
||||
|
||||
注意:这篇文章中的代码示例同时兼容静止的和动态的玩家妖精。
|
||||
|
||||
将你的玩家妖精命名为 `hero.png`。如果你正在创建一个动态的妖精,则需要在名字后面加上一个数字,从 `hero1.png` 开始。
|
||||
|
||||
### 创建一个 Python 类
|
||||
|
||||
在 Python 中,当你在创建一个你想要显示在屏幕上的对象时,你需要创建一个类。
|
||||
|
||||
在你的 Python 脚本靠近顶端的位置,加入如下代码来创建一个玩家。在以下的代码示例中,前三行已经在你正在处理的 Python 脚本中:
|
||||
|
||||
```
|
||||
import pygame
|
||||
import sys
|
||||
import os # 以下是新代码
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
生成一个玩家
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.images = []
|
||||
img = pygame.image.load(os.path.join('images','hero.png')).convert()
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
```
|
||||
|
||||
如果你的可操控角色拥有一个走路循环,在 `images` 文件夹中将对应图片保存为 `hero1.png` 到 `hero4.png` 的独立文件。
|
||||
|
||||
使用一个循环来告诉 Python 遍历每个文件。
|
||||
|
||||
```
|
||||
'''
|
||||
对象
|
||||
'''
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
生成一个玩家
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.images = []
|
||||
for i in range(1,5):
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
```
|
||||
|
||||
### 将玩家带入游戏世界
|
||||
|
||||
现在已经创建好了一个 Player 类,你需要使用它在你的游戏世界中生成一个玩家妖精。如果你不调用 Player 类,那它永远不会起作用,(游戏世界中)也就不会有玩家。你可以通过立马运行你的游戏来验证一下。游戏会像上一篇文章末尾看到的那样运行,并得到明确的结果:一个空荡荡的游戏世界。
|
||||
|
||||
为了将一个玩家妖精带到你的游戏世界,你必须通过调用 Player 类来生成一个妖精,并将它加入到 Pygame 的妖精组中。在如下的代码示例中,前三行是已经存在的代码,你需要在其后添加代码:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
|
||||
backdropbox = screen.get_rect()
|
||||
|
||||
# 以下是新代码
|
||||
|
||||
player = Player() # 生成玩家
|
||||
player.rect.x = 0 # 移动 x 坐标
|
||||
player.rect.y = 0 # 移动 y 坐标
|
||||
player_list = pygame.sprite.Group()
|
||||
player_list.add(player)
|
||||
```
|
||||
|
||||
尝试启动你的游戏来看看发生了什么。高能预警:它不会像你预期的那样工作,当你启动你的项目,玩家妖精没有出现。事实上它生成了,只不过只出现了一毫秒。你要如何修复一个只出现了一毫秒的东西呢?你可能回想起上一篇文章中,你需要在主循环中添加一些东西。为了使玩家的存在时间超过一毫秒,你需要告诉 Python 在每次循环中都绘制一次。
|
||||
|
||||
将你的循环底部的语句更改如下:
|
||||
|
||||
```
|
||||
world.blit(backdrop, backdropbox)
|
||||
player_list.draw(screen) # 绘制玩家
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
现在启动你的游戏,你的玩家出现了!
|
||||
|
||||
### 设置 alpha 通道
|
||||
|
||||
根据你如何创建你的玩家妖精,在它周围可能会有一个色块。你所看到的是 alpha 通道应该占据的空间。它本来是不可见的“颜色”,但 Python 现在还不知道要使它不可见。那么你所看到的,是围绕在妖精周围的边界区(或现代游戏术语中的“<ruby>命中区<rt>hit box</rt></ruby>”)内的空间。
|
||||
|
||||

|
||||
|
||||
你可以通过设置一个 alpha 通道和 RGB 值来告诉 Python 使哪种颜色不可见。如果你不知道你使用 alpha 通道的图像的 RGB 值,你可以使用 Krita 或 Inkscape 打开它,并使用一种独特的颜色,比如 `#00ff00`(差不多是“绿屏绿”)来填充图像周围的空白区域。记下颜色对应的十六进制值(此处为 `#00ff00`,绿屏绿)并将其作为 alpha 通道用于你的 Python 脚本。
|
||||
|
||||
使用 alpha 通道需要在你的妖精生成相关代码中添加如下两行。类似第一行的代码已经存在于你的脚本中,你只需要添加另外两行:
|
||||
|
||||
```
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
img.convert_alpha() # 优化 alpha
|
||||
img.set_colorkey(ALPHA) # 设置 alpha
|
||||
```
|
||||
|
||||
除非你告诉它,否则 Python 不知道将哪种颜色作为 alpha 通道。在你代码的设置相关区域,添加一些颜色定义。将如下的变量定义添加于你的设置相关区域的任意位置:
|
||||
|
||||
```
|
||||
ALPHA = (0, 255, 0)
|
||||
```
|
||||
|
||||
在以上示例代码中,`0,255,0` 被我们使用,它在 RGB 中所代表的值与 `#00ff00` 在十六进制中所代表的值相同。你可以通过一个优秀的图像应用程序,如 [GIMP][7]、Krita 或 Inkscape,来获取所有这些颜色值。或者,你可以使用一个优秀的系统级颜色选择器,如 [KColorChooser][8],来检测颜色。
|
||||
|
||||

|
||||
|
||||
如果你的图像应用程序将你的妖精背景渲染成了其他的值,你可以按需调整 `ALPHA` 变量的值。不论你将 alpha 设为多少,最后它都将“不可见”。RGB 颜色值是非常严格的,因此如果你需要将 alpha 设为 000,但你又想将 000 用于你图像中的黑线,你只需要将图像中线的颜色设为 111。这样一来,(图像中的黑线)就足够接近黑色,但除了电脑以外没有人能看出区别。
|
||||
|
||||
运行你的游戏查看结果。
|
||||
|
||||

|
||||
|
||||
在 [这个系列的第四篇文章][9] 中,我会向你们展示如何使你的妖精动起来。多么的激动人心啊!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/12/game-python-add-a-player
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[cycoe](https://github.com/cycoe)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linux.cn/article-9071-1.html
|
||||
[2]: https://linux.cn/article-10850-1.html
|
||||
[3]: http://krita.org
|
||||
[4]: http://inkscape.org
|
||||
[5]: http://openclipart.org
|
||||
[6]: https://opengameart.org/
|
||||
[7]: http://gimp.org
|
||||
[8]: https://github.com/KDE/kcolorchooser
|
||||
[9]: https://opensource.com/article/17/12/program-game-python-part-4-moving-your-sprite
|
@ -0,0 +1,130 @@
|
||||
DomTerm:一款为 Linux 打造的终端模拟器
|
||||
======
|
||||
> 了解一下 DomTerm,这是一款终端模拟器和复用器,带有 HTML 图形和其它不多见的功能。
|
||||
|
||||

|
||||
|
||||
[DomTerm][1] 是一款现代化的终端模拟器,它使用浏览器引擎作为 “GUI 工具包”。这就支持了一些相关的特性,例如可嵌入图像和链接、HTML 富文本以及可折叠(显示/隐藏)命令。除此以外,它看起来感觉就像一个功能完整、独立的终端模拟器,有着出色 xterm 兼容性(包括鼠标处理和 24 位色)和恰当的 “装饰” (菜单)。另外它内置支持了会话管理和副窗口(如同 `tmux` 和 `GNU Screen` 中一样)、基本输入编辑(如在 `readline` 中)以及分页(如在 `less` 中)。
|
||||
|
||||

|
||||
|
||||
*图 1: DomTerminal 终端模拟器。*
|
||||
|
||||
在以下部分我们将看一看这些特性。我们将假设你已经安装好了 `domterm` (如果你需要获取并构建 Dormterm 请跳到本文最后)。开始之前先让我们概览一下这项技术。
|
||||
|
||||
### 前端 vs. 后端
|
||||
|
||||
DomTerm 大部分是用 JavaScript 写的,它运行在一个浏览器引擎中。它可以是像例如 Chrome 或者 Firefox 一样的桌面浏览器(见图 3),也可以是一个内嵌的浏览器。使用一个通用的网页浏览器没有问题,但是用户体验却不够好(因为菜单是为通用的网页浏览而不是为了终端模拟器所打造),并且其安全模型也会妨碍使用。因此使用内嵌的浏览器更好一些。
|
||||
|
||||
目前以下这些是支持的:
|
||||
|
||||
* qdomterm,使用了 Qt 工具包 和 QtWebEngine
|
||||
* 一个内嵌的 [Electron][2](见图 1)
|
||||
* atom-domterm 以 [Atom 文本编辑器][3](同样基于 Electron)包的形式运行 DomTerm,并和 Atom 面板系统集成在一起(见图 2)
|
||||
* 一个为 JavaFX 的 WebEngine 包装器,这对 Java 编程十分有用(见图 4)
|
||||
* 之前前端使用 [Firefox-XUL][4] 作为首选,但是 Mozilla 已经终止了 XUL
|
||||
|
||||
![在 Atom 编辑器中的 DomTerm 终端面板][6]
|
||||
|
||||
*图 2:在 Atom 编辑器中的 DomTerm 终端面板。*
|
||||
|
||||
目前,Electron 前端可能是最佳选择,紧随其后的是 Qt 前端。如果你使用 Atom,atom-domterm 也工作得相当不错。
|
||||
|
||||
后端服务器是用 C 写的。它管理着伪终端(PTY)和会话。它同样也是一个为前端提供 Javascript 和其它文件的 HTTP 服务器。`domterm` 命令启动终端任务和执行其它请求。如果没有服务器在运行,domterm 就会自己来服务。后端与服务器之间的通讯通常是用 WebSockets(在服务器端是[libwebsockets][8])完成的。然而,JavaFX 的嵌入既不用 Websockets 也不用 DomTerm 服务器。相反 Java 应用直接通过 Java-Javascript 桥接进行通讯。
|
||||
|
||||
### 一个稳健的可兼容 xterm 的终端模拟器
|
||||
|
||||
DomTerm 看上去感觉像一个现代的终端模拟器。它处理鼠标事件、24 位色、Unicode、倍宽字符(CJK)以及输入方式。DomTerm 在 [vttest 测试套件][9] 上工作地十分出色。
|
||||
|
||||
其不同寻常的特性包括:
|
||||
|
||||
**展示/隐藏按钮(“折叠”):** 小三角(如上图 2)是隐藏/展示相应输出的按钮。仅需在[提示符][11]中添加特定的[转义字符][10]就可以创建按钮。
|
||||
|
||||
**对于 readline 和类似输入编辑器的鼠标点击支持:** 如果你点击输入区域(黄色),DomTerm 会向应用发送正确的方向键按键序列。(可以通过提示符中的转义字符启用这一特性,你也可以通过 `Alt+点击` 强制使用。)
|
||||
|
||||
**用 CSS 样式化终端:** 这通常是在 `~/.domterm/settings.ini` 里完成的,保存时会自动重载。例如在图 2 中,设置了终端专用的背景色。
|
||||
|
||||
### 一个更好的 REPL 控制台
|
||||
|
||||
一个经典的终端模拟器基于长方形的字符单元格工作的。这在 REPL(命令行)上没问题,但是并不理想。这里有些通常在终端模拟器中不常见的 REPL 很有用的 DomTerm 特性:
|
||||
|
||||
**一个能“打印”图片、图形、数学公式或者一组可点击的链接的命令:** 应用可以发送包含几乎任何 HTML 的转义字符。(HTML 会被剔除部分,以移除 JavaScript 和其它危险特性。)
|
||||
|
||||
图 3 显示了来自 [gnuplot][12] 会话的一个片段。Gnuplot(2.1 或者跟高版本)支持 DormTerm 作为终端类型。图形输出被转换成 [SVG 图片][13],然后被打印到终端。我的博客帖子[在 DormTerm 上的 Gnuplot 展示][14]在这方面提供了更多信息。
|
||||
|
||||

|
||||
|
||||
*图 3:Gnuplot 截图。*
|
||||
|
||||
[Kawa][15] 语言有一个创建并转换[几何图像值][16]的库。如果你将这样的图片值打印到 DomTerm 终端,图片就会被转换成 SVG 形式并嵌入进输出中。
|
||||
|
||||

|
||||
|
||||
*图 4:Kawa 中可计算的几何形状。*
|
||||
|
||||
**富文本输出:** 有着 HTML 样式的帮助信息更加便于阅读,看上去也更漂亮。图片 1 的下面面板展示 `dormterm help` 的输出。(如果没在 DomTerm 下运行的话输出的是普通文本。)注意自带的分页器中的 `PAUSED` 消息。
|
||||
|
||||
**包括可点击链接的错误消息:** DomTerm 可以识别语法 `filename:line:column` 并将其转化成一个能在可定制文本编辑器中打开文件并定位到行的链接。(这适用于相对路径的文件名,如果你用 `PROMPT_COMMAND` 或类似的跟踪目录。)
|
||||
|
||||
编译器可以侦测到它在 DomTerm 下运行,并直接用转义字符发出文件链接。这比依赖 DomTerm 的样式匹配要稳健得多,因为它可以处理空格和其他字符并且无需依赖目录追踪。在图 4 中,你可以看到来自 [Kawa Compiler][15] 的错误消息。悬停在文件位置上会使其出现下划线,`file:` URL 出现在 `atom-domterm` 消息栏(窗口底部)中。(当不用 atom-domterm 时,这样的消息会在一个浮层的框中显示,如图 1 中所看到的 `PAUSED` 消息所示。)
|
||||
|
||||
点击链接时的动作是可以配置的。默认对于带有 `#position` 后缀的 `file:` 链接的动作是在文本编辑器中打开那个文件。
|
||||
|
||||
**结构化内部表示:**以下内容均以内部节点结构表示:命令、提示符、输入行、正常和错误输出、标签,如果“另存为 HTML”,则保留结构。HTML 文件与 XML 兼容,因此你可以使用 XML 工具搜索或转换输出。命令 `domterm view-saved` 会以一种启用命令折叠(显示/隐藏按钮处于活动状态)和重新调整窗口大小的方式打开保存的 HTML 文件。
|
||||
|
||||
**内建的 Lisp 样式优美打印:** 你可以在输出中包括优美打印指令(比如,grouping),这样断行会根据窗口大小调整而重新计算。查看我的文章 [DomTerm 中的动态优美打印][17]以更深入探讨。
|
||||
|
||||
**基本的内建行编辑**,带着历史记录(像 GNU readline 一样): 这使用浏览器自带的编辑器,因此它有着优秀的鼠标和选择处理机制。你可以在正常字符模式(大多数输入的字符被指接送向进程);或者行模式(通常的字符是直接插入的,而控制字符导致编辑操作,回车键会向进程发送被编辑行)之间转换。默认的是自动模式,根据 PTY 是在原始模式还是终端模式中,DomTerm 在字符模式与行模式间转换。
|
||||
|
||||
**自带的分页器**(类似简化版的 `less`):键盘快捷键控制滚动。在“页模式”中,输出在每个新的屏幕(或者单独的行,如果你想一行行地向前移)后暂停;页模式对于用户输入简单智能,因此(如果你想的话)你无需阻碍交互式程序就可以运行它。
|
||||
|
||||
### 多路复用和会话
|
||||
|
||||
**标签和平铺:** 你不仅可以创建多个终端标签,也可以平铺它们。你可以要么使用鼠标或键盘快捷键来创建或者切换面板和标签。它们可以用鼠标重新排列并调整大小。这是通过 [GoldenLayout][18] JavaScript 库实现的。图 1 展示了一个有着两个面板的窗口。上面的有两个标签,一个运行 [Midnight Commander][20];底下的面板以 HTML 形式展示了 `dormterm help` 输出。然而相反在 Atom 中我们使用其自带的可拖拽的面板和标签。你可以在图 2 中看到这个。
|
||||
|
||||
**分离或重接会话:** 与 `tmux` 和 GNU `screen` 类似,DomTerm 支持会话安排。你甚至可以给同样的会话接上多个窗口或面板。这支持多用户会话分享和远程链接。(为了安全,同一个服务器的所有会话都需要能够读取 Unix 域接口和一个包含随机密钥的本地文件。当我们有了良好、安全的远程链接,这个限制将会有所放松。)
|
||||
|
||||
**domterm 命令** 类似与 `tmux` 和 GNU `screen`,它有多个选项可以用于控制或者打开单个或多个会话的服务器。主要的差别在于,如果它没在 DomTerm 下运行,`dormterm` 命令会创建一个新的顶层窗口,而不是在现有的终端中运行。
|
||||
|
||||
与 `tmux` 和 `git` 类似,`dormterm` 命令有许多子命令。一些子命令创建窗口或者会话。另一些(例如“打印”一张图片)仅在现有的 DormTerm 会话下起作用。
|
||||
|
||||
命令 `domterm browse` 打开一个窗口或者面板以浏览一个指定的 URL,例如浏览文档的时候。
|
||||
|
||||
### 获取并安装 DomTerm
|
||||
|
||||
DomTerm 可以从其 [Github 仓库][21]获取。目前没有提前构建好的包,但是有[详细指导][22]。所有的前提条件在 Fedora 27 上都有,这使得其特别容易被搭建。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/1/introduction-domterm-terminal-emulator
|
||||
|
||||
作者:[Per Bothner][a]
|
||||
译者:[tomjlw](https://github.com/tomjlw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/perbothner
|
||||
[1]:http://domterm.org/
|
||||
[2]:https://electronjs.org/
|
||||
[3]:https://atom.io/
|
||||
[4]:https://en.wikipedia.org/wiki/XUL
|
||||
[5]:/file/385346
|
||||
[6]:https://opensource.com/sites/default/files/images/dt-atom1.png (DomTerm terminal panes in Atom editor)
|
||||
[7]:https://opensource.com/sites/default/files/images/dt-atom1.png
|
||||
[8]:https://libwebsockets.org/
|
||||
[9]:http://invisible-island.net/vttest/
|
||||
[10]:http://domterm.org/Wire-byte-protocol.html
|
||||
[11]:http://domterm.org/Shell-prompts.html
|
||||
[12]:http://www.gnuplot.info/
|
||||
[13]:https://developer.mozilla.org/en-US/docs/Web/SVG
|
||||
[14]:http://per.bothner.com/blog/2016/gnuplot-in-domterm/
|
||||
[15]:https://www.gnu.org/software/kawa/
|
||||
[16]:https://www.gnu.org/software/kawa/Composable-pictures.html
|
||||
[17]:http://per.bothner.com/blog/2017/dynamic-prettyprinting/
|
||||
[18]:https://golden-layout.com/
|
||||
[19]:https://opensource.com/sites/default/files/u128651/domterm1.png
|
||||
[20]:https://midnight-commander.org/
|
||||
[21]:https://github.com/PerBothner/DomTerm
|
||||
[22]:http://domterm.org/Downloading-and-building.html
|
||||
|
130
published/20180605 How to use autofs to mount NFS shares.md
Normal file
130
published/20180605 How to use autofs to mount NFS shares.md
Normal file
@ -0,0 +1,130 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10830-1.html)
|
||||
[#]: subject: (How to use autofs to mount NFS shares)
|
||||
[#]: via: (https://opensource.com/article/18/6/using-autofs-mount-nfs-shares)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss)
|
||||
|
||||
如何使用 autofs 挂载 NFS 共享
|
||||
======
|
||||
|
||||
> 给你的网络文件系统(NFS)配置一个基本的自动挂载功能。
|
||||
|
||||

|
||||
|
||||
大多数 Linux 文件系统在引导时挂载,并在系统运行时保持挂载状态。对于已在 `fstab` 中配置的任何远程文件系统也是如此。但是,有时你可能希望仅按需挂载远程文件系统。例如,通过减少网络带宽使用来提高性能,或出于安全原因隐藏或混淆某些目录。[autofs][1] 软件包提供此功能。在本文中,我将介绍如何配置基本的自动挂载。
|
||||
|
||||
首先做点假设:假设有台 NFS 服务器 `tree.mydatacenter.net` 已经启动并运行。另外假设一个名为 `ourfiles` 的数据目录还有供 Carl 和 Sarah 使用的用户目录,它们都由服务器共享。
|
||||
|
||||
一些最佳实践可以使工作更好:服务器上的用户和任何客户端工作站上的帐号有相同的用户 ID。此外,你的工作站和服务器应有相同的域名。检查相关配置文件应该确认。
|
||||
|
||||
```
|
||||
alan@workstation1:~$ sudo getent passwd carl sarah
|
||||
[sudo] password for alan:
|
||||
carl:x:1020:1020:Carl,,,:/home/carl:/bin/bash
|
||||
sarah:x:1021:1021:Sarah,,,:/home/sarah:/bin/bash
|
||||
|
||||
alan@workstation1:~$ sudo getent hosts
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 workstation1.mydatacenter.net workstation1
|
||||
10.10.1.5 tree.mydatacenter.net tree
|
||||
```
|
||||
|
||||
如你所见,客户端工作站和 NFS 服务器都在 `hosts` 文件中配置。我假设这是一个基本的家庭甚至小型办公室网络,可能缺乏适合的内部域名服务(即 DNS)。
|
||||
|
||||
### 安装软件包
|
||||
|
||||
你只需要安装两个软件包:用于 NFS 客户端的 `nfs-common` 和提供自动挂载的 `autofs`。
|
||||
|
||||
```
|
||||
alan@workstation1:~$ sudo apt-get install nfs-common autofs
|
||||
```
|
||||
|
||||
你可以验证 autofs 相关的文件是否已放在 `/etc` 目录中:
|
||||
|
||||
```
|
||||
alan@workstation1:~$ cd /etc; ll auto*
|
||||
-rw-r--r-- 1 root root 12596 Nov 19 2015 autofs.conf
|
||||
-rw-r--r-- 1 root root 857 Mar 10 2017 auto.master
|
||||
-rw-r--r-- 1 root root 708 Jul 6 2017 auto.misc
|
||||
-rwxr-xr-x 1 root root 1039 Nov 19 2015 auto.net*
|
||||
-rwxr-xr-x 1 root root 2191 Nov 19 2015 auto.smb*
|
||||
alan@workstation1:/etc$
|
||||
```
|
||||
|
||||
### 配置 autofs
|
||||
|
||||
现在你需要编辑其中几个文件并添加 `auto.home` 文件。首先,将以下两行添加到文件 `auto.master` 中:
|
||||
|
||||
```
|
||||
/mnt/tree /etc/auto.misc
|
||||
/home/tree /etc/auto.home
|
||||
```
|
||||
|
||||
每行以挂载 NFS 共享的目录开头。继续创建这些目录:
|
||||
|
||||
```
|
||||
alan@workstation1:/etc$ sudo mkdir /mnt/tree /home/tree
|
||||
```
|
||||
|
||||
接下来,将以下行添加到文件 `auto.misc`:
|
||||
|
||||
```
|
||||
ourfiles -fstype=nfs tree:/share/ourfiles
|
||||
```
|
||||
|
||||
该行表示 autofs 将挂载 `auto.master` 文件中匹配 `auto.misc` 的 `ourfiles` 共享。如上所示,这些文件将在 `/mnt/tree/ourfiles` 目录中。
|
||||
|
||||
第三步,使用以下行创建文件 `auto.home`:
|
||||
|
||||
```
|
||||
* -fstype=nfs tree:/home/&
|
||||
```
|
||||
|
||||
该行表示 autofs 将挂载 `auto.master` 文件中匹配 `auto.home` 的用户共享。在这种情况下,Carl 和 Sarah 的文件将分别在目录 `/home/tree/carl` 或 `/home/tree/sarah`中。星号 `*`(称为通配符)使每个用户的共享可以在登录时自动挂载。`&` 符号也可以作为表示服务器端用户目录的通配符。它们的主目录会相应地根据 `passwd` 文件映射。如果你更喜欢本地主目录,则无需执行此操作。相反,用户可以将其用作特定文件的简单远程存储。
|
||||
|
||||
最后,重启 `autofs` 守护进程,以便识别并加载这些配置的更改。
|
||||
|
||||
```
|
||||
alan@workstation1:/etc$ sudo service autofs restart
|
||||
```
|
||||
|
||||
### 测试 autofs
|
||||
|
||||
如果更改文件 `auto.master` 中的列出目录,并运行 `ls` 命令,那么不会立即看到任何内容。例如,切换到目录 `/mnt/tree`。首先,`ls` 的输出不会显示任何内容,但在运行 `cd ourfiles` 之后,将自动挂载 `ourfiles` 共享目录。 `cd` 命令也将被执行,你将进入新挂载的目录中。
|
||||
|
||||
```
|
||||
carl@workstation1:~$ cd /mnt/tree
|
||||
carl@workstation1:/mnt/tree$ ls
|
||||
carl@workstation1:/mnt/tree$ cd ourfiles
|
||||
carl@workstation1:/mnt/tree/ourfiles$
|
||||
```
|
||||
|
||||
为了进一步确认正常工作,`mount` 命令会显示已挂载共享的细节。
|
||||
|
||||
```
|
||||
carl@workstation1:~$ mount
|
||||
|
||||
tree:/mnt/share/ourfiles on /mnt/tree/ourfiles type nfs4 (rw,relatime,vers=4.0,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.10.1.22,local_lock=none,addr=10.10.1.5)
|
||||
|
||||
```
|
||||
|
||||
对于 Carl 和 Sarah,`/home/tree` 目录工作方式相同。
|
||||
|
||||
我发现在我的文件管理器中添加这些目录的书签很有用,可以用来快速访问。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/6/using-autofs-mount-nfs-shares
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[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/alanfdoss
|
||||
[1]:https://wiki.archlinux.org/index.php/autofs
|
@ -0,0 +1,596 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10848-1.html)
|
||||
[#]: subject: (TLP – An Advanced Power Management Tool That Improve Battery Life On Linux Laptop)
|
||||
[#]: via: (https://www.2daygeek.com/tlp-increase-optimize-linux-laptop-battery-life/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
TLP:一个可以延长 Linux 笔记本电池寿命的高级电源管理工具
|
||||
======
|
||||
|
||||

|
||||
|
||||
笔记本电池是针对 Windows 操作系统进行了高度优化的,当我在笔记本电脑中使用 Windows 操作系统时,我已经意识到这一点,但对于 Linux 来说却不一样。
|
||||
|
||||
多年来,Linux 在电池优化方面取得了很大进步,但我们仍然需要做一些必要的事情来改善 Linux 中笔记本电脑的电池寿命。
|
||||
|
||||
当我考虑延长电池寿命时,我没有多少选择,但我觉得 TLP 对我来说是一个更好的解决方案,所以我会继续使用它。
|
||||
|
||||
在本教程中,我们将详细讨论 TLP 以延长电池寿命。
|
||||
|
||||
我们之前在我们的网站上写过三篇关于 Linux [笔记本电池节电工具][1] 的文章:[PowerTOP][2] 和 [电池充电状态][3]。
|
||||
|
||||
### TLP
|
||||
|
||||
[TLP][4] 是一款自由开源的高级电源管理工具,可在不进行任何配置更改的情况下延长电池寿命。
|
||||
|
||||
由于它的默认配置已针对电池寿命进行了优化,因此你可能只需要安装,然后就忘记它吧。
|
||||
|
||||
此外,它可以高度定制化,以满足你的特定要求。TLP 是一个具有自动后台任务的纯命令行工具。它不包含GUI。
|
||||
|
||||
TLP 适用于各种品牌的笔记本电脑。设置电池充电阈值仅适用于 IBM/Lenovo ThinkPad。
|
||||
|
||||
所有 TLP 设置都存储在 `/etc/default/tlp` 中。其默认配置提供了开箱即用的优化的节能设置。
|
||||
|
||||
以下 TLP 设置可用于自定义,如果需要,你可以相应地进行必要的更改。
|
||||
|
||||
### TLP 功能
|
||||
|
||||
* 内核笔记本电脑模式和脏缓冲区超时
|
||||
* 处理器频率调整,包括 “turbo boost”/“turbo core”
|
||||
* 限制最大/最小的 P 状态以控制 CPU 的功耗
|
||||
* HWP 能源性能提示
|
||||
* 用于多核/超线程的功率感知进程调度程序
|
||||
* 处理器性能与节能策略(`x86_energy_perf_policy`)
|
||||
* 硬盘高级电源管理级别(APM)和降速超时(按磁盘)
|
||||
* AHCI 链路电源管理(ALPM)与设备黑名单
|
||||
* PCIe 活动状态电源管理(PCIe ASPM)
|
||||
* PCI(e) 总线设备的运行时电源管理
|
||||
* Radeon 图形电源管理(KMS 和 DPM)
|
||||
* Wifi 省电模式
|
||||
* 关闭驱动器托架中的光盘驱动器
|
||||
* 音频省电模式
|
||||
* I/O 调度程序(按磁盘)
|
||||
* USB 自动暂停,支持设备黑名单/白名单(输入设备自动排除)
|
||||
* 在系统启动和关闭时启用或禁用集成的 wifi、蓝牙或 wwan 设备
|
||||
* 在系统启动时恢复无线电设备状态(从之前的关机时的状态)
|
||||
* 无线电设备向导:在网络连接/断开和停靠/取消停靠时切换无线电
|
||||
* 禁用 LAN 唤醒
|
||||
* 挂起/休眠后恢复集成的 WWAN 和蓝牙状态
|
||||
* 英特尔处理器的动态电源降低 —— 需要内核和 PHC-Patch 支持
|
||||
* 电池充电阈值 —— 仅限 ThinkPad
|
||||
* 重新校准电池 —— 仅限 ThinkPad
|
||||
|
||||
### 如何在 Linux 上安装 TLP
|
||||
|
||||
TLP 包在大多数发行版官方存储库中都可用,因此,使用发行版的 [包管理器][5] 来安装它。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][6] 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo dnf install tlp tlp-rdw
|
||||
```
|
||||
|
||||
ThinkPad 需要一些附加软件包。
|
||||
|
||||
```
|
||||
$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
|
||||
$ sudo dnf install http://repo.linrunner.de/fedora/tlp/repos/releases/tlp-release.fc$(rpm -E %fedora).noarch.rpm
|
||||
$ sudo dnf install akmod-tp_smapi akmod-acpi_call kernel-devel
|
||||
```
|
||||
|
||||
安装 smartmontool 以显示 tlp-stat 中 S.M.A.R.T. 数据。
|
||||
|
||||
```
|
||||
$ sudo dnf install smartmontools
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][7] 或 [APT 命令][8] 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo apt install tlp tlp-rdw
|
||||
```
|
||||
|
||||
ThinkPad 需要一些附加软件包。
|
||||
|
||||
```
|
||||
$ sudo apt-get install tp-smapi-dkms acpi-call-dkms
|
||||
```
|
||||
|
||||
安装 smartmontool 以显示 tlp-stat 中 S.M.A.R.T. 数据。
|
||||
|
||||
```
|
||||
$ sudo apt-get install smartmontools
|
||||
```
|
||||
|
||||
当基于 Ubuntu 的系统的官方软件包过时时,请使用以下 PPA 存储库,该存储库提供最新版本。运行以下命令以使用 PPA 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo add-apt-repository ppa:linrunner/tlp
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install tlp
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman 命令][9] 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo pacman -S tlp tlp-rdw
|
||||
```
|
||||
|
||||
ThinkPad 需要一些附加软件包。
|
||||
|
||||
```
|
||||
$ pacman -S tp_smapi acpi_call
|
||||
```
|
||||
|
||||
安装 smartmontool 以显示 tlp-stat 中 S.M.A.R.T. 数据。
|
||||
|
||||
```
|
||||
$ sudo pacman -S smartmontools
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,在启动时启用 TLP 和 TLP-Sleep 服务。
|
||||
|
||||
```
|
||||
$ sudo systemctl enable tlp.service
|
||||
$ sudo systemctl enable tlp-sleep.service
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,你还应该屏蔽以下服务以避免冲突,并确保 TLP 的无线电设备切换选项的正确操作。
|
||||
|
||||
```
|
||||
$ sudo systemctl mask systemd-rfkill.service
|
||||
$ sudo systemctl mask systemd-rfkill.socket
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统,使用 [YUM 命令][10] 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo yum install tlp tlp-rdw
|
||||
```
|
||||
|
||||
安装 smartmontool 以显示 tlp-stat 中 S.M.A.R.T. 数据。
|
||||
|
||||
```
|
||||
$ sudo yum install smartmontools
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][11] 安装 TLP。
|
||||
|
||||
```
|
||||
$ sudo zypper install TLP
|
||||
```
|
||||
|
||||
安装 smartmontool 以显示 tlp-stat 中 S.M.A.R.T. 数据。
|
||||
|
||||
```
|
||||
$ sudo zypper install smartmontools
|
||||
```
|
||||
|
||||
成功安装 TLP 后,使用以下命令启动服务。
|
||||
|
||||
```
|
||||
$ systemctl start tlp.service
|
||||
```
|
||||
|
||||
### 使用方法
|
||||
|
||||
#### 显示电池信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -b
|
||||
或
|
||||
$ sudo tlp-stat --battery
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Battery Status
|
||||
/sys/class/power_supply/BAT0/manufacturer = SMP
|
||||
/sys/class/power_supply/BAT0/model_name = L14M4P23
|
||||
/sys/class/power_supply/BAT0/cycle_count = (not supported)
|
||||
/sys/class/power_supply/BAT0/energy_full_design = 60000 [mWh]
|
||||
/sys/class/power_supply/BAT0/energy_full = 48850 [mWh]
|
||||
/sys/class/power_supply/BAT0/energy_now = 48850 [mWh]
|
||||
/sys/class/power_supply/BAT0/power_now = 0 [mW]
|
||||
/sys/class/power_supply/BAT0/status = Full
|
||||
|
||||
Charge = 100.0 [%]
|
||||
Capacity = 81.4 [%]
|
||||
```
|
||||
|
||||
#### 显示磁盘信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -d
|
||||
或
|
||||
$ sudo tlp-stat --disk
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Storage Devices
|
||||
/dev/sda:
|
||||
Model = WDC WD10SPCX-24HWST1
|
||||
Firmware = 02.01A02
|
||||
APM Level = 128
|
||||
Status = active/idle
|
||||
Scheduler = mq-deadline
|
||||
|
||||
Runtime PM: control = on, autosuspend_delay = (not available)
|
||||
|
||||
SMART info:
|
||||
4 Start_Stop_Count = 18787
|
||||
5 Reallocated_Sector_Ct = 0
|
||||
9 Power_On_Hours = 606 [h]
|
||||
12 Power_Cycle_Count = 1792
|
||||
193 Load_Cycle_Count = 25775
|
||||
194 Temperature_Celsius = 31 [°C]
|
||||
|
||||
|
||||
+++ AHCI Link Power Management (ALPM)
|
||||
/sys/class/scsi_host/host0/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host1/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host2/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host3/link_power_management_policy = med_power_with_dipm
|
||||
|
||||
+++ AHCI Host Controller Runtime Power Management
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata1/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata2/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata3/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata4/power/control = on
|
||||
```
|
||||
|
||||
#### 显示 PCI 设备信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -e
|
||||
或
|
||||
$ sudo tlp-stat --pcie
|
||||
```
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -e
|
||||
or
|
||||
$ sudo tlp-stat --pcie
|
||||
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Runtime Power Management
|
||||
Device blacklist = (not configured)
|
||||
Driver blacklist = amdgpu nouveau nvidia radeon pcieport
|
||||
|
||||
/sys/bus/pci/devices/0000:00:00.0/power/control = auto (0x060000, Host bridge, skl_uncore)
|
||||
/sys/bus/pci/devices/0000:00:01.0/power/control = auto (0x060400, PCI bridge, pcieport)
|
||||
/sys/bus/pci/devices/0000:00:02.0/power/control = auto (0x030000, VGA compatible controller, i915)
|
||||
/sys/bus/pci/devices/0000:00:14.0/power/control = auto (0x0c0330, USB controller, xhci_hcd)
|
||||
|
||||
......
|
||||
```
|
||||
|
||||
#### 显示图形卡信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -g
|
||||
或
|
||||
$ sudo tlp-stat --graphics
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Intel Graphics
|
||||
/sys/module/i915/parameters/enable_dc = -1 (use per-chip default)
|
||||
/sys/module/i915/parameters/enable_fbc = 1 (enabled)
|
||||
/sys/module/i915/parameters/enable_psr = 0 (disabled)
|
||||
/sys/module/i915/parameters/modeset = -1 (use per-chip default)
|
||||
```
|
||||
|
||||
#### 显示处理器信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -p
|
||||
或
|
||||
$ sudo tlp-stat --processor
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Processor
|
||||
CPU model = Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
|
||||
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver = intel_pstate
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor = powersave
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors = performance powersave
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq = 800000 [kHz]
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq = 3500000 [kHz]
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference = balance_power
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences = default performance balance_performance balance_power power
|
||||
|
||||
......
|
||||
|
||||
/sys/devices/system/cpu/intel_pstate/min_perf_pct = 22 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/max_perf_pct = 100 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/no_turbo = 0
|
||||
/sys/devices/system/cpu/intel_pstate/turbo_pct = 33 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/num_pstates = 28
|
||||
|
||||
x86_energy_perf_policy: program not installed.
|
||||
|
||||
/sys/module/workqueue/parameters/power_efficient = Y
|
||||
/proc/sys/kernel/nmi_watchdog = 0
|
||||
|
||||
+++ Undervolting
|
||||
PHC kernel not available.
|
||||
```
|
||||
|
||||
#### 显示系统数据信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -s
|
||||
或
|
||||
$ sudo tlp-stat --system
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ System Info
|
||||
System = LENOVO Lenovo ideapad Y700-15ISK 80NV
|
||||
BIOS = CDCN35WW
|
||||
Release = "Manjaro Linux"
|
||||
Kernel = 4.19.6-1-MANJARO #1 SMP PREEMPT Sat Dec 1 12:21:26 UTC 2018 x86_64
|
||||
/proc/cmdline = BOOT_IMAGE=/boot/vmlinuz-4.19-x86_64 root=UUID=69d9dd18-36be-4631-9ebb-78f05fe3217f rw quiet resume=UUID=a2092b92-af29-4760-8e68-7a201922573b
|
||||
Init system = systemd
|
||||
Boot mode = BIOS (CSM, Legacy)
|
||||
|
||||
+++ TLP Status
|
||||
State = enabled
|
||||
Last run = 11:04:00 IST, 596 sec(s) ago
|
||||
Mode = battery
|
||||
Power source = battery
|
||||
```
|
||||
|
||||
#### 显示温度和风扇速度信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -t
|
||||
或
|
||||
$ sudo tlp-stat --temp
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Temperatures
|
||||
CPU temp = 36 [°C]
|
||||
Fan speed = (not available)
|
||||
```
|
||||
|
||||
#### 显示 USB 设备数据信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -u
|
||||
或
|
||||
$ sudo tlp-stat --usb
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ USB
|
||||
Autosuspend = disabled
|
||||
Device whitelist = (not configured)
|
||||
Device blacklist = (not configured)
|
||||
Bluetooth blacklist = disabled
|
||||
Phone blacklist = disabled
|
||||
WWAN blacklist = enabled
|
||||
|
||||
Bus 002 Device 001 ID 1d6b:0003 control = auto, autosuspend_delay_ms = 0 -- Linux Foundation 3.0 root hub (hub)
|
||||
Bus 001 Device 003 ID 174f:14e8 control = auto, autosuspend_delay_ms = 2000 -- Syntek (uvcvideo)
|
||||
|
||||
......
|
||||
```
|
||||
|
||||
#### 显示警告信息
|
||||
|
||||
```
|
||||
$ sudo tlp-stat -w
|
||||
或
|
||||
$ sudo tlp-stat --warn
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
No warnings detected.
|
||||
```
|
||||
|
||||
#### 状态报告及配置和所有活动的设置
|
||||
|
||||
```
|
||||
$ sudo tlp-stat
|
||||
```
|
||||
|
||||
```
|
||||
--- TLP 1.1 --------------------------------------------
|
||||
|
||||
+++ Configured Settings: /etc/default/tlp
|
||||
TLP_ENABLE=1
|
||||
TLP_DEFAULT_MODE=AC
|
||||
TLP_PERSISTENT_DEFAULT=0
|
||||
DISK_IDLE_SECS_ON_AC=0
|
||||
DISK_IDLE_SECS_ON_BAT=2
|
||||
MAX_LOST_WORK_SECS_ON_AC=15
|
||||
MAX_LOST_WORK_SECS_ON_BAT=60
|
||||
|
||||
......
|
||||
|
||||
+++ System Info
|
||||
System = LENOVO Lenovo ideapad Y700-15ISK 80NV
|
||||
BIOS = CDCN35WW
|
||||
Release = "Manjaro Linux"
|
||||
Kernel = 4.19.6-1-MANJARO #1 SMP PREEMPT Sat Dec 1 12:21:26 UTC 2018 x86_64
|
||||
/proc/cmdline = BOOT_IMAGE=/boot/vmlinuz-4.19-x86_64 root=UUID=69d9dd18-36be-4631-9ebb-78f05fe3217f rw quiet resume=UUID=a2092b92-af29-4760-8e68-7a201922573b
|
||||
Init system = systemd
|
||||
Boot mode = BIOS (CSM, Legacy)
|
||||
|
||||
+++ TLP Status
|
||||
State = enabled
|
||||
Last run = 11:04:00 IST, 684 sec(s) ago
|
||||
Mode = battery
|
||||
Power source = battery
|
||||
|
||||
+++ Processor
|
||||
CPU model = Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
|
||||
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver = intel_pstate
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor = powersave
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors = performance powersave
|
||||
|
||||
......
|
||||
|
||||
/sys/devices/system/cpu/intel_pstate/min_perf_pct = 22 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/max_perf_pct = 100 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/no_turbo = 0
|
||||
/sys/devices/system/cpu/intel_pstate/turbo_pct = 33 [%]
|
||||
/sys/devices/system/cpu/intel_pstate/num_pstates = 28
|
||||
|
||||
x86_energy_perf_policy: program not installed.
|
||||
|
||||
/sys/module/workqueue/parameters/power_efficient = Y
|
||||
/proc/sys/kernel/nmi_watchdog = 0
|
||||
|
||||
+++ Undervolting
|
||||
PHC kernel not available.
|
||||
|
||||
+++ Temperatures
|
||||
CPU temp = 42 [°C]
|
||||
Fan speed = (not available)
|
||||
|
||||
+++ File System
|
||||
/proc/sys/vm/laptop_mode = 2
|
||||
/proc/sys/vm/dirty_writeback_centisecs = 6000
|
||||
/proc/sys/vm/dirty_expire_centisecs = 6000
|
||||
/proc/sys/vm/dirty_ratio = 20
|
||||
/proc/sys/vm/dirty_background_ratio = 10
|
||||
|
||||
+++ Storage Devices
|
||||
/dev/sda:
|
||||
Model = WDC WD10SPCX-24HWST1
|
||||
Firmware = 02.01A02
|
||||
APM Level = 128
|
||||
Status = active/idle
|
||||
Scheduler = mq-deadline
|
||||
|
||||
Runtime PM: control = on, autosuspend_delay = (not available)
|
||||
|
||||
SMART info:
|
||||
4 Start_Stop_Count = 18787
|
||||
5 Reallocated_Sector_Ct = 0
|
||||
9 Power_On_Hours = 606 [h]
|
||||
12 Power_Cycle_Count = 1792
|
||||
193 Load_Cycle_Count = 25777
|
||||
194 Temperature_Celsius = 31 [°C]
|
||||
|
||||
|
||||
+++ AHCI Link Power Management (ALPM)
|
||||
/sys/class/scsi_host/host0/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host1/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host2/link_power_management_policy = med_power_with_dipm
|
||||
/sys/class/scsi_host/host3/link_power_management_policy = med_power_with_dipm
|
||||
|
||||
+++ AHCI Host Controller Runtime Power Management
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata1/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata2/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata3/power/control = on
|
||||
/sys/bus/pci/devices/0000:00:17.0/ata4/power/control = on
|
||||
|
||||
+++ PCIe Active State Power Management
|
||||
/sys/module/pcie_aspm/parameters/policy = powersave
|
||||
|
||||
+++ Intel Graphics
|
||||
/sys/module/i915/parameters/enable_dc = -1 (use per-chip default)
|
||||
/sys/module/i915/parameters/enable_fbc = 1 (enabled)
|
||||
/sys/module/i915/parameters/enable_psr = 0 (disabled)
|
||||
/sys/module/i915/parameters/modeset = -1 (use per-chip default)
|
||||
|
||||
+++ Wireless
|
||||
bluetooth = on
|
||||
wifi = on
|
||||
wwan = none (no device)
|
||||
|
||||
hci0(btusb) : bluetooth, not connected
|
||||
wlp8s0(iwlwifi) : wifi, connected, power management = on
|
||||
|
||||
+++ Audio
|
||||
/sys/module/snd_hda_intel/parameters/power_save = 1
|
||||
/sys/module/snd_hda_intel/parameters/power_save_controller = Y
|
||||
|
||||
+++ Runtime Power Management
|
||||
Device blacklist = (not configured)
|
||||
Driver blacklist = amdgpu nouveau nvidia radeon pcieport
|
||||
|
||||
/sys/bus/pci/devices/0000:00:00.0/power/control = auto (0x060000, Host bridge, skl_uncore)
|
||||
/sys/bus/pci/devices/0000:00:01.0/power/control = auto (0x060400, PCI bridge, pcieport)
|
||||
/sys/bus/pci/devices/0000:00:02.0/power/control = auto (0x030000, VGA compatible controller, i915)
|
||||
|
||||
......
|
||||
|
||||
+++ USB
|
||||
Autosuspend = disabled
|
||||
Device whitelist = (not configured)
|
||||
Device blacklist = (not configured)
|
||||
Bluetooth blacklist = disabled
|
||||
Phone blacklist = disabled
|
||||
WWAN blacklist = enabled
|
||||
|
||||
Bus 002 Device 001 ID 1d6b:0003 control = auto, autosuspend_delay_ms = 0 -- Linux Foundation 3.0 root hub (hub)
|
||||
Bus 001 Device 003 ID 174f:14e8 control = auto, autosuspend_delay_ms = 2000 -- Syntek (uvcvideo)
|
||||
Bus 001 Device 002 ID 17ef:6053 control = on, autosuspend_delay_ms = 2000 -- Lenovo (usbhid)
|
||||
Bus 001 Device 004 ID 8087:0a2b control = auto, autosuspend_delay_ms = 2000 -- Intel Corp. (btusb)
|
||||
Bus 001 Device 001 ID 1d6b:0002 control = auto, autosuspend_delay_ms = 0 -- Linux Foundation 2.0 root hub (hub)
|
||||
|
||||
+++ Battery Status
|
||||
/sys/class/power_supply/BAT0/manufacturer = SMP
|
||||
/sys/class/power_supply/BAT0/model_name = L14M4P23
|
||||
/sys/class/power_supply/BAT0/cycle_count = (not supported)
|
||||
/sys/class/power_supply/BAT0/energy_full_design = 60000 [mWh]
|
||||
/sys/class/power_supply/BAT0/energy_full = 51690 [mWh]
|
||||
/sys/class/power_supply/BAT0/energy_now = 50140 [mWh]
|
||||
/sys/class/power_supply/BAT0/power_now = 12185 [mW]
|
||||
/sys/class/power_supply/BAT0/status = Discharging
|
||||
|
||||
Charge = 97.0 [%]
|
||||
Capacity = 86.2 [%]
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/tlp-increase-optimize-linux-laptop-battery-life/
|
||||
|
||||
作者:[Magesh Maruthamuthu][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.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/check-laptop-battery-status-and-charging-state-in-linux-terminal/
|
||||
[2]: https://www.2daygeek.com/powertop-monitors-laptop-battery-usage-linux/
|
||||
[3]: https://www.2daygeek.com/monitor-laptop-battery-charging-state-linux/
|
||||
[4]: https://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html
|
||||
[5]: https://www.2daygeek.com/category/package-management/
|
||||
[6]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[7]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[8]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[9]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[10]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[11]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
@ -0,0 +1,212 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (bodhix)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10804-1.html)
|
||||
[#]: subject: (How to Restart a Network in Ubuntu [Beginner’s Tip])
|
||||
[#]: via: (https://itsfoss.com/restart-network-ubuntu)
|
||||
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
|
||||
|
||||
Linux 初学者:如何在 Ubuntu 中重启网络
|
||||
======
|
||||
|
||||
你[是否正在使用基于 Ubuntu 的系统,然后发现无法连接网络][1]?你一定会很惊讶,很多的问题都可以简单地通过重启服务解决。
|
||||
|
||||
在这篇文章中,我会介绍在 Ubuntu 或者其他 Linux 发行版中重启网络的几种方法,你可以根据自身需要选择对应的方法。这些方法基本分为两类:
|
||||
|
||||
![Ubuntu Restart Network][2]
|
||||
|
||||
### 通过命令行方式重启网络
|
||||
|
||||
如果你使用的 Ubuntu 服务器版,那么你已经在使用命令行终端了。如果你使用的是桌面版,那么你可以通过快捷键 `Ctrl+Alt+T` [Ubuntu 键盘快捷键][3] 打开命令行终端。
|
||||
|
||||
在 Ubuntu 中,有多个命令可以重启网络。这些命令,一部分或者说大部分,也适用于在 Debian 或者其他的 Linux 发行版中重启网络。
|
||||
|
||||
#### 1、network manager 服务
|
||||
|
||||
这是通过命令行方式重启网络最简单的方法。它相当于是通过图形化界面重启网络(重启 Network-Manager 服务)。
|
||||
|
||||
```
|
||||
sudo service network-manager restart
|
||||
```
|
||||
|
||||
此时,网络图标会消失一会儿然后重新显示。
|
||||
|
||||
#### 2、systemd
|
||||
|
||||
`service` 命令仅仅是这个方式的一个封装(同样的也是 init.d 系列脚本和 Upstart 相关命令的封装)。`systemctl` 命令的功能远多于 `service` 命令。通常我更喜欢使用这个命令。
|
||||
|
||||
```
|
||||
sudo systemctl restart NetworkManager.service
|
||||
```
|
||||
|
||||
这时,网络图标又会消失一会儿。 如果你想了解 `systemctl` 的其他选项, 可以参考 man 帮助文档。
|
||||
|
||||
#### 3、nmcli
|
||||
|
||||
这是 Linux 上可以管理网络的另一个工具。这是一个功能强大而且实用的工具。很多系统管理员都喜欢使用该工具,因为它非常容易使用。
|
||||
|
||||
这种方法有两个操作步骤:关闭网络,再开启网络。
|
||||
|
||||
```
|
||||
sudo nmcli networking off
|
||||
```
|
||||
|
||||
这样就会关闭网络,网络图标会消失。接下来,再开启网络:
|
||||
|
||||
```
|
||||
sudo nmcli networking on
|
||||
```
|
||||
|
||||
你可以通过 man 帮助文档了解 nmcli 的更多用法。
|
||||
|
||||
#### 4、ifup & ifdown
|
||||
|
||||
这两个命令直接操作网口,切换网口是否可以收发包的状态。这是 [Linux 中最应该了解的网络命令][4] 之一。
|
||||
|
||||
使用 `ifdown` 关闭所有网口,再使用 `ifup` 重新启用网口。
|
||||
|
||||
通常推荐的做法是将这两个命令一起使用。
|
||||
|
||||
```
|
||||
sudo ifdown -a && sudo ifup -a
|
||||
```
|
||||
|
||||
注意:这种方法不会让网络图标从系统托盘中消失,另外,各种网络连接也会断。
|
||||
|
||||
#### 补充工具: nmtui
|
||||
|
||||
这是系统管理员们常用的另外一种方法。它是在命令行终端中管理网络的文本菜单工具。
|
||||
|
||||
```
|
||||
nmtui
|
||||
```
|
||||
|
||||
打开如下菜单:
|
||||
|
||||
![nmtui Menu][5]
|
||||
|
||||
注意:在 nmtui 中,可以通过 `up` 和 `down` 方向键选择选项。
|
||||
|
||||
选择 “Activate a connection”:
|
||||
|
||||
![nmtui Menu Select "Activate a connection"][6]
|
||||
|
||||
按下回车键,打开 “connections” 菜单。
|
||||
|
||||
![nmtui Connections Menu][7]
|
||||
|
||||
接下来,选择前面带星号(*)的网络。在这个例子中,就是 MGEO72。
|
||||
|
||||
![Select your connection in the nmtui connections menu.][8]
|
||||
|
||||
按下回车键。 这就将“停用”你的网络连接。
|
||||
|
||||
![nmtui Connections Menu with no active connection][9]
|
||||
|
||||
选择你要连接的网络:
|
||||
|
||||
![Select the connection you want in the nmtui connections menu.][10]
|
||||
|
||||
按下回车键。这样就重新激活了所选择的网络连接。
|
||||
|
||||
![nmtui Connections Menu][11]
|
||||
|
||||
按下 `Tab` 键两次,选择 “Back”:
|
||||
|
||||
![Select "Back" in the nmtui connections menu.][12]
|
||||
|
||||
按下回车键,回到 nmtui 的主菜单。
|
||||
|
||||
![nmtui Main Menu][13]
|
||||
|
||||
选择 “Quit” :
|
||||
|
||||
![nmtui Quit Main Menu][14]
|
||||
|
||||
退出该界面,返回到命令行终端。
|
||||
|
||||
就这样,你已经成功重启网络了。
|
||||
|
||||
### 通过图形化界面重启网络
|
||||
|
||||
显然,这是 Ubuntu 桌面版用户重启网络最简单的方法。如果这个方法不生效,你可以尝试使用前文提到的命令行方式重启网络。
|
||||
|
||||
NM 小程序是 [NetworkManager][15] 的系统托盘程序标志。我们将使用它来重启网络。
|
||||
|
||||
首先,查看顶部状态栏。你会在系统托盘找到一个网络图标 (因为我使用 Wi-Fi,所以这里是一个 Wi-Fi 图标)。
|
||||
|
||||
接下来,点击该图标(也可以点击音量图标或电池图标)。打开菜单。选择 “Turn Off” 关闭网络。
|
||||
|
||||
![Restart network in Ubuntu][16]
|
||||
|
||||
网络图标会在状态栏中消失,这表示你已经成功关闭网络了。
|
||||
|
||||
再次点击系统托盘重新打开菜单,选择 “Turn On”,重新开启网络。
|
||||
|
||||
![Restarting network in Ubuntu][17]
|
||||
|
||||
恭喜!你现在已经重启你的网络了。
|
||||
|
||||
#### 其他提示:刷新可用网络列表
|
||||
|
||||
如果你已经连接上一个网络,但是你想连接到另外一个网络,你如何刷新 WiFi 列表,查找其他可用的网络呢?我来向你展示一下。
|
||||
|
||||
Ubuntu 没有可以直接 “刷新 WiFi 网络” 的选项,它有点隐蔽。
|
||||
|
||||
你需要再次打开配置菜单,然后点击 “Select Network” 。
|
||||
|
||||
![Refresh wifi network list in Ubuntu][18]
|
||||
|
||||
选择对应的网络修改你的 WiFi 连接。
|
||||
|
||||
你无法马上看到可用的无线网络列表。打开网络列表之后,大概需要 5 秒才会显示其它可用的无线网络。
|
||||
|
||||
![Select another wifi network in Ubuntu][19]
|
||||
|
||||
等待大概 5 秒钟,看到其他可用的网络。
|
||||
|
||||
现在,你就可以选择你想要连接的网络,点击连接。这样就完成了。
|
||||
|
||||
### 总结
|
||||
|
||||
重启网络连接是每个 Linux 用户在使用过程中必须经历的事情。
|
||||
|
||||
我们希望这些方法可以帮助你处理这样的问题!
|
||||
|
||||
你是如何重启或管理你的网络的?我们是否还有遗漏的?请在下方留言。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/restart-network-ubuntu
|
||||
|
||||
作者:[Sergiu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[bodhix](https://github.com/bodhix)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/sergiu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/fix-no-wireless-network-ubuntu/
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/ubuntu-restart-network.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/ubuntu-shortcuts/
|
||||
[4]: https://itsfoss.com/basic-linux-networking-commands/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu.png?fit=800%2C602&ssl=1
|
||||
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu_select_option.png?fit=800%2C579&ssl=1
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_on.png?fit=800%2C585&ssl=1
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_select_connection_on.png?fit=800%2C576&ssl=1
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_off.png?fit=800%2C572&ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_select_connection_off.png?fit=800%2C566&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_on-1.png?fit=800%2C585&ssl=1
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_back.png?fit=800%2C585&ssl=1
|
||||
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu_select_option-1.png?fit=800%2C579&ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_menu_quit.png?fit=800%2C580&ssl=1
|
||||
[15]: https://wiki.gnome.org/Projects/NetworkManager
|
||||
[16]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/restart-network-ubuntu-1.jpg?resize=800%2C400&ssl=1
|
||||
[17]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/restart-network-ubuntu-2.jpg?resize=800%2C400&ssl=1
|
||||
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/select-wifi-network-ubuntu.jpg?resize=800%2C400&ssl=1
|
||||
[19]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/select-wifi-network-ubuntu-1.jpg?resize=800%2C400&ssl=1
|
||||
[20]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/ubuntu-restart-network.png?fit=800%2C450&ssl=1
|
@ -0,0 +1,123 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "zgj1024"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-10834-1.html"
|
||||
[#]: subject: "Why DevOps is the most important tech strategy today"
|
||||
[#]: via: "https://opensource.com/article/19/3/devops-most-important-tech-strategy"
|
||||
[#]: author: "Kelly Albrecht https://opensource.com/users/ksalbrecht"
|
||||
|
||||
为何 DevOps 是如今最重要的技术策略
|
||||
======
|
||||
|
||||
> 消除一些关于 DevOps 的疑惑。
|
||||
|
||||
![CICD with gears][1]
|
||||
|
||||
很多人初学 [DevOps][2] 时,看到它其中一个结果就问这个是如何得来的。其实理解这部分 Devops 的怎样实现并不重要,重要的是——理解(使用) DevOps 策略的原因——这是做一个行业的领导者还是追随者的差别。
|
||||
|
||||
你可能会听过些 Devops 的难以置信的成果,例如生产环境非常有弹性,就算是有个“<ruby>[癫狂的猴子][3]<rt>Chaos Monkey</rt></ruby>)跳来跳去将不知道哪个插头随便拔下,每天仍可以处理数千个发布。这是令人印象深刻的,但就其本身而言,这是一个 DevOps 的证据不足的案例,其本质上会被一个[反例][4]困扰:DevOps 环境有弹性是因为严重的故障还没有被观测到。
|
||||
|
||||
有很多关于 DevOps 的疑惑,并且许多人还在尝试弄清楚它的意义。下面是来自我 LinkedIn Feed 中的某个人的一个案例:
|
||||
|
||||
> 最近我参加一些 #DevOps 的交流会,那里一些演讲人好像在倡导 #敏捷开发是 DevOps 的子集。不知为何,我的理解恰恰相反。
|
||||
>
|
||||
> 能听一下你们的想法吗?你认为敏捷开发和 DevOps 之间是什么关系呢?
|
||||
>
|
||||
> 1. DevOps 是敏捷开发的子集
|
||||
> 2. 敏捷开发是 DevOps 的子集
|
||||
> 3. DevOps 是敏捷开发的扩展,从敏捷开发结束的地方开始
|
||||
> 4. DevOps 是敏捷开发的新版本
|
||||
|
||||
科技行业的专业人士在那篇 LinkedIn 的帖子上表达了各种各样的答案,你会怎样回复呢?
|
||||
|
||||
### DevOps 源于精益和敏捷
|
||||
|
||||
如果我们从亨利福特的战略和丰田生产系统对福特车型的改进(的历史)开始, DevOps 就更有意义了。精益制造就诞生在那段历史中,人们对精益制作进行了良好的研究。James P. Womack 和 Daniel T. Jones 将精益思维([Lean Thinking][5])提炼为五个原则:
|
||||
|
||||
1. 指明客户所需的价值
|
||||
2. 确定提供该价值的每个产品的价值流,并对当前提供该价值所需的所有浪费步骤提起挑战
|
||||
3. 使产品通过剩余的增值步骤持续流动
|
||||
4. 在可以连续流动的所有步骤之间引入拉力
|
||||
5. 管理要尽善尽美,以便为客户服务所需的步骤数量和时间以及信息量持续下降
|
||||
|
||||
精益致力于持续消除浪费并增加客户的价值流动。这很容易识别并明白精益的核心原则:单一流。我们可以做一些游戏去了解为何同一时间移动单个比批量移动要快得多。其中的两个游戏是[硬币游戏][6]和[飞机游戏][7]。在硬币游戏中,如果一批 20 个硬币到顾客手中要用 2 分钟,顾客等 2 分钟后能拿到整批硬币。如果一次只移动一个硬币,顾客会在 5 秒内得到第一枚硬币,并会持续获得硬币,直到在大约 25 秒后第 20 个硬币到达。(LCTT 译注:有相关的视频的)
|
||||
|
||||
这是巨大的不同,但是不是生活中的所有事都像硬币游戏那样简单并可预测的。这就是敏捷的出现的原因。我们当然看到了高效绩敏捷团队的精益原则,但这些团队需要的不仅仅是精益去做他们要做的事。
|
||||
|
||||
为了能够处理典型的软件开发任务的不可预见性和变化,敏捷开发的方法论会将重点放在意识、审议、决策和行动上,以便在不断变化的现实中调整。例如,敏捷框架(如 srcum)通过每日站立会议和冲刺评审会议等仪式提高意识。如果 scrum 团队意识到新的事实,框架允许并鼓励他们在必要时及时调整路线。
|
||||
|
||||
要使团队做出这些类型的决策,他们需要高度信任的环境中的自我组织能力。以这种方式工作的高效绩敏捷团队在不断调整的同时实现快速的价值流,消除错误方向上的浪费。
|
||||
|
||||
### 最佳批量大小
|
||||
|
||||
要了解 DevOps 在软件开发中的强大功能,这会帮助我们理解批处理大小的经济学。请考虑以下来自Donald Reinertsen 的[产品开发流程原则][8]的U曲线优化示例:
|
||||
|
||||
![U-curve optimization illustration of optimal batch size][9]
|
||||
|
||||
这可以类比杂货店购物来解释。假设你需要买一些鸡蛋,而你住的地方离商店只有 30 分钟的路程。买一个鸡蛋(图中最左边)意味着每次要花 30 分钟的路程,这就是你的*交易成本*。*持有成本*可能是鸡蛋变质和在你的冰箱中持续地占用空间。*总成本*是*交易成本*加上你的*持有成本*。这个 U 型曲线解释了为什么对大部分人来说,一次买一打鸡蛋是他们的*最佳批量大小*。如果你就住在商店的旁边,步行到那里不会花费你任何的时候,你可能每次只会买一小盒鸡蛋,以此来节省冰箱的空间并享受新鲜的鸡蛋。
|
||||
|
||||
这 U 型优化曲线可以说明为什么在成功的敏捷转换中生产力会显著提高。考虑敏捷转换对组织决策的影响。在传统的分级组织中,决策权是集中的。这会导致较少的人做更大的决策。敏捷方法论会有效地降低组织决策中的交易成本,方法是将决策分散到最被人熟知的认识和信息的位置:跨越高度信任,自组织的敏捷团队。
|
||||
|
||||
下面的动画演示了降低事务成本后,最佳批量大小是如何向左移动。在更频繁地做出更快的决策方面,你不能低估组织的价值。
|
||||
|
||||
![U-curve optimization illustration][10]
|
||||
|
||||
### DevOps 适合哪些地方
|
||||
|
||||
自动化是 DevOps 最知名的事情之一。前面的插图非常详细地展示了自动化的价值。通过自动化,我们将交易成本降低到接近于零,实质上是可以免费进行测试和部署。这使我们可以利用越来越小的批量工作。较小批量的工作更容易理解、提交、测试、审查和知道何时能完成。这些较小的批量大小也包含较少的差异和风险,使其更易于部署,如果出现问题,可以进行故障排除和恢复。通过自动化与扎实的敏捷实践相结合,我们可以使我们的功能开发非常接近单件流程,从而快速、持续地为客户提供价值。
|
||||
|
||||
更传统地说,DevOps 被理解为一种打破开发团队和运营团队之间混乱局面的方法。在这个模型中,开发团队开发新的功能,而运营团队则保持系统的稳定和平稳运行。摩擦的发生是因为开发过程中的新功能将更改引入到系统中,从而增加了停机的风险,运营团队并不认为要对此负责,但无论如何都必须处理这一问题。DevOps 不仅仅尝试让人们一起工作,更重要的是尝试在复杂的环境中安全地进行更频繁的更改。
|
||||
|
||||
我们可以看看 [Ron Westrum][11] 在有关复杂组织中实现安全性的研究。在研究为什么有些组织比其他组织更安全时,他发现组织的文化可以预测其安全性。他确定了三种文化:病态的、官僚主义的和生产式的。他发现病态的可以预测其安全性较低,而生产式文化被预测为更安全(例如,在他的主要研究领域中,飞机坠毁或意外住院死亡的数量要少得多)。
|
||||
|
||||
![Three types of culture identified by Ron Westrum][12]
|
||||
|
||||
高效的 DevOps 团队通过精益和敏捷的实践实现了一种生成性文化,这表明速度和安全性是互补的,或者说是同一个问题的两个方面。通过将决策和功能的最佳批量大小减少到非常小,DevOps 实现了更快的信息流和价值,同时消除了浪费并降低了风险。
|
||||
|
||||
与 Westrum 的研究一致,在提高安全性和可靠性的同时,变化也很容易发生。当一个敏捷的 DevOps 团队被信任做出自己的决定时,我们将获得 DevOps 目前最为人所知的工具和技术:自动化和持续交付。通过这种自动化,交易成本比以往任何时候都进一步降低,并且实现了近乎单一的精益流程,每天创造数千个决策和发布的潜力,正如我们在高效绩的 DevOps 组织中看到的那样
|
||||
|
||||
### 流动、反馈、学习
|
||||
|
||||
DevOps 并不止于此。我们主要讨论了 DevOps 实现了革命性的流程,但通过类似的努力可以进一步放大精益和敏捷实践,从而实现更快的反馈循环和更快的学习。在[DevOps手册][13] 中,作者除了详细解释快速流程外, DevOps 如何在整个价值流中实现遥测,从而获得快速且持续的反馈。此外,利用[精益求精的突破][14]和 scrum 的[回顾][15],高效的 DevOps 团队将不断推动学习和持续改进深入到他们的组织的基础,实现软件产品开发行业的精益制造革命。
|
||||
|
||||
### 从 DevOps 评估开始
|
||||
|
||||
利用 DevOps 的第一步是,经过大量研究或在 DevOps 顾问和教练的帮助下,对高效绩 DevOps 团队中始终存在的一系列维度进行评估。评估应确定需要改进的薄弱或不存在的团队规范。对评估的结果进行评估,以找到具有高成功机会的快速获胜焦点领域,从而产生高影响力的改进。快速获胜非常重要,能让团队获取解决更具挑战性领域所需的动力。团队应该产生可以快速尝试的想法,并开始关注 DevOps 转型。
|
||||
|
||||
一段时间后,团队应重新评估相同的维度,以衡量改进并确立新的高影响力重点领域,并再次采纳团队的新想法。一位好的教练将根据需要进行咨询、培训、指导和支持,直到团队拥有自己的持续改进方案,并通过不断地重新评估、试验和学习,在所有维度上实现近乎一致。
|
||||
|
||||
在本文的[第二部分][16]中,我们将查看 Drupal 社区中 DevOps 调查的结果,并了解最有可能找到快速获胜的位置。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/devops-most-important-tech-strategy
|
||||
|
||||
作者:[Kelly Albrecht][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zgj1024](https://github.com/zgj1024)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksalbrecht/users/brentaaronreed/users/wpschaub/users/wpschaub/users/ksalbrecht
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cicd_continuous_delivery_deployment_gears.png?itok=kVlhiEkc "CICD with gears"
|
||||
[2]: https://opensource.com/resources/devops
|
||||
[3]: https://github.com/Netflix/chaosmonkey
|
||||
[4]: https://en.wikipedia.org/wiki/Burden_of_proof_(philosophy)#Proving_a_negative
|
||||
[5]: https://www.amazon.com/dp/B0048WQDIO/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
|
||||
[6]: https://youtu.be/5t6GhcvKB8o?t=54
|
||||
[7]: https://www.shmula.com/paper-airplane-game-pull-systems-push-systems/8280/
|
||||
[8]: https://www.amazon.com/dp/B00K7OWG7O/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
|
||||
[9]: https://opensource.com/sites/default/files/uploads/batch_size_optimal_650.gif "U-curve optimization illustration of optimal batch size"
|
||||
[10]: https://opensource.com/sites/default/files/uploads/batch_size_650.gif "U-curve optimization illustration"
|
||||
[11]: https://en.wikipedia.org/wiki/Ron_Westrum
|
||||
[12]: https://opensource.com/sites/default/files/uploads/information_flow.png "Three types of culture identified by Ron Westrum"
|
||||
[13]: https://www.amazon.com/DevOps-Handbook-World-Class-Reliability-Organizations/dp/1942788002/ref=sr_1_3?keywords=DevOps+handbook&qid=1553197361&s=books&sr=1-3
|
||||
[14]: https://en.wikipedia.org/wiki/Kaizen
|
||||
[15]: https://www.scrum.org/resources/what-is-a-sprint-retrospective
|
||||
[16]: https://opensource.com/article/19/3/where-drupal-community-stands-devops-adoption
|
||||
[17]: https://events.drupal.org/seattle2019/sessions/devops-why-how-and-what
|
||||
[18]: https://events.drupal.org/seattle2019/bofs/devops-getting-started
|
||||
[19]: https://events.drupal.org/seattle2019
|
@ -0,0 +1,99 @@
|
||||
5 款适合程序员的开源字体
|
||||
======
|
||||
|
||||
> 编程字体有些在普通字体中没有的特点,这五种字体你可以看看。
|
||||
|
||||

|
||||
|
||||
什么是最好的编程字体呢?首先,你需要考虑到字体被设计出来的初衷可能并不相同。当选择一款用于休闲阅读的字体时,读者希望该字体的字母能够顺滑地衔接,提供一种轻松愉悦的体验。一款标准字体的每个字符,类似于拼图的一块,它需要被仔细的设计,从而与整个字体的其他部分融合在一起。
|
||||
|
||||
然而,在编写代码时,通常来说对字体的要求更具功能性。这也是为什么大多数程序员在选择时更偏爱使用固定宽度的等宽字体。选择一款带有容易分辨的数字和标点的字体在美学上令人愉悦;但它是否拥有满足你需求的版权许可也是非常重要的。
|
||||
|
||||
某些功能使得字体更适合编程。首先要清楚是什么使得等宽字体看上去井然有序。这里,让我们对比一下字母 `w` 和字母 `i`。当选择一款字体时,重要的是要考虑字母本身及周围的空白。在纸质的书籍和报纸中,有效地利用空间是极为重要的,为瘦小的 `i` 分配较小的空间,为宽大的字母 `w` 分配较大的空间是有意义的。
|
||||
|
||||
然而在终端中,你没有这些限制。每个字符享有相等的空间将非常有用。这么做的首要好处是你可以随意扫过一段代码来“估测”代码的长度。第二个好处是能够轻松地对齐字符和标点,高亮在视觉上更加明显。另外打印纸张上的等宽字体比均衡字体更加容易通过 OCR 识别。
|
||||
|
||||
在本篇文章中,我们将探索 5 款卓越的开源字体,使用它们来编程和写代码都非常理想。
|
||||
|
||||
### 1、Firacode:最佳整套编程字体
|
||||
|
||||
![FiraCode 示例][1]
|
||||
|
||||
*FiraCode, Andrew Lekashman*
|
||||
|
||||
在我们列表上的首款字体是 [FiraCode][3],一款真正符合甚至超越了其职责的编程字体。FiraCode 是 Fira 的扩展,而后者是由 Mozilla 委托设计的开源字体族。使得 FiraCode 与众不同的原因是它修改了在代码中常使用的一些符号的组合或连字,使得它看上去更具可读性。这款字体有几种不同的风格,特别是还包含 Retina 选项。你可以在它的 [GitHub][3] 主页中找到它被使用到多种编程语言中的例子。
|
||||
|
||||
![FiraCode compared to Fira Mono][2]
|
||||
|
||||
*FiraCode 与 Fira Mono 的对比,[Nikita Prokopov][3],源自 GitHub*
|
||||
|
||||
### 2、Inconsolata:优雅且由卓越设计者创造
|
||||
|
||||
![Inconsolata 示例][4]
|
||||
|
||||
*Inconsolata, Andrew Lekashman*
|
||||
|
||||
[Inconsolata][5] 是最为漂亮的等宽字体之一。从 2006 年开始它便一直是一款开源和可免费获取的字体。它的创造者 Raph Levien 在设计 Inconsolata 时秉承的一个基本原则是:等宽字体并不应该那么糟糕。使得 Inconsolata 如此优秀的两个原因是:对于 `0` 和 `o` 这两个字符它们有很大的不同,另外它还特别地设计了标点符号。
|
||||
|
||||
### 3、DejaVu Sans Mono:许多 Linux 发行版的标准配置,庞大的字形覆盖率
|
||||
|
||||
![DejaVu Sans Mono example][6]
|
||||
|
||||
*DejaVu Sans Mono, Andrew Lekashman*
|
||||
|
||||
受在 GNOME 中使用的带有版权和闭源的 Vera 字体的启发,[DejaVu Sans Mono][7] 是一个非常受欢迎的编程字体,几乎在每个现代的 Linux 发行版中都带有它。在 Book Variant 风格下 DejaVu 拥有惊人的 3310 个字形,相比于一般的字体,它们含有 100 个左右的字形。在工作中你将不会出现缺少某些字符的情况,它覆盖了 Unicode 的绝大部分,并且一直在活跃地增长着。
|
||||
|
||||
### 4、Source Code Pro:优雅、可读性强,由 Adobe 中一个小巧但天才的团队打造
|
||||
|
||||
![Source Code Pro example][8]
|
||||
|
||||
*Source Code Pro, Andrew Lekashman*
|
||||
|
||||
由 Paul Hunt 和 Teo Tuominen 设计,[Source Code Pro][9] 是[由 Adobe 创造的][10],成为了它的首款开源字体。Source Code Pro 值得注意的地方在于它极具可读性,且对于容易混淆的字符和标点,它有着非常好的区分度。Source Code Pro 也是一个字体族,有 7 中不同的风格:Extralight、Light、Regular、Medium、Semibold、Bold 和 Black,每种风格都还有斜体变体。
|
||||
|
||||
![Differentiating potentially confusable characters][11]
|
||||
|
||||
*潜在易混淆的字符之间的区别,[Paul D. Hunt][10] 源自 Adobe Typekit 博客。*
|
||||
|
||||
![Metacharacters with special meaning in computer languages][12]
|
||||
|
||||
*在计算机领域中有特别含义的特殊元字符, [Paul D. Hunt][10] 源自 Adobe Typekit 博客。*
|
||||
|
||||
### 5、Noto Mono:巨量的语言覆盖率,由 Google 中的一个大团队打造
|
||||
|
||||
![Noto Mono example][13]
|
||||
|
||||
*Noto Mono, Andrew Lekashman*
|
||||
|
||||
在我们列表上的最后一款字体是 [Noto Mono][14],这是 Google 打造的庞大 Note 字体族中的等宽版本。尽管它并不是专为编程所设计,但它在 209 种语言(包括 emoji 颜文字!)中都可以使用,并且一直在维护和更新。该项目非常庞大,是 Google 宣称 “组织全世界信息” 的使命的延续。假如你想更多地了解它,可以查看这个绝妙的[关于这些字体的视频][15]。
|
||||
|
||||
### 选择合适的字体
|
||||
|
||||
无论你选择那个字体,你都有可能在每天中花费数小时面对它,所以请确保它在审美和哲学层面上与你产生共鸣。选择正确的开源字体是确保你拥有最佳生产环境的一个重要部分。这些字体都是很棒的选择,每个都具有让它脱颖而出的功能强大的特性。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/11/how-select-open-source-programming-font
|
||||
|
||||
作者:[Andrew Lekashman][a]
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com
|
||||
[1]:https://opensource.com/sites/default/files/u128651/firacode.png (FiraCode example)
|
||||
[2]:https://opensource.com/sites/default/files/u128651/firacode2.png (FiraCode compared to Fira Mono)
|
||||
[3]:https://github.com/tonsky/FiraCode
|
||||
[4]:https://opensource.com/sites/default/files/u128651/inconsolata.png (Inconsolata example)
|
||||
[5]:http://www.levien.com/type/myfonts/inconsolata.html
|
||||
[6]:https://opensource.com/sites/default/files/u128651/dejavu_sans_mono.png (DejaVu Sans Mono example)
|
||||
[7]:https://dejavu-fonts.github.io/
|
||||
[8]:https://opensource.com/sites/default/files/u128651/source_code_pro.png (Source Code Pro example)
|
||||
[9]:https://github.com/adobe-fonts/source-code-pro
|
||||
[10]:https://blog.typekit.com/2012/09/24/source-code-pro/
|
||||
[11]:https://opensource.com/sites/default/files/u128651/source_code_pro2.png (Differentiating potentially confusable characters)
|
||||
[12]:https://opensource.com/sites/default/files/u128651/source_code_pro3.png (Metacharacters with special meaning in computer languages)
|
||||
[13]:https://opensource.com/sites/default/files/u128651/noto.png (Noto Mono example)
|
||||
[14]:https://www.google.com/get/noto/#mono-mono
|
||||
[15]:https://www.youtube.com/watch?v=AAzvk9HSi84
|
94
published/201904/20171226 The shell scripting trap.md
Normal file
94
published/201904/20171226 The shell scripting trap.md
Normal file
@ -0,0 +1,94 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (jdh8383)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10772-1.html)
|
||||
[#]: subject: (The shell scripting trap)
|
||||
[#]: via: (https://arp242.net/weblog/shell-scripting-trap.html)
|
||||
[#]: author: (Martin Tournoij https://arp242.net/)
|
||||
|
||||
Shell 脚本编程陷阱
|
||||
======
|
||||
|
||||
Shell 脚本很棒,你可以非常轻松地写出有用的东西来。甚至像是下面这个傻瓜式的命令:
|
||||
|
||||
```
|
||||
# 用含有 Go 的词汇起名字:
|
||||
$ grep -i ^go /usr/share/dict/* | cut -d: -f2 | sort -R | head -n1
|
||||
goldfish
|
||||
```
|
||||
|
||||
如果用其他编程语言,就需要花费更多的脑力,用多行代码实现,比如用 Ruby 的话:
|
||||
|
||||
```
|
||||
puts(Dir['/usr/share/dict/*-english'].map do |f|
|
||||
File.open(f)
|
||||
.readlines
|
||||
.select { |l| l[0..1].downcase == 'go' }
|
||||
end.flatten.sample.chomp)
|
||||
```
|
||||
|
||||
Ruby 版本的代码虽然不是那么长,也并不复杂。但是 shell 版是如此简单,我甚至不用实际测试就可以确保它是正确的。而 Ruby 版的我就没法确定它不会出错了,必须得测试一下。而且它要长一倍,看起来也更复杂。
|
||||
|
||||
这就是人们使用 Shell 脚本的原因,它简单却实用。下面是另一个例子:
|
||||
|
||||
```
|
||||
curl https://nl.wikipedia.org/wiki/Lijst_van_Nederlandse_gemeenten |
|
||||
grep '^<li><a href=' |
|
||||
sed -r 's|<li><a href="/wiki/.+" title=".+">(.+)</a>.*</li>|\1|' |
|
||||
grep -Ev '(^Tabel van|^Lijst van|Nederland)'
|
||||
```
|
||||
|
||||
这个脚本可以从维基百科上获取荷兰基层政权的列表。几年前我写了这个临时的脚本,用来快速生成一个数据库,到现在它仍然可以正常运行,当时写它并没有花费我多少精力。但要用 Ruby 完成同样的功能则会麻烦得多。
|
||||
|
||||
---
|
||||
|
||||
现在来说说 shell 的缺点吧。随着代码量的增加,你的脚本会变得越来越难以维护,但你也不会想用别的语言重写一遍,因为你已经在这个 shell 版上花费了很多时间。
|
||||
|
||||
我把这种情况称为“Shell 脚本编程陷阱”,这是[沉没成本谬论][1]的一种特例(LCTT 译注:“沉没成本谬论”是一个经济学概念,可以简单理解为,对已经投入的成本可能被浪费而念念不忘)。
|
||||
|
||||
实际上许多脚本会增长到超出预期的大小,你经常会花费过多的时间来“修复某个 bug”,或者“添加一个小功能”。如此循环往复,让人头大。
|
||||
|
||||
如果你从一开始就使用 Python、Ruby 或是其他类似的语言来写这个程序,你可能会在写第一版的时候多花些时间,但以后维护起来就容易很多,bug 也肯定会少很多。
|
||||
|
||||
以我的 [packman.vim][2] 脚本为例。它起初只包含一个简单的用来遍历所有目录的 `for` 循环,外加一个 `git pull`,但在这之后就刹不住车了,它现在有 200 行左右的代码,这肯定不能算是最复杂的脚本,但假如我一上来就按计划用 Go 来编写它的话,那么增加一些像“打印状态”或者“从配置文件里克隆新的 git 库”这样的功能就会轻松很多;添加“并行克隆”的支持也几乎不算个事儿了,而在 shell 脚本里却很难实现(尽管不是不可能)。事后看来,我本可以节省时间,并且获得更好的结果。
|
||||
|
||||
出于类似的原因,我很后悔写出了许多这样的 shell 脚本,而我在 2018 年的新年誓言就是不要再犯类似的错误了。
|
||||
|
||||
### 附录:问题汇总
|
||||
|
||||
需要指出的是,shell 编程的确存在一些实际的限制。下面是一些例子:
|
||||
|
||||
* 在处理一些包含“空格”或者其他“特殊”字符的文件名时,需要特别注意细节。绝大多数脚本都会犯错,即使是那些经验丰富的作者(比如我)编写的脚本,因为太容易写错了,[只添加引号是不够的][3]。
|
||||
* 有许多所谓“正确”和“错误”的做法。你应该用 `which` 还是 `command`?该用 `$@` 还是 `$*`,是不是得加引号?你是该用 `cmd $arg` 还是 `cmd "$arg"`?等等等等。
|
||||
* 你没法在变量里存储空字节(0x00);shell 脚本处理二进制数据很麻烦。
|
||||
* 虽然你可以非常快速地写出有用的东西,但实现更复杂的算法则要痛苦许多,即使用 ksh/zsh/bash 扩展也是如此。我上面那个解析 HTML 的脚本临时用用是可以的,但你真的不会想在生产环境中使用这种脚本。
|
||||
* 很难写出跨平台的通用型 shell 脚本。`/bin/sh` 可能是 `dash` 或者 `bash`,不同的 shell 有不同的运行方式。外部工具如 `grep`、`sed` 等,不一定能支持同样的参数。你能确定你的脚本可以适用于 Linux、macOS 和 Windows 的所有版本吗(无论是过去、现在还是将来)?
|
||||
* 调试 shell 脚本会很难,特别是你眼中的语法可能会很快变得记不清了,并不是所有人都熟悉 shell 编程的语境。
|
||||
* 处理错误会很棘手(检查 `$?` 或是 `set -e`),排查一些超过“出了个小错”级别的复杂错误几乎是不可能的。
|
||||
* 除非你使用了 `set -u`,变量未定义将不会报错,而这会导致一些“搞笑事件”,比如 `rm -r ~/$undefined` 会删除用户的整个家目录([瞅瞅 Github 上的这个悲剧][4])。
|
||||
* 所有东西都是字符串。一些 shell 引入了数组,能用,但是语法非常丑陋和费解。带分数的数字运算仍然难以应付,并且依赖像 `bc` 或 `dc` 这样的外部工具(`$(( .. ))` 这种方式只能对付一下整数)。
|
||||
|
||||
**反馈**
|
||||
|
||||
你可以发邮件到 [martin@arp242.net][5],或者[在 GitHub 上创建 issue][6] 来向我反馈,提问等。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://arp242.net/weblog/shell-scripting-trap.html
|
||||
|
||||
作者:[Martin Tournoij][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[jdh8383](https://github.com/jdh8383)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://arp242.net/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://youarenotsosmart.com/2011/03/25/the-sunk-cost-fallacy/
|
||||
[2]: https://github.com/Carpetsmoker/packman.vim
|
||||
[3]: https://dwheeler.com/essays/filenames-in-shell.html
|
||||
[4]: https://github.com/ValveSoftware/steam-for-linux/issues/3671
|
||||
[5]: mailto:martin@arp242.net
|
||||
[6]: https://github.com/Carpetsmoker/arp242.net/issues/new
|
@ -0,0 +1,173 @@
|
||||
12 个最佳 GNOME(GTK)主题
|
||||
======
|
||||
|
||||
> 让我们来看一些漂亮的 GTK 主题,你不仅可以用在 Ubuntu 上,也可以用在其它使用 GNOME 的 Linux 发行版上。
|
||||
|
||||
对于我们这些使用 Ubuntu 的人来说,默认的桌面环境从 Unity 变成了 Gnome 使得主题和定制变得前所未有的简单。Gnome 有个相当大的定制用户社区,其中不乏可供用户选择的漂亮的 GTK 主题。最近几个月,我不断找到了一些喜欢的主题。我相信这些是你所能找到的最好的主题之一了。
|
||||
|
||||
### Ubuntu 和其它 Linux 发行版的最佳主题
|
||||
|
||||
这不是一个详细清单,可能不包括一些你已经使用和喜欢的主题,但希望你能至少找到一个能让你喜爱的没见过的主题。所有这里提及的主题都可以工作在 Gnome 3 上,不管是 Ubuntu 还是其它 Linux 发行版。有一些主题的屏幕截屏我没有,所以我从官方网站上找到了它们的图片。
|
||||
|
||||
在这里列出的主题没有特别的次序。
|
||||
|
||||
但是,在你看这些最好的 GNOME 主题前,你应该学习一下 [如何在 Ubuntu GNOME 中安装主题][1]。
|
||||
|
||||
#### 1、Arc-Ambiance
|
||||
|
||||
![][2]
|
||||
|
||||
Arc 和 Arc 变体主题已经出现了相当长的时间,普遍认为它们是最好的主题之一。在这个示例中,我选择了 Arc-Ambiance ,因为它是 Ubuntu 中的默认 Ambiance 主题。
|
||||
|
||||
我是 Arc 主题和默认 Ambiance 主题的粉丝,所以不用说,当我遇到一个融合了两者优点的主题,我不禁长吸了一口气。如果你是 Arc 主题的粉丝,但不是这个特定主题的粉丝,Gnome 的外观上当然还有适合你口味的大量的选择。
|
||||
|
||||
- [下载 Arc-Ambiance 主题][3]
|
||||
|
||||
#### 2、Adapta Colorpack
|
||||
|
||||
![][4]
|
||||
|
||||
Adapta 主题是我所见过的最喜欢的扁平主题之一。像 Arc 一样,Adapata 被很多 Linux 用户广泛采用。我选择这个配色包,是因为一次下载你就有数个可选择的配色方案。事实上,有 19 个配色方案可以选择,是的,你没看错,19 个呢!
|
||||
|
||||
所以,如果你是如今常见的扁平风格/<ruby>材料设计风格<rt>Material Design Language</rt></ruby>的粉丝,那么,在这个主题包中很可能至少有一个能满足你喜好的变体。
|
||||
|
||||
- [下载 Adapta Colorpack 主题][5]
|
||||
|
||||
#### 3、Numix Collection
|
||||
|
||||
![][6]
|
||||
|
||||
啊,Numix! 让我想起了我们一起度过的那些年!对于那些在过去几年装点过桌面环境的人来说,你肯定在某个时间点上遇到过 Numix 主题或图标包。Numix 可能是我爱上的第一个 Linux 现代主题,现在我仍然爱它。虽然经过这些年,但它仍然魅力不失。
|
||||
|
||||
灰色色调贯穿主题,尤其是默认的粉红色高亮,带来了真正干净而完整的体验。你可能很难找到一个像 Numix 一样精美的主题包。而且在这个主题包中,你还有很多可供选择的余地,简直不要太棒了!
|
||||
|
||||
- [下载 Numix Collection 主题][7]
|
||||
|
||||
#### 4、Hooli
|
||||
|
||||
![][8]
|
||||
|
||||
Hooli 是一个已经出现了一段时间的主题,但是我最近才偶然发现它。我是很多扁平主题的粉丝,但是通常不太喜欢材料设计风格的主题。Hooli 像 Adapta 一样吸取了那些设计风格,但是我认为它和其它的那些有所不同。绿色高亮是我对这个主题最喜欢的部分之一,并且,它在不冲击整个主题方面做的很好。
|
||||
|
||||
- [下载 Hooli 主题][9]
|
||||
|
||||
#### 5、Arrongin/Telinkrin
|
||||
|
||||
![][10]
|
||||
|
||||
福利:二合一主题!它们是在主题领域中的相对新的竞争者。它们都吸取了 Ubuntu 接近完成的 “[communitheme][11]” 的思路,并带它到了你的桌面。这两个主题我能找到的唯一真正的区别就是颜色。Arrongin 以 Ubuntu 家族的橙色颜色为中心,而 Telinkrin 则更偏向于 KDE Breeze 系的蓝色,我个人更喜欢蓝色,但是两者都是极好的选择!
|
||||
|
||||
- [下载 Arrongin/Telinkrin 主题][12]
|
||||
|
||||
#### 6、Gnome-osx
|
||||
|
||||
![][13]
|
||||
|
||||
我不得不承认,通常,当我看到一个主题有 “osx” 或者在标题中有类似的内容时我就不会不期望太多。大多数受 Apple 启发的主题看起来都比较雷同,我真不能找到使用它们的原因。但我想这两个主题能够打破这种思维定式:这就是 Arc-osc 主题和 Gnome-osx 主题。
|
||||
|
||||
我喜欢 Gnome-osx 主题的原因是它在 Gnome 桌面上看起来确实很像 OSX。它在融入桌面环境而不至于变的太扁平方面做得很好。所以,对于那些喜欢稍微扁平的主题的人来说,如果你喜欢红黄绿按钮样式(用于关闭、最小化和最大化),这个主题非常适合你。
|
||||
|
||||
- [下载 Gnome-osx 主题][14]
|
||||
|
||||
#### 7、Ultimate Maia
|
||||
|
||||
![][15]
|
||||
|
||||
曾经有一段时间我使用 Manjaro Gnome。尽管那以后我又回到了 Ubuntu,但是,我希望我能打包带走的一个东西是 Manjaro 主题。如果你对 Manjaro 主题和我一样感受相同,那么你是幸运的,因为你可以带它到你想运行 Gnome 的任何 Linux 发行版!
|
||||
|
||||
丰富的绿色颜色,Breeze 式的关闭、最小化、最大化按钮,以及全面雕琢过的主题使它成为一个不可抗拒的选择。如果你不喜欢绿色,它甚至为你提供一些其它颜色的变体。但是说实话……谁会不喜欢 Manjaro 的绿色呢?
|
||||
|
||||
- [下载 Ultimate Maia 主题][16]
|
||||
|
||||
#### 8、Vimix
|
||||
|
||||
![][17]
|
||||
|
||||
这是一个让我激动的主题。它是现代风格的,吸取了 macOS 的红黄绿按钮的风格,但并不是直接复制了它们,并且减少了多变的主题颜色,使之成为了大多数主题的独特替代品。它带来三个深色的变体和几个彩色配色,我们中大多数人都可以从中找到我们喜欢的。
|
||||
|
||||
- [下载 Vimix 主题][18]
|
||||
|
||||
#### 9、Ant
|
||||
|
||||
![][19]
|
||||
|
||||
像 Vimix 一样,Ant 从 macOS 的按钮颜色中吸取了灵感,但不是直接复制了样式。在 Vimix 减少了颜色花哨的地方,Ant 却增加了丰富的颜色,在我的 System 76 Galago Pro 屏幕看起来绚丽极了。三个主题变体的变化差异大相径庭,虽然它可能不见得符合每个人的口味,它无疑是最适合我的。
|
||||
|
||||
- [下载 Ant 主题][20]
|
||||
|
||||
#### 10、Flat Remix
|
||||
|
||||
![][21]
|
||||
|
||||
如果你还没有注意到这点,对于一些关注关闭、最小化、最大化按钮的人来说我就是一个傻瓜。Flat Remix 使用的颜色主题是我从未在其它地方看到过的,它采用红色、蓝色和橙色方式。把这些添加到一个几乎看起来像是一个混合了 Arc 和 Adapta 的主题的上面,就有了 Flat Remix。
|
||||
|
||||
我本人喜欢它的深色主题,但是换成亮色的也是非常好的。因此,如果你喜欢稍稍透明、风格一致的深色主题,以及偶尔的一点点颜色,那 Flat Remix 就适合你。
|
||||
|
||||
- [下载 Flat Remix 主题][22]
|
||||
|
||||
#### 11、Paper
|
||||
|
||||
![][23]
|
||||
|
||||
[Paper][24] 已经出现一段时间。我记得第一次使用它是在 2014 年。可以说,Paper 的图标包比其 GTK 主题更出名,但是这并不意味着它自身的主题不是一个极好的选择。即使我从一开始就倾心于 Paper 图标,我不能说当我第一次尝试它的时候我就是一个 Paper 主题忠实粉丝。
|
||||
|
||||
我觉得鲜亮的色彩和有趣的方式被放到一个主题里是一种“不成熟”的体验。现在,几年后,Paper 在我心目中已经长大,至少可以这样说,这个主题采取的轻快方式是我非常欣赏的一个。
|
||||
|
||||
- [下载 Paper 主题][25]
|
||||
|
||||
#### 12、Pop
|
||||
|
||||
![][26]
|
||||
|
||||
Pop 在这个列表上是一个较新的主题,是由 [System 76][27] 的人们创造的,Pop GTK 主题是前面列出的 Adapta 主题的一个分支,并带有一个匹配的图标包,图标包是先前提到的 Paper 图标包的一个分支。
|
||||
|
||||
该主题是在 System 76 发布了 [他们自己的发行版][28] Pop!_OS 之后不久发布的。你可以阅读我的 [Pop!_OS 点评][29] 来了解更多信息。不用说,我认为 Pop 是一个极好的主题,带有华丽的装饰,并为 Gnome 桌面带来了一股清新之风。
|
||||
|
||||
- [下载 Pop 主题][30]
|
||||
|
||||
#### 结束语
|
||||
|
||||
很明显,我们有比文中所描述的主题更多的选择,但是这些大多是我在最近几月所使用的最完整、最精良的主题。如果你认为我们错过一些你确实喜欢的主题,或你确实不喜欢我在上面描述的主题,那么在下面的评论区让我们知道,并分享你喜欢的主题更好的原因!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/best-gtk-themes/
|
||||
|
||||
作者:[Phillip Prado][a]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://itsfoss.com/author/phillip/
|
||||
[1]:https://itsfoss.com/install-themes-ubuntu/
|
||||
[2]:https://i2.wp.com/itsfoss.com/wp-content/uploads/2018/03/arcambaince.png
|
||||
[3]:https://www.gnome-look.org/p/1193861/
|
||||
[4]:https://i0.wp.com/itsfoss.com/wp-content/uploads/2018/03/adapta.jpg
|
||||
[5]:https://www.gnome-look.org/p/1190851/
|
||||
[6]:https://i2.wp.com/itsfoss.com/wp-content/uploads/2018/03/numix.png
|
||||
[7]:https://www.gnome-look.org/p/1170667/
|
||||
[8]:https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/03/hooli2.jpg
|
||||
[9]:https://www.gnome-look.org/p/1102901/
|
||||
[10]:https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/03/AT.jpg
|
||||
[11]:https://itsfoss.com/ubuntu-community-theme/
|
||||
[12]:https://www.gnome-look.org/p/1215199/
|
||||
[13]:https://itsfoss.com/wp-content/uploads/2018/03/gosx-800x473.jpg
|
||||
[14]:https://www.opendesktop.org/s/Gnome/p/1171688/
|
||||
[15]:https://itsfoss.com/wp-content/uploads/2018/03/ultimatemaia-800x450.jpg
|
||||
[16]:https://www.opendesktop.org/s/Gnome/p/1193879/
|
||||
[17]:https://itsfoss.com/wp-content/uploads/2018/03/vimix-800x450.jpg
|
||||
[18]:https://www.gnome-look.org/p/1013698/
|
||||
[19]:https://itsfoss.com/wp-content/uploads/2018/03/ant-800x533.png
|
||||
[20]:https://www.opendesktop.org/p/1099856/
|
||||
[21]:https://itsfoss.com/wp-content/uploads/2018/03/flatremix-800x450.png
|
||||
[22]:https://www.opendesktop.org/p/1214931/
|
||||
[23]:https://itsfoss.com/wp-content/uploads/2018/04/paper-800x450.jpg
|
||||
[24]:https://itsfoss.com/install-paper-theme-linux/
|
||||
[25]:https://snwh.org/paper/download
|
||||
[26]:https://itsfoss.com/wp-content/uploads/2018/04/pop-800x449.jpg
|
||||
[27]:https://system76.com/
|
||||
[28]:https://itsfoss.com/system76-popos-linux/
|
||||
[29]:https://itsfoss.com/pop-os-linux-review/
|
||||
[30]:https://github.com/pop-os/gtk-theme/blob/master/README.md
|
78
published/201904/20180718 3 Emacs modes for taking notes.md
Normal file
78
published/201904/20180718 3 Emacs modes for taking notes.md
Normal file
@ -0,0 +1,78 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10792-1.html)
|
||||
[#]: subject: (3 Emacs modes for taking notes)
|
||||
[#]: via: (https://opensource.com/article/18/7/emacs-modes-note-taking)
|
||||
[#]: author: (Scott Nesbitt https://opensource.com/users/scottnesbitt)
|
||||
|
||||
用来记笔记的三个 Emacs 模式
|
||||
======
|
||||
|
||||
> 借助这些 Emacs 模式轻松记录信息。
|
||||
|
||||

|
||||
|
||||
|
||||
不管你从事哪种工作,你都无可避免地需要记笔记。而且可能还不是一点点。现在这年头,大家都开始以数字的形式来记笔记了。
|
||||
|
||||
开源软件爱好者有多种途径来以电子的方式记下他们的创意、想法和研究过程。你可以使用 [网页工具][1],可以使用 [桌面应用][2],或者你也可以 [使用命令行工具][3]。
|
||||
|
||||
如果你使用 [Emacs][4](伪装成文本编辑器的强力操作系统),有多个<ruby>模式<rt>mode</rt></ruby>可以帮你有效地记录笔记。我们这里列举三个例子。
|
||||
|
||||
### Deft
|
||||
|
||||

|
||||
|
||||
在少数情况下,我只能使用 Mac时,有一个工具是我不能缺少的:[nvALT][5] 笔记应用。[Deft 模式][6] 为 Emacs 带来了 nvALT 式的体验。
|
||||
|
||||
Deft 将你的笔记以文本文件的形式存储在电脑中的某个文件夹中。当你进入 Deft 模式,你会看到一系列的笔记及其摘要。这些摘要其实就是文本文件的第一行。若第一行是 Markdown、LaTeX,甚至 Emacs Org 模式的格式的话,Deft 会忽略掉这些格式而只显示文本内容。
|
||||
|
||||
要打开笔记,只需要向下滚动到该笔记的位置然后按下回车即可。然而 Deft 不仅仅只是这样。根据 Deft 开发者 Jason Blevins 的说法,它的*主要操作是搜索和过滤*。Deft 的实现方式简单而有效。输入关键字然后 Deft 会只显示标题中包含关键字的笔记。这在你要从大量笔记中找到某条笔记时非常有用。
|
||||
|
||||
### Org 模式
|
||||
|
||||

|
||||
|
||||
如果本文没有包含 [Org 模式][7] 的话,那么我可能会被人所诟病。为什么?它可以说是 Emacs 中最灵活、使用最广泛的记录笔记的方式了。以正确的方式使用它,Org 模式可以极大地增强记笔记的能力。
|
||||
|
||||
Org 模式的主要优势在于它组织笔记的方式。在 Org 模式中,一个笔记文件会被组织成一个巨大的大纲。每个章节就是大纲里的一个节点,你可以对它进行展开和折叠。这些章节又可以有子章节,这些子章节也可以展开和折叠。这不仅使你一次只关注于某个章节,而且可以让你浏览整个大纲。
|
||||
|
||||
你可以在多个章节之间 [进行互联][8],无需通过剪切和复制就能快速移动章节,以及 [附加文件][9] 到笔记中。Org 模式支持带格式的字符和表格。如果你需要转换笔记到其他格式,Org 模式也有大量的[导出选项][10]。
|
||||
|
||||
|
||||
### Howm
|
||||
|
||||

|
||||
|
||||
当我使用 Emacs 已经成为一种习惯时,[howm][11] 马上就成为我严重依赖的模式之一了。虽然我特别喜欢使用 Org 模式,但 howm 依然占有一席之地。
|
||||
|
||||
Howm 就好像是一个小型维基。你可以创建笔记和任务列表,还能在它们之间创建链接。通过输入或点击某个链接,你可以在笔记之间跳转。如果你需要,还可以使用关键字为笔记添加标签。不仅如此,你可以对笔记进行搜索、排序和合并。
|
||||
|
||||
Howm 不是最漂亮的 Emacs 模式,它的用户体验也不是最佳。它需要你花一点时间来适应它,而一旦你适应了它,记录和查找笔记就是轻而易举的事情了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/7/emacs-modes-note-taking
|
||||
|
||||
作者:[Scott Nesbitt][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/scottnesbitt
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/alternatives/evernote
|
||||
[2]: https://opensource.com/life/16/9/4-desktop-note-taking-applications
|
||||
[3]: https://opensource.com/article/18/3/command-line-note-taking-applications
|
||||
[4]: https://www.gnu.org/software/emacs/
|
||||
[5]: http://brettterpstra.com/projects/nvalt/
|
||||
[6]: https://jblevins.org/projects/deft/
|
||||
[7]: https://orgmode.org/
|
||||
[8]: https://orgmode.org/org.html#Hyperlinks
|
||||
[9]: https://orgmode.org/org.html#Attachments
|
||||
[10]: https://orgmode.org/org.html#Exporting
|
||||
[11]: https://howm.osdn.jp/
|
@ -0,0 +1,301 @@
|
||||
Sensu 监控入门
|
||||
======
|
||||
> 这个开源解决方案可以简单而有效地监控你的云基础设施。
|
||||
|
||||

|
||||
|
||||
Sensu 是一个开源的基础设施和应用程序监控解决方案,它可以监控服务器、相关服务和应用程序健康状况,并通过第三方集成发送警报和通知。Sensu 用 Ruby 编写,可以使用 [RabbitMQ][1] 或 [Redis][2] 来处理消息,它使用 Redis 来存储数据。
|
||||
|
||||
如果你想以一种简单而有效的方式监控云基础设施,Sensu 是一个不错的选择。它可以与你的组织已经使用的许多现代 DevOps 组件集成,比如 [Slack][3]、[HipChat][4] 或 [IRC][5],它甚至可以用 [PagerDuty][6] 发送移动或寻呼机的警报。
|
||||
|
||||
Sensu 的[模块化架构][7]意味着每个组件都可以安装在同一台服务器上或者在完全独立的机器上。
|
||||
|
||||
### 结构
|
||||
|
||||
Sensu 的主要通信机制是 Transport。每个 Sensu 组件必须连接到 Transport 才能相互发送消息。Transport 可以使用 RabbitMQ(在生产环境中推荐使用)或 Redis。
|
||||
|
||||
Sensu 服务器处理事件数据并采取行动。它注册客户端并使用过滤器、增变器和处理程序检查结果和监视事件。服务器向客户端发布检查说明,Sensu API 提供 RESTful API,提供对监控数据和核心功能的访问。
|
||||
|
||||
[Sensu 客户端][8]执行 Sensu 服务器安排的检查或本地检查定义。Sensu 使用数据存储(Redis)来保存所有的持久数据。最后,[Uchiwa][9] 是与 Sensu API 进行通信的 Web 界面。
|
||||
|
||||
![][11]
|
||||
|
||||
### 安装 Sensu
|
||||
|
||||
#### 条件
|
||||
|
||||
* 一个 Linux 系统作为服务器节点(本文使用了 CentOS 7)
|
||||
* 要监控的一台或多台 Linux 机器(客户机)
|
||||
|
||||
#### 服务器侧
|
||||
|
||||
Sensu 需要安装 Redis。要安装 Redis,启用 EPEL 仓库:
|
||||
|
||||
```
|
||||
$ sudo yum install epel-release -y
|
||||
```
|
||||
|
||||
然后安装 Redis:
|
||||
|
||||
```
|
||||
$ sudo yum install redis -y
|
||||
```
|
||||
|
||||
修改 `/etc/redis.conf` 来禁用保护模式,监听每个地址并设置密码:
|
||||
|
||||
```
|
||||
$ sudo sed -i 's/^protected-mode yes/protected-mode no/g' /etc/redis.conf
|
||||
$ sudo sed -i 's/^bind 127.0.0.1/bind 0.0.0.0/g' /etc/redis.conf
|
||||
$ sudo sed -i 's/^# requirepass foobared/requirepass password123/g' /etc/redis.conf
|
||||
```
|
||||
|
||||
启用并启动 Redis 服务:
|
||||
|
||||
```
|
||||
$ sudo systemctl enable redis
|
||||
$ sudo systemctl start redis
|
||||
```
|
||||
|
||||
Redis 现在已经安装并准备好被 Sensu 使用。
|
||||
|
||||
现在让我们来安装 Sensu。
|
||||
|
||||
首先,配置 Sensu 仓库并安装软件包:
|
||||
|
||||
```
|
||||
$ sudo tee /etc/yum.repos.d/sensu.repo << EOF
|
||||
[sensu]
|
||||
name=sensu
|
||||
baseurl=https://sensu.global.ssl.fastly.net/yum/\$releasever/\$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
EOF
|
||||
|
||||
$ sudo yum install sensu uchiwa -y
|
||||
```
|
||||
|
||||
让我们为 Sensu 创建最简单的配置文件:
|
||||
|
||||
```
|
||||
$ sudo tee /etc/sensu/conf.d/api.json << EOF
|
||||
{
|
||||
"api": {
|
||||
"host": "127.0.0.1",
|
||||
"port": 4567
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
然后,配置 `sensu-api` 在本地主机上使用端口 4567 监听:
|
||||
|
||||
```
|
||||
$ sudo tee /etc/sensu/conf.d/redis.json << EOF
|
||||
{
|
||||
"redis": {
|
||||
"host": "<IP of server>",
|
||||
"port": 6379,
|
||||
"password": "password123"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
||||
$ sudo tee /etc/sensu/conf.d/transport.json << EOF
|
||||
{
|
||||
"transport": {
|
||||
"name": "redis"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
在这两个文件中,我们将 Sensu 配置为使用 Redis 作为传输机制,还有 Reids 监听的地址。客户端需要直接连接到传输机制。每台客户机都需要这两个文件。
|
||||
|
||||
```
|
||||
$ sudo tee /etc/sensu/uchiwa.json << EOF
|
||||
{
|
||||
"sensu": [
|
||||
{
|
||||
"name": "sensu",
|
||||
"host": "127.0.0.1",
|
||||
"port": 4567
|
||||
}
|
||||
],
|
||||
"uchiwa": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 3000
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
在这个文件中,我们配置 Uchiwa 监听每个地址(0.0.0.0)的端口 3000。我们还配置 Uchiwa 使用 `sensu-api`(已配置好)。
|
||||
|
||||
出于安全原因,更改刚刚创建的配置文件的所有者:
|
||||
|
||||
```
|
||||
$ sudo chown -R sensu:sensu /etc/sensu
|
||||
```
|
||||
|
||||
启用并启动 Sensu 服务:
|
||||
|
||||
```
|
||||
$ sudo systemctl enable sensu-server sensu-api sensu-client
|
||||
$ sudo systemctl start sensu-server sensu-api sensu-client
|
||||
$ sudo systemctl enable uchiwa
|
||||
$ sudo systemctl start uchiwa
|
||||
```
|
||||
|
||||
尝试访问 Uchiwa 网站:`http://<服务器的 IP 地址>:3000`
|
||||
|
||||
对于生产环境,建议运行 RabbitMQ 集群作为 Transport 而不是 Redis(虽然 Redis 集群也可以用于生产环境),运行多个 Sensu 服务器实例和 API 实例,以实现负载均衡和高可用性。
|
||||
|
||||
Sensu 现在安装完成,让我们来配置客户端。
|
||||
|
||||
#### 客户端侧
|
||||
|
||||
要添加一个新客户端,你需要通过创建 `/etc/yum.repos.d/sensu.repo` 文件在客户机上启用 Sensu 仓库。
|
||||
|
||||
```
|
||||
$ sudo tee /etc/yum.repos.d/sensu.repo << EOF
|
||||
[sensu]
|
||||
name=sensu
|
||||
baseurl=https://sensu.global.ssl.fastly.net/yum/\$releasever/\$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
EOF
|
||||
```
|
||||
|
||||
启用仓库后,安装 Sensu:
|
||||
|
||||
```
|
||||
$ sudo yum install sensu -y
|
||||
```
|
||||
|
||||
要配置 `sensu-client`,创建在服务器中相同的 `redis.json` 和 `transport.json`,还有 `client.json` 配置文件:
|
||||
|
||||
```
|
||||
$ sudo tee /etc/sensu/conf.d/client.json << EOF
|
||||
{
|
||||
"client": {
|
||||
"name": "rhel-client",
|
||||
"environment": "development",
|
||||
"subscriptions": [
|
||||
"frontend"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
在 `name` 字段中,指定一个名称来标识此客户机(通常是主机名)。`environment` 字段可以帮助你过滤,而 `subscriptions` 定义了客户机将执行哪些监视检查。
|
||||
|
||||
最后,启用并启动服务并签入 Uchiwa,因为客户机会自动注册:
|
||||
|
||||
```
|
||||
$ sudo systemctl enable sensu-client
|
||||
$ sudo systemctl start sensu-client
|
||||
```
|
||||
|
||||
### Sensu 检查
|
||||
|
||||
Sensu 检查有两个组件:一个插件和一个定义。
|
||||
|
||||
Sensu 与 [Nagios 检查插件规范][12]兼容,因此无需修改即可使用用于 Nagios 的任何检查。检查是可执行文件,由 Sensu 客户机运行。
|
||||
|
||||
检查定义可以让 Sensu 知道如何、在哪以及何时运行插件。
|
||||
|
||||
#### 客户端侧
|
||||
|
||||
让我们在客户机上安装一个检查插件。请记住,此插件将在客户机上执行。
|
||||
|
||||
启用 EPEL 并安装 `nagios-plugins-http`:
|
||||
|
||||
```
|
||||
$ sudo yum install -y epel-release
|
||||
$ sudo yum install -y nagios-plugins-http
|
||||
```
|
||||
|
||||
现在让我们通过手动执行它来了解这个插件。尝试检查客户机上运行的 Web 服务器的状态。它应该会失败,因为我们并没有运行 Web 服务器:
|
||||
|
||||
```
|
||||
$ /usr/lib64/nagios/plugins/check_http -I 127.0.0.1
|
||||
connect to address 127.0.0.1 and port 80: Connection refused
|
||||
HTTP CRITICAL - Unable to open TCP socket
|
||||
```
|
||||
|
||||
不出所料,它失败了。检查执行的返回值:
|
||||
|
||||
```
|
||||
$ echo $?
|
||||
2
|
||||
```
|
||||
|
||||
Nagios 检查插件规范定义了插件执行的四个返回值:
|
||||
|
||||
| 插件返回码 | 状态 |
|
||||
|----------|-----------|
|
||||
| 0 | OK |
|
||||
| 1 | WARNING |
|
||||
| 2 | CRITICAL |
|
||||
| 3 | UNKNOWN |
|
||||
|
||||
有了这些信息,我们现在可以在服务器上创建检查定义。
|
||||
|
||||
#### 服务器侧
|
||||
|
||||
在服务器机器上,创建 `/etc/sensu/conf.d/check_http.json` 文件:
|
||||
|
||||
```
|
||||
{
|
||||
"checks": {
|
||||
"check_http": {
|
||||
"command": "/usr/lib64/nagios/plugins/check_http -I 127.0.0.1",
|
||||
"interval": 10,
|
||||
"subscribers": [
|
||||
"frontend"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在 `command` 字段中,使用我们之前测试过的命令。`interval` 会告诉 Sensu 这个检查的频率,以秒为单位。最后,`subscribers` 将定义执行检查的客户机。
|
||||
|
||||
重新启动 `sensu-api` 和 `sensu-server` 并确认新检查在 Uchiwa 中可用。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart sensu-api sensu-server
|
||||
```
|
||||
|
||||
### 接下来
|
||||
|
||||
Sensu 是一个功能强大的工具,本文只简要介绍它可以干什么。参阅[文档][13]了解更多信息,访问 Sensu 网站了解有关 [Sensu 社区][14]的更多信息。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/8/getting-started-sensu-monitoring-solution
|
||||
|
||||
作者:[Michael Zamot][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/mzamot
|
||||
[1]:https://www.rabbitmq.com/
|
||||
[2]:https://redis.io/topics/config
|
||||
[3]:https://slack.com/
|
||||
[4]:https://en.wikipedia.org/wiki/HipChat
|
||||
[5]:http://www.irc.org/
|
||||
[6]:https://www.pagerduty.com/
|
||||
[7]:https://docs.sensu.io/sensu-core/1.4/overview/architecture/
|
||||
[8]:https://docs.sensu.io/sensu-core/1.4/installation/install-sensu-client/
|
||||
[9]:https://uchiwa.io/#/
|
||||
[10]:/file/406576
|
||||
[11]:https://opensource.com/sites/default/files/uploads/sensu_system.png (sensu_system.png)
|
||||
[12]:https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/pluginapi.html
|
||||
[13]:https://docs.sensu.io/
|
||||
[14]:https://sensu.io/community
|
@ -0,0 +1,201 @@
|
||||
Linux 初学者:移动文件
|
||||
=====================
|
||||
|
||||

|
||||
|
||||
在之前的该系列的部分中,[你学习了有关目录][1]和[访问目录][2][的权限][7]是如何工作的。你在这些文章中学习的大多数内容都可应用于文件,除了如何让一个文件变成可执行文件。
|
||||
|
||||
因此让我们在开始之前先解决这个问题。
|
||||
|
||||
### 不需要 .exe 扩展名
|
||||
|
||||
在其他操作系统中,一个文件的性质通常由它的后缀决定。如果一个文件有一个 .jpg 扩展,操作系统会认为它是一幅图像;如果它以 .wav 结尾,它是一个音频文件;如果它在文件名末尾以 .exe 结尾,它就是一个你可以执行的程序。
|
||||
|
||||
这导致了严重的问题,比如说木马可以伪装成文档文件。幸运的是,在 Linux 下事物不是这样运行的。可以确定的是,你可能会看到有些可执行文件是以 .sh 结尾暗示它们是可执行的脚本,但是这大部分是为了便于人眼找到文件,就像你使用 `ls --color` 将可执行文件的名字以亮绿色显示的方式相同。
|
||||
|
||||
事实上大多数应用根本没有扩展名。决定一个文件是否是一个真正程序的是 `x` (指*可执行的*)位。你可以通过运行以下命令使任何文件变得可执行,
|
||||
|
||||
```
|
||||
chmod a+x some_program
|
||||
```
|
||||
|
||||
而不管它的扩展名是什么或者是否存在。在上面命令中的 `x` 设置了 `x` 位,`a` 说明你为*所有*用户设置它。你同样可以为一组用户设置成拥有这个文件(`g+x`),或者只为一个用户——拥有者——设置 (`u+x`)。
|
||||
|
||||
尽管我们会在该系列之后的部分包含从命令行创建和运行脚本的内容,并学习通过输入它的路径并在结尾加上程序名的方式运行一个程序:
|
||||
|
||||
```
|
||||
path/to/directory/some_program
|
||||
```
|
||||
|
||||
或者,如果你当前在相同目录,你可以使用:
|
||||
|
||||
```
|
||||
./some_program
|
||||
```
|
||||
|
||||
还有其他方式可以使你的程序在目录树的任意位置运行 (提示:查询 `$PATH` 环境变量),但是当我们讨论 shell 脚本的时候你会读到这些。
|
||||
|
||||
### 复制、移动、链接
|
||||
|
||||
明显地,从命令行修改和处理文件有很多的方式,而不仅仅是处理它们的权限。当你试图打开一个不存在的文件是,大多数应用会创建一个新文件。如果 `test.txt` 当前并不存在,下列命令:
|
||||
|
||||
```
|
||||
nano test.txt
|
||||
```
|
||||
|
||||
```
|
||||
vim test.txt
|
||||
```
|
||||
|
||||
([nano][3] 和 [vim][4] 是流行的命令行文本编辑器)都将为你创建一个空的 `test.txt` 文件来编辑。
|
||||
|
||||
你可以通过 “触摸” (`touch`)来创建一个空的文件,
|
||||
|
||||
```
|
||||
touch test.txt
|
||||
```
|
||||
|
||||
会创建一个文件,但是不会在任何应用中打开它。
|
||||
|
||||
你可以使用 `cp` 来拷贝一个文件到另一个位置,或者使用一个不同的名字:
|
||||
|
||||
```
|
||||
cp test.txt copy_of_test.txt
|
||||
```
|
||||
|
||||
你也可以拷贝一堆文件:
|
||||
|
||||
```
|
||||
cp *.png /home/images
|
||||
```
|
||||
|
||||
上面的命令拷贝当前目录下的所有 PNG 文件到相对你的主目录下的 `images/` 目录。在你尝试之前 `images/` 目录必须存在, 不然 `cp` 将显示一个错误。同样的,警惕,当你复制一个文件到一个已经包含相同名字的文件的目录时,`cp` 会静默地用新文件覆盖老的文件。
|
||||
|
||||
你可以使用:
|
||||
|
||||
```
|
||||
cp -i *.png /home/images
|
||||
```
|
||||
|
||||
如果你想要 `cp` 命令在有任何危险时警告你 (`-i` 选项代表*交互式的*)。
|
||||
|
||||
你同样可以复制整个目录,但是为了做到这样,你需要 `-r` 选项:
|
||||
|
||||
```
|
||||
cp -rv directory_a/ directory_b
|
||||
```
|
||||
|
||||
`-r` 选项代表*递归*,意味着 `cp` 会向下探索目录 `directory_a`,复制所有的文件和子目录下内部包含的。我个人喜欢包含 `-v` 选项,因为它使 `cp` 冗长而啰嗦,意味着它会显示你当前它正在做什么而不是仅仅静默的复制然后存在。
|
||||
|
||||
`mv` 命令移动东西。也就是说,它移动文件从一个位置到另一个位置。最简单的形式,`mv` 表现的更像 `cp`:
|
||||
|
||||
```
|
||||
mv test.txt new_test.txt
|
||||
```
|
||||
|
||||
上面的命令使 `new_test.txt` 出现,`test.txt` 消失。
|
||||
|
||||
```
|
||||
mv *.png /home/images
|
||||
```
|
||||
|
||||
移动当前目录下所有的 PNG 文件到相对于你的主目录的 `images/` 目录。同样的你必须小心你没有意外的覆盖已存在的文件。使用
|
||||
|
||||
```
|
||||
mv -i *.png /home/images
|
||||
|
||||
```
|
||||
|
||||
如果你想站在安全的角度,你可以使用与 `cp` 相同的方式。
|
||||
|
||||
除了移动与拷贝的不同外,另一个 `mv` 和 `cp` 之间的不同是当你移动目录时:
|
||||
|
||||
```
|
||||
mv directory_a/ directory_b
|
||||
```
|
||||
|
||||
不需要添加递归的标志。这是因为你实际做的是重命名一个目录,与第一个例子相同,你做的是重命名文件。实际上,即使你从一个目录到另一个目录 “移动” 一个文件,只要两个目录在相同的存储设备和分区,你就是在重命名文件。
|
||||
|
||||
你可以做一个实验来证明。 `time` 是一个工具来让你测量一个命令花费多久来执行。找一个非常大的文件,可以是几百 MB 甚至 几 GB (例如一个长视频),像下方这样尝试拷贝到另一个目录:
|
||||
|
||||
```
|
||||
$ time cp hefty_file.mkv another_directory/
|
||||
real 0m3,868s
|
||||
user 0m0,016s
|
||||
sys 0m0,887s
|
||||
```
|
||||
|
||||
下面是 `time` 的输出。需要关注的是第一行, real 时间。它花费了几乎 4 秒来拷贝 355 MB 的 `hefty_file.mkv` 到 `another_directory/` 目录。
|
||||
|
||||
现在让我们尝试移动它:
|
||||
|
||||
```
|
||||
$ time mv hefty_file.mkv another_directory/
|
||||
real 0m0,004s
|
||||
user 0m0,000s
|
||||
sys 0m0,003s
|
||||
```
|
||||
|
||||
移动几乎是瞬时的!这是违反直觉的,因为看起来 `mv` 必须复制这个文件然后删除原来的。这是 `mv` 对比 `cp` 命令必须做的两件事。但是,实际上,`mv` 快了 1000 倍。
|
||||
|
||||
这是因为文件系统结构中,它的所有目录树,只为了让用户便利而存在。在每个分区的开始,有一个称作*分区表*的东西告诉操作系统在实际的物理磁盘上去哪找每个文件。在磁盘上,数据没有分为目录甚至是文件。[作为替代的是轨道、扇区和簇][5]。当你在相同分区 “移动” 一个文件时,操作系统实际做的仅仅是在分区表中改变了那个文件的入口,但它仍然指向磁盘上相同的簇信息。
|
||||
|
||||
是的!移动是一个谎言!至少在相同分区下是。如果你试图移动一个文件到一个不同的分区或者不同的设备, `mv` 仍然很快,但可以察觉到它比在相同分区下移动文件慢了。这是因为实际上发生了复制和清除数据。
|
||||
|
||||
### 重命名
|
||||
|
||||
有几个不同的命令行 `rename` 工具。没有一个像 `cp` 和 `mv` 那样固定,并且它们工作的方式都有一点不同,相同的一点是它们都被用来改变文件名的部分。
|
||||
|
||||
在 Debian 和 Ubuntu 中, 默认的 `rename` 工具使用 [正则表达式][6](字符组成的字符串模式)来大量的改变目录中的文件。命令:
|
||||
|
||||
```
|
||||
rename 's/\.JPEG$/.jpg/' *
|
||||
```
|
||||
|
||||
将改变所有扩展名为 `JPEG` 的文件为 `jpg`。文件 `IMG001.JPEG` 变成 `IMG001.jpg`、 `my_pic.JPEG` 变成 `my_pic.jpg`,等等。
|
||||
|
||||
另一个 `rename` 版本默认在 Manjaro 上可获得,这是一个 Arch 的衍生版,更简单,但是可能没有那么强大:
|
||||
|
||||
```
|
||||
rename .JPEG .jpg *
|
||||
```
|
||||
|
||||
这和你之前看到的上面做相同的重命名操作。在这个版本,`.JPEG` 是你想改变的字符组成的字符串,`.jpg` 是你想要改变成为的,`*` 表示当前目录下的所有文件。
|
||||
|
||||
基本原则是如果你所做的仅仅是重命名一个文件或者目录,你最好用 `mv`,这是因为 `mv` 在所有分发版上都是可靠一致的。
|
||||
|
||||
### 了解更多
|
||||
|
||||
查看 `mv` 和 `cp` 的 man 页面了解更多。运行
|
||||
|
||||
```
|
||||
man cp
|
||||
```
|
||||
|
||||
或者
|
||||
```
|
||||
man mv
|
||||
```
|
||||
|
||||
来阅读这些命令自带的所有选项,这些使他们使用起来更强大和安全。
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/2018/8/linux-beginners-moving-things-around
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[1]: https://linux.cn/article-10066-1.html
|
||||
[2]: https://linux.cn/article-10399-1.html
|
||||
[3]: https://www.nano-editor.org/
|
||||
[4]: https://www.vim.org/
|
||||
[5]: https://en.wikipedia.org/wiki/Disk_sector
|
||||
[6]: https://en.wikipedia.org/wiki/Regular_expression
|
||||
[7]: https://linux.cn/article-10370-1.html
|
||||
|
@ -0,0 +1,153 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (liujing97)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10727-1.html)
|
||||
[#]: subject: (7 Methods To Identify Disk Partition/FileSystem UUID On Linux)
|
||||
[#]: via: (https://www.2daygeek.com/check-partitions-uuid-filesystem-uuid-universally-unique-identifier-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
Linux 中获取硬盘分区或文件系统的 UUID 的七种方法
|
||||
======
|
||||
|
||||
作为一个 Linux 系统管理员,你应该知道如何去查看分区的 UUID 或文件系统的 UUID。因为现在大多数的 Linux 系统都使用 UUID 挂载分区。你可以在 `/etc/fstab` 文件中可以验证。
|
||||
|
||||
有许多可用的实用程序可以查看 UUID。本文我们将会向你展示多种查看 UUID 的方法,并且你可以选择一种适合于你的方法。
|
||||
|
||||
### 何为 UUID?
|
||||
|
||||
UUID 意即<ruby>通用唯一识别码<rt>Universally Unique Identifier</rt></ruby>,它可以帮助 Linux 系统识别一个磁盘分区而不是块设备文件。
|
||||
|
||||
自内核 2.15.1 起,libuuid 就是 util-linux-ng 包中的一部分,它被默认安装在 Linux 系统中。UUID 由该库生成,可以合理地认为在一个系统中 UUID 是唯一的,并且在所有系统中也是唯一的。
|
||||
|
||||
这是在计算机系统中用来标识信息的一个 128 位(比特)的数字。UUID 最初被用在<ruby>阿波罗网络计算机系统<rt>Apollo Network Computing System</rt></ruby>(NCS)中,之后 UUID 被<ruby>开放软件基金会<rt>Open Software Foundation</rt></ruby>(OSF)标准化,成为<ruby>分布式计算环境<rt>Distributed Computing Environment</rt></ruby>(DCE)的一部分。
|
||||
|
||||
UUID 以 32 个十六进制的数字表示,被连字符分割为 5 组显示,总共的 36 个字符的格式为 8-4-4-4-12(32 个字母或数字和 4 个连字符)。
|
||||
|
||||
例如: `d92fa769-e00f-4fd7-b6ed-ecf7224af7fa`
|
||||
|
||||
我的 `/etc/fstab` 文件示例:
|
||||
|
||||
```
|
||||
# cat /etc/fstab
|
||||
|
||||
# /etc/fstab: static file system information.
|
||||
#
|
||||
# Use 'blkid' to print the universally unique identifier for a device; this may
|
||||
# be used with UUID= as a more robust way to name devices that works even if
|
||||
# disks are added and removed. See fstab(5).
|
||||
#
|
||||
#
|
||||
UUID=69d9dd18-36be-4631-9ebb-78f05fe3217f / ext4 defaults,noatime 0 1
|
||||
UUID=a2092b92-af29-4760-8e68-7a201922573b swap swap defaults,noatime 0 2
|
||||
```
|
||||
|
||||
我们可以使用下面的 7 个命令来查看。
|
||||
|
||||
* `blkid` 命令:定位或打印块设备的属性。
|
||||
* `lsblk` 命令:列出所有可用的或指定的块设备的信息。
|
||||
* `hwinfo` 命令:硬件信息工具,是另外一个很好的实用工具,用于查询系统中已存在硬件。
|
||||
* `udevadm` 命令:udev 管理工具
|
||||
* `tune2fs` 命令:调整 ext2/ext3/ext4 文件系统上的可调文件系统参数。
|
||||
* `dumpe2fs` 命令:查询 ext2/ext3/ext4 文件系统的信息。
|
||||
* 使用 `by-uuid` 路径:该目录下包含有 UUID 和实际的块设备文件,UUID 与实际的块设备文件链接在一起。
|
||||
|
||||
### Linux 中如何使用 blkid 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
`blkid` 是定位或打印块设备属性的命令行实用工具。它利用 libblkid 库在 Linux 系统中获得到磁盘分区的 UUID。
|
||||
|
||||
```
|
||||
# blkid
|
||||
/dev/sda1: UUID="d92fa769-e00f-4fd7-b6ed-ecf7224af7fa" TYPE="ext4" PARTUUID="eab59449-01"
|
||||
/dev/sdc1: UUID="d17e3c31-e2c9-4f11-809c-94a549bc43b7" TYPE="ext2" PARTUUID="8cc8f9e5-01"
|
||||
/dev/sdc3: UUID="ca307aa4-0866-49b1-8184-004025789e63" TYPE="ext4" PARTUUID="8cc8f9e5-03"
|
||||
/dev/sdc5: PARTUUID="8cc8f9e5-05"
|
||||
```
|
||||
|
||||
### Linux 中如何使用 lsblk 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
`lsblk` 列出所有有关可用或指定块设备的信息。`lsblk` 命令读取 sysfs 文件系统和 udev 数据库以收集信息。
|
||||
|
||||
如果 udev 数据库不可用或者编译的 lsblk 不支持 udev,它会试图从块设备中读取卷标、UUID 和文件系统类型。这种情况下,必须以 root 身份运行。该命令默认会以类似于树的格式打印出所有的块设备(RAM 盘除外)。
|
||||
|
||||
```
|
||||
# lsblk -o name,mountpoint,size,uuid
|
||||
NAME MOUNTPOINT SIZE UUID
|
||||
sda 30G
|
||||
└─sda1 / 20G d92fa769-e00f-4fd7-b6ed-ecf7224af7fa
|
||||
sdb 10G
|
||||
sdc 10G
|
||||
├─sdc1 1G d17e3c31-e2c9-4f11-809c-94a549bc43b7
|
||||
├─sdc3 1G ca307aa4-0866-49b1-8184-004025789e63
|
||||
├─sdc4 1K
|
||||
└─sdc5 1G
|
||||
sdd 10G
|
||||
sde 10G
|
||||
sr0 1024M
|
||||
```
|
||||
|
||||
### Linux 中如何使用 by-uuid 路径查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
该目录包含了 UUID 和实际的块设备文件,UUID 与实际的块设备文件链接在一起。
|
||||
|
||||
```
|
||||
# ls -lh /dev/disk/by-uuid/
|
||||
total 0
|
||||
lrwxrwxrwx 1 root root 10 Jan 29 08:34 ca307aa4-0866-49b1-8184-004025789e63 -> ../../sdc3
|
||||
lrwxrwxrwx 1 root root 10 Jan 29 08:34 d17e3c31-e2c9-4f11-809c-94a549bc43b7 -> ../../sdc1
|
||||
lrwxrwxrwx 1 root root 10 Jan 29 08:34 d92fa769-e00f-4fd7-b6ed-ecf7224af7fa -> ../../sda1
|
||||
```
|
||||
|
||||
### Linux 中如何使用 hwinfo 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
[hwinfo][1] 意即硬件信息工具,是另外一种很好的实用工具。它被用来检测系统中已存在的硬件,并且以可读的格式显示各种硬件组件的细节信息。
|
||||
|
||||
```
|
||||
# hwinfo --block | grep by-uuid | awk '{print $3,$7}'
|
||||
/dev/sdc1, /dev/disk/by-uuid/d17e3c31-e2c9-4f11-809c-94a549bc43b7
|
||||
/dev/sdc3, /dev/disk/by-uuid/ca307aa4-0866-49b1-8184-004025789e63
|
||||
/dev/sda1, /dev/disk/by-uuid/d92fa769-e00f-4fd7-b6ed-ecf7224af7fa
|
||||
```
|
||||
|
||||
### Linux 中如何使用 udevadm 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
`udevadm` 需要命令和命令特定的操作。它控制 systemd-udevd 的运行时行为,请求内核事件、管理事件队列并且提供简单的调试机制。
|
||||
|
||||
```
|
||||
# udevadm info -q all -n /dev/sdc1 | grep -i by-uuid | head -1
|
||||
S: disk/by-uuid/d17e3c31-e2c9-4f11-809c-94a549bc43b7
|
||||
```
|
||||
|
||||
### Linux 中如何使用 tune2fs 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
`tune2fs` 允许系统管理员在 Linux 的 ext2、ext3、ext4 文件系统中调整各种可调的文件系统参数。这些选项的当前值可以使用选项 `-l` 显示。
|
||||
|
||||
```
|
||||
# tune2fs -l /dev/sdc1 | grep UUID
|
||||
Filesystem UUID: d17e3c31-e2c9-4f11-809c-94a549bc43b7
|
||||
```
|
||||
|
||||
### Linux 中如何使用 dumpe2fs 命令查看磁盘分区或文件系统的 UUID?
|
||||
|
||||
`dumpe2fs` 打印出现在设备文件系统中的超级块和块组的信息。
|
||||
|
||||
```
|
||||
# dumpe2fs /dev/sdc1 | grep UUID
|
||||
dumpe2fs 1.43.5 (04-Aug-2017)
|
||||
Filesystem UUID: d17e3c31-e2c9-4f11-809c-94a549bc43b7
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/check-partitions-uuid-filesystem-uuid-universally-unique-identifier-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[liujing97](https://github.com/liujing97)
|
||||
校对:[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/hwinfo-check-display-detect-system-hardware-information-linux/
|
@ -0,0 +1,86 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10774-1.html)
|
||||
[#]: subject: (Enjoy Netflix? You Should Thank FreeBSD)
|
||||
[#]: via: (https://itsfoss.com/netflix-freebsd-cdn/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
喜欢 Netflix 么?你应该感谢 FreeBSD
|
||||
======
|
||||
|
||||
![][7]
|
||||
|
||||
Netflix 是世界上最受欢迎的流媒体服务之一。对,你已经知道了。但你可能不知道的是 Netflix 使用 [FreeBSD][1] 向你提供内容。
|
||||
|
||||
是的。Netflix 依靠 FreeBSD 来构建其内部内容交付网络(CDN)。
|
||||
|
||||
[CDN][2] 是一组位于世界各地的服务器。它主要用于向终端用户分发像图像和视频这样的“大文件”。
|
||||
|
||||
Netflix 没有选择商业 CDN 服务,而是建立了自己的内部 CDN,名为 [Open Connect][3]。
|
||||
|
||||
Open Connect 使用[自定义硬件][4]:Open Connect Appliance。你可以在下面的图片中看到它。它可以每秒处理 40Gb 的数据,存储容量为 248 TB。
|
||||
|
||||
![Netflix’s Open Connect Appliance runs FreeBSD][5]
|
||||
|
||||
Netflix 免费为合格的互联网服务提供商(ISP) 提供 Open Connect Appliance。通过这种方式,大量的 Netflix 流量得到了本地化,ISP 可以更高效地提供 Netflix 内容。
|
||||
|
||||
Open Connect Appliance 运行在 FreeBSD 操作系统上,并且[几乎完全运行开源软件][6]。
|
||||
|
||||
### Open Connect 使用最新版 FreeBSD
|
||||
|
||||
|
||||
你或许会觉得 Netflix 会在这样一个关键基础设施上使用 FreeBSD 的稳定版本,但 Netflix 会跟踪 [FreeBSD 最新/当前版本][8]。Netflix 表示,跟踪“最新版”可以让他们“保持前瞻性,专注于创新”。
|
||||
|
||||
以下是 Netflix 跟踪最新版 FreeBSD 的好处:
|
||||
|
||||
* 更快的功能迭代
|
||||
* 更快地使用 FreeBSD 的新功能
|
||||
* 更快的 bug 修复
|
||||
* 实现协作
|
||||
* 尽量减少合并冲突
|
||||
* 摊销合并“成本”
|
||||
|
||||
> 运行 FreeBSD “最新版” 可以让我们非常高效地向用户分发大量数据,同时保持高速的功能开发。
|
||||
>
|
||||
> Netflix
|
||||
|
||||
请记得,甚至[谷歌也使用 Debian][9] 测试版而不是 Debian 稳定版。也许这些企业更喜欢最先进的功能。
|
||||
|
||||
与谷歌一样,Netflix 也计划向上游提供代码。这应该有助于 FreeBSD 和其他基于 FreeBSD 的 BSD 发行版。
|
||||
|
||||
那么 Netflix 用 FreeBSD 实现了什么?以下是一些统计数据:
|
||||
|
||||
> 使用 FreeBSD 和商业硬件,我们在 16 核 2.6 GHz CPU 上使用约 55% 的 CPU,实现了 90 Gb/s 的 TLS 加密连接。
|
||||
>
|
||||
> Netflix
|
||||
|
||||
如果你想了解更多关于 Netflix 和 FreeBSD 的信息,可以参考 [FOSDEM 的这个演示文稿][10]。你还可以在[这里][11]观看演示文稿的视频。
|
||||
|
||||
目前,大型企业主要依靠 Linux 来实现其服务器基础架构,但 Netflix 已经信任了 BSD。这对 BSD 社区来说是一件好事,因为如果像 Netflix 这样的行业领导者重视 BSD,那么其他人也可以跟上。你怎么看?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/netflix-freebsd-cdn/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.freebsd.org/
|
||||
[2]: https://www.cloudflare.com/learning/cdn/what-is-a-cdn/
|
||||
[3]: https://openconnect.netflix.com/en/
|
||||
[4]: https://openconnect.netflix.com/en/hardware/
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/02/netflix-open-connect-appliance.jpeg?fit=800%2C533&ssl=1
|
||||
[6]: https://openconnect.netflix.com/en/software/
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/02/netflix-freebsd.png?resize=800%2C450&ssl=1
|
||||
[8]: https://www.bsdnow.tv/tutorials/stable-current
|
||||
[9]: https://itsfoss.com/goobuntu-glinux-google/
|
||||
[10]: https://fosdem.org/2019/schedule/event/netflix_freebsd/attachments/slides/3103/export/events/attachments/netflix_freebsd/slides/3103/FOSDEM_2019_Netflix_and_FreeBSD.pdf
|
||||
[11]: http://mirror.onet.pl/pub/mirrors/video.fosdem.org/2019/Janson/netflix_freebsd.webm
|
@ -0,0 +1,48 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10769-1.html)
|
||||
[#]: subject: (Which programming languages should you learn?)
|
||||
[#]: via: (https://opensource.com/article/19/2/which-programming-languages-should-you-learn)
|
||||
[#]: author: (Marty Kalin https://opensource.com/users/mkalindepauledu)
|
||||
|
||||
你应该学习哪种编程语言?
|
||||
======
|
||||
|
||||
> 学习一门新的编程语言是在你的职业生涯中继续前进的好方法,但是应该学习哪一门呢?
|
||||
|
||||

|
||||
|
||||
如果你想要开始你的编程生涯或继续前进,那么学习一门新语言是一个聪明的主意。但是,大量活跃使用的语言引发了一个问题:哪种编程语言是最好的?要回答这个问题,让我们从一个简单的问题开始:你想做什么样的程序?
|
||||
|
||||
如果你想在客户端进行网络编程,那么特定语言 HTML、CSS 和 JavaScript(看似无穷无尽的方言之一)是必须要学习的。
|
||||
|
||||
如果你想在服务器端进行 Web 编程,那么选择包括常见的通用语言:C++、Golang、Java、C#、 Node.js、Perl、Python、Ruby 等等。当然,服务器程序与数据存储(例如关系数据库和其他数据库)打交道,这意味着 SQL 等查询语言可能会发挥作用。
|
||||
|
||||
如果你正在为移动设备编写原生应用程序,那么了解目标平台非常重要。对于 Apple 设备,Swift 已经取代 Objective C 成为首选语言。对于 Android 设备,Java(带有专用库和工具集)仍然是主要语言。有一些特殊语言,如与 C# 一起使用的 Xamarin,可以为 Apple、Android 和 Windows 设备生成特定于平台的代码。
|
||||
|
||||
那么通用语言呢?通常有各种各样的选择。在*动态*或*脚本*语言(如 Perl、Python 和 Ruby)中,有一些新东西,如 Node.js。而 Java 和 C# 的相似之处比它们的粉丝愿意承认的还要多,仍然是针对虚拟机(分别是 JVM 和 CLR)的主要*静态编译*语言。在可以编译为*原生可执行文件*的语言中,C++ 仍在使用,还有后来出现的 Golang 和 Rust 等。通用的*函数式*语言比比皆是(如 Clojure、Haskell、Erlang、F#、Lisp 和 Scala),它们通常都有热情投入的社区。值得注意的是,面向对象语言(如 Java 和 C#)已经添加了函数式构造(特别是 lambdas),而动态语言从一开始就有函数式构造。
|
||||
|
||||
让我以 C 语言结尾,它是一种小巧、优雅、可扩展的语言,不要与 C++ 混淆。现代操作系统主要用 C 语言编写,其余部分用汇编语言编写。任何平台上的标准库大多数都是用 C 语言编写的。例如,任何打印 `Hello, world!` 这种问候都是通过调用名为 `write` 的 C 库函数来实现的。
|
||||
|
||||
C 作为一种可移植的汇编语言,公开了其他高级语言有意隐藏的底层系统的详细信息。因此,理解 C 可以更好地掌握程序如何竞争执行所需的共享系统资源(如处理器、内存和 I/O 设备)。C 语言既高级又接近硬件,因此在性能方面无与伦比,当然,汇编语言除外。最后,C 是编程语言中的通用语言,几乎所有通用语言都支持某种形式的 C 调用。
|
||||
|
||||
有关现代 C 语言的介绍,参考我的书籍 《[C 语言编程:可移植的汇编器介绍][1]》。无论你怎么做,学习 C 语言,你会学到比另一种编程语言多得多的东西。
|
||||
|
||||
你认为学习哪些编程语言很重要?你是否同意这些建议?在评论告知我们!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/2/which-programming-languages-should-you-learn
|
||||
|
||||
作者:[Marty Kalin][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/mkalindepauledu
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.amazon.com/dp/1977056954?ref_=pe_870760_150889320
|
@ -1,20 +1,20 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10723-1.html)
|
||||
[#]: subject: (Ubuntu 14.04 is Reaching the End of Life. Here are Your Options)
|
||||
[#]: via: (https://itsfoss.com/ubuntu-14-04-end-of-life/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
Ubuntu 14.04 即将结束支持。下面是你的选择
|
||||
Ubuntu 14.04 即将结束支持,你该怎么办?
|
||||
======
|
||||
|
||||
Ubuntu 14.04 即将于 2019 年 4 月 30 日结束支持。这意味着在此日期之后 Ubuntu 14.04 用户将无法获得安全和维护更新。
|
||||
|
||||
你甚至不会获得已安装应用的更新,并且不手动修改 sources.list 则无法使用 apt 命令或软件中心安装新应用。
|
||||
你甚至不会获得已安装应用的更新,并且不手动修改 `sources.list` 则无法使用 `apt` 命令或软件中心安装新应用。
|
||||
|
||||
Ubuntu 14.04 大约在五年前发布。这是 Ubuntu 长期支持版本。
|
||||
Ubuntu 14.04 大约在五年前发布。这是 Ubuntu 长期支持版本(LTS)。
|
||||
|
||||
[检查 Ubuntu 版本][1]并查看你是否仍在使用 Ubuntu 14.04。如果是桌面或服务器版,你可能想知道在这种情况下你应该怎么做。
|
||||
|
||||
@ -36,7 +36,7 @@ Ubuntu 16.04 也是一个长期支持版本,它将支持到 2021 年 4 月。
|
||||
|
||||
我说的备份指的是将这些文件夹复制到外部 USB 盘。换句话说,你应该有办法将数据复制回计算机,因为你将格式化你的系统。
|
||||
|
||||
我建议桌面用户使用此选项。 Ubuntu 18.04 是目前的长期支持版本,它将至少在 2023 年 4 月之前得到支持。在你被迫进行下次升级之前,你将有四年的时间。
|
||||
我建议桌面用户使用此选项。Ubuntu 18.04 是目前的长期支持版本,它将至少在 2023 年 4 月之前得到支持。在你被迫进行下次升级之前,你将有四年的时间。
|
||||
|
||||
### 支付扩展安全维护费用并继续使用 Ubuntu 14.04
|
||||
|
||||
@ -48,7 +48,7 @@ Ubuntu Advantage 计划用户还有[扩展安全维护][4](ESM)功能。即
|
||||
|
||||
### 还在使用 Ubuntu 14.04 吗?
|
||||
|
||||
如果你还在使用 Ubuntu 14.04,那么你应该开始了解这些选择,因为你还有不到两个月的时间。
|
||||
如果你还在使用 Ubuntu 14.04,那么你应该开始了解这些选择,因为你还有不到一个月的时间。
|
||||
|
||||
在任何情况下,你都不能在 2019 年 4 月 30 日之后使用 Ubuntu 14.04,因为你的系统由于缺乏安全更新而容易受到攻击。无法安装新应用将是一个额外的痛苦。
|
||||
|
||||
@ -61,7 +61,7 @@ via: https://itsfoss.com/ubuntu-14-04-end-of-life/
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,53 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10731-1.html)
|
||||
[#]: subject: (How to contribute to the Raspberry Pi community)
|
||||
[#]: via: (https://opensource.com/article/19/3/contribute-raspberry-pi-community)
|
||||
[#]: author: (Anderson Silva (Red Hat) https://opensource.com/users/ansilva/users/kepler22b/users/ansilva)
|
||||
|
||||
树莓派使用入门:如何为树莓派社区做出贡献
|
||||
======
|
||||
|
||||
> 在我们的入门系列的第 13 篇文章中,发现参与树莓派社区的方法。
|
||||
|
||||
![][1]
|
||||
|
||||
这个系列已经逐渐接近尾声,我已经写了很多它的乐趣,我大多希望它能帮助人们使用树莓派进行教育或娱乐。也许这些文章能说服你买你的第一个树莓派,或者让你重新发现抽屉里的吃灰设备。如果这里有真的,那么我认为这个系列就是成功的。
|
||||
|
||||
如果你想买一台,并宣传这块绿色的小板子有多么多功能,这里有几个方法帮你与树莓派社区建立连接:
|
||||
|
||||
* 帮助改进[官方文档][2]
|
||||
* 贡献代码给依赖的[项目][3]
|
||||
* 用 Raspbian 报告 [bug][4]
|
||||
* 报告不同 ARM 架构分发版的的 bug
|
||||
* 看一眼英国国内的树莓派基金会的[代码俱乐部][5]或英国境外的[国际代码俱乐部][6],帮助孩子学习编码
|
||||
* 帮助[翻译][7]
|
||||
* 在 [Raspberry Jam][8] 当志愿者
|
||||
|
||||
这些只是你可以为树莓派社区做贡献的几种方式。最后但同样重要的是,你可以加入我并[投稿文章][9]到你最喜欢的开源网站 [Opensource.com][10]。 :-)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/contribute-raspberry-pi-community
|
||||
|
||||
作者:[Anderson Silva (Red Hat)][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/ansilva/users/kepler22b/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry_pi_community.jpg?itok=dcKwb5et
|
||||
[2]: https://www.raspberrypi.org/documentation/CONTRIBUTING.md
|
||||
[3]: https://www.raspberrypi.org/github/
|
||||
[4]: https://www.raspbian.org/RaspbianBugs
|
||||
[5]: https://www.codeclub.org.uk/
|
||||
[6]: https://www.codeclubworld.org/
|
||||
[7]: https://www.raspberrypi.org/translate/
|
||||
[8]: https://www.raspberrypi.org/jam/
|
||||
[9]: https://opensource.com/participate
|
||||
[10]: http://Opensource.com
|
@ -0,0 +1,75 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10734-1.html)
|
||||
[#]: subject: (14 days of celebrating the Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/happy-pi-day)
|
||||
[#]: author: (Anderson Silva (Red Hat) https://opensource.com/users/ansilva)
|
||||
|
||||
树莓派使用入门:庆祝树莓派的 14 天
|
||||
======
|
||||
|
||||
> 在我们关于树莓派入门系列的第 14 篇也是最后一篇文章中,回顾一下我们学到的所有东西。
|
||||
|
||||
![][1]
|
||||
|
||||
### 派节快乐!
|
||||
|
||||
每年的 3 月 14 日,我们这些极客都会庆祝派节。我们用这种方式缩写日期: `MMDD`,3 月 14 于是写成 03/14,它的数字上提醒我们 3.14,或者说 [π][2] 的前三位数字。许多美国人没有意识到的是,世界上几乎没有其他国家使用这种[日期格式][3],因此派节几乎只适用于美国,尽管它在全球范围内得到了庆祝。
|
||||
|
||||
无论你身在何处,让我们一起庆祝树莓派,并通过回顾过去两周我们所涉及的主题来结束本系列:
|
||||
|
||||
* 第 1 天:[你应该选择哪种树莓派?][4]
|
||||
* 第 2 天:[如何购买树莓派][5]
|
||||
* 第 3 天:[如何启动一个新的树莓派][6]
|
||||
* 第 4 天:[用树莓派学习 Linux][7]
|
||||
* 第 5 天:[教孩子们用树莓派学编程的 5 种方法][8]
|
||||
* 第 6 天:[可以使用树莓派学习的 3 种流行编程语言][9]
|
||||
* 第 7 天:[如何更新树莓派][10]
|
||||
* 第 8 天:[如何使用树莓派来娱乐][11]
|
||||
* 第 9 天:[树莓派上的模拟器和原生 Linux 游戏][12]
|
||||
* 第 10 天:[进入物理世界 —— 如何使用树莓派的 GPIO 针脚][13]
|
||||
* 第 11 天:[通过树莓派和 kali Linux 学习计算机安全][14]
|
||||
* 第 12 天:[在树莓派上使用 Mathematica 进行高级数学运算][15]
|
||||
* 第 13 天:[如何为树莓派社区做出贡献][16]
|
||||
|
||||
![Pi Day illustration][18]
|
||||
|
||||
我将结束本系列,感谢所有关注的人,尤其是那些在过去 14 天里从中学到了东西的人!我还想鼓励大家不断扩展他们对树莓派以及围绕它构建的所有开源(和闭源)技术的了解。
|
||||
|
||||
我还鼓励你了解其他文化、哲学、宗教和世界观。让我们成为人类的是这种惊人的 (有时是有趣的) 能力,我们不仅要适应外部环境,而且要适应智力环境。
|
||||
|
||||
不管你做什么,保持学习!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/happy-pi-day
|
||||
|
||||
作者:[Anderson Silva (Red Hat)][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/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry-pi-juggle.png?itok=oTgGGSRA
|
||||
[2]: https://www.piday.org/million/
|
||||
[3]: https://en.wikipedia.org/wiki/Date_format_by_country
|
||||
[4]: https://linux.cn/article-10611-1.html
|
||||
[5]: https://linux.cn/article-10615-1.html
|
||||
[6]: https://linux.cn/article-10644-1.html
|
||||
[7]: https://linux.cn/article-10645-1.html
|
||||
[8]: https://linux.cn/article-10653-1.html
|
||||
[9]: https://linux.cn/article-10661-1.html
|
||||
[10]: https://linux.cn/article-10665-1.html
|
||||
[11]: https://linux.cn/article-10669-1.html
|
||||
[12]: https://linux.cn/article-10682-1.html
|
||||
[13]: https://linux.cn/article-10687-1.html
|
||||
[14]: https://linux.cn/article-10690-1.html
|
||||
[15]: https://linux.cn/article-10711-1.html
|
||||
[16]: https://linux.cn/article-10731-1.html
|
||||
[17]: /file/426561
|
||||
[18]: https://opensource.com/sites/default/files/uploads/raspberrypi_14_piday.jpg (Pi Day illustration)
|
@ -92,7 +92,7 @@ via: https://itsfoss.com/history-of-firefox
|
||||
[3]: https://en.wikipedia.org/wiki/Tim_Berners-Lee
|
||||
[4]: https://www.w3.org/DesignIssues/TimBook-old/History.html
|
||||
[5]: http://viola.org/
|
||||
[6]: https://en.wikipedia.org/wiki/Mosaic_(web_browser
|
||||
[6]: https://en.wikipedia.org/wiki/Mosaic_(web_browser)
|
||||
[7]: http://www.computinghistory.org.uk/det/1789/Marc-Andreessen/
|
||||
[8]: http://www.davetitus.com/mozilla/
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/Mozilla_boxing.jpg?ssl=1
|
||||
@ -110,7 +110,7 @@ via: https://itsfoss.com/history-of-firefox
|
||||
[21]: https://en.wikipedia.org/wiki/Usage_share_of_web_browsers
|
||||
[22]: http://gs.statcounter.com/browser-market-share/desktop/worldwide/#monthly-201901-201901-bar
|
||||
[23]: https://en.wikipedia.org/wiki/Red_panda
|
||||
[24]: https://en.wikipedia.org/wiki/Flock_(web_browser
|
||||
[24]: https://en.wikipedia.org/wiki/Flock_(web_browser)
|
||||
[25]: https://www.windowscentral.com/microsoft-building-chromium-powered-web-browser-windows-10
|
||||
[26]: https://itsfoss.com/why-firefox/
|
||||
[27]: https://itsfoss.com/firefox-quantum-ubuntu/
|
@ -1,24 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10732-1.html)
|
||||
[#]: subject: (Sweet Home 3D: An open source tool to help you decide on your dream home)
|
||||
[#]: via: (https://opensource.com/article/19/3/tool-find-home)
|
||||
[#]: author: (Jeff Macharyas (Community Moderator) )
|
||||
|
||||
Sweet Home 3D:一个帮助你决定梦想家庭的开源工具
|
||||
Sweet Home 3D:一个帮助你寻找梦想家庭的开源工具
|
||||
======
|
||||
|
||||
室内设计应用可以轻松渲染你喜欢的房子,不管是真实的或是想象的。
|
||||
> 室内设计应用可以轻松渲染你喜欢的房子,不管是真实的或是想象的。
|
||||
|
||||
![Houses in a row][1]
|
||||
|
||||
我最近接受了一份在弗吉尼亚州的新工作。由于我妻子一直在纽约工作,看着我们在纽约的房子直至出售,我有责任出去为我们和我们的猫找一所新房子。在我们搬进去之前她不会看到的房子!
|
||||
我最近接受了一份在弗吉尼亚州的新工作。由于我妻子一直在纽约工作,看着我们在纽约的房子直至出售,我有责任出去为我们和我们的猫找一所新房子。在我们搬进去之前她看不到新房子。
|
||||
|
||||
我和一个房地产经纪人签约,并看了几间房子,拍了许多照片,写下了潦草的笔记。晚上,我会将照片上传到 Google Drive 文件夹中,我和我老婆会通过手机同时查看这些照片,同时我还想记住房间是在右边还是左边,是否有风扇等。
|
||||
我和一个房地产经纪人签约,并看了几间房子,拍了许多照片,写下了潦草的笔记。晚上,我会将照片上传到 Google Drive 文件夹中,我和我老婆会通过手机同时查看这些照片,同时我还要记住房间是在右边还是左边,是否有风扇等。
|
||||
|
||||
由于这是一个相当繁琐且不太准确的方式来展示我的发现,我因此去寻找一个开源解决方案,以更好地展示我们未来的梦想之家将会是什么样的,而不会取决于我的模糊记忆和模糊的照片。
|
||||
由于这是一个相当繁琐且不太准确的展示我的发现的方式,我因此去寻找一个开源解决方案,以更好地展示我们未来的梦想之家将会是什么样的,而不会取决于我的模糊记忆和模糊的照片。
|
||||
|
||||
[Sweet Home 3D][2] 完全满足了我的要求。Sweet Home 3D 可在 Sourceforge 上获取,并在 GNU 通用公共许可证下发布。它的[网站][3]信息非常丰富,我能够立即启动并运行。Sweet Home 3D 由总部位于巴黎的 eTeks 的 Emmanuel Puybaret 开发。
|
||||
|
||||
@ -32,19 +32,19 @@ Sweet Home 3D:一个帮助你决定梦想家庭的开源工具
|
||||
|
||||
现在我画完了“内墙”,我从网站下载了各种“家具”,其中包括实际的家具以及门、窗、架子等。每个项目都以 ZIP 文件的形式下载,因此我创建了一个包含所有未压缩文件的文件夹。我可以自定义每件家具和重复的物品比如门,可以方便地复制粘贴到指定的地方。
|
||||
|
||||
在我将所有墙壁和门窗都布置完后,我就使用应用的 3D 视图浏览房屋。根据照片和记忆,我对所有物体进行了调整直到接近房屋的样子。我可以花更多时间添加纹理,附属家具和物品,但这已经达到了我需要的程度。
|
||||
在我将所有墙壁和门窗都布置完后,我就使用这个应用的 3D 视图浏览房屋。根据照片和记忆,我对所有物体进行了调整,直到接近房屋的样子。我可以花更多时间添加纹理,附属家具和物品,但这已经达到了我需要的程度。
|
||||
|
||||
![Sweet Home 3D floorplan][7]
|
||||
|
||||
完成之后,我将计划导出为 OBJ 文件,它可在各种程序中打开,例如 [Blender][8] 和 Mac 上的 Preview,方便旋转房屋并从各个角度查看。视频功能最有用,我可以创建一个起点,然后在房子中绘制一条路径,并记录“旅程”。我将视频导出为 MOV 文件,并使用 QuickTime 在 Mac 上打开和查看。
|
||||
完成之后,我将该项目导出为 OBJ 文件,它可在各种程序中打开,例如 [Blender][8] 和 Mac 上的“预览”中,方便旋转房屋并从各个角度查看。视频功能最有用,我可以创建一个起点,然后在房子中绘制一条路径,并记录“旅程”。我将视频导出为 MOV 文件,并使用 QuickTime 在 Mac 上打开和查看。
|
||||
|
||||
我的妻子能够(几乎)所有我看到的,我们甚至可以开始在搬家前布置家具。现在,我所要做的就是装上卡车搬到新家。
|
||||
我的妻子能够(几乎)能看到所有我看到的,我们甚至可以开始在搬家前布置家具。现在,我所要做的就是把行李装上卡车搬到新家。
|
||||
|
||||
Sweet Home 3D 在我的新工作中也是有用的。我正在寻找一种方法来改善学院建筑的地图,并计划在 [Inkscape][9] 或 Illustrator 或其他软件中重新绘制它。但是,由于我有平面地图,我可以使用 Sweet Home 3D 创建平面图的 3D 版本并将其上传到我们的网站以便更方便地找到地方。
|
||||
|
||||
### 开源犯罪现场?
|
||||
|
||||
一件有趣的事:根据 [Sweet Home 3D 的博客][10],“法国法医办公室(科学警察)最近选择 Sweet Home 3D 作为设计计划表示路线和犯罪现场的工具。这是法国政府建议优先考虑免费开源解决方案的具体应用。“
|
||||
一件有趣的事:根据 [Sweet Home 3D 的博客][10],“法国法医办公室(科学警察)最近选择 Sweet Home 3D 作为设计规划表示路线和犯罪现场的工具。这是法国政府建议优先考虑自由开源解决方案的具体应用。“
|
||||
|
||||
这是公民和政府如何利用开源解决方案创建个人项目、解决犯罪和建立世界的又一点证据。
|
||||
|
||||
@ -55,11 +55,11 @@ via: https://opensource.com/article/19/3/tool-find-home
|
||||
作者:[Jeff Macharyas (Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[a]: https://opensource.com/users/jeffmacharyas
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/house_home_colors_live_building.jpg?itok=HLpsIfIL (Houses in a row)
|
||||
[2]: https://sourceforge.net/projects/sweethome3d/
|
@ -0,0 +1,296 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (liujing97)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10746-1.html)
|
||||
[#]: subject: (How To Configure sudo Access In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-configure-sudo-access-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
如何在 Linux 中配置 sudo 访问权限
|
||||
======
|
||||
|
||||
Linux 系统中 root 用户拥有 Linux 中全部控制权力。Linux 系统中 root 是拥有最高权力的用户,可以在系统中实施任意的行为。
|
||||
|
||||
如果其他用户想去实施一些行为,不能为所有人都提供 root 访问权限。因为如果他或她做了一些错误的操作,没有办法去纠正它。
|
||||
|
||||
为了解决这个问题,有什么方案吗?
|
||||
|
||||
我们可以把 sudo 权限发放给相应的用户来克服这种情况。
|
||||
|
||||
`sudo` 命令提供了一种机制,它可以在不用分享 root 用户的密码的前提下,为信任的用户提供系统的管理权限。
|
||||
|
||||
他们可以执行大部分的管理操作,但又不像 root 一样有全部的权限。
|
||||
|
||||
### 什么是 sudo?
|
||||
|
||||
`sudo` 是一个程序,普通用户可以使用它以超级用户或其他用户的身份执行命令,是由安全策略指定的。
|
||||
|
||||
sudo 用户的访问权限是由 `/etc/sudoers` 文件控制的。
|
||||
|
||||
### sudo 用户有什么优点?
|
||||
|
||||
在 Linux 系统中,如果你不熟悉一个命令,`sudo` 是运行它的一个安全方式。
|
||||
|
||||
* Linux 系统在 `/var/log/secure` 和 `/var/log/auth.log` 文件中保留日志,并且你可以验证 sudo 用户实施了哪些行为操作。
|
||||
* 每一次它都为当前的操作提示输入密码。所以,你将会有时间去验证这个操作是不是你想要执行的。如果你发觉它是不正确的行为,你可以安全地退出而且没有执行此操作。
|
||||
|
||||
基于 RHEL 的系统(如 Redhat (RHEL)、 CentOS 和 Oracle Enterprise Linux (OEL))和基于 Debian 的系统(如 Debian、Ubuntu 和 LinuxMint)在这点是不一样的。
|
||||
|
||||
我们将会教你如何在本文中提及的两种发行版中执行该操作。
|
||||
|
||||
这里有三种方法可以应用于两个发行版本。
|
||||
|
||||
* 增加用户到相应的组。基于 RHEL 的系统,我们需要添加用户到 `wheel` 组。基于 Debain 的系统,我们添加用户到 `sudo` 或 `admin` 组。
|
||||
* 手动添加用户到 `/etc/group` 文件中。
|
||||
* 用 `visudo` 命令添加用户到 `/etc/sudoers` 文件中。
|
||||
|
||||
### 如何在 RHEL/CentOS/OEL 系统中配置 sudo 访问权限?
|
||||
|
||||
在基于 RHEL 的系统中(如 Redhat (RHEL)、 CentOS 和 Oracle Enterprise Linux (OEL)),使用下面的三个方法就可以做到。
|
||||
|
||||
#### 方法 1:在 Linux 中如何使用 wheel 组为普通用户授予超级用户访问权限?
|
||||
|
||||
wheel 是基于 RHEL 的系统中的一个特殊组,它提供额外的权限,可以授权用户像超级用户一样执行受到限制的命令。
|
||||
|
||||
注意,应该在 `/etc/sudoers` 文件中激活 `wheel` 组来获得该访问权限。
|
||||
|
||||
```
|
||||
# grep -i wheel /etc/sudoers
|
||||
|
||||
## Allows people in group wheel to run all commands
|
||||
%wheel ALL=(ALL) ALL
|
||||
# %wheel ALL=(ALL) NOPASSWD: ALL
|
||||
```
|
||||
|
||||
假设我们已经创建了一个用户账号来执行这些操作。在此,我将会使用 `daygeek` 这个用户账号。
|
||||
|
||||
执行下面的命令,添加用户到 `wheel` 组。
|
||||
|
||||
```
|
||||
# usermod -aG wheel daygeek
|
||||
```
|
||||
|
||||
我们可以通过下面的命令来确定这一点。
|
||||
|
||||
```
|
||||
# getent group wheel
|
||||
wheel:x:10:daygeek
|
||||
```
|
||||
|
||||
我将要检测用户 `daygeek` 是否可以访问属于 root 用户的文件。
|
||||
|
||||
```
|
||||
$ tail -5 /var/log/secure
|
||||
tail: cannot open /var/log/secure for reading: Permission denied
|
||||
```
|
||||
|
||||
当我试图以普通用户身份访问 `/var/log/secure` 文件时出现错误。 我将使用 `sudo` 访问同一个文件,让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo tail -5 /var/log/secure
|
||||
[sudo] password for daygeek:
|
||||
Mar 17 07:01:56 CentOS7 sudo: daygeek : TTY=pts/0 ; PWD=/home/daygeek ; USER=root ; COMMAND=/bin/tail -5 /var/log/secure
|
||||
Mar 17 07:01:56 CentOS7 sudo: pam_unix(sudo:session): session opened for user root by daygeek(uid=0)
|
||||
Mar 17 07:01:56 CentOS7 sudo: pam_unix(sudo:session): session closed for user root
|
||||
Mar 17 07:05:10 CentOS7 sudo: daygeek : TTY=pts/0 ; PWD=/home/daygeek ; USER=root ; COMMAND=/bin/tail -5 /var/log/secure
|
||||
Mar 17 07:05:10 CentOS7 sudo: pam_unix(sudo:session): session opened for user root by daygeek(uid=0)
|
||||
```
|
||||
|
||||
#### 方法 2:在 RHEL/CentOS/OEL 中如何使用 /etc/group 文件为普通用户授予超级用户访问权限?
|
||||
|
||||
我们可以通过编辑 `/etc/group` 文件来手动地添加用户到 `wheel` 组。
|
||||
|
||||
只需打开该文件,并在恰当的组后追加相应的用户就可完成这一点。
|
||||
|
||||
```
|
||||
$ grep -i wheel /etc/group
|
||||
wheel:x:10:daygeek,user1
|
||||
```
|
||||
|
||||
在该例中,我将使用 `user1` 这个用户账号。
|
||||
|
||||
我将要通过在系统中重启 Apache httpd 服务来检查用户 `user1` 是不是拥有 sudo 访问权限。让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart httpd
|
||||
[sudo] password for user1:
|
||||
|
||||
$ sudo grep -i user1 /var/log/secure
|
||||
[sudo] password for user1:
|
||||
Mar 17 07:09:47 CentOS7 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/systemctl restart httpd
|
||||
Mar 17 07:10:40 CentOS7 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/systemctl restart httpd
|
||||
Mar 17 07:12:35 CentOS7 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/grep -i httpd /var/log/secure
|
||||
```
|
||||
|
||||
#### 方法 3:在 Linux 中如何使用 /etc/sudoers 文件为普通用户授予超级用户访问权限?
|
||||
|
||||
sudo 用户的访问权限是被 `/etc/sudoers` 文件控制的。因此,只需将用户添加到 `sudoers` 文件中 的 `wheel` 组下即可。
|
||||
|
||||
只需通过 `visudo` 命令将期望的用户追加到 `/etc/sudoers` 文件中。
|
||||
|
||||
```
|
||||
# grep -i user2 /etc/sudoers
|
||||
user2 ALL=(ALL) ALL
|
||||
```
|
||||
|
||||
在该例中,我将使用 `user2` 这个用户账号。
|
||||
|
||||
我将要通过在系统中重启 MariaDB 服务来检查用户 `user2` 是不是拥有 sudo 访问权限。让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart mariadb
|
||||
[sudo] password for user2:
|
||||
|
||||
$ sudo grep -i mariadb /var/log/secure
|
||||
[sudo] password for user2:
|
||||
Mar 17 07:23:10 CentOS7 sudo: user2 : TTY=pts/0 ; PWD=/home/user2 ; USER=root ; COMMAND=/bin/systemctl restart mariadb
|
||||
Mar 17 07:26:52 CentOS7 sudo: user2 : TTY=pts/0 ; PWD=/home/user2 ; USER=root ; COMMAND=/bin/grep -i mariadb /var/log/secure
|
||||
```
|
||||
|
||||
### 在 Debian/Ubuntu 系统中如何配置 sudo 访问权限?
|
||||
|
||||
在基于 Debian 的系统中(如 Debian、Ubuntu 和 LinuxMint),使用下面的三个方法就可以做到。
|
||||
|
||||
#### 方法 1:在 Linux 中如何使用 sudo 或 admin 组为普通用户授予超级用户访问权限?
|
||||
|
||||
`sudo` 或 `admin` 是基于 Debian 的系统中的特殊组,它提供额外的权限,可以授权用户像超级用户一样执行受到限制的命令。
|
||||
|
||||
注意,应该在 `/etc/sudoers` 文件中激活 `sudo` 或 `admin` 组来获得该访问权限。
|
||||
|
||||
```
|
||||
# grep -i 'sudo\|admin' /etc/sudoers
|
||||
|
||||
# Members of the admin group may gain root privileges
|
||||
%admin ALL=(ALL) ALL
|
||||
|
||||
# Allow members of group sudo to execute any command
|
||||
%sudo ALL=(ALL:ALL) ALL
|
||||
```
|
||||
|
||||
假设我们已经创建了一个用户账号来执行这些操作。在此,我将会使用 `2gadmin` 这个用户账号。
|
||||
|
||||
执行下面的命令,添加用户到 `sudo` 组。
|
||||
|
||||
```
|
||||
# usermod -aG sudo 2gadmin
|
||||
```
|
||||
|
||||
我们可以通过下面的命令来确定这一点。
|
||||
|
||||
```
|
||||
# getent group sudo
|
||||
sudo:x:27:2gadmin
|
||||
```
|
||||
|
||||
我将要检测用户 `2gadmin` 是否可以访问属于 root 用户的文件。
|
||||
|
||||
```
|
||||
$ less /var/log/auth.log
|
||||
/var/log/auth.log: Permission denied
|
||||
```
|
||||
|
||||
当我试图以普通用户身份访问 `/var/log/auth.log` 文件时出现错误。 我将要使用 `sudo` 访问同一个文件,让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo tail -5 /var/log/auth.log
|
||||
[sudo] password for 2gadmin:
|
||||
Mar 17 20:39:47 Ubuntu18 sudo: 2gadmin : TTY=pts/0 ; PWD=/home/2gadmin ; USER=root ; COMMAND=/bin/bash
|
||||
Mar 17 20:39:47 Ubuntu18 sudo: pam_unix(sudo:session): session opened for user root by 2gadmin(uid=0)
|
||||
Mar 17 20:40:23 Ubuntu18 sudo: pam_unix(sudo:session): session closed for user root
|
||||
Mar 17 20:40:48 Ubuntu18 sudo: 2gadmin : TTY=pts/0 ; PWD=/home/2gadmin ; USER=root ; COMMAND=/usr/bin/tail -5 /var/log/auth.log
|
||||
Mar 17 20:40:48 Ubuntu18 sudo: pam_unix(sudo:session): session opened for user root by 2gadmin(uid=0)
|
||||
```
|
||||
|
||||
或者,我们可以通过添加用户到 `admin` 组来执行相同的操作。
|
||||
|
||||
运行下面的命令,添加用户到 `admin` 组。
|
||||
|
||||
```
|
||||
# usermod -aG admin user1
|
||||
```
|
||||
|
||||
我们可以通过下面的命令来确定这一点。
|
||||
|
||||
```
|
||||
# getent group admin
|
||||
admin:x:1011:user1
|
||||
```
|
||||
|
||||
让我们看看输出信息。
|
||||
|
||||
```
|
||||
$ sudo tail -2 /var/log/auth.log
|
||||
[sudo] password for user1:
|
||||
Mar 17 20:53:36 Ubuntu18 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/usr/bin/tail -2 /var/log/auth.log
|
||||
Mar 17 20:53:36 Ubuntu18 sudo: pam_unix(sudo:session): session opened for user root by user1(uid=0)
|
||||
```
|
||||
|
||||
#### 方法 2:在 Debian/Ubuntu 中如何使用 /etc/group 文件为普通用户授予超级用户访问权限?
|
||||
|
||||
我们可以通过编辑 `/etc/group` 文件来手动地添加用户到 `sudo` 组或 `admin` 组。
|
||||
|
||||
只需打开该文件,并在恰当的组后追加相应的用户就可完成这一点。
|
||||
|
||||
```
|
||||
$ grep -i sudo /etc/group
|
||||
sudo:x:27:2gadmin,user2
|
||||
```
|
||||
|
||||
在该例中,我将使用 `user2` 这个用户账号。
|
||||
|
||||
我将要通过在系统中重启 Apache httpd 服务来检查用户 `user2` 是不是拥有 `sudo` 访问权限。让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart apache2
|
||||
[sudo] password for user2:
|
||||
|
||||
$ sudo tail -f /var/log/auth.log
|
||||
[sudo] password for user2:
|
||||
Mar 17 21:01:04 Ubuntu18 systemd-logind[559]: New session 22 of user user2.
|
||||
Mar 17 21:01:04 Ubuntu18 systemd: pam_unix(systemd-user:session): session opened for user user2 by (uid=0)
|
||||
Mar 17 21:01:33 Ubuntu18 sudo: user2 : TTY=pts/0 ; PWD=/home/user2 ; USER=root ; COMMAND=/bin/systemctl restart apache2
|
||||
```
|
||||
|
||||
#### 方法 3:在 Linux 中如何使用 /etc/sudoers 文件为普通用户授予超级用户访问权限?
|
||||
|
||||
sudo 用户的访问权限是被 `/etc/sudoers` 文件控制的。因此,只需将用户添加到 `sudoers` 文件中的 `sudo` 或 `admin` 组下即可。
|
||||
|
||||
只需通过 `visudo` 命令将期望的用户追加到 `/etc/sudoers` 文件中。
|
||||
|
||||
```
|
||||
# grep -i user3 /etc/sudoers
|
||||
user3 ALL=(ALL:ALL) ALL
|
||||
```
|
||||
|
||||
在该例中,我将使用 `user3` 这个用户账号。
|
||||
|
||||
我将要通过在系统中重启 MariaDB 服务来检查用户 `user3` 是不是拥有 `sudo` 访问权限。让我们看看这个魔术。
|
||||
|
||||
```
|
||||
$ sudo systemctl restart mariadb
|
||||
[sudo] password for user3:
|
||||
|
||||
$ sudo tail -f /var/log/auth.log
|
||||
[sudo] password for user3:
|
||||
Mar 17 21:12:32 Ubuntu18 systemd-logind[559]: New session 24 of user user3.
|
||||
Mar 17 21:12:49 Ubuntu18 sudo: user3 : TTY=pts/0 ; PWD=/home/user3 ; USER=root ; COMMAND=/bin/systemctl restart mariadb
|
||||
Mar 17 21:12:49 Ubuntu18 sudo: pam_unix(sudo:session): session opened for user root by user3(uid=0)
|
||||
Mar 17 21:12:53 Ubuntu18 sudo: pam_unix(sudo:session): session closed for user root
|
||||
Mar 17 21:13:08 Ubuntu18 sudo: user3 : TTY=pts/0 ; PWD=/home/user3 ; USER=root ; COMMAND=/usr/bin/tail -f /var/log/auth.log
|
||||
Mar 17 21:13:08 Ubuntu18 sudo: pam_unix(sudo:session): session opened for user root by user3(uid=0)
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-configure-sudo-access-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[liujing97](https://github.com/liujing97)
|
||||
校对:[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
|
@ -0,0 +1,183 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "zero-MK"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-10766-1.html"
|
||||
[#]: subject: "How To Check If A Port Is Open On Multiple Remote Linux System Using Shell Script With nc Command?"
|
||||
[#]: via: "https://www.2daygeek.com/check-a-open-port-on-multiple-remote-linux-server-using-nc-command/"
|
||||
[#]: author: "Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/"
|
||||
|
||||
|
||||
如何检查多个远程 Linux 系统是否打开了指定端口?
|
||||
======
|
||||
|
||||
我们最近写了一篇文章关于如何检查远程 Linux 服务器是否打开指定端口。它能帮助你检查单个服务器。
|
||||
|
||||
如果要检查五个服务器有没有问题,可以使用以下任何一个命令,如 `nc`(netcat)、`nmap` 和 `telnet`。但是如果想检查 50 多台服务器,那么你的解决方案是什么?
|
||||
|
||||
要检查所有服务器并不容易,如果你一个一个这样做,完全没有必要,因为这样你将会浪费大量的时间。为了解决这种情况,我使用 `nc` 命令编写了一个 shell 小脚本,它将允许我们扫描任意数量服务器给定的端口。
|
||||
|
||||
如果你要查找单个服务器扫描,你有多个选择,你只需阅读 [检查远程 Linux 系统上的端口是否打开?][1] 了解更多信息。
|
||||
|
||||
本教程中提供了两个脚本,这两个脚本都很有用。这两个脚本都用于不同的目的,你可以通过阅读标题轻松理解其用途。
|
||||
|
||||
在你阅读这篇文章之前,我会问你几个问题,如果你不知道答案你可以通过阅读这篇文章来获得答案。
|
||||
|
||||
如何检查一个远程 Linux 服务器上指定的端口是否打开?
|
||||
|
||||
如何检查多个远程 Linux 服务器上指定的端口是否打开?
|
||||
|
||||
如何检查多个远程 Linux 服务器上是否打开了多个指定的端口?
|
||||
|
||||
### 什么是 nc(netcat)命令?
|
||||
|
||||
`nc` 即 netcat。它是一个简单实用的 Unix 程序,它使用 TCP 或 UDP 协议进行跨网络连接进行数据读取和写入。
|
||||
|
||||
它被设计成一个可靠的 “后端” 工具,我们可以直接使用或由其他程序和脚本轻松驱动它。
|
||||
|
||||
同时,它也是一个功能丰富的网络调试和探索工具,因为它可以创建你需要的几乎任何类型的连接,并具有几个有趣的内置功能。
|
||||
|
||||
netcat 有三个主要的模式。分别是连接模式,监听模式和隧道模式。
|
||||
|
||||
`nc`(netcat)的通用语法:
|
||||
|
||||
```
|
||||
$ nc [-options] [HostName or IP] [PortNumber]
|
||||
```
|
||||
|
||||
### 如何检查多个远程 Linux 服务器上的端口是否打开?
|
||||
|
||||
如果要检查多个远程 Linux 服务器上给定端口是否打开,请使用以下 shell 脚本。
|
||||
|
||||
在我的例子中,我们将检查端口 22 是否在以下远程服务器中打开,确保你已经更新文件中的服务器列表而不是使用我的服务器列表。
|
||||
|
||||
你必须确保已经更新服务器列表 :`server-list.txt` 。每个服务器(IP)应该在单独的行中。
|
||||
|
||||
```
|
||||
# cat server-list.txt
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
192.168.1.7
|
||||
```
|
||||
|
||||
使用以下脚本可以达到此目的。
|
||||
|
||||
```
|
||||
# vi port_scan.sh
|
||||
|
||||
#!/bin/sh
|
||||
for server in `more server-list.txt`
|
||||
do
|
||||
#echo $i
|
||||
nc -zvw3 $server 22
|
||||
done
|
||||
```
|
||||
|
||||
设置 `port_scan.sh` 文件的可执行权限。
|
||||
|
||||
```
|
||||
$ chmod +x port_scan.sh
|
||||
```
|
||||
|
||||
最后运行脚本来达到此目的。
|
||||
|
||||
```
|
||||
# sh port_scan.sh
|
||||
|
||||
Connection to 192.168.1.2 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.3 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.4 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.5 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.6 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.7 22 port [tcp/ssh] succeeded!
|
||||
```
|
||||
|
||||
### 如何检查多个远程 Linux 服务器上是否打开多个端口?
|
||||
|
||||
如果要检查多个服务器中的多个端口,请使用下面的脚本。
|
||||
|
||||
在我的例子中,我们将检查给定服务器的 22 和 80 端口是否打开。确保你必须替换所需的端口和服务器名称而不使用是我的。
|
||||
|
||||
你必须确保已经将要检查的端口写入 `port-list.txt` 文件中。每个端口应该在一个单独的行中。
|
||||
|
||||
```
|
||||
# cat port-list.txt
|
||||
22
|
||||
80
|
||||
```
|
||||
|
||||
你必须确保已经将要检查的服务器(IP 地址)写入 `server-list.txt` 到文件中。每个服务器(IP) 应该在单独的行中。
|
||||
|
||||
```
|
||||
# cat server-list.txt
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
192.168.1.7
|
||||
```
|
||||
|
||||
使用以下脚本来达成此目的。
|
||||
|
||||
```
|
||||
# vi multiple_port_scan.sh
|
||||
|
||||
#!/bin/sh
|
||||
for server in `more server-list.txt`
|
||||
do
|
||||
for port in `more port-list.txt`
|
||||
do
|
||||
#echo $server
|
||||
nc -zvw3 $server $port
|
||||
echo ""
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
设置 `multiple_port_scan.sh` 文件的可执行权限。
|
||||
|
||||
```
|
||||
$ chmod +x multiple_port_scan.sh
|
||||
```
|
||||
|
||||
最后运行脚本来实现这一目的。
|
||||
|
||||
```
|
||||
# sh multiple_port_scan.sh
|
||||
Connection to 192.168.1.2 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.2 80 port [tcp/http] succeeded!
|
||||
|
||||
Connection to 192.168.1.3 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.3 80 port [tcp/http] succeeded!
|
||||
|
||||
Connection to 192.168.1.4 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.4 80 port [tcp/http] succeeded!
|
||||
|
||||
Connection to 192.168.1.5 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.5 80 port [tcp/http] succeeded!
|
||||
|
||||
Connection to 192.168.1.6 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.6 80 port [tcp/http] succeeded!
|
||||
|
||||
Connection to 192.168.1.7 22 port [tcp/ssh] succeeded!
|
||||
Connection to 192.168.1.7 80 port [tcp/http] succeeded!
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/check-a-open-port-on-multiple-remote-linux-server-using-nc-command/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zero-MK](https://github.com/zero-mk)
|
||||
校对:[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-10675-1.html
|
@ -0,0 +1,222 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Modrisco)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10752-1.html)
|
||||
[#]: subject: (Getting started with Vim: The basics)
|
||||
[#]: via: (https://opensource.com/article/19/3/getting-started-vim)
|
||||
[#]: author: (Bryant Son https://opensource.com/users/brson)
|
||||
|
||||
Vim 入门:基础
|
||||
======
|
||||
|
||||
> 为工作或者新项目学习足够的 Vim 知识。
|
||||
|
||||
![Person standing in front of a giant computer screen with numbers, data][1]
|
||||
|
||||
我还清晰地记得我第一次接触 Vim 的时候。那时我还是一名大学生,计算机学院的机房里都装着 Ubuntu 系统。尽管我在上大学前也曾接触过不同的 Linux 发行版(比如 RHEL —— Red Hat 在百思买出售它的 CD),但这却是我第一次要在日常中频繁使用 Linux 系统,因为我的课程要求我这样做。当我开始使用 Linux 时,正如我的前辈和将来的后继者们一样,我感觉自己像是一名“真正的程序员”了。
|
||||
|
||||
![Real Programmers comic][2]
|
||||
|
||||
*真正的程序员,来自 [xkcd][3]*
|
||||
|
||||
学生们可以使用像 [Kate][4] 一样的图形文本编辑器,这也安装在学校的电脑上了。对于那些可以使用 shell 但不习惯使用控制台编辑器的学生,最流行的选择是 [Nano][5],它提供了很好的交互式菜单和类似于 Windows 图形文本编辑器的体验。
|
||||
|
||||
我有时会用 Nano,但当我听说 [Vi/Vim][6] 和 [Emacs][7] 能做一些很棒的事情时我决定试一试它们(主要是因为它们看起来很酷,而且我也很好奇它们有什么特别之处)。第一次使用 Vim 时吓到我了 —— 我不想搞砸任何事情!但是,一旦我掌握了它的诀窍,事情就变得容易得多,我就可以欣赏这个编辑器的强大功能了。至于 Emacs,呃,我有点放弃了,但我很高兴我坚持和 Vim 在一起。
|
||||
|
||||
在本文中,我将介绍一下 Vim(基于我的个人经验),这样你就可以在 Linux 系统上用它来作为编辑器使用了。这篇文章不会让你变成 Vim 的专家,甚至不会触及 Vim 许多强大功能的皮毛。但是起点总是很重要的,我想让开始的经历尽可能简单,剩下的则由你自己去探索。
|
||||
|
||||
### 第 0 步:打开一个控制台窗口
|
||||
|
||||
在使用 Vim 前,你需要做一些准备工作。在 Linux 操作系统打开控制台终端。(因为 Vim 也可以在 MacOS 上使用,Mac 用户也可以使用这些说明)。
|
||||
|
||||
打开终端窗口后,输入 `ls` 命令列出当前目录下的内容。然后,输入 `mkdir Tutorial` 命令创建一个名为 `Tutorial` 的新目录。通过输入 `cd Tutorial` 来进入该目录。
|
||||
|
||||
![Create a folder][8]
|
||||
|
||||
这就是全部的准备工作。现在是时候转到有趣的部分了——开始使用 Vim。
|
||||
|
||||
### 第 1 步:创建一个 Vim 文件和不保存退出
|
||||
|
||||
还记得我一开始说过我不敢使用 Vim 吗?我当时在害怕“如果我改变了一个现有的文件,把事情搞砸了怎么办?”毕竟,一些计算机科学作业要求我修改现有的文件。我想知道:_如何在不保存更改的情况下打开和关闭文件?_
|
||||
|
||||
好消息是你可以使用相同的命令在 Vim 中创建或打开文件:`vim <FILE_NAME>`,其中 `<FILE_NAME>` 表示要创建或修改的目标文件名。让我们通过输入 `vim HelloWorld.java` 来创建一个名为 `HelloWorld.java` 的文件。
|
||||
|
||||
你好,Vim!现在,讲一下 Vim 中一个非常重要的概念,可能也是最需要记住的:Vim 有多种模式,下面是 Vim 基础中需要知道的的三种:
|
||||
|
||||
模式 | 描述
|
||||
---|---
|
||||
正常模式 | 默认模式,用于导航和简单编辑
|
||||
插入模式 | 用于直接插入和修改文本
|
||||
命令行模式 | 用于执行如保存,退出等命令
|
||||
|
||||
Vim 也有其他模式,例如可视模式、选择模式和命令模式。不过上面的三种模式对我们来说已经足够用了。
|
||||
|
||||
你现在正处于正常模式,如果有文本,你可以用箭头键移动或使用其他导航键(将在稍后看到)。要确定你正处于正常模式,只需按下 `esc` (Escape)键即可。
|
||||
|
||||
> **提示:** `Esc` 切换到正常模式。即使你已经在正常模式下,点击 `Esc` 只是为了练习。
|
||||
|
||||
现在,有趣的事情发生了。输入 `:` (冒号键)并接着 `q!` (完整命令:`:q!`)。你的屏幕将显示如下:
|
||||
|
||||
![Editing Vim][9]
|
||||
|
||||
在正常模式下输入冒号会将 Vim 切换到命令行模式,执行 `:q!` 命令将退出 Vim 编辑器而不进行保存。换句话说,你放弃了所有的更改。你也可以使用 `ZQ` 命令;选择你认为更方便的选项。
|
||||
|
||||
一旦你按下 `Enter` (回车),你就不再在 Vim 中。重复练习几次来掌握这条命令。熟悉了这部分内容之后,请转到下一节,了解如何对文件进行更改。
|
||||
|
||||
### 第 2 步:在 Vim 中修改并保存
|
||||
|
||||
通过输入 `vim HelloWorld.java` 和回车键来再次打开这个文件。你可以在插入模式中修改文件。首先,通过 `Esc` 键来确定你正处于正常模式。接着输入 `i` 来进入插入模式(没错,就是字母 **i**)。
|
||||
|
||||
在左下角,你将看到 `-- INSERT --`,这标志着你这处于插入模式。
|
||||
|
||||
![Vim insert mode][10]
|
||||
|
||||
写一些 Java 代码。你可以写任何你想写的,不过这也有一份你可以参照的例子。你的屏幕将显示如下:
|
||||
|
||||
```
|
||||
public class HelloWorld {
|
||||
public static void main([String][11][] args) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
非常漂亮!注意文本是如何在 Java 语法中高亮显示的。因为这是个 Java 文件,所以 Vim 将自动检测语法并高亮颜色。
|
||||
|
||||
保存文件:按下 `Esc` 来退出插入模式并进入命令行模式。输入 `:` 并接着 `x!` (完整命令:`:x!`),按回车键来保存文件。你也可以输入 `wq` 来执行相同的操作。
|
||||
|
||||
现在,你知道了如何使用插入模式输入文本并使用以下命令保存文件:`:x!` 或者 `:wq`。
|
||||
|
||||
### 第 3 步:Vim 中的基本导航
|
||||
|
||||
虽然你总是可以使用上箭头、下箭头、左箭头和右箭头在文件中移动,但在一个几乎有数不清行数的大文件中,这将是非常困难的。能够在一行中跳跃光标将会是很有用的。虽然 Vim 提供了不少很棒的导航功能,不过在一开始,我想向你展示如何在 Vim 中到达某一特定的行。
|
||||
|
||||
单击 `Esc` 来确定你处于正常模式,接着输入 `:set number` 并键入回车。
|
||||
|
||||
瞧!你现在可以在每一行的左侧看到行号。
|
||||
|
||||
![Showing Line Numbers][12]
|
||||
|
||||
好,你也许会说,“这确实很酷,不过我该怎么跳到某一行呢?”再一次的,确认你正处于正常模式。接着输入 `:<LINE_NUMBER>`,在这里 `<LINE_NUMBER>` 是你想去的那一行的行数。按下回车键来试着移动到第二行。
|
||||
|
||||
```
|
||||
:2
|
||||
```
|
||||
|
||||
现在,跳到第三行。
|
||||
|
||||
![Jump to line 3][13]
|
||||
|
||||
但是,假如你正在处理一个一千多行的文件,而你正想到文件底部。这该怎么办呢?确认你正处于正常模式,接着输入 `:$` 并按下回车。
|
||||
|
||||
你将来到最后一行!
|
||||
|
||||
现在,你知道如何在行间跳跃了,作为补充,我们来学一下如何移动到一行的行尾。确认你正处于有文本内容的一行,如第三行,接着输入 `$`。
|
||||
|
||||
![Go to the last character][14]
|
||||
|
||||
你现在来到这行的最后一个字节了。在此示例中,高亮左大括号以显示光标移动到的位置,右大括号被高亮是因为它是高亮的左大括号的匹配字符。
|
||||
|
||||
这就是 Vim 中的基本导航功能。等等,别急着退出文件。让我们转到 Vim 中的基本编辑。不过,你可以暂时顺便喝杯咖啡或茶休息一下。
|
||||
|
||||
### 第 4 步:Vim 中的基本编辑
|
||||
|
||||
现在,你已经知道如何通过跳到想要的一行来在文件中导航,你可以使用这个技能在 Vim 中进行一些基本编辑。切换到插入模式。(还记得怎么做吗?是不是输入 `i` ?)当然,你可以使用键盘逐一删除或插入字符来进行编辑,但是 Vim 提供了更快捷的方法来编辑文件。
|
||||
|
||||
来到第三行,这里的代码是 `public static void main(String[] args) {`。双击 `d` 键,没错,就是 `dd`。如果你成功做到了,你将会看到,第三行消失了,剩下的所有行都向上移动了一行。(例如,第四行变成了第三行)。
|
||||
|
||||
![Deleting A Line][15]
|
||||
|
||||
这就是<ruby>删除<rt>delete</rt></ruby>命令。不要担心,键入 `u`,你会发现这一行又回来了。喔,这就是<ruby>撤销<rt>undo</rt></ruby>命令。
|
||||
|
||||
![Undoing a change in Vim][16]
|
||||
|
||||
下一课是学习如何复制和粘贴文本,但首先,你需要学习如何在 Vim 中突出显示文本。按下 `v` 并向左右移动光标来选择或反选文本。当你向其他人展示代码并希望标识你想让他们注意到的代码时,这个功能也非常有用。
|
||||
|
||||
![Highlighting text in Vim][17]
|
||||
|
||||
来到第四行,这里的代码是 `System.out.println("Hello, Opensource");`。高亮这一行的所有内容。好了吗?当第四行的内容处于高亮时,按下 `y`。这就叫做<ruby>复制<rt>yank</rt></ruby>模式,文本将会被复制到剪贴板上。接下来,输入 `o` 来创建新的一行。注意,这将让你进入插入模式。通过按 `Esc` 退出插入模式,然后按下 `p`,代表<ruby>粘贴<rt>paste</rt></ruby>。这将把复制的文本从第三行粘贴到第四行。
|
||||
|
||||
![Pasting in Vim][18]
|
||||
|
||||
作为练习,请重复这些步骤,但也要修改新创建的行中的文字。此外,请确保这些行对齐工整。
|
||||
|
||||
> **提示:** 您需要在插入模式和命令行模式之间来回切换才能完成此任务。
|
||||
|
||||
当你完成了,通过 `x!` 命令保存文件。以上就是 Vim 基本编辑的全部内容。
|
||||
|
||||
### 第 5 步:Vim 中的基本搜索
|
||||
|
||||
假设你的团队领导希望你更改项目中的文本字符串。你该如何快速完成任务?你可能希望使用某个关键字来搜索该行。
|
||||
|
||||
Vim 的搜索功能非常有用。通过 `Esc` 键来进入命令模式,然后输入冒号 `:`,我们可以通过输入 `/<SEARCH_KEYWORD>` 来搜索关键词, `<SEARCH_KEYWORD>` 指你希望搜索的字符串。在这里,我们搜索关键字符串 `Hello`。在下面的图示中没有显示冒号,但这是必须输入的。
|
||||
|
||||
![Searching in Vim][19]
|
||||
|
||||
但是,一个关键字可以出现不止一次,而这可能不是你想要的那一个。那么,如何找到下一个匹配项呢?只需按 `n` 键即可,这代表<ruby>下一个<rt>next</rt></ruby>。执行此操作时,请确保你没有处于插入模式!
|
||||
|
||||
### 附加步骤:Vim 中的分割模式
|
||||
|
||||
以上几乎涵盖了所有的 Vim 基础知识。但是,作为一个额外奖励,我想给你展示 Vim 一个很酷的特性,叫做<ruby>分割<rt>split</rt></ruby>模式。
|
||||
|
||||
退出 `HelloWorld.java` 并创建一个新文件。在控制台窗口中,输入 `vim GoodBye.java` 并按回车键来创建一个名为 `GoodBye.java` 的新文件。
|
||||
|
||||
输入任何你想输入的让内容,我选择输入 `Goodbye`。保存文件(记住你可以在命令模式中使用 `:x!` 或者 `:wq`)。
|
||||
|
||||
在命令模式中,输入 `:split HelloWorld.java`,来看看发生了什么。
|
||||
|
||||
![Split mode in Vim][20]
|
||||
|
||||
Wow!快看! `split` 命令将控制台窗口水平分割成了两个部分,上面是 `HelloWorld.java`,下面是 `GoodBye.java`。该怎么能在窗口之间切换呢? 按住 `Control` 键(在 Mac 上)或 `Ctrl` 键(在 PC 上),然后按下 `ww` (即双击 `w` 键)。
|
||||
|
||||
作为最后一个练习,尝试通过复制和粘贴 `HelloWorld.java` 来编辑 `GoodBye.java` 以匹配下面屏幕上的内容。
|
||||
|
||||
![Modify GoodBye.java file in Split Mode][21]
|
||||
|
||||
保存两份文件,成功!
|
||||
|
||||
> **提示 1:** 如果你想将两个文件窗口垂直分割,使用 `:vsplit <FILE_NAME>` 命令。(代替 `:split <FILE_NAME>` 命令,`<FILE_NAME>` 指你想要使用分割模式打开的文件名)。
|
||||
>
|
||||
> **提示 2:** 你可以通过调用任意数量的 `split` 或者 `vsplit` 命令来打开两个以上的文件。试一试,看看它效果如何。
|
||||
|
||||
### Vim 速查表
|
||||
|
||||
在本文中,您学会了如何使用 Vim 来完成工作或项目,但这只是你开启 Vim 强大功能之旅的开始,可以查看其他很棒的教程和技巧。
|
||||
|
||||
为了让一切变得简单些,我已经将你学到的一切总结到了 [一份方便的速查表][22] 中。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/getting-started-vim
|
||||
|
||||
作者:[Bryant Son][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Modrisco](https://github.com/Modrisco)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/brson
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_metrics_analytics_desktop_laptop.png?itok=9QXd7AUr (Person standing in front of a giant computer screen with numbers, data)
|
||||
[2]: https://opensource.com/sites/default/files/uploads/1_xkcdcartoon.jpg (Real Programmers comic)
|
||||
[3]: https://xkcd.com/378/
|
||||
[4]: https://kate-editor.org
|
||||
[5]: https://www.nano-editor.org
|
||||
[6]: https://www.vim.org
|
||||
[7]: https://www.gnu.org/software/emacs
|
||||
[8]: https://opensource.com/sites/default/files/uploads/2_createtestfolder.jpg (Create a folder)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/4_existingvim.jpg (Editing Vim)
|
||||
[10]: https://opensource.com/sites/default/files/uploads/6_insertionmode.jpg (Vim insert mode)
|
||||
[11]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||
[12]: https://opensource.com/sites/default/files/uploads/10_setnumberresult_0.jpg (Showing Line Numbers)
|
||||
[13]: https://opensource.com/sites/default/files/uploads/12_jumpintoline3.jpg (Jump to line 3)
|
||||
[14]: https://opensource.com/sites/default/files/uploads/14_gotolastcharacter.jpg (Go to the last character)
|
||||
[15]: https://opensource.com/sites/default/files/uploads/15_deletinglines.jpg (Deleting A Line)
|
||||
[16]: https://opensource.com/sites/default/files/uploads/16_undoingtheline.jpg (Undoing a change in Vim)
|
||||
[17]: https://opensource.com/sites/default/files/uploads/17_highlighting.jpg (Highlighting text in Vim)
|
||||
[18]: https://opensource.com/sites/default/files/uploads/19_pasting.jpg (Pasting in Vim)
|
||||
[19]: https://opensource.com/sites/default/files/uploads/22_searchmode.jpg (Searching in Vim)
|
||||
[20]: https://opensource.com/sites/default/files/uploads/26_copytonewfiles.jpg (Split mode in Vim)
|
||||
[21]: https://opensource.com/sites/default/files/uploads/27_exercise.jpg (Modify GoodBye.java file in Split Mode)
|
||||
[22]: https://opensource.com/downloads/cheat-sheet-vim
|
@ -1,24 +1,24 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10717-1.html)
|
||||
[#]: subject: (Using Square Brackets in Bash: Part 1)
|
||||
[#]: via: (https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
在 Bash 中使用方括号 [第 1 节]
|
||||
在 Bash 中使用[方括号] (一)
|
||||
======
|
||||
|
||||
![square brackets][1]
|
||||
|
||||
> 这篇文章将要介绍方括号及其在命令行中的用法。
|
||||
> 这篇文章将要介绍方括号及其在命令行中的不同用法。
|
||||
|
||||
看完[花括号在命令行中的用法][3]之后,现在我们继续来看方括号(`[]`)在上下文中是如何发挥作用的。
|
||||
|
||||
### <ruby>通配<rt>Globbing</rt></ruby>
|
||||
### 通配
|
||||
|
||||
方括号最简单的用法就是通配。你可能在知道“通配”这个概念之前就已经通过通配来匹配内容了,列出具有相同特征的多个文件就是一个很常见的场景,例如列出所有 JPEG 文件:
|
||||
方括号最简单的用法就是通配。你可能在知道“<ruby><rt>Globbing</rt></ruby>”这个概念之前就已经通过通配来匹配内容了,列出具有相同特征的多个文件就是一个很常见的场景,例如列出所有 JPEG 文件:
|
||||
|
||||
```
|
||||
ls *.jpg
|
||||
@ -70,7 +70,7 @@ ls file0[259][278]
|
||||
cp file0[12]? archive0[12]?
|
||||
```
|
||||
|
||||
因为通配只能针对已有的文件,而 archive 开头的文件并不存在,不能进行通配。
|
||||
因为通配只能针对已有的文件,而 `archive` 开头的文件并不存在,不能进行通配。
|
||||
|
||||
而这条命令
|
||||
|
||||
@ -82,7 +82,6 @@ cp file0[12]? archive0[1..2][0..9]
|
||||
|
||||
```
|
||||
mkdir archive
|
||||
|
||||
cp file0[12]? archive
|
||||
```
|
||||
|
||||
@ -94,7 +93,6 @@ cp file0[12]? archive
|
||||
|
||||
```
|
||||
myvar="Hello World"
|
||||
|
||||
echo Goodbye Cruel ${myvar#Hello}
|
||||
```
|
||||
|
||||
@ -104,11 +102,8 @@ echo Goodbye Cruel ${myvar#Hello}
|
||||
|
||||
```
|
||||
for i in file0[12]?;\
|
||||
|
||||
do\
|
||||
|
||||
cp $i archive${i#file};\
|
||||
|
||||
done
|
||||
```
|
||||
|
||||
@ -120,7 +115,7 @@ done
|
||||
"archive" + "file019" - "file" = "archive019"
|
||||
```
|
||||
|
||||
最终整个 `cp` 命令是这样的:
|
||||
最终整个 `cp` 命令展开为:
|
||||
|
||||
```
|
||||
cp file019 archive019
|
||||
@ -137,7 +132,7 @@ via: https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -145,5 +140,5 @@ via: https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/square-gabriele-diwald-475007-unsplash.jpg?itok=cKmysLfd "square brackets"
|
||||
[2]: https://www.linux.com/LICENSES/CATEGORY/CREATIVE-COMMONS-ZERO
|
||||
[3]: https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash
|
||||
[3]: https://linux.cn/article-10624-1.html
|
||||
|
104
published/201904/20190328 How to run PostgreSQL on Kubernetes.md
Normal file
104
published/201904/20190328 How to run PostgreSQL on Kubernetes.md
Normal file
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (arrowfeng)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10762-1.html)
|
||||
[#]: subject: (How to run PostgreSQL on Kubernetes)
|
||||
[#]: via: (https://opensource.com/article/19/3/how-run-postgresql-kubernetes)
|
||||
[#]: author: (Jonathan S. Katz https://opensource.com/users/jkatz05)
|
||||
|
||||
怎样在 Kubernetes 上运行 PostgreSQL
|
||||
======
|
||||
|
||||
> 创建统一管理的,具备灵活性的云原生生产部署来部署一个个性化的数据库即服务(DBaaS)。
|
||||
|
||||
![cubes coming together to create a larger cube][1]
|
||||
|
||||
通过在 [Kubernetes][2] 上运行 [PostgreSQL][3] 数据库,你能创建统一管理的,具备灵活性的云原生生产部署应用来部署一个个性化的数据库即服务为你的特定需求进行量身定制。
|
||||
|
||||
对于 Kubernetes,使用 Operator 允许你提供额外的上下文去[管理有状态应用][4]。当使用像PostgreSQL 这样开源的数据库去执行包括配置、扩展、高可用和用户管理时,Operator 也很有帮助。
|
||||
|
||||
让我们来探索如何在 Kubernetes 上启动并运行 PostgreSQL。
|
||||
|
||||
### 安装 PostgreSQL Operator
|
||||
|
||||
将 PostgreSQL 和 Kubernetes 结合使用的第一步是安装一个 Operator。在针对 Linux 系统的Crunchy 的[快速启动脚本][6]的帮助下,你可以在任意基于 Kubernetes 的环境下启动和运行开源的[Crunchy PostgreSQL Operator][5]。
|
||||
|
||||
快速启动脚本有一些必要前提:
|
||||
|
||||
* [Wget][7] 工具已安装。
|
||||
* [kubectl][8] 工具已安装。
|
||||
* 在你的 Kubernetes 中已经定义了一个 [StorageClass][9]。
|
||||
* 拥有集群权限的可访问 Kubernetes 的用户账号,以安装 Operator 的 [RBAC][10] 规则。
|
||||
* 一个 PostgreSQL Operator 的 [命名空间][11]。
|
||||
|
||||
执行这个脚本将提供给你一个默认的 PostgreSQL Operator 部署,其默认假设你采用 [动态存储][12]和一个名为 `standard` 的 StorageClass。这个脚本允许用户采用自定义的值去覆盖这些默认值。
|
||||
|
||||
通过下列命令,你能下载这个快速启动脚本并把它的权限设置为可执行:
|
||||
|
||||
```
|
||||
wget <https://raw.githubusercontent.com/CrunchyData/postgres-operator/master/examples/quickstart.sh>
|
||||
chmod +x ./quickstart.sh
|
||||
```
|
||||
|
||||
然后你运行快速启动脚本:
|
||||
|
||||
```
|
||||
./examples/quickstart.sh
|
||||
```
|
||||
|
||||
在脚本提示你相关的 Kubernetes 集群基本信息后,它将执行下列操作:
|
||||
|
||||
* 下载 Operator 配置文件
|
||||
* 将 `$HOME/.pgouser` 这个文件设置为默认设置
|
||||
* 以 Kubernetes [Deployment][13] 部署 Operator
|
||||
* 设置你的 `.bashrc` 文件包含 Operator 环境变量
|
||||
* 设置你的 `$HOME/.bash_completion` 文件为 `pgo bash_completion` 文件
|
||||
|
||||
在快速启动脚本的执行期间,你将会被提示在你的 Kubernetes 集群设置 RBAC 规则。在另一个终端,执行快速启动命令所提示你的命令。
|
||||
|
||||
一旦这个脚本执行完成,你将会得到提示设置一个端口以转发到 PostgreSQL Operator pod。在另一个终端,执行这个端口转发操作;这将允许你开始对 PostgreSQL Operator 执行命令!尝试输入下列命令创建集群:
|
||||
|
||||
```
|
||||
pgo create cluster mynewcluster
|
||||
```
|
||||
|
||||
你能输入下列命令测试你的集群运行状况:
|
||||
|
||||
```
|
||||
pgo test mynewcluster
|
||||
```
|
||||
|
||||
现在,你能在 Kubernetes 环境下管理你的 PostgreSQL 数据库了!你可以在[官方文档][14]找到非常全面的命令,包括扩容,高可用,备份等等。
|
||||
|
||||
这篇文章部分参考了该作者为 Crunchy 博客而写的[在 Kubernetes 上开始运行 PostgreSQL][15]。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/how-run-postgresql-kubernetes
|
||||
|
||||
作者:[Jonathan S. Katz][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[arrowfeng](https://github.com/arrowfeng)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/jkatz05
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cube_innovation_process_block_container.png?itok=vkPYmSRQ (cubes coming together to create a larger cube)
|
||||
[2]: https://www.postgresql.org/
|
||||
[3]: https://kubernetes.io/
|
||||
[4]: https://opensource.com/article/19/2/scaling-postgresql-kubernetes-operators
|
||||
[5]: https://github.com/CrunchyData/postgres-operator
|
||||
[6]: https://crunchydata.github.io/postgres-operator/stable/installation/#quickstart-script
|
||||
[7]: https://www.gnu.org/software/wget/
|
||||
[8]: https://kubernetes.io/docs/tasks/tools/install-kubectl/
|
||||
[9]: https://kubernetes.io/docs/concepts/storage/storage-classes/
|
||||
[10]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
|
||||
[11]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
[12]: https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/
|
||||
[13]: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
|
||||
[14]: https://crunchydata.github.io/postgres-operator/stable/#documentation
|
||||
[15]: https://info.crunchydata.com/blog/get-started-runnning-postgresql-on-kubernetes
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10722-1.html)
|
||||
[#]: subject: (3 cool text-based email clients)
|
||||
[#]: via: (https://fedoramagazine.org/3-cool-text-based-email-clients/)
|
||||
[#]: author: (Clément Verna https://fedoramagazine.org/author/cverna/)
|
||||
@ -12,13 +12,13 @@
|
||||
|
||||
![][1]
|
||||
|
||||
编写和接收电子邮件是每个人日常工作的重要组成部分,选择电子邮件客户端通常是一个重要决定。 Fedora 系统提供了大量的电子邮件客户端选择,其中包括基于文本的电子邮件应用。
|
||||
编写和接收电子邮件是每个人日常工作的重要组成部分,选择电子邮件客户端通常是一个重要决定。Fedora 系统提供了大量的电子邮件客户端可供选择,其中包括基于文本的电子邮件应用。
|
||||
|
||||
### Mutt
|
||||
|
||||
Mutt 可能是最受欢迎的基于文本的电子邮件客户端之一。它有人们期望的所有常见功能。Mutt 支持颜色代码、邮件会话、POP3 和 IMAP。但它最好的功能之一是它具有高度可配置性。实际上,用户可以轻松地更改键绑定,并创建宏以使工具适应特定的工作流程。
|
||||
Mutt 可能是最受欢迎的基于文本的电子邮件客户端之一。它有人们期望的所有常用功能。Mutt 支持颜色代码、邮件会话、POP3 和 IMAP。但它最好的功能之一是它具有高度可配置性。实际上,用户可以轻松地更改键绑定,并创建宏以使工具适应特定的工作流程。
|
||||
|
||||
要尝试 Mutt,请[使用 sudo][2] 和 dnf 安装它:
|
||||
要尝试 Mutt,请[使用 sudo][2] 和 `dnf` 安装它:
|
||||
|
||||
```
|
||||
$ sudo dnf install mutt
|
||||
@ -28,27 +28,27 @@ $ sudo dnf install mutt
|
||||
|
||||
### Alpine
|
||||
|
||||
Alpine 也是最受欢迎的基于文本的电子邮件客户端。它比 Mutt 更适合初学者,你可以通过应用本身配置大部分功能而无需编辑文件。Alpine 的一个强大功能是能够对电子邮件进行评分。这对那些订阅含有大量邮件的邮件列表如 Fedora 的[开发列表][4]的用户来说尤其有趣。通过使用分数,Alpine 可以根据用户的兴趣对电子邮件进行排序,首先显示高分的电子邮件。
|
||||
Alpine 也是最受欢迎的基于文本的电子邮件客户端。它比 Mutt 更适合初学者,你可以通过应用本身配置大部分功能而无需编辑配置文件。Alpine 的一个强大功能是能够对电子邮件进行评分。这对那些订阅含有大量邮件的邮件列表如 Fedora 的[开发列表][4]的用户来说尤其有趣。通过使用分数,Alpine 可以根据用户的兴趣对电子邮件进行排序,首先显示高分的电子邮件。
|
||||
|
||||
也可以使用 dnf 从 Fedora 的仓库安装 Alpine。
|
||||
也可以使用 `dnf` 从 Fedora 的仓库安装 Alpine。
|
||||
|
||||
```
|
||||
$ sudo dnf install alpine
|
||||
```
|
||||
|
||||
使用 Alpine 时,你可以按 _Ctrl+G_ 组合键轻松访问文档。
|
||||
使用 Alpine 时,你可以按 `Ctrl+G` 组合键轻松访问文档。
|
||||
|
||||
### nmh
|
||||
|
||||
nmh(new Mail Handling)遵循 UNIX 工具哲学。它提供了一组用于发送、接收、保存、检索和操作电子邮件的单一用途程序。这使你可以将 _nmh_ 命令与其他程序交换,或利用 _nmh_ 编写脚本来创建更多自定义工具。例如,你可以将 Mutt 与 nmh 一起使用。
|
||||
nmh(new Mail Handling)遵循 UNIX 工具哲学。它提供了一组用于发送、接收、保存、检索和操作电子邮件的单一用途程序。这使你可以将 `nmh` 命令与其他程序交换,或利用 `nmh` 编写脚本来创建更多自定义工具。例如,你可以将 Mutt 与 `nmh` 一起使用。
|
||||
|
||||
使用 dnf 可以轻松安装 nmh。
|
||||
使用 `dnf` 可以轻松安装 `nmh`。
|
||||
|
||||
```
|
||||
$ sudo dnf install nmh
|
||||
```
|
||||
|
||||
要了解有关 nmh 和邮件处理的更多信息,你可以阅读这本 GPL 许可证的[书][5]。
|
||||
要了解有关 `nmh` 和邮件处理的更多信息,你可以阅读这本 GPL 许可的[书][5]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -57,7 +57,7 @@ via: https://fedoramagazine.org/3-cool-text-based-email-clients/
|
||||
作者:[Clément Verna][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,74 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10742-1.html)
|
||||
[#]: subject: (Parallel computation in Python with Dask)
|
||||
[#]: via: (https://opensource.com/article/19/4/parallel-computation-python-dask)
|
||||
[#]: author: (Moshe Zadka (Community Moderator) https://opensource.com/users/moshez)
|
||||
|
||||
使用 Dask 在 Python 中进行并行计算
|
||||
======
|
||||
|
||||
> Dask 库可以将 Python 计算扩展到多个核心甚至是多台机器。
|
||||
|
||||
![Pair programming][1]
|
||||
|
||||
关于 Python 性能的一个常见抱怨是[全局解释器锁][2](GIL)。由于 GIL,同一时刻只能有一个线程执行 Python 字节码。因此,即使在现代的多核机器上,使用线程也不会加速计算。
|
||||
|
||||
但当你需要并行化到多核时,你不需要放弃使用 Python:[Dask][3] 库可以将计算扩展到多个内核甚至多个机器。某些设置可以在数千台机器上配置 Dask,每台机器都有多个内核。虽然存在扩展规模的限制,但一般达不到。
|
||||
|
||||
虽然 Dask 有许多内置的数组操作,但举一个非内置的例子,我们可以计算[偏度][4]:
|
||||
|
||||
```
|
||||
import numpy
|
||||
import dask
|
||||
from dask import array as darray
|
||||
|
||||
arr = dask.from_array(numpy.array(my_data), chunks=(1000,))
|
||||
mean = darray.mean()
|
||||
stddev = darray.std(arr)
|
||||
unnormalized_moment = darry.mean(arr * arr * arr)
|
||||
## See formula in wikipedia:
|
||||
skewness = ((unnormalized_moment - (3 * mean * stddev ** 2) - mean ** 3) /
|
||||
stddev ** 3)
|
||||
```
|
||||
|
||||
请注意,每个操作将根据需要使用尽可能多的内核。这将在所有核心上并行化执行,即使在计算数十亿个元素时也是如此。
|
||||
|
||||
当然,并不是我们所有的操作都可由这个库并行化,有时我们需要自己实现并行性。
|
||||
|
||||
为此,Dask 有一个“延迟”功能:
|
||||
|
||||
```
|
||||
import dask
|
||||
|
||||
def is_palindrome(s):
|
||||
return s == s[::-1]
|
||||
|
||||
palindromes = [dask.delayed(is_palindrome)(s) for s in string_list]
|
||||
total = dask.delayed(sum)(palindromes)
|
||||
result = total.compute()
|
||||
```
|
||||
|
||||
这将计算字符串是否是回文并返回回文的数量。
|
||||
|
||||
虽然 Dask 是为数据科学家创建的,但它绝不仅限于数据科学。每当我们需要在 Python 中并行化任务时,我们可以使用 Dask —— 无论有没有 GIL。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/parallel-computation-python-dask
|
||||
|
||||
作者:[Moshe Zadka (Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/collab-team-pair-programming-code-keyboard.png?itok=kBeRTFL1 (Pair programming)
|
||||
[2]: https://wiki.python.org/moin/GlobalInterpreterLock
|
||||
[3]: https://github.com/dask/dask
|
||||
[4]: https://en.wikipedia.org/wiki/Skewness#Definition
|
@ -0,0 +1,165 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10761-1.html)
|
||||
[#]: subject: (Using Square Brackets in Bash: Part 2)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/4/using-square-brackets-bash-part-2)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
在 Bash 中使用[方括号](二)
|
||||
======
|
||||
|
||||
![square brackets][1]
|
||||
|
||||
> 我们继续来看方括号的用法,它们甚至还可以在 Bash 当中作为一个命令使用。
|
||||
|
||||
欢迎回到我们的方括号专题。在[前一篇文章][3]当中,我们介绍了方括号在命令行中可以用于通配操作,如果你已经读过前一篇文章,就可以从这里继续了。
|
||||
|
||||
方括号还可以以一个命令的形式使用,就像这样:
|
||||
|
||||
```
|
||||
[ "a" = "a" ]
|
||||
```
|
||||
|
||||
上面这种 `[ ... ]` 的形式就可以看成是一个可执行的命令。要注意,方括号内部的内容 `"a" = "a"` 和方括号 `[`、`]` 之间是有空格隔开的。因为这里的方括号被视作一个命令,因此要用空格将命令和它的参数隔开。
|
||||
|
||||
上面这个命令的含义是“判断字符串 `"a"` 和字符串 `"a"` 是否相同”,如果判断结果为真,那么 `[ ... ]` 就会以<ruby>状态码<rt>status code</rt></ruby> 0 退出,否则以状态码 1 退出。在[之前的文章][4]中,我们也有介绍过状态码的概念,可以通过 `$?` 变量获取到最近一个命令的状态码。
|
||||
|
||||
分别执行
|
||||
|
||||
```
|
||||
[ "a" = "a" ]
|
||||
echo $?
|
||||
```
|
||||
|
||||
以及
|
||||
|
||||
```
|
||||
[ "a" = "b" ]
|
||||
echo $?
|
||||
```
|
||||
|
||||
这两段命令中,前者会输出 0(判断结果为真),后者则会输出 1(判断结果为假)。在 Bash 当中,如果一个命令的状态码是 0,表示这个命令正常执行完成并退出,而且其中没有出现错误,对应布尔值 `true`;如果在命令执行过程中出现错误,就会返回一个非零的状态码,对应布尔值 `false`。而 `[ ... ]` 也同样遵循这样的规则。
|
||||
|
||||
因此,`[ ... ]` 很适合在 `if ... then`、`while` 或 `until` 这种在代码块结束前需要判断是否达到某个条件结构中使用。
|
||||
|
||||
对应使用的逻辑判断运算符也相当直观:
|
||||
|
||||
```
|
||||
[ STRING1 = STRING2 ] => 检查字符串是否相等
|
||||
[ STRING1 != STRING2 ] => 检查字符串是否不相等
|
||||
[ INTEGER1 -eq INTEGER2 ] => 检查整数 INTEGER1 是否等于 INTEGER2
|
||||
[ INTEGER1 -ge INTEGER2 ] => 检查整数 INTEGER1 是否大于等于 INTEGER2
|
||||
[ INTEGER1 -gt INTEGER2 ] => 检查整数 INTEGER1 是否大于 INTEGER2
|
||||
[ INTEGER1 -le INTEGER2 ] => 检查整数 INTEGER1 是否小于等于 INTEGER2
|
||||
[ INTEGER1 -lt INTEGER2 ] => 检查整数 INTEGER1 是否小于 INTEGER2
|
||||
[ INTEGER1 -ne INTEGER2 ] => 检查整数 INTEGER1 是否不等于 INTEGER2
|
||||
等等……
|
||||
```
|
||||
|
||||
方括号的这种用法也可以很有 shell 风格,例如通过带上 `-f` 参数可以判断某个文件是否存在:
|
||||
|
||||
```
|
||||
for i in {000..099}; \
|
||||
do \
|
||||
if [ -f file$i ]; \
|
||||
then \
|
||||
echo file$i exists; \
|
||||
else \
|
||||
touch file$i; \
|
||||
echo I made file$i; \
|
||||
fi; \
|
||||
done
|
||||
```
|
||||
|
||||
如果你在上一篇文章使用到的测试目录中运行以上这串命令,其中的第 3 行会判断那几十个文件当中的某个文件是否存在。如果文件存在,会输出一条提示信息;如果文件不存在,就会把对应的文件创建出来。最终,这个目录中会完整存在从 `file000` 到 `file099` 这一百个文件。
|
||||
|
||||
上面这段命令还可以写得更加简洁:
|
||||
|
||||
```
|
||||
for i in {000..099};\
|
||||
do\
|
||||
if [ ! -f file$i ];\
|
||||
then\
|
||||
touch file$i;\
|
||||
echo I made file$i;\
|
||||
fi;\
|
||||
done
|
||||
```
|
||||
|
||||
其中 `!` 运算符表示将判断结果取反,因此第 3 行的含义就是“如果文件 `file$i` 不存在”。
|
||||
|
||||
可以尝试一下将测试目录中那几十个文件随意删除几个,然后运行上面的命令,你就可以看到它是如何把被删除的文件重新创建出来的。
|
||||
|
||||
除了 `-f` 之外,还有很多有用的参数。`-d` 参数可以判断某个目录是否存在,`-h` 参数可以判断某个文件是不是一个符号链接。可以用 `-G` 参数判断某个文件是否属于某个用户组,用 `-ot` 参数判断某个文件的最后更新时间是否早于另一个文件,甚至还可以判断某个文件是否为空文件。
|
||||
|
||||
运行下面的几条命令,可以向几个文件中写入一些内容:
|
||||
|
||||
```
|
||||
echo "Hello World" >> file023
|
||||
echo "This is a message" >> file065
|
||||
echo "To humanity" >> file010
|
||||
```
|
||||
|
||||
然后运行:
|
||||
|
||||
```
|
||||
for i in {000..099};\
|
||||
do\
|
||||
if [ ! -s file$i ];\
|
||||
then\
|
||||
rm file$i;\
|
||||
echo I removed file$i;\
|
||||
fi;\
|
||||
done
|
||||
```
|
||||
|
||||
你就会发现所有空文件都被删除了,只剩下少数几个非空的文件。
|
||||
|
||||
如果你还想了解更多别的参数,可以执行 `man test` 来查看 `test` 命令的 man 手册(`test` 是 `[ ... ]` 的命令别名)。
|
||||
|
||||
有时候你还会看到 `[[ ... ]]` 这种双方括号的形式,使用起来和单方括号差别不大。但双方括号支持的比较运算符更加丰富:例如可以使用 `==` 来判断某个字符串是否符合某个<ruby>模式<rt>pattern</rt></ruby>,也可以使用 `<`、`>` 来判断两个字符串的出现顺序。
|
||||
|
||||
可以在 [Bash 表达式文档][5]中了解到双方括号支持的更多运算符。
|
||||
|
||||
### 下一集
|
||||
|
||||
在下一篇文章中,我们会开始介绍圆括号 `()` 在 Linux 命令行中的用法,敬请关注!
|
||||
|
||||
### 更多
|
||||
|
||||
- [Linux 工具:点的含义][6]
|
||||
- [理解 Bash 中的尖括号][7]
|
||||
- [Bash 中尖括号的更多用法][8]
|
||||
- [Linux 中的 &][9]
|
||||
- [Bash 中的 & 符号和文件描述符][10]
|
||||
- [Bash 中的逻辑和(&)][4]
|
||||
- [浅析 Bash 中的 {花括号}][11]
|
||||
- [在 Bash 中使用[方括号] (一)][3]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2019/4/using-square-brackets-bash-part-2
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/square-brackets-3734552_1920.jpg?itok=hv9D6TBy "square brackets"
|
||||
[2]: /LICENSES/CATEGORY/CREATIVE-COMMONS-ZERO
|
||||
[3]: https://linux.cn/article-10717-1.html
|
||||
[4]: https://linux.cn/article-10596-1.html
|
||||
[5]: https://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions
|
||||
[6]: https://linux.cn/article-10465-1.html
|
||||
[7]: https://linux.cn/article-10502-1.html
|
||||
[8]: https://linux.cn/article-10529-1.html
|
||||
[9]: https://linux.cn/article-10587-1.html
|
||||
[10]: https://linux.cn/article-10591-1.html
|
||||
[11]: https://linux.cn/article-10624-1.html
|
||||
|
@ -1,64 +1,64 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10757-1.html)
|
||||
[#]: subject: (5 useful open source log analysis tools)
|
||||
[#]: via: (https://opensource.com/article/19/4/log-analysis-tools)
|
||||
[#]: author: (Sam Bocetta https://opensource.com/users/sambocetta)
|
||||
|
||||
5 个有用的开源日志分析工具
|
||||
======
|
||||
监控网络活动既重要又繁琐,以下这些工具可以使它更容易。
|
||||
|
||||
> 监控网络活动既重要又繁琐,以下这些工具可以使它更容易。
|
||||
|
||||
![People work on a computer server][1]
|
||||
|
||||
监控网络活动是一项繁琐的工作,但有充分的理由这样做。例如,它允许你查找和调查工作站、连接到网络的设备和服务器上的可疑登录,同时确定管理员滥用了什么。你还可以跟踪软件安装和数据传输,以实时识别潜在问题,而不是在损坏发生后才进行跟踪。
|
||||
监控网络活动是一项繁琐的工作,但有充分的理由这样做。例如,它允许你查找和调查工作站和连接到网络的设备及服务器上的可疑登录,同时确定管理员滥用了什么。你还可以跟踪软件安装和数据传输,以实时识别潜在问题,而不是在损坏发生后才进行跟踪。
|
||||
|
||||
这些日志还有助于使你的公司遵守适用于在欧盟范围内运营的任何实体的[通用数据保护条例][2](GFPR)。如果你的网站在欧盟可以浏览,那么你就有资格。
|
||||
这些日志还有助于使你的公司遵守适用于在欧盟范围内运营的任何实体的[通用数据保护条例][2](GDPR)。如果你的网站在欧盟可以浏览,那么你就有遵守的该条例的资格。
|
||||
|
||||
日志记录,包括跟踪和分析,应该是任何监控基础设置中的一个基本过程。要从灾难中恢复 SQL Server 数据库,需要事务日志文件。此外,通过跟踪日志文件,DevOps 团队和数据库管理员(DBA)可以保持最佳的数据库性能,或者,在网络攻击的情况下找到未经授权活动的证据。因此,定期监视和分析系统日志非常重要。这是一种可靠的方式来重新创建导致出现任何问题的事件链。
|
||||
日志记录,包括跟踪和分析,应该是任何监控基础设置中的一个基本过程。要从灾难中恢复 SQL Server 数据库,需要事务日志文件。此外,通过跟踪日志文件,DevOps 团队和数据库管理员(DBA)可以保持最佳的数据库性能,又或者,在网络攻击的情况下找到未经授权活动的证据。因此,定期监视和分析系统日志非常重要。这是一种重新创建导致出现任何问题的事件链的可靠方式。
|
||||
|
||||
现在有很多开源日志跟踪器和分析工具可供使用,这使得为活动日志选择合适的资源比你想象的更容易。免费和开源软件社区提供的日志设计适用于各种站点和操作系统。以下是五个我用过的最好的,它们并没有特别的顺序。
|
||||
现在有很多开源日志跟踪器和分析工具可供使用,这使得为活动日志选择合适的资源比你想象的更容易。自由和开源软件社区提供的日志设计适用于各种站点和操作系统。以下是五个我用过的最好的工具,它们并没有特别的顺序。
|
||||
|
||||
### Graylog
|
||||
|
||||
[Graylog][3] 于 2011 年在德国启动,现在作为开源工具或商业解决方案提供。它被设计成一个集中式日志管理系统,接受来自不同服务器或端点的数据流,并允许你快速浏览或分析该信息。
|
||||
[Graylog][3] 于 2011 年在德国创立,现在作为开源工具或商业解决方案提供。它被设计成一个集中式日志管理系统,接受来自不同服务器或端点的数据流,并允许你快速浏览或分析该信息。
|
||||
|
||||
![Graylog screenshot][4]
|
||||
|
||||
Graylog 在系统管理员中建立了良好的声誉,因为它易于扩展。大多数 Web 项目都是从小规模开始的,‘但它们可能指数级增长。Graylog 可以平衡后端服务网络中的负载,每天可以处理几 TB 的日志数据。
|
||||
Graylog 在系统管理员中有着良好的声誉,因为它易于扩展。大多数 Web 项目都是从小规模开始的,但它们可能指数级增长。Graylog 可以均衡后端服务网络中的负载,每天可以处理几 TB 的日志数据。
|
||||
|
||||
IT 管理员会发现 Graylog 的前端界面易于使用,而且功能强大。Graylog 是围绕仪表板的概念构建的,它允许你选择你认为最有价值的指标或数据源,并快速查看一段时间内的趋势。
|
||||
|
||||
当发生安全或性能事件时,IT 管理员希望能够尽可能地将症状追根溯源。Graylog 的搜索功能使这变得容易。它有内置的容错功能,可运行多线程搜索,因此你可以同时分析多个潜在的威胁。
|
||||
当发生安全或性能事件时,IT 管理员希望能够尽可能地根据症状追根溯源。Graylog 的搜索功能使这变得容易。它有内置的容错功能,可运行多线程搜索,因此你可以同时分析多个潜在的威胁。
|
||||
|
||||
### Nagios
|
||||
|
||||
[Nagios][5] 于 1999 年开始由一个开发人员开发,现在已经发展成为管理日志数据最可靠的开源工具之一。当前版本的 Nagios 可以与运行 Microsoft Windows, Linux 或 Unix 的服务器集成。
|
||||
[Nagios][5] 始于 1999 年,最初是由一个开发人员开发的,现在已经发展成为管理日志数据最可靠的开源工具之一。当前版本的 Nagios 可以与运行 Microsoft Windows、Linux 或 Unix 的服务器集成。
|
||||
|
||||
![Nagios Core][6]
|
||||
|
||||
它的主要产品是日志服务器,旨在简化数据收集并使系统管理员更容易访问信息。Nagios 日志服务器引擎将实时捕获数据并将其提供给一个强大的搜索工具。通过内置的设置向导,可以轻松地与新端点或应用程序集成。
|
||||
它的主要产品是日志服务器,旨在简化数据收集并使系统管理员更容易访问信息。Nagios 日志服务器引擎将实时捕获数据,并将其提供给一个强大的搜索工具。通过内置的设置向导,可以轻松地与新端点或应用程序集成。
|
||||
|
||||
Nagios 最常用于需要监控其本地网络安全性的组织。它可以审核一系列与网络相关的事件,并帮助自动分发警报。如果满足特定条件,甚至可以将 Nagios 配置为运行预定义的脚本,从而允许你在人员介入之前解决问题。
|
||||
|
||||
作为网络审核的一部分,Nagios 将根据日志数据来源的地理位置过滤日志数据。这意味着你可以使用映射技术构建全面的仪表板,以了解 Web 流量是如何流动的。
|
||||
作为网络审计的一部分,Nagios 将根据日志数据来源的地理位置过滤日志数据。这意味着你可以使用地图技术构建全面的仪表板,以了解 Web 流量是如何流动的。
|
||||
|
||||
### Elastic Stack ("ELK Stack")
|
||||
### Elastic Stack (ELK Stack)
|
||||
|
||||
[Elastic Stack][7],通常称为 ELK Stack,是需要筛选大量数据并理解其日志系统的组织中最受欢迎的开源工具之一(这也是我个人的最爱)。
|
||||
|
||||
![ELK Stack][8]
|
||||
|
||||
它的主要产品由三个独立的产品组成:Elasticsearch, Kibana 和 Logstash:
|
||||
它的主要产品由三个独立的产品组成:Elasticsearch、Kibana 和 Logstash:
|
||||
|
||||
* 顾名思义, _**Elasticsearch**_ 旨在帮助用户使用多种查询语言和类型在数据集中找到匹配项。速度是它最大的优势。它可以扩展成由数百个服务器节点组成的集群,轻松处理 PB 级的数据。
|
||||
* 顾名思义, Elasticsearch 旨在帮助用户使用多种查询语言和类型在数据集之中找到匹配项。速度是它最大的优势。它可以扩展成由数百个服务器节点组成的集群,轻松处理 PB 级的数据。
|
||||
* Kibana 是一个可视化工具,与 Elasticsearch 一起工作,允许用户分析他们的数据并构建强大的报告。当你第一次在服务器集群上安装 Kibana 引擎时,你会看到一个显示着统计数据、图表甚至是动画的界面。
|
||||
* ELK Stack 的最后一部分是 Logstash,它作为一个纯粹的服务端管道进入 Elasticsearch 数据库。你可以将 Logstash 与各种编程语言和 API 集成,这样你的网站和移动应用程序中的信息就可以直接提供给强大的 Elastic Stalk 搜索引擎中。
|
||||
|
||||
* _**Kibana**_ 是一个可视化工具,与 Elasticsearch 一起工作,允许用户分析他们的数据并构建强大的报告。当你第一次在服务器集群上安装 Kibana 引擎时,你将访问一个显示统计数据、图表甚至是动画的界面。
|
||||
|
||||
* ELK Stack 的最后一部分是 _**Logstash**_ ,它作为一个纯粹的服务端管道进入 Elasticsearch 数据库。你可以将 Logstash 与各种编程语言和 API 集成,这样你的网站和移动应用程序中的信息就可以直接提供给强大的 Elastic Stalk 搜索引擎中。
|
||||
|
||||
ELK Stack 的一个独特功能是,它允许你监视构建在 WordPress 开源安装上的应用程序。与[跟踪管理员和 PHP 日志][9]的大多数开箱即用的安全审计日志工具相比,ELK Stack 可以筛选 Web 服务器和数据库日志。
|
||||
ELK Stack 的一个独特功能是,它允许你监视构建在 WordPress 开源网站上的应用程序。与[跟踪管理日志和 PHP 日志][9]的大多数开箱即用的安全审计日志工具相比,ELK Stack 可以筛选 Web 服务器和数据库日志。
|
||||
|
||||
糟糕的日志跟踪和数据库管理是导致网站性能不佳的最常见原因之一。没有定期检查、优化和清空数据库日志,不仅会降低站点的运行速度,还可能导致其完全崩溃。因此,ELK Stack 对于每个 WordPress 开发人员的工具包来说都是一个优秀的工具。
|
||||
|
||||
@ -97,7 +97,7 @@ via: https://opensource.com/article/19/4/log-analysis-tools
|
||||
作者:[Sam Bocetta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,89 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (tomjlw)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10741-1.html)
|
||||
[#]: subject: (Streaming internet radio with RadioDroid)
|
||||
[#]: via: (https://opensource.com/article/19/4/radiodroid-internet-radio-player)
|
||||
[#]: author: (Chris Hermansen (Community Moderator) https://opensource.com/users/clhermansen)
|
||||
|
||||
使用 RadioDroid 流传输网络广播
|
||||
======
|
||||
|
||||
> 通过简单的设置使用你家中的音响收听你最爱的网络电台。
|
||||
|
||||
![][1]
|
||||
|
||||
最近网络媒体对 [Google 的 Chromecast 音频设备的下架][2]发出叹息。该设备在音频媒体界备受[好评][3],因此我已经在考虑入手一个。基于 Chromecast 退场的消息,我决定在它们全部被打包扔进垃圾堆之前以一个合理价位买一个。
|
||||
|
||||
我在 [MobileFun][4] 上找到一个放进我的订单中。这个设备最终到货了。它被包在一个普普通通、简简单单的 Google 包装袋中,外面打印着非常简短的使用指南。
|
||||
|
||||
![Google Chromecast 音频][5]
|
||||
|
||||
我通过我的数模转换器的光纤 S/PDIF 连接接入到家庭音响,希望以此能提供最佳的音质。
|
||||
|
||||
安装过程并无纰漏,在五分钟后我就可以播放一些音乐了。我知道一些安卓应用支持 Chromecast,因此我决定用 Google Play Music 测试它。意料之中,它工作得不错,音乐效果听上去也相当好。然而作为一个具有开源精神的人,我决定看看我能找到什么开源播放器能兼容 Chromecast。
|
||||
|
||||
### RadioDroid 的救赎
|
||||
|
||||
[RadioDroid 安卓应用][6] 满足条件。它是开源的,并且可从 [GitHub][7]、Google Play 以及 [F-Droid][8] 上获取。根据帮助文档,RadioDroid 从 [Community Radio Browser][9] 网页寻找播放流。因此我决定在我的手机上安装尝试一下。
|
||||
|
||||
![RadioDroid][10]
|
||||
|
||||
安装过程快速顺利,RadioDroid 打开展示当地电台十分迅速。你可以在这个屏幕截图的右上方附近看到 Chromecast 按钮(看上去像一个有着波阵面的长方形图标)。
|
||||
|
||||
我尝试了几个当地电台。这个应用可靠地在我手机喇叭上播放了音乐。但是我不得不摆弄 Chromecast 按钮来通过 Chromecast 把音乐传到流上。但是它确实可以做到流传输。
|
||||
|
||||
我决定找一下我喜爱的网络广播电台:法国马赛的 [格雷诺耶广播电台][11]。在 RadioDroid 上有许多找到电台的方法。其中一种是使用标签——“当地”、“最流行”等——就在电台列表上方。其中一个标签是国家,我找到法国,在其 1500 个电台中划来划去寻找格雷诺耶广播电台。另一种办法是使用屏幕上方的查询按钮;查询迅速找到了那家美妙的电台。我尝试了其它几次查询它们都返回了合理的信息。
|
||||
|
||||
回到“当地”标签,我在列表中翻来覆去,发现“当地”的定义似乎是“在同一个国家”。因此尽管西雅图、波特兰、旧金山、洛杉矶和朱诺比多伦多更靠近我的家,我并没有在“当地”标签中看到它们。然而通过使用查询功能,我可以发现所有名字中带有西雅图的电台。
|
||||
|
||||
“语言”标签使我找到所有用葡语(及葡语方言)播报的电台。我很快发现了另一个最爱的电台 [91 Rock Curitiba][12]。
|
||||
|
||||
接着灵感来了,虽然现在是春天了,但又如何呢?让我们听一些圣诞音乐。意料之中,搜寻圣诞把我引到了 [181.FM – Christmas Blender][13]。不错,一两分钟的欣赏对我就够了。
|
||||
|
||||
因此总的来说,我推荐把 RadioDroid 和 Chromecast 的组合作为一种用家庭音响以合理价位播放网络电台的良好方式。
|
||||
|
||||
### 对于音乐方面……
|
||||
|
||||
最近我从 [Blue Coast Music][16] 商店里选了一个 [Qua Continuum][15] 创作的叫作 [Continuum One][14] 的有趣的氛围(甚至无节拍)音乐专辑。
|
||||
|
||||
Blue Coast 有许多可提供给开源音乐爱好者的。音乐可以无需通过那些奇怪的平台专用下载管理器下载(有时以物理形式)。它通常提供几种形式,包括 WAV、FLAC 和 DSD;WAV 和 FLAC 还提供不同的字长和比特率,包括 16/44.1、24/96 和 24/192,针对 DSD 则有 2.8、5.6 和 11.2 MHz。音乐是用优秀的仪器精心录制的。不幸的是,我并没有找到许多符合我口味的音乐,尽管我喜欢 Blue Coast 上能获取的几个艺术家,包括 Qua Continuum,[Art Lande][17] 以及 [Alex De Grassi][18]。
|
||||
|
||||
在 [Bandcamp][19] 上,我挑选了 [Emancipator's Baralku][20] 和 [Framework's Tides][21],两个都是我喜欢的。两位艺术家创作的音乐符合我的口味——电音但又(总体来说)不是舞蹈,它们的音乐旋律优美,副歌也很好听。有许多可以让开源音乐发烧友爱上 Bandcamp 的东西,比如买前试听整首歌的服务;没有垃圾软件下载器;与大量音乐家的合作;以及对 [Creative Commons music][22] 的支持。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/radiodroid-internet-radio-player
|
||||
|
||||
作者:[Chris Hermansen (Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[tomjlw](https://github.com/tomjlw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/clhermansen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop-music-headphones.png?itok=EQZ2WKzy (woman programming)
|
||||
[2]: https://www.theverge.com/2019/1/11/18178751/google-chromecast-audio-discontinued-sale
|
||||
[3]: https://www.whathifi.com/google/chromecast-audio/review
|
||||
[4]: https://www.mobilefun.com/google-chromecast-audio-black-70476
|
||||
[5]: https://opensource.com/sites/default/files/uploads/internet-radio_chromecast.png (Google Chromecast Audio)
|
||||
[6]: https://play.google.com/store/apps/details?id=net.programmierecke.radiodroid2
|
||||
[7]: https://github.com/segler-alex/RadioDroid
|
||||
[8]: https://f-droid.org/en/packages/net.programmierecke.radiodroid2/
|
||||
[9]: http://www.radio-browser.info/gui/#!/
|
||||
[10]: https://opensource.com/sites/default/files/uploads/internet-radio_radiodroid.png (RadioDroid)
|
||||
[11]: http://www.radiogrenouille.com/
|
||||
[12]: https://91rock.com.br/
|
||||
[13]: http://player.181fm.com/?station=181-xblender
|
||||
[14]: https://www.youtube.com/watch?v=PqLCQXPS8iQ
|
||||
[15]: https://bluecoastmusic.com/artists/qua-continuum
|
||||
[16]: https://bluecoastmusic.com/store
|
||||
[17]: https://bluecoastmusic.com/store?f%5B0%5D=search_api_multi_aggregation_1%3Aart%20lande
|
||||
[18]: https://bluecoastmusic.com/store?f%5B0%5D=search_api_multi_aggregation_1%3Aalex%20de%20grassi
|
||||
[19]: https://bandcamp.com/
|
||||
[20]: https://emancipator.bandcamp.com/album/baralku
|
||||
[21]: https://frameworksuk.bandcamp.com/album/tides
|
||||
[22]: https://bandcamp.com/tag/creative-commons
|
186
published/201904/20190407 Fixing Ubuntu Freezing at Boot Time.md
Normal file
186
published/201904/20190407 Fixing Ubuntu Freezing at Boot Time.md
Normal file
@ -0,0 +1,186 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Raverstern)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10756-1.html)
|
||||
[#]: subject: (Fixing Ubuntu Freezing at Boot Time)
|
||||
[#]: via: (https://itsfoss.com/fix-ubuntu-freezing/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
解决 Ubuntu 在启动时冻结的问题
|
||||
======
|
||||
|
||||
> 本文将向你一步步展示如何通过安装 NVIDIA 专有驱动来处理 Ubuntu 在启动过程中冻结的问题。本教程仅在一个新安装的 Ubuntu 系统上操作验证过,不过在其它情况下也理应可用。
|
||||
|
||||
不久前我买了台[宏碁掠夺者][1]笔记本电脑来测试各种 Linux 发行版。这台庞大且笨重的机器与我喜欢的,类似[戴尔 XPS][3]那般小巧轻便的笔记本电脑大相径庭。
|
||||
|
||||
我即便不打游戏也选择这台电竞笔记本电脑的原因,就是为了 [NVIDIA 的显卡][4]。宏碁掠夺者 Helios 300 上搭载了一块 [NVIDIA Geforce][5] GTX 1050Ti 显卡。
|
||||
|
||||
NVIDIA 那糟糕的 Linux 兼容性为人们所熟知。过去很多 It’s FOSS 的读者都向我求助过关于 NVIDIA 笔记本电脑的问题,而我当时无能为力,因为我手头上没有使用 NVIDIA 显卡的系统。
|
||||
|
||||
所以当我决定搞一台专门的设备来测试 Linux 发行版时,我选择了带有 NVIDIA 显卡的笔记本电脑。
|
||||
|
||||
这台笔记本原装的 Windows 10 系统安装在 120 GB 的固态硬盘上,并另外配有 1 TB 的机械硬盘来存储数据。在此之上我配置好了 [Windows 10 和 Ubuntu 18.04 双系统][6]。整个的安装过程舒适、方便、快捷。
|
||||
|
||||
随后我启动了 [Ubuntu][7]。那熟悉的紫色界面展现了出来,然后我就发现它卡在那儿了。鼠标一动不动,我也输入不了任何东西,然后除了长按电源键强制关机以外我啥事儿都做不了。
|
||||
|
||||
然后再次尝试启动,结果一模一样。整个系统就一直卡在那个紫色界面,随后的登录界面也出不来。
|
||||
|
||||
这听起来很耳熟吧?下面就让我来告诉你如何解决这个 Ubuntu 在启动过程中冻结的问题。
|
||||
|
||||
> 如果你用的不是 Ubuntu
|
||||
|
||||
> 请注意,尽管是在 Ubuntu 18.04 上操作的,本教程应该也能用于其他基于 Ubuntu 的发行版,例如 Linux Mint、elementary OS 等等。关于这点我已经在 Zorin OS 上确认过。
|
||||
|
||||
### 解决 Ubuntu 启动中由 NVIDIA 驱动引起的冻结问题
|
||||
|
||||
![][8]
|
||||
|
||||
我介绍的解决方案适用于配有 NVIDIA 显卡的系统,因为你所面临的系统冻结问题是由开源的 [NVIDIA Nouveau 驱动][9]所导致的。
|
||||
|
||||
事不宜迟,让我们马上来看看如何解决这个问题。
|
||||
|
||||
#### 步骤 1:编辑 Grub
|
||||
|
||||
在启动系统的过程中,请你在如下图所示的 Grub 界面上停下。如果你没看到这个界面,在启动电脑时请按住 `Shift` 键。
|
||||
|
||||
在这个界面上,按 `E` 键进入编辑模式。
|
||||
|
||||
![按“E”按键][10]
|
||||
|
||||
你应该看到一些如下图所示的代码。此刻你应关注于以 “linux” 开头的那一行。
|
||||
|
||||
![前往 Linux 开头的那一行][11]
|
||||
|
||||
#### 步骤 2:在 Grub 中临时修改 Linux 内核参数
|
||||
|
||||
回忆一下,我们的问题出在 NVIDIA 显卡驱动上,是开源版 NVIDIA 驱动的不适配导致了我们的问题。所以此处我们能做的就是禁用这些驱动。
|
||||
|
||||
此刻,你有多种方式可以禁用这些驱动。我最喜欢的方式是通过 `nomodeset` 来禁用所有显卡的驱动。
|
||||
|
||||
请把下列文本添加到以 “linux” 开头的那一行的末尾。此处你应该可以正常输入。请确保你把这段文本加到了行末。
|
||||
|
||||
```
|
||||
nomodeset
|
||||
```
|
||||
|
||||
现在你屏幕上的显示应如下图所示:
|
||||
|
||||
![通过向内核添加 nomodeset 来禁用显卡驱动][12]
|
||||
|
||||
按 `Ctrl+X` 或 `F10` 保存并退出。下次你就将以修改后的内核参数来启动。
|
||||
|
||||
> 对以上操作的解释
|
||||
|
||||
> 所以我们究竟做了些啥?那个 `nomodeset` 又是个什么玩意儿?让我来向你简单地解释一下。
|
||||
|
||||
> 通常来说,显卡是在 X 或者是其他显示服务器开始执行后才被启用的,也就是在你登录系统并看到图形界面以后。
|
||||
|
||||
> 但近来,视频模式的设置被移进了内核。这么做的众多优点之一就是能你看到一个漂亮且高清的启动画面。
|
||||
|
||||
> 若你往内核中加入 `nomodeset` 参数,它就会指示内核在显示服务启动后才加载显卡驱动。
|
||||
|
||||
> 换句话说,你在此时禁止视频驱动的加载,由此产生的冲突也会随之消失。你在登录进系统以后,还是能看到一切如旧,那是因为显卡驱动在随后的过程中被加载了。
|
||||
|
||||
#### 步骤 3:更新你的系统并安装 NVIDIA 专有驱动
|
||||
|
||||
别因为现在可以登录系统了就过早地高兴起来。你之前所做的只是临时措施,在下次启动的时候,你的系统依旧会尝试加载 Nouveau 驱动而因此冻结。
|
||||
|
||||
这是否意味着你将不得不在 Grub 界面上不断地编辑内核?可喜可贺,答案是否定的。
|
||||
|
||||
你可以在 Ubuntu 上为 NVIDIA 显卡[安装额外的驱动][13]。在使用专有驱动后,Ubuntu 将不会在启动过程中冻结。
|
||||
|
||||
我假设这是你第一次登录到一个新安装的系统。这意味着在做其他事情之前你必须先[更新 Ubuntu][14]。通过 Ubuntu 的 `Ctrl+Alt+T` [系统快捷键][15]打开一个终端,并输入以下命令:
|
||||
|
||||
```
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
```
|
||||
|
||||
在上述命令执行完以后,你可以尝试安装额外的驱动。不过根据我的经验,在安装新驱动之前你需要先重启一下你的系统。在你重启时,你还是需要按我们之前做的那样修改内核参数。
|
||||
|
||||
当你的系统已经更新和重启完毕,按下 `Windows` 键打开一个菜单栏,并搜索“<ruby>软件与更新<rt>Software & Updates</rt></ruby>”。
|
||||
|
||||
![点击“软件与更新”(Software & Updates)][16]
|
||||
|
||||
然后切换到“<ruby>额外驱动<rt>Additional Drivers</rt></ruby>”标签页,并等待数秒。然后你就能看到可供系统使用的专有驱动了。在这个列表上你应该可以找到 NVIDIA。
|
||||
|
||||
选择专有驱动并点击“<ruby>应用更改<rt>Apply Changes</rt></ruby>”。
|
||||
|
||||
![NVIDIA 驱动安装中][17]
|
||||
|
||||
新驱动的安装会费点时间。若你的系统启用了 UEFI 安全启动,你将被要求设置一个密码。*你可以将其设置为任何容易记住的密码*。它的用处我将在步骤 4 中说明。
|
||||
|
||||
![你可能需要设置一个安全启动密码][18]
|
||||
|
||||
安装完成后,你会被要求重启系统以令之前的更改生效。
|
||||
|
||||
![在新驱动安装好后重启你的系统][19]
|
||||
|
||||
#### 步骤 4:处理 MOK(仅针对启用了 UEFI 安全启动的设备)
|
||||
|
||||
如果你之前被要求设置安全启动密码,此刻你会看到一个蓝色界面,上面写着 “MOK management”。这是个复杂的概念,我试着长话短说。
|
||||
|
||||
对 MOK([设备所有者密码][20])的要求是因为安全启动的功能要求所有内核模块都必须被签名。Ubuntu 中所有随 ISO 镜像发行的内核模块都已经签了名。由于你安装了一个新模块(也就是那个额外的驱动),或者你对内核模块做了修改,你的安全系统可能视之为一个未经验证的外部修改,从而拒绝启动。
|
||||
|
||||
因此,你可以自己对系统模块进行签名(以告诉 UEFI 系统莫要大惊小怪,这些修改是你做的),或者你也可以简单粗暴地[禁用安全启动][21]。
|
||||
|
||||
现在你对[安全启动和 MOK][22] 有了一定了解,那咱们就来看看在遇到这个蓝色界面后该做些什么。
|
||||
|
||||
如果你选择“继续启动”,你的系统将有很大概率如往常一样启动,并且你啥事儿也不用做。不过在这种情况下,新驱动的有些功能有可能工作不正常。
|
||||
|
||||
这就是为什么,你应该“选择注册 MOK”。
|
||||
|
||||
![][23]
|
||||
|
||||
它会在下一个页面让你点击“继续”,然后要你输入一串密码。请输入在上一步中,在安装额外驱动时设置的密码。
|
||||
|
||||
> 别担心!
|
||||
|
||||
> 如果你错过了这个关于 MOK 的蓝色界面,或不小心点了“继续启动”而不是“注册 MOK”,不必惊慌。你的主要目的是能够成功启动系统,而通过禁用 Nouveau 显卡驱动,你已经成功地实现了这一点。
|
||||
|
||||
> 最坏的情况也不过就是你的系统切换到 Intel 集成显卡而不再使用 NVIDIA 显卡。你可以之后的任何时间安装 NVIDIA 显卡驱动。你的首要任务是启动系统。
|
||||
|
||||
#### 步骤 5:享受安装了专有 NVIDIA 驱动的 Linux 系统
|
||||
|
||||
当新驱动被安装好后,你需要再次重启系统。别担心!目前的情况应该已经好起来了,并且你不必再去修改内核参数,而是能够直接启动 Ubuntu 系统了。
|
||||
|
||||
我希望本教程帮助你解决了 Ubuntu 系统在启动中冻结的问题,并让你能够成功启动 Ubuntu 系统。
|
||||
|
||||
如果你有任何问题或建议,请在下方评论区给我留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/fix-ubuntu-freezing/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Raverstern](https://github.com/Raverstern)
|
||||
校对:[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://amzn.to/2YVV6rt
|
||||
[2]: https://itsfoss.com/affiliate-policy/
|
||||
[3]: https://itsfoss.com/dell-xps-13-ubuntu-review/
|
||||
[4]: https://www.nvidia.com/en-us/
|
||||
[5]: https://www.nvidia.com/en-us/geforce/
|
||||
[6]: https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/
|
||||
[7]: https://www.ubuntu.com/
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/fixing-frozen-ubuntu.png?resize=800%2C450&ssl=1
|
||||
[9]: https://nouveau.freedesktop.org/wiki/
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/edit-grub-menu.jpg?resize=800%2C393&ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/editing-grub-to-fix-nvidia-issue.jpg?resize=800%2C343&ssl=1
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/editing-grub-to-fix-nvidia-issue-2.jpg?resize=800%2C320&ssl=1
|
||||
[13]: https://itsfoss.com/install-additional-drivers-ubuntu/
|
||||
[14]: https://itsfoss.com/update-ubuntu/
|
||||
[15]: https://itsfoss.com/ubuntu-shortcuts/
|
||||
[16]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/02/activities_software_updates_search-e1551416201782-800x228.png?resize=800%2C228&ssl=1
|
||||
[17]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/install-nvidia-driver-ubuntu.jpg?resize=800%2C520&ssl=1
|
||||
[18]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/secure-boot-nvidia.jpg?ssl=1
|
||||
[19]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/nvidia-drivers-installed-Ubuntu.jpg?resize=800%2C510&ssl=1
|
||||
[20]: https://firmware.intel.com/blog/using-mok-and-uefi-secure-boot-suse-linux
|
||||
[21]: https://itsfoss.com/disable-secure-boot-in-acer/
|
||||
[22]: https://wiki.ubuntu.com/UEFI/SecureBoot/DKMS
|
||||
[23]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/MOK-Secure-boot.jpg?resize=800%2C350&ssl=1
|
@ -1,44 +1,45 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10725-1.html)
|
||||
[#]: subject: (Bash vs. Python: Which language should you use?)
|
||||
[#]: via: (https://opensource.com/article/19/4/bash-vs-python)
|
||||
[#]: author: (Archit Modi Red Hat https://opensource.com/users/architmodi/users/greg-p/users/oz123)
|
||||
|
||||
|
||||
Bash vs Python: 该使用哪种语言?
|
||||
Bash vs Python:你该使用哪个?
|
||||
======
|
||||
两种编程语言都各有优缺点,一些任务使得它们在某些方面互有胜负。
|
||||
|
||||
> 两种编程语言都各有优缺点,它们在某些任务方面互有胜负。
|
||||
|
||||
![][1]
|
||||
|
||||
[Bash][2] 和 [Python][3] 是大多数自动化工程师最喜欢的编程语言。它们都各有优缺点,有时很难选择应该使用哪一个。诚实的答案是:这取决于任务、范围、背景和任务的复杂性。
|
||||
[Bash][2] 和 [Python][3] 是大多数自动化工程师最喜欢的编程语言。它们都各有优缺点,有时很难选择应该使用哪一个。所以,最诚实的答案是:这取决于任务、范围、背景和任务的复杂性。
|
||||
|
||||
让我们来比较一下这两种语言,以便更好地理解它们各自的优点。
|
||||
|
||||
### Bash
|
||||
|
||||
* 是一种 Linux/Unix shell 命令语言
|
||||
* 非常适合编写使用命令行界面(CLI)实用程序的 shell 脚本,利用一个命令的输出传递给另一个命令(管道),以及执行简单的任务(最多 100 行代码)
|
||||
* 非常适合编写使用命令行界面(CLI)实用程序的 shell 脚本,利用一个命令的输出传递给另一个命令(管道),以及执行简单的任务(可以多达 100 行代码)
|
||||
* 可以按原样使用命令行命令和实用程序
|
||||
* 启动时间比 Python 快,但执行时间性能差
|
||||
* Windows 默认没有安装。你的脚本可能不会兼容多个操作系统,但是 Bash 是大多数 Linux/Unix 系统的默认 shell
|
||||
* 与其它 shell (如 csh、zsh、fish) _不_ 完全兼容。
|
||||
* 管道 ("|") CLI 实用程序如 sed、awk、grep 等可以降低其性能
|
||||
* 缺少很多函数、对象、数据结构和多线程,这限制了它在复杂脚本或编程中的使用
|
||||
* 启动时间比 Python 快,但执行时性能差
|
||||
* Windows 中默认没有安装。你的脚本可能不会兼容多个操作系统,但是 Bash 是大多数 Linux/Unix 系统的默认 shell
|
||||
* 与其它 shell (如 csh、zsh、fish) *不* 完全兼容。
|
||||
* 通过管道(`|`)传递 CLI 实用程序如 `sed`、`awk`、`grep` 等会降低其性能
|
||||
* 缺少很多函数、对象、数据结构和多线程支持,这限制了它在复杂脚本或编程中的使用
|
||||
* 缺少良好的调试工具和实用程序
|
||||
|
||||
### Python
|
||||
|
||||
* 是一种面对对象编程语言(OOP),因此它比 Bash 更加通用
|
||||
* 几乎可以用于任何任务
|
||||
* 适用于大多数操作系统,默认情况下它安装在大多数 Unix/Linux 系统中
|
||||
* 适用于大多数操作系统,默认情况下它在大多数 Unix/Linux 系统中都有安装
|
||||
* 与伪代码非常相似
|
||||
* 具有简单、清晰、易于学习和阅读的语法
|
||||
* 拥有大量的库、文档以及一个活跃的社区
|
||||
* 提供比 Bash 更友好的错误处理特性
|
||||
* 有比 Bash 更好的调试工具和实用程序,这使得它在开发涉及很多行代码的复杂软件应用程序中是一种很棒的语言
|
||||
* 有比 Bash 更好的调试工具和实用程序,这使得它在开发涉及到很多行代码的复杂软件应用程序时是一种很棒的语言
|
||||
* 应用程序(或脚本)可能包含许多第三方依赖项,这些依赖项必须在执行前安装
|
||||
* 对于简单任务,需要编写比 Bash 更多的代码
|
||||
|
||||
@ -53,7 +54,7 @@ via: https://opensource.com/article/19/4/bash-vs-python
|
||||
作者:[Archit Modi (Red Hat)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,74 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (tomjlw)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10747-1.html)
|
||||
[#]: subject: (Cisco, Google reenergize multicloud/hybrid cloud joint development)
|
||||
[#]: via: (https://www.networkworld.com/article/3388218/cisco-google-reenergize-multicloudhybrid-cloud-joint-development.html#tk.rss_all)
|
||||
[#]: author: (Michael Cooney https://www.networkworld.com/author/Michael-Cooney/)
|
||||
|
||||
思科、谷歌重新赋能多/混合云共同开发
|
||||
======
|
||||
> 思科、VMware、HPE 等公司开始采用了新的 Google Cloud Athos 云技术。
|
||||
|
||||
![Thinkstock][1]
|
||||
|
||||
思科与谷歌已扩展它们的混合云开发活动,以帮助其客户可以在从本地数据中心到公共云上的任何地方更轻松地搭建安全的多云以及混合云应用。
|
||||
|
||||
这次扩张围绕着谷歌被称作 Anthos 的新的开源混合云包展开,它是在这周的 Google Next 活动上推出的。Anthos 基于并取代了谷歌现有的谷歌云服务测试版。Anthos 将让客户们无须修改应用就可以在现有的本地硬件或公共云上运行应用。据谷歌说,它可以在[谷歌云平台][5] (GCP) 与 [谷歌 Kubernetes 引擎][6] (GKE) 或者在数据中心中与 [GKE On-Prem][7] 一同使用。谷歌说,Anthos 首次让客户们可以无需管理员和开发者了解不同的坏境和 API 就能从谷歌平台上管理在第三方云上(如 AWS 和 Azure)的工作负荷。
|
||||
|
||||
关键在于,Athos 提供了一个单一的托管服务,它使得客户们无须担心不同的环境或 API 就能跨云管理、部署工作负荷。
|
||||
|
||||
作为首秀的一部分,谷歌也宣布一个叫做 [Anthos Migrate][8] 的测试计划,它能够从本地环境或者其它云自动迁移虚拟机到 GKE 上的容器中。谷歌说,“这种独特的迁移技术使你无须修改原来的虚拟机或者应用就能以一种行云流水般的方式迁移、更新你的基础设施”。谷歌称它给予了公司按客户节奏转移本地应用到云环境的灵活性。
|
||||
|
||||
### 思科和谷歌
|
||||
|
||||
就思科来说,它宣布对 Anthos 的支持并承诺将它紧密集成进思科的数据中心技术中,例如 HyperFlex 超融合包、应用中心基础设施(思科的旗舰 SDN 方案)、SD-WAN 和 StealthWatch 云。思科说,无论是本地的还是在云端的,这次集成将通过自动更新到最新版本和安全补丁,给予一种一致的、云般的感觉。
|
||||
|
||||
“谷歌云在容器(Kubernetes)和<ruby>服务网格<rt>service mesh</rt></ruby>(Istio)上的专业与它们在开发者社区的领导力,再加上思科的企业级网络、计算、存储和安全产品及服务,将为我们的顾客促成一次强强联合。”思科的云平台和解决方案集团资深副总裁 Kip Compton 这样[写道][9],“思科对于 Anthos 的集成将会帮助顾客跨本地数据中心和公共云搭建、管理多云/混合云应用,让他们专注于创新和灵活性,同时不会影响安全性或增加复杂性。”
|
||||
|
||||
### 谷歌云和思科
|
||||
|
||||
谷歌云工程副总裁 Eyal Manor [写道][10] 通过思科对 Anthos 的支持,客户将能够:
|
||||
|
||||
* 受益于全托管服务例如 GKE 以及思科的超融合基础设施、网络和安全技术;
|
||||
* 在企业数据中心和云中一致运行
|
||||
* 在企业数据中心使用云服务
|
||||
* 用最新的云技术更新本地基础设施
|
||||
|
||||
思科和谷歌从 2017 年 10 月就在紧密合作,当时他们表示正在开发一个能够连接本地基础设施和云环境的开放混合云平台。该套件,即[思科为谷歌云打造的混合云平台][11],大致在 2018 年 9 月上市。它使得客户们能通过谷歌云托管 Kubernetes 容器开发企业级功能,包含思科网络和安全技术以及来自 Istio 的服务网格监控。
|
||||
|
||||
谷歌说开源的 Istio 的容器和微服务优化技术给开发者提供了一种一致的方式,通过服务级的 mTLS (双向传输层安全)身份验证访问控制来跨云连接、保护、管理和监听微服务。因此,客户能够轻松实施新的可移植的服务,并集中配置和管理这些服务。
|
||||
|
||||
思科不是唯一宣布对 Anthos 支持的供应商。谷歌表示,至少 30 家大型合作商包括 [VMware][12]、[Dell EMC][13]、[HPE][14]、Intel 和联想致力于为他们的客户在它们自己的超融合基础设施上提供 Anthos 服务。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3388218/cisco-google-reenergize-multicloudhybrid-cloud-joint-development.html
|
||||
|
||||
作者:[Michael Cooney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[tomjlw](https://github.com/tomjlw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Michael-Cooney/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.techhive.com/images/article/2016/12/hybrid_cloud-100700390-large.jpg
|
||||
[2]: https://www.networkworld.com/article/3233132/cloud-computing/what-is-hybrid-cloud-computing.html
|
||||
[3]: https://www.networkworld.com/article/3252775/hybrid-cloud/multicloud-mania-what-to-know.html
|
||||
[4]: https://www.networkworld.com/newsletters/signup.html
|
||||
[5]: https://cloud.google.com/
|
||||
[6]: https://cloud.google.com/kubernetes-engine/
|
||||
[7]: https://cloud.google.com/gke-on-prem/
|
||||
[8]: https://cloud.google.com/contact/
|
||||
[9]: https://blogs.cisco.com/news/next-phase-cisco-google-cloud
|
||||
[10]: https://cloud.google.com/blog/topics/partners/google-cloud-partners-with-cisco-on-hybrid-cloud-next19?utm_medium=unpaidsocial&utm_campaign=global-googlecloud-liveevent&utm_content=event-next
|
||||
[11]: https://cloud.google.com/cisco/
|
||||
[12]: https://blogs.vmware.com/networkvirtualization/2019/04/vmware-and-google-showcase-hybrid-cloud-deployment.html/
|
||||
[13]: https://www.dellemc.com/en-us/index.htm
|
||||
[14]: https://www.hpe.com/us/en/newsroom/blog-post/2019/04/hpe-and-google-cloud-join-forces-to-accelerate-innovation-with-hybrid-cloud-solutions-optimized-for-containerized-applications.html
|
||||
[15]: https://www.facebook.com/NetworkWorld/
|
||||
[16]: https://www.linkedin.com/company/network-world
|
||||
|
67
published/201904/20190409 Enhanced security at the edge.md
Normal file
67
published/201904/20190409 Enhanced security at the edge.md
Normal file
@ -0,0 +1,67 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hopefully2333)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10773-1.html)
|
||||
[#]: subject: (Enhanced security at the edge)
|
||||
[#]: via: (https://www.networkworld.com/article/3388130/enhanced-security-at-the-edge.html#tk.rss_all)
|
||||
[#]: author: (Anne Taylor https://www.networkworld.com/author/Anne-Taylor/)
|
||||
|
||||
增强边缘计算的安全性
|
||||
======
|
||||
|
||||
> 边缘计算环境带来的安全风险迫使公司必须特别关注它的安全措施。
|
||||
|
||||

|
||||
|
||||
说数据安全是高管们和董事会最关注的问题已经是陈词滥调了。但问题是:数据安全问题不会自己消失。
|
||||
|
||||
骇客和攻击者一直在寻找利用缺陷的新方法。就像公司开始使用人工智能和机器学习等新兴技术来自动化地保护他们的组织一样,那些不良分子们也在使用这些技术来达成他们的目的。
|
||||
|
||||
简而言之,安全问题是一定不能忽视的。现在,随着越来越多的公司开始使用边缘计算,如何保护这些边缘计算环境,需要有新的安全考量。
|
||||
|
||||
### 边缘计算的风险更高
|
||||
|
||||
正如 Network World 的一篇文章所说,边缘计算的安全架构应该将重点放在物理安全上。这并不是说要忽视保护传输过程中的数据。而是说,实际的物理环境和物理设备更加值得关注。
|
||||
|
||||
例如,边缘计算的硬件设备通常位于较大的公司或者广阔空间中,有时候是在很容易进入的共享办公室和公共区域里。从表面上看,这节省了成本,能更快地访问到相关的数据,而不必在后端的数据中心和前端的设备之间往返。
|
||||
|
||||
但是,如果没有任何级别的访问控制,这台设备就会暴露在恶意操作和简单人为错误的双重风险之下。想象一下办公室的清洁工意外地关掉了设备,以及随之而来的停机所造成的后果。
|
||||
|
||||
另一个风险是 “影子边缘 IT”。有时候非 IT 人员会部署一个边缘设备来快速启动项目,却没有及时通知 IT 部门这个设备正在连接到网络。例如,零售商店可能会主动安装他们自己的数字标牌,或者,销售团队会将物联网传感器应用到电视中,并在销售演示中实时地部署它们。
|
||||
|
||||
在这种情况下,IT 部门很少甚至完全看不到这些边缘设备,这就使得网络可能暴露在外。
|
||||
|
||||
### 保护边缘计算环境
|
||||
|
||||
部署微型数据中心(MDC)是规避上述风险的一个简单方法。
|
||||
|
||||
> “在历史上,大多数这些[边缘]环境都是不受控制的,”施耐德电气安全能源部门的首席技术官和创新高级副总裁 Kevin Brown 说。“它们可能是第 1 级,但很可能是第 0 级类型的设计 —— 它们就像开放的配线柜。它们现在需要像微型数据中心一样的对待。你管理它需要像管理关键任务数据中心一样”
|
||||
|
||||
单说听起来的感觉,这个解决方案是一个安全、独立的机箱,它包括在室内和室外运行程序所需的所有存储空间、处理性能和网络资源。它同样包含必要的电源、冷却、安全和管理工具。
|
||||
|
||||
而它最重要的是高级别的安全性。这个装置是封闭的,有上锁的门,可以防止非法入侵。通过合适的供应商,DMC 可以进行定制,包括用于远程数字化管理的监控摄像头、传感器和监控技术。
|
||||
|
||||
随着越来越多的公司开始利用边缘计算的优势,他们必须利用安全解决方案的优势来保护他们的数据和边缘环境。
|
||||
|
||||
在 APC.com 上了解保护你的边缘计算环境的最佳方案。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3388130/enhanced-security-at-the-edge.html
|
||||
|
||||
作者:[Anne Taylor][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hopefully2333](https://github.com/hopefully2333)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Anne-Taylor/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.idgesg.net/images/article/2019/04/istock-1091707448-100793312-large.jpg
|
||||
[2]: https://www.csoonline.com/article/3250144/6-ways-hackers-will-use-machine-learning-to-launch-attacks.html
|
||||
[3]: https://www.marketwatch.com/press-release/edge-computing-market-2018-global-analysis-opportunities-and-forecast-to-2023-2018-08-20
|
||||
[4]: https://www.networkworld.com/article/3224893/what-is-edge-computing-and-how-it-s-changing-the-network.html
|
||||
[5]: https://www.youtube.com/watch?v=1NLk1cXEukQ
|
||||
[6]: https://www.apc.com/us/en/solutions/business-solutions/edge-computing.jsp
|
@ -0,0 +1,340 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (NeverKnowsTomorrow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10768-1.html)
|
||||
[#]: subject: (Four Methods To Add A User To Group In Linux)
|
||||
[#]: via: (https://www.2daygeek.com/linux-add-user-to-group-primary-secondary-group-usermod-gpasswd/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
在 Linux 中把用户添加到组的四个方法
|
||||
======
|
||||
|
||||
Linux 组是用于管理 Linux 中用户帐户的组织单位。对于 Linux 系统中的每一个用户和组,它都有惟一的数字标识号。它被称为 用户 ID(UID)和组 ID(GID)。组的主要目的是为组的成员定义一组特权。它们都可以执行特定的操作,但不能执行其他操作。
|
||||
|
||||
Linux 中有两种类型的默认组。每个用户应该只有一个 <ruby>主要组<rt>primary group</rt></ruby> 和任意数量的 <ruby>次要组<rt>secondary group</rt></ruby>。
|
||||
|
||||
* **主要组:** 创建用户帐户时,已将主要组添加到用户。它通常是用户的名称。在执行诸如创建新文件(或目录)、修改文件或执行命令等任何操作时,主要组将应用于用户。用户的主要组信息存储在 `/etc/passwd` 文件中。
|
||||
* **次要组:** 它被称为次要组。它允许用户组在同一组成员文件中执行特定操作。例如,如果你希望允许少数用户运行 Apache(httpd)服务命令,那么它将非常适合。
|
||||
|
||||
你可能对以下与用户管理相关的文章感兴趣。
|
||||
|
||||
* [在 Linux 中创建用户帐户的三种方法?][1]
|
||||
* [如何在 Linux 中创建批量用户?][2]
|
||||
* [如何在 Linux 中使用不同的方法更新/更改用户密码?][3]
|
||||
|
||||
可以使用以下四种方法实现。
|
||||
|
||||
* `usermod`:修改系统帐户文件,以反映在命令行中指定的更改。
|
||||
* `gpasswd`:用于管理 `/etc/group` 和 `/etc/gshadow`。每个组都可以有管理员、成员和密码。
|
||||
* Shell 脚本:可以让管理员自动执行所需的任务。
|
||||
* 手动方式:我们可以通过编辑 `/etc/group` 文件手动将用户添加到任何组中。
|
||||
|
||||
我假设你已经拥有此操作所需的组和用户。在本例中,我们将使用以下用户和组:`user1`、`user2`、`user3`,另外的组是 `mygroup` 和 `mygroup1`。
|
||||
|
||||
在进行更改之前,我希望检查一下用户和组信息。详见下文。
|
||||
|
||||
我可以看到下面的用户与他们自己的组关联,而不是与其他组关联。
|
||||
|
||||
```
|
||||
# id user1
|
||||
uid=1008(user1) gid=1008(user1) groups=1008(user1)
|
||||
|
||||
# id user2
|
||||
uid=1009(user2) gid=1009(user2) groups=1009(user2)
|
||||
|
||||
# id user3
|
||||
uid=1010(user3) gid=1010(user3) groups=1010(user3)
|
||||
```
|
||||
|
||||
我可以看到这个组中没有关联的用户。
|
||||
|
||||
```
|
||||
# getent group mygroup
|
||||
mygroup:x:1012:
|
||||
|
||||
# getent group mygroup1
|
||||
mygroup1:x:1013:
|
||||
```
|
||||
|
||||
### 方法 1:使用 usermod 命令
|
||||
|
||||
`usermod` 命令修改系统帐户文件,以反映命令行上指定的更改。
|
||||
|
||||
#### 如何使用 usermod 命令将现有的用户添加到次要组或附加组?
|
||||
|
||||
要将现有用户添加到辅助组,请使用带有 `-G` 选项和组名称的 `usermod` 命令。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# usermod [-G] [GroupName] [UserName]
|
||||
```
|
||||
|
||||
如果系统中不存在给定的用户或组,你将收到一条错误消息。如果没有得到任何错误,那么用户已经被添加到相应的组中。
|
||||
|
||||
```
|
||||
# usermod -a -G mygroup user1
|
||||
```
|
||||
|
||||
让我使用 `id` 命令查看输出。是的,添加成功。
|
||||
|
||||
```
|
||||
# id user1
|
||||
uid=1008(user1) gid=1008(user1) groups=1008(user1),1012(mygroup)
|
||||
```
|
||||
|
||||
#### 如何使用 usermod 命令将现有的用户添加到多个次要组或附加组?
|
||||
|
||||
要将现有用户添加到多个次要组中,请使用带有 `-G` 选项的 `usermod` 命令和带有逗号分隔的组名称。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# usermod [-G] [GroupName1,GroupName2] [UserName]
|
||||
```
|
||||
|
||||
在本例中,我们将把 `user2` 添加到 `mygroup` 和 `mygroup1` 中。
|
||||
|
||||
```
|
||||
# usermod -a -G mygroup,mygroup1 user2
|
||||
```
|
||||
|
||||
让我使用 `id` 命令查看输出。是的,`user2` 已成功添加到 `myGroup` 和 `myGroup1` 中。
|
||||
|
||||
```
|
||||
# id user2
|
||||
uid=1009(user2) gid=1009(user2) groups=1009(user2),1012(mygroup),1013(mygroup1)
|
||||
```
|
||||
|
||||
#### 如何改变用户的主要组?
|
||||
|
||||
要更改用户的主要组,请使用带有 `-g` 选项和组名称的 `usermod` 命令。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# usermod [-g] [GroupName] [UserName]
|
||||
```
|
||||
|
||||
我们必须使用 `-g` 改变用户的主要组。
|
||||
|
||||
```
|
||||
# usermod -g mygroup user3
|
||||
```
|
||||
|
||||
让我们看看输出。是的,已成功更改。现在,显示`user3` 主要组是 `mygroup` 而不是 `user3`。
|
||||
|
||||
```
|
||||
# id user3
|
||||
uid=1010(user3) gid=1012(mygroup) groups=1012(mygroup)
|
||||
```
|
||||
|
||||
### 方法 2:使用 gpasswd 命令
|
||||
|
||||
`gpasswd` 命令用于管理 `/etc/group` 和 `/etc/gshadow`。每个组都可以有管理员、成员和密码。
|
||||
|
||||
#### 如何使用 gpasswd 命令将现有用户添加到次要组或者附加组?
|
||||
|
||||
要将现有用户添加到次要组,请使用带有 `-M` 选项和组名称的 `gpasswd` 命令。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# gpasswd [-M] [UserName] [GroupName]
|
||||
```
|
||||
|
||||
在本例中,我们将把 `user1 ` 添加到 `mygroup` 中。
|
||||
|
||||
```
|
||||
# gpasswd -M user1 mygroup
|
||||
```
|
||||
|
||||
让我使用 `id` 命令查看输出。是的,`user1` 已成功添加到 `mygroup` 中。
|
||||
|
||||
```
|
||||
# id user1
|
||||
uid=1008(user1) gid=1008(user1) groups=1008(user1),1012(mygroup)
|
||||
```
|
||||
|
||||
#### 如何使用 gpasswd 命令添加多个用户到次要组或附加组中?
|
||||
|
||||
要将多个用户添加到辅助组中,请使用带有 `-M` 选项和组名称的 `gpasswd` 命令。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# gpasswd [-M] [UserName1,UserName2] [GroupName]
|
||||
```
|
||||
|
||||
在本例中,我们将把 `user2` 和 `user3` 添加到 `mygroup1` 中。
|
||||
|
||||
```
|
||||
# gpasswd -M user2,user3 mygroup1
|
||||
```
|
||||
|
||||
让我使用 `getent` 命令查看输出。是的,`user2` 和 `user3` 已成功添加到 `myGroup1` 中。
|
||||
|
||||
```
|
||||
# getent group mygroup1
|
||||
mygroup1:x:1013:user2,user3
|
||||
```
|
||||
|
||||
#### 如何使用 gpasswd 命令从组中删除一个用户?
|
||||
|
||||
要从组中删除用户,请使用带有 `-d` 选项的 `gpasswd` 命令以及用户和组的名称。
|
||||
|
||||
语法:
|
||||
|
||||
```
|
||||
# gpasswd [-d] [UserName] [GroupName]
|
||||
```
|
||||
|
||||
在本例中,我们将从 `mygroup` 中删除 `user1` 。
|
||||
|
||||
```
|
||||
# gpasswd -d user1 mygroup
|
||||
Removing user user1 from group mygroup
|
||||
```
|
||||
|
||||
### 方法 3:使用 Shell 脚本
|
||||
|
||||
基于上面的例子,我知道 `usermod` 命令没有能力将多个用户添加到组中,可以通过 `gpasswd` 命令完成。但是,它将覆盖当前与组关联的现有用户。
|
||||
|
||||
例如,`user1` 已经与 `mygroup` 关联。如果要使用 `gpasswd` 命令将 `user2` 和 `user3` 添加到 `mygroup` 中,它将不会按预期生效,而是对组进行修改。
|
||||
|
||||
如果要将多个用户添加到多个组中,解决方案是什么?
|
||||
|
||||
两个命令中都没有默认选项来实现这一点。
|
||||
|
||||
因此,我们需要编写一个小的 shell 脚本来实现这一点。
|
||||
|
||||
#### 如何使用 gpasswd 命令将多个用户添加到次要组或附加组?
|
||||
|
||||
如果要使用 `gpasswd` 命令将多个用户添加到次要组或附加组,请创建以下 shell 脚本。
|
||||
|
||||
创建用户列表。每个用户应该在单独的行中。
|
||||
|
||||
```bash
|
||||
$ cat user-lists.txt
|
||||
user1
|
||||
user2
|
||||
user3
|
||||
```
|
||||
|
||||
使用以下 shell 脚本将多个用户添加到单个次要组。
|
||||
|
||||
```bash
|
||||
vi group-update.sh
|
||||
|
||||
#!/bin/bash
|
||||
for user in `cat user-lists.txt`
|
||||
do
|
||||
usermod -a -G mygroup $user
|
||||
done
|
||||
```
|
||||
|
||||
设置 `group-update.sh` 文件的可执行权限。
|
||||
|
||||
```
|
||||
# chmod + group-update.sh
|
||||
```
|
||||
|
||||
最后运行脚本来实现它。
|
||||
|
||||
```
|
||||
# sh group-update.sh
|
||||
```
|
||||
|
||||
让我看看使用 `getent` 命令的输出。 是的,`user1`、`user2` 和 `user3` 已成功添加到 `mygroup` 中。
|
||||
|
||||
```
|
||||
# getent group mygroup
|
||||
mygroup:x:1012:user1,user2,user3
|
||||
```
|
||||
|
||||
#### 如何使用 gpasswd 命令将多个用户添加到多个次要组或附加组?
|
||||
|
||||
如果要使用 `gpasswd` 命令将多个用户添加到多个次要组或附加组中,请创建以下 shell 脚本。
|
||||
|
||||
创建用户列表。每个用户应该在单独的行中。
|
||||
|
||||
```bash
|
||||
$ cat user-lists.txt
|
||||
user1
|
||||
user2
|
||||
user3
|
||||
```
|
||||
|
||||
创建组列表。每组应在单独的行中。
|
||||
|
||||
```bash
|
||||
$ cat group-lists.txt
|
||||
mygroup
|
||||
mygroup1
|
||||
```
|
||||
|
||||
使用以下 shell 脚本将多个用户添加到多个次要组。
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
for user in `more user-lists.txt`
|
||||
do
|
||||
for group in `more group-lists.txt`
|
||||
do
|
||||
usermod -a -G $group $user
|
||||
done
|
||||
```
|
||||
|
||||
设置 `group-update-1.sh` 文件的可执行权限。
|
||||
|
||||
```
|
||||
# chmod +x group-update-1.sh
|
||||
```
|
||||
|
||||
最后运行脚本来实现它。
|
||||
|
||||
```
|
||||
# sh group-update-1.sh
|
||||
```
|
||||
|
||||
让我看看使用 `getent` 命令的输出。 是的,`user1`、`user2` 和 `user3` 已成功添加到 `mygroup` 中。
|
||||
|
||||
```
|
||||
# getent group mygroup
|
||||
mygroup:x:1012:user1,user2,user3
|
||||
```
|
||||
|
||||
此外,`user1`、`user2` 和 `user3` 已成功添加到 `mygroup1` 中。
|
||||
|
||||
```
|
||||
# getent group mygroup1
|
||||
mygroup1:x:1013:user1,user2,user3
|
||||
```
|
||||
|
||||
### 方法 4:在 Linux 中将用户添加到组中的手动方法
|
||||
|
||||
我们可以通过编辑 `/etc/group` 文件手动将用户添加到任何组中。
|
||||
|
||||
打开 `/etc/group` 文件并搜索要更新用户的组名。最后将用户更新到相应的组中。
|
||||
|
||||
```
|
||||
# vi /etc/group
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/linux-add-user-to-group-primary-secondary-group-usermod-gpasswd/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[NeverKnowsTomorrow](https://github.com/NeverKnowsTomorrow)
|
||||
校对:[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/linux-user-account-creation-useradd-adduser-newusers/
|
||||
[2]: https://www.2daygeek.com/how-to-create-the-bulk-users-in-linux/
|
||||
[3]: https://www.2daygeek.com/linux-passwd-chpasswd-command-set-update-change-users-password-in-linux-using-shell-script/
|
@ -1,75 +1,69 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10751-1.html)
|
||||
[#]: subject: (How To Install And Enable Flatpak Support On Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-install-and-enable-flatpak-support-on-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How To Install And Enable Flatpak Support On Linux?
|
||||
如何在 Linux 上安装并启用 Flatpak 支持?
|
||||
======
|
||||
|
||||
Currently we all are using distributions official package managers to install any required packages.
|
||||
目前,我们都在使用 Linux 发行版的官方软件包管理器来安装所需的软件包。
|
||||
|
||||
in Linux, it’s doing good without any issues. (It’s doing their job nicely without any compromise)
|
||||
在 Linux 中,它做得很好,没有任何问题。(它不打折扣地很好的完成了它应该做的工作)
|
||||
|
||||
There was some limitation on this that will think about other alternative solutions to fix it.
|
||||
但在一些方面它也有一些限制,所以会让我们考虑其他替代解决方案来解决。
|
||||
|
||||
Yes, by default we won’t get the latest version of packages from the distributions official package managers because as these were built while building a current OS version. And they offers only security updates until the next major release comes.
|
||||
是的,默认情况下,我们不能从发行版官方软件包管理器获取到最新版本的软件包,因为这些软件包是在构建当前 OS 版本时构建的。它们只会提供安全更新,直到下一个主要版本发布。
|
||||
|
||||
So, what will be the solution for this?
|
||||
那么,这种情况有什么解决办法吗?是的,我们有多种解决方案,而且我们大多数人已经开始使用其中的一些了。
|
||||
|
||||
Yes, we have multiple solutions for this and most of us were already started using few of those.
|
||||
有些什么呢,它们有什么好处?
|
||||
|
||||
What it is and what is the benefit of those?
|
||||
* **对于基于 Ubuntu 的系统:** PPA
|
||||
* **对于基于 RHEL 的系统:** [EPEL 仓库][1]、[ELRepo 仓库][2]、[nux-dextop 仓库][3]、[IUS 社区仓库][4]、[RPMfusion 仓库][5] 和 [Remi 仓库][6]
|
||||
|
||||
* **For Ubuntu based systems:** PPAs
|
||||
* **For RHEL based systems:** [EPEL Repository][1], [ELRepo Repository][2], [nux-dextop Repository][3], [IUS Community Repo][4], [RPMfusion Repository][5] and [Remi Repository][6].
|
||||
使用上面的仓库,我们将获得最新的软件包。这些软件包通常都得到了很好的维护,还有大多数社区的推荐。但这些只是建议,可能并不总是安全的。
|
||||
|
||||
近年来,出现了一下通用软件包封装格式,并且得到了广泛的应用。
|
||||
|
||||
* Flatpak:它是独立于发行版的包格式,主要贡献者是 Fedora 项目团队。大多数主要的 Linux 发行版都采用了 Flatpak 框架。
|
||||
* Snaps:Snappy 是一种通用的软件包封装格式,最初由 Canonical 为 Ubuntu 手机及其操作系统设计和构建的。后来,更多的发行版都接纳了它。
|
||||
* AppImage:AppImage 是一种可移植的包格式,可以在不安装和不需要 root 权限的情况下运行。
|
||||
|
||||
Using the above repos, we will be getting the latest packages for the distribution. And these are usually well maintained and suggested by most of the community. But these are advisable by the OS and may not always be safe.
|
||||
我们之前已经介绍过 [Snap 包管理器和包封装格式][7]。今天我们将讨论 Flatpak 包封装格式。
|
||||
|
||||
In recent years, the following universal packaging formats were come out and gained a lot of popularity.
|
||||
### 什么是 Flatpak?
|
||||
|
||||
* **`Flatpak:`**`` It’s distribution independent package format and the main contributor is Fedora project team. The Flatpak framework is adopted by most of the major Linux distributions.
|
||||
* **`Snaps:`**`` Snappy is a universal packaging formats originally designed and built by Canonical for the Ubuntu phone and it’s operating system. Later most of the distributions are adapted.
|
||||
* **`AppImage:`**`` AppImage is a portable package format and it can run without installation or the need for root rights.
|
||||
Flatpak(以前称为 X Desktop Group 或 xdg-app)是一个软件实用程序。它提供了一种通用的包封装格式,可以在任何 Linux 发行版中使用。
|
||||
|
||||
它提供了一个沙箱(隔离的)环境来运行应用程序,不会影响其他应用程序和发行版核心软件包。我们还可以安装并运行不同版本的软件包。
|
||||
|
||||
Flatpak 的一个缺点是不像 Snap 和 AppImage 那样支持服务器操作系统,它只在少数桌面环境下工作。
|
||||
|
||||
We had already covered about the **[Snap package manager& packaging format][7]** in the past. Today we are going to discuss about Flatpak packing format.
|
||||
比如说,如果你想在系统上运行两个版本的 php,那么你可以轻松安装并按照你的意愿运行。
|
||||
|
||||
### What Is Flatpak?
|
||||
这就是现在通用包封装格式非常有名的地方。
|
||||
|
||||
Flatpak (formerly know as X Desktop Group or xdg-app) is a software utility. It’s offering a universal packaging formats which can be used in any Linux distributions.
|
||||
### 如何在 Linux 中安装 Flatpak?
|
||||
|
||||
It provides a sandbox (isolated) environment to run the app and it doesn’t impact either other apps and distribution core packages. Also we can install and run the different version of same package.
|
||||
大多数 Linux 发行版官方仓库都提供 Flatpak 软件包。因此,可以使用它们来进行安装。
|
||||
|
||||
There is an disadvantage on flatpak is that doesn’t support server OS unlike Snap and AppImage. It’s working only on few desktops environment.
|
||||
|
||||
Say for example. If you would like to run two version of php on your system then you can easily install and run as your wish.
|
||||
|
||||
That’s where the universal packaging formats are become very famous nowadays.
|
||||
|
||||
### How To Install Flatpak On Linux?
|
||||
|
||||
Flatpak package is available in most of the Linux distribution official repository. Hence, it can be installed using those.
|
||||
|
||||
For **`Fedora`** system, use **[DNF Command][8]** to install flatpak.
|
||||
对于 Fedora 系统,使用 [DNF 命令][8] 来安装 flatpak。
|
||||
|
||||
```
|
||||
$ sudo dnf install flatpak
|
||||
```
|
||||
|
||||
For **`Debian/Ubuntu`** systems, use **[APT-GET Command][9]** or **[APT Command][10]** to install flatpak.
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][9] 或 [APT 命令][10] 来安装 flatpak。
|
||||
|
||||
```
|
||||
$ sudo apt install flatpak
|
||||
```
|
||||
|
||||
For older Ubuntu versions.
|
||||
对于较旧的 Ubuntu 版本:
|
||||
|
||||
```
|
||||
$ sudo add-apt-repository ppa:alexlarsson/flatpak
|
||||
@ -77,52 +71,50 @@ $ sudo apt update
|
||||
$ sudo apt install flatpak
|
||||
```
|
||||
|
||||
For **`Arch Linux`** based systems, use **[Pacman Command][11]** to install flatpak.
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman 命令][11] 来安装 flatpak。
|
||||
|
||||
```
|
||||
$ sudo pacman -S flatpak
|
||||
```
|
||||
|
||||
For **`RHEL/CentOS`** systems, use **[YUM Command][12]** to install flatpak.
|
||||
对于 RHEL/CentOS 系统,使用 [YUM 命令][12] 来安装 flatpak。
|
||||
|
||||
```
|
||||
$ sudo yum install flatpak
|
||||
```
|
||||
|
||||
For **`openSUSE Leap`** system, use **[Zypper Command][13]** to install flatpak.
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][13] 来安装 flatpak。
|
||||
|
||||
```
|
||||
$ sudo zypper install flatpak
|
||||
```
|
||||
|
||||
### How To Enable Flathub Support On Linux?
|
||||
### 如何在 Linux 上启用 Flathub 支持?
|
||||
|
||||
Flatbub website is a app store for Flatpak packages where you can find them.
|
||||
Flathub 网站是一个应用程序商店,你可以在其中找到 flatpak 软件包。它是一个中央仓库,所有的 flatpak 应用程序都可供用户使用。
|
||||
|
||||
It’s a central repository where all the flatpak applications are available for users.
|
||||
|
||||
Run the following command to enable Flathub support on Linux.
|
||||
运行以下命令在 Linux 上启用 Flathub 支持:
|
||||
|
||||
```
|
||||
$ sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
```
|
||||
|
||||
Install the Software Flatpak plugin for GNOME Desktop Environment.
|
||||
为 GNOME 桌面环境安装 Software Flatpak 插件。
|
||||
|
||||
```
|
||||
$ sudo apt install gnome-software-plugin-flatpak
|
||||
```
|
||||
|
||||
Also, you can enable GNOME Repository if you are using GNOME Desktop Environment. It’s containing all GNOME core applications.
|
||||
此外,如果你使用的是 GNOME 桌面环境,则可以启用 GNOME 仓库。它包含所有 GNOME 核心应用程序。
|
||||
|
||||
```
|
||||
$ wget https://sdk.gnome.org/keys/gnome-sdk.gpg
|
||||
$ sudo flatpak remote-add --gpg-import=gnome-sdk.gpg --if-not-exists gnome-apps https://sdk.gnome.org/repo-apps/
|
||||
```
|
||||
|
||||
### How To List configured flatpak repositories?
|
||||
### 如何列出已配置的 flakpak 仓库?
|
||||
|
||||
Run the following command, if you would like to view list of the configured flatpak repositories on your system.
|
||||
如果要查看系统上已配置的 flatpak 仓库列表,运行以下命令:
|
||||
|
||||
```
|
||||
$ flatpak remotes
|
||||
@ -131,9 +123,9 @@ flathub system
|
||||
gnome-apps system
|
||||
```
|
||||
|
||||
### How To List The Available Packages In The Configured Repositories?
|
||||
### 如何列出已配置仓库中的可用软件包?
|
||||
|
||||
Run the following command, if you would like to view list of the available packages (It will display all together like, applications and run times) in the configured repositories.
|
||||
如果要查看已配置仓库中的可用软件包的列表(它将显示所有软件包,如应用程序和运行环境),运行以下命令:
|
||||
|
||||
```
|
||||
$ flatpak remote-ls | head -10
|
||||
@ -150,21 +142,21 @@ org.gnome.Documents gnome-apps
|
||||
org.gnome.Epiphany gnome-apps
|
||||
```
|
||||
|
||||
To list only applications not runtimes.
|
||||
仅列出应用程序:
|
||||
|
||||
```
|
||||
$ flatpak remote-ls --app
|
||||
```
|
||||
|
||||
To list specific repository applications.
|
||||
列出特定的仓库应用程序:
|
||||
|
||||
```
|
||||
$ flatpak remote-ls gnome-apps
|
||||
```
|
||||
|
||||
### How To Install A Package From flatpak?
|
||||
### 如何从 flatpak 安装包?
|
||||
|
||||
Run the following command to install a package from flatpak repository.
|
||||
运行以下命令从 flatpak 仓库安装软件包:
|
||||
|
||||
```
|
||||
$ sudo flatpak install flathub com.github.muriloventuroso.easyssh
|
||||
@ -198,24 +190,24 @@ Installing: com.github.muriloventuroso.easyssh.Locale/x86_64/stable from flathub
|
||||
Now at af837356b222.
|
||||
```
|
||||
|
||||
All the installed application will be placed in the following location.
|
||||
所有已安装的应用程序都将放在以下位置:
|
||||
|
||||
```
|
||||
$ ls /var/lib/flatpak/app/
|
||||
com.github.muriloventuroso.easyssh
|
||||
```
|
||||
|
||||
### How To Run The Installed Application?
|
||||
### 如何运行已安装的应用程序?
|
||||
|
||||
Run the following command to launch the required application. Make sure, you have to replace with your application name instead.
|
||||
运行以下命令以启动所需的应用程序,确保替换为你的应用程序名称:
|
||||
|
||||
```
|
||||
$ flatpak run com.github.muriloventuroso.easyssh
|
||||
```
|
||||
|
||||
### How To View The Installed Application?
|
||||
### 如何查看已安装的应用程序?
|
||||
|
||||
Run the following command to view the installed application.
|
||||
运行以下命令来查看已安装的应用程序:
|
||||
|
||||
```
|
||||
$ flatpak list
|
||||
@ -225,9 +217,9 @@ org.freedesktop.Platform.html5-codecs/x86_64/18.08 system,runtime
|
||||
org.gnome.Platform/x86_64/3.30 system,runtime
|
||||
```
|
||||
|
||||
### How To View The Detailed Information About The Installed Application?
|
||||
### 如何查看有关已安装应用程序的详细信息?
|
||||
|
||||
Run the following command to view the detailed information about the installed application.
|
||||
运行以下命令以查看有关已安装应用程序的详细信息:
|
||||
|
||||
```
|
||||
$ flatpak info com.github.muriloventuroso.easyssh
|
||||
@ -248,29 +240,29 @@ Runtime: org.gnome.Platform/x86_64/3.30
|
||||
Sdk: org.gnome.Sdk/x86_64/3.30
|
||||
```
|
||||
|
||||
### How To Update The Installed Application?
|
||||
### 如何更新已安装的应用程序?
|
||||
|
||||
Run the following command to updated the installed application to latest version.
|
||||
运行以下命令将已安装的应用程序更新到最新版本:
|
||||
|
||||
```
|
||||
$ flatpak update
|
||||
```
|
||||
|
||||
For specific application, use the following format.
|
||||
对于特定应用程序,使用以下格式:
|
||||
|
||||
```
|
||||
$ flatpak update com.github.muriloventuroso.easyssh
|
||||
```
|
||||
|
||||
### How To Remove The Installed Application?
|
||||
### 如何移除已安装的应用程序?
|
||||
|
||||
Run the following command to remove the installed application.
|
||||
运行以下命令来移除已安装的应用程序:
|
||||
|
||||
```
|
||||
$ sudo flatpak uninstall com.github.muriloventuroso.easyssh
|
||||
```
|
||||
|
||||
Go to the man page for more details and options.
|
||||
进入 man 页面以获取更多细节和选项:
|
||||
|
||||
```
|
||||
$ flatpak --help
|
||||
@ -282,8 +274,8 @@ via: https://www.2daygeek.com/how-to-install-and-enable-flatpak-support-on-linux
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,45 +1,35 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (heguangzhi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10736-1.html)
|
||||
[#]: subject: (How To Check The List Of Open Ports In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/linux-scan-check-open-ports-using-netstat-ss-nmap/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
|
||||
如何检查Linux中的开放端口列表?
|
||||
如何检查 Linux 中的开放端口列表?
|
||||
======
|
||||
|
||||
最近,我们就同一主题写了两篇文章。
|
||||
最近,我们就同一主题写了两篇文章。这些文章内容帮助你如何检查远程服务器中给定的端口是否打开。
|
||||
|
||||
这些文章内容帮助您如何检查远程服务器中给定的端口是否打开。
|
||||
如果你想 [检查远程 Linux 系统上的端口是否打开][1] 请点击链接浏览。如果你想 [检查多个远程 Linux 系统上的端口是否打开][2] 请点击链接浏览。如果你想 [检查多个远程 Linux 系统上的多个端口状态][2] 请点击链接浏览。
|
||||
|
||||
如果您想 **[检查远程 Linux 系统上的端口是否打开][1]** 请点击链接浏览。
|
||||
但是本文帮助你检查本地系统上的开放端口列表。
|
||||
|
||||
如果您想 **[检查多个远程 Linux 系统上的端口是否打开][2]** 请点击链接浏览。
|
||||
在 Linux 中很少有用于此目的的实用程序。然而,我提供了四个最重要的 Linux 命令来检查这一点。
|
||||
|
||||
如果您想 **[检查多个远程Linux系统上的多个端口状态][2]** 请点击链接浏览。
|
||||
|
||||
但是本文帮助您检查本地系统上的开放端口列表。
|
||||
|
||||
在 Linux 中很少有用于此目的的实用程序。
|
||||
|
||||
然而,我提供了四个最重要的 Linux 命令来检查这一点。
|
||||
|
||||
您可以使用以下四个命令来完成这个工作。这些命令是非常出名的并被 Linux 管理员广泛使用。
|
||||
|
||||
* **`netstat:`** netstat (“network statistics”) 是一个显示网络连接(进和出)相关信息命令行工具,例如:路由表, 伪装连接,多点传送成员和网络端口。
|
||||
* **`nmap:`** Nmap (“Network Mapper”) 是一个网络探索与安全审计的开源工具。它旨在快速扫描大型网络。
|
||||
* **`ss:`** ss 被用于转储套接字统计信息。它也可以类似 netstat 使用。相比其他工具它可以展示更多的TCP状态信息。
|
||||
* **`lsof:`** lsof 是 List Open File 的缩写. 它用于输出被某个进程打开的所有文件。
|
||||
你可以使用以下四个命令来完成这个工作。这些命令是非常出名的并被 Linux 管理员广泛使用。
|
||||
|
||||
* `netstat`:netstat (“network statistics”) 是一个显示网络连接(进和出)相关信息命令行工具,例如:路由表, 伪装连接,多点传送成员和网络端口。
|
||||
* `nmap`:Nmap (“Network Mapper”) 是一个网络探索与安全审计的开源工具。它旨在快速扫描大型网络。
|
||||
* `ss`: ss 被用于转储套接字统计信息。它也可以类似 netstat 使用。相比其他工具它可以展示更多的TCP状态信息。
|
||||
* `lsof`: lsof 是 List Open File 的缩写. 它用于输出被某个进程打开的所有文件。
|
||||
|
||||
### 如何使用 Linux 命令 netstat 检查系统中的开放端口列表
|
||||
|
||||
netstat 是 Network Statistics 的缩写,是一个显示网络连接(进和出)相关信息命令行工具,例如:路由表, 伪装连接,多点传送成员和网络端口。
|
||||
`netstat` 是 Network Statistics 的缩写,是一个显示网络连接(进和出)相关信息命令行工具,例如:路由表、伪装连接、多播成员和网络端口。
|
||||
|
||||
它可以列出所有的 tcp, udp 连接 和所有的 unix 套接字连接。
|
||||
它可以列出所有的 tcp、udp 连接和所有的 unix 套接字连接。
|
||||
|
||||
它用于发现发现网络问题,确定网络连接数量。
|
||||
|
||||
@ -81,7 +71,7 @@ eth0 1 ff02::1
|
||||
eth0 1 ff01::1
|
||||
```
|
||||
|
||||
您也可以使用下面的命令检查特定的端口。
|
||||
你也可以使用下面的命令检查特定的端口。
|
||||
|
||||
```
|
||||
# # netstat -tplugn | grep :22
|
||||
@ -92,7 +82,7 @@ tcp6 0 0 :::22 :::* LISTEN
|
||||
|
||||
### 如何使用 Linux 命令 ss 检查系统中的开放端口列表?
|
||||
|
||||
ss 被用于转储套接字统计信息。它也可以类似 netstat 使用。相比其他工具它可以展示更多的TCP状态信息。
|
||||
`ss` 被用于转储套接字统计信息。它也可以显示类似 `netstat` 的信息。相比其他工具它可以展示更多的 TCP 状态信息。
|
||||
|
||||
```
|
||||
# ss -lntu
|
||||
@ -121,7 +111,7 @@ tcp LISTEN 0 100 :::25
|
||||
tcp LISTEN 0 128 :::22 :::*
|
||||
```
|
||||
|
||||
您也可以使用下面的命令检查特定的端口。
|
||||
你也可以使用下面的命令检查特定的端口。
|
||||
|
||||
```
|
||||
# # ss -lntu | grep ':25'
|
||||
@ -132,12 +122,11 @@ tcp LISTEN 0 100 :::25 :::*
|
||||
|
||||
### 如何使用 Linux 命令 nmap 检查系统中的开放端口列表?
|
||||
|
||||
|
||||
Nmap (“Network Mapper”) 是一个网络探索与安全审计的开源工具。它旨在快速扫描大型网络,当然它也可以工作在独立主机上。
|
||||
|
||||
Nmap使用裸 IP 数据包以一种新颖的方式来确定网络上有哪些主机可用,这些主机提供什么服务(应用程序名称和版本),它们运行什么操作系统(操作系统版本),使用什么类型的数据包过滤器/防火墙,以及许多其他特征。
|
||||
Nmap 使用裸 IP 数据包以一种新颖的方式来确定网络上有哪些主机可用,这些主机提供什么服务(应用程序名称和版本),它们运行什么操作系统(版本),使用什么类型的数据包过滤器/防火墙,以及许多其他特征。
|
||||
|
||||
虽然 Nmap 通常用于安全审计,但许多系统和网络管理员发现它对于日常工作也非常有用,例如网络清点、管理服务升级计划以及监控主机或服务正常运行时间。
|
||||
虽然 Nmap 通常用于安全审计,但许多系统和网络管理员发现它对于日常工作也非常有用,例如网络资产清点、管理服务升级计划以及监控主机或服务正常运行时间。
|
||||
|
||||
```
|
||||
# nmap -sTU -O localhost
|
||||
@ -166,9 +155,7 @@ OS detection performed. Please report any incorrect results at http://nmap.org/s
|
||||
Nmap done: 1 IP address (1 host up) scanned in 1.93 seconds
|
||||
```
|
||||
|
||||
|
||||
您也可以使用下面的命令检查特定的端口。
|
||||
|
||||
你也可以使用下面的命令检查特定的端口。
|
||||
|
||||
```
|
||||
# nmap -sTU -O localhost | grep 123
|
||||
@ -176,10 +163,9 @@ Nmap done: 1 IP address (1 host up) scanned in 1.93 seconds
|
||||
123/udp open ntp
|
||||
```
|
||||
|
||||
|
||||
### 如何使用 Linux 命令 lsof 检查系统中的开放端口列表?
|
||||
|
||||
它向您显示系统上打开的文件列表以及打开它们的进程。还会向您显示与文件相关的其他信息。
|
||||
它向你显示系统上打开的文件列表以及打开它们的进程。还会向你显示与文件相关的其他信息。
|
||||
|
||||
```
|
||||
# lsof -i
|
||||
@ -214,8 +200,7 @@ httpd 13374 apache 3u IPv4 20337 0t0 TCP *:http (LISTEN)
|
||||
httpd 13375 apache 3u IPv4 20337 0t0 TCP *:http (LISTEN)
|
||||
```
|
||||
|
||||
您也可以使用下面的命令检查特定的端口。
|
||||
|
||||
你也可以使用下面的命令检查特定的端口。
|
||||
|
||||
```
|
||||
# lsof -i:80
|
||||
@ -236,11 +221,11 @@ via: https://www.2daygeek.com/linux-scan-check-open-ports-using-netstat-ss-nmap/
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[heguangzhi](https://github.com/heguangzhi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/how-to-check-whether-a-port-is-open-on-the-remote-linux-system-server/
|
||||
[1]: https://linux.cn/article-10675-1.html
|
||||
[2]: https://www.2daygeek.com/check-a-open-port-on-multiple-remote-linux-server-using-nc-command/
|
117
published/201904/20190410 Managing Partitions with sgdisk.md
Normal file
117
published/201904/20190410 Managing Partitions with sgdisk.md
Normal file
@ -0,0 +1,117 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10771-1.html)
|
||||
[#]: subject: (Managing Partitions with sgdisk)
|
||||
[#]: via: (https://fedoramagazine.org/managing-partitions-with-sgdisk/)
|
||||
[#]: author: (Gregory Bartholomew https://fedoramagazine.org/author/glb/)
|
||||
|
||||
使用 sgdisk 管理分区
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
[Roderick W. Smith][2] 的 `sgdisk` 命令可在命令行中管理硬盘的分区。下面将介绍使用它所需的基础知识。
|
||||
|
||||
使用 sgdisk 的大多数基本功能只需要了解以下六个参数:
|
||||
|
||||
1、`-p` *打印* 分区表:
|
||||
|
||||
```
|
||||
# sgdisk -p /dev/sda
|
||||
```
|
||||
|
||||
2、 `-d x` *删除* 分区 x:
|
||||
|
||||
```
|
||||
# sgdisk -d 1 /dev/sda
|
||||
```
|
||||
|
||||
3、 `-n x:y:z` 创建一个编号 x 的*新*分区,从 y 开始,从 z 结束:
|
||||
|
||||
```
|
||||
# sgdisk -n 1:1MiB:2MiB /dev/sda
|
||||
```
|
||||
|
||||
4、`-c x:y` *更改*分区 x 的名称为 y:
|
||||
|
||||
```
|
||||
# sgdisk -c 1:grub /dev/sda
|
||||
```
|
||||
|
||||
5、`-t x:y` 将分区 x 的*类型*更改为 y:
|
||||
|
||||
```
|
||||
# sgdisk -t 1:ef02 /dev/sda
|
||||
```
|
||||
|
||||
6、`–list-types` 列出分区类型代码:
|
||||
|
||||
```
|
||||
# sgdisk --list-types
|
||||
```
|
||||
|
||||
![The SGDisk Command][3]
|
||||
|
||||
如你在上面的例子中所见,大多数命令都要求将要操作的硬盘的[设备文件名][4]指定为最后一个参数。
|
||||
|
||||
可以组合上面的参数,这样你可以一次定义所有分区:
|
||||
|
||||
```
|
||||
# sgdisk -n 1:1MiB:2MiB -t 1:ef02 -c 1:grub /dev/sda
|
||||
```
|
||||
|
||||
在值的前面加上 `+` 或 `–` 符号,可以为某些字段指定相对值。如果你使用相对值,`sgdisk` 会为你做数学运算。例如,上面的例子可以写成:
|
||||
|
||||
```
|
||||
# sgdisk -n 1:1MiB:+1MiB -t 1:ef02 -c 1:grub /dev/sda
|
||||
```
|
||||
|
||||
`0` 值对于以下几个字段有特殊意义:
|
||||
|
||||
* 对于*分区号*字段,0 表示应使用下一个可用编号(编号从 1 开始)。
|
||||
* 对于*起始地址*字段,0 表示使用最大可用空闲块的头。硬盘开头的一些空间始终保留给分区表本身。
|
||||
* 对于*结束地址*字段,0 表示使用最大可用空闲块的末尾。
|
||||
|
||||
通过在适当的字段中使用 `0` 和相对值,你可以创建一系列分区,而无需预先计算任何绝对值。例如,如果在一块空白硬盘中,以下 `sgdisk` 命令序列将创建典型 Linux 安装所需的所有基本分区:
|
||||
|
||||
```
|
||||
# sgdisk -n 0:0:+1MiB -t 0:ef02 -c 0:grub /dev/sda
|
||||
# sgdisk -n 0:0:+1GiB -t 0:ea00 -c 0:boot /dev/sda
|
||||
# sgdisk -n 0:0:+4GiB -t 0:8200 -c 0:swap /dev/sda
|
||||
# sgdisk -n 0:0:0 -t 0:8300 -c 0:root /dev/sda
|
||||
```
|
||||
|
||||
上面的例子展示了如何为基于 BIOS 的计算机分区硬盘。基于 UEFI 的计算机上不需要 [grub 分区][5]。由于 `sgdisk` 在上面的示例中为你计算了所有绝对值,因此你可以在基于 UEFI 的计算机上跳过第一个命令,并且可以无需修改即可运行其余命令。同样,你可以跳过创建交换分区,并且不需要修改其余命令。
|
||||
|
||||
还有使用一个命令删除硬盘上所有分区的快捷方式:
|
||||
|
||||
```
|
||||
# sgdisk --zap-all /dev/sda
|
||||
```
|
||||
|
||||
关于最新和详细信息,请查看手册页:
|
||||
|
||||
```
|
||||
$ man sgdisk
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/managing-partitions-with-sgdisk/
|
||||
|
||||
作者:[Gregory Bartholomew][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/glb/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/managing-partitions-816x345.png
|
||||
[2]: https://www.rodsbooks.com/
|
||||
[3]: https://fedoramagazine.org/wp-content/uploads/2019/04/sgdisk.jpg
|
||||
[4]: https://en.wikipedia.org/wiki/Device_file
|
||||
[5]: https://en.wikipedia.org/wiki/BIOS_boot_partition
|
@ -0,0 +1,106 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10778-1.html)
|
||||
[#]: subject: (How to Zip Files and Folders in Linux [Beginner Tip])
|
||||
[#]: via: (https://itsfoss.com/linux-zip-folder/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
初级:如何在 Linux 中 zip 压缩文件和文件夹
|
||||
======
|
||||
|
||||
> 本文向你展示了如何在 Ubuntu 和其他 Linux 发行版中创建一个 zip 文件夹。终端和 GUI 方法都有。
|
||||
|
||||
zip 是最流行的归档文件格式之一。使用 zip,你可以将多个文件压缩到一个文件中。这不仅节省了磁盘空间,还节省了网络带宽。这就是为什么你几乎一直会看到 zip 文件的原因。
|
||||
|
||||
作为普通用户,大多数情况下你会在 Linux 中解压缩文件夹。但是如何在 Linux 中压缩文件夹?本文可以帮助你回答这个问题。
|
||||
|
||||
**先决条件:验证是否安装了 zip**
|
||||
|
||||
通常 [zip][1] 已经安装,但验证下也没坏处。你可以运行以下命令来安装 `zip` 和 `unzip`。如果它尚未安装,它将立即安装。
|
||||
|
||||
```
|
||||
sudo apt install zip unzip
|
||||
```
|
||||
|
||||
现在你知道你的系统有 zip 支持,你可以继续了解如何在 Linux 中压缩一个目录。
|
||||
|
||||
![][2]
|
||||
|
||||
### 在 Linux 命令行中压缩文件夹
|
||||
|
||||
`zip` 命令的语法非常简单。
|
||||
|
||||
```
|
||||
zip [option] output_file_name input1 input2
|
||||
```
|
||||
|
||||
虽然有几个选项,但我不希望你将它们混淆。如果你只想要将一堆文件变成一个 zip 文件夹,请使用如下命令:
|
||||
|
||||
```
|
||||
zip -r output_file.zip file1 folder1
|
||||
```
|
||||
|
||||
`-r` 选项将递归目录并压缩其内容。输出文件中的 .zip 扩展名是可选的,因为默认情况下会添加 .zip。
|
||||
|
||||
你应该会在 zip 操作期间看到要添加到压缩文件夹中的文件。
|
||||
|
||||
```
|
||||
zip -r myzip abhi-1.txt abhi-2.txt sample_directory
|
||||
adding: abhi-1.txt (stored 0%)
|
||||
adding: abhi-2.txt (stored 0%)
|
||||
adding: sample_directory/ (stored 0%)
|
||||
adding: sample_directory/newfile.txt (stored 0%)
|
||||
adding: sample_directory/agatha.txt (deflated 41%)
|
||||
```
|
||||
|
||||
你可以使用 `-e` 选项[在 Linux 中创建密码保护的 zip 文件夹][3]。
|
||||
|
||||
你并不是只能通过终端创建 zip 归档文件。你也可以用图形方式做到这一点。下面是如何做的!
|
||||
|
||||
### 在 Ubuntu Linux 中使用 GUI 压缩文件夹
|
||||
|
||||
*虽然我在这里使用 Ubuntu,但在使用 GNOME 或其他桌面环境的其他发行版中,方法应该基本相同。*
|
||||
|
||||
如果要在 Linux 桌面中压缩文件或文件夹,只需点击几下即可。
|
||||
|
||||
进入到你想将文件(和文件夹)压缩到一个 zip 文件夹的所在文件夹。
|
||||
|
||||
在这里,选择文件和文件夹。现在,右键单击并选择“压缩”。你也可以对单个文件执行相同操作。
|
||||
|
||||
![Select the files, right click and click compress][4]
|
||||
|
||||
现在,你可以使用 zip、tar xz 或 7z 格式创建压缩归档文件。如果你好奇,这三个都是各种压缩算法,你可以使用它们来压缩文件。
|
||||
|
||||
输入一个你想要的名字,并点击“创建”。
|
||||
|
||||
![Create archive file][5]
|
||||
|
||||
这不会花很长时间,你会同一目录中看到一个归档文件。
|
||||
|
||||
![][6]
|
||||
|
||||
好了,就是这些。你已经成功地在 Linux 中创建了一个 zip 文件夹。
|
||||
|
||||
我希望这篇文章能帮助你了解 zip 文件。请随时分享你的建议。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/linux-zip-folder/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Zip_(file_format)
|
||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/zip-folder-linux.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/password-protect-zip-file/
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/create-zip-file-ubuntu.jpg?resize=800%2C428&ssl=1
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/create-zip-folder-ubuntu-1.jpg?ssl=1
|
||||
[6]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/zip-file-created-in-ubuntu.png?resize=800%2C277&ssl=1
|
443
published/201904/20190413 The Fargate Illusion.md
Normal file
443
published/201904/20190413 The Fargate Illusion.md
Normal file
@ -0,0 +1,443 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10740-1.html)
|
||||
[#]: subject: (The Fargate Illusion)
|
||||
[#]: via: (https://leebriggs.co.uk/blog/2019/04/13/the-fargate-illusion.html)
|
||||
[#]: author: (Lee Briggs https://leebriggs.co.uk/)
|
||||
|
||||
破除对 AWS Fargate 的幻觉
|
||||
======
|
||||
|
||||
我在 $work 建立了一个基于 Kubernetes 的平台已经快一年了,而且有点像 Kubernetes 的布道者了。真的,我认为这项技术太棒了。然而我并没有对它的运营和维护的困难程度抱过什么幻想。今年早些时候我读了[这样][1]的一篇文章,并对其中某些观点深以为然。如果我在一家规模较小的、有 10 到 15 个工程师的公司,假如有人建议管理和维护一批 Kubernetes 集群,那我会感到害怕的,因为它的运维开销太高了!
|
||||
|
||||
尽管我现在对 Kubernetes 的一切都很感兴趣,但我仍然对“<ruby>无服务器<rt>Serverless</rt></ruby>”计算会消灭运维工程师的说法抱有好奇。这种好奇心主要来源于我希望在未来仍然能有一份有报酬的工作 —— 如果我们前景光明的未来不需要运维工程师,那我得明白到底是怎么回事。我已经在 Lamdba 和Google Cloud Functions 上做了一些实验,结果让我印象十分深刻,但我仍然坚信无服务器解决方案只是解决了一部分问题。
|
||||
|
||||
我关注 [AWS Fargate][2] 已经有一段时间了,这就是 $work 的开发人员所推崇为“无服务器计算”的东西 —— 主要是因为 Fargate,用它你就可以无需管理底层节点而运行你的 Docker 容器。我想看看它到底意味着什么,所以我开始尝试从头开始在 Fargate 上运行一个应用,看看是否可以成功。这里我对成功的定义是一个与“生产级”应用程序相近的东西,我想应该包含以下内容:
|
||||
|
||||
* 一个在 Fargate 上运行的容器
|
||||
* 配置信息以环境变量的形式下推
|
||||
* “秘密信息” 不能是明文的
|
||||
* 位于负载均衡器之后
|
||||
* 有效的 SSL 证书的 TLS 通道
|
||||
|
||||
我以“基础设施即代码”的角度来开始整个任务,不遵循默认的 AWS 控制台向导,而是使用 terraform 来定义基础架构。这很可能让整个事情变得复杂,但我想确保任何部署都是可重现的,任何想要遵循此步骤的人都可发现我的结论。
|
||||
|
||||
上述所有标准通常都可以通过基于 Kubernetes 的平台使用一些外部的附加组件和插件来实现,所以我确实是以一种比较的心态来处理整个任务的,因为我要将它与我的常用工作流程进行比较。我的主要目标是看看Fargate 有多容易,特别是与 Kubernetes 相比时。结果让我感到非常惊讶。
|
||||
|
||||
### AWS 是有开销的
|
||||
|
||||
我有一个干净的 AWS 账户,并决定从零到部署一个 webapp。与 AWS 中的其它基础设施一样,我必须首先使基本的基础设施正常工作起来,因此我需要先定义一个 VPC。
|
||||
|
||||
遵循最佳实践,因此我将这个 VPC 划分为跨可用区(AZ)的子网,一个公共子网和私有子网。这时我想到,只要这种设置基础设施的需求存在,我就能找到一份这种工作。AWS 是"免"运维的这一概念一直让我感到愤怒。开发者社区中的许多人理所当然地认为在设置和定义一个设计良好的 AWS 账户和基础设施是不需要付出多少工作和努力的。而这种想当然甚至发生在开始谈论多帐户架构*之前*就有了——现在我仍然使用单一帐户,我已经必须定义好基础设施和传统的网络设备。
|
||||
|
||||
这里也值得记住,我已经做了很多次,所以我*很清楚*该做什么。我可以在我的帐户中使用默认的 VPC 以及预先提供的子网,我觉得很多刚开始的人也可以使用它。这大概花了我半个小时才运行起来,但我不禁想到,即使我想运行 lambda 函数,我仍然需要某种连接和网络。定义 NAT 网关和在 VPC 中路由根本不会让你觉得很“Serverless”,但要往下进行这就是必须要做的。
|
||||
|
||||
### 运行简单的容器
|
||||
|
||||
在我启动运行了基本的基础设施之后,现在我想让我的 Docker 容器运行起来。我开始翻阅 Fargate 文档并浏览 [入门][3] 文档,这些就马上就展现在了我面前:
|
||||
|
||||
![][4]
|
||||
|
||||
等等,只是让我的容器运行就至少要有**三个**步骤?这完全不像我所想的,不过还是让我们开始吧。
|
||||
|
||||
#### 任务定义
|
||||
|
||||
“<ruby>任务定义<rt>Task Definition<rt></ruby>”用来定义要运行的实际容器。我在这里遇到的问题是,任务定义这件事非常复杂。这里有很多选项都很简单,比如指定 Docker 镜像和内存限制,但我还必须定义一个网络模型以及我并不熟悉的其它各种选项。真需要这样吗?如果我完全没有 AWS 方面的知识就进入到这个过程里,那么在这个阶段我会感觉非常的不知所措。可以在 AWS 页面上找到这些 [参数][5] 的完整列表,这个列表很长。我知道我的容器需要一些环境变量,它需要暴露一个端口。所以我首先在一个神奇的 [terraform 模块][6] 的帮助下定义了这一点,这真的让这件事更容易了。如果没有这个模块,我就得手写 JSON 来定义我的容器定义。
|
||||
|
||||
首先我定义了一些环境变量:
|
||||
|
||||
```
|
||||
container_environment_variables = [
|
||||
{
|
||||
name = "USER"
|
||||
value = "${var.user}"
|
||||
},
|
||||
{
|
||||
name = "PASSWORD"
|
||||
value = "${var.password}"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
然后我使用上面提及的模块组成了任务定义:
|
||||
|
||||
```
|
||||
module "container_definition_app" {
|
||||
source = "cloudposse/ecs-container-definition/aws"
|
||||
version = "v0.7.0"
|
||||
|
||||
container_name = "${var.name}"
|
||||
container_image = "${var.image}"
|
||||
|
||||
container_cpu = "${var.ecs_task_cpu}"
|
||||
container_memory = "${var.ecs_task_memory}"
|
||||
container_memory_reservation = "${var.container_memory_reservation}"
|
||||
|
||||
port_mappings = [
|
||||
{
|
||||
containerPort = "${var.app_port}"
|
||||
hostPort = "${var.app_port}"
|
||||
protocol = "tcp"
|
||||
},
|
||||
]
|
||||
|
||||
environment = "${local.container_environment_variables}"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
在这一点上我非常困惑,我需要在这里定义很多配置才能运行,而这时什么都没有开始呢,但这是必要的 —— 运行 Docker 容器肯定需要了解一些容器配置的知识。我 [之前写过][7] 关于 Kubernetes 和配置管理的问题的文章,在这里似乎遇到了同样的问题。
|
||||
|
||||
接下来,我在上面的模块中定义了任务定义(幸好从我这里抽象出了所需的 JSON —— 如果我不得不手写JSON,我可能已经放弃了)。
|
||||
|
||||
当我定义模块参数时,我突然意识到我漏掉了一些东西。我需要一个 IAM 角色!好吧,让我来定义:
|
||||
|
||||
```
|
||||
resource "aws_iam_role" "ecs_task_execution" {
|
||||
name = "${var.name}-ecs_task_execution"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ecs-tasks.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "ecs_task_execution" {
|
||||
count = "${length(var.policies_arn)}"
|
||||
|
||||
role = "${aws_iam_role.ecs_task_execution.id}"
|
||||
policy_arn = "${element(var.policies_arn, count.index)}"
|
||||
}
|
||||
```
|
||||
|
||||
这样做是有意义的,我需要在 Kubernetes 中定义一个 RBAC 策略,所以在这里我还未完全错失或获得任何东西。这时我开始觉得从 Kubernetes 的角度来看,这种感觉非常熟悉。
|
||||
|
||||
```
|
||||
resource "aws_ecs_task_definition" "app" {
|
||||
family = "${var.name}"
|
||||
network_mode = "awsvpc"
|
||||
requires_compatibilities = ["FARGATE"]
|
||||
cpu = "${var.ecs_task_cpu}"
|
||||
memory = "${var.ecs_task_memory}"
|
||||
execution_role_arn = "${aws_iam_role.ecs_task_execution.arn}"
|
||||
task_role_arn = "${aws_iam_role.ecs_task_execution.arn}"
|
||||
|
||||
container_definitions = "${module.container_definition_app.json}"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
现在,为了运行起来我已经写了很多行代码,我阅读了很多 ECS 文档,我所做的就是定义一个任务定义。我还没有让这个东西运行起来。在这一点上,我真的很困惑这个基于 Kubernetes 的平台到底增值了什么,但我继续前行。
|
||||
|
||||
#### 服务
|
||||
|
||||
服务,一定程度上是将容器如何暴露给外部,另外是如何定义它拥有的副本数量。我的第一个想法是“啊!这就像一个 Kubernetes 服务!”我开始着手映射端口等。这是我第一次在 terraform 上跑:
|
||||
|
||||
```
|
||||
resource "aws_ecs_service" "app" {
|
||||
name = "${var.name}"
|
||||
cluster = "${module.ecs.this_ecs_cluster_id}"
|
||||
task_definition = "${data.aws_ecs_task_definition.app.family}:${max(aws_ecs_task_definition.app.revision, data.aws_ecs_task_definition.app.revision)}"
|
||||
desired_count = "${var.ecs_service_desired_count}"
|
||||
launch_type = "FARGATE"
|
||||
deployment_maximum_percent = "${var.ecs_service_deployment_maximum_percent}"
|
||||
deployment_minimum_healthy_percent = "${var.ecs_service_deployment_minimum_healthy_percent}"
|
||||
|
||||
network_configuration {
|
||||
subnets = ["${values(local.private_subnets)}"]
|
||||
security_groups = ["${module.app.this_security_group_id}"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
当我必须定义允许访问所需端口的安全组时,我再次感到沮丧,当我这样做了并将其插入到网络配置中后,我就像被扇了一巴掌。
|
||||
|
||||
我还需要定义自己的负载均衡器?
|
||||
|
||||
什么?
|
||||
|
||||
当然不是吗?
|
||||
|
||||
##### 负载均衡器从未远离
|
||||
|
||||
老实说,我很满意,我甚至不确定为什么。我已经习惯了 Kubernetes 的服务和 Ingress 对象,我一心认为用 Kubernetes 将我的应用程序放到网上是多么容易。当然,我们在 $work 花了几个月的时间建立一个平台,以便更轻松。我是 [external-dns][8] 和 [cert-manager][9] 的重度用户,它们可以自动填充 Ingress 对象上的 DNS 条目并自动化 TLS 证书,我非常了解进行这些设置所需的工作,但老实说,我认为在 Fargate 上做这件事会更容易。我认识到 Fargate 并没有声称自己是“如何运行应用程序”这件事的全部和最终目的,它只是抽象出节点管理,但我一直被告知这比 Kubernetes *更加容易*。我真的很惊讶。定义负载均衡器(即使你不想使用 Ingress 和 Ingress Controller)也是向 Kubernetes 部署服务的重要组成部分,我不得不在这里再次做同样的事情。这一切都让人觉得如此熟悉。
|
||||
|
||||
我现在意识到我需要:
|
||||
|
||||
* 一个负载均衡器
|
||||
* 一个 TLS 证书
|
||||
* 一个 DNS 名字
|
||||
|
||||
所以我着手做了这些。我使用了一些流行的 terraform 模块,并做了这个:
|
||||
|
||||
```
|
||||
# Define a wildcard cert for my app
|
||||
module "acm" {
|
||||
source = "terraform-aws-modules/acm/aws"
|
||||
version = "v1.1.0"
|
||||
|
||||
create_certificate = true
|
||||
|
||||
domain_name = "${var.route53_zone_name}"
|
||||
zone_id = "${data.aws_route53_zone.this.id}"
|
||||
|
||||
subject_alternative_names = [
|
||||
"*.${var.route53_zone_name}",
|
||||
]
|
||||
|
||||
|
||||
tags = "${local.tags}"
|
||||
|
||||
}
|
||||
# Define my loadbalancer
|
||||
resource "aws_lb" "main" {
|
||||
name = "${var.name}"
|
||||
subnets = [ "${values(local.public_subnets)}" ]
|
||||
security_groups = ["${module.alb_https_sg.this_security_group_id}", "${module.alb_http_sg.this_security_group_id}"]
|
||||
}
|
||||
|
||||
resource "aws_lb_target_group" "main" {
|
||||
name = "${var.name}"
|
||||
port = "${var.app_port}"
|
||||
protocol = "HTTP"
|
||||
vpc_id = "${local.vpc_id}"
|
||||
target_type = "ip"
|
||||
depends_on = [ "aws_lb.main" ]
|
||||
}
|
||||
|
||||
# Redirect all traffic from the ALB to the target group
|
||||
resource "aws_lb_listener" "main" {
|
||||
load_balancer_arn = "${aws_lb.main.id}"
|
||||
port = "80"
|
||||
protocol = "HTTP"
|
||||
|
||||
default_action {
|
||||
target_group_arn = "${aws_lb_target_group.main.id}"
|
||||
type = "forward"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lb_listener" "main-tls" {
|
||||
load_balancer_arn = "${aws_lb.main.id}"
|
||||
port = "443"
|
||||
protocol = "HTTPS"
|
||||
certificate_arn = "${module.acm.this_acm_certificate_arn}"
|
||||
|
||||
default_action {
|
||||
target_group_arn = "${aws_lb_target_group.main.id}"
|
||||
type = "forward"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
我必须承认,我在这里搞砸了好几次。我不得不在 AWS 控制台中四处翻弄,以弄清楚我做错了什么。这当然不是一个“轻松”的过程,而且我之前已经做过很多次了。老实说,在这一点上,Kubernetes 看起来对我很有启发性,但我意识到这是因为我对它非常熟悉。幸运的是我能够使用托管的 Kubernetes 平台(预装了 external-dns 和 cert-manager),我真的很想知道我漏掉了 Fargate 什么增值的地方。它真的感觉不那么简单。
|
||||
|
||||
经过一番折腾,我现在有一个可以工作的 ECS 服务。包括服务在内的最终定义如下所示:
|
||||
|
||||
```
|
||||
data "aws_ecs_task_definition" "app" {
|
||||
task_definition = "${var.name}"
|
||||
depends_on = ["aws_ecs_task_definition.app"]
|
||||
}
|
||||
|
||||
resource "aws_ecs_service" "app" {
|
||||
name = "${var.name}"
|
||||
cluster = "${module.ecs.this_ecs_cluster_id}"
|
||||
task_definition = "${data.aws_ecs_task_definition.app.family}:${max(aws_ecs_task_definition.app.revision, data.aws_ecs_task_definition.app.revision)}"
|
||||
desired_count = "${var.ecs_service_desired_count}"
|
||||
launch_type = "FARGATE"
|
||||
deployment_maximum_percent = "${var.ecs_service_deployment_maximum_percent}"
|
||||
deployment_minimum_healthy_percent = "${var.ecs_service_deployment_minimum_healthy_percent}"
|
||||
|
||||
network_configuration {
|
||||
subnets = ["${values(local.private_subnets)}"]
|
||||
security_groups = ["${module.app_sg.this_security_group_id}"]
|
||||
}
|
||||
|
||||
load_balancer {
|
||||
target_group_arn = "${aws_lb_target_group.main.id}"
|
||||
container_name = "app"
|
||||
container_port = "${var.app_port}"
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
"aws_lb_listener.main",
|
||||
]
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
我觉得我已经接近完成了,但后来我记起了我只完成了最初的“入门”文档中所需的 3 个步骤中的 2 个,我仍然需要定义 ECS 群集。
|
||||
|
||||
#### 集群
|
||||
|
||||
感谢 [定义模块][10],定义要所有这些运行的集群实际上非常简单。
|
||||
|
||||
```
|
||||
module "ecs" {
|
||||
source = "terraform-aws-modules/ecs/aws"
|
||||
version = "v1.1.0"
|
||||
|
||||
name = "${var.name}"
|
||||
}
|
||||
```
|
||||
|
||||
这里让我感到惊讶的是为什么我必须定义一个集群。作为一个相当熟悉 ECS 的人,你会觉得你需要一个集群,但我试图从一个必须经历这个过程的新人的角度来考虑这一点 —— 对我来说,Fargate 标榜自己“
|
||||
Serverless”而你仍需要定义集群,这似乎很令人惊讶。当然这是一个小细节,但它确实盘旋在我的脑海里。
|
||||
|
||||
### 告诉我你的 Secret
|
||||
|
||||
在这个阶段,我很高兴我成功地运行了一些东西。然而,我的原始的成功标准缺少一些东西。如果我们回到任务定义那里,你会记得我的应用程序有一个存放密码的环境变量:
|
||||
|
||||
```
|
||||
container_environment_variables = [
|
||||
{
|
||||
name = "USER"
|
||||
value = "${var.user}"
|
||||
},
|
||||
{
|
||||
name = "PASSWORD"
|
||||
value = "${var.password}"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
如果我在 AWS 控制台中查看我的任务定义,我的密码就在那里,明晃晃的明文。我希望不要这样,所以我开始尝试将其转化为其他东西,类似于 [Kubernetes 的Secrets管理][11]。
|
||||
|
||||
#### AWS SSM
|
||||
|
||||
Fargate / ECS 执行<ruby>secret 管理<rt>secret management</rt></ruby>部分的方式是使用 [AWS SSM][12](此服务的全名是 AWS 系统管理器参数存储库 Systems Manager Parameter Store,但我不想使用这个名称,因为坦率地说这个名字太愚蠢了)。
|
||||
|
||||
AWS 文档很好的[涵盖了这个内容][13],因此我开始将其转换为 terraform。
|
||||
|
||||
##### 指定秘密信息
|
||||
|
||||
首先,你必须定义一个参数并为其命名。在 terraform 中,它看起来像这样:
|
||||
|
||||
```
|
||||
resource "aws_ssm_parameter" "app_password" {
|
||||
name = "${var.app_password_param_name}" # The name of the value in AWS SSM
|
||||
type = "SecureString"
|
||||
value = "${var.app_password}" # The actual value of the password, like correct-horse-battery-stable
|
||||
}
|
||||
```
|
||||
|
||||
显然,这里的关键部分是 “SecureString” 类型。这会使用默认的 AWS KMS 密钥来加密数据,这对我来说并不是很直观。这比 Kubernetes 的 Secret 管理具有巨大优势,默认情况下,这些 Secret 在 etcd 中是不加密的。
|
||||
|
||||
然后我为 ECS 指定了另一个本地值映射,并将其作为 Secret 参数传递:
|
||||
|
||||
```
|
||||
container_secrets = [
|
||||
{
|
||||
name = "PASSWORD"
|
||||
valueFrom = "${var.app_password_param_name}"
|
||||
},
|
||||
]
|
||||
|
||||
module "container_definition_app" {
|
||||
source = "cloudposse/ecs-container-definition/aws"
|
||||
version = "v0.7.0"
|
||||
|
||||
container_name = "${var.name}"
|
||||
container_image = "${var.image}"
|
||||
|
||||
container_cpu = "${var.ecs_task_cpu}"
|
||||
container_memory = "${var.ecs_task_memory}"
|
||||
container_memory_reservation = "${var.container_memory_reservation}"
|
||||
|
||||
port_mappings = [
|
||||
{
|
||||
containerPort = "${var.app_port}"
|
||||
hostPort = "${var.app_port}"
|
||||
protocol = "tcp"
|
||||
},
|
||||
]
|
||||
|
||||
environment = "${local.container_environment_variables}"
|
||||
secrets = "${local.container_secrets}"
|
||||
```
|
||||
|
||||
##### 出了个问题
|
||||
|
||||
此刻,我重新部署了我的任务定义,并且非常困惑。为什么任务没有正确拉起?当新的任务定义(版本 8)可用时,我一直在控制台中看到正在运行的应用程序仍在使用先前的任务定义(版本 7)。解决这件事花费的时间比我预期的要长,但是在控制台的事件屏幕上,我注意到了 IAM 错误。我错过了一个步骤,容器无法从 AWS SSM 中读取 Secret 信息,因为它没有正确的 IAM 权限。这是我第一次真正对整个这件事情感到沮丧。从用户体验的角度来看,这里的反馈非常*糟糕*。如果我没有发觉的话,我会认为一切都很好,因为仍然有一个任务正在运行,我的应用程序仍然可以通过正确的 URL 访问 —— 只不过是旧的配置而已。
|
||||
|
||||
在 Kubernetes 里,我会清楚地看到 pod 定义中的错误。Fargate 可以确保我的应用不会停止,这绝对是太棒了,但作为一名运维,我需要一些关于发生了什么的实际反馈。这真的不够好。我真的希望 Fargate 团队的人能够读到这篇文章,改善这种体验。
|
||||
|
||||
### 就这样了
|
||||
|
||||
到这里就结束了,我的应用程序正在运行,也符合我的所有标准。我确实意识到我做了一些改进,其中包括:
|
||||
|
||||
* 定义一个 cloudwatch 日志组,这样我就可以正确地写日志了
|
||||
* 添加了一个 route53 托管区域,使整个事情从 DNS 角度更容易自动化
|
||||
* 修复并重新调整了 IAM 权限,这里太宽泛了
|
||||
|
||||
但老实说,现在我想反思一下这段经历。我写了一个关于我的经历的 [推特会话][14],然后花了其余时间思考我在这里的真实感受。
|
||||
|
||||
### 代价
|
||||
|
||||
经过一夜的反思,我意识到无论你是使用 Fargate 还是 Kubernetes,这个过程都大致相同。最让我感到惊讶的是,尽管我经常听说 Fargate “更容易”,但我真的没有看到任何超过 Kubernetes 平台的好处。现在,如果你正在构建 Kubernetes 集群,我绝对可以看到这里的价值 —— 管理节点和控制面板只是不必要的开销,问题是 —— 基于 Kubernetes 的平台的大多数消费者都*没有*这样做。如果你很幸运能够使用 GKE,你几乎不需要考虑集群的管理,你可以使用单个 `gcloud` 命令来运行集群。我经常使用 Digital Ocean 的 Kubernetes 托管服务,我可以肯定地说它就像操作 Fargate 集群一样简单,实际上在某种程度上它更容易。
|
||||
|
||||
必须定义一些基础设施来运行你的容器就是此时的代价。谷歌本周可能刚刚使用他们的 [Google Cloud Run][15] 产品改变了游戏规则,但他们在这一领域的领先优势远远领先于其他所有人。
|
||||
|
||||
从这整个经历中,我可以肯定的说:*大规模运行容器仍然很难。*它需要思考,需要领域知识,需要运维和开发人员之间的协作。它还需要一个基础来构建 —— 任何基于 AWS 的操作都需要事先定义和运行一些基础架构。我对一些公司似乎渴望的 “NoOps” 概念非常感兴趣。我想如果你正在运行一个无状态应用程序,你可以把它全部放在一个 lambda 函数和一个 API 网关中,这可能不错,但我们是否真的适合在任何一种企业环境中这样做?我真的不这么认为。
|
||||
|
||||
#### 公平比较
|
||||
|
||||
令我印象深刻的另一个现实是,技术 A 和技术 B 之间的比较通常不太公平,我经常在 AWS 上看到这一点。这种实际情况往往与 Jeff Barr 博客文章截然不同。如果你是一家足够小的公司,你可以使用 AWS 控制台在 AWS 中部署你的应用程序并接受所有默认值,这绝对更容易。但是,我不想使用默认值,因为默认值几乎是不适用于生产环境的。一旦你开始剥离掉云服务商服务的层面,你就会开始意识到最终你仍然是在运行软件 —— 它仍然需要设计良好、部署良好、运行良好。我相信 AWS 和 Kubernetes 以及所有其他云服务商的增值服务使得它更容易运行、设计和操作,但它绝对不是免费的。
|
||||
|
||||
#### Kubernetes 的争议
|
||||
|
||||
最后就是:如果你将 Kubernetes 纯粹视为一个容器编排工具,你可能会喜欢 Fargate。然而,随着我对 Kubernetes 越来越熟悉,我开始意识到它作为一种技术的重要性 —— 不仅因为它是一个伟大的容器编排工具,而且因为它的设计模式 —— 它是声明性的、API 驱动的平台。 在*整个* Fargate 过程期间发生的一个简单的事情是,如果我删除这里某个东西,Fargate 不一定会为我重新创建它。自动缩放很不错,不需要管理服务器和操作系统的补丁及更新也很棒,但我觉得因为无法使用 Kubernetes 自我修复和 API 驱动模型而失去了很多。当然,Kubernetes 有一个学习曲线,但从这里的体验来看,Fargate 也是如此。
|
||||
|
||||
### 总结
|
||||
|
||||
尽管我在这个过程中遭遇了困惑,但我确实很喜欢这种体验。我仍然相信 Fargate 是一项出色的技术,AWS 团队对 ECS/Fargate 所做的工作确实非常出色。然而,我的观点是,这绝对不比 Kubernetes “更容易”,只是……难点不同。
|
||||
|
||||
在生产环境中运行容器时出现的问题大致相同。如果你从这篇文章中有所收获,它应该是这样的:*不管你选择的哪种方式都有运维开销*。不要相信你选择一些东西你的世界就变得更轻松。我个人的意见是:如果你有一个运维团队,而你的公司要为多个应用程序团队部署容器 —— 选择一种技术并围绕它构建流程和工具以使其更容易。
|
||||
|
||||
人们说的一点肯定没错,用点技巧可以更容易地使用某种技术。在这个阶段,谈到 Fargate,下面的漫画这总结了我的感受:
|
||||
|
||||
![][16]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://leebriggs.co.uk/blog/2019/04/13/the-fargate-illusion.html
|
||||
|
||||
作者:[Lee Briggs][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Bestony](https://github.com/Bestony)
|
||||
校对:[wxy](https://github.com/wxy), 临石(阿里云智能技术专家)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://leebriggs.co.uk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://matthias-endler.de/2019/maybe-you-dont-need-kubernetes/
|
||||
[2]: https://aws.amazon.com/fargate/
|
||||
[3]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_GetStarted.html
|
||||
[4]: https://i.imgur.com/YfMyXBdl.png
|
||||
[5]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html
|
||||
[6]: https://github.com/cloudposse/terraform-aws-ecs-container-definition
|
||||
[7]: https://leebriggs.co.uk/blog/2018/05/08/kubernetes-config-mgmt.html
|
||||
[8]: https://github.com/kubernetes-incubator/external-dns
|
||||
[9]: https://github.com/jetstack/cert-manager
|
||||
[10]: https://github.com/terraform-aws-modules/terraform-aws-ecs
|
||||
[11]: https://kubernetes.io/docs/concepts/configuration/secret/
|
||||
[12]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
|
||||
[13]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html
|
||||
[14]: https://twitter.com/briggsl/status/1116870900719030272
|
||||
[15]: https://cloud.google.com/run/
|
||||
[16]: https://i.imgur.com/Bx7Q50Jl.jpg
|
@ -0,0 +1,121 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10780-1.html)
|
||||
[#]: subject: (Getting started with Mercurial for version control)
|
||||
[#]: via: (https://opensource.com/article/19/4/getting-started-mercurial)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
Mercurial 版本控制入门
|
||||
======
|
||||
|
||||
> 了解 Mercurial 的基础知识,它是一个用 Python 写的分布式版本控制系统。
|
||||
|
||||
![][1]
|
||||
|
||||
[Mercurial][2] 是一个用 Python 编写的分布式版本控制系统。因为它是用高级语言编写的,所以你可以用 Python 函数编写一个 Mercurial 扩展。
|
||||
|
||||
在[官方文档中][3]说明了几种安装 Mercurial 的方法。我最喜欢的一种方法不在里面:使用 `pip`。这是开发本地扩展的最合适方式!
|
||||
|
||||
目前,Mercurial 仅支持 Python 2.7,因此你需要创建一个 Python 2.7 虚拟环境:
|
||||
|
||||
```
|
||||
python2 -m virtualenv mercurial-env
|
||||
./mercurial-env/bin/pip install mercurial
|
||||
```
|
||||
|
||||
为了让命令简短一些,以及满足人们对化学幽默的渴望,该命令称之为 `hg`。
|
||||
|
||||
```
|
||||
$ source mercurial-env/bin/activate
|
||||
(mercurial-env)$ mkdir test-dir
|
||||
(mercurial-env)$ cd test-dir
|
||||
(mercurial-env)$ hg init
|
||||
(mercurial-env)$ hg status
|
||||
(mercurial-env)$
|
||||
```
|
||||
|
||||
由于还没有任何文件,因此状态为空。添加几个文件:
|
||||
|
||||
```
|
||||
(mercurial-env)$ echo 1 > one
|
||||
(mercurial-env)$ echo 2 > two
|
||||
(mercurial-env)$ hg status
|
||||
? one
|
||||
? two
|
||||
(mercurial-env)$ hg addremove
|
||||
adding one
|
||||
adding two
|
||||
(mercurial-env)$ hg commit -m 'Adding stuff'
|
||||
(mercurial-env)$ hg log
|
||||
changeset: 0:1f1befb5d1e9
|
||||
tag: tip
|
||||
user: Moshe Zadka <[moshez@zadka.club][4]>
|
||||
date: Fri Mar 29 12:42:43 2019 -0700
|
||||
summary: Adding stuff
|
||||
```
|
||||
|
||||
`addremove` 命令很有用:它将任何未被忽略的新文件添加到托管文件列表中,并移除任何已删除的文件。
|
||||
|
||||
如我所说,Mercurial 扩展用 Python 写成,它们只是常规的 Python 模块。
|
||||
|
||||
这是一个简短的 Mercurial 扩展示例:
|
||||
|
||||
```
|
||||
from mercurial import registrar
|
||||
from mercurial.i18n import _
|
||||
|
||||
cmdtable = {}
|
||||
command = registrar.command(cmdtable)
|
||||
|
||||
@command('say-hello',
|
||||
[('w', 'whom', '', _('Whom to greet'))])
|
||||
def say_hello(ui, repo, `opts):
|
||||
ui.write("hello ", opts['whom'], "\n")
|
||||
```
|
||||
|
||||
简单的测试方法是将它手动加入虚拟环境中的文件中:
|
||||
|
||||
```
|
||||
`$ vi ../mercurial-env/lib/python2.7/site-packages/hello_ext.py`
|
||||
```
|
||||
|
||||
然后你需要*启用*扩展。你可以仅在当前仓库中启用它:
|
||||
|
||||
```
|
||||
$ cat >> .hg/hgrc
|
||||
[extensions]
|
||||
hello_ext =
|
||||
```
|
||||
|
||||
现在,问候有了:
|
||||
|
||||
```
|
||||
(mercurial-env)$ hg say-hello --whom world
|
||||
hello world
|
||||
```
|
||||
|
||||
大多数扩展会做更多有用的东西,甚至可能与 Mercurial 有关。 `repo` 对象是 `mercurial.hg.repository` 的对象。
|
||||
|
||||
有关 Mercurial API 的更多信息,请参阅[官方文档][5]。并访问[官方仓库][6]获取更多示例和灵感。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/getting-started-mercurial
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_cloud21x_cc.png?itok=5UwC92dO
|
||||
[2]: https://www.mercurial-scm.org/
|
||||
[3]: https://www.mercurial-scm.org/wiki/UnixInstall
|
||||
[4]: mailto:moshez@zadka.club
|
||||
[5]: https://www.mercurial-scm.org/wiki/MercurialApi#Repositories
|
||||
[6]: https://www.mercurial-scm.org/repo/hg/file/tip/hgext
|
@ -0,0 +1,127 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10777-1.html)
|
||||
[#]: subject: (How to identify duplicate files on Linux)
|
||||
[#]: via: (https://www.networkworld.com/article/3387961/how-to-identify-duplicate-files-on-linux.html#tk.rss_all)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
如何识别 Linux 上的文件分身
|
||||
======
|
||||
|
||||
> Linux 系统上的一些文件可能出现在多个位置。按照本文指示查找并识别这些“同卵双胞胎”,还可以了解为什么硬链接会如此有利。
|
||||
|
||||
![Archana Jarajapu \(CC BY 2.0\)][1]
|
||||
|
||||
识别使用同一个磁盘空间的文件依赖于利用文件使用相同的 inode 这一事实。这种数据结构存储除了文件名和内容之外的所有信息。如果两个或多个文件具有不同的名称和文件系统位置,但共享一个 inode,则它们还共享内容、所有权、权限等。
|
||||
|
||||
这些文件通常被称为“硬链接”,不像符号链接(即软链接)那样仅仅通过包含它们的名称指向其他文件,符号链接很容易在文件列表中通过第一个位置的 `l` 和引用文件的 `->` 符号识别出来。
|
||||
|
||||
```
|
||||
$ ls -l my*
|
||||
-rw-r--r-- 4 shs shs 228 Apr 12 19:37 myfile
|
||||
lrwxrwxrwx 1 shs shs 6 Apr 15 11:18 myref -> myfile
|
||||
-rw-r--r-- 4 shs shs 228 Apr 12 19:37 mytwin
|
||||
```
|
||||
|
||||
在单个目录中的硬链接并不是很明显,但它仍然非常容易找到。如果使用 `ls -i` 命令列出文件并按 inode 编号排序,则可以非常容易地挑选出硬链接。在这种类型的 `ls` 输出中,第一列显示 inode 编号。
|
||||
|
||||
```
|
||||
$ ls -i | sort -n | more
|
||||
...
|
||||
788000 myfile <==
|
||||
788000 mytwin <==
|
||||
801865 Name_Labels.pdf
|
||||
786692 never leave home angry
|
||||
920242 NFCU_Docs
|
||||
800247 nmap-notes
|
||||
```
|
||||
|
||||
扫描输出,查找相同的 inode 编号,任何匹配都会告诉你想知道的内容。
|
||||
|
||||
另一方面,如果你只是想知道某个特定文件是否是另一个文件的硬链接,那么有一种方法比浏览数百个文件的列表更简单,即 `find` 命令的 `-samefile` 选项将帮助你完成工作。
|
||||
|
||||
```
|
||||
$ find . -samefile myfile
|
||||
./myfile
|
||||
./save/mycopy
|
||||
./mytwin
|
||||
```
|
||||
|
||||
注意,提供给 `find` 命令的起始位置决定文件系统会扫描多少来进行匹配。在上面的示例中,我们正在查看当前目录和子目录。
|
||||
|
||||
使用 `find` 的 `-ls` 选项添加输出的详细信息可能更有说服力:
|
||||
|
||||
```
|
||||
$ find . -samefile myfile -ls
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 ./myfile
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 ./save/mycopy
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 ./mytwin
|
||||
```
|
||||
|
||||
第一列显示 inode 编号,然后我们会看到文件权限、链接、所有者、文件大小、日期信息以及引用相同磁盘内容的文件的名称。注意,在这种情况下,链接字段是 “4” 而不是我们可能期望的 “3”。这告诉我们还有另一个指向同一个 inode 的链接(但不在我们的搜索范围内)。
|
||||
|
||||
如果你想在一个目录中查找所有硬链接的实例,可以尝试以下的脚本来创建列表并为你查找副本:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
# seaches for files sharing inodes
|
||||
|
||||
prev=""
|
||||
|
||||
# list files by inode
|
||||
ls -i | sort -n > /tmp/$0
|
||||
|
||||
# search through file for duplicate inode #s
|
||||
while read line
|
||||
do
|
||||
inode=`echo $line | awk '{print $1}'`
|
||||
if [ "$inode" == "$prev" ]; then
|
||||
grep $inode /tmp/$0
|
||||
fi
|
||||
prev=$inode
|
||||
done < /tmp/$0
|
||||
|
||||
# clean up
|
||||
rm /tmp/$0
|
||||
```
|
||||
|
||||
```
|
||||
$ ./findHardLinks
|
||||
788000 myfile
|
||||
788000 mytwin
|
||||
```
|
||||
|
||||
你还可以使用 `find` 命令按 inode 编号查找文件,如命令中所示。但是,此搜索可能涉及多个文件系统,因此可能会得到错误的结果。因为相同的 inode 编号可能会在另一个文件系统中使用,代表另一个文件。如果是这种情况,文件的其他详细信息将不相同。
|
||||
|
||||
```
|
||||
$ find / -inum 788000 -ls 2> /dev/null
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 /tmp/mycopy
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 /home/shs/myfile
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 /home/shs/save/mycopy
|
||||
788000 4 -rw-r--r-- 4 shs shs 228 Apr 12 19:37 /home/shs/mytwin
|
||||
```
|
||||
|
||||
注意,错误输出被重定向到 `/dev/null`,这样我们就不必查看所有 “Permission denied” 错误,否则这些错误将显示在我们不允许查看的其他目录中。
|
||||
|
||||
此外,扫描包含相同内容但不共享 inode 的文件(即,简单的文本拷贝)将花费更多的时间和精力。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3387961/how-to-identify-duplicate-files-on-linux.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][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.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.idgesg.net/images/article/2019/04/reflections-candles-100793651-large.jpg
|
||||
[2]: https://www.networkworld.com/article/3242170/linux/invaluable-tips-and-tricks-for-troubleshooting-linux.html
|
||||
[3]: https://www.facebook.com/NetworkWorld/
|
||||
[4]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,236 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (arrowfeng)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10789-1.html)
|
||||
[#]: subject: (How to Install MySQL in Ubuntu Linux)
|
||||
[#]: via: (https://itsfoss.com/install-mysql-ubuntu/)
|
||||
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
|
||||
|
||||
怎样在 Ubuntu Linux 上安装 MySQL
|
||||
======
|
||||
|
||||
> 本教程教你如何在基于 Ubuntu 的 Linux 发行版上安装 MySQL。对于首次使用的用户,你将会学习到如何验证你的安装和第一次怎样去连接 MySQL。
|
||||
|
||||
[MySQL][1] 是一个典型的数据库管理系统。它被用于许多技术栈中,包括流行的 [LAMP][2] (Linux、Apache、MySQL、PHP)技术栈。它已经被证实了其稳定性。另一个让 MySQL 受欢迎的原因是它是开源的。
|
||||
|
||||
MySQL 是关系型数据库(基本上是表格数据)。以这种方式它很容易去存储、组织和访问数据。它使用SQL(结构化查询语言)来管理数据。
|
||||
|
||||
这这篇文章中,我将向你展示如何在 Ubuntu 18.04 安装和使用 MySQL 8.0。让我们一起来看看吧!
|
||||
|
||||
### 在 Ubuntu 上安装 MySQL
|
||||
|
||||
![][3]
|
||||
|
||||
我将会介绍两种在 Ubuntu 18.04 上安装 MySQL 的方法:
|
||||
|
||||
1. 从 Ubuntu 仓库上安装 MySQL。非常简单,但不是最新版(5.7)
|
||||
2. 从官方仓库安装 MySQL。你将额外增加一些步处理过程,但不用担心。你将会拥有最新版的MySQL(8.0)
|
||||
|
||||
有必要的时候,我将会提供屏幕截图去引导你。但这篇文章中的大部分步骤,我将直接在终端(默认热键: `CTRL+ALT+T`)输入命令。别害怕!
|
||||
|
||||
#### 方法 1、从 Ubuntu 仓库安装 MySQL
|
||||
|
||||
首先,输入下列命令确保你的仓库已经被更新:
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
```
|
||||
|
||||
现在,安装 MySQL 5.7,简单输入下列命令:
|
||||
|
||||
```
|
||||
sudo apt install mysql-server -y
|
||||
```
|
||||
|
||||
就是这样!简单且高效。
|
||||
|
||||
#### 方法 2、使用官方仓库安装 MySQL
|
||||
|
||||
虽然这个方法多了一些步骤,但我将逐一介绍,并尝试写下清晰的笔记。
|
||||
|
||||
首先浏览 MySQL 官方网站的[下载页面][4]。
|
||||
|
||||
![][5]
|
||||
|
||||
在这里,选择 DEB 软件包,点击“Download”链接。
|
||||
|
||||
![][6]
|
||||
|
||||
滑到有关于 Oracle 网站信息的底部,右键 “No thanks, just start my download.”,然后选择 “Copy link location”。
|
||||
|
||||
现在回到终端,我们将使用 [Curl][7] 命令去下载这个软件包:
|
||||
|
||||
```
|
||||
curl -OL https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb
|
||||
```
|
||||
|
||||
`https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb` 是我刚刚从网页上复制的链接。根据当前的 MySQL 版本,它有可能不同。让我们使用 `dpkg` 去开始安装 MySQL:
|
||||
|
||||
```
|
||||
sudo dpkg -i mysql-apt-config*
|
||||
```
|
||||
|
||||
更新你的仓库:
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
```
|
||||
|
||||
要实际安装 MySQL,我们将使用像第一个方法中同样的命令来安装:
|
||||
|
||||
```
|
||||
sudo apt install mysql-server -y
|
||||
```
|
||||
|
||||
这样做会在你的终端中打开包配置的提示。使用向下箭头选择“Ok”选项。
|
||||
|
||||
![][8]
|
||||
|
||||
点击回车。这应该会提示你输入密码:这是在为 MySQL 设置 root 密码。不要与 [Ubuntu 的 root 密码混淆][9]。
|
||||
|
||||
![][10]
|
||||
|
||||
输入密码然后点击 Tab 键去选择“Ok“。点击回车键,你将重新输入密码。操作完之后,再次键入 Tab 去选择 “Ok”。按下回车键。
|
||||
|
||||
![][11]
|
||||
|
||||
将会展示一些关于 MySQL Server 的配置信息。再次按下 Tab 去选择 “Ok” 和按下回车键:
|
||||
|
||||
![][12]
|
||||
|
||||
这里你需要去选择默认验证插件。确保选择了“Use Strong Password Encryption”。按下 Tab 键和回车键。
|
||||
|
||||
就是这样!你已经成功地安装了 MySQL。
|
||||
|
||||
#### 验证你的 MySQL 安装
|
||||
|
||||
要验证 MySQL 已经正确安装,使用下列命令:
|
||||
|
||||
```
|
||||
sudo systemctl status mysql.service
|
||||
```
|
||||
|
||||
这将展示一些关于 MySQL 服务的信息:
|
||||
|
||||
![][13]
|
||||
|
||||
你应该在那里看到 “Active: active (running)”。如果你没有看到,使用下列命令去开始这个服务:
|
||||
|
||||
```
|
||||
sudo systemctl start mysql.service
|
||||
```
|
||||
|
||||
#### 配置/保护 MySQL
|
||||
|
||||
对于刚安装的 MySQL,你应该运行它提供的安全相关的更新命令。就是:
|
||||
|
||||
```
|
||||
sudo mysql_secure_installation
|
||||
```
|
||||
|
||||
这样做首先会询问你是否想使用 “<ruby>密码有效强度<rt>validate password component</rt></ruby>”。如果你想使用它,你将必须选择一个最小密码强度(0 – 低,1 – 中,2 – 高)。你将无法输入任何不遵守所选规则的密码。如果你没有使用强密码的习惯(本应该使用),这可能会配上用场。如果你认为它可能有帮助,那你就键入 `y` 或者 `Y`,按下回车键,然后为你的密码选择一个强度等级和输入一个你想使用的密码。如果成功,你将继续强化过程;否则你将重新输入一个密码。
|
||||
|
||||
但是,如果你不想要此功能(我不会),只需按回车或任何其他键即可跳过使用它。
|
||||
|
||||
对于其他选项,我建议开启它们(对于每一步输入 `y` 或者 `Y` 和按下回车)。它们(依序)是:“<ruby>移除匿名用户<rt>remove anonymous user</rt></ruby>”,“<ruby>禁止 root 远程登录<rt>disallow root login remotely</rt></ruby>”,“<ruby>移除测试数据库及其访问<rt>remove test database and access to it</rt></ruby>”。“<ruby>重新载入权限表<rt>reload privilege tables now</rt></ruby>”。
|
||||
|
||||
#### 链接与断开 MySQL Server
|
||||
|
||||
为了运行 SQL 查询,你首先必须使用 MySQL 连到服务器并在 MySQL 提示符使用。
|
||||
|
||||
执行此操作的命令是:
|
||||
|
||||
```
|
||||
mysql -h host_name -u user -p
|
||||
```
|
||||
|
||||
* `-h` 用来指定一个主机名(如果这个服务被安装到其他机器上,那么会有用;如果没有,忽略它)
|
||||
* `-u` 指定登录的用户
|
||||
* `-p` 指定你想输入的密码.
|
||||
|
||||
虽然出于安全原因不建议,但是你可以在命令行最右边的 `-p` 后直接输入密码。例如,如果用户`test_user` 的密码是 `1234`,那么你可以在你使用的机器上尝试去连接,你可以这样使用:
|
||||
|
||||
```
|
||||
mysql -u test_user -p1234
|
||||
```
|
||||
|
||||
如果你成功输入了必要的参数,你将会收到由 MySQL shell 提示符提供的欢迎(`mysql >`):
|
||||
|
||||
![][14]
|
||||
|
||||
要从服务端断开连接和离开 MySQL 提示符,输入:
|
||||
|
||||
```
|
||||
QUIT
|
||||
```
|
||||
|
||||
输入 `quit` (MySQL 不区分大小写)或者 `\q` 也能工作。按下回车退出。
|
||||
|
||||
你使用简单的命令也能输出关于版本的信息:
|
||||
|
||||
```
|
||||
sudo mysqladmin -u root version -p
|
||||
```
|
||||
|
||||
如果你想看命令行选项列表,使用:
|
||||
|
||||
```
|
||||
mysql --help
|
||||
```
|
||||
|
||||
#### 卸载 MySQL
|
||||
|
||||
如果您决定要使用较新版本或只是想停止使用 MySQL。
|
||||
|
||||
首先,关闭服务:
|
||||
|
||||
```
|
||||
sudo systemctl stop mysql.service && sudo systemctl disable mysql.service
|
||||
```
|
||||
|
||||
确保你备份了你的数据库,以防你之后想使用它们。你可以通过运行下列命令卸载 MySQL:
|
||||
|
||||
```
|
||||
sudo apt purge mysql*
|
||||
```
|
||||
|
||||
清理依赖:
|
||||
|
||||
```
|
||||
sudo apt autoremove
|
||||
```
|
||||
|
||||
### 小结
|
||||
|
||||
在这篇文章中,我已经介绍如何在 Ubuntu Linux 上安装 Mysql。我很高兴如果这篇文章能帮助到那些正为此挣扎的用户或者刚刚开始的用户。
|
||||
|
||||
如果你发现这篇文章是一个很有用的资源,在评论里告诉我们。你为了什么使用 MySQL? 我们渴望收到你的任何反馈、印象和建议。感谢阅读,并毫不犹豫地尝试这个很棒的工具!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/install-mysql-ubuntu/
|
||||
|
||||
作者:[Sergiu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[arrowfeng](https://github.com/arrowfeng)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/sergiu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.mysql.com/
|
||||
[2]: https://en.wikipedia.org/wiki/LAMP_(software_bundle)
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/install-mysql-ubuntu.png?resize=800%2C450&ssl=1
|
||||
[4]: https://dev.mysql.com/downloads/repo/apt/
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_apt_download_page.jpg?fit=800%2C280&ssl=1
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_deb_download_link.jpg?fit=800%2C507&ssl=1
|
||||
[7]: https://linuxhandbook.com/curl-command-examples/
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_package_configuration_ok.jpg?fit=800%2C587&ssl=1
|
||||
[9]: https://itsfoss.com/change-password-ubuntu/
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_enter_password.jpg?fit=800%2C583&ssl=1
|
||||
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_information_on_configuring.jpg?fit=800%2C581&ssl=1
|
||||
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_default_authentication_plugin.jpg?fit=800%2C586&ssl=1
|
||||
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_service_information.jpg?fit=800%2C402&ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/mysql_shell_prompt-2.jpg?fit=800%2C423&ssl=1
|
@ -0,0 +1,311 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (zgj1024)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10765-1.html)
|
||||
[#]: subject: (HTTPie – A Modern Command Line HTTP Client For Curl And Wget Alternative)
|
||||
[#]: via: (https://www.2daygeek.com/httpie-curl-wget-alternative-http-client-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
HTTPie:替代 Curl 和 Wget 的现代 HTTP 命令行客户端
|
||||
======
|
||||
|
||||
大多数时间我们会使用 `curl` 命令或是 `wget` 命令下载文件或者做其他事。
|
||||
|
||||
我们以前曾写过 [最佳命令行下载管理器][1] 的文章。你可以点击相应的 URL 连接来浏览这些文章。
|
||||
|
||||
* [aria2 – Linux 下的多协议命令行下载工具][2]
|
||||
* [Axel – Linux 下的轻量级命令行下载加速器][3]
|
||||
* [Wget – Linux 下的标准命令行下载工具][4]
|
||||
* [curl – Linux 下的实用的命令行下载工具][5]
|
||||
|
||||
今天我们将讨论同样的话题。这个实用程序名为 HTTPie。
|
||||
|
||||
它是现代命令行 http 客户端,也是 `curl` 和 `wget` 命令的最佳替代品。
|
||||
|
||||
### 什么是 HTTPie?
|
||||
|
||||
HTTPie (发音是 aitch-tee-tee-pie) 是一个 HTTP 命令行客户端。
|
||||
|
||||
HTTPie 工具是现代的 HTTP 命令行客户端,它能通过命令行界面与 Web 服务进行交互。
|
||||
|
||||
它提供一个简单的 `http` 命令,允许使用简单而自然的语法发送任意的 HTTP 请求,并会显示彩色的输出。
|
||||
|
||||
HTTPie 能用于测试、调试及与 HTTP 服务器交互。
|
||||
|
||||
### 主要特点
|
||||
|
||||
* 具表达力的和直观语法
|
||||
* 格式化的及彩色化的终端输出
|
||||
* 内置 JSON 支持
|
||||
* 表单和文件上传
|
||||
* HTTPS、代理和认证
|
||||
* 任意请求数据
|
||||
* 自定义头部
|
||||
* 持久化会话
|
||||
* 类似 `wget` 的下载
|
||||
* 支持 Python 2.7 和 3.x
|
||||
|
||||
### 在 Linux 下如何安装 HTTPie
|
||||
|
||||
大部分 Linux 发行版都提供了系统包管理器,可以用它来安装。
|
||||
|
||||
Fedora 系统,使用 [DNF 命令][6] 来安装 httpie:
|
||||
|
||||
```
|
||||
$ sudo dnf install httpie
|
||||
```
|
||||
|
||||
Debian/Ubuntu 系统,使用 [APT-GET 命令][7] 或 [APT 命令][8] 来安装 HTTPie。
|
||||
|
||||
```
|
||||
$ sudo apt install httpie
|
||||
```
|
||||
|
||||
基于 Arch Linux 的系统,使用 [Pacman 命令][9] 来安装 HTTPie。
|
||||
|
||||
```
|
||||
$ sudo pacman -S httpie
|
||||
```
|
||||
|
||||
RHEL/CentOS 的系统,使用 [YUM 命令][10] 来安装 HTTPie。
|
||||
|
||||
```
|
||||
$ sudo yum install httpie
|
||||
```
|
||||
|
||||
openSUSE Leap 系统,使用 [Zypper 命令][11] 来安装 HTTPie。
|
||||
|
||||
```
|
||||
$ sudo zypper install httpie
|
||||
```
|
||||
|
||||
### 用法
|
||||
|
||||
#### 如何使用 HTTPie 请求 URL?
|
||||
|
||||
HTTPie 的基本用法是将网站的 URL 作为参数。
|
||||
|
||||
```
|
||||
# http 2daygeek.com
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
CF-RAY: 4c4a618d0c02ce6d-LHR
|
||||
Cache-Control: max-age=3600
|
||||
Connection: keep-alive
|
||||
Date: Tue, 09 Apr 2019 06:21:28 GMT
|
||||
Expires: Tue, 09 Apr 2019 07:21:28 GMT
|
||||
Location: https://2daygeek.com/
|
||||
Server: cloudflare
|
||||
Transfer-Encoding: chunked
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
#### 如何使用 HTTPie 下载文件
|
||||
|
||||
你可以使用带 `--download` 参数的 HTTPie 命令下载文件。类似于 `wget` 命令。
|
||||
|
||||
```
|
||||
# http --download https://www.2daygeek.com/wp-content/uploads/2019/04/Anbox-Easy-Way-To-Run-Android-Apps-On-Linux.png
|
||||
HTTP/1.1 200 OK
|
||||
Accept-Ranges: bytes
|
||||
CF-Cache-Status: HIT
|
||||
CF-RAY: 4c4a65d5ca360a66-LHR
|
||||
Cache-Control: public, max-age=7200
|
||||
Connection: keep-alive
|
||||
Content-Length: 32066
|
||||
Content-Type: image/png
|
||||
Date: Tue, 09 Apr 2019 06:24:23 GMT
|
||||
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
||||
Expires: Tue, 09 Apr 2019 08:24:23 GMT
|
||||
Last-Modified: Mon, 08 Apr 2019 04:54:25 GMT
|
||||
Server: cloudflare
|
||||
Set-Cookie: __cfduid=dd2034b2f95ae42047e082f59f2b964f71554791063; expires=Wed, 08-Apr-20 06:24:23 GMT; path=/; domain=.2daygeek.com; HttpOnly; Secure
|
||||
Vary: Accept-Encoding
|
||||
|
||||
Downloading 31.31 kB to "Anbox-Easy-Way-To-Run-Android-Apps-On-Linux.png"
|
||||
Done. 31.31 kB in 0.01187s (2.58 MB/s)
|
||||
```
|
||||
|
||||
你还可以使用 `-o` 参数用不同的名称保存输出文件。
|
||||
|
||||
```
|
||||
# http --download https://www.2daygeek.com/wp-content/uploads/2019/04/Anbox-Easy-Way-To-Run-Android-Apps-On-Linux.png -o Anbox-1.png
|
||||
HTTP/1.1 200 OK
|
||||
Accept-Ranges: bytes
|
||||
CF-Cache-Status: HIT
|
||||
CF-RAY: 4c4a68194daa0a66-LHR
|
||||
Cache-Control: public, max-age=7200
|
||||
Connection: keep-alive
|
||||
Content-Length: 32066
|
||||
Content-Type: image/png
|
||||
Date: Tue, 09 Apr 2019 06:25:56 GMT
|
||||
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
||||
Expires: Tue, 09 Apr 2019 08:25:56 GMT
|
||||
Last-Modified: Mon, 08 Apr 2019 04:54:25 GMT
|
||||
Server: cloudflare
|
||||
Set-Cookie: __cfduid=d3eea753081690f9a2d36495a74407dd71554791156; expires=Wed, 08-Apr-20 06:25:56 GMT; path=/; domain=.2daygeek.com; HttpOnly; Secure
|
||||
Vary: Accept-Encoding
|
||||
|
||||
Downloading 31.31 kB to "Anbox-1.png"
|
||||
Done. 31.31 kB in 0.01551s (1.97 MB/s)
|
||||
```
|
||||
|
||||
#### 如何使用 HTTPie 恢复部分下载?
|
||||
|
||||
你可以使用带 `-c` 参数的 HTTPie 继续下载。
|
||||
|
||||
```
|
||||
# http --download --continue https://speed.hetzner.de/100MB.bin -o 100MB.bin
|
||||
HTTP/1.1 206 Partial Content
|
||||
Connection: keep-alive
|
||||
Content-Length: 100442112
|
||||
Content-Range: bytes 4415488-104857599/104857600
|
||||
Content-Type: application/octet-stream
|
||||
Date: Tue, 09 Apr 2019 06:32:52 GMT
|
||||
ETag: "5253f0fd-6400000"
|
||||
Last-Modified: Tue, 08 Oct 2013 11:48:13 GMT
|
||||
Server: nginx
|
||||
Strict-Transport-Security: max-age=15768000; includeSubDomains
|
||||
|
||||
Downloading 100.00 MB to "100MB.bin"
|
||||
| 24.14 % 24.14 MB 1.12 MB/s 0:01:07 ETA^C
|
||||
```
|
||||
|
||||
你根据下面的输出验证是否同一个文件:
|
||||
|
||||
```
|
||||
[email protected]:/var/log# ls -lhtr 100MB.bin
|
||||
-rw-r--r-- 1 root root 25M Apr 9 01:33 100MB.bin
|
||||
```
|
||||
|
||||
#### 如何使用 HTTPie 上传文件?
|
||||
|
||||
你可以通过使用带有小于号 `<` 的 HTTPie 命令上传文件
|
||||
|
||||
```
|
||||
$ http https://transfer.sh < Anbox-1.png
|
||||
```
|
||||
|
||||
#### 如何使用带有重定向符号 > 下载文件?
|
||||
|
||||
你可以使用带有重定向 `>` 符号的 HTTPie 命令下载文件。
|
||||
|
||||
```
|
||||
# http https://www.2daygeek.com/wp-content/uploads/2019/03/How-To-Install-And-Enable-Flatpak-Support-On-Linux-1.png > Flatpak.png
|
||||
|
||||
# ls -ltrh Flatpak.png
|
||||
-rw-r--r-- 1 root root 47K Apr 9 01:44 Flatpak.png
|
||||
```
|
||||
|
||||
#### 发送一个 HTTP GET 请求?
|
||||
|
||||
您可以在请求中发送 HTTP GET 方法。GET 方法会使用给定的 URI,从给定服务器检索信息。
|
||||
|
||||
|
||||
```
|
||||
# http GET httpie.org
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
CF-RAY: 4c4a83a3f90dcbe6-SIN
|
||||
Cache-Control: max-age=3600
|
||||
Connection: keep-alive
|
||||
Date: Tue, 09 Apr 2019 06:44:44 GMT
|
||||
Expires: Tue, 09 Apr 2019 07:44:44 GMT
|
||||
Location: https://httpie.org/
|
||||
Server: cloudflare
|
||||
Transfer-Encoding: chunked
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
#### 提交表单?
|
||||
|
||||
使用以下格式提交表单。POST 请求用于向服务器发送数据,例如客户信息、文件上传等。要使用 HTML 表单。
|
||||
|
||||
```
|
||||
# http -f POST Ubuntu18.2daygeek.com hello='World'
|
||||
HTTP/1.1 200 OK
|
||||
Accept-Ranges: bytes
|
||||
Connection: Keep-Alive
|
||||
Content-Encoding: gzip
|
||||
Content-Length: 3138
|
||||
Content-Type: text/html
|
||||
Date: Tue, 09 Apr 2019 06:48:12 GMT
|
||||
ETag: "2aa6-5844bf1b047fc-gzip"
|
||||
Keep-Alive: timeout=5, max=100
|
||||
Last-Modified: Sun, 17 Mar 2019 15:29:55 GMT
|
||||
Server: Apache/2.4.29 (Ubuntu)
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
运行下面的指令以查看正在发送的请求。
|
||||
|
||||
```
|
||||
# http -v Ubuntu18.2daygeek.com
|
||||
GET / HTTP/1.1
|
||||
Accept: */*
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Host: ubuntu18.2daygeek.com
|
||||
User-Agent: HTTPie/0.9.8
|
||||
|
||||
hello=World
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Accept-Ranges: bytes
|
||||
Connection: Keep-Alive
|
||||
Content-Encoding: gzip
|
||||
Content-Length: 3138
|
||||
Content-Type: text/html
|
||||
Date: Tue, 09 Apr 2019 06:48:30 GMT
|
||||
ETag: "2aa6-5844bf1b047fc-gzip"
|
||||
Keep-Alive: timeout=5, max=100
|
||||
Last-Modified: Sun, 17 Mar 2019 15:29:55 GMT
|
||||
Server: Apache/2.4.29 (Ubuntu)
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
#### HTTP 认证?
|
||||
|
||||
当前支持的身份验证认证方案是基本认证(Basic)和摘要验证(Digest)。
|
||||
|
||||
基本认证:
|
||||
|
||||
```
|
||||
$ http -a username:password example.org
|
||||
```
|
||||
|
||||
摘要验证:
|
||||
|
||||
```
|
||||
$ http -A digest -a username:password example.org
|
||||
```
|
||||
|
||||
提示输入密码:
|
||||
|
||||
```
|
||||
$ http -a username example.org
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/httpie-curl-wget-alternative-http-client-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zgj1024](https://github.com/zgj1024)
|
||||
校对:[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/best-4-command-line-download-managers-accelerators-for-linux/
|
||||
[2]: https://www.2daygeek.com/aria2-linux-command-line-download-utility-tool/
|
||||
[3]: https://www.2daygeek.com/axel-linux-command-line-download-accelerator/
|
||||
[4]: https://www.2daygeek.com/wget-linux-command-line-download-utility-tool/
|
||||
[5]: https://www.2daygeek.com/curl-linux-command-line-download-manager/
|
||||
[6]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[7]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[8]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[9]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[10]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[11]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
97
published/201904/20190417 Managing RAID arrays with mdadm.md
Normal file
97
published/201904/20190417 Managing RAID arrays with mdadm.md
Normal file
@ -0,0 +1,97 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10785-1.html)
|
||||
[#]: subject: (Managing RAID arrays with mdadm)
|
||||
[#]: via: (https://fedoramagazine.org/managing-raid-arrays-with-mdadm/)
|
||||
[#]: author: (Gregory Bartholomew https://fedoramagazine.org/author/glb/)
|
||||
|
||||
使用 mdadm 管理 RAID 阵列
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
mdadm 是<ruby>多磁盘和设备管理<rt>Multiple Disk and Device Administration</rt></ruby> 的缩写。它是一个命令行工具,可用于管理 Linux 上的软件 [RAID][2] 阵列。本文概述了使用它的基础知识。
|
||||
|
||||
以下 5 个命令是你使用 mdadm 的基础功能:
|
||||
|
||||
1. **创建 RAID 阵列**:`mdadm --create /dev/md/test --homehost=any --metadata=1.0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1`
|
||||
2. **组合(并启动)RAID 阵列**:`mdadm --assemble /dev/md/test /dev/sda1 /dev/sdb1`
|
||||
3. **停止 RAID 阵列**:`mdadm --stop /dev/md/test`
|
||||
4. **删除 RAID 阵列**:`mdadm --zero-superblock /dev/sda1 /dev/sdb1`
|
||||
5. **检查所有已组合的 RAID 阵列的状态**:`cat /proc/mdstat`
|
||||
|
||||
### 功能说明
|
||||
|
||||
#### mdadm --create
|
||||
|
||||
上面的创建命令除了 `-create` 参数自身和设备名之外,还包括了四个参数:
|
||||
|
||||
1、`–homehost`:
|
||||
|
||||
默认情况下,`mdadm` 将你的计算机名保存为 RAID 阵列的属性。如果你的计算机名与存储的名称不匹配,则阵列将不会自动组合。此功能在共享硬盘的服务器群集中很有用,因为如果多个服务器同时尝试访问同一驱动器,通常会发生文件系统损坏。名称 `any` 是保留字段,并禁用 `-homehost` 限制。
|
||||
|
||||
2、 `–metadata`:
|
||||
|
||||
`-mdadm` 保留每个 RAID 设备的一小部分空间,以存储有关 RAID 阵列本身的信息。 `-metadata` 参数指定信息的格式和位置。`1.0` 表示使用版本 1 格式,并将元数据存储在设备的末尾。
|
||||
|
||||
3、`–level`:
|
||||
|
||||
`-level` 参数指定数据应如何在底层设备之间分布。级别 `1` 表示每个设备应包含所有数据的完整副本。此级别也称为[磁盘镜像] [3]。
|
||||
|
||||
4、`–raid-devices`:
|
||||
|
||||
`-raid-devices` 参数指定将用于创建 RAID 阵列的设备数。
|
||||
|
||||
通过将 `-level=1`(镜像)与 `-metadata=1.0` (将元数据存储在设备末尾)结合使用,可以创建一个 RAID1 阵列,如果不通过 mdadm 驱动访问,那么它的底层设备会正常显示。这在灾难恢复的情况下很有用,因为即使新系统不支持 mdadm 阵列,你也可以访问该设备。如果程序需要在 mdadm 可用之前以*只读*访问底层设备时也很有用。例如,计算机中的 [UEFI][4] 固件可能需要在启动 mdadm 之前从 [ESP][5] 读取引导加载程序。
|
||||
|
||||
#### mdadm --assemble
|
||||
|
||||
如果成员设备丢失或损坏,上面的组合命令将会失败。要强制 RAID 阵列在其中一个成员丢失时进行组合并启动,请使用以下命令:
|
||||
|
||||
```
|
||||
# mdadm --assemble --run /dev/md/test /dev/sda1
|
||||
```
|
||||
|
||||
### 其他重要说明
|
||||
|
||||
避免直接写入底层是 RAID1 的设备。这导致设备不同步,并且 mdadm 不会知道它们不同步。如果你访问了在其他地方被修改了设备的某个 RAID1 阵列,则可能导致文件系统损坏。如果你在其他地方修改 RAID1 设备并需要强制阵列重新同步,请从要覆盖的设备中删除 mdadm 元数据,然后将其重新添加到阵列,如下所示:
|
||||
|
||||
```
|
||||
# mdadm --zero-superblock /dev/sdb1
|
||||
# mdadm --assemble --run /dev/md/test /dev/sda1
|
||||
# mdadm /dev/md/test --add /dev/sdb1
|
||||
```
|
||||
|
||||
以上用 sda1 的内容完全覆盖 sdb1 的内容。
|
||||
|
||||
要指定在计算机启动时自动激活的 RAID 阵列,请创建 `/etc/mdadm.conf` 配置。
|
||||
|
||||
有关最新和详细信息,请查看手册页:
|
||||
|
||||
```
|
||||
$ man mdadm
|
||||
$ man mdadm.conf
|
||||
```
|
||||
|
||||
本系列的下一篇文章将展示如何将现有的单磁盘 Linux 系统变为镜像磁盘安装,这意味着即使其中一个硬盘突然停止工作,系统仍将继续运行!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/managing-raid-arrays-with-mdadm/
|
||||
|
||||
作者:[Gregory Bartholomew][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/glb/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/mdadm-816x345.jpg
|
||||
[2]: https://en.wikipedia.org/wiki/RAID
|
||||
[3]: https://en.wikipedia.org/wiki/Disk_mirroring
|
||||
[4]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface
|
||||
[5]: https://en.wikipedia.org/wiki/EFI_system_partition
|
@ -0,0 +1,69 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (arrowfeng)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10797-1.html)
|
||||
[#]: subject: (Most data center workers happy with their jobs -- despite the heavy demands)
|
||||
[#]: via: (https://www.networkworld.com/article/3389359/most-data-center-workers-happy-with-their-jobs-despite-the-heavy-demands.html#tk.rss_all)
|
||||
[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/)
|
||||
|
||||
许多数据中心的工作者很满意他们的工作,将鼓励他们的孩子继续从事这份工作
|
||||
======
|
||||
|
||||
> 一份 Informa Engage 和 Data Center Knowledge 的报告调查发现,在数据中心工作的人很满意他们的工作,因此他们将会鼓励他们的孩子从事这份工作。
|
||||
|
||||
![Thinkstock][1]
|
||||
|
||||
一份由 [Informa Engage 和 Data Center Knowledge][2] 主导的调查报告显示,数据中心的工作者总体上对他们的工作很满意。尽管对时间和大脑的要求很高,但是他们还是鼓励自己的孩子能从事这项工作。
|
||||
|
||||
总体满意度非常好,72% 的受访者普遍同意“我喜欢我目前的工作”这一说法,三分之一的受访者则表示非常同意。75% 的人同意声明,“如果我的孩子、侄女或侄子问,我将建议他们进入 IT 行业。”
|
||||
|
||||
在数据中心工作的员工之中,有一种很重要的感觉,88% 的人觉得他们自己对于雇主的成功非常重要。
|
||||
|
||||
尽管存在一些挑战,其中最主要的是技能和认证的缺乏。调查的受访者认为缺乏技能是最受关注的领域。只有 56% 的人认为他们需要完成工作所需的培训,74% 的人表示他们已经在 IT 行业工作了十多年。
|
||||
|
||||
这个行业提供认证计划,每个主要的 IT 硬件供应商都有,但是 61% 的人表示在过去的 12 个月里他们并没有完成或者重新续订证书。有几个原因:
|
||||
|
||||
三分之一(34%)说是由于他们工作的组织缺乏培训预算,而 24% 的人认为是缺乏时间,16% 的人表示管理者认为不需要培训,以及另外 16% 的人表示在他们的工作地点没有培训计划。
|
||||
|
||||
这并不让我感到惊讶,因为科技是世界上最开放的行业之一,在那里你可以找到培训和教育材料并自学。已经证实了[许多程序员是自学成才][4],包括行业巨头比尔·盖茨、史蒂夫·沃兹尼亚克、约翰·卡马克和杰克·多尔西。
|
||||
|
||||
### 数据中心工作者们的薪水
|
||||
|
||||
数据中心工作者不会抱怨酬劳。当然,大部分不会。50% 的人每年可以赚到 $100,000 甚至更多,然而 11% 的人赚的少于 $40,000。三分之二的受访者来自于美国,因此那些低端收入人士可能在国外。
|
||||
|
||||
有一个值得注意的差异。史蒂夫·布朗是伦敦数据中心人力资源的总经理,他说软件工程师获得的薪水比硬件工程师多。
|
||||
|
||||
布朗在这篇报道中说,“数据中心软件工程方面的工作可以与高收入的职业媲美,而在物理基础设施——机械/电气方面的工作——情况并非如此。它更像是中层管理。”
|
||||
|
||||
### 数据中心的专业人士仍然主要是男性
|
||||
|
||||
最不令人惊讶的发现?10 个受访者中有 9 个是男性。该行业正在调整解决性别歧视问题,但是现在没什么改变。
|
||||
|
||||
这篇报告的结论有一点不太好,但是我认为是错的:
|
||||
|
||||
> “随着数据中心基础设施完成云计算模式的过渡,软件进入到容器和微服务时代,数据中心剩下来的珍贵领导者——在 20 世纪获得技能的人——可能会发现没有任何他们了解的东西需要管理,也没有人需要他们领导。当危机最终来临时,我们可能会感到震惊,但是我们不能说我们没有受到警告。"
|
||||
|
||||
我说过了很多次,[数据中心不会消失][6]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3389359/most-data-center-workers-happy-with-their-jobs-despite-the-heavy-demands.html
|
||||
|
||||
作者:[Andy Patrizio][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[arrowfeng](https://github.com/arrowfeng)
|
||||
校对:[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/02/data_center_thinkstock_879720438-100749725-large.jpg
|
||||
[2]: https://informa.tradepub.com/c/pubRD.mpl?sr=oc&_t=oc:&qf=w_dats04&ch=datacenterkids
|
||||
[3]: https://www.networkworld.com/article/3276025/20-hot-jobs-ambitious-it-pros-should-shoot-for.html
|
||||
[4]: https://www.networkworld.com/article/3046178/survey-finds-most-coders-are-self-taught.html
|
||||
[5]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fpaths%2Fupgrading-your-technology-career
|
||||
[6]: https://www.networkworld.com/article/3289509/two-studies-show-the-data-center-is-thriving-instead-of-dying.html
|
||||
[7]: https://www.facebook.com/NetworkWorld/
|
||||
[8]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,105 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10795-1.html)
|
||||
[#]: subject: (Ubuntu 19.04 ‘Disco Dingo’ Has Arrived: Downloads Available Now!)
|
||||
[#]: via: (https://itsfoss.com/ubuntu-19-04-release/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
下载安装 Ubuntu 19.04 “Disco Dingo”
|
||||
======
|
||||
|
||||
Ubuntu 19.04 “Disco Dingo” 已经发布,可以下载了。虽然我们已经知道 [Ubuntu 19.04 中的新功能][1] —— 我将在下面提到一些重要的地方,还会给出官方的下载链接。
|
||||
|
||||
### Ubuntu 19.04:你需要知道什么
|
||||
|
||||
以下是你应该了解的有关 Ubuntu 19.04 Disco Dingo 发布的一些内容。
|
||||
|
||||
#### Ubuntu 19.04 不是 LTS 版本
|
||||
|
||||
与 Ubuntu 18.04 LTS 不同,它不会[支持 10 年][2]。相反,非 LTS 的 19.04 将支持 **9 个月,直到 2020 年 1 月。**
|
||||
|
||||
因此,如果你有生产环境,我们可能不会立即建议你进行升级。例如,如果你有一台运行在 Ubuntu 18.04 LTS 上的服务器 —— 只是因为它是一个新的版本就将它升级到 19.04 可能不是一个好主意。
|
||||
|
||||
但是,对于希望在计算机上安装最新版本的用户,可以尝试一下。
|
||||
|
||||
![][3]
|
||||
|
||||
#### Ubuntu 19.04 对 NVIDIA GPU 用户是个不错的更新
|
||||
|
||||
Martin Wimpress(来自 Canonical)在 Ubuntu MATE 19.04(Ubuntu 版本之一)的 [GitHub][4] 的最终发布说明中提到 Ubuntu 19.04 对 NVIDIA GPU 用户来说特别重要。
|
||||
|
||||
换句话说,在安装专有图形驱动时 —— 它现在会选择与你特定 GPU 型号兼容最佳的驱动程序。
|
||||
|
||||
#### Ubuntu 19.04 功能
|
||||
|
||||
- https://youtu.be/sbbPYdpdMb8
|
||||
|
||||
尽管我们已经讨论过 [Ubuntu 19.04][1] Disco Dingo 的[最佳功能][1],但值得一提的是,我对本次发布的主要变化:桌面更新 (GNOME 3.32) 和 Linux 内核 (5.0)感到兴奋。
|
||||
|
||||
#### 从 Ubuntu 18.10 升级到 19.04
|
||||
|
||||
显而易见,如果你安装了 Ubuntu 18.10,你应该升级它。18.10 将于 2019 年 7 月停止支持 —— 所以我们建议你将其升级到 19.04。
|
||||
|
||||
要做到这一点,你可以直接进入“软件和更新”设置,然后选择“更新”选项卡。
|
||||
|
||||
现在将选项从“通知我新的 Ubuntu 版本” 变成 “任何新版本都通知我”。
|
||||
|
||||
现在再次运行更新管理器时,你应该会看到 Ubuntu 19.04。
|
||||
|
||||
![][5]
|
||||
|
||||
#### 从 Ubuntu 18.04 升级到 19.04
|
||||
|
||||
建议不要直接从 18.04 升级到 19.04,因为你需要先将操作系统更新到 18.10,然后再继续升级到 19.04。
|
||||
|
||||
相反,你只需下载 Ubuntu 19.04 的官方 ISO 映像,然后在你的系统上重新安装 Ubuntu。
|
||||
|
||||
### Ubuntu 19.04:所有版本都可下载
|
||||
|
||||
根据[发行说明][6],现在可以下载 Ubuntu 19.04。你可以在其官方发布下载页面上获取种子或 ISO 文件。
|
||||
|
||||
- [下载 Ubuntu 19.04][7]
|
||||
|
||||
如果你需要不同的桌面环境或需要特定的东西,你应该查看 Ubuntu 的官方版本:
|
||||
|
||||
* [Ubuntu MATE][8]
|
||||
* [Kubuntu][9]
|
||||
* [Lubuntu][10]
|
||||
* [Ubuntu Budgie][11]
|
||||
* [Ubuntu Studio][12]
|
||||
* [Xubuntu][13]
|
||||
|
||||
上面提到的一些 Ubuntu 版本还没有在页面提供 19.04。但你可以[仍然在 Ubuntu 的发行说明网页上找到 ISO][6]。就个人而言,我使用带 GNOME 桌面的 Ubuntu。你可以选择你喜欢的。
|
||||
|
||||
### 总结
|
||||
|
||||
你如何看待 Ubuntu 19.04 Disco Dingo?这些新功能是否足够令人兴奋?你试过了吗?请在下面的评论中告诉我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/ubuntu-19-04-release/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/ubuntu-19-04-release-features/
|
||||
[2]: https://itsfoss.com/ubuntu-18-04-ten-year-support/
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2018/11/ubuntu-19-04-Disco-Dingo-default-wallpaper.jpg?resize=800%2C450&ssl=1
|
||||
[4]: https://github.com/ubuntu-mate/ubuntu-mate.org/blob/master/blog/20190418-ubuntu-mate-disco-final-release.md
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/ubuntu-19-04-upgrade-available.jpg?ssl=1
|
||||
[6]: https://wiki.ubuntu.com/DiscoDingo/ReleaseNotes
|
||||
[7]: https://www.ubuntu.com/download/desktop
|
||||
[8]: https://ubuntu-mate.org/download/
|
||||
[9]: https://kubuntu.org/getkubuntu/
|
||||
[10]: https://lubuntu.me/cosmic-released/
|
||||
[11]: https://ubuntubudgie.org/downloads
|
||||
[12]: https://ubuntustudio.org/2019/04/ubuntu-studio-19-04-released/
|
||||
[13]: https://xubuntu.org/download/
|
@ -0,0 +1,105 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10787-1.html)
|
||||
[#]: subject: (4 cool new projects to try in COPR for April 2019)
|
||||
[#]: via: (https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-april-2019/)
|
||||
[#]: author: (Dominik Turecek https://fedoramagazine.org/author/dturecek/)
|
||||
|
||||
COPR 仓库中 4 个很酷的新软件(2019.4)
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
COPR 是个人软件仓库[集合][1],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准。或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。
|
||||
|
||||
这是 COPR 中一组新的有趣项目。
|
||||
|
||||
### Joplin
|
||||
|
||||
[Joplin][3] 是一个笔记和待办事项应用。笔记以 Markdown 格式编写,并通过使用标签和将它们分类到各种笔记本中进行组织。Joplin 可以从任何 Markdown 源导入笔记或从 Evernote 导出笔记。除了桌面应用之外,还有一个 Android 版本,通过使用 Nextcloud、Dropbox 或其他云服务同步笔记。最后,它还有 Chrome 和 Firefox 的浏览器扩展程序,用于保存网页和屏幕截图。
|
||||
|
||||
![][4]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[COPR 仓库][5]目前为 Fedora 29 和 30 以及 EPEL 7 提供 Joplin。要安装 Joplin,请[带上 sudo][6] 使用这些命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable taw/joplin
|
||||
sudo dnf install joplin
|
||||
```
|
||||
|
||||
### Fzy
|
||||
|
||||
[Fzy][7] 是用于模糊字符串搜索的命令行程序。它从标准输入读取并根据最有可能的搜索结果进行排序,然后打印所选行。除了命令行,`fzy` 也可以在 vim 中使用。你可以在这个在线 [demo][8] 中尝试 `fzy`。
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[COPR 仓库][9]目前为 Fedora 29、30 和 Rawhide 以及其他发行版提供了 `fzy`。要安装 `fzy`,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable lehrenfried/fzy
|
||||
sudo dnf install fzy
|
||||
```
|
||||
|
||||
### Fondo
|
||||
|
||||
Fondo 是一个浏览 [unsplash.com][10] 网站照片的程序。它有一个简单的界面,允许你一次查找某个主题或所有主题的图片。然后,你可以通过单击将找到的图片设置为壁纸,或者共享它。
|
||||
|
||||
![][11]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[COPR 仓库][12]目前为 Fedora 29、30 和 Rawhide 提供 Fondo。要安装 Fondo,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable atim/fondo
|
||||
sudo dnf install fondo
|
||||
```
|
||||
|
||||
### YACReader
|
||||
|
||||
[YACReader][13] 是一款数字漫画阅读器,它支持许多漫画和图像格式,例如 cbz、cbr、pdf 等。YACReader 会跟踪阅读进度,并可以从 [Comic Vine][14] 下载漫画信息。它还有一个 YACReader 库,用于组织和浏览你的漫画集。
|
||||
|
||||
![][15]
|
||||
|
||||
#### 安装说明
|
||||
|
||||
[COPR 仓库][16]目前为 Fedora 29、30 和 Rawhide 提供 YACReader。要安装 YACReader,请使用以下命令:
|
||||
|
||||
```
|
||||
sudo dnf copr enable atim/yacreader
|
||||
sudo dnf install yacreader
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-april-2019/
|
||||
|
||||
作者:[Dominik Turecek][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/dturecek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg
|
||||
[2]: https://copr.fedorainfracloud.org/
|
||||
[3]: https://joplin.cozic.net/
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2019/04/joplin.png
|
||||
[5]: https://copr.fedorainfracloud.org/coprs/taw/joplin/
|
||||
[6]: https://fedoramagazine.org/howto-use-sudo/
|
||||
[7]: https://github.com/jhawthorn/fzy
|
||||
[8]: https://jhawthorn.github.io/fzy-demo/
|
||||
[9]: https://copr.fedorainfracloud.org/coprs/lehrenfried/fzy/
|
||||
[10]: https://unsplash.com/
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2019/04/fondo.png
|
||||
[12]: https://copr.fedorainfracloud.org/coprs/atim/fondo/
|
||||
[13]: https://www.yacreader.com/
|
||||
[14]: https://comicvine.gamespot.com/
|
||||
[15]: https://fedoramagazine.org/wp-content/uploads/2019/04/yacreader.png
|
||||
[16]: https://copr.fedorainfracloud.org/coprs/atim/yacreader/
|
@ -0,0 +1,147 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10790-1.html)
|
||||
[#]: subject: (New Features Coming to Debian 10 Buster Release)
|
||||
[#]: via: (https://itsfoss.com/new-features-coming-to-debian-10-buster-release/)
|
||||
[#]: author: (Shirish https://itsfoss.com/author/shirish/)
|
||||
|
||||
即将到来的 Debian 10 Buster 发布版的新特点
|
||||
=======================================
|
||||
|
||||
Debian 10 Buster 即将发布。第一个发布候选版已经发布,我们预期可以在几周内见到待最终版。
|
||||
|
||||
如果你期待对这个新的主要发布版本,让我告诉你里面有什么。
|
||||
|
||||
### Debian 10 Buster 发布计划
|
||||
|
||||
[Debian 10 Buster][1] 的发布日期并没有确定。为什么这样呢?不像其他分发版,[Debian][2] 并不基于时间发布。相反地它主要关注于修复<ruby>发布版重要 Bug<rt>release-critical bug</rt></ruby>。发布版重要 Bug 要么是严重的安全问题([CVE][3]),要么是一些其他阻止 Debian 发布的严重问题。
|
||||
|
||||
Debian 在它的软件归档中分为三个部分,叫做 Main、contrib 和 non-free。在这三者之中,Debian 开发者和发布管理者最关心的包组成了该分发版的基石。Main 是像石头一样稳定的。因此他们要确保那里没有主要的功能或者安全问题。他们同样给予了不同的优先级,例如 Essential、Required、Important、Standard、Optional 和 Extra。更多关于此方面的知识参考后续的 Debian 文章。
|
||||
|
||||
这是必要的,因为 Debian 在很多环境中被用作服务器,人们已经变得依赖 Debian。他们同样看重升级周期是否有破环,因此他们寻找人们来测试,来查看当升级的时候是否有破坏并通知 Debian 有这样的问题。
|
||||
|
||||
这种提交方式带来的稳定性[是我喜欢 Debian 的众多原因之一][4]。
|
||||
|
||||
### Debian 10 Buster 版本的新内容
|
||||
|
||||
这里是即将到来的 Debian 主要发布版的一些视觉上和内部的改变。
|
||||
|
||||
#### 新的主题和壁纸
|
||||
|
||||
Buster 的 Debian 主题被称为 [FuturePrototype][5] 并且看起来如下图:
|
||||
|
||||
![Debian Buster FuturePrototype Theme][6]
|
||||
|
||||
#### 1、GNOME 桌面 3.30
|
||||
|
||||
Debian Stretch 版中的 GNOME 桌面在 Buster 中从 1.3.22 升级到了 1.3.30。在 GNOME 桌面发布版中新包含的一些包是 gnome-todo、tracker 替代了 tracker-gui、gstreamer1.0-packagekit 的依赖,因此可以通过自动地安装编码解码器来做播放电影之类的事。对于所有包来说一个大的改变是从 libgtk2+ 到 libgtk3+。
|
||||
|
||||
#### 2、Linux 内核 4.19.0-4
|
||||
|
||||
Debian 使用 LTS 内核版本,因此你可以期待更好的硬件支持和长达 5 年的维护和支持周期。我们已经从内核 4.9.0.3 到 4.19.0-4。
|
||||
|
||||
```
|
||||
$ uname -r
|
||||
4.19.0-4-amd64
|
||||
```
|
||||
|
||||
#### 3、OpenJDK 11.0
|
||||
|
||||
Debian 在很长时间里都是 OpenJDK 8.0。现在在 Debian Buster 里我们已经升级为 OpenJDK 11.0,并且会有一个团队维护新的版本。
|
||||
|
||||
#### 4、默认启用 AppArmor
|
||||
|
||||
在 Debian Buster 中是默认启用 [AppArmor][7] 的。这是一个好事,谨慎是系统管理员必须采取的正确策略。这仅仅是第一步,并且可能需要修复很多对用户觉得有用的脚本。
|
||||
|
||||
#### 5、Nodejs 10.15.2
|
||||
|
||||
在很长一段时间里 Debian 在仓库中都只有 Nodejs 4.8。在这个周期里 Debian 已经移到 Nodejs 10.15.2。事实上,Debian Buster 有很多 javascript 库例如 yarnpkg (一个 nmp 的替代品)等等。
|
||||
|
||||
当然,你可以从该项目仓库[在 Debian 中安装最新的 Nodejs][8],但是从 Debian 仓库中看到更新的版本是很棒的。
|
||||
|
||||
#### 6、NFtables 替代了 iptables
|
||||
|
||||
Debian Buster 提供了 nftables 来完整地替代了 iptables,因为它有更好、更简单的语法,更好的支持双栈 ipv4/v6 防火墙等等。
|
||||
|
||||
#### 7、支持更多的 ARM 64 和 ARMHF 的单板机。
|
||||
|
||||
Debian 已经支持一些常见的新的单板机,其中最新的包括 pine64_plus、ARM64 的 pinebook、Firefly-RK3288、ARMHF 64 的 u-boot-rockchip 以及 Odroid HC1/HC2 板、SolidRun Cubox-i 双核/四核(1.5som)和 SolidRun Cubox-i 双核/四核(1.5som+emmc)板、Cubietruckplus 等。同样支持 Rock 64、Banana Pi M2 Berry、Pine A64 LTS Board、Olimex A64 Teres-1 与 Rapberry Pi 1、Zero 和 Pi 3。对于 RISC-V 系统同样支持开箱即用。
|
||||
|
||||
#### 8、Python 2 已死,Python 3 长存
|
||||
|
||||
在 2020 年 1 月 1 日,Python 2 将被 python.org 废弃。在 Debian 将所有的软件包从 Python 2.7 移到 Python 3 以后,Python 2.7 将从软件仓库中移除。这可能发生在 Buster 发布版或者将来的某个发布版,这是肯定要来临的。因此 Python 开发者被鼓励移植他们的代码库来兼容 Python 3。在写本文的时候,在 Debian Buster 中同时支持 python2 和 pythone3。
|
||||
|
||||
#### 9、Mailman 3
|
||||
|
||||
在 Debian 中终于可以使用 Mailman3 了。同时 [Mailman][10] 已经被细分成为组件。要安装整个软件栈,可以安装 mailman3-full 来获取所有组件。
|
||||
|
||||
#### 10、任意已有的 Postgresql 数据库将需要重新索引
|
||||
|
||||
由于 glibc 本地数据的更新,放入文本索引中的信息排序的方式将会改变,因为重新索引是有益的,这样在将来就不会有数据破坏发生。
|
||||
|
||||
#### 11、默认 Bash 5.0
|
||||
|
||||
你可能已经了解了 [Bash 5.0 的新特点][11],在 Debian 中已经是该版本了。
|
||||
|
||||
#### 12、Debian 实现 /usr/merge
|
||||
|
||||
我们已经分享过一个优秀的 freedesktop [读物][12],介绍了 `/usr/merge` 带来了什么。有一些事项需要注意。当 Debian 想要整个过渡时,可能由于未预见的情况,一些二进制文件可能并没有做这些改变。需要指出的一点是,`/var` 和 `/etc` 不会被触及,因此使用容器或者云技术的不需要考虑太多 :)。
|
||||
|
||||
#### 13、支持安全启动
|
||||
|
||||
在 Buster RC1 中,Debian 现在支持<ruby>安全启动<rt>secure-boot</rt></ruby>。这意味着打开了安全启动设置的机器应该能够轻松安装 Debian。不再需要禁止或者处理安全启动的事 :)
|
||||
|
||||
#### 14、Debian-Live 镜像的 Calameres Live-installer
|
||||
|
||||
对于 Debian Buster 的 Live 版,Debian 引入了 [Calameres 安装器][13]来替代老的 Debian-installer。Debian-installer 比 Calameres 功能更多,但对于初学者,Calameres 相对于 Debian-installer 提供了另外一种全新的安装方式。安装过程的截图:
|
||||
|
||||
![Calamares Partitioning Stage][14]
|
||||
|
||||
如图所见,在 Calamares 下安装 Debian 相当简单,只要经历 5 个步骤你就能在你的机器上安装 Debian。
|
||||
|
||||
### 下载 Debian 10 Live 镜像 (只用于测试)
|
||||
|
||||
现在还不要将它用于生产机器。可以在测试机上尝试或者一个虚拟机。
|
||||
|
||||
你可以从 Debian Live [目录][15]获取 Debian 64 位和 32 位的镜像。如果你想要 64 位的就进入 `64-bit` 目录,如果你想要 32 位的,就进入 `32-bit` 目录。
|
||||
|
||||
- [下载 Debian 10 Buster Live Images][15]
|
||||
|
||||
如果你从已存在的稳定版升级并且出现了一些问题,查看它是否在预安装的[升级报告][16]中提及了,使用 [reportbug][17] 报告你看到的问题。如果 bug 没有被报告,那么请尽可能地报告和分享更多地信息。
|
||||
|
||||
### 总结
|
||||
|
||||
当上千个包被升级时,看起来不可能一一列出。我已经列出了一些你在 Debian Buster 可以找到的一些主要的改变。你怎么看呢?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/new-features-coming-to-debian-10-buster-release/
|
||||
|
||||
作者:[Shirish][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/shirish/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://wiki.debian.org/DebianBuster
|
||||
[2]: https://www.debian.org/
|
||||
[3]: https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures
|
||||
[4]: https://itsfoss.com/reasons-why-i-love-debian/
|
||||
[5]: https://wiki.debian.org/DebianArt/Themes/futurePrototype
|
||||
[6]: https://itsfoss.com/wp-content/uploads/2019/04/debian-buster-theme-800x450.png
|
||||
[7]: https://wiki.debian.org/AppArmor
|
||||
[8]: https://itsfoss.com/install-nodejs-ubuntu/
|
||||
[9]: https://www.python.org/dev/peps/pep-0373/
|
||||
[10]: https://www.list.org/
|
||||
[11]: https://itsfoss.com/bash-5-release/
|
||||
[12]: https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/
|
||||
[13]: https://calamares.io/about/
|
||||
[14]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/calamares-partitioning-wizard.jpg?fit=800%2C538&ssl=1
|
||||
[15]: https://cdimage.debian.org/cdimage/weekly-live-builds/
|
||||
[16]: https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=upgrade-reports;dist=unstable
|
||||
[17]: https://itsfoss.com/bug-report-debian/
|
164
published/20190401 What is 5G- How is it better than 4G.md
Normal file
164
published/20190401 What is 5G- How is it better than 4G.md
Normal file
@ -0,0 +1,164 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10812-1.html)
|
||||
[#]: subject: (What is 5G? How is it better than 4G?)
|
||||
[#]: via: (https://www.networkworld.com/article/3203489/what-is-5g-how-is-it-better-than-4g.html#tk.rss_all)
|
||||
[#]: author: (Josh Fruhlinger https://www.networkworld.com/author/Josh-Fruhlinger/)
|
||||
|
||||
什么是 5G?它比 4G 好在哪里?
|
||||
==========================
|
||||
|
||||
> 5G 网络将使无线网络吞吐量提高 10 倍并且能够替代有线宽带。但是它们什么时候能够投入使用呢,为什么 5G 和物联网如此紧密地联系在一起呢?
|
||||
|
||||
![Thinkstock][1]
|
||||
|
||||
[5G 无线][2] 是一个概括的术语,用来描述一系列更快的无线互联网的标准和技术,理论上比 4G 快了 20 倍并且延迟降低了 120 倍,为物联网的发展和对新的高带宽应用的支持奠定了基础。
|
||||
|
||||
### 什么是 5G?科技还是流行词?
|
||||
|
||||
这个技术在世界范围内完全发挥它的潜能还需要数年时间,但同时当今一些 5G 网络服务已经投入使用。5G 不仅是一个技术术语,也是一个营销术语,并不是市场上的所有 5G 服务是标准的。
|
||||
|
||||
- [来自世界移动大会:[5G 时代即将来到][3]]
|
||||
|
||||
### 5G 与 4G 的速度对比
|
||||
|
||||
无线技术的每一代,最大的呼吁是增加速度。5G 网络潜在的峰值下载速度可以达到[20 Gbps,一般在 10 Gbps][4]。这不仅仅比当前 4G 网络更快,4G 目前峰值大约 1 Gbps,并且比更多家庭的有线网络连接更快。5G 提供的网络速度能够与光纤一较高下。
|
||||
|
||||
吞吐量不是 5G 仅有的速度提升;它还有的特点是极大降低了网络延迟。这是一个重要的区分:吞吐量用来测量花费多久来下载一个大文件,而延迟由网络瓶颈决定,延迟在往返的通讯中减慢了响应速度。
|
||||
|
||||
延迟很难量化,因为它因各种网络状态变化而变化,但是 5G 网络在理想情况下有能力使延迟率在 1 ms 内。总的来说,5G 延迟将比 4G 降低 60 到 120 倍。这会使很多应用变得可能,例如当前虚拟现实的延迟使它变得不实际。
|
||||
|
||||
### 5G 技术
|
||||
|
||||
5G 技术的基础有一系列标准定义,在过去的 10 年里一直在研究更好的部分。这些里面最重要的是 5G New Radio(5G NR),由 3GPP(一个为移动电话开发协议的标准化组织)组织标准化。5G NR 规定了很多 5G 设备操作的方式,[于 2018 年 7 月 完成终版][5]。
|
||||
|
||||
很多独特的技术同时出现来尽可能地提升 5G 的速度并降低延迟,下面是一些重要的。
|
||||
|
||||
### 毫米波
|
||||
|
||||
5G 网络大部分使用在 30 到 300 GHz 范围的频率。(正如名称一样,这些频率的波长在 1 到 10 毫米之间)这些高频范围能够[在每个时间单元比低频信号携带更多的信息][7],4G LTE 当前使用的就是通常频率在 1 GHz 以下的低频信号,或者 WiFi,最高 6 GHz。
|
||||
|
||||
毫米波技术传统上是昂贵并且难于部署的。科技进步已经克服了这些困难,这也是 5G 在如今成为了可能的原因。
|
||||
|
||||
### 小蜂窝
|
||||
|
||||
毫米波传输的一个缺点是当它们传输通过物理对象的时候比 4G 或 WiFi 信号更容易被干扰。
|
||||
|
||||
为了克服这些,5G 基础设施的模型将不同于 4G。替代了大的像景观一样移动天线桅杆,5G 网络将由[分布在城市中大概间距 250 米的更小的基站][8]提供支持,创建更小的服务区域。
|
||||
|
||||
这些 5G 基站的功率要求低于 4G,并且可以更容易地连接到建筑物和电线杆上。
|
||||
|
||||
### 大量的 MIMO
|
||||
|
||||
尽管 5G 基站比 4G 的对应部分小多了,但它们却带了更多的天线。这些天线是[多输入多输出的(MIMO)][9],意味着在相同的数据信道能够同时处理多个双向会话。5G 网络能够处理比 4G 网络超过 20 倍的会话。
|
||||
|
||||
大量的 MIMO 保证了[基站容量限制下的极大提升][10],允许单个基站承载更多的设备会话。这就是 5G 可能推动物联网更广泛应用的原因。理论上,更多的连接到互联网的无线设备能够部署在相同的空间而不会使网络被压垮。
|
||||
|
||||
### 波束成形
|
||||
|
||||
确保所有的会话来回地到达正确的地方是比较棘手的,尤其是前面提到的毫米波信号的干涉问题。为了克服这些问题,5G 基站部署了更高级的波束技术,使用建设性和破坏性的无线电干扰来使信号有向而不是广播。这在一个特定的方向上有效地加强了信号强度和范围。
|
||||
|
||||
### 5G 可获得性
|
||||
|
||||
第一个 5G 商用网络 [2018 年 5 月在卡塔尔推出][12]。自那以后,5G 网络已经扩展到全世界,从阿根廷到越南。[Lifewire 有一个不错的,经常更新的列表][13].
|
||||
|
||||
牢记一点的是,尽管这样,目前不是所有的 5G 网络都履行了所有的技术承诺。一些早期的 5G 产品依赖于现有的 4G 基础设施,减少了可以获得的潜在速度;其它服务为了市场目的而标榜 5G 但是并不符合标准。仔细观察美国无线运营商的产品都会发现一些陷阱。
|
||||
|
||||
### 无线运营商和 5G
|
||||
|
||||
技术上讲,5G 服务如今在美国已经可获得了。但声明中包含的注意事项因运营商而异,表明 5G 普及之前还有很长的路要走。
|
||||
|
||||
Verizon 可能是早期 5G 最大的推动者。它宣告到 2018 年 10 月 将有 4 个城市成为 [5G 家庭][14]的一部分,这是一项需要你的其他设备通过 WiFi 来连接特定的 5G 热点,由热点连接到网络的服务。
|
||||
|
||||
Verizon 计划四月在 [Minneapolis 和 Chicago 发布 5G 移动服务][15],该服务将在这一年内传播到其他城市。访问 5G 网络将需要消费者每月额外花费费用,加上购买能够实际访问 5G 的手机花费(稍后会详细介绍)。另外,Verizon 的部署被称作 [5G TF][16],实际上不符合 5G NR 的标准。
|
||||
|
||||
AT&T [声明在 2018 年 12 月将有美国的 12 个城市可以使用 5G][17],在 2019 年的末尾将增加 9 个城市,但最终在这些城市里,只有市中心商业区能够访问。为了访问 5G 网络,需要一个特定的 Netgear 热点来连接到 5G 服务,然后为手机和其他设备提供一个 Wi-Fi 信号。
|
||||
|
||||
与此同时,AT&T 也在推出 4G 网络的速度提升计划,被成为 5GE,即使这些提升和 5G 网络没有关系。([这会向后兼容][18])
|
||||
|
||||
Sprint 将在 2019 年 5 月之前在四个城市提供 5G 服务,在年末将有更多。但是 Sprint 的 5G 产品充分利用了 MIMO 单元,他们[没有使用毫米波信道][19],意味着 Sprint 的用户不会看到像其他运营商一样的速度提升。
|
||||
|
||||
T-Mobile 采用相似的模型,它[在 2019 年年底之前不会推出 5G 服务][20],因为他们没有手机能够连接到它。
|
||||
|
||||
一个可能阻止 5G 速度的迅速传播的障碍是需要铺开所有这些小蜂窝基站。它们小的尺寸和较低的功耗需求使它们技术上比 4G 技术更容易部署,但这不意味着它能够很简单的使政府和财产拥有者信服到处安装一堆基站。Verizon 实际上建立了[向本地民选官员请愿的网站][21]来加速 5G 基站的部署。
|
||||
|
||||
### 5G 手机:何时可获得?何时可以买?
|
||||
|
||||
第一部声称为 5G 手机的是 Samsung Galaxy S10 5G,将在 2019 年夏末首发。你也可以从 Verizon 订阅一个“[Moto Mod][22]”,用来[转换 Moto Z3 手机为 5G 兼容设备][23]。
|
||||
|
||||
但是除非你不能忍受作为一个早期使用者的诱惑,你会希望再等待一下;一些关于运营商的奇怪和突显的问题意味着可能你的手机[不兼容你的运营商的整个 5G 网络][24]。
|
||||
|
||||
一个可能令你吃惊的落后者是苹果:分析者确信最早直到 2020 年以前 iPhone 不会与 5G 兼容。但这符合该公司的特点;苹果在 2012 年末也落后于三星发布兼容 4G 的手机。
|
||||
|
||||
不可否认,5G 洪流已经到来。5G 兼容的设备[在 2019 年统治了巴塞罗那世界移动大会][3],因此期待视野里有更多的选择。
|
||||
|
||||
### 为什么人们已经在讨论 6G 了?
|
||||
|
||||
一些专家说缺点是[5G 不能够达到延迟和可靠性的目标][27]。这些完美主义者已经在探寻 6G,来试图解决这些缺点。
|
||||
|
||||
有一个[研究新的能够融入 6G 技术的小组][28],自称为“融合 TeraHertz 通信与传感中心”(ComSenTer)。根据说明,他们努力让每个设备的带宽达到 100Gbps。
|
||||
|
||||
除了增加可靠性,还突破了可靠性并增加速度,6G 同样试图允许上千的并发连接。如果成功的话,这个特点将帮助物联网设备联网,使在工业设置中部署上千个传感器。
|
||||
|
||||
即使仍在胚胎当中,6G 已经由于新发现的 [在基于 tera-hretz 的网络中潜在的中间人攻击][29]的紧迫性面临安全的考虑。好消息是有大量时间来解决这个问题。6G 网络直到 2030 之前才可能出现。
|
||||
|
||||
阅读更多关于 5G 网络:
|
||||
|
||||
* [企业如何为 5G 网络做准备][30]
|
||||
* [5G 与 4G:速度、延迟和应用支持的差异][31]
|
||||
* [私人 5G 网络即将到来][32]
|
||||
* [5G 和 6G 无线存在安全问题][33]
|
||||
* [毫米波无线技术如何支持 5G 和物联网][34]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3203489/what-is-5g-how-is-it-better-than-4g.html
|
||||
|
||||
作者:[Josh Fruhlinger][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Josh-Fruhlinger/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.techhive.com/images/article/2017/04/5g-100718139-large.jpg
|
||||
[2]: https://www.networkworld.com/article/3203489/what-is-5g-wireless-networking-benefits-standards-availability-versus-lte.html
|
||||
[3]: https://www.networkworld.com/article/3354477/mobile-world-congress-the-time-of-5g-is-almost-here.html
|
||||
[4]: https://www.networkworld.com/article/3330603/5g-versus-4g-how-speed-latency-and-application-support-differ.html
|
||||
[5]: https://www.theverge.com/2018/6/15/17467734/5g-nr-standard-3gpp-standalone-finished
|
||||
[6]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fcourses%2Fmobile-device-management-big-picture
|
||||
[7]: https://www.networkworld.com/article/3291323/millimeter-wave-wireless-could-help-support-5g-and-iot.html
|
||||
[8]: https://spectrum.ieee.org/video/telecom/wireless/5g-bytes-small-cells-explained
|
||||
[9]: https://www.networkworld.com/article/3250268/what-is-mu-mimo-and-why-you-need-it-in-your-wireless-routers.html
|
||||
[10]: https://spectrum.ieee.org/tech-talk/telecom/wireless/5g-researchers-achieve-new-spectrum-efficiency-record
|
||||
[11]: https://www.networkworld.com/article/3262991/future-wireless-networks-will-have-no-capacity-limits.html
|
||||
[12]: https://venturebeat.com/2018/05/14/worlds-first-commercial-5g-network-launches-in-qatar/
|
||||
[13]: https://www.lifewire.com/5g-availability-world-4156244
|
||||
[14]: https://www.digitaltrends.com/computing/verizon-5g-home-promises-up-to-gigabit-internet-speeds-for-50/
|
||||
[15]: https://lifehacker.com/heres-your-cheat-sheet-for-verizons-new-5g-data-plans-1833278817
|
||||
[16]: https://www.theverge.com/2018/10/2/17927712/verizon-5g-home-internet-real-speed-meaning
|
||||
[17]: https://www.cnn.com/2018/12/18/tech/5g-mobile-att/index.html
|
||||
[18]: https://www.networkworld.com/article/3339720/like-4g-before-it-5g-is-being-hyped.html?nsdr=true
|
||||
[19]: https://www.digitaltrends.com/mobile/sprint-5g-rollout/
|
||||
[20]: https://www.cnet.com/news/t-mobile-delays-full-600-mhz-5g-launch-until-second-half/
|
||||
[21]: https://lets5g.com/
|
||||
[22]: https://www.verizonwireless.com/support/5g-moto-mod-faqs/?AID=11365093&SID=100098X1555750Xbc2e857934b22ebca1a0570d5ba93b7c&vendorid=CJM&PUBID=7105813&cjevent=2e2150cb478c11e98183013b0a1c0e0c
|
||||
[23]: https://www.digitaltrends.com/cell-phone-reviews/moto-z3-review/
|
||||
[24]: https://www.businessinsider.com/samsung-galaxy-s10-5g-which-us-cities-have-5g-networks-2019-2
|
||||
[25]: https://www.cnet.com/news/why-apples-in-no-rush-to-sell-you-a-5g-iphone/
|
||||
[26]: https://mashable.com/2012/09/09/iphone-5-4g-lte/#hYyQUelYo8qq
|
||||
[27]: https://www.networkworld.com/article/3305359/6g-will-achieve-terabits-per-second-speeds.html
|
||||
[28]: https://www.networkworld.com/article/3285112/get-ready-for-upcoming-6g-wireless-too.html
|
||||
[29]: https://www.networkworld.com/article/3315626/5g-and-6g-wireless-technologies-have-security-issues.html
|
||||
[30]: https://%20https//www.networkworld.com/article/3306720/mobile-wireless/how-enterprises-can-prep-for-5g.html
|
||||
[31]: https://%20https//www.networkworld.com/article/3330603/mobile-wireless/5g-versus-4g-how-speed-latency-and-application-support-differ.html
|
||||
[32]: https://%20https//www.networkworld.com/article/3319176/mobile-wireless/private-5g-networks-are-coming.html
|
||||
[33]: https://www.networkworld.com/article/3315626/network-security/5g-and-6g-wireless-technologies-have-security-issues.html
|
||||
[34]: https://www.networkworld.com/article/3291323/mobile-wireless/millimeter-wave-wireless-could-help-support-5g-and-iot.html
|
||||
[35]: https://www.facebook.com/NetworkWorld/
|
||||
[36]: https://www.linkedin.com/company/network-world
|
||||
|
@ -0,0 +1,87 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10809-1.html)
|
||||
[#]: subject: (Command line quick tips: Cutting content out of files)
|
||||
[#]: via: (https://fedoramagazine.org/command-line-quick-tips-cutting-content-out-of-files/)
|
||||
[#]: author: (Stephen Snow https://fedoramagazine.org/author/jakfrost/)
|
||||
|
||||
命令行技巧:分割文件内容
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Fedora 发行版是一个功能齐全的操作系统,有出色的图形化桌面环境。用户可以很容易地通过单击动作来完成任何典型任务。所有这些美妙的易用性掩盖了其底层强大的命令行细节。本文是向你展示一些常见命令行实用程序的系列文章的一部分。让我们进入 shell 来看看 `cut`。
|
||||
|
||||
通常,当你在命令行中工作时,你处理的是文本文件。有时这些文件可能很长,虽然可以完整地阅读它们,但是可能会耗费大量时间,并且容易出错。在本文中,你将学习如何从文本文件中提取内容,并从中获取你所需的信息。
|
||||
|
||||
重要的是要意识到,在 Fedora 中有许多方法可以完成类似的命令行任务。例如,Fedora 仓库含有用于解析和处理文本的完整语言系统。此外,还有多个命令行实用程序可用于 shell 中任何可能的用途。本文只关注使用其中几个实用程序选项,从文件中提取一些信息并以可读的格式呈现。
|
||||
|
||||
### cut 使用
|
||||
|
||||
为了演示这个例子,在系统上使用一个标准的大文件,如 `/etc/passwd`。正如本系列的前一篇文章所示,你可以执行 `cat` 命令来查看整个文件:
|
||||
|
||||
```
|
||||
$ cat /etc/passwd
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||
adm:x:3:4:adm:/var/adm:/sbin/nologin
|
||||
...
|
||||
```
|
||||
|
||||
此文件包含系统上所有所有账户的信息。它有一个特定的格式:
|
||||
|
||||
```
|
||||
name:password:user-id:group-id:comment:home-directory:shell
|
||||
```
|
||||
|
||||
假设你只想要系统上所有账户名的列表,如果你只能从每一行中删除 “name” 值。这就是 `cut` 命令派上用场的地方!它一次处理一行输入,并提取该行的特定部分。
|
||||
|
||||
`cut` 命令提供了以不同方式选择一行的部分的选项,在本示例中需要两个,`-d` 和 `-f`。`-d` 选项允许你声明用于分隔行中值的分隔符。在本例中,冒号(`:`)用于分隔值。`-f` 选项允许你选择要提取哪些字段值。因此,在本例中,输入的命令是:
|
||||
|
||||
```
|
||||
$ cut -d: -f1 /etc/passwd
|
||||
root
|
||||
bin
|
||||
daemon
|
||||
adm
|
||||
...
|
||||
```
|
||||
|
||||
太棒了,成功了!但是你将输出打印到标准输出,在终端会话中意味着它需要占据屏幕。如果你需要稍后完成另一项任务所需的信息,这该怎么办?如果有办法将 `cut` 命令的输出保存到文本文件中,那就太好了。对于这样的任务,shell 有一个简单的内置功能,重定向功能(`>`)。
|
||||
|
||||
```
|
||||
$ cut -d: -f1 /etc/passwd > names.txt
|
||||
```
|
||||
|
||||
这会将 `cut` 的输出放到一个名为 `names.txt` 的文件中,你可以使用 `cat` 来查看它的内容:
|
||||
|
||||
```
|
||||
$ cat names.txt
|
||||
root
|
||||
bin
|
||||
daemon
|
||||
adm
|
||||
...
|
||||
```
|
||||
|
||||
使用两个命令和一个 shell 功能,可以很容易地使用 `cat` 从一个文件进行识别、提取和重定向一些信息,并将其保存到另一个文件以供以后使用。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/command-line-quick-tips-cutting-content-out-of-files/
|
||||
|
||||
作者:[Stephen Snow][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://fedoramagazine.org/author/jakfrost/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/commandline-cutting-816x345.jpg
|
||||
[2]: https://unsplash.com/photos/tA5eSY_hay8?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[3]: https://unsplash.com/search/photos/command-line?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
@ -0,0 +1,108 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10833-1.html)
|
||||
[#]: subject: (Getting started with Python's cryptography library)
|
||||
[#]: via: (https://opensource.com/article/19/4/cryptography-python)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
Python 的加密库入门
|
||||
======
|
||||
|
||||
> 加密你的数据并使其免受攻击者的攻击。
|
||||
|
||||
![lock on world map][1]
|
||||
|
||||
密码学俱乐部的第一条规则是:永远不要自己*发明*密码系统。密码学俱乐部的第二条规则是:永远不要自己*实现*密码系统:在现实世界中,在*实现*以及设计密码系统阶段都找到过许多漏洞。
|
||||
|
||||
Python 中的一个有用的基本加密库就叫做 [cryptography][2]。它既是一个“安全”方面的基础库,也是一个“危险”层。“危险”层需要更加小心和相关的知识,并且使用它很容易出现安全漏洞。在这篇介绍性文章中,我们不会涵盖“危险”层中的任何内容!
|
||||
|
||||
cryptography 库中最有用的高级安全功能是一种 Fernet 实现。Fernet 是一种遵循最佳实践的加密缓冲区的标准。它不适用于非常大的文件,如千兆字节以上的文件,因为它要求你一次加载要加密或解密的内容到内存缓冲区中。
|
||||
|
||||
Fernet 支持<ruby>对称<rt>symmetric</rt></ruby>(即<ruby>密钥<rt>secret key</rt></ruby>)加密方式*:加密和解密使用相同的密钥,因此必须保持安全。
|
||||
|
||||
生成密钥很简单:
|
||||
|
||||
```
|
||||
>>> k = fernet.Fernet.generate_key()
|
||||
>>> type(k)
|
||||
<class 'bytes'>
|
||||
```
|
||||
|
||||
这些字节可以写入有适当权限的文件,最好是在安全的机器上。
|
||||
|
||||
有了密钥后,加密也很容易:
|
||||
|
||||
```
|
||||
>>> frn = fernet.Fernet(k)
|
||||
>>> encrypted = frn.encrypt(b"x marks the spot")
|
||||
>>> encrypted[:10]
|
||||
b'gAAAAABb1'
|
||||
```
|
||||
|
||||
如果在你的机器上加密,你会看到略微不同的值。不仅因为(我希望)你生成了和我不同的密钥,而且因为 Fernet 将要加密的值与一些随机生成的缓冲区连接起来。这是我之前提到的“最佳实践”之一:它将阻止对手分辨哪些加密值是相同的,这有时是攻击的重要部分。
|
||||
|
||||
解密同样简单:
|
||||
|
||||
```
|
||||
>>> frn = fernet.Fernet(k)
|
||||
>>> frn.decrypt(encrypted)
|
||||
b'x marks the spot'
|
||||
```
|
||||
|
||||
请注意,这仅加密和解密*字节串*。为了加密和解密*文本串*,通常需要对它们使用 [UTF-8][3] 进行编码和解码。
|
||||
|
||||
20 世纪中期密码学最有趣的进展之一是<ruby>公钥<rt>public key</rt></ruby>加密。它可以在发布加密密钥的同时而让*解密密钥*保持保密。例如,它可用于保存服务器使用的 API 密钥:服务器是唯一可以访问解密密钥的一方,但是任何人都可以保存公共加密密钥。
|
||||
|
||||
虽然 cryptography 没有任何支持公钥加密的*安全*功能,但 [PyNaCl][4] 库有。PyNaCl 封装并提供了一些很好的方法来使用 Daniel J. Bernstein 发明的 [NaCl][5] 加密系统。
|
||||
|
||||
NaCl 始终同时<ruby>加密<rt>encrypt</rt></ruby>和<ruby>签名<rt>sign</rt></ruby>或者同时<ruby>解密<rt>decrypt</rt></ruby>和<ruby>验证签名<rt>verify signature</rt></ruby>。这是一种防止<ruby>基于可伸缩性<rt>malleability-based</rt></ruby>的攻击的方法,其中攻击者会修改加密值。
|
||||
|
||||
加密是使用公钥完成的,而签名是使用密钥完成的:
|
||||
|
||||
```
|
||||
>>> from nacl.public import PrivateKey, PublicKey, Box
|
||||
>>> source = PrivateKey.generate()
|
||||
>>> with open("target.pubkey", "rb") as fpin:
|
||||
... target_public_key = PublicKey(fpin.read())
|
||||
>>> enc_box = Box(source, target_public_key)
|
||||
>>> result = enc_box.encrypt(b"x marks the spot")
|
||||
>>> result[:4]
|
||||
b'\xe2\x1c0\xa4'
|
||||
```
|
||||
|
||||
解密颠倒了角色:它需要私钥进行解密,需要公钥验证签名:
|
||||
|
||||
```
|
||||
>>> from nacl.public import PrivateKey, PublicKey, Box
|
||||
>>> with open("source.pubkey", "rb") as fpin:
|
||||
... source_public_key = PublicKey(fpin.read())
|
||||
>>> with open("target.private_key", "rb") as fpin:
|
||||
... target = PrivateKey(fpin.read())
|
||||
>>> dec_box = Box(target, source_public_key)
|
||||
>>> dec_box.decrypt(result)
|
||||
b'x marks the spot'
|
||||
```
|
||||
|
||||
最后,[PocketProtector][6] 库构建在 PyNaCl 之上,包含完整的密钥管理方案。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/cryptography-python
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-cloud-safe.png?itok=yj2TFPzq (lock on world map)
|
||||
[2]: https://cryptography.io/en/latest/
|
||||
[3]: https://en.wikipedia.org/wiki/UTF-8
|
||||
[4]: https://pynacl.readthedocs.io/en/stable/
|
||||
[5]: https://nacl.cr.yp.to/
|
||||
[6]: https://github.com/SimpleLegal/pocket_protector/blob/master/USER_GUIDE.md
|
@ -0,0 +1,74 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10822-1.html)
|
||||
[#]: subject: (How to quickly deploy, run Linux applications as unikernels)
|
||||
[#]: via: (https://www.networkworld.com/article/3387299/how-to-quickly-deploy-run-linux-applications-as-unikernels.html#tk.rss_all)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
如何快速部署并作为 unikernel 运行 Linux 应用
|
||||
======
|
||||
|
||||
unikernel 是一种用于在云基础架构上部署应用程序的更小、更快、更安全的方式。使用 NanoVMs OPS,任何人都可以将 Linux 应用程序作为 unikernel 运行而无需额外编码。
|
||||
|
||||
![Marcho Verch \(CC BY 2.0\)][1]
|
||||
|
||||
随着 unikernel 的出现,构建和部署轻量级应用变得更容易、更可靠。虽然功能有限,但 unikernal 在速度和安全性方面有许多优势。
|
||||
|
||||
### 什么是 unikernel?
|
||||
|
||||
unikernel 是一种非常特殊的<ruby>单一地址空间<rt>single-address-space</rt></ruby>的机器镜像,类似于已经主导大批互联网的云应用,但它们相当小并且是单一用途的。它们很轻,只提供所需的资源。它们加载速度非常快,而且安全性更高 —— 攻击面非常有限。单个可执行文件中包含所需的所有驱动、I/O 例程和支持库。其最终生成的虚拟镜像可以无需其它部分就可以引导和运行。它们通常比容器快 10 到 20 倍。
|
||||
|
||||
潜在的攻击者无法进入 shell 并获得控制权,因为它没有 shell。他们无法获取系统的 `/etc/passwd`或 `/etc/shadow` 文件,因为这些文件不存在。创建一个 unikernel 就像应用将自己变成操作系统。使用 unikernel,应用和操作系统将成为一个单一的实体。你忽略了不需要的东西,从而消除了漏洞并大幅提高性能。
|
||||
|
||||
简而言之,unikernel:
|
||||
|
||||
* 提供更高的安全性(例如,shell 破解代码无用武之地)
|
||||
* 比标准云应用占用更小空间
|
||||
* 经过高度优化
|
||||
* 启动非常快
|
||||
|
||||
### unikernel 有什么缺点吗?
|
||||
|
||||
unikernel 的唯一严重缺点是你必须构建它们。对于许多开发人员来说,这是一个巨大的进步。由于应用的底层特性,将应用简化为所需的内容然后生成紧凑、平稳运行的应用可能很复杂。在过去,你几乎必须是系统开发人员或底层程序员才能生成它们。
|
||||
|
||||
### 这是怎么改变的?
|
||||
|
||||
最近(2019 年 3 月 24 日)[NanoVMs][3] 宣布了一个将任何 Linux 应用加载为 unikernel 的工具。使用 NanoVMs OPS,任何人都可以将 Linux 应用作为 unikernel 运行而无需额外编码。该应用还可以更快、更安全地运行,并且成本和开销更低。
|
||||
|
||||
### 什么是 NanoVMs OPS?
|
||||
|
||||
NanoVMs 是给开发人员的 unikernel 工具。它能让你运行各种企业级软件,但仍然可以非常严格地控制它的运行。
|
||||
|
||||
使用 OPS 的其他好处包括:
|
||||
|
||||
* 无需经验或知识,开发人员就可以构建 unikernel。
|
||||
* 该工具可在笔记本电脑上本地构建和运行 unikernel。
|
||||
* 无需创建帐户,只需下载并一个命令即可执行 OPS。
|
||||
|
||||
NanoVMs 的介绍可以在 [Youtube 上的 NanoVMs 视频][5] 上找到。你还可以查看该公司的 [LinkedIn 页面][6]并在[此处][7]阅读有关 NanoVMs 安全性的信息。
|
||||
|
||||
还有有关如何[入门][8]的一些信息。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3387299/how-to-quickly-deploy-run-linux-applications-as-unikernels.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.idgesg.net/images/article/2019/04/corn-kernels-100792925-large.jpg
|
||||
[3]: https://nanovms.com/
|
||||
[5]: https://www.youtube.com/watch?v=VHWDGhuxHPM
|
||||
[6]: https://www.linkedin.com/company/nanovms/
|
||||
[7]: https://nanovms.com/security
|
||||
[8]: https://nanovms.gitbook.io/ops/getting_started
|
||||
[9]: https://www.facebook.com/NetworkWorld/
|
||||
[10]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,177 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10843-1.html)
|
||||
[#]: subject: (Anbox – Easy Way To Run Android Apps On Linux)
|
||||
[#]: via: (https://www.2daygeek.com/anbox-best-android-emulator-for-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
Anbox:在 Linux 上运行 Android 应用程序的简单方式
|
||||
======
|
||||
|
||||
Android 模拟器允许我们直接从 Linux 系统上运行我们最喜欢的 Android 应用程序或游戏。对于 Linux 来说,有很多的这样的 Android 模拟器,在过去我们介绍过几个此类应用程序。
|
||||
|
||||
你可以通过导航到下面的网址回顾它们。
|
||||
|
||||
* [如何在 Linux 上安装官方 Android 模拟器 (SDK)][1]
|
||||
* [如何在 Linux 上安装 GenyMotion (Android 模拟器)][2]
|
||||
|
||||
今天我们将讨论 Anbox Android 模拟器。
|
||||
|
||||
### Anbox 是什么?
|
||||
|
||||
Anbox 是 “Android in a box” 的缩写。Anbox 是一个基于容器的方法,可以在普通的 GNU/Linux 系统上启动完整的 Android 系统。
|
||||
|
||||
它是现代化的新模拟器之一。
|
||||
|
||||
Anbox 可以让你在 Linux 系统上运行 Android,而没有虚拟化的迟钝,因为核心的 Android 操作系统已经使用 Linux 命名空间(LXE)放置到容器中了。
|
||||
|
||||
Android 容器不能直接访问到任何硬件,所有硬件的访问都是通过在主机上的守护进程进行的。
|
||||
|
||||
每个应用程序将在一个单独窗口打开,就像其它本地系统应用程序一样,并且它可以显示在启动器中。
|
||||
|
||||
### 如何在 Linux 中安装 Anbox ?
|
||||
|
||||
Anbox 也可作为 snap 软件包安装,请确保你已经在你的系统上启用了 snap 支持。
|
||||
|
||||
Anbox 软件包最近被添加到 Ubuntu 18.10 (Cosmic) 和 Debian 10 (Buster) 软件仓库。如果你正在运行这些版本,那么你可以轻松地在官方发行版的软件包管理器的帮助下安装。否则可以用 snap 软件包安装。
|
||||
|
||||
为使 Anbox 工作,确保需要的内核模块已经安装在你的系统中。对于基于 Ubuntu 的用户,使用下面的 PPA 来安装它。
|
||||
|
||||
```
|
||||
$ sudo add-apt-repository ppa:morphis/anbox-support
|
||||
$ sudo apt update
|
||||
$ sudo apt install linux-headers-generic anbox-modules-dkms
|
||||
```
|
||||
|
||||
在你安装 `anbox-modules-dkms` 软件包后,你必须手动重新加载内核模块,或需要系统重新启动。
|
||||
|
||||
```
|
||||
$ sudo modprobe ashmem_linux
|
||||
$ sudo modprobe binder_linux
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][3] 或 [APT 命令][4] 来安装 anbox。
|
||||
|
||||
```
|
||||
$ sudo apt install anbox
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,我们总是习惯从 AUR 储存库中获取软件包。所以,使用任一个的 [AUR 助手][5] 来安装它。我喜欢使用 [Yay 工具][6]。
|
||||
|
||||
```
|
||||
$ yuk -S anbox-git
|
||||
```
|
||||
|
||||
否则,你可以通过导航到下面的文章来 [在 Linux 中安装和配置 snap][7]。如果你已经在你的系统上安装 snap,其它的步骤可以忽略。
|
||||
|
||||
```
|
||||
$ sudo snap install --devmode --beta anbox
|
||||
```
|
||||
|
||||
### Anbox 的必要条件
|
||||
|
||||
默认情况下,Anbox 并没有带有 Google Play Store。因此,我们需要手动下载每个应用程序(APK),并使用 Android 调试桥(ADB)安装它。
|
||||
|
||||
ADB 工具在大多数的发行版的软件仓库是轻易可获得的,我们可以容易地安装它。
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][3] 或 [APT 命令][4] 来安装 ADB。
|
||||
|
||||
```
|
||||
$ sudo apt install android-tools-adb
|
||||
```
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][8] 来安装 ADB。
|
||||
|
||||
```
|
||||
$ sudo dnf install android-tools
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman 命令][9] 来安装 ADB。
|
||||
|
||||
```
|
||||
$ sudo pacman -S android-tools
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][10] 来安装 ADB。
|
||||
|
||||
```
|
||||
$ sudo zypper install android-tools
|
||||
```
|
||||
|
||||
### 在哪里下载 Android 应用程序?
|
||||
|
||||
既然我们不能使用 Play Store ,你就得从信得过的网站来下载 APK 软件包,像 [APKMirror][11] ,然后手动安装它。
|
||||
|
||||
### 如何启动 Anbox?
|
||||
|
||||
Anbox 可以从 Dash 启动。这是默认的 Anbox 外貌。
|
||||
|
||||
![][13]
|
||||
|
||||
### 如何把应用程序推到 Anbox ?
|
||||
|
||||
像我先前所说,我们需要手动安装它。为测试目的,我们将安装 YouTube 和 Firefox 应用程序。
|
||||
|
||||
首先,你需要启动 ADB 服务。为做到这样,运行下面的命令。
|
||||
|
||||
```
|
||||
$ adb devices
|
||||
```
|
||||
|
||||
我们已经下载 YouTube 和 Firefox 应用程序,现在我们将安装。
|
||||
|
||||
语法格式:
|
||||
|
||||
```
|
||||
$ adb install Name-Of-Your-Application.apk
|
||||
```
|
||||
|
||||
安装 YouTube 和 Firefox 应用程序:
|
||||
|
||||
```
|
||||
$ adb install 'com.google.android.youtube_14.13.54-1413542800_minAPI19(x86_64)(nodpi)_apkmirror.com.apk'
|
||||
Success
|
||||
|
||||
$ adb install 'org.mozilla.focus_9.0-330191219_minAPI21(x86)(nodpi)_apkmirror.com.apk'
|
||||
Success
|
||||
```
|
||||
|
||||
我已经在我的 Anbox 中安装 YouTube 和 Firefox。查看下面的截图。
|
||||
|
||||
![][14]
|
||||
|
||||
像我们在文章的开始所说,它将以新的标签页打开任何的应用程序。在这里,我们将打开 Firefox ,并访问 [2daygeek.com][15] 网站。
|
||||
|
||||
![][16]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/anbox-best-android-emulator-for-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][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://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/install-configure-sdk-android-emulator-on-linux/
|
||||
[2]: https://www.2daygeek.com/install-genymotion-android-emulator-on-ubuntu-debian-fedora-arch-linux/
|
||||
[3]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[4]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[5]: https://www.2daygeek.com/category/aur-helper/
|
||||
[6]: https://www.2daygeek.com/install-yay-yet-another-yogurt-aur-helper-on-arch-linux/
|
||||
[7]: https://www.2daygeek.com/linux-snap-package-manager-ubuntu/
|
||||
[8]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[9]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[10]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[11]: https://www.apkmirror.com/
|
||||
[12]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[13]: https://www.2daygeek.com/wp-content/uploads/2019/04/anbox-best-android-emulator-for-linux-1.jpg
|
||||
[14]: https://www.2daygeek.com/wp-content/uploads/2019/04/anbox-best-android-emulator-for-linux-2.jpg
|
||||
[15]: https://www.2daygeek.com/
|
||||
[16]: https://www.2daygeek.com/wp-content/uploads/2019/04/anbox-best-android-emulator-for-linux-3.jpg
|
@ -0,0 +1,211 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (arrowfeng)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10820-1.html)
|
||||
[#]: subject: (How To Install And Configure Chrony As NTP Client?)
|
||||
[#]: via: (https://www.2daygeek.com/configure-ntp-client-using-chrony-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
如何安装和配置 Chrony 作为 NTP 客户端?
|
||||
======
|
||||
|
||||
NTP 服务器和 NTP 客户端可以让我们通过网络来同步时钟。之前,我们已经撰写了一篇关于 [NTP 服务器和 NTP 客户端的安装与配置][1] 的文章。
|
||||
|
||||
如果你想看这些内容,点击上述的 URL 访问。
|
||||
|
||||
### Chrony 客户端
|
||||
|
||||
Chrony 是 NTP 客户端的替代品。它能以更精确的时间和更快的速度同步时钟,并且它对于那些不是全天候在线的系统非常有用。
|
||||
|
||||
chronyd 更小、更节能,它占用更少的内存且仅当需要时它才唤醒 CPU。即使网络拥塞较长时间,它也能很好地运行。它支持 Linux 上的硬件时间戳,允许在本地网络进行极其准确的同步。
|
||||
|
||||
它提供下列两个服务。
|
||||
|
||||
* `chronyc`:Chrony 的命令行接口。
|
||||
* `chronyd`:Chrony 守护进程服务。
|
||||
|
||||
### 如何在 Linux 上安装和配置 Chrony?
|
||||
|
||||
由于安装包在大多数发行版的官方仓库中可用,因此直接使用包管理器去安装它。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][2] 去安装 chrony。
|
||||
|
||||
```
|
||||
$ sudo dnf install chrony
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][3] 或者 [APT 命令][4] 去安装 chrony。
|
||||
|
||||
```
|
||||
$ sudo apt install chrony
|
||||
```
|
||||
|
||||
对基于 Arch Linux 的系统,使用 [Pacman 命令][5] 去安装 chrony。
|
||||
|
||||
```
|
||||
$ sudo pacman -S chrony
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统,使用 [YUM 命令][6] 去安装 chrony。
|
||||
|
||||
```
|
||||
$ sudo yum install chrony
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][7] 去安装 chrony。
|
||||
|
||||
```
|
||||
$ sudo zypper install chrony
|
||||
```
|
||||
|
||||
在这篇文章中,我们将使用下列设置去测试。
|
||||
|
||||
* NTP 服务器:主机名:CentOS7.2daygeek.com,IP:192.168.1.5,OS:CentOS 7
|
||||
* Chrony 客户端:主机名:Ubuntu18.2daygeek.com,IP:192.168.1.3,OS:Ubuntu 18.04
|
||||
|
||||
服务器的安装请访问 [在 Linux 上安装和配置 NTP 服务器][1] 的 URL。
|
||||
|
||||
我已经在 CentOS7.2daygeek.com 这台主机上安装和配置了 NTP 服务器,因此,将其附加到所有的客户端机器上。此外,还包括其他所需信息。
|
||||
|
||||
`chrony.conf` 文件的位置根据你的发行版不同而不同。
|
||||
|
||||
对基于 RHEL 的系统,它位于 `/etc/chrony.conf`。
|
||||
|
||||
对基于 Debian 的系统,它位于 `/etc/chrony/chrony.conf`。
|
||||
|
||||
```
|
||||
# vi /etc/chrony/chrony.conf
|
||||
|
||||
server CentOS7.2daygeek.com prefer iburst
|
||||
keyfile /etc/chrony/chrony.keys
|
||||
driftfile /var/lib/chrony/chrony.drift
|
||||
logdir /var/log/chrony
|
||||
maxupdateskew 100.0
|
||||
makestep 1 3
|
||||
cmdallow 192.168.1.0/24
|
||||
```
|
||||
|
||||
更新配置后需要重启 Chrony 服务。
|
||||
|
||||
对于 sysvinit 系统。基于 RHEL 的系统需要去运行 `chronyd` 而不是 `chrony`。
|
||||
|
||||
```
|
||||
# service chronyd restart
|
||||
# chkconfig chronyd on
|
||||
```
|
||||
|
||||
对于 systemctl 系统。 基于 RHEL 的系统需要去运行 `chronyd` 而不是 `chrony`。
|
||||
|
||||
```
|
||||
# systemctl restart chronyd
|
||||
# systemctl enable chronyd
|
||||
```
|
||||
|
||||
使用像 `tacking`、`sources` 和 `sourcestats` 这样的子命令去检查 chrony 的同步细节。
|
||||
|
||||
去检查 chrony 的追踪状态。
|
||||
|
||||
```
|
||||
# chronyc tracking
|
||||
Reference ID : C0A80105 (CentOS7.2daygeek.com)
|
||||
Stratum : 3
|
||||
Ref time (UTC) : Thu Mar 28 05:57:27 2019
|
||||
System time : 0.000002545 seconds slow of NTP time
|
||||
Last offset : +0.001194361 seconds
|
||||
RMS offset : 0.001194361 seconds
|
||||
Frequency : 1.650 ppm fast
|
||||
Residual freq : +184.101 ppm
|
||||
Skew : 2.962 ppm
|
||||
Root delay : 0.107966967 seconds
|
||||
Root dispersion : 1.060455322 seconds
|
||||
Update interval : 2.0 seconds
|
||||
Leap status : Normal
|
||||
```
|
||||
|
||||
运行 `sources` 命令去显示当前时间源的信息。
|
||||
|
||||
```
|
||||
# chronyc sources
|
||||
210 Number of sources = 1
|
||||
MS Name/IP address Stratum Poll Reach LastRx Last sample
|
||||
===============================================================================
|
||||
^* CentOS7.2daygeek.com 2 6 17 62 +36us[+1230us] +/- 1111ms
|
||||
```
|
||||
|
||||
`sourcestats` 命令显示有关 chronyd 当前正在检查的每个源的漂移率和偏移估计过程的信息。
|
||||
|
||||
```
|
||||
# chronyc sourcestats
|
||||
210 Number of sources = 1
|
||||
Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev
|
||||
==============================================================================
|
||||
CentOS7.2daygeek.com 5 3 71 -97.314 78.754 -469us 441us
|
||||
```
|
||||
|
||||
当 chronyd 配置为 NTP 客户端或对等端时,你就能通过 `chronyc ntpdata` 命令向每一个 NTP 源发送/接收时间戳模式和交错模式的报告。
|
||||
|
||||
```
|
||||
# chronyc ntpdata
|
||||
|
||||
Remote address : 192.168.1.5 (C0A80105)
|
||||
Remote port : 123
|
||||
Local address : 192.168.1.3 (C0A80103)
|
||||
Leap status : Normal
|
||||
Version : 4
|
||||
Mode : Server
|
||||
Stratum : 2
|
||||
Poll interval : 6 (64 seconds)
|
||||
Precision : -23 (0.000000119 seconds)
|
||||
Root delay : 0.108994 seconds
|
||||
Root dispersion : 0.076523 seconds
|
||||
Reference ID : 85F3EEF4 ()
|
||||
Reference time : Thu Mar 28 06:43:35 2019
|
||||
Offset : +0.000160221 seconds
|
||||
Peer delay : 0.000664478 seconds
|
||||
Peer dispersion : 0.000000178 seconds
|
||||
Response time : 0.000243252 seconds
|
||||
Jitter asymmetry: +0.00
|
||||
NTP tests : 111 111 1111
|
||||
Interleaved : No
|
||||
Authenticated : No
|
||||
TX timestamping : Kernel
|
||||
RX timestamping : Kernel
|
||||
Total TX : 46
|
||||
Total RX : 46
|
||||
Total valid RX : 46
|
||||
```
|
||||
|
||||
最后运行 `date` 命令。
|
||||
|
||||
```
|
||||
# date
|
||||
Thu Mar 28 03:08:11 CDT 2019
|
||||
```
|
||||
|
||||
为了立即跟进系统时钟,绕过任何正在进行的缓步调整,请以 root 身份运行以下命令(以手动调整系统时钟)。
|
||||
|
||||
```
|
||||
# chronyc makestep
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/configure-ntp-client-using-chrony-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[arrowfeng](https://github.com/arrowfeng)
|
||||
校对:[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-10811-1.html
|
||||
[2]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[3]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[4]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[5]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[6]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[7]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
@ -0,0 +1,252 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (arrowfeng)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10811-1.html)
|
||||
[#]: subject: (How To Install And Configure NTP Server And NTP Client In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/install-configure-ntp-server-ntp-client-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
如何在 Linux 上安装、配置 NTP 服务器和客户端?
|
||||
======
|
||||
|
||||
你也许听说过这个词很多次或者你可能已经在使用它了。在这篇文章中我将会清晰的告诉你 NTP 服务器和客户端的安装。
|
||||
|
||||
之后我们将会了解 **[Chrony NTP 客户端的安装][1]**。
|
||||
|
||||
### 什么是 NTP 服务?
|
||||
|
||||
NTP 意即<ruby>网络时间协议<rt>Network Time Protocol</rt></ruby>。它是通过网络在计算机系统之间进行时钟同步的网络协议。换言之,它可以让那些通过 NTP 或者 Chrony 客户端连接到 NTP 服务器的系统保持时间上的一致(它能保持一个精确的时间)。
|
||||
|
||||
NTP 在公共互联网上通常能够保持时间延迟在几十毫秒以内的精度,并在理想条件下,它能在局域网下达到低于一毫秒的延迟精度。
|
||||
|
||||
它使用用户数据报协议(UDP)在端口 123 上发送和接受时间戳。它是个 C/S 架构的应用程序。
|
||||
|
||||
### NTP 客户端
|
||||
|
||||
NTP 客户端将其时钟与网络时间服务器同步。
|
||||
|
||||
### Chrony 客户端
|
||||
|
||||
Chrony 是 NTP 客户端的替代品。它能以更精确的时间更快的同步系统时钟,并且它对于那些不总是在线的系统很有用。
|
||||
|
||||
### 为什么我们需要 NTP 服务?
|
||||
|
||||
为了使你组织中的所有服务器与基于时间的作业保持精确的时间同步。
|
||||
|
||||
为了说明这点,我将告诉你一个场景。比如说,我们有两个服务器(服务器 1 和服务器 2)。服务器 1 通常在 10:55 完成离线作业,然后服务器 2 在 11:00 需要基于服务器 1 完成的作业报告去运行其他作业。
|
||||
|
||||
如果两个服务器正在使用不同的时间(如果服务器 2 时间比服务器 1 提前,服务器 1 的时间就落后于服务器 2),然后我们就不能去执行这个作业。为了达到时间一致,我们应该安装 NTP。
|
||||
|
||||
希望上述能清除你对于 NTP 的疑惑。
|
||||
|
||||
在这篇文章中,我们将使用下列设置去测试。
|
||||
|
||||
* **NTP 服务器:** 主机名:CentOS7.2daygeek.com,IP:192.168.1.8,OS:CentOS 7
|
||||
* **NTP 客户端:** 主机名:Ubuntu18.2daygeek.com,IP:192.168.1.5,OS:Ubuntu 18.04
|
||||
|
||||
### NTP 服务器端:如何在 Linux 上安装 NTP?
|
||||
|
||||
因为它是 C/S 架构,所以 NTP 服务器端和客户端的安装包没有什么不同。在发行版的官方仓库中都有 NTP 安装包,因此可以使用发行版的包管理器安装它。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][2] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo dnf install ntp
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][3] 或者 [APT 命令][4] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo apt install ntp
|
||||
```
|
||||
|
||||
对基于 Arch Linux 的系统,使用 [Pacman 命令][5] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo pacman -S ntp
|
||||
```
|
||||
|
||||
对 RHEL/CentOS 系统,使用 [YUM 命令][6] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo yum install ntp
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][7] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo zypper install ntp
|
||||
```
|
||||
|
||||
### 如何在 Linux 上配置 NTP 服务器?
|
||||
|
||||
安装 NTP 软件包后,请确保在服务器端的 `/etc/ntp.conf` 文件中取消以下配置的注释。
|
||||
|
||||
默认情况下,NTP 服务器配置依赖于 `X.distribution_name.pool.ntp.org`。 如果有必要,可以使用默认配置,也可以访问<https://www.ntppool.org/zone/@>站点,根据你所在的位置(特定国家/地区)进行更改。
|
||||
|
||||
比如说如果你在印度,然后你的 NTP 服务器将是 `0.in.pool.ntp.org`,并且这个地址适用于大多数国家。
|
||||
|
||||
```
|
||||
# vi /etc/ntp.conf
|
||||
|
||||
restrict default kod nomodify notrap nopeer noquery
|
||||
restrict -6 default kod nomodify notrap nopeer noquery
|
||||
restrict 127.0.0.1
|
||||
restrict -6 ::1
|
||||
server 0.asia.pool.ntp.org
|
||||
server 1.asia.pool.ntp.org
|
||||
server 2.asia.pool.ntp.org
|
||||
server 3.asia.pool.ntp.org
|
||||
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
|
||||
driftfile /var/lib/ntp/drift
|
||||
keys /etc/ntp/keys
|
||||
```
|
||||
|
||||
我们仅允许 `192.168.1.0/24` 子网的客户端访问这个 NTP 服务器。
|
||||
|
||||
由于默认情况下基于 RHEL7 的发行版的防火墙是打开的,因此要允许 ntp 服务通过。
|
||||
|
||||
```
|
||||
# firewall-cmd --add-service=ntp --permanent
|
||||
# firewall-cmd --reload
|
||||
```
|
||||
|
||||
更新配置后要重启服务:
|
||||
|
||||
对于 sysvinit 系统。基于 Debian 的系统需要去运行 `ntp` 而不是 `ntpd`。
|
||||
|
||||
```
|
||||
# service ntpd restart
|
||||
# chkconfig ntpd on
|
||||
```
|
||||
|
||||
对于 systemctl 系统。基于 Debian 的需要去运行 `ntp` 和 `ntpd`。
|
||||
|
||||
```
|
||||
# systemctl restart ntpd
|
||||
# systemctl enable ntpd
|
||||
```
|
||||
|
||||
### NTP 客户端:如何在 Linux 上安装 NTP 客户端?
|
||||
|
||||
正如我在这篇文章中前面所说的。NTP 服务器端和客户端的安装包没有什么不同。因此在客户端上也安装同样的软件包。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][2] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo dnf install ntp
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][3] 或者 [APT 命令][4] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo apt install ntp
|
||||
```
|
||||
|
||||
对基于 Arch Linux 的系统,使用 [Pacman 命令][5] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo pacman -S ntp
|
||||
```
|
||||
|
||||
对 RHEL/CentOS 系统,使用 [YUM 命令][6] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo yum install ntp
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][7] 去安装 ntp。
|
||||
|
||||
```
|
||||
$ sudo zypper install ntp
|
||||
```
|
||||
|
||||
我已经在 CentOS7.2daygeek.com` 这台主机上安装和配置了 NTP 服务器,因此将其附加到所有的客户端机器上。
|
||||
|
||||
```
|
||||
# vi /etc/ntp.conf
|
||||
```
|
||||
|
||||
```
|
||||
restrict default kod nomodify notrap nopeer noquery
|
||||
restrict -6 default kod nomodify notrap nopeer noquery
|
||||
restrict 127.0.0.1
|
||||
restrict -6 ::1
|
||||
server CentOS7.2daygeek.com prefer iburst
|
||||
driftfile /var/lib/ntp/drift
|
||||
keys /etc/ntp/keys
|
||||
```
|
||||
|
||||
更新配置后重启服务:
|
||||
|
||||
对于 sysvinit 系统。基于 Debian 的系统需要去运行 `ntp` 而不是 `ntpd`。
|
||||
|
||||
```
|
||||
# service ntpd restart
|
||||
# chkconfig ntpd on
|
||||
```
|
||||
|
||||
对于 systemctl 系统。基于 Debian 的需要去运行 `ntp` 和 `ntpd`。
|
||||
|
||||
```
|
||||
# systemctl restart ntpd
|
||||
# systemctl enable ntpd
|
||||
```
|
||||
|
||||
重新启动 NTP 服务后等待几分钟以便从 NTP 服务器获取同步的时间。
|
||||
|
||||
在 Linux 上运行下列命令去验证 NTP 服务的同步状态。
|
||||
|
||||
```
|
||||
# ntpq –p
|
||||
或
|
||||
# ntpq -pn
|
||||
|
||||
remote refid st t when poll reach delay offset jitter
|
||||
==============================================================================
|
||||
*CentOS7.2daygee 133.243.238.163 2 u 14 64 37 0.686 0.151 16.432
|
||||
```
|
||||
|
||||
运行下列命令去得到 ntpd 的当前状态。
|
||||
|
||||
```
|
||||
# ntpstat
|
||||
synchronised to NTP server (192.168.1.8) at stratum 3
|
||||
time correct to within 508 ms
|
||||
polling server every 64 s
|
||||
```
|
||||
|
||||
最后运行 `date` 命令。
|
||||
|
||||
```
|
||||
# date
|
||||
Tue Mar 26 23:17:05 CDT 2019
|
||||
```
|
||||
|
||||
如果你观察到 NTP 中输出的时间偏移很大。运行下列命令从 NTP 服务器手动同步时钟。当你执行下列命令的时候,确保你的 NTP 客户端应该为未活动状态。(LCTT 译注:当时间偏差很大时,客户端的自动校正需要花费很长时间才能逐步追上,因此应该手动运行以更新)
|
||||
|
||||
```
|
||||
# ntpdate –uv CentOS7.2daygeek.com
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/install-configure-ntp-server-ntp-client-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[arrowfeng](https://github.com/arrowfeng)
|
||||
校对:[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/configure-ntp-client-using-chrony-in-linux/
|
||||
[2]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[3]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[4]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[5]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[6]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[7]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
133
published/20190411 Installing Ubuntu MATE on a Raspberry Pi.md
Normal file
133
published/20190411 Installing Ubuntu MATE on a Raspberry Pi.md
Normal file
@ -0,0 +1,133 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10817-1.html)
|
||||
[#]: subject: (Installing Ubuntu MATE on a Raspberry Pi)
|
||||
[#]: via: (https://itsfoss.com/ubuntu-mate-raspberry-pi/)
|
||||
[#]: author: (Chinmay https://itsfoss.com/author/chinmay/)
|
||||
|
||||
在树莓派上安装 Ubuntu MATE
|
||||
=================================
|
||||
|
||||
> 简介: 这篇快速指南告诉你如何在树莓派设备上安装 Ubuntu MATE。
|
||||
|
||||
[树莓派][1] 是目前最流行的单板机并且是创客首选的板子。[Raspbian][2] 是基于 Debian 的树莓派官方操作系统。它是轻量级的,内置了教育工具和能在大部分场景下完成工作的工具。
|
||||
|
||||
[安装 Raspbian][3] 安装同样简单,但是与 [Debian][4] 随同带来的问题是慢的升级周期和旧的软件包。
|
||||
|
||||
在树莓派上运行 Ubuntu 可以给你带来一个更丰富的体验和最新的软件。当在你的树莓派上运行 Ubuntu 时我们有几个选择。
|
||||
|
||||
1. [Ubuntu MATE][5] :Ubuntu MATE 是仅有的原生支持树莓派且包含一个完整的桌面环境的发行版。
|
||||
2. [Ubuntu Server 18.04][6] + 手动安装一个桌面环境。
|
||||
3. 使用 [Ubuntu Pi Flavor Maker][7] 社区构建的镜像,这些镜像只支持树莓派 2B 和 3B 的变种,并且**不能**更新到最新的 LTS 发布版。
|
||||
|
||||
第一个选择安装是最简单和快速的,而第二个选择给了你自由选择安装桌面环境的机会。我推荐选择前两个中的任一个。
|
||||
|
||||
这里是一些磁盘镜像下载链接。在这篇文章里我只会提及 Ubuntu MATE 的安装。
|
||||
|
||||
### 在树莓派上安装 Ubuntu MATE
|
||||
|
||||
去 Ubuntu MATE 的下载页面获取推荐的镜像。
|
||||
|
||||
![][8]
|
||||
|
||||
试验性的 ARM64 版本只应在你需要在树莓派服务器上运行像 MongoDB 这样的 64 位应用时使用。
|
||||
|
||||
- [下载为树莓派准备的 Ubuntu MATE][9]
|
||||
|
||||
#### 第 1 步:设置 SD 卡
|
||||
|
||||
镜像文件一旦下载完成后需要解压。你可以简单的右击来提取它。
|
||||
|
||||
也可以使用下面命令做同样的事。
|
||||
|
||||
```
|
||||
xz -d ubuntu-mate***.img.xz
|
||||
```
|
||||
|
||||
如果你在 Windows 上你可以使用 [7-zip][10] 替代。
|
||||
|
||||
安装 [Balena Etcher][11],我们将使用这个工具将镜像写入 SD 卡。确保你的 SD 卡有至少 8 GB 的容量。
|
||||
|
||||
启动 Etcher,选择镜像文件和 SD 卡。
|
||||
|
||||
![][12]
|
||||
|
||||
一旦进度完成 SD 卡就准备好了。
|
||||
|
||||
#### 第 2 步:设置树莓派
|
||||
|
||||
你可能已经知道你需要一些外设才能使用树莓派,例如鼠标、键盘、HDMI 线等等。你同样可以[不用键盘和鼠标安装树莓派][13],但是这篇指南不是那样。
|
||||
|
||||
* 插入一个鼠标和一个键盘。
|
||||
* 连接 HDMI 线缆。
|
||||
* 插入 SD 卡 到 SD 卡槽。
|
||||
|
||||
插入电源线给它供电。确保你有一个好的电源供应(5V、3A 至少)。一个不好的电源供应可能降低性能。
|
||||
|
||||
#### Ubuntu MATE 安装
|
||||
|
||||
一旦你给树莓派供电,你将遇到非常熟悉的 Ubuntu 安装过程。在这里的安装过程相当直接。
|
||||
|
||||
![选择你的键盘布局][14]
|
||||
|
||||
![选择你的时区][15]
|
||||
|
||||
选择你的 WiFi 网络并且在网络连接中输入密码。
|
||||
|
||||
![添加用户名和密码][16]
|
||||
|
||||
在设置了键盘布局、时区和用户凭证后,在几分钟后你将被带到登录界面。瞧!你快要完成了。
|
||||
|
||||
![][17]
|
||||
|
||||
一旦登录,第一件事你应该做的是[更新 Ubuntu][18]。你应该使用下列命令。
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt upgrade
|
||||
```
|
||||
|
||||
你同样可以使用软件更新器。
|
||||
|
||||
![][19]
|
||||
|
||||
一旦更新完成安装你就可以开始了。你可以根据你的需要继续安装树莓派平台为 GPIO 和其他 I/O 准备的特定软件包。
|
||||
|
||||
是什么让你考虑在 Raspberry 上安装 Ubuntu,你对 Raspbian 的体验如何呢?请在下方评论来让我知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/ubuntu-mate-raspberry-pi/
|
||||
|
||||
作者:[Chinmay][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/chinmay/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.raspberrypi.org/
|
||||
[2]: https://www.raspberrypi.org/downloads/
|
||||
[3]: https://itsfoss.com/tutorial-how-to-install-raspberry-pi-os-raspbian-wheezy/
|
||||
[4]: https://www.debian.org/
|
||||
[5]: https://ubuntu-mate.org/
|
||||
[6]: https://wiki.ubuntu.com/ARM/RaspberryPi#Recovering_a_system_using_the_generic_kernel
|
||||
[7]: https://ubuntu-pi-flavour-maker.org/download/
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/ubuntu-mate-raspberry-pi-download.jpg?ssl=1
|
||||
[9]: https://ubuntu-mate.org/download/
|
||||
[10]: https://www.7-zip.org/download.html
|
||||
[11]: https://www.balena.io/etcher/
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/Screenshot-from-2019-04-08-01-36-16.png?ssl=1
|
||||
[13]: https://linuxhandbook.com/raspberry-pi-headless-setup/
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/Keyboard-layout-ubuntu.jpg?fit=800%2C467&ssl=1
|
||||
[15]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/select-time-zone-ubuntu.jpg?fit=800%2C468&ssl=1
|
||||
[16]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/Credentials-ubuntu.jpg?fit=800%2C469&ssl=1
|
||||
[17]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/Desktop-ubuntu.jpg?fit=800%2C600&ssl=1
|
||||
[18]: https://itsfoss.com/update-ubuntu/
|
||||
[19]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/update-software.png?ssl=1
|
||||
|
||||
|
@ -0,0 +1,317 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10823-1.html)
|
||||
[#]: subject: (12 Single Board Computers: Alternative to Raspberry Pi)
|
||||
[#]: via: (https://itsfoss.com/raspberry-pi-alternatives/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
12 个可替代树莓派的单板机
|
||||
================================
|
||||
|
||||
> 正在寻找树莓派的替代品?这里有一些单板机可以满足你的 DIY 渴求。
|
||||
|
||||
树莓派是当前最流行的单板机。你可以在你的 DIY 项目中使用它,或者用它作为一个成本效益高的系统来学习编代码,或者为了你的便利,利用一个[流媒体软件][1]运行在上面作为流媒体设备。
|
||||
|
||||
你可以使用树莓派做很多事,但它不是各种极客的最终解决方案。一些人可能在寻找更便宜的开发板,一些可能在寻找更强大的。
|
||||
|
||||
无论是哪种情况,我们都有很多原因需要树莓派的替代品。因此,在这片文章里,我们将讨论最好的 12 个我们认为能够替代树莓派的单板机。
|
||||
|
||||
![][2]
|
||||
|
||||
### 满足你 DIY 渴望的树莓派替代品
|
||||
|
||||
这个列表没有特定的顺序排名。链接的一部分是赞助链接。请阅读我们的[赞助政策][3]。
|
||||
|
||||
#### 1、Onion Omega2+
|
||||
|
||||
![][4]
|
||||
|
||||
只要 $13,Omega2+ 是这里你可以找到的最便宜的 IoT 单板机设备。它运行 LEDE(Linux 嵌入式开发环境)Linux 系统 —— 这是一个基于 [OpenWRT][5] 的发行版。
|
||||
|
||||
由于运行一个自定义 Linux 系统,它的组成元件、花费和灵活性使它完美适合几乎所有类型的 IoT 应用。
|
||||
|
||||
你可以在[亚马逊商城的 Onion Omega 套件][6]或者从他们的网站下单,可能会收取额外的邮费。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* MT7688 SoC
|
||||
* 2.4 GHz IEEE 802.11 b/g/n WiFi
|
||||
* 128 MB DDR2 RAM
|
||||
* 32 MB on-board flash storage
|
||||
* MicroSD Slot
|
||||
* USB 2.0
|
||||
* 12 GPIO Pins
|
||||
|
||||
[查看官网][7]
|
||||
|
||||
#### 2、NVIDIA Jetson Nano Developer Kit
|
||||
|
||||
这是来自 NVIDIA 的只要 **$99** 的非常独特和有趣的树莓派替代品。是的,它不是每个人都能充分利用的设备 —— 只为特定的一组极客或者开发者而生。
|
||||
|
||||
NVIDIA 使用下面的用例解释它:
|
||||
|
||||
> NVIDIA® Jetson Nano™ Developer Kit 是一个小的、强大的计算机,可以让你并行运行多个神经网络的应用像图像分类、对象侦察、图像分段、语音处理。全部在一个易于使用的、运行功率只有 5 瓦特的平台上。
|
||||
>
|
||||
> nvidia
|
||||
|
||||
因此,基本上,如果你正在研究 AI 或者深度学习,你可以充分利用开发设备。如果你很好奇,该设备的产品计算模块将在 2019 年 7 月到来。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* CPU: Quad-core ARM A57 @ 1.43 GHz
|
||||
* GPU: 128-core Maxwell
|
||||
* RAM: 4 GB 64-bit LPDDR4 25.6 GB/s
|
||||
* Display: HDMI 2.0
|
||||
* 4 x USB 3.0 and eDP 1.4
|
||||
|
||||
[查看官网][9]
|
||||
|
||||
#### 3、ASUS Tinker Board S
|
||||
|
||||
![][10]
|
||||
|
||||
ASUS Tinker Board S 不是大多数人可负担得起的树莓派的替换设备 (**$82**,[亚马逊商城][11]),但是它是一个强大的替代品。它的特点是它有你通常可以发现与标准树莓派 3 一样的 40 针脚的连接器,但是提供了强大的处理器和 GPU。同样的,Tinker Board S 的大小恰巧和标准的树莓派3 一样大。
|
||||
|
||||
这个板子的主要亮点是 16 GB [eMMC][12] (用外行术语说,它的板上有一个类似 SSD 的存储单元使它工作时运行的更快。) 的存在。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Rockchip Quad-Core RK3288 processor
|
||||
* 2 GB DDR3 RAM
|
||||
* Integrated Graphics Processor
|
||||
* ARM® Mali™-T764 GPU
|
||||
* 16 GB eMMC
|
||||
* MicroSD Card Slot
|
||||
* 802.11 b/g/n, Bluetooth V4.0 + EDR
|
||||
* USB 2.0
|
||||
* 28 GPIO pins
|
||||
* HDMI Interface
|
||||
|
||||
[查看网站][13]
|
||||
|
||||
#### 4、ClockworkPi
|
||||
|
||||
![][14]
|
||||
|
||||
如果你正在想方设法组装一个模块化的复古的游戏控制台,Clockwork Pi 可能就是你需要的,它通常是 [GameShell Kit][15] 的一部分。然而,你可以 使用 $49 单独购买板子。
|
||||
|
||||
它紧凑的大小、WiFi 连接性和 micro HDMI 端口的存在使它成为许多方面的选择。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Allwinner R16-J Quad-core Cortex-A7 CPU @1.2GHz
|
||||
* Mali-400 MP2 GPU
|
||||
* RAM: 1GB DDR3
|
||||
* WiFi & Bluetooth v4.0
|
||||
* Micro HDMI output
|
||||
* MicroSD Card Slot
|
||||
|
||||
[查看官网][16]
|
||||
|
||||
#### 5、Arduino Mega 2560
|
||||
|
||||
![][17]
|
||||
|
||||
如果你正在研究机器人项目或者你想要一个 3D 打印机 —— Arduino Mega 2560 将是树莓派的便利的替代品。不像树莓派,它是基于微控制器而不是微处理器的。
|
||||
|
||||
在他们的[官网][18],你需要花费 $38.50,或者在[在亚马逊商城是 $33][19]。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Microcontroller: ATmega2560
|
||||
* Clock Speed: 16 MHz
|
||||
* Digital I/O Pins: 54
|
||||
* Analog Input Pins: 16
|
||||
* Flash Memory: 256 KB of which 8 KB used by bootloader
|
||||
|
||||
[查看官网][18]
|
||||
|
||||
#### 6、Rock64 Media Board
|
||||
|
||||
![][20]
|
||||
|
||||
用与你可能想要的树莓派 3 B+ 相同的价格,你将在 Rock64 Media Board 上获得更快的处理器和双倍的内存。除此之外,如果你想要 1 GB RAM 版的,它提供了一个比树莓派更便宜的替代品,花费更少,只要 $10 。
|
||||
|
||||
不像树莓派,它没有无线连接支持,但是 USB 3.0 和 HDMI 2.0 的存在使它与众不同,如果它对你很重要的话。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Rockchip RK3328 Quad-Core ARM Cortex A53 64-Bit Processor
|
||||
* Supports up to 4GB 1600MHz LPDDR3 RAM
|
||||
* eMMC module socket
|
||||
* MicroSD Card slot
|
||||
* USB 3.0
|
||||
* HDMI 2.0
|
||||
|
||||
[查看官网][21]
|
||||
|
||||
#### 7、Odroid-XU4
|
||||
|
||||
![][22]
|
||||
|
||||
Odroid-XU4 是一个完美的树莓派的替代品,如果你有能够稍微提高预算的空间($80-$100 甚至更低,取决于存储的容量)。
|
||||
|
||||
它确实是一个强大的替代品并且体积更小。支持 eMMC 和 USB 3.0 使它工作起来更快。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Samsung Exynos 5422 Octa ARM Cortex™-A15 Quad 2Ghz and Cortex™-A7 Quad 1.3GHz CPUs
|
||||
* 2Gbyte LPDDR3 RAM
|
||||
* GPU: Mali-T628 MP6
|
||||
* USB 3.0
|
||||
* HDMI 1.4a
|
||||
* eMMC 5.0 module socket
|
||||
* MicroSD Card Slot
|
||||
|
||||
[查看官网][23]
|
||||
|
||||
#### 8、PocketBeagle
|
||||
|
||||
![][24]
|
||||
|
||||
它是一个难以置信的小的单板机 —— 几乎和树莓派Zero 相似。然而它的价格相当于完整大小的树莓派 3。主要的亮点是你可以用它作为一个 USB 便携式信息终端,并且进入 Linux 命令行工作。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Processor: Octavo Systems OSD3358 1GHz ARM® Cortex-A8
|
||||
* RAM: 512 MB DDR3
|
||||
* 72 expansion pin headers
|
||||
* microUSB
|
||||
* USB 2.0
|
||||
|
||||
[查看官网][25]
|
||||
|
||||
#### 9、Le Potato
|
||||
|
||||
![][26]
|
||||
|
||||
由 [Libre Computer][27] 出品的 Le Potato,其型号是 AML-S905X-CC。它需要花费你 [$45][28]。
|
||||
|
||||
如果你花费的比树莓派更多的钱,你就能得到双倍内存和 HDMI 2.0 接口,这可能是一个完美的选择。尽管,你还是不能找到嵌入的无线连接。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Amlogic S905X SoC
|
||||
* 2GB DDR3 SDRAM
|
||||
* USB 2.0
|
||||
* HDMI 2.0
|
||||
* microUSB
|
||||
* MicroSD Card Slot
|
||||
* eMMC Interface
|
||||
|
||||
[查看官网][29]
|
||||
|
||||
#### 10、Banana Pi M64
|
||||
|
||||
![][30]
|
||||
|
||||
它自带了 8G 的 eMMC —— 这是替代树莓派的主要亮点。因此,它需要花费 $60。
|
||||
|
||||
HDMI 接口的存在使它胜任 4K。除此之外,Banana Pi 提供了更多种类的开源单板机作为树莓派的替代。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* 1.2 Ghz Quad-Core ARM Cortex A53 64-Bit Processor-R18
|
||||
* 2GB DDR3 SDRAM
|
||||
* 8 GB eMMC
|
||||
* WiFi & Bluetooth
|
||||
* USB 2.0
|
||||
* HDMI
|
||||
|
||||
[查看官网][31]
|
||||
|
||||
#### 11、Orange Pi Zero
|
||||
|
||||
![][32]
|
||||
|
||||
Orange Pi Zero 相对于树莓派来说难以置信的便宜。你可以在 Aliexpress 或者亚马逊上以最多 $10 就能够获得。如果[稍微多花点,你能够获得 512 MB RAM][33]。
|
||||
|
||||
如果这还不够,你可以花费大概 $25 获得更好的配置,比如 Orange Pi 3。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* H2 Quad-core Cortex-A7
|
||||
* Mali400MP2 GPU
|
||||
* RAM: Up to 512 MB
|
||||
* TF Card support
|
||||
* WiFi
|
||||
* USB 2.0
|
||||
|
||||
[查看官网][34]
|
||||
|
||||
#### 12、VIM 2 SBC by Khadas
|
||||
|
||||
![][35]
|
||||
|
||||
由 Khadas 出品的 VIM 2 是最新的单板机,因此你能够在板上得到蓝牙 5.0 支持。它的价格范围[从 $99 的基础款到上限 $140][36]。
|
||||
|
||||
基础款包含 2 GB RAM、16 GB eMMC 和蓝牙 4.1。然而,Pro/Max 版包含蓝牙 5.0,更多的内存,更多的 eMMC 存储。
|
||||
|
||||
**关键参数:**
|
||||
|
||||
* Amlogic S912 1.5GHz 64-bit Octa-Core CPU
|
||||
* T820MP3 GPU
|
||||
* Up to 3 GB DDR4 RAM
|
||||
* Up to 64 GB eMMC
|
||||
* Bluetooth 5.0 (Pro/Max)
|
||||
* Bluetooth 4.1 (Basic)
|
||||
* HDMI 2.0a
|
||||
* WiFi
|
||||
|
||||
### 总结
|
||||
|
||||
我们知道有很多不同种类的单板机电脑。一些比树莓派更好 —— 它的一些小规格的版本有更便宜的价格。同样的,像 Jetson Nano 这样的单板机已经被裁剪用于特定用途。因此,取决于你需要什么 —— 你应该检查一下单板机的配置。
|
||||
|
||||
如果你知道比上述提到的更好的东西,请随意在下方评论来让我们知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/raspberry-pi-alternatives/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[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/best-linux-media-server/
|
||||
[2]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/raspberry-pi-alternatives.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/affiliate-policy/
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/omega-2-plus-e1555306748755-800x444.jpg?resize=800%2C444&ssl=1
|
||||
[5]: https://openwrt.org/
|
||||
[6]: https://amzn.to/2Xj8pkn
|
||||
[7]: https://onion.io/store/omega2p/
|
||||
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/Jetson-Nano-e1555306350976-800x590.jpg?resize=800%2C590&ssl=1
|
||||
[9]: https://developer.nvidia.com/embedded/buy/jetson-nano-devkit
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/asus-tinker-board-s-e1555304945760-800x450.jpg?resize=800%2C450&ssl=1
|
||||
[11]: https://amzn.to/2XfkOFT
|
||||
[12]: https://en.wikipedia.org/wiki/MultiMediaCard
|
||||
[13]: https://www.asus.com/in/Single-Board-Computer/Tinker-Board-S/
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/clockwork-pi-e1555305016242-800x506.jpg?resize=800%2C506&ssl=1
|
||||
[15]: https://itsfoss.com/gameshell-console/
|
||||
[16]: https://www.clockworkpi.com/product-page/cpi-v3-1
|
||||
[17]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/arduino-mega-2560-e1555305257633.jpg?ssl=1
|
||||
[18]: https://store.arduino.cc/usa/mega-2560-r3
|
||||
[19]: https://amzn.to/2KCi041
|
||||
[20]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/ROCK64_board-e1555306092845-800x440.jpg?resize=800%2C440&ssl=1
|
||||
[21]: https://www.pine64.org/?product=rock64-media-board-computer
|
||||
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/odroid-xu4.jpg?fit=800%2C354&ssl=1
|
||||
[23]: https://www.hardkernel.com/shop/odroid-xu4-special-price/
|
||||
[24]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/PocketBeagle.jpg?fit=800%2C450&ssl=1
|
||||
[25]: https://beagleboard.org/p/products/pocketbeagle
|
||||
[26]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/04/aml-libre.-e1555306237972-800x514.jpg?resize=800%2C514&ssl=1
|
||||
[27]: https://libre.computer/
|
||||
[28]: https://amzn.to/2DpG3xl
|
||||
[29]: https://libre.computer/products/boards/aml-s905x-cc/
|
||||
[30]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/banana-pi-m6.jpg?fit=800%2C389&ssl=1
|
||||
[31]: http://www.banana-pi.org/m64.html
|
||||
[32]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/04/orange-pi-zero.jpg?fit=800%2C693&ssl=1
|
||||
[33]: https://amzn.to/2IlI81g
|
||||
[34]: http://www.orangepi.org/orangepizero/index.html
|
||||
[35]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/04/khadas-vim-2-e1555306505640-800x563.jpg?resize=800%2C563&ssl=1
|
||||
[36]: https://amzn.to/2UDvrFE
|
@ -0,0 +1,283 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (bodhix)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10844-1.html)
|
||||
[#]: subject: (How To Enable (UP) And Disable (DOWN) A Network Interface Port (NIC) In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/enable-disable-up-down-nic-network-interface-port-linux-using-ifconfig-ifdown-ifup-ip-nmcli-nmtui/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
Linux 中如何启用和禁用网卡?
|
||||
======
|
||||
|
||||
你可能会根据你的需要执行以下命令。我会在这里列举一些你会用到这些命令的例子。
|
||||
|
||||
当你添加一个网卡或者从一个物理网卡创建出一个虚拟网卡的时候,你可能需要使用这些命令将新网卡启用起来。另外,如果你对网卡做了某些修改或者网卡本身没有启用,那么你也需要使用以下的某个命令将网卡启用起来。
|
||||
|
||||
启用、禁用网卡有很多种方法。在这篇文章里,我们会介绍我们使用过的最好的 5 种方法。
|
||||
|
||||
启用禁用网卡可以使用以下 5 个方法来完成:
|
||||
|
||||
* `ifconfig` 命令:用于配置网卡。它可以提供网卡的很多信息。
|
||||
* `ifdown/up` 命令:`ifdown` 命令用于禁用网卡,`ifup` 命令用于启用网卡。
|
||||
* `ip` 命令:用于管理网卡,用于替代老旧的、不推荐使用的 `ifconfig` 命令。它和 `ifconfig` 命令很相似,但是提供了很多 `ifconfig` 命令所不具有的强大的特性。
|
||||
* `nmcli` 命令:是一个控制 NetworkManager 并报告网络状态的命令行工具。
|
||||
* `nmtui` 命令:是一个与 NetworkManager 交互的、基于 curses 图形库的终端 UI 应用。
|
||||
|
||||
以下显示的是我的 Linux 系统中可用网卡的信息。
|
||||
|
||||
```
|
||||
# ip a
|
||||
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||
inet 127.0.0.1/8 scope host lo
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 ::1/128 scope host
|
||||
valid_lft forever preferred_lft forever
|
||||
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:c2:e4:e8 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s3
|
||||
valid_lft 86049sec preferred_lft 86049sec
|
||||
inet6 fe80::3899:270f:ae38:b433/64 scope link noprefixroute
|
||||
valid_lft forever preferred_lft forever
|
||||
3: enp0s8: mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:30:5d:52 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.3/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s8
|
||||
valid_lft 86049sec preferred_lft 86049sec
|
||||
inet6 fe80::32b7:8727:bdf2:2f3/64 scope link noprefixroute
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
### 1、如何使用 ifconfig 命令启用禁用网卡?
|
||||
|
||||
`ifconfig` 命令用于配置网卡。
|
||||
|
||||
在系统启动过程中如果需要启用网卡,调用的命令就是 `ifconfig`。`ifconfig` 可以提供很多网卡的信息。不管我们想修改网卡的什么配置,都可以使用该命令。
|
||||
|
||||
`ifconfig` 的常用语法:
|
||||
|
||||
```
|
||||
# ifconfig [NIC_NAME] Down/Up
|
||||
```
|
||||
|
||||
执行以下命令禁用 `enp0s3` 网卡。注意,这里你需要输入你自己的网卡名字。
|
||||
|
||||
```
|
||||
# ifconfig enp0s3 down
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经被禁用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 1 "enp0s3:"
|
||||
2: enp0s3: mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
|
||||
link/ether 08:00:27:c2:e4:e8 brd ff:ff:ff:ff:ff:ff
|
||||
```
|
||||
|
||||
执行以下命令启用 `enp0s3` 网卡。
|
||||
|
||||
```
|
||||
# ifconfig enp0s3 up
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经启用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 5 "enp0s3:"
|
||||
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:c2:e4:e8 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s3
|
||||
valid_lft 86294sec preferred_lft 86294sec
|
||||
inet6 fe80::3899:270f:ae38:b433/64 scope link noprefixroute
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
### 2、如何使用 ifdown/up 命令启用禁用网卡?
|
||||
|
||||
`ifdown` 命令用于禁用网卡,`ifup` 命令用于启用网卡。
|
||||
|
||||
注意:这两个命令不支持以 `enpXXX` 命名的新的网络设备。
|
||||
|
||||
`ifdown`/`ifup` 的常用语法:
|
||||
|
||||
```
|
||||
# ifdown [NIC_NAME]
|
||||
# ifup [NIC_NAME]
|
||||
```
|
||||
|
||||
执行以下命令禁用 `eth1` 网卡。
|
||||
|
||||
```
|
||||
# ifdown eth1
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经被禁用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 3 "eth1:"
|
||||
3: eth1: mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
|
||||
link/ether 08:00:27:d5:a0:18 brd ff:ff:ff:ff:ff:ff
|
||||
```
|
||||
|
||||
执行以下命令启用 `eth1` 网卡。
|
||||
|
||||
```
|
||||
# ifup eth1
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经启用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 5 "eth1:"
|
||||
3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
|
||||
link/ether 08:00:27:d5:a0:18 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.7/24 brd 192.168.1.255 scope global eth1
|
||||
inet6 fe80::a00:27ff:fed5:a018/64 scope link tentative dadfailed
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
`ifup` 和 `ifdown` 不支持以 `enpXXX` 命名的网卡。当执行该命令时得到的结果如下:
|
||||
|
||||
```
|
||||
# ifdown enp0s8
|
||||
Unknown interface enp0s8
|
||||
```
|
||||
|
||||
### 3、如何使用 ip 命令启用禁用网卡?
|
||||
|
||||
`ip` 命令用于管理网卡,用于替代老旧的、不推荐使用的 `ifconfig` 命令。
|
||||
|
||||
它和 `ifconfig` 命令很相似,但是提供了很多 `ifconfig` 命令不具有的强大的特性。
|
||||
|
||||
`ip` 的常用语法:
|
||||
|
||||
```
|
||||
# ip link set Down/Up
|
||||
```
|
||||
|
||||
执行以下命令禁用 `enp0s3` 网卡。
|
||||
|
||||
```
|
||||
# ip link set enp0s3 down
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经被禁用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 1 "enp0s3:"
|
||||
2: enp0s3: mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
|
||||
link/ether 08:00:27:c2:e4:e8 brd ff:ff:ff:ff:ff:ff
|
||||
```
|
||||
|
||||
执行以下命令启用 `enp0s3` 网卡。
|
||||
|
||||
```
|
||||
# ip link set enp0s3 up
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经启用了。
|
||||
|
||||
```
|
||||
# ip a | grep -A 5 "enp0s3:"
|
||||
2: enp0s3: mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 08:00:27:c2:e4:e8 brd ff:ff:ff:ff:ff:ff
|
||||
inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s3
|
||||
valid_lft 86294sec preferred_lft 86294sec
|
||||
inet6 fe80::3899:270f:ae38:b433/64 scope link noprefixroute
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
### 4、如何使用 nmcli 命令启用禁用网卡?
|
||||
|
||||
`nmcli` 是一个控制 NetworkManager 并报告网络状态的命令行工具。
|
||||
|
||||
`nmcli` 可以用做 nm-applet 或者其他图形化客户端的替代品。它可以用于展示、创建、修改、删除、启用和停用网络连接。除此之后,它还可以用来管理和展示网络设备状态。
|
||||
|
||||
`nmcli` 命令大部分情况下都是使用“配置名称”工作而不是“设备名称”。所以,执行以下命令,获取网卡对应的配置名称。(LCTT 译注:在使用 `nmtui` 或者 `nmcli` 管理网络连接的时候,可以为网络连接配置一个名称,就是这里提到的<ruby>配置名称<rt>Profile name</rt></ruby>`)
|
||||
|
||||
```
|
||||
# nmcli con show
|
||||
NAME UUID TYPE DEVICE
|
||||
Wired connection 1 3d5afa0a-419a-3d1a-93e6-889ce9c6a18c ethernet enp0s3
|
||||
Wired connection 2 a22154b7-4cc4-3756-9d8d-da5a4318e146 ethernet enp0s8
|
||||
```
|
||||
|
||||
`nmcli` 的常用语法:
|
||||
|
||||
```
|
||||
# nmcli con Down/Up
|
||||
```
|
||||
|
||||
执行以下命令禁用 `enp0s3` 网卡。在禁用网卡的时候,你需要使用配置名称而不是设备名称。
|
||||
|
||||
```
|
||||
# nmcli con down 'Wired connection 1'
|
||||
Connection 'Wired connection 1' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经禁用了。
|
||||
|
||||
```
|
||||
# nmcli dev status
|
||||
DEVICE TYPE STATE CONNECTION
|
||||
enp0s8 ethernet connected Wired connection 2
|
||||
enp0s3 ethernet disconnected --
|
||||
lo loopback unmanaged --
|
||||
```
|
||||
|
||||
执行以下命令启用 `enp0s3` 网卡。同样的,这里你需要使用配置名称而不是设备名称。
|
||||
|
||||
```
|
||||
# nmcli con up 'Wired connection 1'
|
||||
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7)
|
||||
```
|
||||
|
||||
从以下输出结果可以看到网卡已经启用了。
|
||||
|
||||
```
|
||||
# nmcli dev status
|
||||
DEVICE TYPE STATE CONNECTION
|
||||
enp0s8 ethernet connected Wired connection 2
|
||||
enp0s3 ethernet connected Wired connection 1
|
||||
lo loopback unmanaged --
|
||||
```
|
||||
|
||||
### 5、如何使用 nmtui 命令启用禁用网卡?
|
||||
|
||||
`nmtui` 是一个与 NetworkManager 交互的、基于 curses 图形库的终端 UI 应用。
|
||||
|
||||
在启用 `nmtui` 的时候,如果第一个参数没有特别指定,它会引导用户选择对应的操作去执行。
|
||||
|
||||
执行以下命令打开 `mntui` 界面。选择 “Active a connection” 然后点击 “OK”。
|
||||
|
||||
```
|
||||
# nmtui
|
||||
```
|
||||
|
||||
![][2]
|
||||
|
||||
选择你要禁用的网卡,然后点击 “Deactivate” 按钮,就可以将网卡禁用。
|
||||
|
||||
![][3]
|
||||
|
||||
如果要启用网卡,使用上述同样的步骤即可。
|
||||
|
||||
![][4]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/enable-disable-up-down-nic-network-interface-port-linux-using-ifconfig-ifdown-ifup-ip-nmcli-nmtui/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[bodhix](https://github.com/bodhix)
|
||||
校对:[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]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.2daygeek.com/wp-content/uploads/2019/04/enable-disable-up-down-nic-network-interface-port-linux-nmtui-1.png
|
||||
[3]: https://www.2daygeek.com/wp-content/uploads/2019/04/enable-disable-up-down-nic-network-interface-port-linux-nmtui-2.png
|
||||
[4]: https://www.2daygeek.com/wp-content/uploads/2019/04/enable-disable-up-down-nic-network-interface-port-linux-nmtui-3.png
|
@ -0,0 +1,439 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (FSSlc)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10826-1.html)
|
||||
[#]: subject: (Inter-process communication in Linux: Shared storage)
|
||||
[#]: via: (https://opensource.com/article/19/4/interprocess-communication-linux-storage)
|
||||
[#]: author: (Marty Kalin https://opensource.com/users/mkalindepauledu)
|
||||
|
||||
Linux 下的进程间通信:共享存储
|
||||
======
|
||||
|
||||
> 学习在 Linux 中进程是如何与其他进程进行同步的。
|
||||
|
||||
![Filing papers and documents][1]
|
||||
|
||||
本篇是 Linux 下[进程间通信][2](IPC)系列的第一篇文章。这个系列将使用 C 语言代码示例来阐明以下 IPC 机制:
|
||||
|
||||
* 共享文件
|
||||
* 共享内存(使用信号量)
|
||||
* 管道(命名的或非命名的管道)
|
||||
* 消息队列
|
||||
* 套接字
|
||||
* 信号
|
||||
|
||||
在聚焦上面提到的共享文件和共享内存这两个机制之前,这篇文章将带你回顾一些核心的概念。
|
||||
|
||||
### 核心概念
|
||||
|
||||
*进程*是运行着的程序,每个进程都有着它自己的地址空间,这些空间由进程被允许访问的内存地址组成。进程有一个或多个执行*线程*,而线程是一系列执行指令的集合:*单线程*进程就只有一个线程,而*多线程*的进程则有多个线程。一个进程中的线程共享各种资源,特别是地址空间。另外,一个进程中的线程可以直接通过共享内存来进行通信,尽管某些现代语言(例如 Go)鼓励一种更有序的方式,例如使用线程安全的通道。当然对于不同的进程,默认情况下,它们**不**能共享内存。
|
||||
|
||||
有多种方法启动之后要进行通信的进程,下面所举的例子中主要使用了下面的两种方法:
|
||||
|
||||
* 一个终端被用来启动一个进程,另外一个不同的终端被用来启动另一个。
|
||||
* 在一个进程(父进程)中调用系统函数 `fork`,以此生发另一个进程(子进程)。
|
||||
|
||||
第一个例子采用了上面使用终端的方法。这些[代码示例][3]的 ZIP 压缩包可以从我的网站下载到。
|
||||
|
||||
### 共享文件
|
||||
|
||||
程序员对文件访问应该都已经很熟识了,包括许多坑(不存在的文件、文件权限损坏等等),这些问题困扰着程序对文件的使用。尽管如此,共享文件可能是最为基础的 IPC 机制了。考虑一下下面这样一个相对简单的例子,其中一个进程(生产者 `producer`)创建和写入一个文件,然后另一个进程(消费者 `consumer `)从这个相同的文件中进行读取:
|
||||
|
||||
```
|
||||
writes +-----------+ reads
|
||||
producer-------->| disk file |<-------consumer
|
||||
+-----------+
|
||||
```
|
||||
|
||||
在使用这个 IPC 机制时最明显的挑战是*竞争条件*可能会发生:生产者和消费者可能恰好在同一时间访问该文件,从而使得输出结果不确定。为了避免竞争条件的发生,该文件在处于*读*或*写*状态时必须以某种方式处于被锁状态,从而阻止在*写*操作执行时和其他操作的冲突。在标准系统库中与锁相关的 API 可以被总结如下:
|
||||
|
||||
* 生产者应该在写入文件时获得一个文件的排斥锁。一个*排斥*锁最多被一个进程所拥有。这样就可以排除掉竞争条件的发生,因为在锁被释放之前没有其他的进程可以访问这个文件。
|
||||
* 消费者应该在从文件中读取内容时得到至少一个共享锁。多个*读取者*可以同时保有一个*共享*锁,但是没有*写入者*可以获取到文件内容,甚至在当只有一个*读取者*保有一个共享锁时。
|
||||
|
||||
共享锁可以提升效率。假如一个进程只是读入一个文件的内容,而不去改变它的内容,就没有什么原因阻止其他进程来做同样的事。但如果需要写入内容,则很显然需要文件有排斥锁。
|
||||
|
||||
标准的 I/O 库中包含一个名为 `fcntl` 的实用函数,它可以被用来检查或者操作一个文件上的排斥锁和共享锁。该函数通过一个*文件描述符*(一个在进程中的非负整数值)来标记一个文件(在不同的进程中不同的文件描述符可能标记同一个物理文件)。对于文件的锁定, Linux 提供了名为 `flock` 的库函数,它是 `fcntl` 的一个精简包装。第一个例子中使用 `fcntl` 函数来暴露这些 API 细节。
|
||||
|
||||
#### 示例 1. 生产者程序
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FileName "data.dat"
|
||||
#define DataString "Now is the winter of our discontent\nMade glorious summer by this sun of York\n"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1); /* EXIT_FAILURE */
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct flock lock;
|
||||
lock.l_type = F_WRLCK; /* read/write (exclusive versus shared) lock */
|
||||
lock.l_whence = SEEK_SET; /* base for seek offsets */
|
||||
lock.l_start = 0; /* 1st byte in file */
|
||||
lock.l_len = 0; /* 0 here means 'until EOF' */
|
||||
lock.l_pid = getpid(); /* process id */
|
||||
|
||||
int fd; /* file descriptor to identify a file within a process */
|
||||
if ((fd = open(FileName, O_RDWR | O_CREAT, 0666)) < 0) /* -1 signals an error */
|
||||
report_and_exit("open failed...");
|
||||
|
||||
if (fcntl(fd, F_SETLK, &lock) < 0) /** F_SETLK doesn't block, F_SETLKW does **/
|
||||
report_and_exit("fcntl failed to get lock...");
|
||||
else {
|
||||
write(fd, DataString, strlen(DataString)); /* populate data file */
|
||||
fprintf(stderr, "Process %d has written to data file...\n", lock.l_pid);
|
||||
}
|
||||
|
||||
/* Now release the lock explicitly. */
|
||||
lock.l_type = F_UNLCK;
|
||||
if (fcntl(fd, F_SETLK, &lock) < 0)
|
||||
report_and_exit("explicit unlocking failed...");
|
||||
|
||||
close(fd); /* close the file: would unlock if needed */
|
||||
return 0; /* terminating the process would unlock as well */
|
||||
}
|
||||
```
|
||||
|
||||
上面生产者程序的主要步骤可以总结如下:
|
||||
|
||||
* 这个程序首先声明了一个类型为 `struct flock` 的变量,它代表一个锁,并对它的 5 个域做了初始化。第一个初始化
|
||||
|
||||
```c
|
||||
lock.l_type = F_WRLCK; /* exclusive lock */
|
||||
```
|
||||
使得这个锁为排斥锁(read-write)而不是一个共享锁(read-only)。假如生产者获得了这个锁,则其他的进程将不能够对文件做读或者写操作,直到生产者释放了这个锁,或者显式地调用 `fcntl`,又或者隐式地关闭这个文件。(当进程终止时,所有被它打开的文件都会被自动关闭,从而释放了锁)
|
||||
* 上面的程序接着初始化其他的域。主要的效果是*整个*文件都将被锁上。但是,有关锁的 API 允许特别指定的字节被上锁。例如,假如文件包含多个文本记录,则单个记录(或者甚至一个记录的一部分)可以被锁,而其余部分不被锁。
|
||||
* 第一次调用 `fcntl`
|
||||
|
||||
```c
|
||||
if (fcntl(fd, F_SETLK, &lock) < 0)
|
||||
```
|
||||
尝试排斥性地将文件锁住,并检查调用是否成功。一般来说, `fcntl` 函数返回 `-1` (因此小于 0)意味着失败。第二个参数 `F_SETLK` 意味着 `fcntl` 的调用*不是*堵塞的;函数立即做返回,要么获得锁,要么显示失败了。假如替换地使用 `F_SETLKW`(末尾的 `W` 代指*等待*),那么对 `fcntl` 的调用将是阻塞的,直到有可能获得锁的时候。在调用 `fcntl` 函数时,它的第一个参数 `fd` 指的是文件描述符,第二个参数指定了将要采取的动作(在这个例子中,`F_SETLK` 指代设置锁),第三个参数为锁结构的地址(在本例中,指的是 `&lock`)。
|
||||
* 假如生产者获得了锁,这个程序将向文件写入两个文本记录。
|
||||
* 在向文件写入内容后,生产者改变锁结构中的 `l_type` 域为 `unlock` 值:
|
||||
|
||||
```c
|
||||
lock.l_type = F_UNLCK;
|
||||
```
|
||||
并调用 `fcntl` 来执行解锁操作。最后程序关闭了文件并退出。
|
||||
|
||||
#### 示例 2. 消费者程序
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FileName "data.dat"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1); /* EXIT_FAILURE */
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct flock lock;
|
||||
lock.l_type = F_WRLCK; /* read/write (exclusive) lock */
|
||||
lock.l_whence = SEEK_SET; /* base for seek offsets */
|
||||
lock.l_start = 0; /* 1st byte in file */
|
||||
lock.l_len = 0; /* 0 here means 'until EOF' */
|
||||
lock.l_pid = getpid(); /* process id */
|
||||
|
||||
int fd; /* file descriptor to identify a file within a process */
|
||||
if ((fd = open(FileName, O_RDONLY)) < 0) /* -1 signals an error */
|
||||
report_and_exit("open to read failed...");
|
||||
|
||||
/* If the file is write-locked, we can't continue. */
|
||||
fcntl(fd, F_GETLK, &lock); /* sets lock.l_type to F_UNLCK if no write lock */
|
||||
if (lock.l_type != F_UNLCK)
|
||||
report_and_exit("file is still write locked...");
|
||||
|
||||
lock.l_type = F_RDLCK; /* prevents any writing during the reading */
|
||||
if (fcntl(fd, F_SETLK, &lock) < 0)
|
||||
report_and_exit("can't get a read-only lock...");
|
||||
|
||||
/* Read the bytes (they happen to be ASCII codes) one at a time. */
|
||||
int c; /* buffer for read bytes */
|
||||
while (read(fd, &c, 1) > 0) /* 0 signals EOF */
|
||||
write(STDOUT_FILENO, &c, 1); /* write one byte to the standard output */
|
||||
|
||||
/* Release the lock explicitly. */
|
||||
lock.l_type = F_UNLCK;
|
||||
if (fcntl(fd, F_SETLK, &lock) < 0)
|
||||
report_and_exit("explicit unlocking failed...");
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
相比于锁的 API,消费者程序会相对复杂一点儿。特别的,消费者程序首先检查文件是否被排斥性的被锁,然后才尝试去获得一个共享锁。相关的代码为:
|
||||
|
||||
```
|
||||
lock.l_type = F_WRLCK;
|
||||
...
|
||||
fcntl(fd, F_GETLK, &lock); /* sets lock.l_type to F_UNLCK if no write lock */
|
||||
if (lock.l_type != F_UNLCK)
|
||||
report_and_exit("file is still write locked...");
|
||||
```
|
||||
|
||||
在 `fcntl` 调用中的 `F_GETLK` 操作指定检查一个锁,在本例中,上面代码的声明中给了一个 `F_WRLCK` 的排斥锁。假如特指的锁不存在,那么 `fcntl` 调用将会自动地改变锁类型域为 `F_UNLCK` 以此来显示当前的状态。假如文件是排斥性地被锁,那么消费者将会终止。(一个更健壮的程序版本或许应该让消费者*睡*会儿,然后再尝试几次。)
|
||||
|
||||
假如当前文件没有被锁,那么消费者将尝试获取一个共享(read-only)锁(`F_RDLCK`)。为了缩短程序,`fcntl` 中的 `F_GETLK` 调用可以丢弃,因为假如其他进程已经保有一个读写锁,`F_RDLCK` 的调用就可能会失败。重新调用一个只读锁能够阻止其他进程向文件进行写的操作,但可以允许其他进程对文件进行读取。简而言之,共享锁可以被多个进程所保有。在获取了一个共享锁后,消费者程序将立即从文件中读取字节数据,然后在标准输出中打印这些字节的内容,接着释放锁,关闭文件并终止。
|
||||
|
||||
下面的 `%` 为命令行提示符,下面展示的是从相同终端开启这两个程序的输出:
|
||||
|
||||
```
|
||||
% ./producer
|
||||
Process 29255 has written to data file...
|
||||
|
||||
% ./consumer
|
||||
Now is the winter of our discontent
|
||||
Made glorious summer by this sun of York
|
||||
```
|
||||
|
||||
在本次的代码示例中,通过 IPC 传输的数据是文本:它们来自莎士比亚的戏剧《理查三世》中的两行台词。然而,共享文件的内容还可以是纷繁复杂的,任意的字节数据(例如一个电影)都可以,这使得文件共享变成了一个非常灵活的 IPC 机制。但它的缺点是文件获取速度较慢,因为文件的获取涉及到读或者写。同往常一样,编程总是伴随着折中。下面的例子将通过共享内存来做 IPC,而不是通过共享文件,在性能上相应的有极大的提升。
|
||||
|
||||
### 共享内存
|
||||
|
||||
对于共享内存,Linux 系统提供了两类不同的 API:传统的 System V API 和更新一点的 POSIX API。在单个应用中,这些 API 不能混用。但是,POSIX 方式的一个坏处是它的特性仍在发展中,并且依赖于安装的内核版本,这非常影响代码的可移植性。例如,默认情况下,POSIX API 用*内存映射文件*来实现共享内存:对于一个共享的内存段,系统为相应的内容维护一个*备份文件*。在 POSIX 规范下共享内存可以被配置为不需要备份文件,但这可能会影响可移植性。我的例子中使用的是带有备份文件的 POSIX API,这既结合了内存获取的速度优势,又获得了文件存储的持久性。
|
||||
|
||||
下面的共享内存例子中包含两个程序,分别名为 `memwriter` 和 `memreader`,并使用*信号量*来调整它们对共享内存的获取。在任何时候当共享内存进入一个*写入者*场景时,无论是多进程还是多线程,都有遇到基于内存的竞争条件的风险,所以,需要引入信号量来协调(同步)对共享内存的获取。
|
||||
|
||||
`memwriter` 程序应当在它自己所处的终端首先启动,然后 `memreader` 程序才可以在它自己所处的终端启动(在接着的十几秒内)。`memreader` 的输出如下:
|
||||
|
||||
```
|
||||
This is the way the world ends...
|
||||
```
|
||||
|
||||
在每个源程序的最上方注释部分都解释了在编译它们时需要添加的链接参数。
|
||||
|
||||
首先让我们复习一下信号量是如何作为一个同步机制工作的。一般的信号量也被叫做一个*计数信号量*,因为带有一个可以增加的值(通常初始化为 0)。考虑一家租用自行车的商店,在它的库存中有 100 辆自行车,还有一个供职员用于租赁的程序。每当一辆自行车被租出去,信号量就增加 1;当一辆自行车被还回来,信号量就减 1。在信号量的值为 100 之前都还可以进行租赁业务,但如果等于 100 时,就必须停止业务,直到至少有一辆自行车被还回来,从而信号量减为 99。
|
||||
|
||||
*二元信号量*是一个特例,它只有两个值:0 和 1。在这种情况下,信号量的表现为*互斥量*(一个互斥的构造)。下面的共享内存示例将把信号量用作互斥量。当信号量的值为 0 时,只有 `memwriter` 可以获取共享内存,在写操作完成后,这个进程将增加信号量的值,从而允许 `memreader` 来读取共享内存。
|
||||
|
||||
#### 示例 3. memwriter 进程的源程序
|
||||
|
||||
```c
|
||||
/** Compilation: gcc -o memwriter memwriter.c -lrt -lpthread **/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include "shmem.h"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int fd = shm_open(BackingFile, /* name from smem.h */
|
||||
O_RDWR | O_CREAT, /* read/write, create if needed */
|
||||
AccessPerms); /* access permissions (0644) */
|
||||
if (fd < 0) report_and_exit("Can't open shared mem segment...");
|
||||
|
||||
ftruncate(fd, ByteSize); /* get the bytes */
|
||||
|
||||
caddr_t memptr = mmap(NULL, /* let system pick where to put segment */
|
||||
ByteSize, /* how many bytes */
|
||||
PROT_READ | PROT_WRITE, /* access protections */
|
||||
MAP_SHARED, /* mapping visible to other processes */
|
||||
fd, /* file descriptor */
|
||||
0); /* offset: start at 1st byte */
|
||||
if ((caddr_t) -1 == memptr) report_and_exit("Can't get segment...");
|
||||
|
||||
fprintf(stderr, "shared mem address: %p [0..%d]\n", memptr, ByteSize - 1);
|
||||
fprintf(stderr, "backing file: /dev/shm%s\n", BackingFile );
|
||||
|
||||
/* semaphore code to lock the shared mem */
|
||||
sem_t* semptr = sem_open(SemaphoreName, /* name */
|
||||
O_CREAT, /* create the semaphore */
|
||||
AccessPerms, /* protection perms */
|
||||
0); /* initial value */
|
||||
if (semptr == (void*) -1) report_and_exit("sem_open");
|
||||
|
||||
strcpy(memptr, MemContents); /* copy some ASCII bytes to the segment */
|
||||
|
||||
/* increment the semaphore so that memreader can read */
|
||||
if (sem_post(semptr) < 0) report_and_exit("sem_post");
|
||||
|
||||
sleep(12); /* give reader a chance */
|
||||
|
||||
/* clean up */
|
||||
munmap(memptr, ByteSize); /* unmap the storage */
|
||||
close(fd);
|
||||
sem_close(semptr);
|
||||
shm_unlink(BackingFile); /* unlink from the backing file */
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
下面是 `memwriter` 和 `memreader` 程序如何通过共享内存来通信的一个总结:
|
||||
|
||||
* 上面展示的 `memwriter` 程序调用 `shm_open` 函数来得到作为系统协调共享内存的备份文件的文件描述符。此时,并没有内存被分配。接下来调用的是令人误解的名为 `ftruncate` 的函数
|
||||
|
||||
```c
|
||||
ftruncate(fd, ByteSize); /* get the bytes */
|
||||
```
|
||||
它将分配 `ByteSize` 字节的内存,在该情况下,一般为大小适中的 512 字节。`memwriter` 和 `memreader` 程序都只从共享内存中获取数据,而不是从备份文件。系统将负责共享内存和备份文件之间数据的同步。
|
||||
* 接着 `memwriter` 调用 `mmap` 函数:
|
||||
|
||||
```c
|
||||
caddr_t memptr = mmap(NULL, /* let system pick where to put segment */
|
||||
ByteSize, /* how many bytes */
|
||||
PROT_READ | PROT_WRITE, /* access protections */
|
||||
MAP_SHARED, /* mapping visible to other processes */
|
||||
fd, /* file descriptor */
|
||||
0); /* offset: start at 1st byte */
|
||||
```
|
||||
来获得共享内存的指针。(`memreader` 也做一次类似的调用。) 指针类型 `caddr_t` 以 `c` 开头,它代表 `calloc`,而这是动态初始化分配的内存为 0 的一个系统函数。`memwriter` 通过库函数 `strcpy`(字符串复制)来获取后续*写*操作的 `memptr`。
|
||||
* 到现在为止,`memwriter` 已经准备好进行写操作了,但首先它要创建一个信号量来确保共享内存的排斥性。假如 `memwriter` 正在执行写操作而同时 `memreader` 在执行读操作,则有可能出现竞争条件。假如调用 `sem_open` 成功了:
|
||||
|
||||
```c
|
||||
sem_t* semptr = sem_open(SemaphoreName, /* name */
|
||||
O_CREAT, /* create the semaphore */
|
||||
AccessPerms, /* protection perms */
|
||||
0); /* initial value */
|
||||
```
|
||||
那么,接着写操作便可以执行。上面的 `SemaphoreName`(任意一个唯一的非空名称)用来在 `memwriter` 和 `memreader` 识别信号量。初始值 0 将会传递给信号量的创建者,在这个例子中指的是 `memwriter` 赋予它执行*写*操作的权利。
|
||||
* 在写操作完成后,`memwriter* 通过调用 `sem_post` 函数将信号量的值增加到 1:
|
||||
|
||||
```c
|
||||
if (sem_post(semptr) < 0) ..
|
||||
```
|
||||
增加信号了将释放互斥锁,使得 `memreader` 可以执行它的*读*操作。为了更好地测量,`memwriter` 也将从它自己的地址空间中取消映射,
|
||||
|
||||
```c
|
||||
munmap(memptr, ByteSize); /* unmap the storage *
|
||||
```
|
||||
这将使得 `memwriter` 不能进一步地访问共享内存。
|
||||
|
||||
#### 示例 4. memreader 进程的源代码
|
||||
|
||||
```c
|
||||
/** Compilation: gcc -o memreader memreader.c -lrt -lpthread **/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
#include "shmem.h"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int fd = shm_open(BackingFile, O_RDWR, AccessPerms); /* empty to begin */
|
||||
if (fd < 0) report_and_exit("Can't get file descriptor...");
|
||||
|
||||
/* get a pointer to memory */
|
||||
caddr_t memptr = mmap(NULL, /* let system pick where to put segment */
|
||||
ByteSize, /* how many bytes */
|
||||
PROT_READ | PROT_WRITE, /* access protections */
|
||||
MAP_SHARED, /* mapping visible to other processes */
|
||||
fd, /* file descriptor */
|
||||
0); /* offset: start at 1st byte */
|
||||
if ((caddr_t) -1 == memptr) report_and_exit("Can't access segment...");
|
||||
|
||||
/* create a semaphore for mutual exclusion */
|
||||
sem_t* semptr = sem_open(SemaphoreName, /* name */
|
||||
O_CREAT, /* create the semaphore */
|
||||
AccessPerms, /* protection perms */
|
||||
0); /* initial value */
|
||||
if (semptr == (void*) -1) report_and_exit("sem_open");
|
||||
|
||||
/* use semaphore as a mutex (lock) by waiting for writer to increment it */
|
||||
if (!sem_wait(semptr)) { /* wait until semaphore != 0 */
|
||||
int i;
|
||||
for (i = 0; i < strlen(MemContents); i++)
|
||||
write(STDOUT_FILENO, memptr + i, 1); /* one byte at a time */
|
||||
sem_post(semptr);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
munmap(memptr, ByteSize);
|
||||
close(fd);
|
||||
sem_close(semptr);
|
||||
unlink(BackingFile);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
`memwriter` 和 `memreader` 程序中,共享内存的主要着重点都在 `shm_open` 和 `mmap` 函数上:在成功时,第一个调用返回一个备份文件的文件描述符,而第二个调用则使用这个文件描述符从共享内存段中获取一个指针。它们对 `shm_open` 的调用都很相似,除了 `memwriter` 程序创建共享内存,而 `memreader 只获取这个已经创建的内存:
|
||||
|
||||
```c
|
||||
int fd = shm_open(BackingFile, O_RDWR | O_CREAT, AccessPerms); /* memwriter */
|
||||
int fd = shm_open(BackingFile, O_RDWR, AccessPerms); /* memreader */
|
||||
```
|
||||
|
||||
有了文件描述符,接着对 `mmap` 的调用就是类似的了:
|
||||
|
||||
```c
|
||||
caddr_t memptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
```
|
||||
|
||||
`mmap` 的第一个参数为 `NULL`,这意味着让系统自己决定在虚拟内存地址的哪个地方分配内存,当然也可以指定一个地址(但很有技巧性)。`MAP_SHARED` 标志着被分配的内存在进程中是共享的,最后一个参数(在这个例子中为 0 ) 意味着共享内存的偏移量应该为第一个字节。`size` 参数特别指定了将要分配的字节数目(在这个例子中是 512);另外的保护参数(`AccessPerms`)暗示着共享内存是可读可写的。
|
||||
|
||||
当 `memwriter` 程序执行成功后,系统将创建并维护备份文件,在我的系统中,该文件为 `/dev/shm/shMemEx`,其中的 `shMemEx` 是我为共享存储命名的(在头文件 `shmem.h` 中给定)。在当前版本的 `memwriter` 和 `memreader` 程序中,下面的语句
|
||||
|
||||
```c
|
||||
shm_unlink(BackingFile); /* removes backing file */
|
||||
```
|
||||
|
||||
将会移除备份文件。假如没有 `unlink` 这个语句,则备份文件在程序终止后仍然持久地保存着。
|
||||
|
||||
`memreader` 和 `memwriter` 一样,在调用 `sem_open` 函数时,通过信号量的名字来获取信号量。但 `memreader` 随后将进入等待状态,直到 `memwriter` 将初始值为 0 的信号量的值增加。
|
||||
|
||||
```c
|
||||
if (!sem_wait(semptr)) { /* wait until semaphore != 0 */
|
||||
```
|
||||
|
||||
一旦等待结束,`memreader` 将从共享内存中读取 ASCII 数据,然后做些清理工作并终止。
|
||||
|
||||
共享内存 API 包括显式地同步共享内存段和备份文件。在这次的示例中,这些操作都被省略了,以免文章显得杂乱,好让我们专注于内存共享和信号量的代码。
|
||||
|
||||
即便在信号量代码被移除的情况下,`memwriter` 和 `memreader` 程序很大几率也能够正常执行而不会引入竞争条件:`memwriter` 创建了共享内存段,然后立即向它写入;`memreader` 不能访问共享内存,直到共享内存段被创建好。然而,当一个*写操作*处于混合状态时,最佳实践需要共享内存被同步。信号量 API 足够重要,值得在代码示例中着重强调。
|
||||
|
||||
### 总结
|
||||
|
||||
上面共享文件和共享内存的例子展示了进程是怎样通过*共享存储*来进行通信的,前者通过文件而后者通过内存块。这两种方法的 API 相对来说都很直接。这两种方法有什么共同的缺点吗?现代的应用经常需要处理流数据,而且是非常大规模的数据流。共享文件或者共享内存的方法都不能很好地处理大规模的流数据。按照类型使用管道会更加合适一些。所以这个系列的第二部分将会介绍管道和消息队列,同样的,我们将使用 C 语言写的代码示例来辅助讲解。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/interprocess-communication-linux-storage
|
||||
|
||||
作者:[Marty Kalin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mkalindepauledu
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/documents_papers_file_storage_work.png?itok=YlXpAqAJ (Filing papers and documents)
|
||||
[2]: https://en.wikipedia.org/wiki/Inter-process_communication
|
||||
[3]: http://condor.depaul.edu/mkalin
|
||||
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/perror.html
|
||||
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/exit.html
|
||||
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html
|
||||
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
|
||||
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/strcpy.html
|
@ -0,0 +1,347 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10840-1.html)
|
||||
[#]: subject: (Building a DNS-as-a-service with OpenStack Designate)
|
||||
[#]: via: (https://opensource.com/article/19/4/getting-started-openstack-designate)
|
||||
[#]: author: (Amjad Yaseen https://opensource.com/users/ayaseen)
|
||||
|
||||
用 OpenStack Designate 构建一个 DNS 即服务(DNSaaS)
|
||||
======
|
||||
|
||||
> 学习如何安装和配置 Designate,这是一个 OpenStack 的多租户 DNS 即服务(DNSaaS)。
|
||||
|
||||

|
||||
|
||||
[Designate][2] 是一个多租户的 DNS 即服务,它包括一个用于域名和记录管理的 REST API 和集成了 [Neutron][3] 的框架,并支持 Bind9。
|
||||
|
||||
DNSaaS 可以提供:
|
||||
|
||||
* 一个管理区域和记录的干净利落的 REST API
|
||||
* 自动生成记录(集成 OpenStack)
|
||||
* 支持多个授权名字服务器
|
||||
* 可以托管多个项目/组织
|
||||
|
||||
![Designate's architecture][4]
|
||||
|
||||
这篇文章解释了如何在 CentOS 和 RHEL 上手动安装和配置 Designate 的最新版本,但是同样的配置也可以用在其它发行版上。
|
||||
|
||||
### 在 OpenStack 上安装 Designate
|
||||
|
||||
在我的 [GitHub 仓库][5]里,我已经放了 Ansible 的 bind 和 Designate 角色的示范设置。
|
||||
|
||||
这个设置假定 bing 服务是安装 OpenStack 控制器节点之外(即使你可以在本地安装 bind)。
|
||||
|
||||
1、在 OpenStack 控制节点上安装 Designate 和 bind 软件包:
|
||||
|
||||
```
|
||||
# yum install openstack-designate-* bind bind-utils -y
|
||||
```
|
||||
|
||||
2、创建 Designate 数据库和用户:
|
||||
|
||||
```
|
||||
MariaDB [(none)]> CREATE DATABASE designate CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
|
||||
MariaDB [(none)]> GRANT ALL PRIVILEGES ON designate.* TO \
|
||||
'designate'@'localhost' IDENTIFIED BY 'rhlab123';
|
||||
|
||||
MariaDB [(none)]> GRANT ALL PRIVILEGES ON designate.* TO 'designate'@'%' \
|
||||
IDENTIFIED BY 'rhlab123';
|
||||
```
|
||||
|
||||
注意:bind 包必须安装在控制节点之外才能使<ruby>远程名字服务控制<rt>Remote Name Daemon Control</rt></ruby>(RNDC)功能正常。
|
||||
|
||||
### 配置 bind(DNS 服务器)
|
||||
|
||||
1、生成 RNDC 文件:
|
||||
|
||||
```
|
||||
rndc-confgen -a -k designate -c /etc/rndc.key -r /dev/urandom
|
||||
|
||||
cat <<EOF> etcrndc.conf
|
||||
include "/etc/rndc.key";
|
||||
options {
|
||||
default-key "designate";
|
||||
default-server {{ DNS_SERVER_IP }};
|
||||
default-port 953;
|
||||
};
|
||||
EOF
|
||||
```
|
||||
|
||||
2、将下列配置添加到 `named.conf`:
|
||||
|
||||
```
|
||||
include "/etc/rndc.key";
|
||||
controls {
|
||||
inet {{ DNS_SERVER_IP }} allow { localhost;{{ CONTROLLER_SERVER_IP }}; } keys { "designate"; };
|
||||
};
|
||||
```
|
||||
|
||||
在 `option` 节中,添加:
|
||||
|
||||
```
|
||||
options {
|
||||
...
|
||||
allow-new-zones yes;
|
||||
request-ixfr no;
|
||||
listen-on port 53 { any; };
|
||||
recursion no;
|
||||
allow-query { 127.0.0.1; {{ CONTROLLER_SERVER_IP }}; };
|
||||
};
|
||||
```
|
||||
|
||||
添加正确的权限:
|
||||
|
||||
```
|
||||
chown named:named /etc/rndc.key
|
||||
chown named:named /etc/rndc.conf
|
||||
chmod 600 /etc/rndc.key
|
||||
chown -v root:named /etc/named.conf
|
||||
chmod g+w /var/named
|
||||
|
||||
# systemctl restart named
|
||||
# setsebool named_write_master_zones 1
|
||||
```
|
||||
|
||||
3、把 `rndc.key` 和 `rndc.conf` 推入 OpenStack 控制节点:
|
||||
|
||||
```
|
||||
# scp -r /etc/rndc* {{ CONTROLLER_SERVER_IP }}:/etc/
|
||||
```
|
||||
|
||||
### 创建 OpenStack Designate 服务和端点
|
||||
|
||||
输入:
|
||||
|
||||
```
|
||||
# openstack user create --domain default --password-prompt designate
|
||||
# openstack role add --project services --user designate admin
|
||||
# openstack service create --name designate --description "DNS" dns
|
||||
|
||||
# openstack endpoint create --region RegionOne dns public http://{{ CONTROLLER_SERVER_IP }}:9001/
|
||||
# openstack endpoint create --region RegionOne dns internal http://{{ CONTROLLER_SERVER_IP }}:9001/
|
||||
# openstack endpoint create --region RegionOne dns admin http://{{ CONTROLLER_SERVER_IP }}:9001/
|
||||
```
|
||||
|
||||
### 配置 Designate 服务
|
||||
|
||||
1、编辑 `/etc/designate/designate.conf`:
|
||||
|
||||
在 `[service:api]` 节配置 `auth_strategy`:
|
||||
|
||||
```
|
||||
[service:api]
|
||||
listen = 0.0.0.0:9001
|
||||
auth_strategy = keystone
|
||||
api_base_uri = http://{{ CONTROLLER_SERVER_IP }}:9001/
|
||||
enable_api_v2 = True
|
||||
enabled_extensions_v2 = quotas, reports
|
||||
```
|
||||
|
||||
在 `[keystone_authtoken]` 节配置下列选项:
|
||||
|
||||
```
|
||||
[keystone_authtoken]
|
||||
auth_type = password
|
||||
username = designate
|
||||
password = rhlab123
|
||||
project_name = service
|
||||
project_domain_name = Default
|
||||
user_domain_name = Default
|
||||
www_authenticate_uri = http://{{ CONTROLLER_SERVER_IP }}:5000/
|
||||
auth_url = http://{{ CONTROLLER_SERVER_IP }}:5000/
|
||||
```
|
||||
|
||||
在 `[service:worker]` 节,启用 worker 模型:
|
||||
|
||||
```
|
||||
enabled = True
|
||||
notify = True
|
||||
```
|
||||
|
||||
在 `[storage:sqlalchemy]` 节,配置数据库访问:
|
||||
|
||||
```
|
||||
[storage:sqlalchemy]
|
||||
connection = mysql+pymysql://designate:rhlab123@{{ CONTROLLER_SERVER_IP }}/designate
|
||||
```
|
||||
|
||||
填充 Designate 数据库:
|
||||
|
||||
```
|
||||
# su -s /bin/sh -c "designate-manage database sync" designate
|
||||
```
|
||||
|
||||
2、 创建 Designate 的 `pools.yaml` 文件(包含 target 和 bind 细节):
|
||||
|
||||
编辑 `/etc/designate/pools.yaml`:
|
||||
|
||||
```
|
||||
- name: default
|
||||
# The name is immutable. There will be no option to change the name after
|
||||
# creation and the only way will to change it will be to delete it
|
||||
# (and all zones associated with it) and recreate it.
|
||||
description: Default Pool
|
||||
|
||||
attributes: {}
|
||||
|
||||
# List out the NS records for zones hosted within this pool
|
||||
# This should be a record that is created outside of designate, that
|
||||
# points to the public IP of the controller node.
|
||||
ns_records:
|
||||
- hostname: {{Controller_FQDN}}. # Thisis mDNS
|
||||
priority: 1
|
||||
|
||||
# List out the nameservers for this pool. These are the actual BIND servers.
|
||||
# We use these to verify changes have propagated to all nameservers.
|
||||
nameservers:
|
||||
- host: {{ DNS_SERVER_IP }}
|
||||
port: 53
|
||||
|
||||
# List out the targets for this pool. For BIND there will be one
|
||||
# entry for each BIND server, as we have to run rndc command on each server
|
||||
targets:
|
||||
- type: bind9
|
||||
description: BIND9 Server 1
|
||||
|
||||
# List out the designate-mdns servers from which BIND servers should
|
||||
# request zone transfers (AXFRs) from.
|
||||
# This should be the IP of the controller node.
|
||||
# If you have multiple controllers you can add multiple masters
|
||||
# by running designate-mdns on them, and adding them here.
|
||||
masters:
|
||||
- host: {{ CONTROLLER_SERVER_IP }}
|
||||
port: 5354
|
||||
|
||||
# BIND Configuration options
|
||||
options:
|
||||
host: {{ DNS_SERVER_IP }}
|
||||
port: 53
|
||||
rndc_host: {{ DNS_SERVER_IP }}
|
||||
rndc_port: 953
|
||||
rndc_key_file: /etc/rndc.key
|
||||
rndc_config_file: /etc/rndc.conf
|
||||
```
|
||||
|
||||
填充 Designate 池:
|
||||
|
||||
```
|
||||
su -s /bin/sh -c "designate-manage pool update" designate
|
||||
```
|
||||
|
||||
3、启动 Designate 中心和 API 服务:
|
||||
|
||||
```
|
||||
systemctl enable --now designate-central designate-api
|
||||
```
|
||||
|
||||
4、验证 Designate 服务运行:
|
||||
|
||||
```
|
||||
# openstack dns service list
|
||||
|
||||
+--------------+--------+-------+--------------+
|
||||
| service_name | status | stats | capabilities |
|
||||
+--------------+--------+-------+--------------+
|
||||
| central | UP | - | - |
|
||||
| api | UP | - | - |
|
||||
| mdns | UP | - | - |
|
||||
| worker | UP | - | - |
|
||||
| producer | UP | - | - |
|
||||
+--------------+--------+-------+--------------+
|
||||
```
|
||||
|
||||
### 用外部 DNS 配置 OpenStack Neutron
|
||||
|
||||
1、为 Designate 服务配置 iptables:
|
||||
|
||||
```
|
||||
# iptables -I INPUT -p tcp -m multiport --dports 9001 -m comment --comment "designate incoming" -j ACCEPT
|
||||
|
||||
# iptables -I INPUT -p tcp -m multiport --dports 5354 -m comment --comment "Designate mdns incoming" -j ACCEPT
|
||||
|
||||
# iptables -I INPUT -p tcp -m multiport --dports 53 -m comment --comment "bind incoming" -j ACCEPT
|
||||
|
||||
# iptables -I INPUT -p udp -m multiport --dports 53 -m comment --comment "bind/powerdns incoming" -j ACCEPT
|
||||
|
||||
# iptables -I INPUT -p tcp -m multiport --dports 953 -m comment --comment "rndc incoming - bind only" -j ACCEPT
|
||||
|
||||
# service iptables save; service iptables restart
|
||||
# setsebool named_write_master_zones 1
|
||||
```
|
||||
|
||||
2、 编辑 `/etc/neutron/neutron.conf` 的 `[default]` 节:
|
||||
|
||||
```
|
||||
external_dns_driver = designate
|
||||
```
|
||||
|
||||
3、 在 `/etc/neutron/neutron.conf` 中添加 `[designate]` 节:
|
||||
|
||||
```
|
||||
[designate]
|
||||
url = http://{{ CONTROLLER_SERVER_IP }}:9001/v2 ## This end point of designate
|
||||
auth_type = password
|
||||
auth_url = http://{{ CONTROLLER_SERVER_IP }}:5000
|
||||
username = designate
|
||||
password = rhlab123
|
||||
project_name = services
|
||||
project_domain_name = Default
|
||||
user_domain_name = Default
|
||||
allow_reverse_dns_lookup = True
|
||||
ipv4_ptr_zone_prefix_size = 24
|
||||
ipv6_ptr_zone_prefix_size = 116
|
||||
```
|
||||
|
||||
4、编辑 `neutron.conf` 的 `dns_domain`:
|
||||
|
||||
```
|
||||
dns_domain = rhlab.dev.
|
||||
```
|
||||
|
||||
重启:
|
||||
|
||||
```
|
||||
# systemctl restart neutron-*
|
||||
```
|
||||
|
||||
5、在 `/etc/neutron/plugins/ml2/ml2_conf.ini` 中的组成层 2(ML2)中添加 `dns`:
|
||||
|
||||
```
|
||||
extension_drivers=port_security,qos,dns
|
||||
```
|
||||
|
||||
6、在 Designate 中添加区域:
|
||||
|
||||
```
|
||||
# openstack zone create –email=admin@rhlab.dev rhlab.dev.
|
||||
```
|
||||
|
||||
在 `rhlab.dev` 区域中添加记录:
|
||||
|
||||
```
|
||||
# openstack recordset create --record '192.168.1.230' --type A rhlab.dev. Test
|
||||
```
|
||||
|
||||
Designate 现在就安装和配置好了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/getting-started-openstack-designate
|
||||
|
||||
作者:[Amjad Yaseen][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/ayaseen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
|
||||
[2]: https://docs.openstack.org/designate/latest/
|
||||
[3]: /article/19/3/openstack-neutron
|
||||
[4]: https://opensource.com/sites/default/files/uploads/openstack_designate_architecture.png (Designate's architecture)
|
||||
[5]: https://github.com/ayaseen/designate
|
@ -0,0 +1,578 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (FSSlc)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10845-1.html)
|
||||
[#]: subject: (Inter-process communication in Linux: Using pipes and message queues)
|
||||
[#]: via: (https://opensource.com/article/19/4/interprocess-communication-linux-channels)
|
||||
[#]: author: (Marty Kalin https://opensource.com/users/mkalindepauledu)
|
||||
|
||||
Linux 下的进程间通信:使用管道和消息队列
|
||||
======
|
||||
|
||||
> 学习在 Linux 中进程是如何与其他进程进行同步的。
|
||||
|
||||
![Chat bubbles][1]
|
||||
|
||||
本篇是 Linux 下[进程间通信][2](IPC)系列的第二篇文章。[第一篇文章][3] 聚焦于通过共享文件和共享内存段这样的共享存储来进行 IPC。这篇文件的重点将转向管道,它是连接需要通信的进程之间的通道。管道拥有一个*写端*用于写入字节数据,还有一个*读端*用于按照先入先出的顺序读入这些字节数据。而这些字节数据可能代表任何东西:数字、员工记录、数字电影等等。
|
||||
|
||||
管道有两种类型,命名管道和无名管道,都可以交互式的在命令行或程序中使用它们;相关的例子在下面展示。这篇文章也将介绍内存队列,尽管它们有些过时了,但它们不应该受这样的待遇。
|
||||
|
||||
在本系列的第一篇文章中的示例代码承认了在 IPC 中可能受到竞争条件(不管是基于文件的还是基于内存的)的威胁。自然地我们也会考虑基于管道的 IPC 的安全并发问题,这个也将在本文中提及。针对管道和内存队列的例子将会使用 POSIX 推荐使用的 API,POSIX 的一个核心目标就是线程安全。
|
||||
|
||||
请查看一些 [mq_open 函数的 man 页][4],这个函数属于内存队列的 API。这个 man 页中有关 [特性][5] 的章节带有一个小表格:
|
||||
|
||||
接口 | 特性 | 值
|
||||
---|---|---
|
||||
`mq_open()` | 线程安全 | MT-Safe
|
||||
|
||||
上面的 MT-Safe(MT 指的是<ruby>多线程<rt>multi-threaded</rt></ruby>)意味着 `mq_open` 函数是线程安全的,进而暗示是进程安全的:一个进程的执行和它的一个线程执行的过程类似,假如竞争条件不会发生在处于*相同*进程的线程中,那么这样的条件也不会发生在处于不同进程的线程中。MT-Safe 特性保证了调用 `mq_open` 时不会出现竞争条件。一般来说,基于通道的 IPC 是并发安全的,尽管在下面例子中会出现一个有关警告的注意事项。
|
||||
|
||||
### 无名管道
|
||||
|
||||
首先让我们通过一个特意构造的命令行例子来展示无名管道是如何工作的。在所有的现代系统中,符号 `|` 在命令行中都代表一个无名管道。假设我们的命令行提示符为 `%`,接下来考虑下面的命令:
|
||||
|
||||
```shell
|
||||
## 写入方在 | 左边,读取方在右边
|
||||
% sleep 5 | echo "Hello, world!"
|
||||
```
|
||||
|
||||
`sleep` 和 `echo` 程序以不同的进程执行,无名管道允许它们进行通信。但是上面的例子被特意设计为没有通信发生。问候语 “Hello, world!” 出现在屏幕中,然后过了 5 秒后,命令行返回,暗示 `sleep` 和 `echo` 进程都已经结束了。这期间发生了什么呢?
|
||||
|
||||
在命令行中的竖线 `|` 的语法中,左边的进程(`sleep`)是写入方,右边的进程(`echo`)为读取方。默认情况下,读取方将会阻塞,直到从通道中能够读取到字节数据,而写入方在写完它的字节数据后,将发送 <ruby>流已终止<rt>end-of-stream</rt></ruby>的标志。(即便写入方过早终止了,一个流已终止的标志还是会发给读取方。)无名管道将保持到写入方和读取方都停止的那个时刻。
|
||||
|
||||
在上面的例子中,`sleep` 进程并没有向通道写入任何的字节数据,但在 5 秒后就终止了,这时将向通道发送一个流已终止的标志。与此同时,`echo` 进程立即向标准输出(屏幕)写入问候语,因为这个进程并不从通道中读入任何字节,所以它并没有等待。一旦 `sleep` 和 `echo` 进程都终止了,不会再用作通信的无名管道将会消失然后返回命令行提示符。
|
||||
|
||||
下面这个更加实用的示例将使用两个无名管道。我们假定文件 `test.dat` 的内容如下:
|
||||
|
||||
```
|
||||
this
|
||||
is
|
||||
the
|
||||
way
|
||||
the
|
||||
world
|
||||
ends
|
||||
```
|
||||
|
||||
下面的命令:
|
||||
|
||||
```
|
||||
% cat test.dat | sort | uniq
|
||||
```
|
||||
|
||||
会将 `cat`(<ruby>连接<rt>concatenate</rt></ruby>的缩写)进程的输出通过管道传给 `sort` 进程以生成排序后的输出,然后将排序后的输出通过管道传给 `uniq` 进程以消除重复的记录(在本例中,会将两次出现的 “the” 缩减为一个):
|
||||
|
||||
```
|
||||
ends
|
||||
is
|
||||
the
|
||||
this
|
||||
way
|
||||
world
|
||||
```
|
||||
|
||||
下面展示的情景展示的是一个带有两个进程的程序通过一个无名管道通信来进行通信。
|
||||
|
||||
#### 示例 1. 两个进程通过一个无名管道来进行通信
|
||||
|
||||
```c
|
||||
#include <sys/wait.h> /* wait */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* exit functions */
|
||||
#include <unistd.h> /* read, write, pipe, _exit */
|
||||
#include <string.h>
|
||||
|
||||
#define ReadEnd 0
|
||||
#define WriteEnd 1
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1); /** failure **/
|
||||
}
|
||||
|
||||
int main() {
|
||||
int pipeFDs[2]; /* two file descriptors */
|
||||
char buf; /* 1-byte buffer */
|
||||
const char* msg = "Nature's first green is gold\n"; /* bytes to write */
|
||||
|
||||
if (pipe(pipeFDs) < 0) report_and_exit("pipeFD");
|
||||
pid_t cpid = fork(); /* fork a child process */
|
||||
if (cpid < 0) report_and_exit("fork"); /* check for failure */
|
||||
|
||||
if (0 == cpid) { /*** child ***/ /* child process */
|
||||
close(pipeFDs[WriteEnd]); /* child reads, doesn't write */
|
||||
|
||||
while (read(pipeFDs[ReadEnd], &buf, 1) > 0) /* read until end of byte stream */
|
||||
write(STDOUT_FILENO, &buf, sizeof(buf)); /* echo to the standard output */
|
||||
|
||||
close(pipeFDs[ReadEnd]); /* close the ReadEnd: all done */
|
||||
_exit(0); /* exit and notify parent at once */
|
||||
}
|
||||
else { /*** parent ***/
|
||||
close(pipeFDs[ReadEnd]); /* parent writes, doesn't read */
|
||||
|
||||
write(pipeFDs[WriteEnd], msg, strlen(msg)); /* write the bytes to the pipe */
|
||||
close(pipeFDs[WriteEnd]); /* done writing: generate eof */
|
||||
|
||||
wait(NULL); /* wait for child to exit */
|
||||
exit(0); /* exit normally */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
上面名为 `pipeUN` 的程序使用系统函数 `fork` 来创建一个进程。尽管这个程序只有一个单一的源文件,在它正确执行的情况下将会发生多进程的情况。
|
||||
|
||||
> 下面的内容是对库函数 `fork` 如何工作的一个简要回顾:
|
||||
|
||||
> * `fork` 函数由*父*进程调用,在失败时返回 `-1` 给父进程。在 `pipeUN` 这个例子中,相应的调用是:
|
||||
|
||||
> ```c
|
||||
pid_t cpid = fork(); /* called in parent */
|
||||
```
|
||||
|
||||
> 函数调用后的返回值也被保存下来了。在这个例子中,保存在整数类型 `pid_t` 的变量 `cpid` 中。(每个进程有它自己的*进程 ID*,这是一个非负的整数,用来标记进程)。复刻一个新的进程可能会因为多种原因而失败,包括*进程表*满了的原因,这个结构由系统维持,以此来追踪进程状态。明确地说,僵尸进程假如没有被处理掉,将可能引起进程表被填满的错误。
|
||||
> * 假如 `fork` 调用成功,则它将创建一个新的子进程,向父进程返回一个值,向子进程返回另外的一个值。在调用 `fork` 后父进程和子进程都将执行相同的代码。(子进程继承了到此为止父进程中声明的所有变量的拷贝),特别地,一次成功的 `fork` 调用将返回如下的东西:
|
||||
> * 向子进程返回 `0`
|
||||
> * 向父进程返回子进程的进程 ID
|
||||
> * 在一次成功的 `fork` 调用后,一个 `if`/`else` 或等价的结构将会被用来隔离针对父进程和子进程的代码。在这个例子中,相应的声明为:
|
||||
|
||||
> ```c
|
||||
if (0 == cpid) { /*** child ***/
|
||||
...
|
||||
}
|
||||
else { /*** parent ***/
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
假如成功地复刻出了一个子进程,`pipeUN` 程序将像下面这样去执行。在一个整数的数列里:
|
||||
|
||||
```c
|
||||
int pipeFDs[2]; /* two file descriptors */
|
||||
```
|
||||
|
||||
来保存两个文件描述符,一个用来向管道中写入,另一个从管道中写入。(数组元素 `pipeFDs[0]` 是读端的文件描述符,元素 `pipeFDs[1]` 是写端的文件描述符。)在调用 `fork` 之前,对系统 `pipe` 函数的成功调用,将立刻使得这个数组获得两个文件描述符:
|
||||
|
||||
```c
|
||||
if (pipe(pipeFDs) < 0) report_and_exit("pipeFD");
|
||||
```
|
||||
|
||||
父进程和子进程现在都有了文件描述符的副本。但*分离关注点*模式意味着每个进程恰好只需要一个描述符。在这个例子中,父进程负责写入,而子进程负责读取,尽管这样的角色分配可以反过来。在 `if` 子句中的第一个语句将用于关闭管道的读端:
|
||||
|
||||
```c
|
||||
close(pipeFDs[WriteEnd]); /* called in child code */
|
||||
```
|
||||
|
||||
在父进程中的 `else` 子句将会关闭管道的读端:
|
||||
|
||||
```c
|
||||
close(pipeFDs[ReadEnd]); /* called in parent code */
|
||||
```
|
||||
|
||||
然后父进程将向无名管道中写入某些字节数据(ASCII 代码),子进程读取这些数据,然后向标准输出中回放它们。
|
||||
|
||||
在这个程序中还需要澄清的一点是在父进程代码中的 `wait` 函数。一旦被创建后,子进程很大程度上独立于它的父进程,正如简短的 `pipeUN` 程序所展示的那样。子进程可以执行任意的代码,而它们可能与父进程完全没有关系。但是,假如当子进程终止时,系统将会通过一个信号来通知父进程。
|
||||
|
||||
要是父进程在子进程之前终止又该如何呢?在这种情形下,除非采取了预防措施,子进程将会变成在进程表中的一个*僵尸*进程。预防措施有两大类型:第一种是让父进程去通知系统,告诉系统它对子进程的终止没有任何兴趣:
|
||||
|
||||
```c
|
||||
signal(SIGCHLD, SIG_IGN); /* in parent: ignore notification */
|
||||
```
|
||||
|
||||
第二种方法是在子进程终止时,让父进程执行一个 `wait`。这样就确保了父进程可以独立于子进程而存在。在 `pipeUN` 程序中使用了第二种方法,其中父进程的代码使用的是下面的调用:
|
||||
|
||||
```c
|
||||
wait(NULL); /* called in parent */
|
||||
```
|
||||
|
||||
这个对 `wait` 的调用意味着*一直等待直到任意一个子进程的终止发生*,因此在 `pipeUN` 程序中,只有一个子进程。(其中的 `NULL` 参数可以被替换为一个保存有子程序退出状态的整数变量的地址。)对于更细粒度的控制,还可以使用更灵活的 `waitpid` 函数,例如特别指定多个子进程中的某一个。
|
||||
|
||||
`pipeUN` 将会采取另一个预防措施。当父进程结束了等待,父进程将会调用常规的 `exit` 函数去退出。对应的,子进程将会调用 `_exit` 变种来退出,这类变种将快速跟踪终止相关的通知。在效果上,子进程会告诉系统立刻去通知父进程它的这个子进程已经终止了。
|
||||
|
||||
假如两个进程向相同的无名管道中写入内容,字节数据会交错吗?例如,假如进程 P1 向管道写入内容:
|
||||
|
||||
```
|
||||
foo bar
|
||||
```
|
||||
|
||||
同时进程 P2 并发地写入:
|
||||
|
||||
```
|
||||
baz baz
|
||||
```
|
||||
|
||||
到相同的管道,最后的结果似乎是管道中的内容将会是任意错乱的,例如像这样:
|
||||
|
||||
```
|
||||
baz foo baz bar
|
||||
```
|
||||
|
||||
只要没有写入超过 `PIPE_BUF` 字节,POSIX 标准就能确保写入不会交错。在 Linux 系统中, `PIPE_BUF` 的大小是 4096 字节。对于管道我更喜欢只有一个写入方和一个读取方,从而绕过这个问题。
|
||||
|
||||
### 命名管道
|
||||
|
||||
无名管道没有备份文件:系统将维持一个内存缓存来将字节数据从写方传给读方。一旦写方和读方终止,这个缓存将会被回收,进而无名管道消失。相反的,命名管道有备份文件和一个不同的 API。
|
||||
|
||||
下面让我们通过另一个命令行示例来了解命名管道的要点。下面是具体的步骤:
|
||||
|
||||
* 开启两个终端。这两个终端的工作目录应该相同。
|
||||
* 在其中一个终端中,键入下面的两个命令(命令行提示符仍然是 `%`,我的注释以 `##` 打头。):
|
||||
|
||||
```shell
|
||||
% mkfifo tester ## 创建一个备份文件,名为 tester
|
||||
% cat tester ## 将管道的内容输出到 stdout
|
||||
```
|
||||
|
||||
在最开始,没有任何东西会出现在终端中,因为到现在为止没有在命名管道中写入任何东西。
|
||||
* 在第二个终端中输入下面的命令:
|
||||
|
||||
```shell
|
||||
% cat > tester ## redirect keyboard input to the pipe
|
||||
hello, world! ## then hit Return key
|
||||
bye, bye ## ditto
|
||||
<Control-C> ## terminate session with a Control-C
|
||||
```
|
||||
|
||||
无论在这个终端中输入什么,它都会在另一个终端中显示出来。一旦键入 `Ctrl+C`,就会回到正常的命令行提示符,因为管道已经被关闭了。
|
||||
* 通过移除实现命名管道的文件来进行清理:
|
||||
|
||||
```shell
|
||||
% unlink tester
|
||||
```
|
||||
|
||||
正如 `mkfifo` 程序的名字所暗示的那样,命名管道也被叫做 FIFO,因为第一个进入的字节,就会第一个出,其他的类似。有一个名为 `mkfifo` 的库函数,用它可以在程序中创建一个命名管道,它将在下一个示例中被用到,该示例由两个进程组成:一个向命名管道写入,而另一个从该管道读取。
|
||||
|
||||
#### 示例 2. fifoWriter 程序
|
||||
|
||||
```c
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MaxLoops 12000 /* outer loop */
|
||||
#define ChunkSize 16 /* how many written at a time */
|
||||
#define IntsPerChunk 4 /* four 4-byte ints per chunk */
|
||||
#define MaxZs 250 /* max microseconds to sleep */
|
||||
|
||||
int main() {
|
||||
const char* pipeName = "./fifoChannel";
|
||||
mkfifo(pipeName, 0666); /* read/write for user/group/others */
|
||||
int fd = open(pipeName, O_CREAT | O_WRONLY); /* open as write-only */
|
||||
if (fd < 0) return -1; /* can't go on */
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MaxLoops; i++) { /* write MaxWrites times */
|
||||
int j;
|
||||
for (j = 0; j < ChunkSize; j++) { /* each time, write ChunkSize bytes */
|
||||
int k;
|
||||
int chunk[IntsPerChunk];
|
||||
for (k = 0; k < IntsPerChunk; k++)
|
||||
chunk[k] = rand();
|
||||
write(fd, chunk, sizeof(chunk));
|
||||
}
|
||||
usleep((rand() % MaxZs) + 1); /* pause a bit for realism */
|
||||
}
|
||||
|
||||
close(fd); /* close pipe: generates an end-of-stream marker */
|
||||
unlink(pipeName); /* unlink from the implementing file */
|
||||
printf("%i ints sent to the pipe.\n", MaxLoops * ChunkSize * IntsPerChunk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
上面的 `fifoWriter` 程序可以被总结为如下:
|
||||
|
||||
* 首先程序创建了一个命名管道用来写入数据:
|
||||
|
||||
```c
|
||||
mkfifo(pipeName, 0666); /* read/write perms for user/group/others */
|
||||
int fd = open(pipeName, O_CREAT | O_WRONLY);
|
||||
```
|
||||
|
||||
其中的 `pipeName` 是备份文件的名字,传递给 `mkfifo` 作为它的第一个参数。接着命名管道通过我们熟悉的 `open` 函数调用被打开,而这个函数将会返回一个文件描述符。
|
||||
* 在实现层面上,`fifoWriter` 不会一次性将所有的数据都写入,而是写入一个块,然后休息随机数目的微秒时间,接着再循环往复。总的来说,有 768000 个 4 字节整数值被写入到命名管道中。
|
||||
* 在关闭命名管道后,`fifoWriter` 也将使用 `unlink` 取消对该文件的连接。
|
||||
|
||||
```c
|
||||
close(fd); /* close pipe: generates end-of-stream marker */
|
||||
unlink(pipeName); /* unlink from the implementing file */
|
||||
```
|
||||
|
||||
一旦连接到管道的每个进程都执行了 `unlink` 操作后,系统将回收这些备份文件。在这个例子中,只有两个这样的进程 `fifoWriter` 和 `fifoReader`,它们都做了 `unlink` 操作。
|
||||
|
||||
这个两个程序应该在不同终端的相同工作目录中执行。但是 `fifoWriter` 应该在 `fifoReader` 之前被启动,因为需要 `fifoWriter` 去创建管道。然后 `fifoReader` 才能够获取到刚被创建的命名管道。
|
||||
|
||||
#### 示例 3. fifoReader 程序
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned is_prime(unsigned n) { /* not pretty, but efficient */
|
||||
if (n <= 3) return n > 1;
|
||||
if (0 == (n % 2) || 0 == (n % 3)) return 0;
|
||||
|
||||
unsigned i;
|
||||
for (i = 5; (i * i) <= n; i += 6)
|
||||
if (0 == (n % i) || 0 == (n % (i + 2))) return 0;
|
||||
|
||||
return 1; /* found a prime! */
|
||||
}
|
||||
|
||||
int main() {
|
||||
const char* file = "./fifoChannel";
|
||||
int fd = open(file, O_RDONLY);
|
||||
if (fd < 0) return -1; /* no point in continuing */
|
||||
unsigned count = 0, total = 0, primes_count = 0;
|
||||
|
||||
while (1) {
|
||||
int next;
|
||||
int i;
|
||||
|
||||
ssize_t count = read(fd, &next, sizeof(int));
|
||||
if (0 == count) break; /* end of stream */
|
||||
else if (count == sizeof(int)) { /* read a 4-byte int value */
|
||||
total++;
|
||||
if (is_prime(next)) primes_count++;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd); /* close pipe from read end */
|
||||
unlink(file); /* unlink from the underlying file */
|
||||
printf("Received ints: %u, primes: %u\n", total, primes_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
上面的 `fifoReader` 的内容可以总结为如下:
|
||||
|
||||
* 因为 `fifoWriter` 已经创建了命名管道,所以 `fifoReader` 只需要利用标准的 `open` 调用来通过备份文件来获取到管道中的内容:
|
||||
|
||||
```c
|
||||
const char* file = "./fifoChannel";
|
||||
int fd = open(file, O_RDONLY);
|
||||
```
|
||||
|
||||
这个文件的是以只读打开的。
|
||||
* 然后这个程序进入一个潜在的无限循环,在每次循环时,尝试读取 4 字节的块。`read` 调用:
|
||||
|
||||
```c
|
||||
ssize_t count = read(fd, &next, sizeof(int));
|
||||
```
|
||||
|
||||
返回 0 来暗示该流的结束。在这种情况下,`fifoReader` 跳出循环,关闭命名管道,并在终止前 `unlink` 备份文件。
|
||||
* 在读入 4 字节整数后,`fifoReader` 检查这个数是否为质数。这个操作代表了一个生产级别的读取器可能在接收到的字节数据上执行的逻辑操作。在示例运行中,在接收到的 768000 个整数中有 37682 个质数。
|
||||
|
||||
重复运行示例, `fifoReader` 将成功地读取 `fifoWriter` 写入的所有字节。这不是很让人惊讶的。这两个进程在相同的机器上执行,从而可以不用考虑网络相关的问题。命名管道是一个可信且高效的 IPC 机制,因而被广泛使用。
|
||||
|
||||
下面是这两个程序的输出,它们在不同的终端中启动,但处于相同的工作目录:
|
||||
|
||||
```shell
|
||||
% ./fifoWriter
|
||||
768000 ints sent to the pipe.
|
||||
###
|
||||
% ./fifoReader
|
||||
Received ints: 768000, primes: 37682
|
||||
```
|
||||
|
||||
### 消息队列
|
||||
|
||||
管道有着严格的先入先出行为:第一个被写入的字节将会第一个被读,第二个写入的字节将第二个被读,以此类推。消息队列可以做出相同的表现,但它又足够灵活,可以使得字节块可以不以先入先出的次序来接收。
|
||||
|
||||
正如它的名字所提示的那样,消息队列是一系列的消息,每个消息包含两部分:
|
||||
|
||||
* 荷载,一个字节序列(在 C 中是 char)
|
||||
* 类型,以一个正整数值的形式给定,类型用来分类消息,为了更灵活的回收
|
||||
|
||||
看一下下面对一个消息队列的描述,每个消息由一个整数类型标记:
|
||||
|
||||
```
|
||||
+-+ +-+ +-+ +-+
|
||||
sender--->|3|--->|2|--->|2|--->|1|--->receiver
|
||||
+-+ +-+ +-+ +-+
|
||||
```
|
||||
|
||||
在上面展示的 4 个消息中,标记为 1 的是开头,即最接近接收端,然后另个标记为 2 的消息,最后接着一个标记为 3 的消息。假如按照严格的 FIFO 行为执行,消息将会以 1-2-2-3 这样的次序被接收。但是消息队列允许其他收取次序。例如,消息可以被接收方以 3-2-1-2 的次序接收。
|
||||
|
||||
`mqueue` 示例包含两个程序,`sender` 将向消息队列中写入数据,而 `receiver` 将从这个队列中读取数据。这两个程序都包含的头文件 `queue.h` 如下所示:
|
||||
|
||||
#### 示例 4. 头文件 queue.h
|
||||
|
||||
```c
|
||||
#define ProjectId 123
|
||||
#define PathName "queue.h" /* any existing, accessible file would do */
|
||||
#define MsgLen 4
|
||||
#define MsgCount 6
|
||||
|
||||
typedef struct {
|
||||
long type; /* must be of type long */
|
||||
char payload[MsgLen + 1]; /* bytes in the message */
|
||||
} queuedMessage;
|
||||
```
|
||||
|
||||
上面的头文件定义了一个名为 `queuedMessage` 的结构类型,它带有 `payload`(字节数组)和 `type`(整数)这两个域。该文件也定义了一些符号常数(使用 `#define` 语句),前两个常数被用来生成一个 `key`,而这个 `key` 反过来被用来获取一个消息队列的 ID。`ProjectId` 可以是任何正整数值,而 `PathName` 必须是一个存在的、可访问的文件,在这个示例中,指的是文件 `queue.h`。在 `sender` 和 `receiver` 中,它们都有的设定语句为:
|
||||
|
||||
```c
|
||||
key_t key = ftok(PathName, ProjectId); /* generate key */
|
||||
int qid = msgget(key, 0666 | IPC_CREAT); /* use key to get queue id */
|
||||
```
|
||||
|
||||
ID `qid` 在效果上是消息队列文件描述符的对应物。
|
||||
|
||||
#### 示例 5. sender 程序
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "queue.h"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1); /* EXIT_FAILURE */
|
||||
}
|
||||
|
||||
int main() {
|
||||
key_t key = ftok(PathName, ProjectId);
|
||||
if (key < 0) report_and_exit("couldn't get key...");
|
||||
|
||||
int qid = msgget(key, 0666 | IPC_CREAT);
|
||||
if (qid < 0) report_and_exit("couldn't get queue id...");
|
||||
|
||||
char* payloads[] = {"msg1", "msg2", "msg3", "msg4", "msg5", "msg6"};
|
||||
int types[] = {1, 1, 2, 2, 3, 3}; /* each must be > 0 */
|
||||
int i;
|
||||
for (i = 0; i < MsgCount; i++) {
|
||||
/* build the message */
|
||||
queuedMessage msg;
|
||||
msg.type = types[i];
|
||||
strcpy(msg.payload, payloads[i]);
|
||||
|
||||
/* send the message */
|
||||
msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT); /* don't block */
|
||||
printf("%s sent as type %i\n", msg.payload, (int) msg.type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
上面的 `sender` 程序将发送出 6 个消息,每两个为一个类型:前两个是类型 1,接着的连个是类型 2,最后的两个为类型 3。发送的语句:
|
||||
|
||||
```c
|
||||
msgsnd(qid, &msg, sizeof(msg), IPC_NOWAIT);
|
||||
```
|
||||
|
||||
被配置为非阻塞的(`IPC_NOWAIT` 标志),是因为这里的消息体量上都很小。唯一的危险在于一个完整的序列将可能导致发送失败,而这个例子不会。下面的 `receiver` 程序也将使用 `IPC_NOWAIT` 标志来接收消息。
|
||||
|
||||
#### 示例 6. receiver 程序
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <stdlib.h>
|
||||
#include "queue.h"
|
||||
|
||||
void report_and_exit(const char* msg) {
|
||||
perror(msg);
|
||||
exit(-1); /* EXIT_FAILURE */
|
||||
}
|
||||
|
||||
int main() {
|
||||
key_t key= ftok(PathName, ProjectId); /* key to identify the queue */
|
||||
if (key < 0) report_and_exit("key not gotten...");
|
||||
|
||||
int qid = msgget(key, 0666 | IPC_CREAT); /* access if created already */
|
||||
if (qid < 0) report_and_exit("no access to queue...");
|
||||
|
||||
int types[] = {3, 1, 2, 1, 3, 2}; /* different than in sender */
|
||||
int i;
|
||||
for (i = 0; i < MsgCount; i++) {
|
||||
queuedMessage msg; /* defined in queue.h */
|
||||
if (msgrcv(qid, &msg, sizeof(msg), types[i], MSG_NOERROR | IPC_NOWAIT) < 0)
|
||||
puts("msgrcv trouble...");
|
||||
printf("%s received as type %i\n", msg.payload, (int) msg.type);
|
||||
}
|
||||
|
||||
/** remove the queue **/
|
||||
if (msgctl(qid, IPC_RMID, NULL) < 0) /* NULL = 'no flags' */
|
||||
report_and_exit("trouble removing queue...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
这个 `receiver` 程序不会创建消息队列,尽管 API 尽管建议那样。在 `receiver` 中,对
|
||||
|
||||
```c
|
||||
int qid = msgget(key, 0666 | IPC_CREAT);
|
||||
```
|
||||
|
||||
的调用可能因为带有 `IPC_CREAT` 标志而具有误导性,但是这个标志的真实意义是*如果需要就创建,否则直接获取*。`sender` 程序调用 `msgsnd` 来发送消息,而 `receiver` 调用 `msgrcv` 来接收它们。在这个例子中,`sender` 以 1-1-2-2-3-3 的次序发送消息,但 `receiver` 接收它们的次序为 3-1-2-1-3-2,这显示消息队列没有被严格的 FIFO 行为所拘泥:
|
||||
|
||||
```shell
|
||||
% ./sender
|
||||
msg1 sent as type 1
|
||||
msg2 sent as type 1
|
||||
msg3 sent as type 2
|
||||
msg4 sent as type 2
|
||||
msg5 sent as type 3
|
||||
msg6 sent as type 3
|
||||
|
||||
% ./receiver
|
||||
msg5 received as type 3
|
||||
msg1 received as type 1
|
||||
msg3 received as type 2
|
||||
msg2 received as type 1
|
||||
msg6 received as type 3
|
||||
msg4 received as type 2
|
||||
```
|
||||
|
||||
上面的输出显示 `sender` 和 `receiver` 可以在同一个终端中启动。输出也显示消息队列是持久的,即便 `sender` 进程在完成创建队列、向队列写数据、然后退出的整个过程后,该队列仍然存在。只有在 `receiver` 进程显式地调用 `msgctl` 来移除该队列,这个队列才会消失:
|
||||
|
||||
```c
|
||||
if (msgctl(qid, IPC_RMID, NULL) < 0) /* remove queue */
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
管道和消息队列的 API 在根本上来说都是单向的:一个进程写,然后另一个进程读。当然还存在双向命名管道的实现,但我认为这个 IPC 机制在它最为简单的时候反而是最佳的。正如前面提到的那样,消息队列已经不大受欢迎了,尽管没有找到什么特别好的原因来解释这个现象;而队列仍然是 IPC 工具箱中的一个工具。这个快速的 IPC 工具箱之旅将以第 3 部分(通过套接字和信号来示例 IPC)来终结。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/interprocess-communication-linux-channels
|
||||
|
||||
作者:[Marty Kalin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mkalindepauledu
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/talk_chat_communication_team.png?itok=CYfZ_gE7 (Chat bubbles)
|
||||
[2]: https://en.wikipedia.org/wiki/Inter-process_communication
|
||||
[3]: https://linux.cn/article-10826-1.html
|
||||
[4]: http://man7.org/linux/man-pages/man2/mq_open.2.html
|
||||
[5]: http://man7.org/linux/man-pages/man2/mq_open.2.html#ATTRIBUTES
|
||||
[6]: http://www.opengroup.org/onlinepubs/009695399/functions/perror.html
|
||||
[7]: http://www.opengroup.org/onlinepubs/009695399/functions/exit.html
|
||||
[8]: http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html
|
||||
[9]: http://www.opengroup.org/onlinepubs/009695399/functions/rand.html
|
||||
[10]: http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
|
||||
[11]: http://www.opengroup.org/onlinepubs/009695399/functions/strcpy.html
|
||||
[12]: http://www.opengroup.org/onlinepubs/009695399/functions/puts.html
|
@ -0,0 +1,303 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10867-1.html)
|
||||
[#]: subject: (Building scalable social media sentiment analysis services in Python)
|
||||
[#]: via: (https://opensource.com/article/19/4/social-media-sentiment-analysis-python-scalable)
|
||||
[#]: author: (Michael McCune https://opensource.com/users/elmiko/users/jschlessman)
|
||||
|
||||
使用 Python 构建可扩展的社交媒体情感分析服务
|
||||
======
|
||||
|
||||
> 学习如何使用 spaCy、vaderSentiment、Flask 和 Python 来为你的作品添加情感分析能力。
|
||||
|
||||

|
||||
|
||||
本系列的[第一部分][2]提供了情感分析工作原理的一些背景知识,现在让我们研究如何将这些功能添加到你的设计中。
|
||||
|
||||
### 探索 Python 库 spaCy 和 vaderSentiment
|
||||
|
||||
#### 前提条件
|
||||
|
||||
* 一个终端 shell
|
||||
* shell 中的 Python 语言二进制文件(3.4+ 版本)
|
||||
* 用于安装 Python 包的 `pip` 命令
|
||||
* (可选)一个 [Python 虚拟环境][3]使你的工作与系统隔离开来
|
||||
|
||||
#### 配置环境
|
||||
|
||||
在开始编写代码之前,你需要安装 [spaCy][4] 和 [vaderSentiment][5] 包来设置 Python 环境,同时下载一个语言模型来帮助你分析。幸运的是,大部分操作都容易在命令行中完成。
|
||||
|
||||
在 shell 中,输入以下命令来安装 spaCy 和 vaderSentiment 包:
|
||||
|
||||
```
|
||||
pip install spacy vaderSentiment
|
||||
```
|
||||
|
||||
命令安装完成后,安装 spaCy 可用于文本分析的语言模型。以下命令将使用 spaCy 模块下载并安装英语[模型][6]:
|
||||
|
||||
```
|
||||
python -m spacy download en_core_web_sm
|
||||
```
|
||||
|
||||
安装了这些库和模型之后,就可以开始编码了。
|
||||
|
||||
#### 一个简单的文本分析
|
||||
|
||||
使用 [Python 解释器交互模式][7] 编写一些代码来分析单个文本片段。首先启动 Python 环境:
|
||||
|
||||
```
|
||||
$ python
|
||||
Python 3.6.8 (default, Jan 31 2019, 09:38:34)
|
||||
[GCC 8.2.1 20181215 (Red Hat 8.2.1-6)] on linux
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>>
|
||||
```
|
||||
|
||||
*(你的 Python 解释器版本打印可能与此不同。)*
|
||||
|
||||
1、导入所需模块:
|
||||
|
||||
```
|
||||
>>> import spacy
|
||||
>>> from vaderSentiment import vaderSentiment
|
||||
```
|
||||
|
||||
2、从 spaCy 加载英语语言模型:
|
||||
|
||||
```
|
||||
>>> english = spacy.load("en_core_web_sm")
|
||||
```
|
||||
|
||||
3、处理一段文本。本例展示了一个非常简单的句子,我们希望它能给我们带来些许积极的情感:
|
||||
|
||||
```
|
||||
>>> result = english("I like to eat applesauce with sugar and cinnamon.")
|
||||
```
|
||||
|
||||
4、从处理后的结果中收集句子。SpaCy 已识别并处理短语中的实体,这一步为每个句子生成情感(即时在本例中只有一个句子):
|
||||
|
||||
```
|
||||
>>> sentences = [str(s) for s in result.sents]
|
||||
```
|
||||
|
||||
5、使用 vaderSentiments 创建一个分析器:
|
||||
|
||||
```
|
||||
>>> analyzer = vaderSentiment.SentimentIntensityAnalyzer()
|
||||
```
|
||||
|
||||
6、对句子进行情感分析:
|
||||
|
||||
```
|
||||
>>> sentiment = [analyzer.polarity_scores(str(s)) for s in sentences]
|
||||
```
|
||||
|
||||
`sentiment` 变量现在包含例句的极性分数。打印出这个值,看看它是如何分析这个句子的。
|
||||
|
||||
```
|
||||
>>> print(sentiment)
|
||||
[{'neg': 0.0, 'neu': 0.737, 'pos': 0.263, 'compound': 0.3612}]
|
||||
```
|
||||
|
||||
这个结构是什么意思?
|
||||
|
||||
表面上,这是一个只有一个字典对象的数组。如果有多个句子,那么每个句子都会对应一个字典对象。字典中有四个键对应不同类型的情感。`neg` 键表示负面情感,因为在本例中没有报告任何负面情感,`0.0` 值证明了这一点。`neu` 键表示中性情感,它的得分相当高,为 `0.737`(最高为 `1.0`)。`pos` 键代表积极情感,得分适中,为 `0.263`。最后,`cmpound` 键代表文本的总体得分,它可以从负数到正数,`0.3612` 表示积极方面的情感多一点。
|
||||
|
||||
要查看这些值可能如何变化,你可以使用已输入的代码做一个小实验。以下代码块显示了如何对类似句子的情感评分的评估。
|
||||
|
||||
```
|
||||
>>> result = english("I love applesauce!")
|
||||
>>> sentences = [str(s) for s in result.sents]
|
||||
>>> sentiment = [analyzer.polarity_scores(str(s)) for s in sentences]
|
||||
>>> print(sentiment)
|
||||
[{'neg': 0.0, 'neu': 0.182, 'pos': 0.818, 'compound': 0.6696}]
|
||||
```
|
||||
|
||||
你可以看到,通过将例句改为非常积极的句子,`sentiment` 的值发生了巨大变化。
|
||||
|
||||
### 建立一个情感分析服务
|
||||
|
||||
现在你已经为情感分析组装了基本的代码块,让我们将这些东西转化为一个简单的服务。
|
||||
|
||||
在这个演示中,你将使用 Python [Flask 包][9] 创建一个 [RESTful][8] HTTP 服务器。此服务将接受英文文本数据并返回情感分析结果。请注意,此示例服务是用于学习所涉及的技术,而不是用于投入生产的东西。
|
||||
|
||||
#### 前提条件
|
||||
|
||||
* 一个终端 shell
|
||||
* shell 中的 Python 语言二进制文件(3.4+ 版本)
|
||||
* 安装 Python 包的 `pip` 命令
|
||||
* `curl` 命令
|
||||
* 一个文本编辑器
|
||||
* (可选) 一个 [Python 虚拟环境][3]使你的工作与系统隔离开来
|
||||
|
||||
#### 配置环境
|
||||
|
||||
这个环境几乎与上一节中的环境相同,唯一的区别是在 Python 环境中添加了 Flask 包。
|
||||
|
||||
1、安装所需依赖项:
|
||||
|
||||
```
|
||||
pip install spacy vaderSentiment flask
|
||||
```
|
||||
|
||||
2、安装 spaCy 的英语语言模型:
|
||||
|
||||
```
|
||||
python -m spacy download en_core_web_sm
|
||||
```
|
||||
|
||||
#### 创建应用程序文件
|
||||
|
||||
打开编辑器,创建一个名为 `app.py` 的文件。添加以下内容 *(不用担心,我们将解释每一行)*:
|
||||
|
||||
|
||||
```
|
||||
import flask
|
||||
import spacy
|
||||
import vaderSentiment.vaderSentiment as vader
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
analyzer = vader.SentimentIntensityAnalyzer()
|
||||
english = spacy.load("en_core_web_sm")
|
||||
|
||||
def get_sentiments(text):
|
||||
result = english(text)
|
||||
sentences = [str(sent) for sent in result.sents]
|
||||
sentiments = [analyzer.polarity_scores(str(s)) for s in sentences]
|
||||
return sentiments
|
||||
|
||||
@app.route("/", methods=["POST", "GET"])
|
||||
def index():
|
||||
if flask.request.method == "GET":
|
||||
return "To access this service send a POST request to this URL with" \
|
||||
" the text you want analyzed in the body."
|
||||
body = flask.request.data.decode("utf-8")
|
||||
sentiments = get_sentiments(body)
|
||||
return flask.json.dumps(sentiments)
|
||||
```
|
||||
|
||||
虽然这个源文件不是很大,但它非常密集。让我们来看看这个应用程序的各个部分,并解释它们在做什么。
|
||||
|
||||
```
|
||||
import flask
|
||||
import spacy
|
||||
import vaderSentiment.vaderSentiment as vader
|
||||
```
|
||||
|
||||
前三行引入了执行语言分析和 HTTP 框架所需的包。
|
||||
|
||||
```
|
||||
app = flask.Flask(__name__)
|
||||
analyzer = vader.SentimentIntensityAnalyzer()
|
||||
english = spacy.load("en_core_web_sm")
|
||||
```
|
||||
|
||||
接下来的三行代码创建了一些全局变量。第一个变量 `app`,它是 Flask 用于创建 HTTP 路由的主要入口点。第二个变量 `analyzer` 与上一个示例中使用的类型相同,它将用于生成情感分数。最后一个变量 `english` 也与上一个示例中使用的类型相同,它将用于注释和标记初始文本输入。
|
||||
|
||||
你可能想知道为什么全局声明这些变量。对于 `app` 变量,这是许多 Flask 应用程序的标准过程。但是,对于 `analyzer` 和 `english` 变量,将它们设置为全局变量的决定是基于与所涉及的类关联的加载时间。虽然加载时间可能看起来很短,但是当它在 HTTP 服务器的上下文中运行时,这些延迟会对性能产生负面影响。
|
||||
|
||||
```
|
||||
def get_sentiments(text):
|
||||
result = english(text)
|
||||
sentences = [str(sent) for sent in result.sents]
|
||||
sentiments = [analyzer.polarity_scores(str(s)) for s in sentences]
|
||||
return sentiments
|
||||
```
|
||||
|
||||
这部分是服务的核心 —— 一个用于从一串文本生成情感值的函数。你可以看到此函数中的操作对应于你之前在 Python 解释器中运行的命令。这里它们被封装在一个函数定义中,`text` 源作为文本变量传入,最后 `sentiments` 变量返回给调用者。
|
||||
|
||||
```
|
||||
@app.route("/", methods=["POST", "GET"])
|
||||
def index():
|
||||
if flask.request.method == "GET":
|
||||
return "To access this service send a POST request to this URL with" \
|
||||
" the text you want analyzed in the body."
|
||||
body = flask.request.data.decode("utf-8")
|
||||
sentiments = get_sentiments(body)
|
||||
return flask.json.dumps(sentiments)
|
||||
```
|
||||
|
||||
源文件的最后一个函数包含了指导 Flask 如何为服务配置 HTTP 服务器的逻辑。它从一行开始,该行将 HTTP 路由 `/` 与请求方法 `POST` 和 `GET` 相关联。
|
||||
|
||||
在函数定义行之后,`if` 子句将检测请求方法是否为 `GET`。如果用户向服务发送此请求,那么下面的行将返回一条指示如何访问服务器的文本消息。这主要是为了方便最终用户。
|
||||
|
||||
下一行使用 `flask.request` 对象来获取请求的主体,该主体应包含要处理的文本字符串。`decode` 函数将字节数组转换为可用的格式化字符串。经过解码的文本消息被传递给 `get_sentiments` 函数以生成情感分数。最后,分数通过 HTTP 框架返回给用户。
|
||||
|
||||
你现在应该保存文件,如果尚未保存,那么返回 shell。
|
||||
|
||||
#### 运行情感服务
|
||||
|
||||
一切就绪后,使用 Flask 的内置调试服务器运行服务非常简单。要启动该服务,请从与源文件相同的目录中输入以下命令:
|
||||
|
||||
```
|
||||
FLASK_APP=app.py flask run
|
||||
```
|
||||
|
||||
现在,你将在 shell 中看到来自服务器的一些输出,并且服务器将处于运行状态。要测试服务器是否正在运行,你需要打开第二个 shell 并使用 `curl` 命令。
|
||||
|
||||
首先,输入以下命令检查是否打印了指令信息:
|
||||
|
||||
```
|
||||
curl http://localhost:5000
|
||||
```
|
||||
|
||||
你应该看到说明消息:
|
||||
|
||||
```
|
||||
To access this service send a POST request to this URI with the text you want analyzed in the body.
|
||||
```
|
||||
|
||||
接下来,运行以下命令发送测试消息,查看情感分析:
|
||||
|
||||
```
|
||||
curl http://localhost:5000 --header "Content-Type: application/json" --data "I love applesauce!"
|
||||
```
|
||||
|
||||
你从服务器获得的响应应类似于以下内容:
|
||||
|
||||
```
|
||||
[{"compound": 0.6696, "neg": 0.0, "neu": 0.182, "pos": 0.818}]
|
||||
```
|
||||
|
||||
恭喜!你现在已经实现了一个 RESTful HTTP 情感分析服务。你可以在 [GitHub 上找到此服务的参考实现和本文中的所有代码][10]。
|
||||
|
||||
### 继续探索
|
||||
|
||||
现在你已经了解了自然语言处理和情感分析背后的原理和机制,下面是进一步发现探索该主题的一些方法。
|
||||
|
||||
#### 在 OpenShift 上创建流式情感分析器
|
||||
|
||||
虽然创建本地应用程序来研究情绪分析很方便,但是接下来需要能够部署应用程序以实现更广泛的用途。按照[Radnaalytics.io][11] 提供的指导和代码进行操作,你将学习如何创建一个情感分析仪,可以容器化并部署到 Kubernetes 平台。你还将了解如何将 Apache Kafka 用作事件驱动消息传递的框架,以及如何将 Apache Spark 用作情绪分析的分布式计算平台。
|
||||
|
||||
#### 使用 Twitter API 发现实时数据
|
||||
|
||||
虽然 [Radanalytics.io][12] 实验室可以生成合成推文流,但你可以不受限于合成数据。事实上,拥有 Twitter 账户的任何人都可以使用 [Tweepy Python][13] 包访问 Twitter 流媒体 API 对推文进行情感分析。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/social-media-sentiment-analysis-python-scalable
|
||||
|
||||
作者:[Michael McCune][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/elmiko/users/jschlessman
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/windows_building_sky_scale.jpg?itok=mH6CAX29 (Tall building with windows)
|
||||
[2]: https://linux.cn/article-10852-1.html
|
||||
[3]: https://virtualenv.pypa.io/en/stable/
|
||||
[4]: https://pypi.org/project/spacy/
|
||||
[5]: https://pypi.org/project/vaderSentiment/
|
||||
[6]: https://spacy.io/models
|
||||
[7]: https://docs.python.org/3.6/tutorial/interpreter.html
|
||||
[8]: https://en.wikipedia.org/wiki/Representational_state_transfer
|
||||
[9]: http://flask.pocoo.org/
|
||||
[10]: https://github.com/elmiko/social-moments-service
|
||||
[11]: https://github.com/radanalyticsio/streaming-lab
|
||||
[12]: http://Radanalytics.io
|
||||
[13]: https://github.com/tweepy/tweepy
|
@ -0,0 +1,116 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10852-1.html)
|
||||
[#]: subject: (Getting started with social media sentiment analysis in Python)
|
||||
[#]: via: (https://opensource.com/article/19/4/social-media-sentiment-analysis-python)
|
||||
[#]: author: (Michael McCune https://opensource.com/users/elmiko/users/jschlessman)
|
||||
|
||||
使用 Python 进行社交媒体情感分析入门
|
||||
======
|
||||
|
||||
> 学习自然语言处理的基础知识并探索两个有用的 Python 包。
|
||||
|
||||

|
||||
|
||||
自然语言处理(NLP)是机器学习的一种,它解决了口语或书面语言和计算机辅助分析这些语言之间的相关性。日常生活中我们经历了无数的 NLP 创新,从写作帮助和建议到实时语音翻译,还有口译。
|
||||
|
||||
本文研究了 NLP 的一个特定领域:情感分析。重点是确定输入语言的积极、消极或中性性质。本部分将解释 NLP 和情感分析的背景,并探讨两个开源的 Python 包。[第 2 部分][2]将演示如何开始构建自己的可扩展情感分析服务。
|
||||
|
||||
在学习情感分析时,对 NLP 有一个大体了解是有帮助的。本文不会深入研究数学本质。相反,我们的目标是阐明 NLP 中的关键概念,这些概念对于将这些方法实际结合到你的解决方案中至关重要。
|
||||
|
||||
### 自然语言和文本数据
|
||||
|
||||
合理的起点是从定义开始:“什么是自然语言?”它是我们人类相互交流的方式,沟通的主要方式是口语和文字。我们可以更进一步,只关注文本交流。毕竟,生活在 Siri、Alexa 等无处不在的时代,我们知道语音是一组与文本无关的计算。
|
||||
|
||||
### 数据前景和挑战
|
||||
|
||||
我们只考虑使用文本数据,我们可以对语言和文本做什么呢?首先是语言,特别是英语,除了规则还有很多例外,含义的多样性和语境差异,这些都可能使人类口译员感到困惑,更不用说计算机翻译了。在小学,我们学习文章和标点符号,通过讲母语,我们获得了寻找直觉上表示唯一意义的词的能力。比如,出现诸如 “a”、“the” 和 “or” 之类的文章,它们在 NLP 中被称为*停止词*,因为传统上 NLP 算法是在一个序列中找到这些词时意味着搜索停止。
|
||||
|
||||
由于我们的目标是自动将文本分类为情感类,因此我们需要一种以计算方式处理文本数据的方法。因此,我们必须考虑如何向机器表示文本数据。众所周知,利用和解释语言的规则很复杂,输入文本的大小和结构可能会有很大差异。我们需要将文本数据转换为数字数据,这是机器和数学的首选方式。这种转变属于*特征提取*的范畴。
|
||||
|
||||
在提取输入文本数据的数字表示形式后,一个改进可能是:给定一个文本输入体,为上面列出的文章确定一组向量统计数据,并根据这些数据对文档进行分类。例如,过多的副词可能会使撰稿人感到愤怒,或者过度使用停止词可能有助于识别带有内容填充的学期论文。诚然,这可能与我们情感分析的目标没有太大关系。
|
||||
|
||||
### 词袋
|
||||
|
||||
当你评估一个文本陈述是积极还是消极的时候,你使用哪些上下文来评估它的极性?(例如,文本中是否具有积极的、消极的或中性的情感)一种方式是隐含形容词:被称为 “disgusting”(恶心) 的东西被认为是消极的,但如果同样的东西被称为 “beautiful”(漂亮),你会认为它是积极的。从定义上讲,俗语给人一种熟悉感,通常是积极的,而脏话可能是敌意的表现。文本数据也可以包括表情符号,它带有固定的情感。
|
||||
|
||||
理解单个单词的极性影响为文本的<ruby>[词袋][3]<rt>bag-of-words</rt></ruby>(BoW)模型提供了基础。它分析一组单词或词汇表,并提取关于这些单词在输入文本中是否存在的度量。词汇表是通过处理已知极性的文本形成称为*标记的训练数据*。从这组标记数据中提取特征,然后分析特征之间的关系,并将标记与数据关联起来。
|
||||
|
||||
“词袋”这个名称说明了它的用途:即不考虑空间位置或上下文的的单个词。词汇表通常是由训练集中出现的所有单词构建的,训练后往往会被修剪。如果在训练之前没有清理停止词,那么停止词会因为其高频率和低语境而被移除。很少使用的单词也可以删除,因为缺乏为一般输入实例提供的信息。
|
||||
|
||||
但是,重要的是要注意,你可以(并且应该)进一步考虑单词在单个训练数据实例之外的情形,这称为<ruby>[词频][4]<rt>term frequency</rt></ruby>(TF)。你还应该考虑输入数据在所有训练实例中的单词计数,通常,出现在所有文档中的低频词更重要,这被称为<ruby>[逆文本频率指数][5]<rt>inverse document frequency</rt></ruby>(IDF)。这些指标一定会在本主题系列的其他文章和软件包中提及,因此了解它们会有所帮助。
|
||||
|
||||
词袋在许多文档分类应用程序中很有用。然而,在情感分析中,当缺乏情境意识的问题被利用时,事情就可以解决。考虑以下句子:
|
||||
|
||||
* 我们不喜欢这场战争。
|
||||
* 我讨厌下雨天,好事是今天是晴天。
|
||||
* 这不是生死攸关的问题。
|
||||
|
||||
这些短语的情感对于人类口译员来说是有难度的,而且通过严格关注单个词汇的实例,对于机器翻译来说也是困难的。
|
||||
|
||||
在 NLP 中也可以使用称为 “n-grams” 的单词分组。一个二元组考虑两个相邻单词组成的组而不是(或除了)单个词袋。这应该可以缓解诸如上述“不喜欢”之类的情况,但由于缺乏语境意思,它仍然是个问题。此外,在上面的第二句中,下半句的情感语境可以被理解为否定前半部分。因此,这种方法中也会丢失上下文线索的空间局部性。从实用角度来看,使问题复杂化的是从给定输入文本中提取的特征的稀疏性。对于一个完整的大型词汇表,每个单词都有一个计数,可以将其视为一个整数向量。大多数文档的向量中都有大量的零计数向量,这给操作增加了不必要的空间和时间复杂度。虽然已经提出了许多用于降低这种复杂性的简便方法,但它仍然是一个问题。
|
||||
|
||||
### 词嵌入
|
||||
|
||||
<ruby>词嵌入<rt>Word embedding</rt></ruby>是一种分布式表示,它允许具有相似含义的单词具有相似的表示。这是基于使用实值向量来与它们周围相关联。重点在于使用单词的方式,而不仅仅是它们的存在与否。此外,词嵌入的一个巨大实用优势是它们关注于密集向量。通过摆脱具有相应数量的零值向量元素的单词计数模型,词嵌入在时间和存储方面提供了一个更有效的计算范例。
|
||||
|
||||
以下是两个优秀的词嵌入方法。
|
||||
|
||||
#### Word2vec
|
||||
|
||||
第一个是 [Word2vec][6],它是由 Google 开发的。随着你对 NLP 和情绪分析研究的深入,你可能会看到这种嵌入方法。它要么使用一个<ruby>连续的词袋<rt>continuous bag of words</rt></ruby>(CBOW),要么使用一个连续 skip-gram 模型。在 CBOW 中,一个单词的上下文是在训练中根据围绕它的单词来学习的。连续 skip-gram 学习倾向于围绕给定的单词学习单词。虽然这可能超出了你需要解决的问题,但是如果你曾经面对必须生成自己的词嵌入情况,那么 Word2vec 的作者就提倡使用 CBOW 方法来提高速度并评估频繁的单词,而 skip-gram 方法更适合嵌入稀有单词更重要的嵌入。
|
||||
|
||||
#### GloVe
|
||||
|
||||
第二个是<ruby>[用于词表示的全局向量][7]<rt>Global Vectors for Word Representation</rt></ruby>(GloVe),它是斯坦福大学开发的。它是 Word2vec 方法的扩展,试图通过将经典的全局文本统计特征提取获得的信息与 Word2vec 确定的本地上下文信息相结合。实际上,在一些应用程序中,GloVe 性能优于 Word2vec,而在另一些应用程序中则不如 Word2vec。最终,用于词嵌入的目标数据集将决定哪种方法最优。因此,最好了解它们的存在性和高级机制,因为你很可能会遇到它们。
|
||||
|
||||
#### 创建和使用词嵌入
|
||||
|
||||
最后,知道如何获得词嵌入是有用的。在第 2 部分中,你将看到我们通过利用社区中其他人的实质性工作,站到了巨人的肩膀上。这是获取词嵌入的一种方法:即使用现有的经过训练和验证的模型。实际上,有无数的模型适用于英语和其他语言,一定会有一种模型可以满足你的应用程序,让你开箱即用!
|
||||
|
||||
如果没有的话,就开发工作而言,另一个极端是培训你自己的独立模型,而不考虑你的应用程序。实质上,你将获得大量标记的训练数据,并可能使用上述方法之一来训练模型。即使这样,你仍然只是在理解你输入文本数据。然后,你需要为你应用程序开发一个特定的模型(例如,分析软件版本控制消息中的情感价值),这反过来又需要自己的时间和精力。
|
||||
|
||||
你还可以对针对你的应用程序的数据训练一个词嵌入,虽然这可以减少时间和精力,但这个词嵌入将是特定于应用程序的,这将会降低它的可重用性。
|
||||
|
||||
### 可用的工具选项
|
||||
|
||||
考虑到所需的大量时间和计算能力,你可能想知道如何才能找到解决问题的方法。的确,开发可靠模型的复杂性可能令人望而生畏。但是,有一个好消息:已经有许多经过验证的模型、工具和软件库可以为我们提供所需的大部分内容。我们将重点关注 [Python][8],因为它为这些应用程序提供了大量方便的工具。
|
||||
|
||||
#### SpaCy
|
||||
|
||||
[SpaCy][9] 提供了许多用于解析输入文本数据和提取特征的语言模型。它经过了高度优化,并被誉为同类中最快的库。最棒的是,它是开源的!SpaCy 会执行标识化、词性分类和依赖项注释。它包含了用于执行此功能的词嵌入模型,还有用于为超过 46 种语言的其他特征提取操作。在本系列的第二篇文章中,你将看到它如何用于文本分析和特征提取。
|
||||
|
||||
#### vaderSentiment
|
||||
|
||||
[vaderSentiment][10] 包提供了积极、消极和中性情绪的衡量标准。正如 [原论文][11] 的标题(《VADER:一个基于规则的社交媒体文本情感分析模型》)所示,这些模型是专门为社交媒体文本数据开发和调整的。VADER 接受了一组完整的人类标记过的数据的训练,包括常见的表情符号、UTF-8 编码的表情符号以及口语术语和缩写(例如 meh、lol、sux)。
|
||||
|
||||
对于给定的输入文本数据,vaderSentiment 返回一个极性分数百分比的三元组。它还提供了一个单个的评分标准,称为 *vaderSentiment 复合指标*。这是一个在 `[-1, 1]` 范围内的实值,其中对于分值大于 `0.05` 的情绪被认为是积极的,对于分值小于 `-0.05` 的被认为是消极的,否则为中性。
|
||||
|
||||
在[第 2 部分][2]中,你将学习如何使用这些工具为你的设计添加情感分析功能。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/social-media-sentiment-analysis-python
|
||||
|
||||
作者:[Michael McCune][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/elmiko/users/jschlessman
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/getting_started_with_python.png?itok=MFEKm3gl (Raspberry Pi and Python)
|
||||
[2]: https://opensource.com/article/19/4/social-media-sentiment-analysis-python-part-2
|
||||
[3]: https://en.wikipedia.org/wiki/Bag-of-words_model
|
||||
[4]: https://en.wikipedia.org/wiki/Tf%E2%80%93idf#Term_frequency
|
||||
[5]: https://en.wikipedia.org/wiki/Tf%E2%80%93idf#Inverse_document_frequency
|
||||
[6]: https://en.wikipedia.org/wiki/Word2vec
|
||||
[7]: https://en.wikipedia.org/wiki/GloVe_(machine_learning)
|
||||
[8]: https://www.python.org/
|
||||
[9]: https://pypi.org/project/spacy/
|
||||
[10]: https://pypi.org/project/vaderSentiment/
|
||||
[11]: http://comp.social.gatech.edu/papers/icwsm14.vader.hutto.pdf
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10808-1.html)
|
||||
[#]: subject: (This is how System76 does open hardware)
|
||||
[#]: via: (https://opensource.com/article/19/4/system76-hardware)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
System76 是如何打造开源硬件的
|
||||
================================
|
||||
|
||||
> 是什么让新的 Thelio 台式机系列与众不同。
|
||||
|
||||
![在计算机上显示度量和数据][1]
|
||||
|
||||
大多数人对他们电脑的硬件一无所知。作为一个长期的 Linux 用户,当我想让我的无线网卡、视频卡、显示器和其他硬件与我选择的发行版共同运行时,也一样遇到了挫折。商业品牌的硬件通常使判断这些问题变得很困难:为什么以太网驱动、无线驱动或者鼠标驱动和我们预期的不太一样?随着 Linux 发行版变得成熟,这可能不再是问题,但是我们仍能发现触控板和其它外部设备的怪异行为,尤其是当我们对底层的硬件知道的不多时。
|
||||
|
||||
像 [System76][2] 这样的公司致力于解决这些问题,以提升 Linux 用户体验。System76 生产了一系列的 Linux 笔记本、台式机和服务器,甚至提供了它自己的 Linux 发行版 [Pop! OS][3] 作为客户的一个选择。最近我有幸参观了 System76 在 Devnver 的工厂并揭开它的新台式机产品线 [Thelio][5] [的神秘面纱][5]。
|
||||
|
||||
### 关于 Thelio
|
||||
|
||||
System76 宣称 Thelio 的开源硬件子板(被命名为木星之后的第 5 个卫星的名字 Thelio Io)是它在市场上独特的特点之一。Thelio Io 取得了开源硬件协会的认证 [OSHWA #us000145][6],并且有 4 个用于存储的 SATA 端口和一个控制风扇和用于电源按钮控制的嵌入式控制器。Thelio IO SAS 取得了 [OSHWA #us000146][7] 认证,并且有 4 个用于存储的 U.2 端口,没有嵌入式控制器。在展示时,System76 显示了这些组件如何调整风扇通过底盘来优化部件的性能。
|
||||
|
||||
该控制器还管理电源键,和围绕该电源键的 LED 光环,当被按下时它以 100% 的亮度发光。这提供了触觉和视觉上的确认:该主机已经启动电源了。当电脑在使用中,该按钮被设置为 35% 的亮度,当在睡眠模式,它的亮度在 2.35% 和 25% 之间跳动。当计算机关闭后,LED 保持朦胧的亮度,因此能够在黑暗的房间里找到电源控制。
|
||||
|
||||
Thelio 的嵌入式控制器是一个低功耗的 [ATmega32U4][8] 微控制器,并且控制器的设置可以使用 Arduino Micro 进行原型设计。Thelio Io 主板变化的多少取决于你购买哪种 Thelio 型号。
|
||||
|
||||
Thelio 可能是我见过的设计的最好的电脑机箱和系统。如果你曾经亲身体验过在一个常规的 PC 的内部进行操作的话,你可能会同意我的观点。我已经做了很多次了,因此我能以自己过往的糟糕经历来证明这点。
|
||||
|
||||
### 为什么做开源硬件?
|
||||
|
||||
该主板是在 [KiCAD][9] 设计的,你可以在 [GitHub][10] 上按 GPL 许可证访问 Thelio 所有的设计文件。因此,为什么一个与其他 PC 制造商竞争的公司会设计一个独特的接口并公开授权呢?可能是该公司认识到开源设计及根据你的需要调整和分享一个 I/O 主板设计的能力的价值,即便你是市场上的竞争者。
|
||||
|
||||
![在 Thelio 启动时 Don Watkins 与 System76 的 CEO Carl Richell 谈话][11]
|
||||
|
||||
*在 [Thelio 发布会][12] Don Watkins 与 System76 的 CEO Carl Richell 谈话。*
|
||||
|
||||
我问 System76 的设计者和 CEO [Carl Richell][13],该公司是否担心过公开许可它的硬件设计意味着有人可以采取它的独特设计并用它来将 System76 驱逐出市场。他说:
|
||||
|
||||
> 开源硬件对我们所有人都有益。这是我们未来提升技术的方式,并且使得每个人获取技术更容易。我们欢迎任何想要提高 Thelio 设计的人来这么做。开源该硬件不仅可以帮助我们更快的改进我们的电脑,并且能够使我们的消费者 100% 信任他们的设备。我们的目标是尽可能地移除专利功能,同时仍然能够为消费者提供一个有竞争力的 Linux 主机。
|
||||
>
|
||||
> 我们已经与 Linux 社区一起合作了 13 年之久,来为我们的笔记本、台式机、服务器创造一个完美顺滑的体验。我们长期专注于为 Linux 社区提供服务,提供给我们的客户高水准的服务,我们的个性使 System76 变得独特。
|
||||
|
||||
我还问 Carl 为什么开源硬件对 System76 和 PC 市场是有意义的。他回复道:
|
||||
|
||||
> System76 创立之初的想法是技术应该对每个人是开放和可获取的。我们还没有到达 100% 开源创造一个电脑的程度,但是有了开源硬件,我们迈出了接近目标的必不可少的一大步。
|
||||
>
|
||||
> 我们生活在技术变成工具的时代。计算机在各级教育和很多行业当中是人们的工具。由于每个人特定的需要,每个人对于如何提升电脑和软件作为他们的主要工具有他们自己的想法。开源我们的计算机可以让这些想法成为现实,从而反过来促进技术成为一个更强大的工具。在一个开源环境中,我们持续迭代来生产更好的 PC。这有点酷。
|
||||
|
||||
我们总结了我们讨论的关于 System76 技术路线的对话,包含了开源硬件 mini PC,甚至是笔记本。在 System76 品牌下的已售出的 mini PC 和笔记本是由其他供应商制造的,并不是基于开源硬件的(尽管它们用的是 Linux 软件,是开源的)。
|
||||
|
||||
设计和支持开放式硬件是 PC 产业中的变革者,也正是它造就了 System76 的新 Thelio 台式机电脑产品线的不同。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/system76-hardware
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI- (metrics and data shown on a computer screen)
|
||||
[2]: https://system76.com/
|
||||
[3]: https://opensource.com/article/18/1/behind-scenes-popos-linux
|
||||
[4]: /article/18/11/system76-thelio-desktop-computer
|
||||
[5]: https://system76.com/desktops
|
||||
[6]: https://certification.oshwa.org/us000145.html
|
||||
[7]: https://certification.oshwa.org/us000146.html
|
||||
[8]: https://www.microchip.com/wwwproducts/ATmega32u4
|
||||
[9]: http://kicad-pcb.org/
|
||||
[10]: https://github.com/system76/thelio-io
|
||||
[11]: https://opensource.com/sites/default/files/uploads/don_system76_ceo.jpg (Don Watkins speaks with System76 CEO Carl Richell at the Thelio launch event.)
|
||||
[12]: https://trevgstudios.smugmug.com/System76/121418-Thelio-Press-Event/i-FKWFxFv
|
||||
[13]: https://www.linkedin.com/in/carl-richell-9435781
|
||||
|
||||
|
@ -0,0 +1,140 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10841-1.html)
|
||||
[#]: subject: (2 new apps for music tweakers on Fedora Workstation)
|
||||
[#]: via: (https://fedoramagazine.org/2-new-apps-for-music-tweakers-on-fedora-workstation/)
|
||||
[#]: author: (Justin W. Flory https://fedoramagazine.org/author/jflory7/)
|
||||
|
||||
2 个给使用 Fedora 工作站的音乐爱好者的新应用
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Linux 操作系统非常适合进行独特的自定义和调整,以使你的计算机更好地为你工作。例如,[i3 窗口管理器][2] 就让用户认识到了构成现代 Linux 桌面的各种组件和部分。
|
||||
|
||||
Fedora 上有两个音乐爱好者会感兴趣的新软件包:mpris-scrobbler 和 playerctl。mpris-scrobbler 可以在 Last.fm 和/或 ListenBrainz 等音乐跟踪服务上[跟踪你的音乐收听历史][3]。 playerctl 是一个命令行的[音乐播放器的控制器][4]。
|
||||
|
||||
### mpris-scrobbler:记录你的音乐收听趋势
|
||||
|
||||
mpris-scrobbler 是一个命令行应用程序,用于将音乐的播放历史记录提交给 [Last.fm][5]、[Libre.fm][6] 或 [ListenBrainz][7] 等服务。它监听 [MPRIS D-Bus 接口][8] 以检测正在播放的内容。它可以连接几个不同的音乐客户端,如 spotify 客户端、[vlc][9]、audacious、bmp、[cmus][10] 等。
|
||||
|
||||
![Last.fm last week in music report. Generated from user-submitted listening history.][11]
|
||||
|
||||
#### 安装和配置 mpris-scrobbler
|
||||
|
||||
mpris-scrobbler 在 Fedora 28 或更高版本以及 EPEL 7 存储库中可用。在终端中运行以下命令进行安装:
|
||||
|
||||
```
|
||||
sudo dnf install mpris-scrobbler
|
||||
```
|
||||
|
||||
安装完成后,使用 `systemctl` 启动并启用该服务。以下命令启动 mpris-scrobbler 并始终在系统重启后启动它:
|
||||
|
||||
```
|
||||
systemctl --user enable --now mpris-scrobbler.service
|
||||
```
|
||||
|
||||
#### 提交播放信息给 ListenBrainz
|
||||
|
||||
这里将介绍如何将 mpris-scrobbler 与 ListenBrainz 帐户相关联。要使用 Last.fm 或 Libre.fm,请参阅其[上游文档][12]。
|
||||
|
||||
要将播放信息提交到 ListenBrainz 服务器,你需要有一个 ListenBrainz API 令牌。如果你有帐户,请从[个人资料设置页面][13]中获取该令牌。如果有了令牌,请运行此命令以使用 ListenBrainz API 令牌进行身份验证:
|
||||
|
||||
```
|
||||
$ mpris-scrobbler-signon token listenbrainz
|
||||
Token for listenbrainz.org:
|
||||
```
|
||||
|
||||
最后,通过在 Fedora 上用你的音乐客户端播放一首歌来测试它。你播放的歌曲会出现在 ListenBrainz 个人资料页中。
|
||||
|
||||
![Basic statistics and play history from a user profile on ListenBrainz. The current track is playing on a Fedora Workstation laptop with mpris-scrobbler.][14]
|
||||
|
||||
### playerctl 可以控制音乐回放
|
||||
|
||||
`playerctl` 是一个命令行工具,它可以控制任何实现了 MPRIS D-Bus 接口的音乐播放器。你可以轻松地将其绑定到键盘快捷键或媒体热键上。以下是如何在命令行中安装、使用它,以及为 i3 窗口管理器创建键绑定的方法。
|
||||
|
||||
#### 安装和使用 playerctl
|
||||
|
||||
`playerctl` 在 Fedora 28 或更高版本中可用。在终端运行如下命令以安装:
|
||||
|
||||
```
|
||||
sudo dnf install playerctl
|
||||
```
|
||||
|
||||
现在已安装好,你可以立即使用它。在 Fedora 上打开你的音乐播放器。接下来,尝试用以下命令来控制终端的播放。
|
||||
|
||||
播放或暂停当前播放的曲目:
|
||||
|
||||
```
|
||||
playerctl play-pause
|
||||
```
|
||||
|
||||
如果你想跳过下一首曲目:
|
||||
|
||||
```
|
||||
playerctl next
|
||||
```
|
||||
|
||||
列出所有正在运行的播放器:
|
||||
|
||||
```
|
||||
playerctl -l
|
||||
```
|
||||
|
||||
仅使用 spotify 客户端播放或暂停当前播放的内容:
|
||||
|
||||
```
|
||||
playerctl -p spotify play-pause
|
||||
```
|
||||
|
||||
#### 在 i3wm 中创建 playerctl 键绑定
|
||||
|
||||
你是否使用窗口管理器,比如 [i3 窗口管理器][2]?尝试使用 `playerctl` 进行键绑定。你可以将不同的命令绑定到不同的快捷键,例如键盘上的播放/暂停按钮。参照下面的 [i3wm 配置摘录][15] 看看如何做:
|
||||
|
||||
```
|
||||
# Media player controls
|
||||
bindsym XF86AudioPlay exec "playerctl play-pause"
|
||||
bindsym XF86AudioNext exec "playerctl next"
|
||||
bindsym XF86AudioPrev exec "playerctl previous"
|
||||
```
|
||||
|
||||
### 体验一下音乐播放器
|
||||
|
||||
想了解关于在 Fedora 上定制音乐聆听体验的更多信息吗?Fedora Magazine 为你提供服务。看看 Fedora 上这[五个很酷的音乐播放器][16]。
|
||||
|
||||
也可以通过使用 MusicBrainz Picard 对音乐库进行排序和组织,[为你的混乱的音乐库带来秩序][17]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/2-new-apps-for-music-tweakers-on-fedora-workstation/
|
||||
|
||||
作者:[Justin W. Flory][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://fedoramagazine.org/author/jflory7/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/2-music-tweak-apps-816x345.jpg
|
||||
[2]: https://fedoramagazine.org/getting-started-i3-window-manager/
|
||||
[3]: https://github.com/mariusor/mpris-scrobbler
|
||||
[4]: https://github.com/acrisci/playerctl
|
||||
[5]: https://www.last.fm/
|
||||
[6]: https://libre.fm/
|
||||
[7]: https://listenbrainz.org/
|
||||
[8]: https://specifications.freedesktop.org/mpris-spec/latest/
|
||||
[9]: https://www.videolan.org/vlc/
|
||||
[10]: https://cmus.github.io/
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2019/02/Screenshot_2019-04-13-jflory7%E2%80%99s-week-in-music2-1024x500.png
|
||||
[12]: https://github.com/mariusor/mpris-scrobbler#authenticate-to-the-service
|
||||
[13]: https://listenbrainz.org/profile/
|
||||
[14]: https://fedoramagazine.org/wp-content/uploads/2019/04/Screenshot_2019-04-13-User-jflory-ListenBrainz.png
|
||||
[15]: https://github.com/jwflory/swiss-army/blob/ba6ac0c71855e33e3caa1ee1fe51c05d2df0529d/roles/apps/i3wm/files/config#L207-L210
|
||||
[16]: https://fedoramagazine.org/5-cool-music-player-apps/
|
||||
[17]: https://fedoramagazine.org/picard-brings-order-music-library/
|
||||
[18]: https://unsplash.com/photos/Qrspubmx6kE?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
||||
[19]: https://unsplash.com/search/photos/music?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
|
@ -0,0 +1,67 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10814-1.html)
|
||||
[#]: subject: (8 environment-friendly open software projects you should know)
|
||||
[#]: via: (https://opensource.com/article/19/4/environment-projects)
|
||||
[#]: author: (Laura Hilliger https://opensource.com/users/laurahilliger)
|
||||
|
||||
8 个你应该了解的环保开源项目
|
||||
======
|
||||
|
||||
> 通过给这些致力于提升环境的项目做贡献来庆祝地球日。
|
||||
|
||||
![][1]
|
||||
|
||||
在过去的几年里,我一直在帮助 [Greenpeace][2] 建立其第一个完全开源的软件项目,Planet 4. [Planet 4][3] 是一个全球参与平台,Greenpeace 的支持者和活动家可以互动并参与组织。它的目标是让人们代表我们的星球采取行动。我们希望邀请参与并利用人力来应对气候变化和塑料污染等全球性问题。开发者、设计师、作者、贡献者和其他通过开源支持环保主义的人都非常欢迎[参与进来][4]!
|
||||
|
||||
Planet 4 远非唯一关注环境的开源项目。对于地球日,我会分享其他七个关注我们星球的开源项目。
|
||||
|
||||
[Eco Hacker Farm][5] 致力于支持可持续社区。它建议并支持将黑客空间/黑客基地和永续农业生活结合在一起的项目。该组织还有在线项目。访问其 [wiki][6] 或 [Twitter][7] 了解有关 Eco Hacker Farm 正在做的更多信息。
|
||||
|
||||
[Public Lab][8] 是一个开放社区和非营利组织,它致力于将科学掌握在公民手中。它于 2010 年在 BP 石油灾难后形成,Public Lab 与开源合作,协助环境勘探和调查。它是一个多元化的社区,有很多方法可以做[贡献][9]。
|
||||
|
||||
不久前,Opensource.com 的社区管理者 Don Watkins 撰写了一篇 [Open Climate Workbench][10] 的文章,该项目来自 Apache 基金会。 [OCW][11] 提供了进行气候建模和评估的软件,可用于各种应用。
|
||||
|
||||
[Open Source Ecology][12] 是一个旨在改善经济运作方式的项目。该项目着眼于环境再生和社会公正,它旨在重新界定我们的一些肮脏的生产和分配技术,以创造一个更可持续的文明。
|
||||
|
||||
促进开源和大数据工具之间的合作,以实现海洋、大气、土地和气候的研究,“ [Pangeo][13] 是第一个推广开放、可重复和可扩展科学的社区。”大数据可以改变世界!
|
||||
|
||||
[Leaflet][14] 是一个著名的开源 JavaScript 库。它可以做各种各样的事情,包括环保项目,如 [Arctic Web Map][15],它能让科学家准确地可视化和分析北极地区,这是气候研究的关键能力。
|
||||
|
||||
当然,没有我在 Mozilla 的朋友就没有这个列表(这不是个完整的列表!)。[Mozilla Science Lab][16] 社区就像所有 Mozilla 项目一样,非常开放,它致力于将开源原则带给科学界。它的项目和社区使科学家能够进行我们世界所需的各种研究,以解决一些最普遍的环境问题。
|
||||
|
||||
### 如何贡献
|
||||
|
||||
在这个地球日,做为期六个月的承诺,将一些时间贡献给一个有助于应对气候变化的开源项目,或以其他方式鼓励人们保护地球母亲。肯定还有许多关注环境的开源项目,所以请在评论中留言!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/environment-projects
|
||||
|
||||
作者:[Laura Hilliger][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/laurahilliger
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/world_hands_diversity.png?itok=zm4EDxgE
|
||||
[2]: http://www.greenpeace.org
|
||||
[3]: http://medium.com/planet4
|
||||
[4]: https://planet4.greenpeace.org/community/#partners-open-sourcers
|
||||
[5]: https://wiki.ecohackerfarm.org/start
|
||||
[6]: https://wiki.ecohackerfarm.org/
|
||||
[7]: https://twitter.com/EcoHackerFarm
|
||||
[8]: https://publiclab.org/
|
||||
[9]: https://publiclab.org/contribute
|
||||
[10]: https://opensource.com/article/17/1/apache-open-climate-workbench
|
||||
[11]: https://climate.apache.org/
|
||||
[12]: https://wiki.opensourceecology.org/wiki/Project_needs
|
||||
[13]: http://pangeo.io/
|
||||
[14]: https://leafletjs.com/
|
||||
[15]: https://webmap.arcticconnect.ca/#ac_3573/2/20.8/-65.5
|
||||
[16]: https://science.mozilla.org/
|
@ -0,0 +1,96 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10807-1.html)
|
||||
[#]: subject: (Tracking the weather with Python and Prometheus)
|
||||
[#]: via: (https://opensource.com/article/19/4/weather-python-prometheus)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
使用 Python 和 Prometheus 跟踪天气
|
||||
======
|
||||
|
||||
> 创建自定义 Prometheus 集成以跟踪最大的云端提供商:地球母亲。
|
||||
|
||||
![Tree clouds][1]
|
||||
|
||||
开源监控系统 [Prometheus][2] 集成了跟踪多种类型的时间序列数据,但如果没有集成你想要的数据,那么很容易构建一个。一个经常使用的例子使用云端提供商的自定义集成,它使用提供商的 API 抓取特定的指标。但是,在这个例子中,我们将与最大云端提供商集成:地球。
|
||||
|
||||
幸运的是,美国政府已经测量了天气并为集成提供了一个简单的 API。获取红帽总部下一个小时的天气预报很简单。
|
||||
|
||||
```
|
||||
import requests
|
||||
HOURLY_RED_HAT = "<https://api.weather.gov/gridpoints/RAH/73,57/forecast/hourly>"
|
||||
def get_temperature():
|
||||
result = requests.get(HOURLY_RED_HAT)
|
||||
return result.json()["properties"]["periods"][0]["temperature"]
|
||||
```
|
||||
|
||||
现在我们已经完成了与地球的集成,现在是确保 Prometheus 能够理解我们想要内容的时候了。我们可以使用 [Prometheus Python 库][3]中的 gauge 创建一个注册项:红帽总部的温度。
|
||||
|
||||
|
||||
```
|
||||
from prometheus_client import CollectorRegistry, Gauge
|
||||
def prometheus_temperature(num):
|
||||
registry = CollectorRegistry()
|
||||
g = Gauge("red_hat_temp", "Temperature at Red Hat HQ", registry=registry)
|
||||
g.set(num)
|
||||
return registry
|
||||
```
|
||||
|
||||
最后,我们需要以某种方式将它连接到 Prometheus。这有点依赖 Prometheus 的网络拓扑:是 Prometheus 与我们的服务通信更容易,还是反向更容易。
|
||||
|
||||
第一种是通常建议的情况,如果可能的话,我们需要构建一个公开注册入口的 Web 服务器,并配置 Prometheus 收刮(scrape)它。
|
||||
|
||||
我们可以使用 [Pyramid][4] 构建一个简单的 Web 服务器。
|
||||
|
||||
```
|
||||
from pyramid.config import Configurator
|
||||
from pyramid.response import Response
|
||||
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST
|
||||
def metrics_web(request):
|
||||
registry = prometheus_temperature(get_temperature())
|
||||
return Response(generate_latest(registry),
|
||||
content_type=CONTENT_TYPE_LATEST)
|
||||
config = Configurator()
|
||||
config.add_route('metrics', '/metrics')
|
||||
config.add_view(metrics_web, route_name='metrics')
|
||||
app = config.make_wsgi_app()
|
||||
```
|
||||
|
||||
这可以使用任何 Web 网关接口(WSGI)服务器运行。例如,假设我们将代码放在 `earth.py` 中,我们可以使用 `python -m twisted web --wsgi earth.app` 来运行它。
|
||||
|
||||
或者,如果我们的代码连接到 Prometheus 更容易,我们可以定期将其推送到 Prometheus 的[推送网关][5]。
|
||||
|
||||
```
|
||||
import time
|
||||
from prometheus_client import push_to_gateway
|
||||
def push_temperature(url):
|
||||
while True:
|
||||
registry = prometheus_temperature(get_temperature())
|
||||
push_to_gateway(url, "temperature collector", registry)
|
||||
time.sleep(60*60)
|
||||
```
|
||||
|
||||
这里的 URL 是推送网关的 URL。它通常以 `:9091` 结尾。
|
||||
|
||||
祝你构建自定义 Prometheus 集成成功,以便跟踪一切!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/4/weather-python-prometheus
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life_tree_clouds.png?itok=b_ftihhP (Tree clouds)
|
||||
[2]: https://prometheus.io/
|
||||
[3]: https://github.com/prometheus/client_python
|
||||
[4]: https://trypyramid.com/
|
||||
[5]: https://github.com/prometheus/pushgateway
|
@ -0,0 +1,138 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10800-1.html)
|
||||
[#]: subject: (Four Methods To Check The Default Gateway Or Router IP Address In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/check-find-default-gateway-or-router-ip-address-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
4 种在 Linux 中检查默认网关或者路由器 IP 地址的方法
|
||||
==============================================
|
||||
|
||||
你应该意识到你的默认网关是你的路由器的 IP 地址。一般这是在安装过程中由操作系统自动检测的,如果没有,你可能需要改变它。如果你的系统不能 ping 自身,那么很可能是一个网关问题,你必须修复它。在网络中,当你有多个网络适配器或路由器时,这种情况可能会发生。
|
||||
|
||||
网关是一个扮演着入口点角色的路由器,可以从一个网络传递网络数据到另一个网络。
|
||||
|
||||
下面是一些可能帮助你收集到与该话题相似的一些信息。
|
||||
|
||||
* [在 Linux 命令行检查你的公网 IP 地址的 9 种方法][1]
|
||||
* [如何在 Linux 启用和禁用网卡?][2]
|
||||
|
||||
这可以通过下面的四个命令完成。
|
||||
|
||||
* `route` 命令:被用来显示和操作 IP 路由表。
|
||||
* `ip` 命令:类似于 `ifconfig`,常用于设置静态 IP 地址、路由 & 默认网关,等等。
|
||||
* `netstat` 命令:是一个命令行工具,用来显示网络连接相关的信息(包括入站和出站的),例如路由表、伪装连接、多播成员和网络接口。
|
||||
* `routel` 命令:被用来以好看的输出格式列出路由。
|
||||
|
||||
### 1)在 Linux 中如何使用 route 命令检查默认的网关或者路由 IP 地址?
|
||||
|
||||
`route` 命令被用来显示和操作 IP 路由表。
|
||||
|
||||
它主要用于通过一个已经配置的接口给特定的主机或者网络设置静态的路由。
|
||||
|
||||
当使用 `add` 或者 `del` 选项时,`route` 修改路由表。没有这些选项,`route` 显示路由表的当前内容。
|
||||
|
||||
```
|
||||
# route
|
||||
或
|
||||
# route -n
|
||||
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
default www.routerlogin 0.0.0.0 UG 600 0 0 wlp8s0
|
||||
192.168.1.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp8s0
|
||||
```
|
||||
|
||||
### 2)如何在 Linux 中使用 ip 命令检查默认网关或者路由 IP 地址?
|
||||
|
||||
[IP 命令][3] 类似于 `ifconfig`,常用于配置静态 IP 地址、路由 & 默认网关,等等。
|
||||
|
||||
`ifconfig` 命令因为多年没有维护而被遗弃了,即使它仍然在大多数 Linux 发行版上可获得。
|
||||
|
||||
`ifconfig` 命令已经被 `ip` 命令替代了,`ip` 命令是非常强大的,只要一个命令就能执行几个网络管理任务。
|
||||
|
||||
`ip` 命令工具附带在 iproute2 包中。在主要的 Linux 发行版中都默认预装了 iproute2 。
|
||||
|
||||
如果没有,你可以在你的终端中在包管理器的帮助下通过指定 iproute2 来安装它。
|
||||
|
||||
```
|
||||
# ip r
|
||||
或
|
||||
# ip route
|
||||
或
|
||||
# ip route show
|
||||
|
||||
default via 192.168.1.1 dev wlp8s0 proto dhcp metric 600
|
||||
192.168.1.0/24 dev wlp8s0 proto kernel scope link src 192.168.1.6 metric 600
|
||||
```
|
||||
|
||||
### 3)如何在 Linux 中使用 netstat 命令检查默认网关或者路由 IP 地址?
|
||||
|
||||
`netstat` 代表 Network Statistics,是一个用来显示网络连接相关的信息(包括入站和出站)的命令行工具,例如路由表、伪装连接,多播成员和网络接口。
|
||||
|
||||
它列出所有的 tcp、udp 套接字连接和 unix 套接字连接。
|
||||
|
||||
它在网络中被用来诊断网络问题并判断网络中的流量总量来作为性能测量指标。
|
||||
|
||||
```
|
||||
# netstat -r
|
||||
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags MSS Window irtt Iface
|
||||
default www.routerlogin 0.0.0.0 UG 0 0 0 wlp8s0
|
||||
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 wlp8s0
|
||||
```
|
||||
|
||||
### 4)如何在 Linux 中使用 routel 命令检查默认网关或者路由 IP 地址?
|
||||
|
||||
它用来以好看的输出格式列出路由信息。这些程序是一系列你可以用来替代 iproute2 的帮助脚本(`routel` 和 `routef`)。
|
||||
|
||||
`routel` 脚本以一种被认为更容易解释并且等价于 `route` 输出列表的格式来输出路由信息。
|
||||
|
||||
如果 `routef` 脚本不加任何参数,将仅仅简单的将路由表清空。小心!这意味着删除所有的路由,让你的网络不再可用。
|
||||
|
||||
```
|
||||
# routel
|
||||
target gateway source proto scope dev tbl
|
||||
default 192.168.1.1 dhcp wlp8s0
|
||||
192.168.1.0/ 24 192.168.1.6 kernel link wlp8s0
|
||||
127.0.0.0 broadcast 127.0.0.1 kernel link lo local
|
||||
127.0.0.0/ 8 local 127.0.0.1 kernel host lo local
|
||||
127.0.0.1 local 127.0.0.1 kernel host lo local
|
||||
127.255.255.255 broadcast 127.0.0.1 kernel link lo local
|
||||
192.168.1.0 broadcast 192.168.1.6 kernel link wlp8s0 local
|
||||
192.168.1.6 local 192.168.1.6 kernel host wlp8s0 local
|
||||
192.168.1.255 broadcast 192.168.1.6 kernel link wlp8s0 local
|
||||
::1 kernel lo
|
||||
fe80::/ 64 kernel wlp8s0
|
||||
::1 local kernel lo local
|
||||
fe80::ad00:2f7e:d882:5add local kernel wlp8s0 local
|
||||
ff00::/ 8 wlp8s0 local
|
||||
```
|
||||
|
||||
如果你只想打印默认的网关那么使用下面的格式。
|
||||
|
||||
|
||||
```
|
||||
# routel | grep default
|
||||
default 192.168.1.1 dhcp wlp8s0
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/check-find-default-gateway-or-router-ip-address-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[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/check-find-server-public-ip-address-linux/
|
||||
[2]: https://www.2daygeek.com/enable-disable-up-down-nic-network-interface-port-linux-using-ifconfig-ifdown-ifup-ip-nmcli-nmtui/
|
||||
[3]: https://www.2daygeek.com/ip-command-configure-network-interface-usage-linux/
|
@ -0,0 +1,325 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (warmfrog)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10815-1.html)
|
||||
[#]: subject: (How To Monitor Disk I/O Activity Using iotop And iostat Commands In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/check-monitor-disk-io-in-linux-using-iotop-iostat-command/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
在 Linux 中如何使用 iotop 和 iostat 监控磁盘 I/O 活动?
|
||||
======================================
|
||||
|
||||
你知道在 Linux 中我们使用什么工具检修和监控实时的磁盘活动吗?如果 [Linux 系统性能][1]变慢,我们会用 [top 命令][2] 来查看系统性能。它被用来检查是什么进程在服务器上占有如此高的使用率,对于大多数 Linux 系统管理员来说很常见,现实世界中被 Linux 系统管理员广泛采用。
|
||||
|
||||
如果在进程输出中你没有看到很大的不同,你仍然有选择查看其他东西。我会建议你在 `top` 输出中检查 `wa` 状态,因为大多数时间里服务器性能由于在硬盘上的高 I/O 读和写降低了性能。如果它很高或者波动,很可能就是它造成的。因此,我们需要检查硬盘上的 I/O 活动。
|
||||
|
||||
我们可以在 Linux 中使用 `iotop` 和 `iostat` 命令监控所有的磁盘和文件系统的磁盘 I/O 统计。
|
||||
|
||||
### 什么是 iotop?
|
||||
|
||||
`iotop` 是一个类似 `top` 的工具,用来显示实时的磁盘活动。
|
||||
|
||||
`iotop` 监控 Linux 内核输出的 I/O 使用信息,并且显示一个系统中进程或线程的当前 I/O 使用情况。
|
||||
|
||||
它显示每个进程/线程读写 I/O 带宽。它同样显示当等待换入和等待 I/O 的线程/进程花费的时间的百分比。
|
||||
|
||||
`Total DISK READ` 和 `Total DISK WRITE` 的值一方面表示了进程和内核线程之间的总的读写带宽,另一方面也表示内核块设备子系统的。
|
||||
|
||||
`Actual DISK READ` 和 `Actual DISK WRITE` 的值表示在内核块设备子系统和下面硬件(HDD、SSD 等等)对应的实际磁盘 I/O 带宽。
|
||||
|
||||
### 如何在 Linux 中安装 iotop ?
|
||||
|
||||
我们可以轻松在包管理器的帮助下安装,因为该软件包在所有的 Linux 发行版仓库中都可以获得。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][3] 来安装 `iotop`。
|
||||
|
||||
```
|
||||
$ sudo dnf install iotop
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [API-GET 命令][4] 或者 [APT 命令][5] 来安装 `iotop`。
|
||||
|
||||
```
|
||||
$ sudo apt install iotop
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman Command][6] 来安装 `iotop`。
|
||||
|
||||
```
|
||||
$ sudo pacman -S iotop
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 的系统,使用 [YUM Command][7] 来安装 `iotop`。
|
||||
|
||||
```
|
||||
$ sudo yum install iotop
|
||||
```
|
||||
|
||||
对于使用 openSUSE Leap 的系统,使用 [Zypper Command][8] 来安装 `iotop`。
|
||||
|
||||
```
|
||||
$ sudo zypper install iotop
|
||||
```
|
||||
|
||||
### 在 Linux 中如何使用 iotop 命令来监控磁盘 I/O 活动/统计?
|
||||
|
||||
`iotop` 命令有很多参数来检查关于磁盘 I/O 的变化:
|
||||
|
||||
```
|
||||
# iotop
|
||||
```
|
||||
|
||||
![10]
|
||||
|
||||
如果你想检查那个进程实际在做 I/O,那么运行 `iotop` 命令加上 `-o` 或者 `--only` 参数。
|
||||
|
||||
```
|
||||
# iotop --only
|
||||
```
|
||||
|
||||
![11]
|
||||
|
||||
细节:
|
||||
|
||||
* `IO`:它显示每个进程的 I/O 利用率,包含磁盘和交换。
|
||||
* `SWAPIN`: 它只显示每个进程的交换使用率。
|
||||
|
||||
### 什么是 iostat?
|
||||
|
||||
`iostat` 被用来报告中央处理单元(CPU)的统计和设备与分区的输出/输出的统计。
|
||||
|
||||
`iostat` 命令通过观察与它们平均传输率相关的设备活跃时间来监控系统输入/输出设备负载。
|
||||
|
||||
`iostat` 命令生成的报告可以被用来改变系统配置来更好的平衡物理磁盘之间的输入/输出负载。
|
||||
|
||||
所有的统计都在 `iostat` 命令每次运行时被报告。该报告包含一个 CPU 头部,后面是一行 CPU 统计。
|
||||
|
||||
在多处理器系统中,CPU 统计被计算为系统层面的所有处理器的平均值。设备头行后紧跟显示每个配置的设备一行的统计。
|
||||
|
||||
`iostat` 命令生成两种类型的报告,CPU 利用率报告和设备利用率报告。
|
||||
|
||||
### 在 Linux 中怎样安装 iostat?
|
||||
|
||||
`iostat` 工具是 `sysstat` 包的一部分,所以我们可以轻松地在包管理器地帮助下安装,因为在所有的 Linux 发行版的仓库都是可以获得的。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF Command][3] 来安装 `sysstat`。
|
||||
|
||||
```
|
||||
$ sudo dnf install sysstat
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET Command][4] 或者 [APT Command][5] 来安装 `sysstat`。
|
||||
|
||||
```
|
||||
$ sudo apt install sysstat
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman Command][6] 来安装 `sysstat`。
|
||||
|
||||
```
|
||||
$ sudo pacman -S sysstat
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统,使用 [YUM Command][7] 来安装 `sysstat`。
|
||||
|
||||
```
|
||||
$ sudo yum install sysstat
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper Command][8] 来安装 `sysstat`。
|
||||
|
||||
```
|
||||
$ sudo zypper install sysstat
|
||||
```
|
||||
|
||||
### 在 Linux 中如何使用 sysstat 命令监控磁盘 I/O 活动/统计?
|
||||
|
||||
在 `iostat` 命令中有很多参数来检查关于 I/O 和 CPU 的变化统计信息。
|
||||
|
||||
不加参数运行 `iostat` 命令会看到完整的系统统计。
|
||||
|
||||
```
|
||||
# iostat
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.45 0.02 16.47 0.12 0.00 53.94
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
nvme0n1 6.68 126.95 124.97 0.00 58420014 57507206 0
|
||||
sda 0.18 6.77 80.24 0.00 3115036 36924764 0
|
||||
loop0 0.00 0.00 0.00 0.00 2160 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 1093 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 1077 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令加上 `-d` 参数查看所有设备的 I/O 统计。
|
||||
|
||||
```
|
||||
# iostat -d
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
nvme0n1 6.68 126.95 124.97 0.00 58420030 57509090 0
|
||||
sda 0.18 6.77 80.24 0.00 3115292 36924764 0
|
||||
loop0 0.00 0.00 0.00 0.00 2160 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 1093 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 1077 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令加上 `-p` 参数查看所有的设备和分区的 I/O 统计。
|
||||
|
||||
```
|
||||
# iostat -p
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.42 0.02 16.45 0.12 0.00 53.99
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
nvme0n1 6.68 126.94 124.96 0.00 58420062 57512278 0
|
||||
nvme0n1p1 6.40 124.46 118.36 0.00 57279753 54474898 0
|
||||
nvme0n1p2 0.27 2.47 6.60 0.00 1138069 3037380 0
|
||||
sda 0.18 6.77 80.23 0.00 3116060 36924764 0
|
||||
sda1 0.00 0.01 0.00 0.00 3224 0 0
|
||||
sda2 0.18 6.76 80.23 0.00 3111508 36924764 0
|
||||
loop0 0.00 0.00 0.00 0.00 2160 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 1093 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 1077 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令加上 `-x` 参数显示所有设备的详细的 I/O 统计信息。
|
||||
|
||||
```
|
||||
# iostat -x
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.41 0.02 16.45 0.12 0.00 54.00
|
||||
|
||||
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
|
||||
nvme0n1 2.45 126.93 0.60 19.74 0.40 51.74 4.23 124.96 5.12 54.76 3.16 29.54 0.00 0.00 0.00 0.00 0.00 0.00 0.31 30.28
|
||||
sda 0.06 6.77 0.00 0.00 8.34 119.20 0.12 80.23 19.94 99.40 31.84 670.73 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13
|
||||
loop0 0.00 0.00 0.00 0.00 0.08 19.64 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||
loop1 0.00 0.00 0.00 0.00 0.40 12.86 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||
loop2 0.00 0.00 0.00 0.00 0.38 19.58 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||
```
|
||||
|
||||
运行 `iostat` 命令加上 `-d [设备名]` 参数查看具体设备和它的分区的 I/O 统计信息。
|
||||
|
||||
```
|
||||
# iostat -p [Device_Name]
|
||||
|
||||
# iostat -p sda
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.38 0.02 16.43 0.12 0.00 54.05
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
sda 0.18 6.77 80.21 0.00 3117468 36924764 0
|
||||
sda2 0.18 6.76 80.21 0.00 3112916 36924764 0
|
||||
sda1 0.00 0.01 0.00 0.00 3224 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令加上 `-m` 参数以 MB 为单位而不是 KB 查看所有设备的统计。默认以 KB 显示输出。
|
||||
|
||||
```
|
||||
# iostat -m
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.36 0.02 16.41 0.12 0.00 54.09
|
||||
|
||||
Device tps MB_read/s MB_wrtn/s MB_dscd/s MB_read MB_wrtn MB_dscd
|
||||
nvme0n1 6.68 0.12 0.12 0.00 57050 56176 0
|
||||
sda 0.18 0.01 0.08 0.00 3045 36059 0
|
||||
loop0 0.00 0.00 0.00 0.00 2 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 1 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 1 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令使用特定的间隔使用如下的格式。在这个例子中,我们打算以 5 秒捕获的间隔捕获两个报告。
|
||||
|
||||
```
|
||||
# iostat [Interval] [Number Of Reports]
|
||||
|
||||
# iostat 5 2
|
||||
|
||||
Linux 4.19.32-1-MANJARO (daygeek-Y700) Thursday 18 April 2019 _x86_64_ (8 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
29.35 0.02 16.41 0.12 0.00 54.10
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
nvme0n1 6.68 126.89 124.95 0.00 58420116 57525344 0
|
||||
sda 0.18 6.77 80.20 0.00 3118492 36924764 0
|
||||
loop0 0.00 0.00 0.00 0.00 2160 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 1093 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 1077 0 0
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
3.71 0.00 2.51 0.05 0.00 93.73
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
|
||||
nvme0n1 19.00 0.20 311.40 0.00 1 1557 0
|
||||
sda 0.20 25.60 0.00 0.00 128 0 0
|
||||
loop0 0.00 0.00 0.00 0.00 0 0 0
|
||||
loop1 0.00 0.00 0.00 0.00 0 0 0
|
||||
loop2 0.00 0.00 0.00 0.00 0 0 0
|
||||
```
|
||||
|
||||
运行 `iostat` 命令与 `-N` 参数来查看 LVM 磁盘 I/O 统计报告。
|
||||
|
||||
```
|
||||
# iostat -N
|
||||
|
||||
Linux 4.15.0-47-generic (Ubuntu18.2daygeek.com) Thursday 18 April 2019 _x86_64_ (2 CPU)
|
||||
|
||||
avg-cpu: %user %nice %system %iowait %steal %idle
|
||||
0.38 0.07 0.18 0.26 0.00 99.12
|
||||
|
||||
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
|
||||
sda 3.60 57.07 69.06 968729 1172340
|
||||
sdb 0.02 0.33 0.00 5680 0
|
||||
sdc 0.01 0.12 0.00 2108 0
|
||||
2g-2gvol1 0.00 0.07 0.00 1204 0
|
||||
```
|
||||
|
||||
运行 `nfsiostat` 命令来查看 Network File System(NFS)的 I/O 统计。
|
||||
|
||||
```
|
||||
# nfsiostat
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/check-monitor-disk-io-in-linux-using-iotop-iostat-command/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[warmfrog](https://github.com/warmfrog)
|
||||
校对:[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/category/monitoring-tools/
|
||||
[2]: https://www.2daygeek.com/linux-top-command-linux-system-performance-monitoring-tool/
|
||||
[3]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[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]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2015/03/monitor-disk-io-activity-using-iotop-iostat-command-in-linux-1.jpg
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2015/03/monitor-disk-io-activity-using-iotop-iostat-command-in-linux-2.jpg
|
96
published/20190430 Upgrading Fedora 29 to Fedora 30.md
Normal file
96
published/20190430 Upgrading Fedora 29 to Fedora 30.md
Normal file
@ -0,0 +1,96 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10854-1.html)
|
||||
[#]: subject: (Upgrading Fedora 29 to Fedora 30)
|
||||
[#]: via: (https://fedoramagazine.org/upgrading-fedora-29-to-fedora-30/)
|
||||
[#]: author: (Ryan Lerch https://fedoramagazine.org/author/ryanlerch/)
|
||||
|
||||
将 Fedora 29 升级到 Fedora 30
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Fedora 30 [已经发布了][2]。你可能希望将系统升级到最新版本的 Fedora。Fedora 工作站版本有图形化升级的方法。另外,Fedora 也提供了一个命令行方法,用于将 Fedora 29 升级到 Fedora 30。
|
||||
|
||||
### 将 Fedora 29 工作站版本升级到 Fedora 30
|
||||
|
||||
在发布不久后,桌面会显示一条通知告诉你可以升级。你可以单击通知启动 “GNOME 软件” 应用。或者你可以从 GNOME Shell 中选择“软件”。
|
||||
|
||||
在 “GNOME 软件” 中选择*更新*选项卡,你会看到一个页面通知你可以更新 Fedora 30。
|
||||
|
||||
如果你在屏幕上看不到任何内容,请尝试点击左上角的重新加载按钮。发布后,所有系统都可能需要一段时间才能看到可用的升级。
|
||||
|
||||
选择“下载”获取升级包。你可以继续做其他的事直到下载完成。然后使用 “GNOME 软件” 重启系统并应用升级。升级需要时间,因此你可以喝杯咖啡,稍后再回来。
|
||||
|
||||
### 使用命令行
|
||||
|
||||
如果你过去升级过 Fedora 版本,你可能熟悉 `dnf upgrade` 插件。这是从 Fedora 29 升级到 Fedora 30 的推荐和支持的方式。使用这个插件将使你的 Fedora 30 升级简单易行。
|
||||
|
||||
#### 1、更新软件并备份系统
|
||||
|
||||
在你执行任何操作之前,你需要确保在开始升级之前拥有 Fedora 29 的最新软件。要更新软件,请使用 “GNOME 软件” 或在终端中输入以下命令。
|
||||
|
||||
```
|
||||
sudo dnf upgrade --refresh
|
||||
```
|
||||
|
||||
此外,请确保在继续之前备份系统。关于备份的帮助,请参阅 Fedora Magazine 上的[备份系列][3]。
|
||||
|
||||
#### 2、安装 DNF 插件
|
||||
|
||||
接下来,打开终端并输入以下命令来安装插件:
|
||||
|
||||
```
|
||||
sudo dnf install dnf-plugin-system-upgrade
|
||||
```
|
||||
|
||||
#### 3、使用 DNF 开始更新
|
||||
|
||||
现在你的系统是最新的,完成了备份,并且已安装 DNF 插件,你可以在终端中使用以下命令开始升级:
|
||||
|
||||
```
|
||||
sudo dnf system-upgrade download --releasever=30
|
||||
```
|
||||
|
||||
此命令将开始在本地下载所有升级文件以准备升级。如果你因为没有更新包、错误的依赖,或过时的包在升级时遇到问题,请在输入上面的命令时添加 `-- allowerasing` 标志。这将允许 DNF 删除可能阻止系统升级的软件包。
|
||||
|
||||
#### 4、重启并升级
|
||||
|
||||
当前面的命令完成下载所有升级文件后,你的系统就可以重启了。要将系统引导至升级过程,请在终端中输入以下命令:
|
||||
|
||||
```
|
||||
sudo dnf system-upgrade reboot
|
||||
```
|
||||
|
||||
此后你的系统将重启。在许多版本之前,`fedup` 工具将在内核选择/引导页面上创建一个新选项。使用 `dnf-plugin-system-upgrade` 包,你的系统将使用当前 Fedora 29 安装的内核重启。这个是正常的。在内核选择页面后不久,系统开始升级过程。
|
||||
|
||||
现在可以休息一下了!完成后你的系统将重启,你就可以登录新升级的 Fedora 30 了。
|
||||
|
||||
![][4]
|
||||
|
||||
### 解决升级问题
|
||||
|
||||
升级系统时偶尔可能会出现意外问题。如果你遇到任何问题,请访问 [DNF 系统升级的维基页面][5],以获取有关出现问题时的故障排除的更多信息。
|
||||
|
||||
如果你在升级时遇到问题并在系统上安装了第三方仓库,那么可能需要在升级时禁用这些仓库。有关 Fedora 对未提供仓库的支持,请与仓库的提供商联系。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/upgrading-fedora-29-to-fedora-30/
|
||||
|
||||
作者:[Ryan Lerch][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/ryanlerch/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/04/29-30-816x345.jpg
|
||||
[2]: https://fedoramagazine.org/announcing-fedora-30/
|
||||
[3]: https://fedoramagazine.org/taking-smart-backups-duplicity/
|
||||
[4]: https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot_f23-ws-upgrade-test_2016-06-10_110906-1024x768.png
|
||||
[5]: https://fedoraproject.org/wiki/DNF_system_upgrade#Resolving_post-upgrade_issues
|
@ -0,0 +1,81 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10859-1.html)
|
||||
[#]: subject: (Write faster C extensions for Python with Cython)
|
||||
[#]: via: (https://opensource.com/article/19/5/python-cython)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez/users/moshez/users/foundjem/users/jugmac00)
|
||||
|
||||
使用 Cython 为 Python 编写更快的 C 扩展
|
||||
======
|
||||
|
||||
> 在我们这个包含了 7 个 PyPI 库的系列文章中学习解决常见的 Python 问题的方法。
|
||||
|
||||

|
||||
|
||||
Python 是当今使用最多的[流行编程语言][2]之一,因为:它是开源的,它有广泛的用途(例如 Web 编程、业务应用、游戏、科学编程等等),它有一个充满活力和专注的社区支持它。这个社区可以让我们在 [Python Package Index][3](PyPI)中有如此庞大、多样化的软件包,用以扩展和改进 Python 并解决不可避免的问题。
|
||||
|
||||
在本系列中,我们将介绍七个可以帮助你解决常见 Python 问题的 PyPI 库。首先是 [Cython][4],一个简化 Python 编写 C 扩展的语言。
|
||||
|
||||
### Cython
|
||||
|
||||
使用 Python 很有趣,但有时,用它编写的程序可能很慢。所有的运行时动态调度会带来很大的代价:有时它比用 C 或 Rust 等系统语言编写的等效代码慢 10 倍。
|
||||
|
||||
将代码迁移到一种全新的语言可能会在成本和可靠性方面付出巨大代价:所有的手工重写工作都将不可避免地引入错误。我们可以两者兼得么?
|
||||
|
||||
为了练习一下优化,我们需要一些慢代码。有什么比斐波那契数列的意外指数实现更慢?
|
||||
|
||||
```
|
||||
def fib(n):
|
||||
if n < 2:
|
||||
return 1
|
||||
return fib(n-1) + fib(n-2)
|
||||
```
|
||||
|
||||
由于对 `fib` 的调用会导致两次再次调用,因此这种效率极低的算法需要很长时间才能执行。例如,在我的新笔记本电脑上,`fib(36)` 需要大约 4.5 秒。这个 4.5 秒会成为我们探索 Python 的 Cython 扩展能提供的帮助的基准。
|
||||
|
||||
使用 Cython 的正确方法是将其集成到 `setup.py` 中。然而,使用 `pyximport` 可以快速地进行尝试。让我们将 `fib` 代码放在 `fib.pyx` 中并使用 Cython 运行它。
|
||||
|
||||
```
|
||||
>>> import pyximport; pyximport.install()
|
||||
>>> import fib
|
||||
>>> fib.fib(36)
|
||||
```
|
||||
|
||||
只使用 Cython 而不*修改*代码,这个算法在我笔记本上花费的时间减少到大约 2.5 秒。几乎无需任何努力,这几乎减少了 50% 的运行时间。当然,得到了一个不错的成果。
|
||||
|
||||
加把劲,我们可以让它变得更快。
|
||||
|
||||
```
|
||||
cpdef int fib(int n):
|
||||
if n < 2:
|
||||
return 1
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
```
|
||||
|
||||
我们将 `fib` 中的代码变成用 `cpdef` 定义的函数,并添加了两个类型注释:它接受一个整数并返回一个整数。
|
||||
|
||||
这个变得快*多*了,大约只用了 0.05 秒。它是如此之快,以至于我可能开始怀疑我的测量方法包含噪声:之前,这种噪声在信号中丢失了。
|
||||
|
||||
当下次你的 Python 代码花费太多 CPU 时间时,也许会导致风扇狂转,为何不看看 Cython 是否可以解决问题呢?
|
||||
|
||||
在本系列的下一篇文章中,我们将看一下 Black,一个自动纠正代码格式错误的项目。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/5/python-cython
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez/users/moshez/users/foundjem/users/jugmac00
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_hand_draw.png?itok=dpAf--Db (Hand drawing out the word "code")
|
||||
[2]: https://opensource.com/article/18/5/numbers-python-community-trends
|
||||
[3]: https://pypi.org/
|
||||
[4]: https://pypi.org/project/Cython/
|
@ -0,0 +1,99 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10864-1.html)
|
||||
[#]: subject: (Format Python however you like with Black)
|
||||
[#]: via: (https://opensource.com/article/19/5/python-black)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez/users/moshez/users/moshez)
|
||||
|
||||
使用 Black 自由格式化 Python
|
||||
======
|
||||
|
||||
> 在我们覆盖 7 个 PyPI 库的系列文章中了解解决 Python 问题的更多信息。
|
||||
|
||||

|
||||
|
||||
Python 是当今使用最多的[流行编程语言][2]之一,因为:它是开源的,它有广泛的用途(例如 Web 编程、业务应用、游戏、科学编程等等),它有一个充满活力和专注的社区支持它。这个社区可以让我们在 [Python Package Index][3](PyPI)中有如此庞大、多样化的软件包,用以扩展和改进 Python 并解决不可避免的问题。
|
||||
|
||||
在本系列中,我们将介绍七个可以帮助你解决常见 Python 问题的 PyPI 库。在第一篇文章中,我们了解了 [Cython][4]。今天,我们将使用 [Black][5] 这个代码格式化工具。
|
||||
|
||||
### Black
|
||||
|
||||
有时创意可能是一件美妙的事情。有时它只是一种痛苦。我喜欢创造性地解决难题,但我希望我的 Python 格式尽可能一致。没有人对使用“有趣”缩进的代码印象深刻。
|
||||
|
||||
但是比不一致的格式更糟糕的是除了检查格式之外什么都没有做的代码审查。这对审查者来说很烦人,对于被审查者来说甚至更烦人。当你的 linter 告诉你代码缩进不正确时,但没有提示*正确*的缩进量,这也会令人气愤。
|
||||
|
||||
使用 Black,它不会告诉你*要*做什么,它是一个优良、勤奋的机器人:它将为你修复代码。
|
||||
|
||||
要了解它如何工作的,请随意写一些非常不一致的内容,例如:
|
||||
|
||||
```
|
||||
def add(a, b): return a+b
|
||||
|
||||
def mult(a, b):
|
||||
return \
|
||||
a * b
|
||||
```
|
||||
|
||||
Black 抱怨了么?并没有,它为你修复了!
|
||||
|
||||
```
|
||||
$ black math
|
||||
reformatted math
|
||||
All done! ✨ 🍰 ✨
|
||||
1 file reformatted.
|
||||
$ cat math
|
||||
def add(a, b):
|
||||
return a + b
|
||||
|
||||
|
||||
def mult(a, b):
|
||||
return a * b
|
||||
```
|
||||
|
||||
Black 确实提供了报错而不是修复的选项,甚至还有输出 diff 编辑样式的选项。这些选项在持续集成 (CI)系统中非常有用,可以在本地强制运行 Black。此外,如果 diff 输出被记录到 CI 输出中,你可以直接将其粘贴到 `patch` 中,以便在极少数情况下你需要修复输出,但无法本地安装 Black 使用。
|
||||
|
||||
|
||||
```
|
||||
$ black --check --diff bad
|
||||
--- math 2019-04-09 17:24:22.747815 +0000
|
||||
+++ math 2019-04-09 17:26:04.269451 +0000
|
||||
@@ -1,7 +1,7 @@
|
||||
-def add(a, b): return a + b
|
||||
+def add(a, b):
|
||||
+ return a + b
|
||||
|
||||
|
||||
def mult(a, b):
|
||||
- return \
|
||||
- a * b
|
||||
+ return a * b
|
||||
|
||||
would reformat math
|
||||
All done! 💥 💔 💥
|
||||
1 file would be reformatted.
|
||||
$ echo $?
|
||||
1
|
||||
```
|
||||
|
||||
在本系列的下一篇文章中,我们将介绍 attrs ,这是一个可以帮助你快速编写简洁、正确的代码的库。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/5/python-black
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez/users/moshez/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openstack_python_vim_1.jpg?itok=lHQK5zpm (OpenStack source code (Python) in VIM)
|
||||
[2]: https://opensource.com/article/18/5/numbers-python-community-trends
|
||||
[3]: https://pypi.org/
|
||||
[4]: https://opensource.com/article/19/4/7-python-problems-solved-cython
|
||||
[5]: https://pypi.org/project/black/
|
197
published/20190505 How To Create SSH Alias In Linux.md
Normal file
197
published/20190505 How To Create SSH Alias In Linux.md
Normal file
@ -0,0 +1,197 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10851-1.html)
|
||||
[#]: subject: (How To Create SSH Alias In Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-create-ssh-alias-in-linux/)
|
||||
[#]: author: (sk https://www.ostechnix.com/author/sk/)
|
||||
|
||||
如何在 Linux 中创建 SSH 别名
|
||||
======
|
||||
|
||||

|
||||
|
||||
如果你经常通过 SSH 访问许多不同的远程系统,这个技巧将为你节省一些时间。你可以通过 SSH 为频繁访问的系统创建 SSH 别名,这样你就不必记住所有不同的用户名、主机名、SSH 端口号和 IP 地址等。此外,它避免了在 SSH 到 Linux 服务器时重复输入相同的用户名、主机名、IP 地址、端口号。
|
||||
|
||||
### 在 Linux 中创建 SSH 别名
|
||||
|
||||
在我知道这个技巧之前,我通常使用以下任意一种方式通过 SSH 连接到远程系统。
|
||||
|
||||
使用 IP 地址:
|
||||
|
||||
```
|
||||
$ ssh 192.168.225.22
|
||||
```
|
||||
|
||||
或使用端口号、用户名和 IP 地址:
|
||||
|
||||
```
|
||||
$ ssh -p 22 sk@192.168.225.22
|
||||
```
|
||||
|
||||
或使用端口号、用户名和主机名:
|
||||
|
||||
```
|
||||
$ ssh -p 22 sk@server.example.com
|
||||
```
|
||||
|
||||
这里
|
||||
|
||||
* `22` 是端口号,
|
||||
* `sk` 是远程系统的用户名,
|
||||
* `192.168.225.22` 是我远程系统的 IP,
|
||||
* `server.example.com` 是远程系统的主机名。
|
||||
|
||||
我相信大多数 Linux 新手和(或一些)管理员都会以这种方式通过 SSH 连接到远程系统。但是,如果你通过 SSH 连接到多个不同的系统,记住所有主机名或 IP 地址,还有用户名是困难的,除非你将它们写在纸上或者将其保存在文本文件中。别担心!这可以通过为 SSH 连接创建别名(或快捷方式)轻松解决。
|
||||
|
||||
我们可以用两种方法为 SSH 命令创建别名。
|
||||
|
||||
#### 方法 1 – 使用 SSH 配置文件
|
||||
|
||||
这是我创建别名的首选方法。
|
||||
|
||||
我们可以使用 SSH 默认配置文件来创建 SSH 别名。为此,编辑 `~/.ssh/config` 文件(如果此文件不存在,只需创建一个):
|
||||
|
||||
```
|
||||
$ vi ~/.ssh/config
|
||||
```
|
||||
|
||||
添加所有远程主机的详细信息,如下所示:
|
||||
|
||||
```
|
||||
Host webserver
|
||||
HostName 192.168.225.22
|
||||
User sk
|
||||
|
||||
Host dns
|
||||
HostName server.example.com
|
||||
User root
|
||||
|
||||
Host dhcp
|
||||
HostName 192.168.225.25
|
||||
User ostechnix
|
||||
Port 2233
|
||||
```
|
||||
|
||||
![][2]
|
||||
|
||||
*使用 SSH 配置文件在 Linux 中创建 SSH 别名*
|
||||
|
||||
将 `Host`、`Hostname`、`User` 和 `Port` 配置的值替换为你自己的值。添加所有远程主机的详细信息后,保存并退出该文件。
|
||||
|
||||
现在你可以使用以下命令通过 SSH 进入系统:
|
||||
|
||||
```
|
||||
$ ssh webserver
|
||||
$ ssh dns
|
||||
$ ssh dhcp
|
||||
```
|
||||
|
||||
就是这么简单!
|
||||
|
||||
看看下面的截图。
|
||||
|
||||
![][3]
|
||||
|
||||
*使用 SSH 别名访问远程系统*
|
||||
|
||||
看到了吗?我只使用别名(例如 `webserver`)来访问 IP 地址为 `192.168.225.22` 的远程系统。
|
||||
|
||||
请注意,这只使用于当前用户。如果要为所有用户(系统范围内)提供别名,请在 `/etc/ssh/ssh_config` 文件中添加以上行。
|
||||
|
||||
你还可以在 SSH 配置文件中添加许多其他内容。例如,如果你[已配置基于 SSH 密钥的身份验证][4],说明 SSH 密钥文件的位置,如下所示:
|
||||
|
||||
```
|
||||
Host ubuntu
|
||||
HostName 192.168.225.50
|
||||
User senthil
|
||||
IdentityFIle ~/.ssh/id_rsa_remotesystem
|
||||
```
|
||||
|
||||
确保已使用你自己的值替换主机名、用户名和 SSH 密钥文件路径。
|
||||
|
||||
现在使用以下命令连接到远程服务器:
|
||||
|
||||
```
|
||||
$ ssh ubuntu
|
||||
```
|
||||
|
||||
这样,你可以添加希望通过 SSH 访问的任意多台远程主机,并使用别名快速访问它们。
|
||||
|
||||
#### 方法 2 – 使用 Bash 别名
|
||||
|
||||
这是创建 SSH 别名的一种应急变通的方法,可以加快通信的速度。你可以使用 [alias 命令][5]使这项任务更容易。
|
||||
|
||||
打开 `~/.bashrc` 或者 `~/.bash_profile` 文件:
|
||||
|
||||
```
|
||||
alias webserver='ssh sk@server.example.com'
|
||||
alias dns='ssh sk@server.example.com'
|
||||
alias dhcp='ssh sk@server.example.com -p 2233'
|
||||
alias ubuntu='ssh sk@server.example.com -i ~/.ssh/id_rsa_remotesystem'
|
||||
```
|
||||
|
||||
再次确保你已使用自己的值替换主机、主机名、端口号和 IP 地址。保存文件并退出。
|
||||
|
||||
然后,使用命令应用更改:
|
||||
|
||||
```
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```
|
||||
$ source ~/.bash_profile
|
||||
```
|
||||
|
||||
在此方法中,你甚至不需要使用 `ssh 别名` 命令。相反,只需使用别名,如下所示。
|
||||
|
||||
```
|
||||
$ webserver
|
||||
$ dns
|
||||
$ dhcp
|
||||
$ ubuntu
|
||||
```
|
||||
|
||||
![][6]
|
||||
|
||||
这两种方法非常简单,但对于经常通过 SSH 连接到多个不同系统的人来说非常有用,而且非常方便。使用适合你的上述任何一种方法,通过 SSH 快速访问远程 Linux 系统。
|
||||
|
||||
建议阅读:
|
||||
|
||||
* [允许或拒绝 SSH 访问 Linux 中的特定用户或组][7]
|
||||
* [如何在 Linux 上 SSH 到特定目录][8]
|
||||
* [如何在 Linux 中断开 SSH 会话][9]
|
||||
* [4 种方式在退出 SSH 会话后保持命令运行][10]
|
||||
* [SSLH – 共享相同端口的 HTTPS 和 SSH][11]
|
||||
|
||||
目前这就是全部了,希望它对你有帮助。更多好东西要来了,敬请关注!
|
||||
|
||||
干杯!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-create-ssh-alias-in-linux/
|
||||
|
||||
作者:[sk][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.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/wp-content/uploads/2019/04/ssh-alias-720x340.png
|
||||
[2]: http://www.ostechnix.com/wp-content/uploads/2019/04/Create-SSH-Alias-In-Linux.png
|
||||
[3]: http://www.ostechnix.com/wp-content/uploads/2019/04/create-ssh-alias.png
|
||||
[4]: https://www.ostechnix.com/configure-ssh-key-based-authentication-linux/
|
||||
[5]: https://www.ostechnix.com/the-alias-and-unalias-commands-explained-with-examples/
|
||||
[6]: http://www.ostechnix.com/wp-content/uploads/2019/04/create-ssh-alias-1.png
|
||||
[7]: https://www.ostechnix.com/allow-deny-ssh-access-particular-user-group-linux/
|
||||
[8]: https://www.ostechnix.com/how-to-ssh-into-a-particular-directory-on-linux/
|
||||
[9]: https://www.ostechnix.com/how-to-stop-ssh-session-from-disconnecting-in-linux/
|
||||
[10]: https://www.ostechnix.com/4-ways-keep-command-running-log-ssh-session/
|
||||
[11]: https://www.ostechnix.com/sslh-share-port-https-ssh/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user