分类 技术 下的文章

MyCLI 是一个易于使用的命令行客户端,可用于受欢迎的数据库管理系统 MySQL、MariaDB 和 Percona,支持自动补全和语法高亮。它是使用 prompt_toolkit 库写的,需要 Python 2.7、3.3、3.4、3.5 和 3.6 的支持。MyCLI 还支持通过 SSL 安全连接到 MySQL 服务器。

MyCLI 的特性

  • 当你第一次使用它的时候,将会自动创建一个文件 ~/.myclirc
  • 当输入 SQL 的关键词和数据库中的表、视图和列时,支持自动补全。
  • 默认情况下也支持智能补全,能根据上下文的相关性提供补全建议。

比如:

SELECT * FROM <Tab> - 这将显示出数据库中的表名。
SELECT * FROM users WHERE <Tab> - 这将简单的显示出列名称。
  • 通过使用 Pygents 支持语法高亮
  • 支持 SSL 连接
  • 提供多行查询支持
  • 它可以将每一个查询和输出记录到一个文件中(默认情况下禁用)。
  • 允许保存收藏一个查询(使用 \fs 别名 保存一个查询,并可使用 \f 别名 运行它)。
  • 支持 SQL 语句执行和表查询计时
  • 以更吸引人的方式打印表格数据

如何在 Linux 上为 MySQL 和 MariaDB 安装 MyCLI

在 Debian/Ubuntu 发行版上,你可以很容易的像下面这样使用 apt 命令 来安装 MyCLI 包:

$ sudo apt-get update
$ sudo apt-get install mycli

同样,在 Fedora 22+ 上也有 MyCLI 的可用包,你可以像下面这样使用 dnf 命令 来安装它:

$ sudo dnf install mycli

对于其他 Linux 发行版,比如 RHEL/CentOS,你需要使用 Python 的 pip 工具来安装 MyCLI。首先,使用下面的命令来安装 pip:

$ sudo yum install pip  

安装好 pip 以后,你可以像下面这样安装 MyCLI:

$ sudo pip install mycli

在 Linux 中如何使用 MyCLI 连接 MySQL 和 MariaDB

安装好 MyCLI 以后,你可以像下面这样使用它:

$ mycli -u root -h localhost 

自动补全

对于关键词和 SQL 函数可以进行简单的自动补全:

MySQL Auto Completion

MySQL 自动补全

智能补全

当输入 FROM 关键词以后会进行表名称的补全:

MySQL Smart Completion

MySQL 智能补全

别名支持

当表的名称设置别名以后,也支持列名称的补全:

MySQL Alias Support

MySQL 别名支持

语法高亮

支持 MySQL 语法高亮:

MySQL Syntax Highlighting

MySQL 语法高亮

格式化 SQL 的输出

MySQL 的输出会通过 less 命令 进行格式化输出:

MySQL Formatted Output

MySQL 格式化输出

要登录 MySQL 并同时选择数据库,你可以使用和下面类似的命令:

$ mycli local_database
$ mycli -h localhost -u root app_db
$ mycli mysql://amjith@localhost:3306/django_poll

更多使用选项,请输入:

$ mycli --help

MyCLI 主页: http://mycli.net/index

记得阅读一些关于 MySQL 管理的有用文章:

  1. 在 Linux 中用于数据库管理的 20 个 MySQL(Mysqladmin)命令
  2. 如何在 Linux 中更改默认的 MySQL/MariaDB 数据目录
  3. 在 Linux 中监测 MySQL 性能的 4 个实用命令行工具
  4. 如何在 Linux 中更改 MySQL 或 MariaDB 的 Root 密码
  5. MySQL 备份和恢复数据库管理命令

MyCLI 作者写的两篇如何创建具有可发现性的交互式命令行客户端的文章:

  1. 4 个拥有绝佳命令行界面的终端程序
  2. 4 个用于构建优秀的命令行用户界面的 Python 库

这就是本文的全部内容了。在这篇指南中,我们展示了如何通过一些简单的命令在 Linux 中安装和使用 MyCLI。记得通过下面的反馈表向我们分享你关于这篇文章的想法。


作者简介:

Aaron Kili是一名 Linux 和 F.O.S.S 的爱好者,未来的 Linux 系统管理员、网站开发人员,目前是 TecMint 的内容创作者,他喜欢用电脑工作,并乐于分享知识。


via: https://www.tecmint.com/mycli-mysql-client-with-auto-completion-syntax-highlighting/

作者:Aaron Kili 译者:ucasFL 校对:wxy

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

在之前的一篇文章里,我们回顾了 Linux 下 9 个最好的文件比较工具,本篇文章中,我们将会描述在 Linux 下怎样找到两个目录之间的不同。

一般情况下,要在 Linux 下比较两个文件,我们会使用 diff (一个简单的源自 Unix 的命令行工具)来显示两个计算机文件的不同;它一行一行的去比较文件,而且很方便使用,在几乎全部的 Linux 发行版都预装了。

问题是在 Linux 下我们怎么才能比较两个目录?现在,我们想知道两个目录中哪些文件/子目录是共有的,哪些只存在一个于目录。

运行 diff 常规的语法如下:

$ diff [OPTION]… FILES
$ diff options dir1 dir2 

默认情况下,输出是按文件/子文件夹的文件名的字母排序的,如下面截图所示,在命令中, -q 开关是告诉 diif 只有在文件有差异时报告。

$ diff -q directory-1/ directory-2/

Difference Between Two Directories

两个文件夹之间的差异

再次运行 diff 并不能进入子文件夹,但是我们可以使用 -r 开关来读子文件夹,如下所示。

$ diff -qr directory-1/ directory-2/ 

使用 Meld 可视化比较和合并工具

meld 是一个很酷的图形化工具(一个 GNOME 桌面下的可视化的比较和合并工具),可供那些喜欢使用鼠标的人使用,可按如下来安装。

