2015年8月

今天,我们将学习如何快速地对docker容器进行快捷备份、恢复和迁移。Docker是一个开源平台,用于自动化部署应用,以通过快捷的途径在称之为容器的轻量级软件层下打包、发布和运行这些应用。它使得应用平台独立,因为它扮演了Linux上一个额外的操作系统级虚拟化的自动化抽象层。它通过其组件cgroups和命名空间利用Linux内核的资源分离特性,达到避免虚拟机开销的目的。它使得用于部署和扩展web应用、数据库和后端服务的大规模构建组件无需依赖于特定的堆栈或供应者。

所谓的容器,就是那些创建自Docker镜像的软件层,它包含了独立的Linux文件系统和开箱即用的应用程序。如果我们有一个在机器中运行着的Docker容器,并且想要备份这些容器以便今后使用,或者想要迁移这些容器,那么,本教程将帮助你掌握在Linux操作系统中备份、恢复和迁移Docker容器的方法。

我们怎样才能在Linux中备份、恢复和迁移Docker容器呢?这里为您提供了一些便捷的步骤。

1. 备份容器

首先,为了备份Docker中的容器,我们会想看看我们想要备份的容器列表。要达成该目的,我们需要在我们运行着Docker引擎,并已创建了容器的Linux机器中运行 docker ps 命令。

# docker ps

Docker Containers List

在此之后,我们要选择我们想要备份的容器,然后去创建该容器的快照。我们可以使用 docker commit 命令来创建快照。

# docker commit -p 30b8f18f20b4 container-backup

Docker Commit

该命令会生成一个作为Docker镜像的容器快照,我们可以通过运行 docker images 命令来查看Docker镜像,如下。

# docker images

Docker Images

正如我们所看见的,上面做的快照已经作为Docker镜像保存了。现在,为了备份该快照,我们有两个选择,一个是我们可以登录进Docker注册中心,并推送该镜像;另一个是我们可以将Docker镜像打包成tar包备份,以供今后使用。

如果我们想要在Docker注册中心上传或备份镜像,我们只需要运行 docker login 命令来登录进Docker注册中心,然后推送所需的镜像即可。

# docker login

Docker Login

# docker tag a25ddfec4d2a arunpyasi/container-backup:test
# docker push arunpyasi/container-backup

Docker Push

如果我们不想备份到docker注册中心,而是想要将此镜像保存在本地机器中,以供日后使用,那么我们可以将其作为tar包备份。要完成该操作,我们需要运行以下 docker save 命令。

# docker save -o ~/container-backup.tar container-backup

taking tarball backup

要验证tar包是否已经生成,我们只需要在保存tar包的目录中运行 ls 命令即可。

2. 恢复容器

接下来,在我们成功备份了我们的Docker容器后,我们现在来恢复这些制作了Docker镜像快照的容器。如果我们已经在注册中心推送了这些Docker镜像,那么我们仅仅需要把那个Docker镜像拖回并直接运行即可。

# docker pull arunpyasi/container-backup:test

Docker Pull

但是,如果我们将这些Docker镜像作为tar包文件备份到了本地,那么我们只要使用 docker load 命令,后面加上tar包的备份路径,就可以加载该Docker镜像了。

# docker load -i ~/container-backup.tar

现在,为了确保这些Docker镜像已经加载成功,我们来运行 docker images 命令。

# docker images

在镜像被加载后,我们将用加载的镜像去运行Docker容器。

# docker run -d -p 80:80 container-backup

Restoring Docker Tarball

3. 迁移Docker容器

迁移容器同时涉及到了上面两个操作,备份和恢复。我们可以将任何一个Docker容器从一台机器迁移到另一台机器。在迁移过程中,首先我们将把容器备份为Docker镜像快照。然后,该Docker镜像或者是被推送到了Docker注册中心,或者被作为tar包文件保存到了本地。如果我们将镜像推送到了Docker注册中心,我们简单地从任何我们想要的机器上使用 docker run 命令来恢复并运行该容器。但是,如果我们将镜像打包成tar包备份到了本地,我们只需要拷贝或移动该镜像到我们想要的机器上,加载该镜像并运行需要的容器即可。

