分类 技术 下的文章

Hyperledger Fabric

Hyperledger Fabric

Hyperledger 项目 是一个伞形组织,包括许多正在开发的不同模块和系统。在这些子项目中,最受欢迎的是 “Hyperledger Fabric”。这篇博文将探讨一旦区块链系统开始大量使用到主流,将使 Fabric 在不久的将来成为几乎不可或缺的功能。最后,我们还将快速了解开发人员和爱好者们需要了解的有关 Hyperledger Fabric 技术的知识。

起源

按照 Hyperledger 项目的常规方式,Fabric 由其核心成员之一 IBM “捐赠”给该组织,而 IBM 以前是该组织的主要开发者。由 IBM 共享的这个技术平台在 Hyperledger 项目中进行了联合开发,来自 100 多个成员公司和机构为之做出了贡献。

目前,Fabric 正处于 LTS 版本的 v1.4,该版本已经发展很长一段时间,并且被视为企业管理业务数据的解决方案。Hyperledger 项目的核心愿景也必然会渗透到 Fabric 中。Hyperledger Fabric 系统继承了所有企业级的可扩展功能,这些功能已深深地刻入到 Hyperledger 组织旗下所有的项目当中。

Hyperledger Fabric 的亮点

Hyperledger Fabric 提供了多种功能和标准,这些功能和标准围绕着支持快速开发和模块化体系结构的使命而构建。此外,与竞争对手(主要是瑞波和以太坊)相比,Fabric 明确用于封闭和许可区块链。它们的核心目标是开发一套工具,这些工具将帮助区块链开发人员创建定制的解决方案,而不是创建独立的生态系统或产品。

Hyperledger Fabric 的一些亮点如下:

许可区块链系统

这是一个 Hyperledger Fabric 与其他平台(如以太坊和瑞波)差异很大的地方。默认情况下,Fabric 是一种旨在实现私有许可的区块链的工具。此类区块链不能被所有人访问,并且其中致力于达成共识或验证交易的节点将由中央机构进行选择。这对于某些应用(例如银行和保险)可能很重要,在这些应用中,交易必须由中央机构而不是参与者来验证。

机密和受控的信息流

Fabric 内置了权限系统,该权限系统将视情况限制特定组或某些个人中的信息流。与公有区块链不同,在公有区块链中,任何运行节点的人都可以对存储在区块链中的数据进行复制和选择性访问,而 Fabric 系统的管理员可以选择谁能访问共享的信息,以及访问的方式。与现有竞争产品相比,它还有以更好的安全性标准对存储的数据进行加密的子系统。

即插即用架构

Hyperledger Fabric 具有即插即用类型的体系结构。可以选择实施系统的各个组件,而开发人员看不到用处的系统组件可能会被废弃。Fabric 采取高度模块化和可定制的方式进行开发,而不是一种与其竞争对手采用的“一种方法适应所有需求”的方式。对于希望快速构建精益系统的公司和公司而言,这尤其有吸引力。这与 Fabric 和其它 Hyperledger 组件的互操作性相结合,意味着开发人员和设计人员现在可以使用各种标准化工具,而不必从其他来源提取代码并随后进行集成。它还提供了一种相当可靠的方式来构建健壮的模块化系统。

智能合约和链码

运行在区块链上的分布式应用程序称为智能合约。虽然智能合约这个术语或多或少与以太坊平台相关联,但 链码 chaincode 是 Hyperledger 阵营中为其赋予的名称。链码应用程序除了拥有 DApp 中有的所有优点之外,使 Hyperledger 与众不同的是,该应用程序的代码可以用多种高级编程语言编写。它本身支持 Go 和 JavaScript,并且在与适当的编译器模块集成后还支持许多其它编程语言。尽管这一事实在此时可能并不代表什么,但这意味着,如果可以将现有人才用于正在进行的涉及区块链的项目,从长远来看,这有可能为公司节省数十亿美元的人员培训和管理费用。开发人员可以使用自己喜欢的语言进行编码,从而在 Hyperledger Fabric 上开始构建应用程序,而无需学习或培训平台特定的语言和语法。这提供了 Hyperledger Fabric 当前竞争对手无法提供的灵活性。

总结

  • Hyperledger Fabric 是一个后端驱动程序平台,是一个主要针对需要区块链或其它分布式账本技术的集成项目。因此,除了次要的脚本功能外,它不提供任何面向用户的服务。(认可以为​​它更像是一种脚本语言。)
  • Hyperledger Fabric 支持针对特定用例构建侧链。如果开发人员希望将一组用户或参与者隔离到应用程序的特定部分或功能,则可以通过侧链来实现。侧链是衍生自主要父代的区块链,但在其初始块之后形成不同的链。产生新链的块将不受新链进一步变化的影响,即使将新信息添加到原始链中,新链也将保持不变。此功能将有助于扩展正在开发的平台,并引入用户特定的和案例特定的处理功能。
  • 前面的功能还意味着并非所有用户都会像通常对公有链所期望的那样拥有区块链中所有数据的“精确”副本。参与节点将具有仅与之相关的数据副本。例如,假设有一个类似于印度的 PayTM 的应用程序,该应用程序具有钱包功能以及电子商务功能。但是,并非所有的钱包用户都使用 PayTM 在线购物。在这种情况下,只有活跃的购物者将在 PayTM 电子商务网站上拥有相应的交易链,而钱包用户将仅拥有存储钱包交易的链的副本。这种灵活的数据存储和检索体系结构在扩展时非常重要,因为大量的单链区块链已经显示出会增加处理交易的前置时间。这样可以保持链的精简和分类。

我们将在以后的文章中详细介绍 Hyperledger Project 下的其他模块。


via: https://www.ostechnix.com/blockchain-2-0-introduction-to-hyperledger-fabric/

作者:sk 选题:lujun9972 译者:wxy 校对:wxy

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

 title=

