2018年3月

新年伊始,Linux 中国的 2018 年第一次线下沙龙于昨天在北上广杭四个城市成功召集。一如既往,由于超出了预计规模,这次的沙龙我们也是提前关闭了各地的报名通道。

本次沙龙是在北京、上海、广州和杭州举办的,以下是各地的一些沙龙花絮,分享给大家:

北京:最国际范的沙龙

北京依旧是在时光漫步咖啡厅举办的。此次沙龙活动邀请到了 BLUG(Beijing Linux User Group)召集人 Martin 和来自韩国的 GNOME Foundation 成员成大炫(DaeHyun Sung) 作为特邀嘉宾参加。

从左往右,依次是北京站召集人宋贺、鬼谷子、Martin、成大炫

这次沙龙由 Linux中国核心成员 Fine 分享了 《Use OpenSCAP to Scan CVE》。

本着自由的开源精神,Fine已经把 PPT 贡献出来,大家可以无偿自由下载。另外这里提一个小插曲,因为有国际友人在场, Fine 的分享是中英双语交替进行的。Martin 和成大炫也不断与在场小伙伴互动交流。

特邀的运维大咖「鬼谷子」也给现场的几位在校生和刚入职场的年轻人分享了运维人的职业规划经验。

左一是著名 IT 专家鬼谷子,正在分享职业生涯

分享之后,是抽奖和“书籍交换”环节。从 Python 入门到 Git 技巧,再到AI 人工智能,大家各自都交换到了心仪的书籍。

上海:最切实的分享

本次活动上海分站我们选在了中国共产党发源地——上海新天地附近的一家咖啡馆,为了能够占够位置,一叶、瑾萱、ONLY 暴露了他们脸皮的厚度,这三位小伙伴提前一小时来到咖啡馆,经过激烈研究最终采用了瑾萱妹子在大学图书馆占位策略,他们无视了无数人的横眉冷对并占位成功。

下午 2 点时分大家陆续到达,经过一番相互嘘寒问暖,会议开始了。会议由美丽大方的瑾萱妹子主持,会议第一个主题是《我们如何办好 Linux 中国线下沙龙》,大家针对每次会议主题选定、场所选址、活动形式等展开了 360 度无死角讨论。

会议第二个主题是由 LCTT 核心成员昀为大家分享的《Information Open Source》,这位欧洲生活了五六年的集帅与才华的男子的分享将大家对开源的激情带到了最高点,他诚恳的提出了 LCTT 在翻译中的几个问题,并且利用自己在国外生活多年的生活经验为大家一一给出了详实的解决办法。

接下来是我们程序猿大牛一叶为大家分享的《矿池原理》,我只想说一句,我应该早日加入 Linux 中国,我是不是就应该是白富美了?

最后一个环节是我们的图书交换,大家将自己的精神食粮拿来交换,我想这也是一种开源的精神吧。最后特别感谢我们的马丁同学——我们的专职摄影,他无私的奉献记录着我们 Linux 中国的每一步发展脚印。

广州:最苗条的聚会

广州站依然以交流为主,分享为辅助,主要由 Locez 分享了 Yubikey 的基本知识,比较接地气。

大家说话也比较实在,而且比较有趣的是大家在本次活动对抽书环节很谦让,抽中资格的小伙伴都纷纷谦让给别人,只取自己有用的,大家对于以后的活动更加倾向于聚会闲聊,或者可以进行户外活动。

杭州:技术含量最高的聚会

杭州是第一次加入到 Linux 中国线下沙龙中的,报名小伙伴热情都很高大部分都提前到达聚会地点。

沙龙在佛性主持 penghuster 的开场白下,一片欢声笑语中开始。

首先进行了自我介绍,其中初中生大牛 OriginCode 震惊全场,还有第二代程序猿技术大咖捧场。接着进行了核心主题分享环节,首先初中生大牛为我们带来了《一个初中生的 Linux 养成记》,在分享中,初中生大牛口中蹦出的各种在下闻所未闻专业名词让我近距离感受到差距,而且成绩常年年级前三,写代码对他来说就是娱乐、就是享受、就是放松,我也有幸亲眼目睹了别人家的小孩长得原来就是这个样子。

前排从左往右:OriginCode、朱晴、茹丹

接着一位爬虫高手鲁金达为我们带来《爬虫那些看不见的坑》,还现场演示如何避免踩坑。

最后特邀出席的技术大咖杨小浩本以为是一个讲座类的分享准备了一个长达 85 页 ppt 的《容器安全》,但由于时间有限,临时变更为分享其多年程序猿道路的心路历程,让我们见识到其从服务器做到云计算,再到容器,现在到智能硬件如何总是走在浪潮的最顶端。