$ sudo apt install meld  [Debian/Ubuntu systems]
$ sudo yum install meld  [RHEL/CentOS systems]
$ sudo dnf install meld  [Fedora 22+]

一旦你安装了它之后,在 Ubuntu Dash 或者 Linux Mint 菜单搜索 “meld” ,或者 Fedora 或 CentOS 桌面的 Activities Overview,然后启动它。

你可以看到如下的 Meld 界面,可以选择文件或者文件夹来比较,此外还有版本控制视图。点击目录比较并移动到下个界面。 Meld Comparison Tool

Meld 比较工具

选择你想要比较的文件夹,注意你可以勾选 “3-way Comparison” 选项,添加第三个文件夹。

Select Comparison Directories

选择比较的文件夹

选择好要比较的文件夹后,点击 “Compare”。

Listing Difference Between +

文件夹不同列表

在这篇文章中,我们描述了怎么在 Linux 下找到两个文件夹的不同。如果你知道其他的命令或者图形界面工具,不要忘记在下方评论分享你们的想法。


作者简介:

Aaron Kili 是一个 Linux 和 F.O.S.S 爱好者,即将成为 Linux 系统管理员,Web 开发者,目前是 TecMint 的内容创建者,他喜欢使用电脑工作,并且非常相信分享知识。


via: http://www.tecmint.com/compare-find-difference-between-two-directories-in-linux/

作者:Aaron Kili 译者:hkurj 校对:jasminepeng

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

本系列教程将引导你了解如何在 CentOS 7 安装 iRedMail 以及 Samba4 AD 域控制器,以便域帐户可以通过 Thunderbird 桌面客户端或通过 Roundcube Web 界面发送或接收邮件。

将要安装 iRedMail 的 CentOS 7 服务器需允许通过 25 和 587 端口进行 SMTP 或邮件路由服务,并且还将通过 Dovecot 作为邮件传递代理,提供 POP3 和 IMAP 服务,两者都使用安装过程中签发的自签名证书进行安全保护。

收件人邮箱将与 Roundcube 提供的 webmail 用户代理一起存储在同一台 CentOS 服务器上。iRedMail 将使用 Samba4 AD 来查询和验证收件人帐户,在 AD 组的帮助下创建邮件列表,并通过 Samba4 AD DC 控制邮件帐户。

需要:

步骤 1:在 CentOS 7 上安装 iRedMail

1、 在安装 iRedMail 之前,请先确保你使用下面的指南在你的机器上安装了一个全新的 CentOS 7 操作系统:

2、 同样使用下面的命令确保系统更新了最新的安全补丁和软件包。

# yum update

3、 系统同样需要一个 FQDN 主机名,使用下面的命令设置。使用你自定义的 FQDN 代替 mail.tecmint.lan 变量。

# hostnamectl set-hostname mail.tecmint.lan

使用下面的命令验证系统主机名。

# hostname -s   # Short name
# hostname -f   # FQDN
# hostname -d   # Domain
# cat /etc/hostname  # Verify it with cat command

Verify CentOS 7 Hostname

验证 CentOS 7 主机名

4、 通过手动编辑 /etc/hosts,将机器的 FQDN 和短名称映射到机器的回环 IP 地址。添加如下所示的值,并相应替换 mail.tecmint.lan 和 mail 的值。

127.0.0.1   mail.tecmint.lan mail  localhost localhost.localdomain

5、 iRedMail 专家建议应该完全禁用 SELinux。通过编辑 /etc/selinux/config 并将 SELINUX 参数的值从 permissive 设置成 disabled 来禁用 SELinux。

SELINUX=disabled

重启机器并应用新的 SELinux 策略,或者运行 setenforce 带上参数 0 来强制 SELinux 立即禁用。

# reboot
或者
# setenforce 0

6、 接下来,安装下面这些接下来会用来系统管理的软件包:

# yum install bzip2 net-tools bash-completion wget

7、 要安装 iRedMail,首先打开下载页 http://www.iredmail.org/download.html 中并用下面的命令下载最新的版本。

# wget https://bitbucket.org/zhb/iredmail/downloads/iRedMail-0.9.6.tar.bz2

8、 下载完成后,使用下面命令解压压缩包并进入解压后的 iRedMail 目录。

# tar xjf iRedMail-0.9.6.tar.bz2 
# cd iRedMail-0.9.6/
# ls

9、 使用下面的命令执行 iRedMail 的 shell 脚本来开始安装。接下来安装器会询问一系列的问题。

# bash iRedMail.sh

10、 在首个欢迎提示中,点击 Yes 来继续安装。

iRedMail Setup Wizard

iRedMail 安装向导

11、 接下来,选择邮件存储的位置。iRedMail 默认邮箱的存储位置在 /var/vmail/ 中。

如果这个目录所在的分区有足够的空间来保存你所有域帐户的邮件,接着点击 Next 来继续。

否则,如果你已经配置一个更大的分区来用于邮件存储,那么就用不同的目录来更改默认位置。

iRedMail Mail Storage Path

iRedMail 邮件存储路径

12、 在下一步中,选择要与 iRedMail 进行交互的前端 Web 服务器。今后将完全禁用 iRedMail 管理面板,因此我们将使用前端 Web 服务器仅通过 Roundcube Web 面板访问帐户邮件。

如果你每小时没有数以千计的邮件帐户访问 webmail 界面,那么你应该使用 Apache Web 服务器来实现其灵活性和易于管理。

iRedMail Preferred Web Server

iRedMail 首选的 Web 服务器

13、 在此步骤中,由于 Samba4 域控制器的兼容性原因,请选择 OpenLDAP 后端数据库,并点击 Next 继续,但是一旦将 iRedMail 集成到 Samba 域控制器中,我们将不再使用该 OpenLDAP 数据库。