Google Analytics (GA)这个最流行的用户活动追踪工具我们或多或少都听说过甚至使用过,但它的用途并不仅仅限于对页面访问的追踪。作为一个既实用又流行的工具,它已经受到了广泛的欢迎,因此我们将要在下文中介绍如何在各种 Angular 和 React 单页应用中使用 Google Analytics。

这篇文章源自这样一个问题:如何对单页应用中的页面访问进行跟踪?

通常来说,有很多的方法可以解决这个问题,在这里我们只讨论其中的一种方法。下面我会使用 Angular 来写出对应的实现,如果你使用的是 React,相关的用法和概念也不会有太大的差别。接下来就开始吧。

准备好应用程序

首先需要有一个 追踪 ID tracking ID 。在开始编写业务代码之前,要先准备好一个追踪 ID,通过这个唯一的标识,Google Analytics 才能识别出某个点击或者某个页面访问是来自于哪一个应用。

按照以下的步骤:

  1. 访问 https://analytics.google.com
  2. 提交指定信息以完成注册,并确保可用于 Web 应用,因为我们要开发的正是一个 Web 应用;
  3. 同意相关的条款,生成一个追踪 ID;
  4. 保存好追踪 ID。

追踪 ID 拿到了,就可以开始编写业务代码了。

添加 analytics.js 脚本

Google 已经帮我们做好了接入之前需要做的所有事情,接下来就是我们的工作了。不过我们要做的也很简单,只需要把下面这段脚本添加到应用的 index.html 里,就可以了:

<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
</script>

现在我们来看一下 Google Analytics 是如何在应用程序中初始化的。

创建追踪器

首先创建一个应用程序的追踪器。在 app.component.ts 中执行以下两个步骤:

  1. 声明一个名为 ga,类型为 any 的全局变量(在 Typescript 中需要制定变量类型);
  2. 将下面一行代码加入到 ngInInit() 中。
ga('create', <你的追踪 ID>, 'auto');

这样就已经成功地在应用程序中初始化了一个 Google Analytics 的追踪器了。由于追踪器的初始化是在 OnInit() 函数中执行的,因此每当应用程序启动,追踪器就会启动。

在单页应用中记录页面访问情况

我们需要实现的是记录 访问路由 route-visits

如何记录用户在一个应用中不同部分的访问,这是一个难点。从功能上来看,单页应用中的路由对应了传统多页面应用中各个页面之间的跳转,因此我们需要记录访问路由。要做到这一点尽管不算简单,但仍然是可以实现的。在 app.component.tsngOnInit() 函数中添加以下的代码片段:

import { Router, NavigationEnd } from '@angular/router';
...
constructor(public router: Router) {}
...
this.router.events.subscribe(
    event => {
        if (event instanceof NavigationEnd) {
            ga('set', 'page', event.urlAfterRedirects);
            ga('send', { hitType: 'pageview', hitCallback: () => { this.pageViewSent = true; }});
        }
    } 
);

神奇的是,只需要这么几行代码,就实现了 Angular 应用中记录页面访问情况的功能。

这段代码实际上做了以下几件事情:

  1. 从 Angular Router 中导入了 RouterNavigationEnd
  2. 通过构造函数中将 Router 添加到组件中;
  3. 然后订阅 router 事件,也就是由 Angular Router 发出的所有事件;
  4. 只要产生了一个 NavigationEnd 事件实例,就将路由和目标作为一个页面访问进行记录。

这样,只要使用到了页面路由,就会向 Google Analytics 发送一条页面访问记录,在 Google Analytics 的在线控制台中可以看到这些记录。

类似地,我们可以用相同的方式来记录除了页面访问之外的活动,例如某个界面的查看次数或者时长等等。只要像上面的代码那样使用 hitCallBack() 就可以在有需要收集的数据的时候让应用程序作出反应,这里我们做的事情仅仅是把一个变量的值设为 true,但实际上 hitCallBack() 中可以执行任何代码。

追踪用户交互活动

除了页面访问记录之外,Google Analytics 还经常被用于追踪用户的交互活动,例如某个按钮的点击情况。“提交按钮被用户点击了多少次?”,“产品手册会被经常查阅吗?”这些都是 Web 应用程序的产品评审会议上的常见问题。这一节我们将会介绍如何实现这些数据的统计。

按钮点击

设想这样一种场景,需要统计到应用程序中某个按钮或链接被点击的次数,这是一个和注册之类的关键动作关系最密切的数据指标。下面我们来举一个例子:

假设应用程序中有一个“感兴趣”按钮,用于显示即将推出的活动,你希望通过统计这个按钮被点击的次数来推测有多少用户对此感兴趣。那么我们可以使用以下的代码来实现这个功能:

...
params = {
    eventCategory:
    'Button'
    ,
    eventAction:
    'Click'
    ,
    eventLabel:
    'Show interest'
    ,
    eventValue:
    1
};

showInterest() {
    ga('send', 'event', this.params);
}
...

现在看下这段代码实际上做了什么。正如前面说到,当我们向 Google Analytics 发送数据的时候,Google Analytics 就会记录下来。因此我们可以向 send() 方法传递不同的参数,以区分不同的事件,例如两个不同按钮的点击记录。

1、首先我们定义了一个 params 对象,这个对象包含了以下几个字段:

  1. eventCategory – 交互发生的对象,这里对应的是按钮(button)
  2. eventAction – 发生的交互的类型,这里对应的是点击(click)
  3. eventLabel – 交互动作的标识,这里对应的是这个按钮的内容,也就是“感兴趣”
  4. eventValue – 与每个发生的事件实例相关联的值

由于这个例子中是要统计点击了“感兴趣”按钮的用户数,因此我们把 eventValue 的值定为 1。

2、对象构造完成之后,下一步就是将 params 对象作为请求负载发送到 Google Analytics,而这一步是通过事件绑定将 showInterest() 绑定在按钮上实现的。这也是使用 Google Analytics 追踪中最常用的发送事件方法。