最后进行旧书交换的环节,本来是准备有偿交换,但本着"互助、贡献、共享"的开源精神,我提议免费交换旧书,得到小伙伴们的积极响应,在场的小伙伴都挑选到自己感兴趣的书籍,发挥出书籍最大的价值。

总结

作为 Linux 中国线下化的重要举措,以后我们每个月都会在各个城市举办沙龙,希望大家不仅仅是网上的朋友,也能在线下成为好友。下一步,我们还将扩大城市范围,比如深圳就有很多同学举手报名了。

“如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道它们是如何工作的。” --Steve Yegge

就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道 编译器 compiler 解释器 interpreter 是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。

所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。

或者如果你不知道但你非常想要了解它。

不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。

为什么要学习编译器和解释器?有三点理由。

  1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对编写软件非常有用,而不是仅仅局限于解释器或编译器。
  2. 你确实想要了解电脑是怎么工作的。通常解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解它们的原理,把事情做好。
  3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个,你还要为它创建一个解释器或者编译器。最近,兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世:Elixir,Go,Rust,还有很多。

好,但什么是解释器和编译器?

解释器编译器 的任务是把用高级语言写的源程序翻译成其他的格式。很奇怪,是不是?忍一忍,稍后你会在这个系列学到到底把源程序翻译成什么东西。

这时你可能会奇怪解释器和编译器之间有什么区别。为了实现这个系列的目的,我们规定一下,如果有个翻译器把源程序翻译成机器语言,那它就是 编译器。如果一个翻译器可以处理并执行源程序,却不用把它翻译器机器语言,那它就是 解释器。直观上它看起来像这样:

我希望你现在确信你很想学习构建一个编译器和解释器。你期望在这个教程里学习解释器的哪些知识呢?

你看这样如何。你和我一起为 Pascal 语言的一个大子集做一个简单的解释器。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 pdb 那样的源代码级别的调试器。

你或许会问,为什么是 Pascal?一方面,它不是我为了这个系列而提出的一个虚构的语言:它是真实存在的一门编程语言,有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错 :))。

这有个 Pascal 中的阶乘函数示例,你将能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造:

program factorial;

function factorial(n: integer): longint;
begin
    if n = 0 then
        factorial := 1
    else
        factorial := n * factorial(n - 1);
end;

var
    n: integer;

begin
    for n := 0 to 16 do
        writeln(n, '! = ', factorial(n));
end.

这个 Pascal 解释器的实现语言会使用 Python,但你也可以用其他任何语言,因为这里展示的思想不依赖任何特殊的实现语言。好,让我们开始干活。准备好了,出发!

你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 3+5。下面是你的计算器的源代码——不好意思,是解释器:

# 标记类型
#
# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成
INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF'


class Token(object):
    def __init__(self, type, value):
        # token 类型: INTEGER, PLUS, MINUS, or EOF
        self.type = type
        # token 值: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '+', 或 None
        self.value = value

    def __str__(self):
        """String representation of the class instance.

        Examples:
            Token(INTEGER, 3)
            Token(PLUS '+')
        """
        return 'Token({type}, {value})'.format(
            type=self.type,
            value=repr(self.value)
        )

    def __repr__(self):
        return self.__str__()


class Interpreter(object):
    def __init__(self, text):
        # 用户输入字符串, 例如 "3+5"
        self.text = text
        # self.pos 是 self.text 的索引
        self.pos = 0
        # 当前标记实例
        self.current_token = None

    def error(self):
        raise Exception('Error parsing input')

    def get_next_token(self):
        """词法分析器(也说成扫描器或者标记器)

        该方法负责把一个句子分成若干个标记。每次处理一个标记
        """
        text = self.text

        # self.pos 索引到达了 self.text 的末尾吗?
        # 如果到了,就返回 EOF 标记,因为没有更多的
        # 能转换成标记的输入了
        if self.pos > len(text) - 1:
            return Token(EOF, None)

        # 从 self.pos 位置获取当前的字符,
        # 基于单个字符判断要生成哪种标记
        current_char = text[self.pos]
        # 如果字符是一个数字,就把他转换成一个整数,生成一个 INTEGER # 标记,累加 self.pos 索引,指向数字后面的下一个字符,
        # 并返回 INTEGER 标记
        if current_char.isdigit():
            token = Token(INTEGER, int(current_char))
            self.pos += 1
            return token

        if current_char == '+':
            token = Token(PLUS, current_char)
            self.pos += 1
            return token

        self.error()

    def eat(self, token_type):
        # 将当前的标记类型与传入的标记类型作比较,如果他们相匹配,就
        # “eat” 掉当前的标记并将下一个标记赋给 self.current_token,
        # 否则抛出一个异常
        if self.current_token.type == token_type:
            self.current_token = self.get_next_token()
        else:
            self.error()

    def expr(self):
        """expr -> INTEGER PLUS INTEGER"""
        # 将输入中的第一个标记设置成当前标记
        self.current_token = self.get_next_token()

        # 我们期望当前标记是个位数。
        left = self.current_token
        self.eat(INTEGER)

        # 期望当前标记是 ‘+’ 号
        op = self.current_token
        self.eat(PLUS)

        # 我们期望当前标记是个位数。
        right = self.current_token
        self.eat(INTEGER)

        # 上述操作完成后,self.current_token 被设成 EOF 标记
        # 这时成功找到 INTEGER PLUS INTEGER 标记序列
        # 这个方法就可以返回两个整数相加的结果了,
        # 即高效的解释了用户输入
        result = left.value + right.value
        return result