iRedMail LDAP Backend

iRedMail LDAP 后端

14、 接下来,如下图所示,为你的 Samba4 域名指定 LDAP 后缀,然后点击 Next 继续。

iRedMail LDAP Suffix

iRedMail LDAP 后缀

15、 在接下来的提示中,只要输入你的域名,并点击 Next 继续。相应地替换 tecmint.lan 值。

iRedMail Mail Domain

iRedMail 邮件域

16、 现在,为 [email protected] 管理员设置一个密码,并点击 Next 继续。

iRedMail Mail Domain Administrator

iRedMail 邮件域管理员

17、 接下来,从列表中选择要与邮件服务器集成的可选组件。我强烈建议你安装 Roundcube,以便为域帐户提供访问邮件的 Web 界面,尽管你也可以在不同的计算机上安装并配置 Roundcube,以便在高负载情况下释放邮件服务器资源。

对于受限访问互联网的本地域,特别是在我们使用域集成时,除了 Awstats 可以用于你进行邮件分析,其他组件不是非常有用。

iRedMail Optional Components

iRedMail 可选组件

18、 在下一步中输入 Y 来应用配置并开始安装。

iRedMail Configuration Changes

iRedMail 配置更改

19、 最后,所有的问题都输入 Y,接受 iRedMail 脚本自动配置你的防火墙以及 MySQL 配置文件。

iRedMail System Configuration

iRedMail 系统配置

20、 安装完成后,安装器会提供一些敏感信息。比如 iRedAdmin 凭证、web 面板的 URL 地址以及安装过程中使用的所有参数的文件位置。

iRedMail Installation Summary

iRedMail 安装总结

仔细阅读上面的信息,使用下面的命令重启机器来使所有的邮件服务启用。

# init 6

21、 系统重启后,使用 root 权限的帐户登录或以 root 身份登录,并使用下面的命令列出所有的网络套接字以及你邮件服务器监听的相关程序。

在套接字列表中,你会看到邮件服务器几乎覆盖邮件服务正常运行所需的所有服务:SMTP/S、POP3/S、IMAP/S 和防病毒以及垃圾邮件保护。

# netstat -tulpn

iRedMail Network Sockets

iRedMail 网络套接字

22、 为了查看 iRedMail 已修改的所有配置文件的位置、iRedMail 安装过程中用于数据库管理的凭据、邮件管理帐户以及其他帐户,那么就显示 iRedMail.tips 这个文件。

该文件位于你最初解压安装包的目录中。请注意,你应该移动并保护此文件,因为它包含有关邮件服务器的敏感信息。

# less iRedMail-0.9.6/iRedMail.tips

23、 上面提到的包含邮件服务器详细信息的文件也将自动发送到 postmaster 这个邮件服务器管理员帐户中。

通过在浏览器中输入机器的 IP 地址,你可以通过 HTTPS 协议安全地访问 webmail。接受 iRedMail 自签名证书在浏览器中生成的错误,并使用在安装中为 postmaster@your\_domain.tld 帐户设置的密码登录。阅读并将此电子邮件存储到一个安全的邮箱。

https://192.168.1.254

iRedMail Account Login

iRedMail 登录帐户

iRedMail Web Mail

iRedMail Web 邮件

就是这样了!到目前为止,你已经配置了一台完整的自己运行的邮件服务器了,但尚未与 Samba4 AD 域控制器服务集成。

在下一部分中,我们将看到如何修改 iRedMail 服务(postfix,dovecot 和 roundcube 配置文件),以便查询域帐户、发送、接收和读取邮件。


作者简介:

我是一个电脑上瘾的家伙,开源和基于 linux 系统软件的粉丝,在 Linux 发行版桌面、服务器和 bash 脚本方面拥有大约 4 年的经验。


via: http://www.tecmint.com/install-iredmail-on-centos-7-for-samba4-ad-integration/

作者:Matei Cezar 译者:geekpi 校对:wxy

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

快速测试 - 下面的代码输出什么?

vals := make([]int, 5)  
for i := 0; i < 5; i++ {  
  vals = append(vals, i)
}
fmt.Println(vals)  

在 Go Playground 运行一下

如果你猜测的是 [0 0 0 0 0 0 1 2 3 4],那你是对的。

等等,什么? 为什么不是 [0 1 2 3 4]?

如果你在测试中做错了,你也不用担心。这是在过渡到 Go 语言的过程中相当常见的错误,在这篇文章中,我们将说明为什么输出不是你预期的,以及如何利用 Go 的细微差别来使你的代码更有效率。

切片 vs 数组

在 Go 中同时有数组(array)和切片(slice)。这可能令人困惑,但一旦你习惯了,你会喜欢上它。请相信我。

切片和数组之间存在许多差异,但我们要在本文中重点介绍的内容是数组的大小是其类型的一部分,而切片可以具有动态大小,因为它们是围绕数组的封装。

这在实践中意味着什么?那么假设我们有数组 val a [10]int。该数组具有固定大小,且无法更改。如果我们调用 len(a),它总是返回 10,因为这个大小是类型的一部分。因此,如果你突然需要在数组中超过 10 个项,则必须创建一个完全不同类型的新对象,例如 val b [11]int,然后将所有值从 a 复制到 b

在特定情况下,含有集合大小的数组是有价值的,但一般而言,这不是开发人员想要的。相反,他们希望在 Go 中使用类似于数组的东西,但是随着时间的推移,它们能够随时增长。一个粗略的方式是创建一个比它需要大得多的数组,然后将数组的一个子集视为数组。下面的代码是个例子。

var vals [20]int  
for i := 0; i < 5; i++ {  
  vals[i] = i * i
}
subsetLen := 5

fmt.Println("The subset of our array has a length of:", subsetLen)

// Add a new item to our array
vals[subsetLen] = 123  
subsetLen++  
fmt.Println("The subset of our array has a length of:", subsetLen)  