至此,Google Analytics 就可以通过记录按钮的点击次数来统计感兴趣的用户数了。

追踪社交活动

Google Analytics 还可以通过应用程序追踪用户在社交媒体上的互动。其中一种场景就是在应用中放置类似 Facebook 的点赞按钮,下面我们来看看如何使用 Google Analytics 来追踪这一行为。

...
fbLikeParams = {
    socialNetwork:
        'Facebook',
    socialAction:
        'Like',
    socialTarget:
        'https://facebook.com/mypage'
};
...
fbLike() {
    ga('send', 'social', this.fbLikeParams);
}

如果你觉得这段代码似曾相识,那是因为它确实跟上面统计“感兴趣”按钮点击次数的代码非常相似。下面我们继续看其中每一步的内容:

1、构造发送的数据负载,其中包括以下字段:

  1. socialNetwork – 交互发生的社交媒体,例如 Facebook、Twitter 等等
  2. socialAction – 发生的交互类型,例如点赞、发表推文、分享等等
  3. socialTarget – 交互的目标 URL,一般是社交媒体账号的主页

2、下一步是增加一个函数来发送整个交互记录。和统计按钮点击数量时相比,这里使用 send() 的方式有所不同。另外,我们还需要把这个函数绑定到已有的点赞按钮上。

在追踪用户交互方面,Google Analytics 还可以做更多的事情,其中最重要的一种是针对异常的追踪,这让我们可以通过 Google Analytics 来追踪应用程序中出现的错误和异常。在本文中我们就不赘述这一点了,但我们鼓励读者自行探索。

用户识别

隐私是一项权利,而不是奢侈品

Google Analytics 除了可以记录很多用户的操作和交互活动之外,这一节还将介绍一个不太常见的功能,就是可以控制是否对用户的身份进行追踪。

Cookies

Google Analytics 追踪用户活动的方式是基于 Cookies 的,因此我们可以自定义 Cookies 的名称以及一些其它的内容,请看下面这段代码:

trackingID =
    'UA-139883813-1'
;
cookieParams = {
    cookieName: 'myGACookie',
    cookieDomain: window.location.hostname,
    cookieExpires: 604800
};
...
ngOnInit() {
    ga('create', this.trackingID, this.cookieParams);
...
}

在上面这段代码中,我们设置了 Google Analytics Cookies 的名称、域以及过期时间,这就让我们能够将不同网站或 Web 应用的 Cookies 区分开来。因此我们需要为我们自己的应用程序的 Google Analytics 追踪器的 Cookies 设置一个自定义的标识1,而不是一个自动生成的随机标识。

IP 匿名

在某些场景下,我们可能不需要知道应用程序的流量来自哪里。例如对于一个按钮点击的追踪器,我们只需要关心按钮的点击量,而不需要关心点击者的地理位置。在这种场景下,Google Analytics 允许我们只追踪用户的操作行为,而不获取到用户的 IP 地址。

ipParams = {
    anonymizeIp: true
};
...
ngOnInit() {
    ...
    ga('set', this.ipParams);
    ...
}

在上面这段代码中,我们将 Google Analytics 追踪器的 abibymizeIp 参数设置为 true。这样用户的 IP 地址就不会被 Google Analytics 所追踪,这可以让用户知道自己的隐私正在被保护。

不被跟踪

还有些时候用户可能不希望自己的行为受到追踪,而 Google Analytics 也允许这样的需求。因此也存在让用户不被追踪的选项。

...
optOut() {
    window['ga-disable-UA-139883813-1'] = true;
}
...

optOut() 是一个自定义函数,它可以禁用页面中的 Google Analytics 追踪,我们可以使用按钮或复选框上得事件绑定来使用这一个功能,这样用户就可以选择是否会被 Google Analytics 追踪。

在本文中,我们讨论了 Google Analytics 集成到单页应用时的难点,并探索出了一种相关的解决方法。我们还了解到了如何在单页应用中追踪页面访问和用户交互,例如按钮点击、社交媒体活动等。

最后,我们还了解到 Google Analytics 为用户提供了保护隐私的功能,尤其是用户的一些隐私数据并不需要参与到统计当中的时候。而用户也可以选择完全不受到 Google Analytics 的追踪。除此以外,Google Analytics 还可以做到很多其它的事情,这就需要我们继续不断探索了。


via: https://opensourceforu.com/2019/10/all-that-you-can-do-with-google-analytics-and-more/

作者:Ashwin Sathian 选题:lujun9972 译者:HankChow 校对:wxy

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

VNC( 虚拟网络计算 Virtual Network Computing )服务器是基于 GUI 的桌面共享平台,它可让你访问远程桌面计算机。在 Centos 8 和 RHEL 8 系统中,默认未安装 VNC 服务器,它需要手动安装。在本文中,我们将通过简单的分步指南,介绍如何在 Centos 8 / RHEL 8 上安装 VNC 服务器。

在 Centos 8 / RHEL 8 上安装 VNC 服务器的先决要求

要在你的系统中安装 VNC 服务器,请确保你的系统满足以下要求:

  • CentOS 8 / RHEL 8
  • GNOME 桌面环境
  • root 用户权限
  • DNF / YUM 软件包仓库

在 Centos 8 / RHEL 8 上安装 VNC 服务器的分步指导

步骤 1)安装 GNOME 桌面环境

在 CentOS 8 / RHEL 8 中安装 VNC 服务器之前,请确保已安装了桌面环境(DE)。如果已经安装了 GNOME 桌面或安装了 GUI 支持,那么可以跳过此步骤。

在 CentOS 8 / RHEL 8 中,GNOME 是默认的桌面环境。如果你的系统中没有它,请使用以下命令进行安装:

[root@linuxtechi ~]# dnf groupinstall "workstation"
或者
[root@linuxtechi ~]# dnf groupinstall "Server with GUI

成功安装上面的包后,请运行以下命令启用图形模式:

[root@linuxtechi ~]# systemctl set-default graphical