def main():
    while True:
        try:
            # 要在 Python3 下运行,请把 ‘raw_input’ 换成 ‘input’
            text = raw_input('calc> ')
        except EOFError:
            break
        if not text:
            continue
        interpreter = Interpreter(text)
        result = interpreter.expr()
        print(result)


if __name__ == '__main__':
    main()

把上面的代码保存到 calc1.py 文件,或者直接从 GitHub 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 raw_input 换成 input):

$ python calc1.py
calc> 3+4
7
calc> 3+5
8
calc> 3+9
12
calc>

要让你的简易计算器正常工作,不抛出异常,你的输入要遵守以下几个规则:

  • 只允许输入个位数
  • 此时支持的唯一一个运算符是加法
  • 输入中不允许有任何的空格符号

要让计算器变得简单,这些限制非常必要。不用担心,你很快就会让它变得很复杂。

好,现在让我们深入它,看看解释器是怎么工作,它是怎么评估出算术表达式的。

当你在命令行中输入一个表达式 3+5,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么,它首先要把输入 “3+5” 分到叫做 token(标记)的容器里。 标记 token 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。

把输入字符串分成标记的过程叫 词法分析 lexical analysis 。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做 词法分析器 lexical analyzer ,或者简短点叫 lexer。你也可以给它起别的名字,诸如 扫描器 scanner 或者 标记器 tokenizer 。它们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。

Interpreter 类中的 get_next_token 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。pos 开始时设为 0,指向字符 ‘3’。这个方法一开始检查字符是不是数字,如果是,就将 pos 加 1,并返回一个 INTEGER 类型的标记实例,并把字符 ‘3’ 的值设为整数,也就是整数 3:

现在 pos 指向文本中的 ‘+’ 号。下次调用这个方法的时候,它会测试 pos 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 pos 加 1,返回一个新创建的标记,类型是 PLUS,值为 ‘+’。

pos 现在指向字符 ‘5’。当你再调用 get_next_token 方法时,该方法会检查这是不是个数字,就是这样,然后它把 pos 加 1,返回一个新的 INTEGER 标记,该标记的值被设为整数 5:

因为 pos 索引现在到了字符串 “3+5” 的末尾,你每次调用 get_next_token 方法时,它将会返回 EOF 标记:

自己试一试,看看计算器里的词法分析器的运行:

>>> from calc1 import Interpreter
>>>
>>> interpreter = Interpreter('3+5')
>>> interpreter.get_next_token()
Token(INTEGER, 3)
>>>
>>> interpreter.get_next_token()
Token(PLUS, '+')
>>>
>>> interpreter.get_next_token()
Token(INTEGER, 5)
>>>
>>> interpreter.get_next_token()
Token(EOF, None)
>>>

既然你的解释器能够从输入字符中获取标记流,解释器需要对它做点什么:它需要在词法分析器 get_next_token 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构:INTEGER -> PLUS -> INTEGER。就是这样,它尝试找出标记的序列:整数后面要跟着加号,加号后面要跟着整数。

负责找出并解释结构的方法就是 expr。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后,就会生成加号左右两边的标记的值相加的结果,这样就成功解释你输入到解释器中的算术表达式了。

expr 方法用了一个助手方法 eat 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,eat 方法会获取下一个标记,并将其赋给 current_token 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER -> PLUS -> INTEGER 标记序列不对应,eat 方法就抛出一个异常。