尾声

最后,我们已经学习了如何快速地备份、恢复和迁移Docker容器,本教程适用于各个可以成功运行Docker的操作系统平台。真的,Docker是一个相当简单易用,然而功能却十分强大的工具。它的命令相当易记,这些命令都非常短,带有许多简单而强大的标记和参数。上面的方法让我们备份容器时很是安逸,使得我们可以在日后很轻松地恢复它们。这会帮助我们恢复我们的容器和镜像,即便主机系统崩溃,甚至意外地被清除。如果你还有很多问题、建议、反馈,请在下面的评论框中写出来吧,可以帮助我们改进或更新我们的内容。谢谢大家!享受吧 :-)


via: http://linoxide.com/linux-how-to/backup-restore-migrate-containers-docker/

作者:Arun Pyasi 译者:GOLinux 校对:wxy

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

按照预期计划, LibreOffice 5 开源办公套件于今日发布。

LibreOffice 5.0 带来了许多新功能,从 首次支持 GTK3 和 Wayland 到为支持移动和云端所做的基础工作,以及对 spreadsheets 的改进、OpenGL 渲染的提升等等。

你可以在 LibreOffice 5.0 的开发者 Michael Meeks 的博客读到更多的底层工作。现在就可以在 LibreOffice.org 下载支持所有主要平台的 LibreOffice 了。

下载

如果需要,还可以下载简体中文及其他语言的语言包。

用正则表达式验证邮件地址似乎是一件简单的事情,但是如果要完美的验证一个合规的邮件地址,其实也许很复杂。

邮件地址的规范来自于 RFC 5322 。有一个网站 emailregex.com 专门列出各种编程语言下的验证邮件地址的正则表达式,其中很多正则表达式都是我听说过而从未见过的复杂——我想说,做这个网站的程序员是被邮件验证这件事伤害了多深啊!

其实,在产品环境中,一般来说并不需要这么复杂的正则表达式来做到99.99%正确。一般来说,从执行效率和测试覆盖率来说,只需要一个简单的版本即可:

/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i

那么下面我们来看看这些更严谨、更复杂的正则表达式吧:

验证邮件地址的通用正则表达式(符合 RFC 5322 标准)

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

由于各种语言对正则表达式的支持不同、语法差异和覆盖率不同,所以,不同语言里面的正则表达式也不同:

Python

这个是个简单的版本:

r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"

Javascript

这个有点复杂了:

/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i

Swift

[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}

PHP

PHP 的这个版本就更复杂了,覆盖率就更大一些:

/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD

Perl / Ruby

对与 PHP 的版本,Perl 和 Ruby 表示不服,可以更严谨:

(?:(?:
)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[\t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)*\<(?:(?:
)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[\t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*(?:,@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*)*:(?:(?:
)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*\>(?:(?:
)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)*:(?:(?:
)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\]\000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)*\<(?:(?:
)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*(?:,@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\]\000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*)*:(?:(?:
)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*\>(?:(?:
)?[ \t])*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)*\<(?:(?:
)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*(?:,@(?:(?:
)?[\t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*)*:(?:(?:
)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:
)?[ \t]))*"(?:(?:
)?[ \t])*))*@(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*)(?:\.(?:(?:
)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:
)?[ \t])*))*\>(?:(?:
)?[ \t])*))*)?;\s

Perl 5.10 及以后版本

上面的版本,嗯,我可以说是天书吗?反正我是没有解读的想法了。当然,新版本的 Perl 语言还有一个更易读的版本(你是说真的么?)