在 Go Playground 中运行

在代码中,我们有一个长度为 20 的数组,但是由于我们只使用一个子集,代码中我们可以假定数组的长度是 5,然后在我们向数组中添加一个新的项之后是 6

这是(非常粗略地说)切片是如何工作的。它们包含一个具有设置大小的数组,就像我们前面的例子中的数组一样,它的大小为 20

它们还跟踪程序中使用的数组的子集 - 这就是 append 属性,它类似于上一个例子中的 subsetLen 变量。

最后,一个切片还有一个 capacity,类似于前面例子中我们的数组的总长度(20)。这是很有用的,因为它会告诉你的子集在无法容纳切片数组之前可以增长的大小。当发生这种情况时,需要分配一个新的数组,但所有这些逻辑都隐藏在 append 函数的后面。

简而言之,使用 append 函数组合切片给我们一个非常类似于数组的类型,但随着时间的推移,它可以处理更多的元素。

我们再来看一下前面的例子,但是这次我们将使用切片而不是数组。

var vals []int  
for i := 0; i < 5; i++ {  
  vals = append(vals, i)
  fmt.Println("The length of our slice is:", len(vals))
  fmt.Println("The capacity of our slice is:", cap(vals))
}

// Add a new item to our array
vals = append(vals, 123)  
fmt.Println("The length of our slice is:", len(vals))  
fmt.Println("The capacity of our slice is:", cap(vals))

// Accessing items is the same as an array
fmt.Println(vals[5])  
fmt.Println(vals[2])  

在 Go Playground 中运行

我们仍然可以像数组一样访问我们的切片中的元素,但是通过使用切片和 append 函数,我们不再需要考虑背后数组的大小。我们仍然可以通过使用 lencap 函数来计算出这些东西,但是我们不用担心太多。简洁吧?

回到测试

记住这点,让我们回顾前面的测试,看下什么出错了。

vals := make([]int, 5)  
for i := 0; i < 5; i++ {  
  vals = append(vals, i)
}
fmt.Println(vals)  

当调用 make 时,我们允许最多传入 3 个参数。第一个是我们分配的类型,第二个是类型的“长度”,第三个是类型的“容量”(这个参数是可选的)。

通过传递参数 make([]int, 5),我们告诉程序我们要创建一个长度为 5 的切片,在这种情况下,默认的容量与长度相同 - 本例中是 5。

虽然这可能看起来像我们想要的那样,这里的重要区别是我们告诉我们的切片,我们要将“长度”和“容量”设置为 5,假设你想要在初始的 5 个元素之后添加新的元素,我们接着调用 append 函数,那么它会增加容量的大小,并且会在切片的最后添加新的元素。

如果在代码中添加一条 Println() 语句,你可以看到容量的变化。

vals := make([]int, 5)  
fmt.Println("Capacity was:", cap(vals))  
for i := 0; i < 5; i++ {  
  vals = append(vals, i)
  fmt.Println("Capacity is now:", cap(vals))
}

fmt.Println(vals)  

在 Go Playground 中运行

最后,我们最终得到 [0 0 0 0 0 0 1 2 3 4] 的输出而不是希望的 [0 1 2 3 4]

如何修复它呢?好的,这有几种方法,我们将讲解两种,你可以选取任何一种在你的场景中最有用的方法。

直接使用索引写入而不是 append

第一种修复是保留 make 调用不变,并且显式地使用索引来设置每个元素。这样,我们就得到如下的代码:

vals := make([]int, 5)  
for i := 0; i < 5; i++ {  
  vals[i] = i
}
fmt.Println(vals)  

在 Go Playground 中运行

在这种情况下,我们设置的值恰好与我们要使用的索引相同,但是你也可以独立跟踪索引。

比如,如果你想要获取 map 的键,你可以使用下面的代码。

package main

import "fmt"

func main() {  
  fmt.Println(keys(map[string]struct{}{
    "dog": struct{}{},
    "cat": struct{}{},
  }))
}

func keys(m map[string]struct{}) []string {  
  ret := make([]string, len(m))
  i := 0
  for key := range m {
    ret[i] = key
    i++
  }
  return ret
}

在 Go Playground 中运行

这样做很好,因为我们知道我们返回的切片的长度将与 map 的长度相同,因此我们可以用该长度初始化我们的切片,然后将每个元素分配到适当的索引中。这种方法的缺点是我们必须跟踪 i,以便了解每个索引要设置的值。

这就让我们引出了第二种方法……

使用 0 作为你的长度并指定容量

与其跟踪我们要添加的值的索引,我们可以更新我们的 make 调用,并在切片类型之后提供两个参数。第一个,我们的新切片的长度将被设置为 0,因为我们还没有添加任何新的元素到切片中。第二个,我们新切片的容量将被设置为 map 参数的长度,因为我们知道我们的切片最终会添加许多字符串。

这会如前面的例子那样仍旧会在背后构建相同的数组,但是现在当我们调用 append 时,它会将它们放在切片开始处,因为切片的长度是 0。

package main

import "fmt"

func main() {  
  fmt.Println(keys(map[string]struct{}{
    "dog": struct{}{},
    "cat": struct{}{},
  }))
}

func keys(m map[string]struct{}) []string {  
  ret := make([]string, 0, len(m))
  for key := range m {
    ret = append(ret, key)
  }
  return ret
}

在 Go Playground 中运行

如果 append 处理它,为什么我们还要担心容量呢?

接下来你可能会问:“如果 append 函数可以为我增加切片的容量,那我们为什么要告诉程序容量呢?”

事实是,在大多数情况下,你不必担心这太多。如果它使你的代码变得更复杂,只需用 var vals []int 初始化你的切片,然后让 append 函数处理接下来的事。