现在重启系统,进入 GNOME 登录页面(LCTT 译注:你可以通过切换运行态来进入图形界面)。

[root@linuxtechi ~]# reboot

重启后,请取消注释 /etc/gdm/custom.conf 中的 WaylandEnable=false,以使通过 vnc 进行的远程桌面会话请求由 GNOME 桌面的 xorg 处理,来代替 Wayland 显示管理器。

注意: Wayland 是 GNOME 中的默认显示管理器 (GDM),并且未配置用于处理 X.org 等远程渲染的 API。

步骤 2)安装 VNC 服务器(tigervnc-server)

接下来,我们将安装 VNC 服务器,有很多 VNC 服务器可以选择,出于安装目的,我们将安装 TigerVNC 服务器。它是最受欢迎的 VNC 服务器之一,并且高性能还独立于平台,它使用户可以轻松地与远程计算机进行交互。

现在,使用以下命令安装 TigerVNC 服务器:

[root@linuxtechi ~]# dnf install tigervnc-server tigervnc-server-module -y

步骤 3)为本地用户设置 VNC 密码

假设我们希望用户 pkumar 使用 VNC 进行远程桌面会话,然后切换到该用户并使用 vncpasswd 命令设置其密码,

[root@linuxtechi ~]# su - pkumar
[root@linuxtechi ~]$ vncpasswd
Password:
Verify:
Would you like to enter a view-only password (y/n)? n
A view-only password is not used
[root@linuxtechi ~]$
[root@linuxtechi ~]$ exit
logout
[root@linuxtechi ~]#

步骤 4)设置 VNC 服务器配置文件

下一步是配置 VNC 服务器配置文件。创建含以下内容的 /etc/systemd/system/[email protected],以便为上面的本地用户 pkumar 启动 tigervnc-server 的服务。

[root@linuxtechi ~]# vim /etc/systemd/system/[email protected]
[Unit]
Description=Remote Desktop VNC Service
After=syslog.target network.target

[Service]
Type=forking
WorkingDirectory=/home/pkumar
User=pkumar
Group=pkumar

ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
ExecStart=/usr/bin/vncserver -autokill %i
ExecStop=/usr/bin/vncserver -kill %i

[Install]
WantedBy=multi-user.target

保存并退出文件,

注意:替换上面文件中的用户名为你自己的。

默认情况下,VNC 服务器在 tcp 端口 5900+n 上监听,其中 n 是显示端口号,如果显示端口号为 “1”,那么 VNC 服务器将在 TCP 端口 5901 上监听其请求。

步骤 5)启动 VNC 服务并允许防火墙中的端口

我将显示端口号设置为 1,因此请使用以下命令在显示端口号 “1” 上启动并启用 vnc 服务,

[root@linuxtechi ~]# systemctl daemon-reload
[root@linuxtechi ~]# systemctl start vncserver@:1.service
[root@linuxtechi ~]# systemctl enable vncserver@:1.service
Created symlink /etc/systemd/system/multi-user.target.wants/vncserver@:1.service → /etc/systemd/system/[email protected].
[root@linuxtechi ~]#

使用下面的 netstatss 命令来验证 VNC 服务器是否开始监听 5901 上的请求,

[root@linuxtechi ~]# netstat -tunlp | grep 5901
tcp        0      0 0.0.0.0:5901            0.0.0.0:*               LISTEN      8169/Xvnc
tcp6       0      0 :::5901                 :::*                    LISTEN      8169/Xvnc
[root@linuxtechi ~]# ss -tunlp | grep -i 5901
tcp   LISTEN  0       5                    0.0.0.0:5901           0.0.0.0:*      users:(("Xvnc",pid=8169,fd=6))                    
tcp   LISTEN  0       5                       [::]:5901              [::]:*      users:(("Xvnc",pid=8169,fd=7))                    
[root@linuxtechi ~]#

使用下面的 systemctl 命令验证 VNC 服务器的状态,

[root@linuxtechi ~]# systemctl status vncserver@:1.service

vncserver-status-centos8-rhel8

上面命令的输出确认在 tcp 端口 5901 上成功启动了 VNC。使用以下命令在系统防火墙中允许 VNC 服务器端口 “5901”,

[root@linuxtechi ~]# firewall-cmd --permanent --add-port=5901/tcp
success
[root@linuxtechi ~]# firewall-cmd --reload
success
[root@linuxtechi ~]#

步骤 6)连接到远程桌面会话

现在,我们已经准备就绪,可以查看远程桌面连接是否正常工作。要访问远程桌面,请在 Windows / Linux 工作站中启动 VNC Viewer,然后输入 VNC 服务器的 IP 地址和端口号,然后按回车。

VNC-Viewer-Windows10

接下来,它将询问你的 VNC 密码。输入你先前为本地用户创建的密码,然后单击 “OK” 继续。

VNC-Viewer-Connect-CentOS8-RHEL8-VNC-Server

现在你可以看到远程桌面,

VNC-Desktop-Screen-CentOS8

就是这样,你已经在 Centos 8 / RHEL 8 中成功安装了 VNC 服务器。

总结

希望这篇在 Centos 8 / RHEL 8 上安装 VNC 服务器的分步指南为你提供了轻松设置 VNC 服务器并访问远程桌面的所有信息。请在下面的评论栏中提供你的意见和建议。下篇文章再见。谢谢再见!!!


via: https://www.linuxtechi.com/install-configure-vnc-server-centos8-rhel8/

作者:Pradeep Kumar 选题:lujun9972 译者:geekpi 校对:wxy

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

这些必不可少的 Bash 快捷键可在命令行上节省时间。

大多数介绍 Bash 历史记录的指南都详尽地列出了全部可用的快捷方式。这样做的问题是,你会对每个快捷方式都浅尝辄止,然后在尝试了那么多的快捷方式后就搞得目不暇接。而在开始工作时它们就全被丢在脑后,只记住了刚开始使用 Bash 时学到的 !! 技巧。这些技巧大多数从未进入记忆当中。