让我们回顾下解释器做了什么来对算术表达式进行评估的:

  • 解释器接受输入字符串,比如说 “3+5”
  • 解释器调用 expr 方法,在词法分析器 get_next_token 返回的标记流中找出结构。这个结构就是 INTEGER -> PLUS -> INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加来解释输入,因为此时对于解释器来说很清楚,它要做的就是把两个整数 3 和 5 进行相加。

恭喜。你刚刚学习了怎么构建自己的第一个解释器!

现在是时候做练习了。

看了这篇文章,你肯定觉得不够,是吗?好,准备好做这些练习:

  1. 修改代码,允许输入多位数,比如 “12+3”
  2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如 “12 + 3”
  3. 修改代码,用 ‘-’ 号而非 ‘+’ 号去执行减法比如 “7-5”

检验你的理解

  1. 什么是解释器?
  2. 什么是编译器
  3. 解释器和编译器有什么差别?
  4. 什么是标记?
  5. 将输入分隔成若干个标记的过程叫什么?
  6. 解释器中进行词法分析的部分叫什么?
  7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字?

在结束本文前,我衷心希望你能留下学习解释器和编译器的承诺。并且现在就开始做。不要把它留到以后。不要拖延。如果你已经看完了本文,就开始吧。如果已经仔细看完了但是还没做什么练习 —— 现在就开始做吧。如果已经开始做练习了,那就把剩下的做完。你懂得。而且你知道吗?签下承诺书,今天就开始学习解释器和编译器!

本人, \_\_\_\_\_\_,身体健全,思想正常,在此承诺从今天开始学习解释器和编译器,直到我百分百了解它们是怎么工作的!

签字人:

日期:

签字,写上日期,把它放在你每天都能看到的地方,确保你能坚守承诺。谨记你的承诺:

“承诺就是,你说自己会去做的事,在你说完就一直陪着你的东西。” —— Darren Hardy

好,今天的就结束了。这个系列的下一篇文章里,你将会扩展自己的计算器,让它能够处理更复杂的算术表达式。敬请期待。


via: https://ruslanspivak.com/lsbasi-part1/

作者:Ruslan Spivak 译者:BriFuture 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

提要:Apache 2.0许可证中的专利许可条款使得开源代码可以安全使用,但它经常被误解。

 title=

Apache 2.0 许可证包含许多关键条款,其中也包括根据我的经验经常被误解的 专利许可 patent grant 条款。专利许可对于开源代码的安全使用具有重大影响。我通过分析 Apache 2.0 许可证第 3 部分的其中一段来具体解释:

3. 专利许可的授予 Grant of Patent License 。根据本许可证的条款和条件,每个 贡献者 Contributor 特此授予您永久的、全球性的、非独占的、免费的、免版税的、不可撤销的(本节所述除外)专利许可,从而制作、委托制作、使用、许诺销售、销售、进口和以其他方式转移 作品 the Work ,该专利许可仅适用于贡献者提供的满足以下条件的专利权利要求:贡献者的 贡献 Contribution 单独对该权利要求必然构成侵权,或贡献者的贡献与贡献者提交此类贡献的作品之间的结合对该权利要求必然构成侵权。

实质上,当软件开发人员为项目(即 Apache 2.0 许可证中的“作品”)贡献代码,他/她就成为贡献者。在上述条款中,贡献者授予了使用任何可能与其贡献相关的专利的许可。这让用户感到安心,因为贡献者可能会被禁止向任何使用包含该贡献的软件的用户收取专利许可费。

但当软件开发人员贡献的代码仅其自身来说没有被贡献者的任何专利所覆盖,而只有与贡献者提交此类贡献的遵循 Apache 2.0 许可证的开源项目相结合才能被相关专利覆盖时,问题就变得复杂了。因此,拥有相关专利的贡献者可以向使用修订版作品的用户收取专利许可费。Apache 2.0 许可证的作者进行了前瞻性思考,对这种情况也进行了说明。第 3 条规定,该许可证适用于“贡献者提供的满足以下条件的专利权利要求:……贡献者的贡献与贡献者提交此类贡献的作品之间的结合对该权利要求必然构成侵权。”

一些贡献者可能担心他们的贡献会导致广泛的专利许可。例如,您向遵循 Apache 2.0 许可证的开源项目贡献代码,在您提交贡献的时候,无论是您的贡献自身还是其与开源项目的结合都没有对您的专利构成侵权,但后续该作品通过其他人而非您的贡献在功能上进行了扩展,从而被您的专利所覆盖,这种情况该怎么办呢?您的专利会被自动许可吗?按照 Apache 软件基金会的常见问题解答,情况并非如此。