但这种情况是不同的。它并不是声明容量困难的例子,实际上这很容易确定我们的切片的最后容量,因为我们知道它将直接映射到提供的 map 中。因此,当我们初始化它时,我们可以声明切片的容量,并免于让我们的程序执行不必要的内存分配。

如果要查看额外的内存分配情况,请在 Go Playground 上运行以下代码。每次增加容量,程序都需要做一次内存分配。

package main

import "fmt"

func main() {  
  fmt.Println(keys(map[string]struct{}{
    "dog":       struct{}{},
    "cat":       struct{}{},
    "mouse":     struct{}{},
    "wolf":      struct{}{},
    "alligator": struct{}{},
  }))
}

func keys(m map[string]struct{}) []string {  
  var ret []string
  fmt.Println(cap(ret))
  for key := range m {
    ret = append(ret, key)
    fmt.Println(cap(ret))
  }
  return ret
}

在 Go Playground 中运行

现在将此与相同的代码进行比较,但具有预定义的容量。

package main

import "fmt"

func main() {  
  fmt.Println(keys(map[string]struct{}{
    "dog":       struct{}{},
    "cat":       struct{}{},
    "mouse":     struct{}{},
    "wolf":      struct{}{},
    "alligator": struct{}{},
  }))
}

func keys(m map[string]struct{}) []string {  
  ret := make([]string, 0, len(m))
  fmt.Println(cap(ret))
  for key := range m {
    ret = append(ret, key)
    fmt.Println(cap(ret))
  }
  return ret
}

在 Go Playground 中运行

在第一个代码示例中,我们的容量从 0 开始,然后增加到 124, 最后是 8,这意味着我们不得不分配 5 次数组,最后一个容纳我们切片的数组的容量是 8,这比我们最终需要的要大。

另一方面,我们的第二个例子开始和结束都是相同的容量(5),它只需要在 keys() 函数的开头分配一次。我们还避免了浪费任何额外的内存,并返回一个能放下这个数组的完美大小的切片。

不要过分优化

如前所述,我通常不鼓励任何人做这样的小优化,但如果最后大小的效果真的很明显,那么我强烈建议你尝试为切片设置适当的容量或长度。

这不仅有助于提高程序的性能,还可以通过明确说明输入的大小和输出的大小之间的关系来帮助澄清你的代码。

总结

你好!我写了很多关于Go、Web 开发和其他我觉得有趣的话题。

如果你想跟上最新的文章,请注册我的邮件列表。我会给你发送我新书的样例、Go 的 Web 开发、以及每当有新文章(通常每周 1-2 次)会给你发送邮件。

哦,我保证不会发垃圾邮件。我像你一样讨厌它 :)

本文并不是对切片或数组之间差异的详细讨论,而是简要介绍了容量和长度如何影响切片,以及它们在方案中的用途。

为了进一步阅读,我强烈推荐 Go 博客中的以下文章:


作者简介:

Jon 是一名软件顾问,也是 《Web Development with Go》 一书的作者。在此之前,他创立了 EasyPost,一家 Y Combinator 支持的创业公司,并在 Google 工作。

https://www.usegolang.com


via: https://www.calhoun.io/how-to-use-slice-capacity-and-length-in-go

作者:Jon Calhoun 译者:geekpi 校对:wxy

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

OTRS ,即开源 问题单 ticket 申请系统,是一个用于客户服务、帮助台和 IT 服务管理的开源问题单软件。该软件是用 Perl 和 javascript 编写的。对于那些需要管理票据、投诉、支持请求或其他类型的报告的公司和组织来说,这是一个问题单解决方案。OTRS 支持包括 MySQL、PostgreSQL、Oracle 和 SQL Server 在内的多个数据库系统,它是一个可以安装在 Windows 和 Linux 上的多平台软件。

在本教程中,我将介绍如何在 Ubuntu 16.04 上安装和配置 OTRS。我将使用 PostgreSQL 作为 OTRS 的数据库,将 Apache Web 服务器用作 Web 服务器。

先决条件

  • Ubuntu 16.04。
  • 最小 2GB 的内存。
  • root 权限

步骤 1 - 安装 Apache 和 PostgreSQL

在第一步中,我们将安装 Apache Web 服务器以及 PostgreSQL。我们将从 ubuntu 仓库中使用最新的版本。

使用 SSH 登录到你的 Ubuntu 服务器中:

ssh [email protected]

更新 Ubuntu 仓库。

sudo apt-get update

使用 apt 安装 Apache2 以及 PostgreSQL:

sudo apt-get install -y apache2 libapache2-mod-perl2 postgresql

通过检查服务器端口确保 Apache 以及 PostgreSQL 运行了。

netstat -plntu

Install Apache and PostgreSQL

你可以看到 80 端口被 apache 使用了,5432 端口被 postgresql 数据库使用了。

步骤 2 - 安装 Perl 模块

OTRS 基于 Perl,因此我们需要安装一些 OTRS 需要的 Perl 模块。

使用这个 apt 命令安装 perl 模块:

sudo apt-get install -y libapache2-mod-perl2 libdbd-pg-perl libnet-dns-perl libnet-ldap-perl libio-socket-ssl-perl libpdf-api2-perl libsoap-lite-perl libgd-text-perl libgd-graph-perl libapache-dbi-perl libarchive-zip-perl libcrypt-eksblowfish-perl libcrypt-ssleay-perl libencode-hanextra-perl libjson-xs-perl libmail-imapclient-perl libtemplate-perl libtext-csv-xs-perl libxml-libxml-perl libxml-libxslt-perl libpdf-api2-simple-perl libyaml-libyaml-perl

安装完成后,我们需要为 apache 激活 Perl 模块,接着重启 apache 服务。

a2enmod perl
systemctl restart apache2

接下来,使用下面的命令检查模块是否已经加载了:

apachectl -M | sort

Enable Apache Perl Module