本文概述了我每天实际使用的快捷方式。它基于我的书《Bash 学习,艰难之旅》中的某些内容(你可以阅读其中的样章以了解更多信息)。

当人们看到我使用这些快捷方式时,他们经常问我:“你做了什么!?” 学习它们只需付出很少的精力或智力,但是要真正的学习它们,我建议每周用一天学一个,然后下次再继续学习一个。值得花时间让它们落在你的指尖下,因为从长远来看,节省的时间将很重要。

1、最后一个参数:!$

如果你仅想从本文中学习一种快捷方式,那就是这个。它会将最后一个命令的最后一个参数替换到你的命令行中。

看看这种情况:

$ mv /path/to/wrongfile /some/other/place
mv: cannot stat '/path/to/wrongfile': No such file or directory

啊哈,我在命令中写了错误的文件名 “wrongfile”,我应该用正确的文件名 “rightfile” 代替。

你可以重新键入上一个命令,并用 “rightfile” 完全替换 “wrongfile”。但是,你也可以键入:

$ mv /path/to/rightfile !$
mv /path/to/rightfile /some/other/place

这个命令也可以奏效。

在 Bash 中还有其他方法可以通过快捷方式实现相同的目的,但是重用上一个命令的最后一个参数的这种技巧是我最常使用的。

2、第 n 个参数:!:2

是不是干过像这样的事情:

$ tar -cvf afolder afolder.tar
tar: failed to open

像许多其他人一样,我也经常搞错 tar(和 ln)的参数顺序。

 title=

当你搞混了参数,你可以这样:

$ !:0 !:1 !:3 !:2
tar -cvf afolder.tar afolder

这样就不会出丑了。

上一个命令的各个参数的索引是从零开始的,并且可以用 !: 之后跟上该索引数字代表各个参数。

显然,你也可以使用它来重用上一个命令中的特定参数,而不是所有参数。

3、全部参数:!:1-$

假设我运行了类似这样的命令:

$ grep '(ping|pong)' afile

参数是正确的。然而,我想在文件中匹配 “ping” 或 “pong”,但我使用的是 grep 而不是 egrep

我开始输入 egrep,但是我不想重新输入其他参数。因此,我可以使用 !:1-$ 快捷方式来调取上一个命令的所有参数,从第二个(记住它们的索引从零开始,因此是 1)到最后一个(由 $ 表示)。

$ egrep !:1-$
egrep '(ping|pong)' afile
ping

你不用必须用 1-$ 选择全部参数;你也可以选择一个子集,例如 1-23-9 (如果上一个命令中有那么多参数的话)。

4、倒数第 n 行的最后一个参数:!-2:$

当我输错之后马上就知道该如何更正我的命令时,上面的快捷键非常有用,但是我经常在原来的命令之后运行别的命令,这意味着上一个命令不再是我所要引用的命令。

例如,还是用之前的 mv 例子,如果我通过 ls 检查文件夹的内容来纠正我的错误:

$ mv /path/to/wrongfile /some/other/place
mv: cannot stat '/path/to/wrongfile': No such file or directory
$ ls /path/to/
rightfile

我就不能再使用 !$ 快捷方式了。

在这些情况下,我可以在 ! 之后插入 -n:(其中 n 是要在历史记录中回溯的命令条数),以从较旧的命令取得最后的参数:

$ mv /path/to/rightfile !-2:$
mv /path/to/rightfile /some/other/place

同样,一旦你学会了它,你可能会惊讶于你需要使用它的频率。

5、进入文件夹:!$:h

从表面上看,这个看起来不太有用,但我每天要用它几十次。

想象一下,我运行的命令如下所示:

$ tar -cvf system.tar /etc/system
 tar: /etc/system: Cannot stat: No such file or directory
 tar: Error exit delayed from previous errors.

我可能要做的第一件事是转到 /etc 文件夹,查看其中的内容并找出我做错了什么。

我可以通过以下方法来做到这一点:

$ cd !$:h
cd /etc

这是说:“获取上一个命令的最后一个参数(/etc/system),并删除其最后的文件名部分,仅保留 / etc。”

6、当前行:!#:1

多年以来,在我最终找到并学会之前,我有时候想知道是否可以在当前行引用一个参数。我多希望我能早早学会这个快捷方式。我经常常使用它制作备份文件:

$ cp /path/to/some/file !#:1.bak
cp /path/to/some/file /path/to/some/file.bak

但当我学会之后,它很快就被下面的快捷方式替代了……

7、搜索并替换:!!:gs

这将搜索所引用的命令,并将前两个 / 之间的字符替换为后两个 / 之间的字符。

假设我想告诉别人我的 s 键不起作用,而是输出了 f

$ echo my f key doef not work
my f key doef not work

然后我意识到这里出现的 f 键都是错的。要将所有 f 替换为 s,我可以输入:

$ !!:gs/f /s /
echo my s key does not work
my s key does not work

它不只对单个字符起作用。我也可以替换单词或句子:

$ !!:gs/does/did/
echo my s key did not work
my s key did not work

测试一下

为了向你展示如何组合这些快捷方式,你知道这些命令片段将输出什么吗?

$ ping !#:0:gs/i/o
$ vi /tmp/!:0.txt
$ ls !$:h
$ cd !-2:$:h
$ touch !$!-3:$ !! !$.txt
$ cat !:1-$

总结

对于日常的命令行用户,Bash 可以作为快捷方式的优雅来源。虽然有成千上万的技巧要学习,但这些是我经常使用的最喜欢的技巧。

如果你想更深入地了解 Bash 可以教给你的全部知识,请买本我的书,《Bash 学习,艰难之旅》,或查看我的在线课程《精通 Bash shell》。


本文最初发布在 Ian 的博客 Zwischenzugs.com 上,并经允许重复发布。


via: https://opensource.com/article/19/10/bash-history-shortcuts

作者:Ian Miell 选题:lujun9972 译者:wxy 校对:wxy

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