这个结果似乎以一种开放/合作的方式,在向 Apache 2.0 开源项目贡献代码的专利所有者与保证相关专利不会针对依据 Apache 2.0 许可证享有权益的作品用户主张专利权的必要性之间,达成了一种明智的平衡。

关于依据 Apache 2.0 许可证向 Apache 软件基金会提交贡献的专利许可范围的相关问题和答案,可以在 Apache 软件基金会有关许可的常见问题解答里找到。

请记住,这是 Apache 软件基金会对 Apache 2.0 许可证的解释。使用 Apache 2.0 许可证的其他许可人可能会以不同的方式解释该许可证中专利许可条款的范围,但我认为那似乎不太可能会成功,Apache 软件基金会的常见问题解答对专利许可条款的解释看起来合情合理。


作者简介:Jeffrey R. Kaufman 是全球领先的开源软件解决方案供应商 Red Hat 公司的开源知识产权律师,还担任 托马斯杰斐逊法学院 Thomas Jefferson School of Law 的兼职教授。在任职 Red Hat 之前,Jeffrey曾担任 高通公司 Qualcomm Incorporated 的专利顾问,为 首席科学家办公室 Office of the Chief Scientist 提供开源事务咨询。

译者简介:薛亮,集慧智佳知识产权咨询公司高级咨询师,擅长专利检索、专利分析、竞争对手跟踪、FTO 分析、开源软件知识产权风险分析,致力于为互联网企业、高科技公司提供知识产权咨询服务。

虽然大多数 Chromebook 已经能够运行 Android 应用程序,但似乎 Google 希望在其 Chrome OS 上增加在容器或虚拟机上运行 Linux 应用程序的支持。

一则 Reddit 消息,谷歌显然正在开发 Chrome OS 的 Crostini 项目,以在 Chrome OS 上支持 Linux 的虚拟机。这条消息指出,最近的 Chromium 提交 会解释一条新的设备策略,如果其设置为真,那么将允许在 Chrome OS 上运行 Linux 虚拟机。

“如果该策略未设置或设置为真,那么在 Chrome OS 上运行 Linux 虚拟机是允许的。未设置也是允许的意味着非管理的设备是允许运行 Linux 虚拟机的。此时,要让 Linux 虚拟机运行起来,也需要启用 Finch 试验性特性,当该特性完全启用后,Finch 控制逻辑将被移除。”

在 Chrome OS 上运行 Linux 应用将让多少人梦想成真

这表明在你的 Chromebook 上运行 Linux 应用的梦想终于要变成了真的。不会让你等待太久,当这个新策略逐步经历 Chrome OS 的 Dev、Beta 和 Stable 等频道之后,你就可以在 Chrome OS 上尝鲜 Linux 应用了。

ChromeUnboxed 的消息,该特性或许出现在五月份早一些的时候 Chrome OS 66 发布时。显然这是首次在 Chrome OS 上支持容器化的 Linux 应用,我们对此功能表示无比的高兴,而这也将进一步让更多的人去使用 Chrome OS。

Chromebook 操作系统的当前版本是 Google 上个月发布的 Chrome OS 64,它支持并行运行 Android 应用,以及一些其它的核心功能,而且这个补丁也为 Chromebook 解决了 Meltdown 和 Spectre 安全缺陷影响

我在我的 Linux 系统上定义了如下 mount 别名:

alias mount='mount | column -t'

但是我需要在挂载文件系统和其他用途时绕过这个 bash 别名。我如何在 Linux、*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢?

你可以使用 alias 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。

4 种绕过 bash 别名的方法

尝试以下任意一种方法来运行被 bash shell 别名绕过的命令。让我们如下定义一个别名

alias mount='mount | column -t'

运行如下:

mount

示例输出:

sysfs                        on  /sys                             type  sysfs            (rw,nosuid,nodev,noexec,relatime)
proc                         on  /proc                            type  proc             (rw,nosuid,nodev,noexec,relatime)
udev                         on  /dev                             type  devtmpfs         (rw,nosuid,relatime,size=8023572k,nr_inodes=2005893,mode=755)
devpts                       on  /dev/pts                         type  devpts           (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs                        on  /run                             type  tmpfs            (rw,nosuid,noexec,relatime,size=1610240k,mode=755)
/dev/mapper/ubuntu--vg-root  on  /                                type  ext4             (rw,relatime,errors=remount-ro,data=ordered)
/dev/sda1                    on  /boot                            type  ext4             (rw,relatime,data=ordered)
binfmt_misc                  on  /proc/sys/fs/binfmt_misc         type  binfmt_misc      (rw,relatime)
lxcfs                        on  /var/lib/lxcfs                   type  fuse.lxcfs       (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)

方法 1 - 使用 \command

输入以下命令暂时绕过名为 mount 的 bash 别名:

\mount

方法 2 - 使用 "command"'command'

如下引用 mount 命令调用实际的 /bin/mount

"mount"

或者

'mount'

方法 3 - 使用命令的完全路径

使用完整的二进制路径,如 /bin/mount

/bin/mount
/bin/mount /dev/sda1 /mnt/sda

方法 4 - 使用内部命令 command

语法是:

command cmd
command cmd arg1 arg2

要覆盖 .bash_aliases 中设置的别名,例如 mount

command mount
command mount /dev/sdc /mnt/pendrive/

“command” 直接运行命令或显示关于命令的信息。它带参数运行命令会抑制 shell 函数查询或者别名,或者显示有关给定命令的信息。

关于 unalias 命令的说明

要从当前会话的已定义别名列表中移除别名,请使用 unalias 命令:

unalias mount

要从当前 bash 会话中删除所有别名定义:

unalias -a

确保你更新你的 ~/.bashrc$HOME/.bash_aliases。如果要永久删除定义的别名,则必须删除定义的别名:

vi ~/.bashrc

或者

joe $HOME/.bash_aliases

想了解更多信息,参考这里的在线手册,或者输入下面的命令查看:

man bash
help command
help unalias
help alias

via: https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/

作者:Vivek Gite 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

sar 命令用用收集、报告、或者保存 UNIX / Linux 系统的活动信息。它保存选择的计数器到操作系统的 /var/log/sa/sadd 文件中。从收集的数据中,你可以得到许多关于你的服务器的信息:

  1. CPU 使用率
  2. 内存页面和使用率
  3. 网络 I/O 和传输统计
  4. 进程创建活动
  5. 所有的块设备活动
  6. 每秒中断数等等

sar 命令的输出能够用于识别服务器瓶颈。但是,分析 sar 命令提供的信息可能比较困难,所以要使用 kSar 工具。kSar 工具可以将 sar 命令的输出绘制成基于时间周期的、易于理解的图表。

sysstat 包

sarsa1、和 sa2 命令都是 sysstat 包的一部分。它是 Linux 包含的性能监视工具集合。

  1. sar:显示数据
  2. sa1sa2:收集和保存数据用于以后分析。sa2 shell 脚本在 /var/log/sa 目录中每日写入一个报告。sa1 shell 脚本将每日的系统活动信息以二进制数据的形式写入到文件中。
  3. sadc —— 系统活动数据收集器。你可以通过修改 sa1sa2 脚本去配置各种选项。它们位于以下的目录:

    • /usr/lib64/sa/sa1 (64 位)或者 /usr/lib/sa/sa1 (32 位) —— 它调用 sadc 去记录报告到 /var/log/sa/sadX 格式。
    • /usr/lib64/sa/sa2 (64 位)或者 /usr/lib/sa/sa2 (32 位) —— 它调用 sar 去记录报告到 /var/log/sa/sarX 格式。

如何在我的系统上安装 sar?

在一个基于 CentOS/RHEL 的系统上,输入如下的 yum 命令 去安装 sysstat:

# yum install sysstat

示例输出如下:

Loaded plugins: downloadonly, fastestmirror, priorities,
              : protectbase, security
Loading mirror speeds from cached hostfile
 * addons: mirror.cs.vt.edu
 * base: mirror.ash.fastserv.com
 * epel: serverbeach1.fedoraproject.org
 * extras: mirror.cogentco.com
 * updates: centos.mirror.nac.net
0 packages excluded due to repository protections
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package sysstat.x86_64 0:7.0.2-3.el5 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

====================================================================
 Package        Arch          Version             Repository   Size
====================================================================
Installing:
 sysstat        x86_64        7.0.2-3.el5         base        173 k

Transaction Summary
====================================================================
Install      1 Package(s)
Update       0 Package(s)
Remove       0 Package(s)

Total download size: 173 k
Is this ok [y/N]: y
Downloading Packages:
sysstat-7.0.2-3.el5.x86_64.rpm               | 173 kB     00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : sysstat                                      1/1

Installed:
  sysstat.x86_64 0:7.0.2-3.el5

Complete!

为 sysstat 配置文件

编辑 /etc/sysconfig/sysstat 文件去指定日志文件保存多少天(最长为一个月):

# vi /etc/sysconfig/sysstat

示例输出如下 :

# keep log for 28 days
# the default is 7
HISTORY=28

保存并关闭这个文件。

找到 sar 默认的 cron 作业

默认的 cron 作业位于 /etc/cron.d/sysstat

# cat /etc/cron.d/sysstat

示例输出如下:

# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A

告诉 sadc 去报告磁盘的统计数据

使用一个文本编辑器去编辑 /etc/cron.d/sysstat 文件,比如使用 vim 命令,输入如下:

# vi /etc/cron.d/sysstat

像下面的示例那样更新这个文件,以记录所有的硬盘统计数据(-d 选项强制记录每个块设备的统计数据,而 -I 选项强制记录所有系统中断的统计数据):

# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 -I -d 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A 

在 CentOS/RHEL 7.x 系统上你需要传递 -S DISK 选项去收集块设备的数据。传递 -S XALL 选项去采集如下所列的数据:

  1. 磁盘
  2. 分区
  3. 系统中断
  4. SNMP
  5. IPv6
# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 -S DISK 1 1
# 0 * * * * root /usr/lib64/sa/sa1 600 6 &
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A
# Run system activity accounting tool every 10 minutes

保存并关闭这个文件。

打开 CentOS/RHEL 版本 5.x/6.x 的服务

输入如下命令:

chkconfig sysstat on
service sysstat start

示例输出如下:

Calling the system activity data collector (sadc):

对于 CentOS/RHEL 7.x,运行如下的命令:

# systemctl enable sysstat
# systemctl start sysstat.service
# systemctl status sysstat.service 

示例输出:

● sysstat.service - Resets System Activity Logs
   Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; vendor preset: enabled)
   Active: active (exited) since Sat 2018-01-06 16:33:19 IST; 3s ago
  Process: 28297 ExecStart=/usr/lib64/sa/sa1 --boot (code=exited, status=0/SUCCESS)
 Main PID: 28297 (code=exited, status=0/SUCCESS)