/(?(DEFINE)
(?<address> (?&mailbox) | (?&group))
(?<mailbox> (?&name_addr) | (?&addr_spec))
(?<name_addr> (?&display_name)? (?&angle_addr))
(?<angle_addr> (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
(?<group> (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
(?&CFWS)?)
(?<display_name> (?&phrase))
(?<mailbox_list> (?&mailbox) (?: , (?&mailbox))*)

(?<addr_spec> (?&local_part) \@ (?&domain))
(?<local_part> (?&dot_atom) | (?&quoted_string))
(?<domain> (?&dot_atom) | (?&domain_literal))
(?<domain_literal> (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
\] (?&CFWS)?)
(?<dcontent> (?&dtext) | (?&quoted_pair))
(?<dtext> (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

(?<atext> (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
(?<atom> (?&CFWS)? (?&atext)+ (?&CFWS)?)
(?<dot_atom> (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
(?<dot_atom_text> (?&atext)+ (?: \. (?&atext)+)*)

(?<text> [\x01-\x09\x0b\x0c\x0e-\x7f])
(?<quoted_pair> \\ (?&text))

(?<qtext> (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
(?<qcontent> (?&qtext) | (?&quoted_pair))
(?<quoted_string> (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
(?&FWS)? (?&DQUOTE) (?&CFWS)?)

(?<word> (?&atom) | (?&quoted_string))
(?<phrase> (?&word)+)

# Folding white space
(?<FWS> (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
(?<ctext> (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
(?<ccontent> (?&ctext) | (?&quoted_pair) | (?&comment))
(?<comment> \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
(?<CFWS> (?: (?&FWS)? (?&comment))*
(?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

# No whitespace control
(?<NO_WS_CTL> [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

(?<ALPHA> [A-Za-z])
(?<DIGIT> [0-9])
(?<CRLF> \x0d \x0a)
(?<DQUOTE> ")
(?<WSP> [\x20\x09])
)

(?&address)/x

Ruby (简单版)

Ruby 表示,其实人家还有个简单版本:

/\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i

.NET

这样的版本谁没有啊——.NET 说:

^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

grep 命令

用 grep 命令在文件中查找邮件地址,我想你不会写个若干行的正则表达式吧,意思一下就行了:

$ grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" filename.txt

SQL Server

在 SQL Server 中也是可以用正则表达式的,不过这个代码片段应该是来自某个产品环境中的,所以,还体贴的照顾了那些把邮件地址写错的人:

 select email 
 from table_name where 
 patindex ('%[ &'',":;!+=\/()<>]%', email) > 0 -- Invalid characters
 or patindex ('[@.-_]%', email) > 0 -- Valid but cannot be starting character
 or patindex ('%[@.-_]', email) > 0 -- Valid but cannot be ending character
 or email not like '%@%.%' -- Must contain at least one @ and one .
 or email like '%..%' -- Cannot have two periods in a row
 or email like '%@%@%' -- Cannot have two @ anywhere
 or email like '%.@%' or email like '%@.%' -- Cannot have @ and . next to each other
 or email like '%.cm' or email like '%.co' -- Camaroon or Colombia? Typos. 
 or email like '%.or' or email like '%.ne' -- Missing last letter

Oracle PL/SQL

这个是不是有点偷懒?尤其是在那些“复杂”的正则表达式之后:

SELECT email 
FROM table_name
WHERE REGEXP_LIKE (email, '[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}');

MySQL

好吧,看来最后也一样懒:

SELECT * FROM `users` WHERE `email` NOT REGEXP '^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$';

那么,你有没有关于验证邮件地址的正则表达式分享给大家?

不久前,开源模式还被成熟的工业级厂商以怀疑的态度认作是叛逆小孩的玩物。如今,开源的促进会和基金会在一长列的供应商提供者的支持下正蓬勃发展,而他们将开源模式视作创新的关键。

技术的开放发展驱动着创新

在过去的 20 几年间,技术的开源推进已被视作驱动创新的关键因素。即使那些以前将开源视作威胁的公司也开始接受这个观点 — 例如微软,如今它在一系列的开源的促进会中表现活跃。到目前为止,大多数的开源推进都集中在软件方面,但甚至这个也正在改变,因为社区已经开始向开源硬件倡议方面聚拢。这里介绍 7 个成功地在硬件和软件方面同时促进和发展开源技术的组织。

OpenPOWER 基金会

OpenPOWER 基金会 由 IBM, Google, Mellanox, Tyan 和 NVIDIA 于 2013 年共同创建,在与开源软件发展相同的精神下,旨在驱动开放协作硬件的发展,在过去的 20 几年间,开源软件发展已经找到了肥沃的土壤。

IBM 通过开放其基于 Power 架构的硬件和软件技术,向使用 Power IP 的独立硬件产品提供许可证等方式为基金会的建立播下种子。如今超过 70 个成员共同协作来为基于 Linux 的数据中心提供自定义的开放服务器,组件和硬件。

去年四月,在比最新基于 x86 系统快 50 倍的数据分析能力的新的 POWER8 处理器的服务器的基础上, OpenPOWER 推出了一个技术路线图。七月, IBM 和 Google 发布了一个固件堆栈。去年十月见证了 NVIDIA GPU 带来加速 POWER8 系统的能力和来自 Tyan 的第一个 OpenPOWER 参考服务器。

Linux 基金会

于 2000 年建立的 Linux 基金会 如今成为掌控着历史上最大的开源协同开发成果,它有着超过 180 个合作成员和许多独立成员及学生成员。它赞助 Linux 核心开发者的工作并促进、保护和推进 Linux 操作系统,并协调软件的协作开发。

它最为成功的协作项目包括 Code Aurora Forum (一个拥有为移动无线产业服务的企业财团),MeeGo (一个为移动设备和 IVI [注:指的是车载消息娱乐设备,为 In-Vehicle Infotainment 的简称] 构建一个基于 Linux 内核的操作系统的项目) 和 Open Virtualization Alliance (开放虚拟化联盟,它促进自由和开源软件虚拟化解决方案的采用)。

开放虚拟化联盟

开放虚拟化联盟(OVA) 的存在目的为:通过提供使用案例和对具有互操作性的通用接口和 API 的发展提供支持,来促进自由、开源软件的虚拟化解决方案,例如 KVM 的采用。KVM 将 Linux 内核转变为一个虚拟机管理程序。

如今, KVM 已成为和 OpenStack 共同使用的最为常见的虚拟机管理程序。

OpenStack 基金会

原本作为一个 IaaS(基础设施即服务) 产品由 NASA 和 Rackspace 于 2010 年启动,OpenStack 基金会 已成为最大的开源项目聚居地之一。它拥有超过 200 家公司成员,其中包括 AT&T, AMD, Avaya, Canonical, Cisco, Dell 和 HP。

大约以 6 个月为一个发行周期,基金会的 OpenStack 项目开发用于通过一个基于 Web 的仪表盘,命令行工具或一个 RESTful 风格的 API 来控制或调配流经一个数据中心的处理存储池和网络资源。至今为止,基金会支持的协同开发已经孕育出了一系列 OpenStack 组件,其中包括 OpenStack Compute(一个云计算网络控制器,它是一个 IaaS 系统的主要部分),OpenStack Networking(一个用以管理网络和 IP 地址的系统) 和 OpenStack Object Storage(一个可扩展的冗余存储系统)。

OpenDaylight

作为来自 Linux 基金会的另一个协作项目, OpenDaylight 是一个由诸如 Dell, HP, Oracle 和 Avaya 等行业厂商于 2013 年 4 月建立的联合倡议。它的任务是建立一个由社区主导、开源、有工业支持的针对软件定义网络( SDN: Software-Defined Networking)的包含代码和蓝图的框架。其思路是提供一个可直接部署的全功能 SDN 平台,而不需要其他组件,供应商可提供附件组件和增强组件。

Apache 软件基金会

Apache 软件基金会 (ASF) 是将近 150 个顶级项目的聚居地,这些项目涵盖从开源的企业级自动化软件到与 Apache Hadoop 相关的分布式计算的整个生态系统。这些项目分发企业级、可免费获取的软件产品,而 Apache 协议则是为了让无论是商业用户还是个人用户更方便地部署 Apache 的产品。

ASF 是 1999 年成立的一个会员制,非盈利公司,以精英为其核心 — 要成为它的成员,你必须首先在基金会的一个或多个协作项目中做出积极贡献。

开放计算项目

作为 Facebook 重新设计其 Oregon 数据中心的副产物, 开放计算项目 旨在发展针对数据中心的开源硬件解决方案。 OCP 是一个由廉价无浪费的服务器、针对 Open Rack(为数据中心设计的机架标准,来让机架集成到数据中心的基础设施中) 的模块化 I/O 存储和一个相对 "绿色" 的数据中心设计方案等构成。

OCP 董事会成员包括来自 Facebook,Intel,Goldman Sachs,Rackspace 和 Microsoft 的代表。

OCP 最近宣布了有两种可选的许可证: 一个类似 Apache 2.0 的允许衍生工作的许可证,和一个更规范的鼓励将更改回馈到原有软件的许可证。


via: http://www.networkworld.com/article/2866074/opensource-subnet/7-communities-driving-open-source-development.html

作者:Thor Olavsrud 译者:FSSlc 校对:wxy

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

在我们之前的文章中,我们介绍了什么是 LVM 以及能用 LVM 做什么,今天我们会给你介绍一些 LVM 的主要管理工具,使得你在设置和扩展安装时更游刃有余。

正如之前所述,LVM 是介于你的操作系统和物理硬盘驱动器之间的抽象层。这意味着你的物理硬盘驱动器和分区不再依赖于他们所在的硬盘驱动和分区。而是你的操作系统所见的硬盘驱动和分区可以是由任意数目的独立硬盘汇集而成的或是一个软件磁盘阵列。

要管理 LVM,这里有很多可用的 GUI 工具,但要真正理解 LVM 配置发生的事情,最好要知道一些命令行工具。这当你在一个服务器或不提供 GUI 工具的发行版上管理 LVM 时尤为有用。

LVM 的大部分命令和彼此都非常相似。每个可用的命令都由以下其中之一开头:

  • Physical Volume (物理卷) = pv
  • Volume Group (卷组)= vg
  • Logical Volume (逻辑卷)= lv

物理卷命令用于在卷组中添加或删除硬盘驱动。卷组命令用于为你的逻辑卷操作更改显示的物理分区抽象集。逻辑卷命令会以分区形式显示卷组,使得你的操作系统能使用指定的空间。

可下载的 LVM 备忘单

为了帮助你理解每个前缀可用的命令,我们制作了一个备忘单。我们会在该文章中介绍一些命令,但仍有很多你可用但没有介绍到的命令。

该列表中的所有命令都要以 root 身份运行,因为你更改的是会影响整个机器系统级设置。

如何查看当前 LVM 信息

你首先需要做的事情是检查你的 LVM 设置。s 和 display 命令可以和物理卷(pv)、卷组(vg)以及逻辑卷(lv)一起使用,是一个找出当前设置的好起点。

display 命令会格式化输出信息,因此比 s 命令更易于理解。对每个命令你会看到名称和 pv/vg 的路径,它还会给出空闲和已使用空间的信息。

最重要的信息是 PV 名称和 VG 名称。用这两部分信息我们可以继续进行 LVM 设置。

创建一个逻辑卷

逻辑卷是你的操作系统在 LVM 中使用的分区。创建一个逻辑卷,首先需要拥有一个物理卷和卷组。下面是创建一个新的逻辑卷所需要的全部命令。

创建物理卷

我们会从一个全新的没有任何分区和信息的硬盘开始。首先找出你将要使用的磁盘。(/dev/sda, sdb, 等)

注意:记住所有的命令都要以 root 身份运行或者在命令前面添加 'sudo' 。
fdisk -l

如果之前你的硬盘从未格式化或分区过,在 fdisk 的输出中你很可能看到类似下面的信息。这完全正常,因为我们会在下面的步骤中创建需要的分区。

我们的新磁盘位置是 /dev/sdb,让我们用 fdisk 命令在磁盘上创建一个新的分区。

这里有大量能创建新分区的 GUI 工具,包括 Gparted,但由于我们已经打开了终端,我们将使用 fdisk 命令创建需要的分区。

在终端中输入以下命令:

fdisk /dev/sdb

这会使你进入到一个特殊的 fdisk 提示符中。

以指定的顺序输入命令创建一个使用新硬盘 100% 空间的主分区并为 LVM 做好了准备。如果你需要更改分区的大小或想要多个分区,我建议使用 GParted 或自己了解一下关于 fdisk 命令的使用。

警告:下面的步骤会格式化你的硬盘驱动。确保在进行下面步骤之前你的硬盘驱动中没有任何有用的信息。

  • n = 创建新分区
  • p = 创建主分区
  • 1 = 成为磁盘上的首个分区

输入 enter 键两次以接受默认的第一个和最后一个柱面。

用下面的命令准备 LVM 所使用的分区。

  • t = 更改分区类型
  • 8e = 更改为 LVM 分区类型

核实并将信息写入硬盘。

  • p = 查看分区设置使得在写入更改到磁盘之前可以回看
  • w = 写入更改到磁盘

运行这些命令之后,会退出 fdisk 提示符并返回到终端的 bash 提示符中。

输入 pvcreate /dev/sdb1 在刚创建的分区上新建一个 LVM 物理卷。

你也许会问为什么我们不用一个文件系统格式化分区,不用担心,该步骤在后面。

创建卷组

现在我们有了一个指定的分区和创建好的物理卷,我们需要创建一个卷组。很幸运这只需要一个命令。

vgcreate vgpool /dev/sdb1

vgpool 是新创建的卷组的名称。你可以使用任何你喜欢的名称,但建议标签以 vg 开头,以便后面你使用它时能意识到这是一个卷组。

创建逻辑卷

创建 LVM 将使用的逻辑卷:

lvcreate -L 3G -n lvstuff vgpool

-L 命令指定逻辑卷的大小,在该情况中是 3 GB,-n 命令指定卷的名称。 指定 vgpool 以便 lvcreate 命令知道从什么卷获取空间。

格式化并挂载逻辑卷

最后一步是用一个文件系统格式化新的逻辑卷。如果你需要选择一个 Linux 文件系统的帮助,请阅读 如果根据需要选取最合适的文件系统

mkfs -t ext3 /dev/vgpool/lvstuff

创建挂载点并将卷挂载到你可以使用的地方。

mkdir /mnt/stuff
mount -t ext3 /dev/vgpool/lvstuff /mnt/stuff

重新设置逻辑卷大小

逻辑卷的一个好处是你能使你的存储物理地变大或变小,而不需要移动所有东西到一个更大的硬盘。另外,你可以添加新的硬盘并同时扩展你的卷组。或者如果你有一个不使用的硬盘,你可以从卷组中移除它使得逻辑卷变小。

这里有三个用于使物理卷、卷组和逻辑卷变大或变小的基础工具。

注意:这些命令中的每个都要以 pv、vg 或 lv 开头,取决于你的工作对象。

  • resize – 能压缩或扩展物理卷和逻辑卷,但卷组不能
  • extend – 能使卷组和逻辑卷变大但不能变小
  • reduce – 能使卷组和逻辑卷变小但不能变大

让我们来看一个如何向刚创建的逻辑卷 "lvstuff" 添加新硬盘驱动的例子。

安装并格式化新硬盘驱动

按照上面创建新分区并更改分区类型为 LVM(8e) 的步骤安装一个新硬盘驱动。然后用 pvcreate 命令创建一个 LVM 能识别的物理卷。

添加新硬盘到卷组

要添加新的硬盘到一个卷组,你只需要知道你的新分区,在我们的例子中是 /dev/sdc1,以及想要添加到的卷组的名称。

这会添加新物理卷到已存在的卷组中。

vgextend vgpool /dev/sdc1

扩展逻辑卷

调整逻辑卷的大小,我们需要指出的是通过大小而不是设备来扩展。在我们的例子中,我们会添加一个 8GB 的硬盘驱动到我们的 3GB vgpool。我们可以用 lvextend 或 lvresize 命令使该空间可用。

lvextend -L8G /dev/vgpool/lvstuff

当这个命令工作的时候你会发现它实际上重新设置逻辑卷大小为 8GB 而不是我们期望的将 8GB 添加到已存在的卷上。要添加剩余的可用 3GB 你需要用下面的命令。

lvextend -L+3G /dev/vgpool/lvstuff

现在我们的逻辑卷已经是 11GB 大小了。

扩展文件系统

逻辑卷是 11GB 大小但是上面的文件系统仍然只有 3GB。要使文件系统使用整个的 11GB 可用空间你需要用 resize2fs 命令。你只需要指定 resize2fs 到 11GB 逻辑卷它就会帮你完成其余的工作。

resize2fs /dev/vgpool/lvstuff

注意:如果你使用除 ext3/4 之外的文件系统,请查看调整你的文件系统大小的工具。

压缩逻辑卷

如果你想从卷组中移除一个硬盘驱动你可以按照上面的步骤反向操作,并用 lvreduce 或 vgreduce 命令代替。

  1. 调整文件系统大小 (调整之前确保已经移动文件到硬盘驱动安全的地方)
  2. 减小逻辑卷 (除了 + 可以扩展大小,你也可以用 - 压缩大小)
  3. 用 vgreduce 从卷组中移除硬盘

备份逻辑卷

快照是一些新的高级文件系统提供的功能,但是 ext3/4 文件系统并没有快照的功能。LVM 快照最棒的是你的文件系统永不掉线,你可以拥有你想要的任何大小而不需要额外的硬盘空间。

LVM 获取快照的时候,会有一张和逻辑卷完全相同的“照片”,该“照片”可以用于在不同的硬盘上进行备份。生成一个备份的时候,任何需要添加到逻辑卷的新信息会如往常一样写入磁盘,但会跟踪更改使得原始快照永远不会损毁。

要创建一个快照,我们需要创建拥有足够空闲空间的逻辑卷,用于保存我们备份的时候会写入该逻辑卷的任何新信息。如果驱动并不是经常写入,你可以使用很小的一个存储空间。备份完成的时候我们只需要移除临时逻辑卷,原始逻辑卷会和往常一样。

创建新快照

创建 lvstuff 的快照,用带 -s 标记的 lvcreate 命令。

lvcreate -L512M -s -n lvstuffbackup /dev/vgpool/lvstuff

这里我们创建了一个只有 512MB 的逻辑卷,因为该硬盘实际上并不会使用。512MB 的空间会保存备份时产生的任何新数据。

挂载新快照

和之前一样,我们需要创建一个挂载点并挂载新快照,然后才能从中复制文件。

mkdir /mnt/lvstuffbackup
mount /dev/vgpool/lvstuffbackup /mnt/lvstuffbackup

复制快照和删除逻辑卷

你剩下需要做的是从 /mnt/lvstuffbackup/ 中复制所有文件到一个外部的硬盘或者打包所有文件到一个文件。

注意:tar -c 会创建一个归档文件,-f 要指出归档文件的名称和路径。要获取 tar 命令的帮助信息,可以在终端中输入 man tar。

tar -cf /home/rothgar/Backup/lvstuff-ss /mnt/lvstuffbackup/

记住备份时候写到 lvstuff 的所有文件都会在我们之前创建的临时逻辑卷中被跟踪。确保备份的时候你有足够的空闲空间。

备份完成后,卸载卷并移除临时快照。

umount /mnt/lvstuffbackup
lvremove /dev/vgpool/lvstuffbackup/

删除逻辑卷

要删除一个逻辑卷,你首先需要确保卷已经卸载,然后你可以用 lvremove 命令删除它。逻辑卷删除后你可以移除卷组,卷组删除后你可以删除物理卷。

这是所有移除我们创建的卷和组的命令。

umount /mnt/lvstuff
lvremove /dev/vgpool/lvstuff
vgremove vgpool
pvremove /dev/sdb1 /dev/sdc1

这些已经囊括了关于 LVM 你需要了解的大部分知识。如果你有任何关于这些讨论的经验,请在下面的评论框中和大家分享。


via: http://www.howtogeek.com/howto/40702/how-to-manage-and-use-lvm-logical-volume-management-in-ubuntu/

译者:ictlyh 校对:wxy

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

逻辑分区管理(LVM)是每一个主流Linux发行版都含有的磁盘管理选项。无论是你需要设置存储池,还是只想动态创建分区,那么LVM就是你正在寻找的。

什么是 LVM?

逻辑分区管理是一个存在于磁盘/分区和操作系统之间的一个抽象层。在传统的磁盘管理中,你的操作系统寻找有哪些磁盘可用(/dev/sda、/dev/sdb等等),并且这些磁盘有哪些可用的分区(如/dev/sda1、/dev/sda2等等)。

在LVM下,磁盘和分区可以抽象成一个含有多个磁盘和分区的设备。你的操作系统将不会知道这些区别,因为LVM只会给操作系统展示你设置的卷组(磁盘)和逻辑卷(分区)

因为卷组和逻辑卷并不物理地对应到影片,因此可以很容易地动态调整和创建新的磁盘和分区。除此之外,LVM带来了你的文件系统所不具备的功能。比如,ext3不支持实时快照,但是如果你正在使用LVM你可以不卸载磁盘的情况下做一个逻辑卷的快照。

你什么时候该使用LVM?

在使用LVM之前首先得考虑的一件事是你要用你的磁盘和分区来做什么。注意,一些发行版如Fedora已经默认安装了LVM。

如果你使用的是一台只有一块磁盘的Ubuntu笔记本电脑,并且你不需要像实时快照这样的扩展功能,那么你或许不需要LVM。如果你想要轻松地扩展或者想要将多块磁盘组成一个存储池,那么LVM或许正是你所寻找的。

在Ubuntu中设置LVM

使用LVM首先要了解的一件事是,没有一个简单的方法可以将已有的传统分区转换成逻辑卷。可以将数据移到一个使用LVM的新分区下,但是这并不会在本篇中提到;在这里,我们将全新安装一台Ubuntu 10.10来设置LVM。(LCTT 译注:本文针对的是较老的版本,新的版本已经不需如此麻烦了)

要使用LVM安装Ubuntu你需要使用另外的安装CD。从下面的链接中下载并烧录到CD中或者使用unetbootin创建一个USB盘

从安装盘启动你的电脑,并在磁盘选择界面选择整个磁盘并设置LVM。

注意:这会格式化你的整个磁盘,因此如果正在尝试双启动或者其他的安装选择,选择手动。

选择你想用的主磁盘,最典型的是使用你最大的磁盘,接着进入下一步。

你马上会将改变写入磁盘所以确保此时你选择的是正确的磁盘接着才写入设置。

选择第一个逻辑卷的大小并继续。

确认你的磁盘分区并继续安装。

最后一步将GRUB的bootloader写到磁盘中。重点注意的是GRUB不能作为一个LVM分区因为计算机BIOS不能直接从逻辑卷中读取数据。Ubuntu将自动创建一个255MB的ext2分区用于bootloder。

安装完成之后。重启电脑并如往常一样进入Ubuntu。使用这种方式安装之后应该就感受不到LVM和传统磁盘管理之间的区别了。

要使用LVM的全部功能,静待我们的下篇关于管理LVM的文章。


via: http://www.howtogeek.com/howto/36568/what-is-logical-volume-management-and-how-do-you-enable-it-in-ubuntu/

作者:How-To Geek 译者:geekpi 校对:wxy

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