出于一些原因,你可能需要每月收集一次 Linux 系统运行时间报告。如果是这样,你可以根据需要使用以下 bash 脚本 之一。

我们为什么要收集这份报告?在一段时间后重启 Linux 服务器是解决某些未解决问题的好方法。(LCTT 译注:本文这些观点值得商榷,很多服务器可以稳定运行几千天,尤其是有了内核热补丁之后,启动并不是必须的。)

建议每 180 天重新启动一次。但时间段也许取决于你公司的政策。如果你已经长时间运行服务器而没有重启。这可能导致服务器上出现一些性能或内存问题,我在许多服务器上都注意到了这一点。

这些脚本一次性提供了所有系统运行报告。

什么是 uptime 命令

uptime 命令将告诉你系统已经运行了多长时间。它在一行中显示以下信息:当前时间、系统运行了多长时间、当前登录了多少用户以及过去 1、5 和 15 分钟的平均系统负载。

什么是 tuptime?

tuptime 是用于报告系统的历史和统计运行时间的工具,可在重启之间保存。它类似于 uptime 命令,但输出更有趣。

1)检查 Linux 系统运行时间的 Bash 脚本

该 bash 脚本将收集所有服务器正常运行时间,并将报告发送到给定的电子邮箱地址。

请替换为你的电子邮箱地址,而不是用我们的,否则你将不会收到邮件。

# vi /opt/scripts/system-uptime-script.sh

#!/bin/bash
> /tmp/uptime-report.out
for host in cat /tmp/servers.txt
do
echo -n "$host: "
ssh $host uptime | awk '{print $3,$4}' | sed 's/,//'
done | column -t >> /tmp/uptime-report.out
cat /tmp/uptime-report.out | mail -s "Linux Servers Uptime Report" "[email protected]"

system-uptime-script.sh 设置可执行权限。

$ chmod +x /opt/scripts/system-uptime-script.sh

最后运行 bash 脚本获取输出。

# sh /opt/scripts/system-uptime-script.sh

你将收到类似以下的报告。

# cat /tmp/uptime-report.out

192.168.1.5:          2      days
192.168.1.6:          15     days
192.168.1.7:          30     days
192.168.1.8:          7      days
192.168.1.9:          67     days
192.168.1.10:         130    days
192.168.1.11:         23     days

2)检查 Linux 系统是否运行了 30 天以上的 Bash 脚本

此 bash 脚本会收集运行 30 天以上的服务器,并将报告发送到指定的邮箱地址。你可以根据需要更改天数。

# vi /opt/scripts/system-uptime-script-1.sh

#!/bin/bash
> /tmp/uptime-report-1.out 
for host in cat /tmp/servers.txt
do
echo -n "$host: "
ssh $host uptime | awk '{print $3,$4}' | sed 's/,//'
done | column -t >> /tmp/uptime-report-1.out
cat /tmp/uptime-report-1.out | awk ' $2 >= 30' > /tmp/uptime-report-2.out
cat /tmp/uptime-report-2.out | mail -s "Linux Servers Uptime Report" "[email protected]"

system-uptime-script-1.sh 设置可执行权限。

$ chmod +x /opt/scripts/system-uptime-script-1.sh

最后添加一条 cronjob 来自动执行。它会在每天早上 7 点运行。

# crontab -e

0 7 * * * /bin/bash /opt/scripts/system-uptime-script-1.sh

注意: 你会在每天早上 7 点会收到一封电子邮件提醒,它是昨天的详情。

你将收到类似下面的报告。

# cat /tmp/uptime-report-2.out

192.168.1.7:          30     days
192.168.1.9:          67     days
192.168.1.10:         130    days

via: https://www.2daygeek.com/bash-script-generate-linux-system-uptime-reports/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:geekpi 校对:wxy

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

也许,Fedora 社区追求其促进自由和开源的软件及内容的使命的最著名的方式就是开发 Fedora 软件发行版了。因此,我们将很大一部分的社区资源用于此任务也就不足为奇了。这篇文章总结了这些软件是如何“打包”的,以及使之成为可能的基础工具,如 rpm 之类。

RPM:最小的软件单元

可供用户选择的“版本”和“风味版”(spins / labs / silverblue)其实非常相似。它们都是由各种软件组成的,这些软件经过混合和搭配,可以很好地协同工作。它们之间的不同之处在于放入其中的具体工具不同。这种选择取决于它们所针对的用例。所有这些的“版本”和“风味版”基本组成单位都是 RPM 软件包文件。

RPM 文件是类似于 ZIP 文件或 tarball 的存档文件。实际上,它们使用了压缩来减小存档文件的大小。但是,除了文件之外,RPM 存档中还包含有关软件包的元数据。可以使用 rpm 工具查询:

$ rpm -q fpaste
fpaste-0.3.9.2-2.fc30.noarch

$ rpm -qi fpaste
Name        : fpaste
Version     : 0.3.9.2
Release     : 2.fc30
Architecture: noarch
Install Date: Tue 26 Mar 2019 08:49:10 GMT
Group       : Unspecified
Size        : 64144
License     : GPLv3+
Signature   : RSA/SHA256, Thu 07 Feb 2019 15:46:11 GMT, Key ID ef3c111fcfc659b9
Source RPM  : fpaste-0.3.9.2-2.fc30.src.rpm
Build Date  : Thu 31 Jan 2019 20:06:01 GMT
Build Host  : buildhw-07.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : https://pagure.io/fpaste
Bug URL     : https://bugz.fedoraproject.org/fpaste
Summary     : A simple tool for pasting info onto sticky notes instances
Description :
It is often useful to be able to easily paste text to the Fedora
Pastebin at http://paste.fedoraproject.org and this simple script
will do that and return the resulting URL so that people may
examine the output. This can hopefully help folks who are for
some reason stuck without X, working remotely, or any other
reason they may be unable to paste something into the pastebin