Jan 06 16:33:19 centos7-box systemd[1]: Starting Resets System Activity Logs...
Jan 06 16:33:19 centos7-box systemd[1]: Started Resets System Activity Logs.

如何使用 sar?如何查看统计数据?

使用 sar 命令去显示操作系统中选定的累积活动计数器输出。在这个示例中,运行 sar 命令行,去实时获得 CPU 使用率的报告:

# sar -u 3 10

示例输出:

Linux 2.6.18-164.2.1.el5 (www-03.nixcraft.in)   12/14/2009

09:49:47 PM CPU %user %nice %system %iowait %steal %idle
09:49:50 PM all 5.66 0.00 1.22 0.04 0.00 93.08
09:49:53 PM all 12.29 0.00 1.93 0.04 0.00 85.74
09:49:56 PM all 9.30 0.00 1.61 0.00 0.00 89.10
09:49:59 PM all 10.86 0.00 1.51 0.04 0.00 87.58
09:50:02 PM all 14.21 0.00 3.27 0.04 0.00 82.47
09:50:05 PM all 13.98 0.00 4.04 0.04 0.00 81.93
09:50:08 PM all 6.60 6.89 1.26 0.00 0.00 85.25
09:50:11 PM all 7.25 0.00 1.55 0.04 0.00 91.15
09:50:14 PM all 6.61 0.00 1.09 0.00 0.00 92.31
09:50:17 PM all 5.71 0.00 0.96 0.00 0.00 93.33
Average: all 9.24 0.69 1.84 0.03 0.00 88.20

其中:

  • 3 表示间隔时间
  • 10 表示次数

查看进程创建的统计数据,输入:

# sar -c 3 10

查看 I/O 和传输率统计数据,输入:

# sar -b 3 10

查看内存页面统计数据,输入:

# sar -B 3 10

查看块设备统计数据,输入:

# sar -d 3 10

查看所有中断的统计数据,输入:

# sar -I XALL 3 10

查看网络设备特定的统计数据,输入:

# sar -n DEV 3 10
# sar -n EDEV 3 10

查看 CPU 特定的统计数据,输入:

# sar -P ALL
# Only 1st CPU stats
# sar -P 1 3 10 

查看队列长度和平均负载的统计数据,输入:

# sar -q 3 10

查看内存和交换空间的使用统计数据,输入:

# sar -r 3 10
# sar -R 3 10

查看 inode、文件、和其它内核表统计数据状态,输入:

# sar -v 3 10

查看系统切换活动统计数据,输入:

# sar -w 3 10

查看交换统计数据,输入:

# sar -W 3 10

查看一个 PID 为 3256 的 Apache 进程,输入:

# sar -x 3256 3 10

kSar 介绍