你可以在 “Loaded Modules” 部分下看到 perl\_module

步骤 3 - 为 OTRS 创建新用户

OTRS 是一个基于 web 的程序并且运行与 apache web 服务器下。为了安全,我们需要以普通用户运行它,而不是 root 用户。

使用 useradd 命令创建一个 otrs 新用户:

useradd -r -d /opt/otrs -c 'OTRS User' otrs
  • -r:将用户作为系统用户。
  • -d /opt/otrs:在 /opt/otrs 下放置新用户的主目录。
  • -c:备注。

接下来,将 otrs 用户加入到 www-data 用户组,因为 apache 运行于 www-data 用户及用户组。

usermod -a -G www-data otrs

/etc/passwd 文件中已经有 otrs 用户了。

grep -rin otrs /etc/passwd

Create new user for OTRS

OTRS 的新用户已经创建了。

步骤 4 - 创建和配置数据库

在这节中,我们会为 OTRS 系统创建一个新 PostgreSQL 数据库,并对 PostgreSQL 数据库的配置做一些小的更改。

登录到 postgres 用户并访问 PostgreSQL shell。

su - postgres
psql

创建一个新的角色 otrs,密码是 myotrspw,并且是非特权用户。

create user otrs password 'myotrspw' nosuperuser;

接着使用 otrs 用户权限创建一个新的 otrs 数据库:

create database otrs owner otrs;
\q

接下来为 otrs 角色验证编辑 PostgreSQL 配置文件。

vim /etc/postgresql/9.5/main/pg_hba.conf

在 84 行后粘贴下面的配置:

local   otrs            otrs                                    password
host    otrs            otrs            127.0.0.1/32            password

保存文件并退出 vim

Database Authentication OTRS

使用 exit 回到 root 权限并重启 PostgreSQL:

exit
systemctl restart postgresql

PostgreSQL 已经为 OTRS 的安装准备好了。

Configure PostgreSQL for OTRS

步骤 5 - 下载和配置 OTRS

在本教程中,我们会使用 OTRS 网站中最新的版本。

进入 /opt 目录并使用 wget 命令下载 OTRS 5.0:

cd /opt/
wget http://ftp.otrs.org/pub/otrs/otrs-5.0.16.tar.gz

展开该 otrs 文件,重命名目录并更改所有 otrs 的文件和目录的所属人为 otrs

tar -xzvf otrs-5.0.16.tar.gz
mv otrs-5.0.16 otrs
chown -R otrs:otrs otrs

接下来,我们需要检查系统并确保可以安装 OTRS 了。

使用下面的 otrs 脚本命令检查 OTRS 安装需要的系统软件包:

/opt/otrs/bin/otrs.CheckModules.pl

确保所有的结果是对的,这意味着我们的服务器可以安装 OTRS 了。

OTRS Chek Module needed for Installation

OTRS 已下载,并且我们的服务器可以安装 OTRS 了。

接下,进入 otrs 目录并复制配置文件。

cd /opt/otrs/
cp Kernel/Config.pm.dist Kernel/Config.pm

使用 vim 编辑 Config.pm 文件:

vim Kernel/Config.pm

更改 42 行的数据库密码:

$Self->{DatabasePw} = 'myotrspw';

注释 45 行的 MySQL 数据库支持:

# $Self->{DatabaseDSN} = "DBI:mysql:database=$Self->{Database};host=$Self->{DatabaseHost};";

取消注释 49 行的 PostgreSQL 数据库支持:

$Self->{DatabaseDSN} = "DBI:Pg:dbname=$Self->{Database};";

保存文件并退出 vim。

接着编辑 apache 启动文件来启用 PostgreSQL 支持。

vim scripts/apache2-perl-startup.pl

取消注释 60 和 61 行:

# enable this if you use postgresql
use DBD::Pg ();
use Kernel::System::DB::postgresql;

保存文件并退出编辑器。

最后,检查缺失的依赖和模块。

perl -cw /opt/otrs/bin/cgi-bin/index.pl
perl -cw /opt/otrs/bin/cgi-bin/customer.pl
perl -cw /opt/otrs/bin/otrs.Console.pl

你可以在下面的截图中看到结果是 “OK”:

Check all modules again

步骤 6 - 导入样本数据库

在本教程中,我们会使用样本数据库,这可以在脚本目录中找到。因此我们只需要将所有的样本数据库以及表结构导入到第 4 步创建的数据库中。

登录到 postgres 用户并进入 otrs 目录中。

su - postgres
cd /opt/otrs/

作为 otrs 用户使用 psql 命令插入数据库以及表结构。

psql -U otrs -W -f scripts/database/otrs-schema.postgresql.sql otrs
psql -U otrs -W -f scripts/database/otrs-initial_insert.postgresql.sql otrs
psql -U otrs -W -f scripts/database/otrs-schema-post.postgresql.sql otrs

在需要的时候输入数据库密码 myotrspw

Import OTRS Sample Database

步骤 7 - 启动 OTRS

数据库以及 OTRS 已经配置了,现在我们可以启动 OTRS。

将 otrs 的文件及目录权限设置为 www-data 用户和用户组。

/opt/otrs/bin/otrs.SetPermissions.pl --otrs-user=www-data --web-group=www-data

通过创建一个新的链接文件到 apache 虚拟主机目录中启用 otrs apache 配置。

ln -s /opt/otrs/scripts/apache2-httpd.include.conf /etc/apache2/sites-available/otrs.conf

启用 otrs 虚拟主机并重启 apache。

a2ensite otrs
systemctl restart apache2

确保 apache 启动没有错误。

Enable OTRS Apache Virtual Host

步骤 8 - 配置 OTRS 计划任务

OTRS 已经安装并运行在 Apache Web 服务器中了,但是我们仍然需要配置 OTRS 计划任务。

登录到 otrs 用户,接着以 otrs 用户进入 var/cron 目录。