$ rpm -ql fpaste
/usr/bin/fpaste
/usr/share/doc/fpaste
/usr/share/doc/fpaste/README.rst
/usr/share/doc/fpaste/TODO
/usr/share/licenses/fpaste
/usr/share/licenses/fpaste/COPYING
/usr/share/man/man1/fpaste.1.gz

安装 RPM 软件包后,rpm 工具可以知道具体哪些文件被添加到了系统中。因此,删除该软件包也会删除这些文件,并使系统保持一致状态。这就是为什么要尽可能地使用 rpm 安装软件,而不是从源代码安装软件的原因。

依赖关系

如今,完全独立的软件已经非常罕见。甚至 fpaste,连这样一个简单的单个文件的 Python 脚本,都需要安装 Python 解释器。因此,如果系统未安装 Python(几乎不可能,但有可能),则无法使用 fpaste。用打包者的术语来说,“Python 是 fpaste运行时依赖项。”

构建 RPM 软件包时(本文不讨论构建 RPM 的过程),生成的归档文件中包括了所有这些元数据。这样,与 RPM 软件包归档文件交互的工具就知道必须要安装其它的什么东西,以便 fpaste 可以正常工作:

$ rpm -q --requires fpaste
/usr/bin/python3
python3
rpmlib(CompressedFileNames) &lt;= 3.0.4-1
rpmlib(FileDigests) &lt;= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) &lt;= 4.0-1
rpmlib(PayloadIsXz) &lt;= 5.2-1

$ rpm -q --provides fpaste
fpaste = 0.3.9.2-2.fc30

$ rpm -qi python3
Name        : python3
Version     : 3.7.3
Release     : 3.fc30
Architecture: x86_64
Install Date: Thu 16 May 2019 18:51:41 BST
Group       : Unspecified
Size        : 46139
License     : Python
Signature   : RSA/SHA256, Sat 11 May 2019 17:02:44 BST, Key ID ef3c111fcfc659b9
Source RPM  : python3-3.7.3-3.fc30.src.rpm
Build Date  : Sat 11 May 2019 01:47:35 BST
Build Host  : buildhw-05.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : https://www.python.org/
Bug URL     : https://bugz.fedoraproject.org/python3
Summary     : Interpreter of the Python programming language
Description :
Python is an accessible, high-level, dynamically typed, interpreted programming
language, designed with an emphasis on code readability.
It includes an extensive standard library, and has a vast ecosystem of
third-party libraries.

The python3 package provides the "python3" executable: the reference
interpreter for the Python language, version 3.
The majority of its standard library is provided in the python3-libs package,
which should be installed automatically along with python3.
The remaining parts of the Python standard library are broken out into the
python3-tkinter and python3-test packages, which may need to be installed
separately.

Documentation for Python is provided in the python3-docs package.

Packages containing additional libraries for Python are generally named with
the "python3-" prefix.

$ rpm -q --provides python3
python(abi) = 3.7
python3 = 3.7.3-3.fc30
python3(x86-64) = 3.7.3-3.fc30
python3.7 = 3.7.3-3.fc30
python37 = 3.7.3-3.fc30

解决 RPM 依赖关系

虽然 rpm 知道每个归档文件所需的依赖关系,但不知道在哪里找到它们。这是设计使然:rpm 仅适用于本地文件,必须具体告知它们的位置。因此,如果你尝试安装单个 RPM 软件包,则 rpm 找不到该软件包的运行时依赖项时就会出错。本示例尝试安装从 Fedora 软件包集中下载的软件包:

$ ls
python3-elephant-0.6.2-3.fc30.noarch.rpm

$ rpm -qpi python3-elephant-0.6.2-3.fc30.noarch.rpm
Name        : python3-elephant
Version     : 0.6.2
Release     : 3.fc30
Architecture: noarch
Install Date: (not installed)
Group       : Unspecified
Size        : 2574456
License     : BSD
Signature   : (none)
Source RPM  : python-elephant-0.6.2-3.fc30.src.rpm
Build Date  : Fri 14 Jun 2019 17:23:48 BST
Build Host  : buildhw-02.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : http://neuralensemble.org/elephant
Bug URL     : https://bugz.fedoraproject.org/python-elephant
Summary     : Elephant is a package for analysis of electrophysiology data in Python
Description :
Elephant - Electrophysiology Analysis Toolkit Elephant is a package for the
analysis of neurophysiology data, based on Neo.

$ rpm -qp --requires python3-elephant-0.6.2-3.fc30.noarch.rpm
python(abi) = 3.7
python3.7dist(neo) >= 0.7.1
python3.7dist(numpy) >= 1.8.2
python3.7dist(quantities) >= 0.10.1
python3.7dist(scipy) >= 0.14.0
python3.7dist(six) >= 1.10.0
rpmlib(CompressedFileNames) &lt;= 3.0.4-1
rpmlib(FileDigests) &lt;= 4.6.0-1
rpmlib(PartialHardlinkSets) &lt;= 4.0.4-1
rpmlib(PayloadFilesHavePrefix) &lt;= 4.0-1
rpmlib(PayloadIsXz) &lt;= 5.2-1

$ sudo rpm -i ./python3-elephant-0.6.2-3.fc30.noarch.rpm
error: Failed dependencies:
        python3.7dist(neo) >= 0.7.1 is needed by python3-elephant-0.6.2-3.fc30.noarch
        python3.7dist(quantities) >= 0.10.1 is needed by python3-elephant-0.6.2-3.fc30.noarch

理论上,你可以下载 python3-elephant 所需的所有软件包,并告诉 rpm 它们都在哪里,但这并不方便。如果 python3-neopython3-quantities 还有其它的运行时要求怎么办?很快,这种“依赖链”就会变得相当复杂。

存储库

幸运的是,有了 dnf 和它的朋友们,可以帮助解决此问题。与 rpm 不同,dnf 能感知到存储库。存储库是程序包的集合,带有告诉 dnf 这些存储库包含什么内容的元数据。所有 Fedora 系统都带有默认启用的默认 Fedora 存储库:

$ sudo dnf repolist
repo id              repo name                             status
fedora               Fedora 30 - x86_64                    56,582
fedora-modular       Fedora Modular 30 - x86_64               135
updates              Fedora 30 - x86_64 - Updates           8,573
updates-modular      Fedora Modular 30 - x86_64 - Updates     138
updates-testing      Fedora 30 - x86_64 - Test Updates      8,458

在 Fedora 快速文档中有这些存储库以及如何管理它们的更多信息。

dnf 可用于查询存储库以获取有关它们包含的软件包信息。它还可以在这些存储库中搜索软件,或从中安装/卸载/升级软件包:

$ sudo dnf search elephant
Last metadata expiration check: 0:05:21 ago on Sun 23 Jun 2019 14:33:38 BST.
============================================================================== Name &amp; Summary Matched: elephant ==============================================================================
python3-elephant.noarch : Elephant is a package for analysis of electrophysiology data in Python
python3-elephant.noarch : Elephant is a package for analysis of electrophysiology data in Python

$ sudo dnf list \*elephant\*
Last metadata expiration check: 0:05:26 ago on Sun 23 Jun 2019 14:33:38 BST.
Available Packages
python3-elephant.noarch      0.6.2-3.fc30      updates-testing
python3-elephant.noarch      0.6.2-3.fc30              updates

安装依赖项

现在使用 dnf 安装软件包时,它将解决所有必需的依赖项,然后调用 rpm 执行该事务操作:

$ sudo dnf install python3-elephant
Last metadata expiration check: 0:06:17 ago on Sun 23 Jun 2019 14:33:38 BST.
Dependencies resolved.
==============================================================================================================================================================================================
 Package                                      Architecture                     Version                                                        Repository                                 Size
==============================================================================================================================================================================================
Installing:
 python3-elephant                             noarch                           0.6.2-3.fc30                                                   updates-testing                           456 k
Installing dependencies:
 python3-neo                                  noarch                           0.8.0-0.1.20190215git49b6041.fc30                              fedora                                    753 k
 python3-quantities                           noarch                           0.12.2-4.fc30                                                  fedora                                    163 k
Installing weak dependencies:
 python3-igor                                 noarch                           0.3-5.20150408git2c2a79d.fc30                                  fedora                                     63 k

Transaction Summary
==============================================================================================================================================================================================
Install  4 Packages

Total download size: 1.4 M
Installed size: 7.0 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): python3-igor-0.3-5.20150408git2c2a79d.fc30.noarch.rpm                                                                                                  222 kB/s |  63 kB     00:00
(2/4): python3-elephant-0.6.2-3.fc30.noarch.rpm                                                                                                               681 kB/s | 456 kB     00:00
(3/4): python3-quantities-0.12.2-4.fc30.noarch.rpm                                                                                                            421 kB/s | 163 kB     00:00
(4/4): python3-neo-0.8.0-0.1.20190215git49b6041.fc30.noarch.rpm                                                                                               840 kB/s | 753 kB     00:00
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                         884 kB/s | 1.4 MB     00:01
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                      1/1
  Installing       : python3-quantities-0.12.2-4.fc30.noarch                                                                                                                              1/4
  Installing       : python3-igor-0.3-5.20150408git2c2a79d.fc30.noarch                                                                                                                    2/4
  Installing       : python3-neo-0.8.0-0.1.20190215git49b6041.fc30.noarch                                                                                                                 3/4
  Installing       : python3-elephant-0.6.2-3.fc30.noarch                                                                                                                                 4/4
  Running scriptlet: python3-elephant-0.6.2-3.fc30.noarch                                                                                                                                 4/4
  Verifying        : python3-elephant-0.6.2-3.fc30.noarch                                                                                                                                 1/4
  Verifying        : python3-igor-0.3-5.20150408git2c2a79d.fc30.noarch                                                                                                                    2/4
  Verifying        : python3-neo-0.8.0-0.1.20190215git49b6041.fc30.noarch                                                                                                                 3/4
  Verifying        : python3-quantities-0.12.2-4.fc30.noarch                                                                                                                              4/4

Installed:
  python3-elephant-0.6.2-3.fc30.noarch   python3-igor-0.3-5.20150408git2c2a79d.fc30.noarch   python3-neo-0.8.0-0.1.20190215git49b6041.fc30.noarch   python3-quantities-0.12.2-4.fc30.noarch

Complete!

请注意,dnf 甚至还安装了python3-igor,而它不是 python3-elephant 的直接依赖项。

DnfDragora:DNF 的一个图形界面

尽管技术用户可能会发现 dnf 易于使用,但并非所有人都这样认为。Dnfdragora 通过为 dnf 提供图形化前端来解决此问题。

dnfdragora (version 1.1.1-2 on Fedora 30) listing all the packages installed on a system.

从上面可以看到,dnfdragora 似乎提供了 dnf 的所有主要功能。

Fedora 中还有其他工具也可以管理软件包,GNOME 的“ 软件 Software ”和“ 发现 Discover ”就是其中两个。GNOME “软件”仅专注于图形应用程序。你无法使用这个图形化前端来安装命令行或终端工具,例如 htopweechat。但是,GNOME “软件”支持安装 dnf 所不支持的 Flatpak 和 Snap 应用程序。它们是针对不同目标受众的不同工具,因此提供了不同的功能。

这篇文章仅触及到了 Fedora 软件的生命周期的冰山一角。本文介绍了什么是 RPM 软件包,以及使用 rpmdnf 的主要区别。

在以后的文章中,我们将详细介绍:

  • 创建这些程序包所需的过程
  • 社区如何测试它们以确保它们正确构建
  • 社区用来将其给到社区用户的基础设施

via: https://fedoramagazine.org/rpm-packages-explained/

作者:Ankur Sinha FranciscoD 选题:lujun9972 译者:wxy 校对:wxy

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