sarsadf 提供了基于命令行界面的输出。这种输出可能会使新手用户/系统管理员感到无从下手。因此,你需要使用 kSar,它是一个图形化显示你的 sar 数据的 Java 应用程序。它也允许你以 PDF/JPG/PNG/CSV 格式导出数据。你可以用三种方式去加载数据:本地文件、运行本地命令、以及通过 SSH 远程运行的命令。kSar 可以处理下列操作系统的 sar 输出:

  1. Solaris 8, 9 和 10
  2. Mac OS/X 10.4+
  3. Linux (Systat Version >= 5.0.5)
  4. AIX (4.3 & 5.3)
  5. HPUX 11.00+

下载和安装 kSar

访问 官方 网站去获得最新版本的源代码。使用 wget 去下载源代码,输入:

$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar

如何运行 kSar?

首先要确保你的机器上 JAVA jdk 已安装并能够正常工作。输入下列命令去启动 kSar:

$ java -jar ksar-5.2.4-SNAPSHOT-all.jar

 title=

接下来你将看到 kSar 的主窗口,和有两个菜单的面板。

 title=

左侧有一个列表,是 kSar 根据数据已经解析出的可用图表的列表。右侧窗口将展示你选定的图表。

如何使用 kSar 去生成 sar 图表?

首先,你需要从命名为 server1 的服务器上采集 sar 命令的统计数据。输入如下的命令:

[ server1 ]# LC_ALL=C sar -A  > /tmp/sar.data.txt

接下来,使用 scp 命令从本地桌面拷贝到远程电脑上:

[ desktop ]$ scp [email protected]:/tmp/sar.data.txt /tmp/

切换到 kSar 窗口,点击 “Data” > “Load data from text file” > 从 /tmp/ 中选择 sar.data.txt > 点击 “Open” 按钮。

现在,图表类型树已经出现在左侧面板中并选定了一个图形:

 title=

 title=

 title=

放大和缩小

通过移动你可以交互式缩放图像的一部分。在要缩放的图像的左上角点击并按下鼠标,移动到要缩放区域的右下角,可以选定要缩放的区域。返回到未缩放状态,点击并拖动鼠标到除了右下角外的任意位置,你也可以点击并选择 zoom 选项。

了解 kSar 图像和 sar 数据

我强烈建议你去阅读 sarsadf 命令的 man 页面:

$ man sar
$ man sadf

案例学习:识别 Linux 服务器的 CPU 瓶颈

使用 sar 命令和 kSar 工具,可以得到内存、CPU、以及其它子系统的详细快照。例如,如果 CPU 使用率在一个很长的时间内持续高于 80%,有可能就是出现了一个 CPU 瓶颈。使用 sar -x ALL 你可以找到大量消耗 CPU 的进程。

mpstat 命令 的输出(sysstat 包的一部分)也会帮你去了解 CPU 的使用率。但你可以使用 kSar 很容易地去分析这些信息。

找出 CPU 瓶颈后 …

对 CPU 执行如下的调整:

  1. 确保没有不需要的进程在后台运行。关闭 Linux 上所有不需要的服务
  2. 使用 cron 在一个非高峰时刻运行任务(比如,备份)。
  3. 使用 top 和 ps 命令 去找出所有非关键的后台作业/服务。使用 renice 命令 去调整低优先级作业。
  4. 使用 taskset 命令去设置进程使用的 CPU (卸载所使用的 CPU),即,绑定进程到不同的 CPU 上。例如,在 2# CPU 上运行 MySQL 数据库,而在 3# CPU 上运行 Apache。
  5. 确保你的系统使用了最新的驱动程序和固件。
  6. 如有可能在系统上增加额外的 CPU。
  7. 为单线程应用程序使用更快的 CPU(比如,Lighttpd web 服务器应用程序)。
  8. 为多线程应用程序使用多个 CPU(比如,MySQL 数据库服务器应用程序)。
  9. 为一个 web 应用程序使用多个计算节点并设置一个 负载均衡器

isag —— 交互式系统活动记录器(替代工具)

isag 命令图形化显示了以前运行 sar 命令时存储在二进制文件中的系统活动数据。isag 命令引用 sar 并提取出它的数据来绘制图形。与 kSar 相比,isag 的选项比较少。

 title=

关于作者

本文作者是 nixCraft 的创始人和一位经验丰富的 Linux 操作系统/Unix shell 脚本培训师。他与包括 IT、教育、国防和空间研究、以及非营利组织等全球各行业客户一起合作。可以在 TwitterFacebookGoogle+ 上关注他。


via: https://www.cyberciti.biz/tips/identifying-linux-bottlenecks-sar-graphs-with-ksar.html

作者:Vivek Gite 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出