su - otrs
cd var/cron/
pwd

使用下面的命令复制所有 .dist 计划任务脚本:

for foo in *.dist; do cp $foo `basename $foo .dist`; done

使用 exit 回到 root 权限,并使用 otrs 用户启动计划任务脚本。

exit
/opt/otrs/bin/Cron.sh start otrs

Enable OTRS Cron

接下来,手动收取电子邮件的 PostMaster 创建一个新的计划任务。我会配置为每 2 分钟收取一次邮件。

su - otrs
crontab -e

粘贴下面的配置:

*/2 * * * *    $HOME/bin/otrs.PostMasterMailbox.pl >> /dev/null

保存并退出。

现在停止 otrs 守护进程并再次启动。

bin/otrs.Daemon.pl stop
bin/otrs.Daemon.pl start

Enable OTRS Fetching Email

OTRS 安装以及配置完成了。

步骤 9 - 测试 OTRS

打开你的 web 浏览器并输入你的服务器 IP 地址: http://192.168.33.14/otrs/

使用默认的用户 root@localhost 以及密码 root 登录。

Installation Successfully OTRS Home Page

使用默认的 root 账户你会看到一个警告。点击警告信息来创建一个新的 admin root 用户。

下面是用另外的 admin root 用户登录后出现的 admin 页面,这里没有出现错误信息。

OTRS Admin Dashboard Without Error Messages

如果你想作为客户登录,你可以使用 customer.plhttp://192.168.33.14/otrs/customer.pl

你会看到客户登录界面,输入客户的用户名和密码。

OTRS Customer Login Page

下面是一个创建新单据的客户页面。

Customer Open Ticket

步骤 10 - 疑难排查

如果你仍旧看到 “OTRS Daemon is not running” 的错误,你可以像这样调试 OTRS 守护进程。

su - otrs
cd /opt/otrs/

停止 OTRS 守护进程:

bin/otrs.Daemon.pl stop

使用 --debug 选项启动 OTRS 守护进程。

bin/otrs.Daemon.pl start --debug

参考


via: https://www.howtoforge.com/tutorial/how-to-install-otrs-opensource-trouble-ticket-system-on-ubuntu-16-04/

作者:Muhammad Arul 译者:geekpi 校对:wxy

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

在这个分为两篇的关于具有绝佳命令行界面的终端程序的系列文章的第二篇教程中,我们将讨论 Prompt、Toolkit、Click、Pygments 和 Fuzzy Finder 。

 title=

这是我的一个分为两篇的关于具有绝佳命令行界面的终端程序的系列文章的第二篇教程。在第一篇文章中,我们讨论了一些能够使命令行应用用起来令人感到愉悦的特性。在第二篇文章中,我们来看看如何用 Python 的一些库来实现这些特性。

我打算用少于 20 行 Python 代码来实现。让我们开始吧。

Python Prompt Toolkit

我习惯于把这个库称为命令行应用的瑞士军刀,它可以作为 readlinecurses 等的替代品。让我们首先安装这个库,然后开始该教程:

pip install prompt_toolkit

我们以一个简单的 REPL (LCTT 译注:REPL —— Read-Eval-Print Loop,交互式开发环境)开始。一个典型的 REPL 会接收用户的输入,进行一个操作,然后输出结果。比如在我们的例子中,我们将要实现一个具有 “回显” 功能的 REPL 。它仅仅是原样打印出用户的输入:

REPL

from prompt_toolkit import prompt

while 1:
    user_input = prompt('>')
    print(user_input)

这就是实现 REPL 的全部代码。它可以读取用户的输入,然后打印出用户的输入内容。在这段代码中使用的 prompt 函数来自 prompt_toolkit 库,它是 readline 库的一个替代品。

命令历史

为了增强我们的 REPL 的功能,我们可以添加命令历史:

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory

while 1:
    user_input = prompt('>', 
                        history=FileHistory('history.txt'),
                       )
    print(user_input)

我们刚刚给 REPL 添加了持久的命令历史。现在,我们可以使用上/下箭头来浏览命令历史,并使用 Ctrl-R 来搜索命令历史。它满足了命令行的基本准则。

自动推荐

在第一篇教程中,我讲到的一个可发现性技巧是自动推荐历史命令。(我是首先在 fish shell 中看到的这一特性)让我们把这一特性加入到我们的 REPL 中:

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory

while 1:
    user_input = prompt('>', 
                        history=FileHistory('history.txt'),
                        auto_suggest=AutoSuggestFromHistory(),
                       )
    print(user_input)

我们只需要给 prompt() API 调用添加一个新的参数。现在,我们有了一个具有 fish shell 风格的 REPL,它可以自动推荐历史命令

自动补全

现在,让我们通过自动补全来加强 Tab 补全。它能够在用户开始输入的时候弹出可能的命令推荐。

REPL 如何来进行推荐呢?我们使用一个字典来进行可能项的推荐。

比如说我们实现一个针对 SQL 的 REPL 。我们可以把 SQL 关键字存到自动补全字典里面。让我们看一看这是如何实现的:

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.contrib.completers import WordCompleter

SQLCompleter = WordCompleter(['select', 'from', 'insert', 'update', 'delete', 'drop'],
                             ignore_case=True)

while 1:
    user_input = prompt('SQL>', 
                        history=FileHistory('history.txt'),
                        auto_suggest=AutoSuggestFromHistory(),
                        completer=SQLCompleter,
                        )
    print(user_input)

再次说明,我们只是简单的使用了 prompt-toolkit 内建的一个叫做 WordCompleter 的补全特性,它能够把用户输入和可能推荐的字典进行匹配,然后提供一个列表。

现在,我们有了一个能够自动补全、fish shell 风格的历史命令推荐以及上/下浏览历史的 REPL 。实现这些特性只用了不到 10 行的实际代码。

Click

Click 是一个命令行创建工具包,使用它能够更容易的为程序解析命令行选项的参数和常量。在这儿我们不讨论如何使用 Click 来作为参数解析器。相反,我们将会看看 Click 带有的一些功能。

安装 Click

pip install click

分页器

分页器是 Unix 系统上的实用工具,它们能够一次一页地显示很长的输出。分页器的一些例子包括 lessmoremost 等。通过分页器来显示一个命令的输出不仅仅是一个友好的设计,同时也是必要的。

让我们进一步改进前面的例子。我们不再使用默认的 print() 语句,取而代之的是 click.echo_via_pager() 。它将会把输出通过分页器发送到标准输出。这是平台无关的,因此在 Unix 系统或 Windows 系统上均能工作。如果必要的话,click_via_pager 会尝试使用一个合适的默认分页器来输出,从而能够显示代码高亮。

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.contrib.completers import WordCompleter
import click

SQLCompleter = WordCompleter(['select', 'from', 'insert', 'update', 'delete', 'drop'],
                             ignore_case=True)

while 1:
    user_input = prompt(u'SQL>',
                        history=FileHistory('history.txt'),
                        auto_suggest=AutoSuggestFromHistory(),
                        completer=SQLCompleter,
                        )
    click.echo_via_pager(user_input)

编辑器

在我前面的文章中一个值得一提的细节是,当命令过于复杂的时候进入编辑器来编辑。Click 有一个简单的 API 能够打开编辑器,然后把在编辑器中输入的文本返回给应用。

import click
message = click.edit()

Fuzzy Finder

Fuzzy Finder 是一种通过少量输入来为用户减少推荐的方法。幸运的是,有一个库可以实现 Fuzzy Finder 。让我们首先安装这个库:

pip install fuzzyfinder

Fuzzy Finder 的 API 很简单。用户向它传递部分字符串和一系列可能的选择,然后,Fuzzy Finder 将会返回一个与部分字符串匹配的列表,这一列表是通过模糊算法根据相关性排序得出的。比如:

>>> from fuzzyfinder import fuzzyfinder

>>> suggestions = fuzzyfinder('abc', ['abcd', 'defabca', 'aagbec', 'xyz', 'qux'])

>>> list(suggestions)
['abcd', 'defabca', 'aagbec']

现在我们有了 fuzzyfinder,让我们把它加入到我们的 SQL REPL 中。方法是我们自定义一个 completer 而不是使用来自 prompt-toolkit 库的 WordCompleter 。比如:

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import Completer, Completion
import click
from fuzzyfinder import fuzzyfinder

SQLKeywords = ['select', 'from', 'insert', 'update', 'delete', 'drop']

class SQLCompleter(Completer):
    def get_completions(self, document, complete_event):
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        matches = fuzzyfinder(word_before_cursor, SQLKeywords)
        for m in matches:
            yield Completion(m, start_position=-len(word_before_cursor))

while 1:
    user_input = prompt(u'SQL>',
                        history=FileHistory('history.txt'),
                        auto_suggest=AutoSuggestFromHistory(),
                        completer=SQLCompleter(),
                        )
    click.echo_via_pager(user_input)

Pygments

现在,让我们给用户输入添加语法高亮。我们正在搭建一个 SQL REPL,如果具有彩色高亮的 SQL 语句,这会很棒。

Pygments 是一个提供语法高亮的库,内建支持超过 300 种语言。添加语法高亮能够使应用变得彩色化,从而能够帮助用户在执行程序前发现 SQL 中存在的错误,比如拼写错误、引号不匹配或括号不匹配。

首先,安装 Pygments

pip install pygments

让我们使用 Pygments 来为 SQL REPL 添加颜色:

from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import Completer, Completion
import click
from fuzzyfinder import fuzzyfinder
from pygments.lexers.sql import SqlLexer

SQLKeywords = ['select', 'from', 'insert', 'update', 'delete', 'drop']

class SQLCompleter(Completer):
    def get_completions(self, document, complete_event):
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        matches = fuzzyfinder(word_before_cursor, SQLKeywords)
        for m in matches:
            yield Completion(m, start_position=-len(word_before_cursor))

while 1:
    user_input = prompt(u'SQL>',
                        history=FileHistory('history.txt'),
                        auto_suggest=AutoSuggestFromHistory(),
                        completer=SQLCompleter(),
                        lexer=SqlLexer,
                        )
    click.echo_via_pager(user_input)

Prompt Toolkit 能够和 Pygments 一同很好的工作。我们把 Pygments 提供的 SqlLexer 加入到来自 prompt-toolkitprompt 中。现在,所有的用户输入都会被当作 SQL 语句,并进行适当着色。

结论

我们的“旅途”通过创建一个强大的 REPL 结束,这个 REPL 具有常见的 shell 的全部特性,比如历史命令,键位绑定,用户友好性比如自动补全、模糊查找、分页器支持、编辑器支持和语法高亮。我们仅用少于 20 行 Python 代码就实现了这个 REPL 。

不是很简单吗?现在,你没有理由不会写一个自己的命令行应用了。下面这些资源可能有帮助:

你也可以在我在 PyCon US 2017 的演讲优秀的命令行工具中学到更多东西,该会议是 5 月 20 日在波特兰,俄勒冈举行的。

(题图 : 美国 Mennonite 教堂档案 。 Opensource.com. CC BY-SA 4.0


作者简介:

Amjith Ramanujam - Amjith Ramanujam 是 pgclimycli 的创始人。人们认为它们很酷,他表示笑纳赞誉。他喜欢用 Python、JavaScript 和 C 编程。他喜欢写一些简单、易于理解的代码,有时候这样做是成功的。


via: https://opensource.com/article/17/5/4-practical-python-libraries

作者:Amjith Ramanujam 译者:ucasFL 校对:wxy

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