Skip to content Skip to main navigation Skip to footer

Linux

Linux:使用Docker做开发的建议团队工作流

Linux:使用Docker做开发的建议团队工作流
Linux:使用Docker做开发的建议团队工作流

意义

自从Docker进入到我们的工作流程之后给环境配置框架搭建,持续集成,持续交付方面带来了很多好处,首先相对于虚拟机来说,最直接的好处是带来了更小的镜像,同时程序以容器的方式运行不但启动速度快而且性能也好过虚拟机,同时它的配置可以非常快速的调整。其次对于开发来说,我们整个团队都使用的是Sublime+git的方式进行开发,使用Docker之后无论是什么平台只要有Shell都可以很方便的统一测试&开发环境。

Docker特性的使用

  1. 磁盘挂载(-v)一直以来我们在使用Docker过程中都遵循着一个道理Docker只是一个环境他只是运行程序的一种手段。我们不能在docker中持久化数据,无论是文件还是数据库都是不允许的,因为很有可能测试结束之后会丢失数据。用于开发的Docker Image我们需要针对数据持久化新开方便调试使用的数据库,我们需要挂载针对应用的数据库持久化文件夹,当然我们还需要针对脚本进行目录挂载,如果是golang的话运行之前可能要自动化构建golang程序。
  2. 端口映射虽然docker给我们提供了link的方法来实现容器之间的链接,但是我们依赖还是使用了最传统的端口映射的方式来进行服务的对外发布。因为我们觉得关系越简单,整个平台的服务就越稳定,虽然链接的这种方式并没有什么不好之处。

工作流程

定制容器准备开发&&运行环境

从Dockerfile开始部署环境,有两个方向上的选择,一种是自己定制操作系统,另外一种是依赖其他人做好的。

先说第一种方法:在我之前的blog中已经有提到,可以大概参考一下。

这种方法缺点主要在于,需要非常了解Linux或者至少做过LFS才能方便自己定制操作系统,要对业务底层依赖有一定了解。因为此方法需要精简image所以需要手动解决依赖问题。对于依赖比较多的情况不适用。

第二种方法,在之前的blog中也有提到过,有详细的过程以及Dockerfile参考。

这种方法构建的image大概100MB+虽然比虚拟机(按G来算)小了很多,但是在迁移分发Image的时候还是要注意(如果你没有自己的Docker Hub)。如果使用文件迁移请用save的方式来分发image,在上面链接的blog中有提到备份迁移的问题。

另外一个注意的地方,如果是用别人的image要注意安全,会不会里面挂了后门之类的,然后要摸清系统配置,准备好代码或可执行二进制文件的挂载位置,数据库持久化文件存放的位置等等都要摸清。最后在运行的时候都要给出挂载方案。

发布之后要做的事

因为Docker只是一个容器而不是项目中的一部分,所以只是项目实现的一种手段,具体应该如何使用它,需要一定的文档支撑,也就是开发业务流程文档。

文档中要详细的提出所有依赖的Service配置文件的位置,配置的状态,持久化目录位置,输出的端口,开发完成之后业务部署的位置这些关于项目的尽量能想到的信息,因为这套容器会跟着项目整个周期中作为基础设施的一部分在运行。

除了配置方面,第二部分是建议的使用方法流程,比如:要说清楚代码是在容器内部编译还是在其他容器中有做好的辅助工具编译,还是有一个独立的服务器(项目比较大的时候需要一个独立的构建服务器,甚至需要一个专门管理构建&&版本的同事),如果是脚本语言写的就不需要这么麻烦了。

项目发布

项目进行到一个阶段之后需要发布,把代码或可执行二进制文件直接构建到image里面就行了。注意先要判断项目是否要使用Docker。

好处总结

在文件持久化方面我们挂载的目录实现了统一,配置文件也实现了统一。

在PHP开发中再也不用担心目录大小写敏感,文件大小写敏感,目录长度限制等因为操作系统不统一的问题。

由于不同项目有不同的限制因素,因此在这里介绍总体的工作流程,项目中涉及到不同的应用服务只需要比较小的调整。

来源:http://www.philo.top/2015/06/04/DockerWorkflow/

Linux:创建尽可能小的 Docker 容器

当我们在使用 Docker 的时候,你会很快注意到你正在下载很多 MB 作为你的预先配置的容器。一个简单的 Ubuntu 容器很容易超过 200 MB,并且随着在上面安装软件,尺寸在逐渐增大。在某些情况下,你不需要任何事情都使用 Ubuntu 。例如,如果你只是简单的想运行一个 web 服务,使用 GO 编写的,没有必要围绕它使用任何工具。

Linux:创建尽可能小的 Docker 容器
Linux:创建尽可能小的 Docker 容器

我一直在寻找尽可能小的容器入手,并且发现了一个:

docker pull scratch

scratch 镜像是完美的,真正的完美!它简洁,小巧以及快速。它不包含任何 bug,安全泄漏,慢的代码或是技术债务。这是因为它是一个空的镜像。除了一点由 Docker 加入的元数据。事实上,你可以使用如下命令按照 Docker 文档描述的那样创建一个自己的 scratch 镜像。

tar cv --files-from /dev/null | docker import - scratch

所以这可能就是最小的 Docker 镜像。

或者我们可以说说关于这个的更多东西?比如,你怎样使用 scratch 镜像。这给自己带来了一些挑战。

为 scratch 镜像创建内容

我们可以在一个空镜像中运行什么?一个没有依赖的可执行程序。你是否有没有依赖的可执行程序?

我过去常常使用 Python,Java 和 Javascript 编写代码。每一个这样的语言/平台都需要一个运行时的安装。最近,我开始涉及 Go(或是 golang 如果你喜欢)平台。看起来 Go 是静态连接的。因此我尝试编译一个简单的 web 服务输出 Hello World 并且运行在 scratch 容器中。下面是这个 Hello World web 服务的代码:

package main
import (
    "fmt"
    "net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello World from Go in minimal Docker container")
}
func main() {
    http.HandleFunc("/", helloHandler)
    fmt.Println("Started, serving at 8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic("ListenAndServe: " + err.Error())
    }
}

明显地,我不能在 scratch 容器中编译我的 web 服务,因为容器中没有 Go 编译器。正如我在 Mac 上工作,我也无法编译 Linux 的二进制文件一样(实际上,是可以在不同的平台上交叉编译 Go 的源码的,但这会在另外一篇博客中介绍)。

因此,我首先需要一个有 Go 编译器的 Docker 容器。让我们开始:

docker run -ti google/golang /bin/bash

在这个容器里面,我可以构建一个 Web 服务,通过我已经提交到一个 GitHub 仓库的代码。

go get github.com/adriaandejonge/helloworld

go get 命令是 go build 命令的变种,运行获取和构建远程的依赖。你可以运行可执行的结果:

$GOPATH/bin/helloworld

它工作了,但是这不是我们想要的。我们需要 hello world 容器运行在 scratch 容器里面。因此,实际上,我们需要一个 Dockerfile :

FROM scratch
ADD bin/helloworld /helloworld
CMD ["/helloworld"]

然后启动它,不幸的是,我们开始 google/golang 容器的这个方法, 没有办法构建这个 Dockerfile 。因此,首先,我们需要一种方法从这个容器内部访问到 Docker。

从 Docker 内部调用 Docker

当你使用 Dokcer 时,你迟早会遇到需要从 Docker 内部访问 Docker。可以有多种方法实现它。你可以使用递归和在 Docker 中运行 Docker。尽管如此,这样看起来会很复杂并且导致容器很大。你还可以使用一些额外的命令选项在实例外访问 Docker 服务器:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):$(which docker) -ti google/golang /bin/bash

在你继续前,你重新运行 Go 编译器,由于在重启动过程中 Docker 忘记了我们以前编译过。

go get github.com/adriaandejonge/helloworld

当我们启动这个容器, -v 参数在 Docker 容器中创建一个卷并且允许你从 Docker 的机器提供一个文件作为输入。/var/run/docker.sock 是 UNIX socket,通过这个允许你访问 Docker 服务。 (which docker) 部分是一个非常聪明的方法,它提供了一个在 容器中的 Docker 可执行文件的路径,而不是硬编码。尽管如此,当你在 Mac 上通过 boot2docker 使用这个命令的时候需要小心。如果 Docker 的可执行文件与 boot2docker 虚拟机的在不同的位置,将导致不匹配。因此,你或许想使用 /usr/local/bin/docker 硬编码的方式替换 $(which docker),如果你运行在不同的系统,/var/run/docker.sock 有在不同位置的机会,你需要做相应的调整。

现在你可以在 google/golang 容器的 $GOPATH 目录使用 Dockerfile ,在这个示例中指向 /gopath。实际上,我已经在 github 上检查过了这个 Dockerfile,因此,你可以从 Go build 目录复制它到所需的位置,像这样:

cp $GOPATH/src/github.com/adriaandejonge/helloworld/Dockerfile $GOPATH

你需要复制这个作为二进制的编译文件,现在位于 $GOPATH/bin,并且它不可能从父目录包含文件当构建一个 Dockerfile 的时候。因此复制后,下一步是:

docker build -t adejonge/helloworld $GOPATH

所有的都完成以后, Docker 给出如下响应:

Successfully built 6ff3fd5a381d

允许你运行这个容器:

docker run -ti --name hellobroken adejonge/helloworld

但是不幸的是, Docker 这次响应如下:

2014/07/02 17:06:48 no such file or directory

那么到底是怎么回事?我们在 scratch 容器中有可执行的静态链接。难道我们犯了一个错误?

事实证明,Go 不是静态链接库。或者至少不是所有的库。在 Linux 下,我们可以使用 ldd 命令来看到动态链接库:

ldd $GOPATH/bin/helloworld 

得到如下响应:

linux-vdso.so.1 => (0x00007fff039fe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f61df30f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f61def84000)
/lib64/ld-linux-x86-64.so.2 (0x00007f61df530000)

因此,在我们运行我们的 web 服务之前,我需要告诉 go 编译器实际的静态链接。

创建在 Go 中的可执行静态链接

为了创建可执行的静态链接,我们需要告诉 Go 使用 cgo 编译器而不是 go 编译器。命令如下:

CGO_ENABLED=0 go get -a -ldflags '-s' github.com/adriaandejonge/helloworld

CGO_ENABLED 环境变量告诉 Go 使用 cgo 编译器而不是 go 编译器。-a 参数告诉 GO 重薪构建所有的依赖。否则的话你将以动态链接依赖结束。最后的 -ldflags '-s' 参数是一个非常好的扩展。它大概降低了可执行文件 50% 的文件大小。你也可以不通过 cgo 使用这个。尺寸缩小是去除了调试信息的结果。

为了确定,运行 ldd 命令:

ldd $GOPATH/bin/helloworld 

返回是:

not a dynamic executable

你也可以重新运行步骤,围绕着从 scratch 创建 Docker 容器的可执行文件。

docker build -t adejonge/helloworld $GOPATH

如果一切顺利,Docker 将响应如下:

Successfully built 6ff3fd5a381d

允许你运行这个容器:

docker run -ti --name helloworld adejonge/helloworld

响应如下:

Started, serving at 8080

到目前为止,有许多手动的步骤和很多错误的地方。让我们退出 google/golang 容器并且从周边服务器继续:


exit

你可以检查 Docker 容器和镜像存在不存在:

docker ps -a
docker images -a

你可以使用如下命令清理:

docker rm -f helloworld
docker rmi -f adejonge/helloworld

创建一个 Docker 容器来创建一个 Docker 容器

目前为止,我们花了那么多步骤,我们还可以记录在 Dockerfile 中并且 Docker 会为我们做这些工作:

FROM google/golang
RUN CGO_ENABLED=0 go get -a -ldflags '-s' github.com/adriaandejonge/helloworld
RUN cp /gopath/src/github.com/adriaandejonge/helloworld/Dockerfile /gopath
CMD docker build -t adejonge/helloworld gopath

我在 一个单独的称为 adriaandejonge/hellobuild 的 GitHub 仓库检查了 Dockerfile。它可以使用下面的命令构建:

docker build -t adejonge/hellobuild github.com/adriaandejonge/hellobuild

提供 -t 参数命名 adejonge/hellobuild 镜像并且它的最新的隐式的标签。这些名字让你以后更容易去除镜像。下一步,你可以使用就像我们在这篇文章前面看到的那样提供一个参数从这个镜像中创建一个容器:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):$(which docker) -ti --name hellobuild adejonge/hellobuild

提供 --name hellobuild 参数使得在运行后更容易移除容器。事实上,你可以这样做,因为运行这个命令后,你已经创建了一个 adejonge/helloworld 镜像:

docker rm -f hellobuild
docker rmi -f adejonge/hellobuild

现在你可以创建一个基于 adejonge/helloworld 镜像的名为 helloworld 的新容器,就像你以前做的那样:

docker run -ti --name helloworld adejonge/helloworld

因为所有的这些步骤都是从相同的命令中运行,不需要在 Docker 中打开一个 bash shell 。你可以把这些步骤添加进一个 bash 脚本,自动运行它,为了使你方便,我已经把这些脚本加入了 hellobuild GitHub 仓库

另外,如果你想尝试一个尽可能小的容器,但是又不想遵循博客中的步骤,你可以使用我检入进 Docker Hub repository 的预先构建好的镜像。

docker pull adejonge/helloworld

使用 docker images -a ,你可以看到大小是 3.6MB。当然,如果你成功创建一个比我使用 Go 编写的 web 服务还小的可执行文件,你可以使得它更小。使用 C 语言或者是汇编,你可以这样做到。尽管如此,你不可能使得它比 scratch 镜像还小

扩展阅读

来源:http://segmentfault.com/a/1190000000628247

Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN

问题:我需要连接到一个IPSec VPN网关,鉴于此,我尝试使用Shrew Soft VPN客户端,它是一个免费版本。我怎样才能安装Shrew Soft VPN客户端到[某个Linux发行版]?

市面上有许多商业VPN网关,同时附带有他们自己的专有VPN客户端软件。虽然也有许多开源的VPN服务器/客户端备选方案,但它们通常缺乏复杂的IPsec支持,比如互联网密钥交换(IKE),这是一个标准的IPsec协议,用于加固VPN密钥交换和验证安全。Shrew Soft VPN是一个免费的IPsec VPN客户端,它支持多种验证方法、密钥交换、加密以及防火墙穿透选项。

Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN
Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN

下面介绍如何安装Shrew Soft VPN客户端到Linux平台。

首先,从官方站点下载它的源代码。

安装Shrew VPN客户端到Debian, Ubuntu或者Linux Mint

Shrew Soft VPN客户端图形界面要求使用Qt 4.x。所以,作为依赖,你需要安装其开发文件。

$ sudo apt-get install cmake libqt4-core libqt4-dev libqt4-gui libedit-dev libssl-dev checkinstall flex bison
$ wget https://www.shrew.net/download/ike/ike-2.2.1-release.tbz2
$ tar xvfvj ike-2.2.1-release.tbz2
$ cd ike
$ cmake -DCMAKE_INSTALL_PREFIX=/usr -DQTGUI=YES -DETCDIR=/etc -DNATT=YES .
$ make
$ sudo make install
$ cd /etc/
$ sudo mv iked.conf.sample iked.conf

安装Shrew VPN客户端到CentOS, Fedora或者RHEL

与基于Debian的系统类似,在编译前你需要安装一堆依赖包,包括Qt4。

$ sudo yum install qt-devel cmake gcc-c++ openssl-devel libedit-devel flex bison
$ wget https://www.shrew.net/download/ike/ike-2.2.1-release.tbz2
$ tar xvfvj ike-2.2.1-release.tbz2
$ cd ike
$ cmake -DCMAKE_INSTALL_PREFIX=/usr -DQTGUI=YES -DETCDIR=/etc -DNATT=YES .
$ make
$ sudo make install
$ cd /etc/
$ sudo mv iked.conf.sample iked.conf

在基于Red Hat的系统中,最后一步需要用文本编辑器打开/etc/ld.so.conf文件,并添加以下行。

$ sudo vi /etc/ld.so.conf

include /usr/lib/

重新加载运行时绑定的共享库文件,以容纳新安装的共享库:

$ sudo ldconfig

启动Shrew VPN客户端

首先,启动IKE守护进程(iked)。该守护进作为VPN客户端程通过IKE协议与远程主机经由IPSec通信。

$ sudo iked

现在,启动qikea,它是一个IPsec VPN客户端前端。该GUI应用允许你管理远程站点配置并初始化VPN连接。

Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN
Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN

要创建一个新的VPN配置,点击“添加”按钮,然后填入VPN站点配置。创建配置后,你可以通过点击配置来初始化VPN连接。

Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN
Linux:Linux有问必答:Linux上如何安装Shrew Soft IPsec VPN

故障排除

  1. 我在运行iked时碰到了如下错误。

    iked: error while loading shared libraries: libss_ike.so.2.2.1: cannot open shared object file: No such file or directory

要解决该问题,你需要更新动态链接器来容纳libss_ike库。对于此,请添加库文件的位置路径到/etc/ld.so.conf文件中,然后运行ldconfig命令。

$ sudo ldconfig

验证libss_ike是否添加到了库路径:

$ ldconfig -p | grep ike

libss_ike.so.2.2.1 (libc6,x86-64) => /lib/libss_ike.so.2.2.1
libss_ike.so (libc6,x86-64) => /lib/libss_ike.so

via: http://ask.xmodulo.com/install-shrew-soft-ipsec-vpn-client-linux.html

作者:Dan Nanni 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5600-1.html

Linux:Linux有问必答:如何更新过期版本的Ubuntu

问题: 我的PC上安装了旧版的Ubuntu 13.04(急切的浣熊)。当我在上面运行“sudo apt-get update”时,它丢给了我一大堆“404 Not Found”错误,结果是我不能使用apt-get或aptitude来安装或更新任何软件包了。由于该错误的原因,我甚至不能将它升级到更新的版本。我怎样才能修复这个问题啊?

每个Ubuntu版本都有生命结束周期(EOL)时间;常规的Ubuntu发行版提供18个月的支持,而LTS(长期支持)版本则长达3年(服务器版本)和5年(桌面版本)。当某个Ubuntu版本达到生命结束周期时,其仓库就不能再访问了,你也不能再从Canonical获取任何维护更新和安全补丁。在撰写本文时,Ubuntu 13.04(急切的浣熊)已经达到了它的生命结束周期。

如果你所使用的Ubuntu系统已经被结束生命周期,你就会从apt-get或aptitude得到以下404错误,因为它的仓库已经被遗弃了。

W: Failed to fetch http://us.archive.ubuntu.com/ubuntu/dists/raring-backports/multiverse/binary-i386/Packages  404  Not Found [IP: 91.189.91.13 80]
W: Failed to fetch http://extras.ubuntu.com/ubuntu/dists/raring/main/binary-amd64/Packages  404  Not Found
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/raring-security/universe/binary-i386/Packages  404  Not Found [IP: 91.189.88.149 80]
E: Some index files failed to download. They have been ignored, or old ones used instead

对于那些还在使用旧版本Ubuntu的用户,Canonical维护了一个old-releases.ubuntu.com的网站,这里包含了结束生命周期的仓库归档。因此,当Canonical对你安装的Ubuntu版本结束支持时,你需要将仓库切换到old-releases.ubuntu.com(除非你在结束生命周期之前想要升级)。

这里,通过切换到旧版本仓库提供了一个快速修复“404 Not Found”错误的便捷方式。

首先,使用old-releases仓库替换main/security仓库,就像下面这样。

$ sudo sed -i -r 's/([a-z]{2}\.)?archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
$ sudo sed -i -r 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list

然后,使用文本编辑器打开/etc/apt/sources.list,并查找extras.ubuntu.com。该仓库也不再支持Ubuntu 13.04了,所以你需要使用“#”号将extras.ubuntu.com注释掉。

#deb http://extras.ubuntu.com/ubuntu raring main
#deb-src http://extras.ubuntu.com/ubuntu raring main

现在,你应该可以在旧版不受支持的Ubuntu上安装或更新软件包了。


via: http://ask.xmodulo.com/404-not-found-error-apt-get-update-ubuntu.html

作者:Dan Nanni 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5601-1.html

Linux:基础的 Docker 容器网络命令

各位好,今天我们将学习一些Docker容器的基础命令。Docker 是一个开源项目,提供了一个可以打包、装载和运行任何应用的轻量级容器的开放平台。它没有语言支持、框架和打包系统的限制,从小型的家用电脑到高端服务器,在何时何地都可以运行。它可以使部署和扩展web应用程序、数据库和后端服务像搭积木一样容易,而不依赖特定技术栈或提供商。Docker适用于网络环境,它正应用于数据中心、ISP和越来越多的网络服务。

因此,这里有一些你在管理Docker容器的时候会用到的一些命令。

Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

1. 找到Docker接口

Docker默认会创建一个名为docker0的网桥接口作为连接外部世界的基础。运行中的docker容器直接连接到网桥接口docker0。默认上,docker会分配172.17.42.1/16给docker0,它是所有运行中的容器ip地址的子网。找到Docker接口的ip地址非常简单。要找出docker0网桥接口和连接到网桥上的docker容器,我们可以在安装了docker的终端或者shell中运行ip命令。

# ip a
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

2. 得到Docker容器的ip地址

如我们上面读到的,docker在宿主机中创建了一个叫docker0的网桥接口。在我们创建一个新的docker容器时,它自动被默认分配了一个在该子网范围内的ip地址。因此,要检测运行中的Docker容器的ip地址,我们需要进入一个正在运行的容器并用下面的命令检查ip地址。首先,我们运行一个新的容器并进入其中。如果你已经有一个正在运行的容器,你可以跳过这个步骤。

# docker run -it ubuntu

现在,我们可以运行ip a来得到容器的ip地址了。

# ip a
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

3. 映射暴露的端口

要映射配置在Dockerfile的暴露端口到宿主机的高位端口,我们只需用下面带上-P标志的命令。这会打开docker容器的随机端口并映射到Dockerfile中定义的端口。下面是使用-P来打开/暴露定义的端口的例子。

# docker run -itd -P httpd
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

上面的命令会映射容器的端口到 httpd 容器的 Dockerfile 中定义的80端口上。我们用下面的命令来查看正在运行的容器暴露的端口。

# docker ps

并且可以用下面的curl命令来检查。

# curl http://localhost:49153

Curl Exposed Port

4. 映射到特定的端口上

我们也可以映射暴露端口或者docker容器端口到我们指定的端口上。要实现这个,我们用-p标志来定义我们所需的端口。这里是我们的一个例子。

# docker run -itd -p 8080:80 httpd

上面的命令会映射(宿主机的)8080端口到(容器的)80上。我们可以运行curl来检查这点。

# curl http://localhost:8080

Mapping Specific Port

5. 创建自己的网桥

要给容器创建一个自定义的IP地址,在本篇中我们会创建一个名为br0的新网桥。要分配需要的ip地址,我们需要在运行docker的宿主机中运行下面的命令。

# stop docker.io
# ip link add br0 type bridge
# ip addr add 172.30.1.1/20 dev br0
# ip link set br0 up
# docker -d -b br0
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

创建完docker网桥之后,我们要让docker的守护进程知道它。

# echo 'DOCKER_OPTS="-b=br0"' >> /etc/default/docker
# service docker.io start

Adding Interface to Docker

到这里,桥接后的接口将会分配给容器在桥接子网内的新ip地址。

6. 链接到另外一个容器上

我们可以用Docker将一个容器连接到另外一个上。我们可以在不同的容器上运行不同的程序,并且相互连接或链接。链接允许容器间相互连接并从一个容器上安全地传输信息给另一个容器。要做到这个,我们可以使用–link标志。首先,我们使用–name标志来标示training/postgres镜像。

# docker run -d --name db training/postgres
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

完成之后,我们将容器db与training/webapp链接来形成新的叫web的容器。

# docker run -d -P --name web --link db:db training/webapp python app.py
Linux:基础的 Docker 容器网络命令
Linux:基础的 Docker 容器网络命令

总结

Docker网络很神奇也好玩,我们可以对docker容器做很多事情。我们可以把玩这些简单而基础的docker网络命令。docker的网络是非常先进的,我们可以用它做很多事情。

如果你有任何的问题、建议、反馈请在下面的评论栏写下来以便于我们我们可以提升或者更新文章的内容。谢谢! 玩得开心!:-)


via: http://linoxide.com/linux-how-to/networking-commands-docker-containers/

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

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

来源:https://linux.cn/article-5602-1.html

Linux:Ubuntu 更新错误修复大全

Linux:Ubuntu 更新错误修复大全
Linux:Ubuntu 更新错误修复大全

在Ubuntu更新中,谁没有碰见个错误?在Ubuntu和其它基于Ubuntu的Linux发行版中,更新错误是一个共性的错误,也经常发生。这些错误出现的原因多种多样,修复起来也很简单。在本文中,我们将见到Ubuntu中各种类型频繁发生的更新错误以及它们的修复方法。

合并列表问题

当你在终端中运行更新命令时,你可能会碰到这个错误“合并列表错误”,就像下面这样:

E:Encountered a section with no Package: header,

E:Problem with MergeList /var/lib/apt/lists/archive.ubuntu.comubuntudistspreciseuniversebinary-i386Packages,

E:The package lists or status file could not be parsed or opened.’

可以使用以下命令来修复该错误:

sudo rm -r /var/lib/apt/lists/*
sudo apt-get clean && sudo apt-get update

下载仓库信息失败 -1

实际上,有两种类型的下载仓库信息失败错误。如果你的错误是这样的:

W:Failed to fetch bzip2:/var/lib/apt/lists/partial/in.archive.ubuntu.comubuntudistsoneiricrestrictedbinary-i386Packages Hash Sum mismatch,

W:Failed to fetch bzip2:/var/lib/apt/lists/partial/in.archive.ubuntu.comubuntudistsoneiricmultiversebinary-i386Packages Hash Sum mismatch,

E:Some index files failed to download. They have been ignored, or old ones used instead

那么,你可以用以下命令修复:

sudo rm -rf /var/lib/apt/lists/*
sudo apt-get update

下载仓库信息失败 -2

下载仓库信息失败的另外一种类型是由于PPA过时导致的。通常,当你运行更新管理器,并看到这样的错误时:

你可以运行sudo apt-get update来查看哪个PPA更新失败,你可以把它从源列表中删除。你可以按照这个截图指南来修复下载仓库信息失败错误

下载包文件失败错误

一个类似的错误是下载包文件失败错误,像这样:

Linux:Ubuntu 更新错误修复大全
Linux:Ubuntu 更新错误修复大全

该错误很容易修复,只需修改软件源为主服务器即可。转到“软件和更新”,在那里你可以修改下载服务器为主服务器:

Linux:Ubuntu 更新错误修复大全
Linux:Ubuntu 更新错误修复大全

部分更新错误

在终端中运行更新会出现部分更新错误

Not all updates can be installed

Run a partial upgrade, to install as many updates as possible

在终端中运行以下命令来修复该错误:

sudo apt-get install -f

加载共享库时发生错误

该错误更多是安装错误,而不是更新错误。如果尝试从源码安装程序,你可能会碰到这个错误:

error while loading shared libraries:

cannot open shared object file: No such file or directory

该错误可以通过在终端中运行以下命令来修复:

sudo /sbin/ldconfig -v

你可以在这里查找到更多详细内容加载共享库时发生错误

无法获取锁 /var/cache/apt/archives/lock

在另一个程序在使用APT时,会发生该错误。假定你正在Ubuntu软件中心安装某个东西,然后你又试着在终端中运行apt。

E: Could not get lock /var/cache/apt/archives/lock – open (11: Resource temporarily unavailable)

E: Unable to lock directory /var/cache/apt/archives/

通常,只要你把所有其它使用apt的程序关了,这个问题就会好的。但是,如果问题持续,可以使用以下命令:

sudo rm /var/lib/apt/lists/lock

如果上面的命令不起作用,可以试试这个命令:

sudo killall apt-get

关于该错误的更多信息,可以在这里找到。

GPG错误: 下列签名无法验证

在添加一个PPA时,可能会导致以下错误GPG错误: 下列签名无法验证,这通常发生在终端中运行更新时:

W: GPG error: http://repo.mate-desktop.org saucy InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 68980A0EA10B4DE8

我们所要做的,就是获取系统中的这个公钥,从信息中获取密钥号。在上述信息中,密钥号为68980A0EA10B4DE8。该密钥可通过以下方式使用:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 68980A0EA10B4DE8

在添加密钥后,再次运行更新就没有问题了。

BADSIG错误

另外一个与签名相关的Ubuntu更新错误是BADSIG错误,它看起来像这样:

W: A error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://extras.ubuntu.com precise Release: The following signatures were invalid: BADSIG 16126D3A3E5C1192 Ubuntu Extras Archive Automatic Signing Key

W: GPG error: http://ppa.launchpad.net precise Release:

The following signatures were invalid: BADSIG 4C1CBC1B69B0E2F4 Launchpad PPA for Jonathan French W: Failed to fetch http://extras.ubuntu.com/ubuntu/dists/precise/Release

要修复该BADSIG错误,请在终端中使用以下命令:

sudo apt-get clean
cd /var/lib/apt
sudo mv lists oldlist
sudo mkdir -p lists/partial
sudo apt-get clean
sudo apt-get update

本文汇集了你可能会碰到的Ubuntu更新错误,我希望这会对你处理这些错误有所帮助。你在Ubuntu中是否也碰到过其它更新错误呢?请在下面的评论中告诉我,我会试着写个快速指南。


via: http://itsfoss.com/fix-update-errors-ubuntu-1404/

作者:Abhishek 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5603-1.html

Linux:一个Linux中用于监控的简易shell脚本

系统管理员的任务真的很艰难,因为他/她必须监控服务器、用户、日志,还得创建备份,等等等等。对于大多数重复性的任务,大多数管理员都会写一个自动化脚本来日复一日地重复这些任务。这里,我们已经写了一个shell脚本给大家,用来自动化完成系统管理员所要完成的常规任务,这可能在多数情况下,尤其是对于新手而言十分有用,他们能通过该脚本获取到大多数的他们想要的信息,包括系统、网络、用户、负载、内存、主机、内部IP、外部IP、开机时间等。

我们已经注意并进行了格式化输出(在一定程度上哦)。此脚本不包含任何恶意内容,并且它能以普通用户帐号运行。事实上,我们也推荐你以普通用户运行该脚本,而不是root。

Linux:一个Linux中用于监控的简易shell脚本
Linux:一个Linux中用于监控的简易shell脚本

监控Linux系统健康的Shell脚本

在保留Tecmint和脚本作者应得荣誉的前提下,可以自由使用/修改/再分发下面代码。我们已经试着在一定程度上自定义了输出结果,除了要求的输出内容外,其它内容都不会生成。我们也已经试着使用了那些Linux系统中通常不使用的变量,这些变量应该是可以随便用的。

最小系统要求

你所需要的一切,就是一台正常运转的Linux机器。

依赖性

对于一个标准的Linux发行版,使用此软件包不需任何依赖。此外,该脚本不需要root权限来执行。但是,如果你想要安装,则必须输入一次root密码。

安全性

我们也关注到了系统安全问题,所以在安装此包时,不需要安装任何额外包,也不需要root访问权限来运行。此外,源代码是采用Apache 2.0许可证发布的,这意味着只要你保留Tecmint的版权,你可以自由地编辑、修改并再分发该代码。

如何安装和运行脚本?

首先,使用wget命令下载监控脚本“tecmint_monitor.sh”,给它赋予合适的执行权限。

# wget http://tecmint.com/wp-content/scripts/tecmint_monitor.sh
# chmod 755 tecmint_monitor.sh

强烈建议你以普通用户身份安装该脚本,而不是root。安装过程中会询问root密码,并且在需要的时候安装必要的组件。

要安装“tecmint_monitor.sh”脚本,只需像下面这样使用-i(安装)选项就可以了。

./tecmint_monitor.sh -i

在提示你输入root密码时输入该密码。如果一切顺利,你会看到像下面这样的安装成功信息。

Password:
Congratulations! Script Installed, now run monitor Command

安装完毕后,你可以在任何位置,以任何用户调用命令‘monitor’来运行该脚本。如果你不喜欢安装,你需要在每次运行时输入路径。

# ./Path/to/script/tecmint_monitor.sh

现在,以任何用户从任何地方运行monitor命令,就是这么简单:

$ monitor
Linux:一个Linux中用于监控的简易shell脚本
Linux:一个Linux中用于监控的简易shell脚本

你运行命令就会获得下面这些各种各样和系统相关的信息:

  • 互联网连通性
  • 操作系统类型
  • 操作系统名称
  • 操作系统版本
  • 架构
  • 内核版本
  • 主机名
  • 内部IP
  • 外部IP
  • 域名服务器
  • 已登录用户
  • 内存使用率
  • 交换分区使用率
  • 磁盘使用率
  • 平均负载
  • 系统开机时间

使用-v(版本)开关来检查安装的脚本的版本。

$ monitor -v
tecmint_monitor version 0.1
Designed by Tecmint.com
Released Under Apache 2.0 License

小结

该脚本在一些机器上可以开机即用,这一点我已经检查过。相信对于你而言,它也会正常工作。如果你们发现了什么毛病,可以在评论中告诉我。这个脚本还不完善,这仅仅是个开始。从这里开始,你可以将它改进到任何程度。如果你想要编辑脚本,将它带入一个更深的层次,尽管随意去做吧,别忘了给我们应的的荣誉,也别忘了把你更新后的脚本拿出来和我们分享哦,这样,我们也会更新此文来给你应得的荣誉。

别忘了和我们分享你的想法或者脚本,我们会在这儿帮助你。谢谢你们给予的所有挚爱。继续浏览,不要走开哦。


via: http://www.tecmint.com/linux-server-health-monitoring-script/

作者:Avishek Kumar 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5604-1.html

Linux:如何使用xkill命令杀掉Linux进程/未响应的程序

我们如何在Linux中杀掉一个资源/进程?很明显我们会找出资源的pid然后用kill命令。

说的更明白一点,我们可以找到某个资源(比如terminal)的PID:

$ ps -A | grep -i terminal
6228 ?        00:00:00 gnome-terminal

上面的输出中,‘6288’就是进程(gnome-terminal)的pid, 使用下面的命令来杀掉进程。

$ kill 6228

kill命令会发送一个信号给该pid的进程。

另外一个方法是我们可以使用pkill命令,它可以基于进程的名字或者其他的属性来杀掉进程。同样我们要杀掉一个叫terminal的进程可以这么做:

$ pkill terminal

注意: pkill命令后面进程名的长度不大于15个字符

pkill看上去更加容易上手,因为你你不用找出进程的pid。但是如果你要对系统做更好的控制,那么没有什么可以打败’kill’。使用kill命令可以更好地审视你要杀掉的进程。

我们已经有一篇覆盖了kill、pkill和killall命令细节的指导了。

对于那些运行X Server的人而言,有另外一个工具称为xkill可以将进程从X Window中杀掉而不必传递它的名字或者pid。

xkill工具强制X server关闭与它的客户程序之间的联系,其结果就是X resource关闭了这个客户程序。xkill是X11工具集中一个非常容易上手的杀掉无用窗口的工具。

它支持的选项如在同时运行多个X Server时使用-display选项后面跟上显示号连接到指定的X server,使用-all(并不建议)杀掉所有在屏幕上的所有顶层窗口,以及帧(-frame)参数。

要列出所有的客户程序你可以运行:

$ xlsclients

示例输出

'  ' /usr/lib/libreoffice/program/soffice
deb  gnome-shell
deb  Docky
deb  google-chrome-stable
deb  soffice
deb  gnome-settings-daemon
deb  gnome-terminal-server

如果后面没有跟上资源id,xkill会将鼠标指针变成一个特殊符号,类似于“X”。只需在你要杀掉的窗口上点击,它就会杀掉它与server端的通信,这个程序就被杀掉了。

$ xkill
Linux:如何使用xkill命令杀掉Linux进程/未响应的程序
Linux:如何使用xkill命令杀掉Linux进程/未响应的程序

使用xkill杀掉进程

需要注意的是xkill并不能保证它的通信会被成功杀掉/退出。大多数程序会在与服务端的通信被关闭后杀掉。然而仍有少部分会继续运行。

需要指出的点是:

  • 这个工具只能在X11 server运行的时候才能使用,因为这是X11工具的一部分。
  • 不要在你杀掉一个资源而它没有完全退出时而困惑。
  • 这不是kill的替代品

我需要在linux命令行中使用xkill么

不是,你不必非在命令行中运行xkill。你可以设置一个快捷键,并用它来调用xkill。

下面是如何在典型的gnome3桌面中设置键盘快捷键。

进入设置-> 选择键盘。点击’+’并添加一个名字和命令。点击点击新条目并按下你想要的组合键。我的是Ctrl+Alt+Shift+x。

Linux:如何使用xkill命令杀掉Linux进程/未响应的程序
Linux:如何使用xkill命令杀掉Linux进程/未响应的程序

Gnome 设置

Linux:如何使用xkill命令杀掉Linux进程/未响应的程序
Linux:如何使用xkill命令杀掉Linux进程/未响应的程序

添加快捷键

下次你要杀掉一个X资源只要用组合键就行了(Ctrl+Alt+Shift+x),你看到你的鼠标变成x了。点击想要杀掉的x资源就行了。


via: http://www.tecmint.com/kill-processes-unresponsive-programs-in-ubuntu/

作者:Avishek Kumar 译者:geekpi 校对:wxy

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

来源:https://linux.cn/article-5605-1.html

Linux:用于 ‘Suse‘ Linux 包管理的 Zypper 命令大全

SUSE( Software and System Entwicklung,即软件和系统开发。其中‘entwicklung‘是德语,意为开发)Linux 是由 Novell 公司在 Linux 内核基础上建立的操作系统。SUSE Linux 有两个发行分支。其中之一名为 openSUSE,这是一款自由而且免费的操作系统 (free as in speech as well as free as in wine)。该系统由开源社区开发维护,支持一些最新版本的应用软件,其最新的稳定版本为 13.2。

另外一个分支是 SUSE Linux 企业版。该分支是一个为企业及商业化产品设计的 Linux 发行版,包含了大量的企业应用以及适用于商业产品生产环境的特性。其最新的稳定版本为 12。

以下的链接包含了安装企业版 SUSE Linux 服务器的详细信息。

Linux:用于 ‘Suse‘ Linux 包管理的 Zypper 命令大全
Linux:用于 ‘Suse‘ Linux 包管理的 Zypper 命令大全

Zypper 和 Yast 是 SUSE Linux 平台上的软件包管理工具,他们的底层使用了 RPM(LCTT 译者注:RPM 最初指 Redhat Pacakge Manager ,现普遍解释为递归短语 RPM Package Manager 的缩写)。

Yast(Yet another Setup Tool )是 OpenSUSE 以及企业版 SUSE 上用于系统管理、设置和配置的工具。

Zypper 是软件包管理器ZYpp的命令行接口,可用于安装、删除SUSE Linux上的软件以及进行系统更新。ZYpp为Zypper和Yast提供底层支持。

本文将介绍实际应用中常见的一些Zypper命令。这些命令用来进行安装、更新、删除等任何软件包管理器所能够胜任的工作。

重要 : 切记所有的这些命令都将在系统全局范围内产生影响,所以必须以 root 身份执行,否则命令将失败。

获取基本的 Zypper 帮助信息

  1. 不带任何选项的执行 zypper, 将输出该命令的全局选项以及子命令列表(LCTT 译者注:全局选项,global option,控制台命令的输入分为可选参数和位置参数两大类。按照习惯,一般可选参数称为选项’option’,而位置参数称为参数 ‘argument’)。

    #  zypper
        Usage:
        zypper [--global-options]
  2. 获取一个具体的子命令的帮助信息,比如 ‘in’ (install),可以执行下面的命令

    # zypper help in

    或者

    # zypper help install
    install (in) [options] {capability | rpm_file_uri}
    Install packages with specified capabilities or RPM files with specified
    location. A capability is NAME[.ARCH][OP], where OP is one
    of <, <=, =, >=, >.
      Command options:
    --from     Select packages from the specified repository.
    -r, --repo     Load only the specified repository.
    -t, --type            Type of package (package, patch, pattern, product, srcpackage).
                                Default: package.
    -n, --name                  Select packages by plain name, not by capability.
    -C, --capability            Select packages by capability.
    -f, --force                 Install even if the item is already installed (reinstall),
                                downgraded or changes vendor or architecture.
        --oldpackage            Allow to replace a newer item with an older one.
                                Handy if you are doing a rollback. Unlike --force
                                it will not enforce a reinstall.
        --replacefiles          Install the packages even if they replace files from other,
                                already installed, packages. Default is to treat file conflicts
                                as an error. --download-as-needed disables the fileconflict check.
    ...... 
  3. 安装之前搜索一个安转包(以 gnome-desktop 为例 )

    # zypper se gnome-desktop
    Retrieving repository 'openSUSE-13.2-Debug' metadata ............................................................[done]
    Building repository 'openSUSE-13.2-Debug' cache .................................................................[done]
    Retrieving repository 'openSUSE-13.2-Non-Oss' metadata ......................................................... [done]
    Building repository 'openSUSE-13.2-Non-Oss' cache ...............................................................[done]
    Retrieving repository 'openSUSE-13.2-Oss' metadata ..............................................................[done]
    Building repository 'openSUSE-13.2-Oss' cache ...................................................................[done]
    Retrieving repository 'openSUSE-13.2-Update' metadata ...........................................................[done]
    Building repository 'openSUSE-13.2-Update' cache ................................................................[done]
    Retrieving repository 'openSUSE-13.2-Update-Non-Oss' metadata ...................................................[done]
    Building repository 'openSUSE-13.2-Update-Non-Oss' cache ........................................................[done]
    Loading repository data...
    Reading installed packages...
    S | Name                                  | Summary                                                   | Type
    --+---------------------------------------+-----------------------------------------------------------+-----------
      | gnome-desktop2-lang                   | Languages for package gnome-desktop2                      | package
      | gnome-desktop2                        | The GNOME Desktop API Library                             | package
      | libgnome-desktop-2-17                 | The GNOME Desktop API Library                             | package
      | libgnome-desktop-3-10                 | The GNOME Desktop API Library                             | package
      | libgnome-desktop-3-devel              | The GNOME Desktop API Library -- Development Files        | package
      | libgnome-desktop-3_0-common           | The GNOME Desktop API Library -- Common data files        | package
      | gnome-desktop-debugsource             | Debug sources for package gnome-desktop                   | package
      | gnome-desktop-sharp2-debugsource      | Debug sources for package gnome-desktop-sharp2            | package
      | gnome-desktop2-debugsource            | Debug sources for package gnome-desktop2                  | package
      | libgnome-desktop-2-17-debuginfo       | Debug information for package libgnome-desktop-2-17       | package
      | libgnome-desktop-3-10-debuginfo       | Debug information for package libgnome-desktop-3-10       | package
      | libgnome-desktop-3_0-common-debuginfo | Debug information for package libgnome-desktop-3_0-common | package
      | libgnome-desktop-2-17-debuginfo-32bit | Debug information for package libgnome-desktop-2-17       | package
      | libgnome-desktop-3-10-debuginfo-32bit | Debug information for package libgnome-desktop-3-10       | package
      | gnome-desktop-sharp2                  | Mono bindings for libgnome-desktop                        | package
      | libgnome-desktop-2-devel              | The GNOME Desktop API Library -- Development Files        | packag
      | gnome-desktop-lang                    | Languages for package gnome-desktop                       | package
      | libgnome-desktop-2-17-32bit           | The GNOME Desktop API Library                             | package
      | libgnome-desktop-3-10-32bit           | The GNOME Desktop API Library                             | package
      | gnome-desktop                         | The GNOME Desktop API Library                             | srcpackage
  4. 获取一个模式包的信息(以 lamp_server 为例)。

    # zypper info -t pattern lamp_server
    Loading repository data...
    Reading installed packages...
    Information for pattern lamp_server:
    ------------------------------------
    Repository: openSUSE-13.2-Update
    Name: lamp_server
    Version: 20141007-5.1
    Arch: x86_64
    Vendor: openSUSE
    Installed: No
    Visible to User: Yes
    Summary: Web and LAMP Server
    Description:
      Software to set up a Web server that is able to serve static, dynamic, and interactive content (like a Web shop). This includes Apache HTTP Server, the database management system MySQL,
      and scripting languages such as PHP, Python, Ruby on Rails, or Perl.
    Contents:
    S | Name                          | Type    | Dependency
    --+-------------------------------+---------+-----------
      | apache2-mod_php5              | package |
      | php5-iconv                    | package |
    i | patterns-openSUSE-base        | package |
    i | apache2-prefork               | package |
      | php5-dom                      | package |
      | php5-mysql                    | package |
    i | apache2                       | package |
      | apache2-example-pages         | package |
      | mariadb                       | package |
      | apache2-mod_perl              | package |
      | php5-ctype                    | package |
      | apache2-doc                   | package |
      | yast2-http-server             | package |
      | patterns-openSUSE-lamp_server | package |
  5. 开启一个Zypper Shell 的会话。

    # zypper shell 

    或者

    # zypper sh 
    zypper> help
      Usage:
        zypper [--global-options]

注意:在 Zypper shell里面可以通过键入 ‘help‘ 获得全局选项以及子命令的列表。

Zypper 软件库管理

列举已定义的软件库

  1. 使用 ‘zypper repos’ 或者 ‘zypper lr’ 来列举所有已定以的软件库。

    # zypper repos

    或者

    # zypper lr
      | Alias                     | Name                               | Enabled | Refresh
    --+---------------------------+------------------------------------+---------+--------
    1 | openSUSE-13.2-0           | openSUSE-13.2-0                    | Yes     | No
    2 | repo-debug                | openSUSE-13.2-Debug                | Yes     | Yes
    3 | repo-debug-update         | openSUSE-13.2-Update-Debug         | No      | Yes
    4 | repo-debug-update-non-oss | openSUSE-13.2-Update-Debug-Non-Oss | No      | Yes
    5 | repo-non-oss              | openSUSE-13.2-Non-Oss              | Yes     | Yes
    6 | repo-oss                  | openSUSE-13.2-Oss                  | Yes     | Yes
    7 | repo-source               | openSUSE-13.2-Source               | No      | Yes
    8 | repo-update               | openSUSE-13.2-Update               | Yes     | Yes
    9 | repo-update-non-oss       | openSUSE-13.2-Update-Non-Oss       | Yes     | Yes
  2. 在表格里面显示 zypper URI

    # zypper lr -u
      | Alias                     | Name                               | Enabled | Refresh | URI
    --+---------------------------+------------------------------------+---------+---------+----------------------------------------------------------------
    1 | openSUSE-13.2-0           | openSUSE-13.2-0                    | Yes     | No      | cd:///?devices=/dev/disk/by-id/ata-VBOX_CD-ROM_VB2-01700376
    2 | repo-debug                | openSUSE-13.2-Debug                | Yes     | Yes     | http://download.opensuse.org/debug/distribution/13.2/repo/oss/
    3 | repo-debug-update         | openSUSE-13.2-Update-Debug         | No      | Yes     | http://download.opensuse.org/debug/update/13.2/
    4 | repo-debug-update-non-oss | openSUSE-13.2-Update-Debug-Non-Oss | No      | Yes     | http://download.opensuse.org/debug/update/13.2-non-oss/
    5 | repo-non-oss              | openSUSE-13.2-Non-Oss              | Yes     | Yes     | http://download.opensuse.org/distribution/13.2/repo/non-oss/
    6 | repo-oss                  | openSUSE-13.2-Oss                  | Yes     | Yes     | http://download.opensuse.org/distribution/13.2/repo/oss/
    7 | repo-source               | openSUSE-13.2-Source               | No      | Yes     | http://download.opensuse.org/source/distribution/13.2/repo/oss/
    8 | repo-update               | openSUSE-13.2-Update               | Yes     | Yes     | http://download.opensuse.org/update/13.2/
    9 | repo-update-non-oss       | openSUSE-13.2-Update-Non-Oss       | Yes     | Yes     | http://download.opensuse.org/update/13.2-non-oss/
  3. 根据优先级列举软件库。

    # zypper lr -P
      | Alias                     | Name                               | Enabled | Refresh | Priority
    --+---------------------------+------------------------------------+---------+---------+---------
    1 | openSUSE-13.2-0           | openSUSE-13.2-0                    | Yes     | No      |   99
    2 | repo-debug                | openSUSE-13.2-Debug                | Yes     | Yes     |   99
    3 | repo-debug-update         | openSUSE-13.2-Update-Debug         | No      | Yes     |   99
    4 | repo-debug-update-non-oss | openSUSE-13.2-Update-Debug-Non-Oss | No      | Yes     |   99
    5 | repo-non-oss              | openSUSE-13.2-Non-Oss              | Yes     | Yes     |   85
    6 | repo-oss                  | openSUSE-13.2-Oss                  | Yes     | Yes     |   99
    7 | repo-source               | openSUSE-13.2-Source               | No      | Yes     |   99
    8 | repo-update               | openSUSE-13.2-Update               | Yes     | Yes     |   99
    9 | repo-update-non-oss       | openSUSE-13.2-Update-Non-Oss       | Yes     | Yes     |   99

刷新软件库

  1. 使用 ‘zypper refresh’ or ‘zypper ref’ 来刷新 zypper 软件库。

    # zypper refresh 

    或者

    # zypper ref
    Repository 'openSUSE-13.2-0' is up to date.
    Repository 'openSUSE-13.2-Debug' is up to date.
    Repository 'openSUSE-13.2-Non-Oss' is up to date.
    Repository 'openSUSE-13.2-Oss' is up to date.
    Repository 'openSUSE-13.2-Update' is up to date.
    Repository 'openSUSE-13.2-Update-Non-Oss' is up to date.
    All repositories have been refreshed. 
  2. 刷新一个指定的软件库(以 ‘repo-non-oss’ 为例 )。

    # zypper refresh repo-non-oss
    Repository 'openSUSE-13.2-Non-Oss' is up to date.
    Specified repositories have been refreshed. 
  3. 强制更新一个软件库(以 ‘repo-non-oss’ 为例 )。

    # zypper ref -f repo-non-oss
    Forcing raw metadata refresh
    Retrieving repository 'openSUSE-13.2-Non-Oss' metadata ............................................................[done]
    Forcing building of repository cache
    Building repository 'openSUSE-13.2-Non-Oss' cache ............................................................[done]
    Specified repositories have been refreshed.

修改软件库

本文中我们使用‘zypper modifyrepo‘ 或者 ‘zypper mr‘ 来关闭或者开启 zypper 软件库。

  1. 在关闭一个软件库之前,我们需要知道在 zypper 中,每一个软件库有一个唯一的标示数字与之关联,该数字用于打开或者关闭与之相联系的软件库。假设我们需要关闭 ‘repo-oss’ 软件库,那么我们可以通过以下的法来获得该软件库的标志数字。

    # zypper lr
      | Alias                     | Name                               | Enabled | Refresh
    --+---------------------------+------------------------------------+---------+--------
    1 | openSUSE-13.2-0           | openSUSE-13.2-0                    | Yes     | No
    2 | repo-debug                | openSUSE-13.2-Debug                | Yes     | Yes
    3 | repo-debug-update         | openSUSE-13.2-Update-Debug         | No      | Yes
    4 | repo-debug-update-non-oss | openSUSE-13.2-Update-Debug-Non-Oss | No      | Yes
    5 | repo-non-oss              | openSUSE-13.2-Non-Oss              | Yes     | Yes
    6 | repo-oss                  | openSUSE-13.2-Oss                  | No      | Yes
    7 | repo-source               | openSUSE-13.2-Source               | No      | Yes
    8 | repo-update               | openSUSE-13.2-Update               | Yes     | Yes
    9 | repo-update-non-oss       | openSUSE-13.2-Update-Non-Oss       | Yes     | Yes

    从以上输出的列表中我们可以看到 ‘repo-oss’ 库的标示数字是 6,因此通过以下的命令来关闭该库。

    # zypper mr -d 6
    Repository 'repo-oss' has been successfully disabled.
  2. 如果需要再次开启软件库 ‘repo-oss‘, 接上例,与之相关联的标示数字为 6。

    # zypper mr -e 6
    Repository 'repo-oss' has been successfully enabled.
  3. 针对某一个软件库(以 ‘repo-non-oss’ 为例 )开启自动刷新( auto-refresh )和 rpm 缓存,并设置该软件库的优先级,比如85。

    # zypper mr -rk -p 85 repo-non-oss
    Repository 'repo-non-oss' priority has been left unchanged (85)
    Nothing to change for repository 'repo-non-oss'.
  4. 对所有的软件库关闭 rpm 文件缓存。

    # zypper mr -Ka
    RPM files caching has been disabled for repository 'openSUSE-13.2-0'.
    RPM files caching has been disabled for repository 'repo-debug'.
    RPM files caching has been disabled for repository 'repo-debug-update'.
    RPM files caching has been disabled for repository 'repo-debug-update-non-oss'.
    RPM files caching has been disabled for repository 'repo-non-oss'.
    RPM files caching has been disabled for repository 'repo-oss'.
    RPM files caching has been disabled for repository 'repo-source'.
    RPM files caching has been disabled for repository 'repo-update'.
    RPM files caching has been disabled for repository 'repo-update-non-oss'.
  5. 对所有的软件库开启 rpm 文件缓存。

    # zypper mr -ka
    RPM files caching has been enabled for repository 'openSUSE-13.2-0'.
    RPM files caching has been enabled for repository 'repo-debug'.
    RPM files caching has been enabled for repository 'repo-debug-update'.
    RPM files caching has been enabled for repository 'repo-debug-update-non-oss'.
    RPM files caching has been enabled for repository 'repo-non-oss'.
    RPM files caching has been enabled for repository 'repo-oss'.
    RPM files caching has been enabled for repository 'repo-source'.
    RPM files caching has been enabled for repository 'repo-update'.
    RPM files caching has been enabled for repository 'repo-update-non-oss'.
  6. 关闭远程库的 rpm 文件缓存

    # zypper mr -Kt
    RPM files caching has been disabled for repository 'repo-debug'.
    RPM files caching has been disabled for repository 'repo-debug-update'.
    RPM files caching has been disabled for repository 'repo-debug-update-non-oss'.
    RPM files caching has been disabled for repository 'repo-non-oss'.
    RPM files caching has been disabled for repository 'repo-oss'.
    RPM files caching has been disabled for repository 'repo-source'.
    RPM files caching has been disabled for repository 'repo-update'.
    RPM files caching has been disabled for repository 'repo-update-non-oss'.
  7. 开启远程软件库的 rpm 文件缓存。

    # zypper mr -kt
    RPM files caching has been enabled for repository 'repo-debug'.
    RPM files caching has been enabled for repository 'repo-debug-update'.
    RPM files caching has been enabled for repository 'repo-debug-update-non-oss'.
    RPM files caching has been enabled for repository 'repo-non-oss'.
    RPM files caching has been enabled for repository 'repo-oss'.
    RPM files caching has been enabled for repository 'repo-source'.
    RPM files caching has been enabled for repository 'repo-update'.
    RPM files caching has been enabled for repository 'repo-update-non-oss'.

增加新的软件库

可以通过这两个 zypper 指令 – ‘zypper addrepo’ 和 ‘zypper ar’ 来增加新的软件库。在此过程中可以使用 URL 或者软件库的别名。

  1. 增加一个新的软件库( 以 “http://download.opensuse.org/update/12.3/” 为例 )。

    # zypper ar http://download.opensuse.org/update/11.1/ update
    Adding repository 'update' .............................................................................................................................................................[done]
    Repository 'update' successfully added
    Enabled     : Yes
    Autorefresh : No
    GPG check   : Yes
    URI         : http://download.opensuse.org/update/11.1/
  2. 更改一个软件库的名字,这将仅仅改变软件库的别名。 命令 ‘zypper namerepo’ 或者 ‘zypperr nr’ 可以胜任此工作。例如更改标示数字为10的软件库的名字为 ‘upd8’,或者说将标示数字为10的软件库的别名改为 ‘upd8’,可以使用下面的命令。

    # zypper nr 10 upd8
    Repository 'update' renamed to 'upd8'.

删除软件库

  1. 删除一个软件库。要从系统删除一个软件库可以使 ‘zypper removerepo’ 或者 ‘zypper rr’。例如以下的命令可以删除软件库 ‘upd8’

    # zypper rr upd8
    # Removing repository 'upd8' .........................................................................................[done]
    Repository 'upd8' has been removed.

来源:https://linux.cn/article-5606-1.html

Linux:在Linux命令行下令人惊叹的惊叹号(!)

'!'符号在Linux中不但可以用作否定符号,还可以用来从历史命令记录中取出命令或不加修改的执行之前运行的命令。下面的所有命令都已经在Bash Shell中经过确切地检验。尽管我没有试过,但大多都不能在别的Shell中运行。这里我们介绍下Linux命令行中符号'!'那惊人和奇妙的用法。

Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

1. 使用数字从历史命令列表中找一条命令来执行

您也许没有意识到您可以从历史命令列表(之前已经执行的命令集)中找出一条来运行。首先,通过”history”命令查找之前命令的序号。

$ history
Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

使用history命令找到最后执行的命令

现在,只需要使用历史命令输出中显示在该命令前面的数字便可以运行这个命令。例如,运行一个在history输出中编号是1551的命令。

$ !1551
Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

使用命令ID来执行最后运行的命令

这样,编号为1551的命令(上面的例子是top命令)便运行了。这种通过ID号来执行之前的命令的方式很有用,尤其是在这些命令都很长的情况下。您只需要使用![history命令输出的序号]便可以调用它。

2. 运行之前的倒数第二个、第七个命令等

您可以以另一种方式来运行之前执行的命令,通过使用-1代表最后的命令,-2代表倒数第二个命令,-7代表倒数第七个命令等。

首先使用history命令来获得执行过的命令的列表。history命令的执行很有必要,因为您可以通过它来确保没有rm command > file或其他会导致危险的命令。接下来执行倒数第六个、第八个、第十个命令。

$ history
$ !-6
$ !-8
$ !-10
Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

通过负数序号运行之前执行的命令

3. 传递最后执行的命令的参数,以方便的运行新的命令

我需要显示/home/$USER/Binary/firefox文件夹的内容,因此我执行:

$ ls /home/$USER/Binary/firefox

接下来,我意识到我应该执行’ls -l’来查看哪个文件是可执行文件。因此我应该重新输入整个命令么?不,我不需要。我仅需要在新的命令中带上最后的参数,类似:

$ ls -l !$

这里!$将把最后执行的命令的参数传递到这个新的命令中。

Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

将上一个命令的参数传递给新命令

4. 如何使用!来处理两个或更多的参数

比如说我在桌面创建了一个文本文件file1.txt。

$ touch /home/avi/Desktop/1.txt

然后在cp命令中使用绝对路径将它拷贝到/home/avi/Downloads

$ cp /home/avi/Desktop/1.txt /home/avi/downloads

这里,我们给cp命令传递了两个参数。第一个是/home/avi/Desktop/1.txt,第二个是/home/avi/Downloads。让我们分别处理他们,使用echo [参数]来打印两个不同的参数。

$ echo "1st Argument is : !^"
$ echo "2nd Argument is : !cp:2"

注意第一个参数可以使用"!^"进行打印,其余的命令可以通过"![命令名]:[参数编号]"打印。

在上面的例子中,第一个命令是cp,第二个参数也需要被打印。因此是"!cp:2",如果任何命令比如xyz运行时有5个参数,而您需要获得第四个参数,您可以使用"!xyz:4"。所有的参数都可以通过"!*"来获得。

Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

处理两个或更多的参数

5. 以关键字为基础执行上个的命令

我们可以以关键字为基础执行上次执行的命令。可以从下面的例子中理解:

$ ls /home > /dev/null                      [命令1]
$ ls -l /home/avi/Desktop > /dev/null                       [命令2]
$ ls -la /home/avi/Downloads > /dev/null                    [命令3]
$ ls -lA /usr/bin > /dev/null                       [命令4]

上面我们使用了同样的命令(ls),但有不同的开关和不同的操作文件夹。而且,我们还将输出传递到/dev/null,我们并未显示输出,因而终端依旧很干净。

现在以关键字为基础执行上个的命令。

$ ! ls                  [命令1]
$ ! ls -l               [命令2]
$ ! ls -la              [命令3]
$ ! ls -lA              [命令4]

检查输出,您将惊奇发现您仅仅使用关键字ls便执行了您已经执行过的命令。

Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

以关键字为基础执行命令

(LCTT 译注:澄清一下,这种用法会按照命令名来找到最后匹配的命令,不会匹配参数。所以上述执行的四个命令都是执行了 ls -lA /usr/bin > /dev/null,并增加了新的参数而已。)

6. !!操作符的威力

您可以使用(!!)运行/修改您上个运行的命令。它将附带一些修改/调整并调用上个命令。让我给您展示一些实际情境。

昨天我运行了一行脚本来获得我的私有IP,因此我执行了:

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/

接着,我突然发现我需要将上面脚本的输出重定向到一个ip.txt的文件,因此,我该怎么办呢?我该重新输入整个命令并重定向到一个文件么?一个简单的解决方案是使用向上光标键并添加'> ip.txt'来将输出重定向到文件。

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txt

在这里要感谢救世主”向上光标键”。现在,考虑下面的情况,这次我运行了下面这一行脚本。

$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:

一旦我运行了这个脚本,Bash提示符便返回了错误消息"bash: ifconfig: command not found"。原因并不难猜,我运行了本应以root权限的运行的命令。

所以,怎么解决呢?以root用户登录并且再次键入整个命令就太麻烦了!而且向上导航键也不管用了(LCTT 译注:当你以新的用户身份登录了,是不能用向上光标键找到之前的另外一个用户的命令历史的)。因此,我们需要调用"!!"(去掉引号),它将为那个用户调用上个命令。

$ su -c !! root

这里su是用来切换到root用户的,-c用来以某用户运行特定的命令,最重要的部分是!!,它将被替换为上次运行的命令。当然!您需要提供root密码。

Linux:在Linux命令行下令人惊叹的惊叹号(!)
Linux:在Linux命令行下令人惊叹的惊叹号(!)

!!操作符的威力

我通常在下面的情景中使用!!

当我用普通用户来运行apt-get,我通常收到提示说我没有权限来执行。

$ apt-get upgrade && apt-get dist-upgrade

好吧,有错误。但别担心,使用下面的命令来成功的执行…

$ su -c !!

同样的适用于:

$ service apache2 start

$ /etc/init.d/apache2 start

$ systemctl start apache2

普通用户不被授权执行那些任务,这样相当于我运行:

$ su -c 'service apache2 start'

$ su -c '/etc/init.d/apache2 start'

$ su -c 'systemctl start apache2'

(LCTT 译注:使用!!之前,一定要确认你执行的是什么命令!另外,在 root 身份下,千万不要养成使用它的习惯,因为你总是会在不合适的目录执行不合适的命令!)

7.运行一个影响所有除了![FILE_NAME]的文件命令

!(逻辑非)能用来对除了'!'后的文件的所有的文件/扩展名执行命令。

A.从文件夹移除所有文件,2.txt除外。

$ rm !(2.txt)

B.从文件夹移除所有的文件类型,pdf类型除外。

$ rm !(*.pdf)

8.检查某个文件夹(比如/home/avi/Tecmint)是否存在?并打印

这里,我们使用'! -d'来验证文件夹是否存在,当文件夹不存在时,将使用其后跟随AND操作符(&&)进行打印,当文件夹存在时,将使用OR操作符(||)进行打印。

逻辑上,当[ ! -d /home/avi/Tecmint ]的输出为0时,它将执行AND逻辑符后面的内容,否则,它将执行OR逻辑符(||)后面的内容。

$ [ ! -d /home/avi/Tecmint ] && printf 'nno such /home/avi/Tecmint directory existn' || printf 'n/home/avi/Tecmint directory existn'

9.检查某文件夹是否存在?如果不存在则退出该命令

类似于上面的情况,但这里当期望的文件夹不存在时,该命令会退出。

$ [ ! -d /home/avi/Tecmint ] && exit

10.如果您的home文件夹内不存在一个文件夹(比方说test),则创建它

这是脚本语言中的一个常用的实现,当期望的文件夹不存在时,创建一个。

[ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint

这便是全部了。如果您知道或偶尔遇到其他值得了解的'!'使用方法,请您在反馈的地方给我们提建议。保持联系!


via: http://www.tecmint.com/mysterious-uses-of-symbol-or-operator-in-linux-commands/

作者:Avishek Kumar 译者:wwy-hust 校对:wxy

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

来源:https://linux.cn/article-5608-1.html

Linux:8个增强 PHP 程序安全的函数

Linux:8个增强 PHP 程序安全的函数
Linux:8个增强 PHP 程序安全的函数

安全是编程非常重要的一个方面。在任何一种编程语言中,都提供了许多的函数或者模块来确保程序的安全性。在现代网站应用中,经常要获取来自世界各地用户的输入,但是,我们都知道“永远不能相信那些用户输入的数据”。所以在各种的Web开发语言中,都会提供保证用户输入数据安全的函数。今天,我们就来看看,在著名的开源语言PHP中有哪些有用的安全函数。

在PHP中,有些很有用的函数开源非常方便的防止你的网站遭受各种攻击,例如SQL注入攻击,XSS(Cross Site Scripting:跨站脚本)攻击等。一起看看PHP中常用的、可以确保项目安全的函数。注意,这并不是完整的列表,是我觉得对于你的i项目很有的一些函数。

1. mysql_real_escape_string()

这个函数在PHP中防止SQL注入攻击时非常有用。这个函数会对一些例如单引号、双引号、反斜杠等特殊字符添加一个反斜杠以确保在查询这些数据之前,用户提供的输入是干净的。但要注意,你是在连接数据库的前提下使用这个函数。

但是现在已经不推荐使用mysql_real_escape_string()了,所有新的应用应该使用像PDO一样的函数库执行数据库操作,也就是说,我们可以使用现成的语句防止SQL注入攻击。

2. addslashes()

这个函数的原理跟mysql_real_escape_string()相似。但是当在php.ini文件中,“magic_quotes_gpc“的值是“on”的时候,就不要使用这个函数。magic_quotes_gpc 的默认值是on,对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。你可以使用get_magic_quotes_gpc()函数来确定它是否开启。

3. htmlentities()

这个函数对于过滤用户输入的数据非常有用。它会将一些特殊字符转换为HTML实体。例如,用户输入<时,就会被该函数转化为HTML实体<(&lt),输入>就被转为实体&gt.(HTML实体对照表:http://www.w3school.com.cn/html/html_entities.asp),可以防止XSS和SQL注入攻击。

4. htmlspecialchars()

在HTML中,一些特定字符有特殊的含义,如果要保持字符原来的含义,就应该转换为HTML实体。这个函数会返回转换后的字符串,例如‘&’ (ampersand) 转为’&amp‘(ps:请参照第三点中的实体对照表链接)

ps:此处原文有误(见评论),在此非常感谢瑾瑜提出。现已更正,另外附上此函数常见的转换字符:

The translations performed are:

  •  ‘&’ (ampersand) becomes ‘&’
  •  ‘”‘ (double quote) becomes ‘"’ when ENT_NOQUOTES is not set.
  •  “‘” (single quote) becomes ‘'’ (or ') only when ENT_QUOTES is set.
  •  ‘<’ (less than) becomes ‘<’
  •  ‘>’ (greater than) becomes ‘>’

5. strip_tags()

这个函数可以去除字符串中所有的HTML,JavaScript和PHP标签,当然你也可以通过设置该函数的第二个参数,让一些特定的标签出现。

6. md5()

从安全的角度来说,一些开发者在数据库中存储简单的密码的行为并不值得推荐。md5()函数可以产生给定字符串的32个字符的md5散列,而且这个过程不可逆,即你不能从md5()的结果得到原始字符串。

现在这个函数并不被认为是安全的,因为开源的数据库可以反向检查一个散列值的明文。你可以在这里找到一个MD5散列数据库列表

7. sha1()

这个函数与md5()类似,但是它使用了不同的算法来产生40个字符的SHA-1散列(md5产生的是32个字符的散列)。也不要把绝对安全寄托在这个函数上,否则会有意想不到的结果。

8. intval()

先别笑,我知道这个函数和安全没什么关系。intval()函数是将变量转成整数类型,你可以用这个函数让你的PHP代码更安全,特别是当你在解析id,年龄这样的数据时。

来源:http://www.ido321.com/1202.html

Linux:Linux 有问必答:在 Linux 上如何通过命令行来更改日期和时间

问题: 在 Linux 上, 我怎样通过命令行来改变日期和时间?

在 Linux 系统中保持日期和时间的同步是每一个 Linux 用户和系统管理员的重要责任. 很多程序都依靠精确的时间信息得以正常工作. 另外, 不精确的日期和时间会使得日志文件中的时间戳变得毫无意义, 减弱了它们在系统检查和检修中的作用. 对于生产系统来说, 精确的日期和时间甚至更为重要. 例如, 在零售公司中, 所有产品必须时刻准确地计数(并储存在数据库服务器中)以便于财政部门计算每天及每周,每月,每年的支出和收入.

我们必须注意, 在 Linux 机器上有两种时钟: 由内核维持的软件时钟(又称系统时钟)和在机器关机后记录时间的(电池供电的)硬件时钟. 启动的时候, 内核会把系统时钟与硬件时钟同步. 之后, 两个时钟各自独立运行.

Linux:Linux 有问必答:在 Linux 上如何通过命令行来更改日期和时间
Linux:Linux 有问必答:在 Linux 上如何通过命令行来更改日期和时间

方法一: Date 命令

在 Linux 中, 你可以通过 date 命令来更改系统的日期和时间:

# date --set='NEW_DATE'

其中 NEW_DATE 是诸如 “Sun, 28 Sep 2014 16:21:42” 或者 “2014-09-29 16:21:42” 的可读格式的日期字符串.

日期格式也可以手动指定以获得更精确的结果:

# date +FORMAT --set='NEW_DATE'

例如:

# date +’%Y%m%d %H%m’ --set='20140928 1518'

你也可以用相对的方式地增加或减少一定的天数,周数,月数和秒数,分钟数,小时数。 你也可以把日期和时间的参数放到一个命令中。

# date --set='+5 minutes'
# date --set='-2 weeks'
# date --set='+3 months'
# date --set='-3 months +2 weeks -5 minutes'

最后, 把硬件时钟设置为当前系统时钟:

# hwclock --systohc

运行 hwclock –systohc 的目的是将硬件时钟同软件时钟同步, 这可以更正硬件时钟的系统漂移(即时钟按照一定的速度走快或走慢).

另一方面, 如果硬件时钟是正确的, 但系统时钟有误, 可以用下面的命令更正:

 # hwclock --hctosys

在两种情况下, hwclock 命令都是将两个时钟同步. 否则, 重启后时间会是错误的, 因为当电源关闭时硬件时钟会记忆时间. 然而, 这对于虚拟机器并不适用, 因为虚拟机器并不能访问硬件时钟.

如果你的 Linux 系统上的默认时区是错误的, 你可以按照这个指导进行更正.

方法二: NTP

另一种使系统日期和时间保持精确的方法是使用 NTP (网络时间协议). 在 Linux 上, ntpdate 命令通过 NTP 将系统时钟和公共 NTP 服务器同步.

你可以使用如下命令来安装 ntpdate:

在 Debian 及基于 Debian 的发行版上:

# aptitude install ntpdate

在基于 Ret Hat 的发行版上:

# yum install ntpdate

使用 NTP 同步系统时钟:

# ntpdate -u 
# hwclock --systohc

除了一次性使用 ntpdate 来同步时钟, 你也可以使用 NTP 守护进程(ntpd), 它会始终在后台运行, 不断地通过 NTP 来调整系统时钟. 关于 NTP 的设置, 请参考这个指导.


via: http://ask.xmodulo.com/change-date-time-command-line-linux.html

译者:wangjiezhe 校对:wxy

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

来源:https://linux.cn/article-4187-1.html

Linux:Arch Linux 安装捷径:Evo/Lution

有些人只体验过Ubuntu或Mint的安装,却鼓起勇气想要安装Arch Linux,他们的学习道路是那样的陡峭和严峻,安装过程中半途而废的人数可能要比顺利过关的人多得多。如果你成功搭建并按你所需的配置好了Arch Linux,那么它已经把你培养成了一个饱经风霜的Linux用户。

即使有可以帮助你的维基为新手提供指南,对于那些想要征服Arch的人而言要求仍然太高。你需要至少熟悉诸如fdisk或mkfs之类的终端命令,并且听过mc、nano或chroot这些,并努力掌握它们。这让我回想起了10年前的Debian安装。

对于那些满怀抱负而又缺乏知识的生灵,有一个叫Evo/Lution Live ISO的ISO镜像格式安装器可以拯救他们。即便它貌似像发行版一样启动,但它其实除了辅助安装Arch Linux准系统之外啥都不干。Evo/Lution是一个项目,它旨在通过提供Arch的简单安装方式来为Arch的增加更多的用户基数,就像为那些用户提供全面帮助和文档的社区一样。在这样一个组合中,Evo是Live CD(不可安装),而Lution是个安装器本身。项目创立者看到了Arch及其衍生发行版的开发者和用户之间的巨大鸿沟,而想要在所有参与者之间构筑一个身份平等的社区。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

项目的软件部分是命令行安装器Lution-AIS,它负责解释一个普通的纯净的Arch安装过程中的每一步。安装完毕后,你将获得Arch提供的没有从AUR添加任何东西的最新软件或其它任何自定义的包。

启动这个422MB大小的ISO镜像后,一个由显示在右边的带有选项快捷方式的Conky和一个左边等待运行安装器的LX-Terminal组成的工作区便呈现在我们眼前。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

在通过右击桌面或使用ALT-i启动实际的安装器后,一个写满了16个等待运行的任务列表就出现在你面前了。除非你知道你在做什么,否则请将这些任务全部运行一遍。你可以一次运行,也可以进行选择,如1 3 6,或者1-4,也可以一次将它们全部运行,输入1-16。大多数步骤需要‘y’,即‘yes’,来确认,敲击回车即可。在此期间,你有足够的时间来阅读安装指南,它可以通过ALT-g来打开。当然,你也可以出去溜达一圈再回来。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

这16个步骤分成“基础安装”和“桌面安装”两组。第一个组安装主要关注本地化、分区,以及安装启动器。

安装器带领你穿越分区世界,你可以选择使用gparted、gdisk,以及cfdisk。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

创建完分区后(如,像截图中所示,用gparted划分/dev/sda1用于root,/dev/sda2用于swap),你可以在10个文件系统中选择其中之一。在下一步中,你可以选择内核(最新或长期支持LTS)和基础系统。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

安装完你喜爱的启动加载器后,第一部分安装就完成了,这大约需要花费12分钟。这是在普通的Arch Linux中你第一次重启进入系统所处之处。

在Lution的帮助下,继续进入第二部分,在这一部分中将安装Xorg、声音和图形驱动,然后进入桌面环境。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

安装器会检测是否在VirtualBox中安装,并且会自动为VM安装并加载正确的通用驱动,然后相应地设置systemd

在下一步中,你可以选择KDE、Gnome、Cinnamon、LXDE、Englightenment、Mate或XFCE作为你的桌面环境。如果你不喜欢臃肿的桌面,你也可以试试这些窗口管理器:Awesome、Fluxbox、i3、IceWM、Openbox或PekWM。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

在使用Cinnamon作为桌面环境的情况下,第二部分安装将花费不到10分钟的时间;而选择KDE的话,因为要下载的东西多得多,所以花费的时间也会更长。

Lution-AIS在Cinnamon和Awesome上像个妩媚的小妖精。在安装完成并提示重启后,它就带我进入了我所渴望的环境。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

我要提出两点批评:一是在安装器要我选择一个镜像列表时,以及在创建fstab文件时。在这两种情况下,它都另外开了一个终端,给出了一些文本信息提示。这让我花了点时间才搞清楚,原来我得把它关了,安装器才会继续。在创建fstab后,它又会提示你,而你需要关闭终端,并在问你是否想要保存文件时回答‘是’。

Linux:Arch Linux 安装捷径:Evo/Lution
Linux:Arch Linux 安装捷径:Evo/Lution

我碰到的第二个问题,可能与VirtualBox有关了。在启动的时候,你可以看到没有网络被检测到的提示信息。点击顶部左边的图标,将会打开我们所使用的网络管理器wicd。点击“断开”,然后再点击“连接”并重启安装器,就可以让它自动检测到了。

Evo/Lution看起来是个有价值的项目,在这里Lution工作一切顺利,目前还没有什么可告诉社区的。他们开启了一个全新的网站、论坛和维基,需要填充内容进去啊。所以,如果你喜欢这主意,加入他们的论坛并告诉他们吧。本文中的ISO镜像可以从此网站下载。


via: http://xmodulo.com/2014/09/install-arch-linux-easy-way-evolution.html

作者:Ferdinand Thommes 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-4188-1.html

Linux:Apache Access Log中的OPTIONS *的含义

在Apache的Access Log中会看到很多如下的访问日志:

127.0.0.1 - - [05/May/2011:10:54:07 +0800] "OPTIONS * HTTP/1.0" 200 -
127.0.0.1 - - [05/May/2011:10:54:08 +0800] "OPTIONS * HTTP/1.0" 200 -
127.0.0.1 - - [05/May/2011:10:54:09 +0800] "OPTIONS * HTTP/1.0" 200 -
127.0.0.1 - - [05/May/2011:10:54:10 +0800] "OPTIONS * HTTP/1.0" 200 - 

这是什么意思呢?

Apache的文档中, 有如下的说明:

When the Apache HTTP Server manages its child processes, it needs a way to wake up processes that are listening for new connections. To do this, it sends a simple HTTP request back to itself. This request will appear in the access_log file with the remote address set to the loop-back interface (typically 127.0.0.1 or ::1 if IPv6 is configured). If you log the User-Agent string (as in the combined log format), you will see the server signature followed by “(internal dummy connection)” on non-SSL servers. During certain periods you may see up to one such request for each httpd child process.

可是,为什么要唤醒呢? 唤醒是为了做什么呢?

Linux:Apache Access Log中的OPTIONS *的含义
Linux:Apache Access Log中的OPTIONS *的含义

在Apache Prefork模式下, 启动的时候,Apache就会fork出一些worker进程, 来准备接受请求, 这些worker进程,在完成准备工作以后, 就会进入block模式的监听沉睡中, 等待请求到来而被唤醒。

另外一方面, 在Prefork模式下, 当请求很多, 目前的worker进程数不够处理的时候, 就会额外再fork一些worker进程出来, 以满足当前的请求。

而在这些请求高峰过后, 如果额外fork出来的进程数大于了MaxSpareServers, Apache就会告诉这些worker进程退出, 那么问题就来了。

这些进程都在沉睡中啊, 怎么告诉他们, 并且让他们自我退出呢?

Apache会首先发送一个退出状态字(GRACEFUL_CHAR !)给这些Work进程:

static apr_status_t pod_signal_internal(ap_pod_t *pod)
{
    apr_status_t rv;
    char char_of_death = '!';
    apr_size_t one = 1;
    rv = apr_file_write(pod->pod_out, &char_of_death, &one);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf,
                     "write pipe_of_death");
    }
    return rv;
}

但此时, Worker进程不会去读这些状态字, 因为他们还在沉睡。

这个时候Apache就会发送一个OPTIONS请求给自己, 唤醒这些沉睡的进程:

static apr_status_t dummy_connection(ap_pod_t *pod)
{
//...有省略
    /* Create the request string. We include a User-Agent so that
     * adminstrators can track down the cause of the odd-looking
     * requests in their logs.
     */
    srequest = apr_pstrcat(p, "OPTIONS * HTTP/1.0rnUser-Agent: ",
                           ap_get_server_banner(),
                           " (internal dummy connection)rnrn", NULL);
//...有省略
}

这些进程在处理完当前请求以后(OPTIONS请求), 就会发现, oh, 主进程让我退出。

static void child_main(int child_num_arg)
{
//...有省略
    while (!die_now && !shutdown_pending) {
//...有省略
        //1. listen
        //2. accept
        //3. process request
        /* Check the pod and the generation number after processing a
         * connection so that we'll go away if a graceful restart occurred
         * while we were processing the connection or we are the lucky
         * idle server process that gets to die.
         */
        if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
            die_now = 1;
        }
//...有省略
   }
//...有省略
}

于是, 它就做完清理工作, 然后自我消亡了~~~

来源:http://www.laruence.com/2011/05/05/2002.html

Linux:Linux 有问必答:如何在CentOS或者RHEL上安装REMI仓库

Question:我该如何在CentOS或者RHEL中配置REMI仓库,并安装其中的包?

REMI 仓库提供了CentOS和RHEL的核心包的更新版本,尤其是最新的PHP/MySQL系列(LCTT 译注:当你需要一个更新包,而 CentOS/RHEL 没有及时提供更新时, REMI 仓库可以帮助你)。

安装REMI仓库要记住的一件事是不要在启用了REMI仓库时运行yum update。因为REMI仓库的包名与RHEL/CentOS中的相同,运行yum update可能会触发意外的更新。一个好办法是禁用REMI仓库,在你需要安装RMEI仓库中独有的包时再启用。

Linux:Linux 有问必答:如何在CentOS或者RHEL上安装REMI仓库
Linux:Linux 有问必答:如何在CentOS或者RHEL上安装REMI仓库

预备工作

安装REMI仓库之前,你首先需要启用EPEL仓库,因为REMI中的一些包依赖于EPEL。按照这份指南在CentOS或者RHEL中设置EPEL仓库。

安装REMI仓库

现在按照下面的步骤安装REMI仓库。

在CentOS 7上:

$ sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
$ sudo rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

在CentOS 6上:

$ sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
$ sudo rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

默认地,REMI是禁用的。要检查REMI是否已经成功安装,使用这个命令。你会看到几个REMI仓库,比如remi、remi-php55和remi-php56。

$ yum repolist disabled | grep remi

从REMI仓库中安装一个包

如上所述,最好保持禁用REMI仓库,只有在需要的时候再启用

要搜索或安装REMI仓库中的包,使用这些命令:

$ sudo yum --enablerepo=remi search 
$ sudo yum --enablerepo=remi install 

via: http://ask.xmodulo.com/install-remi-repository-centos-rhel.html

译者:geekpi 校对:wxy

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

来源:https://linux.cn/article-4192-1.html

Linux:SUSE Linux – Zypper 命令示例

Zypper是SUSE Linux中用于安装,升级,卸载,管理仓库、进行各种包查询的命令行接口。本篇将会讨论zypper的几个不同命令的例子。

Linux:SUSE Linux – Zypper 命令示例
Linux:SUSE Linux – Zypper 命令示例

语法:

# zypper [--global-opts]  [--command-opts] [command-arguments]

中括号中的部分可以不需要。执行zypper最简单的方法是输入 zypper 及

例子1:列出可用的全局选项和命令

打开终端,输入zypper并按回车,它会显示所有可用的全局选项和命令。

linux-xa3t:~ # zypper

例子2:获得zypper的某个命令的帮助

语法: zypper help [command]

linux-xa3t:~ # zypper help remove
remove (rm) [options]  ...
Remove packages with specified capabilities.
A capability is NAME[.ARCH][OP], where OP is one of <, <=, =, >=, >.
Command options:
-r, --repo  Load only the specified repository.
-t, --type  Type of package (package, patch, pattern, product).
 Default: package.
-n, --name Select packages by plain name, not by capability.
-C, --capability Select packages by capability.
--debug-solver Create solver test case for debugging.
-R, --no-force-resolution Do not force the solver to find solution,let it ask.
--force-resolution Force the solver to find a solution (even an aggressive one).
-u, --clean-deps Automatically remove unneeded dependencies.
-U, --no-clean-deps No automatic removal of unneeded dependencies.
-D, --dry-run Test the removal, do not actually remove.

例子3:打开zypper shell/会话

linux-xa3t:~ # zypper sh
zypper>

linux-xa3t:~ # zypper shell
zypper>

例子4:列出已定义的仓库

linux-xa3t:~ # zypper repos
Linux:SUSE Linux – Zypper 命令示例
Linux:SUSE Linux – Zypper 命令示例

linux-xa3t:~ # zypper lr

4.1) 以表格的形式列出仓库的URI

Linux:SUSE Linux – Zypper 命令示例
Linux:SUSE Linux – Zypper 命令示例

4.2) 以优先级列出仓库

linux-xa3t:~ # zypper lr -p
Linux:SUSE Linux – Zypper 命令示例
Linux:SUSE Linux – Zypper 命令示例

例子5:刷新仓库

linux-xa3t:~ # zypper ref
Repository 'openSUSE-13.1-Non-Oss' is up to date.
Repository 'openSUSE-13.1-Oss' is up to date.
Repository 'openSUSE-13.1-Update' is up to date.
Repository 'openSUSE-13.1-Update-Non-Oss' is up to date.
All repositories have been refreshed.

例子6:修改zypper仓库

zypper仓库可以通过别名、数字或者URI或者通过‘–all、 –remote、 –local、 –medium-type’这些选项修改。

linux-xa3t:~ # zypper mr -d 6 #禁用6号仓库 linux-xa3t:~ # zypper mr -rk -p 70 upd #启用自动书信并为‘upd’仓库设置rpm文件‘缓存’,且设置它的优先级为70 linux-xa3t:~ # zypper mr -Ka #为所有的仓库禁用rpm文件缓存 linux-xa3t:~ # zypper mr -kt #为远程仓库设置rpm文件缓存

例子7:添加仓库

语法: zypper addrepo 或者 zypper ar <仓库的URL或者别名>

linux-xa3t:~ # zypper ar http://download.opensuse.org/update/13.1/ update
Adding repository 'update' .............................................[done]
Repository 'update' successfully added
Enabled: Yes
Autorefresh: No
GPG check: Yes
URI: http://download.opensuse.org/update/13.1/

例子8:移除仓库

语法: zypper removerepo <仓库名> <别名>

或者

zypper rr <仓库名> <别名>

linux-xa3t:~ # zypper rr openSUSE-13.1-1.10 openSUSE-13.1-1.10
Removing repository 'openSUSE-13.1-1.10' ............................[done]
Repository 'openSUSE-13.1-1.10' has been removed.

来源:https://linux.cn/article-4193-1.html

Linux:Mozilla推出首款为开发者打造的浏览器——火狐开发者专版

2004年11月9日,Firefox1.0正式发布。今年的11月9日,Firefox迎来了自己的十周岁生日。在庆祝Firefox十周年之际,Mozilla发布了Firefox开发者专版,这是首款专门为开发者打造的浏览器。

十年前,Mozilla为发烧友和开发者打造了 Firefox 火狐浏览器,旨在为他们提供更多的选择和控制权。Firefox整合了WebAPI和附加组件,让用户能够更好地与网络互动。然而,Web 的持续成功与开发者密不可分。无论是在手机上或是在电脑上,开发者们打造的内容和应用让大家乐于每天使用互联网。Firefox开发者专版是根据开发者每 天的浏览体验量身打造的,将为开发者提供他们开发所需的相关前沿和核心特性。

对开发者来说有一个最大的痛处是需要使用大量独立的开发环境来应对不同的应用商店或是打造不同的内容。基于这些原因,开发者经常需要在不同平台和浏览器中跳转,这不仅降低了工作效率,更让很多开发者感到沮丧。Firefox开发者专版通过打造一个焦点来让开发流程简单化。同时,这款浏览器是一个稳定的开发者 浏览器,不仅拥有强大的创作工具,也同样可以支持日常的浏览。

同时,它还添加了很多新的功能,简化了在多平台下Web开发的流程。

如果您是一位有经验的开发者,已经对安装的这些工具非常熟悉,可以启动浏览器并专注于开发自己的内容或应用。这里无需下载额外的插件或是应用来调试移动设备;如果您是一位Web开发新手,流线型的工作流和全部准备就绪的环境可以帮助您快速上手,开始打造一款复杂的应用。

这款浏览器中首先让开发者们注意到的可能是浏览器中独特的暗色调设计。浏览器中使用了简洁明了的开发者工具主题,为屏幕中的内容节省空间的同时,与应用开发工具保持统一的暗色外观。

Linux:Mozilla推出首款为开发者打造的浏览器——火狐开发者专版
Linux:Mozilla推出首款为开发者打造的浏览器——火狐开发者专版

这款开发者专版浏览器还整合了两个强大的新功能,Valence和WebIDE,帮助开发者改进工作流并能直接在Firefox 开发者专版中调试其他浏览器和应用。

Valence(之前称作Firefox工具适配器)让开发者可以通过连接Firefox开发者工具到其他主流浏览器的引擎来跨浏览器和设备进行开发和调试。Valence 还将Mozilla打造的用来调试FirefoxOS和Firefox for Android的工具延展到了包括Android上的Chrome以及 iOS上的Safari在内的其他主流移动浏览器中。这些工具目前包括查看器、调试器、控制台和样式编辑器。

WebIDE允许开发者直接在浏览器或是Firefox OS设备上开发、部署和调试Web应用。允许开发者从一个模 板创建一款Firefox OS应用(这是一款Web应用)或是打开已有应用的代码。在这里,开发者可以编辑应用文件,并通过一次点击让应用运行在模拟器 中,继而使用开发者工具进行进一步调试。

除此之外,Firefox开发者专版还包含了所有Web开发者们所熟悉的工具:

  • 响应式设备模式:无需改变浏览器窗口大小,即可查看网站或是Web应用在不同大小屏幕上的效果;
  • 页面查看器:检查网页中的HTML和CSS,简单的调整结构和页面布局;
  • Web控制台: 查看与网页相关的登录信息,在Web控制台中使用JavaScript与网页交互;
  • JavaScript调试器:一步步查看JavaScript代码,检查或修改状态,帮助追踪bug;
  • 网络监控器:查看浏览器中所有的网络请求,每个请求用时多久以及每个请求的具体内容;
  • 样式编辑器:查看和编辑与网页相关的CSS样式,创建新的网页,在任何页面中使用已有的CSS样式表;
  • Web音频编辑器:实时检查并与Web音频API交互,保证所有的音频节点都以预想的方式连接。

下载Firefox开发者专版:https://www.mozilla.org/en-US/firefox/developer/

来源:http://mozilla.com.cn/post/67840/

Linux:如何在Linux里使用xargs命令

你是否遇到过这样的情况,需要一遍又一遍地对多个文件执行同样的操作?如果有过,那你肯定会深有感触这是多么的无聊和效率低下。还好有种简单的方式,可以在基于Unix的操作系统中使用xargs命令解决这个烦恼。通过这个命令你可以有效地处理多个文件,节省你的时间和精力。在这篇教程中,你可以学到如何一次性对多个文件执行命令或脚本操作,再也不用担心像单独处理无数个日志或数据文件那样吓人的任务了。

Linux:如何在Linux里使用xargs命令
Linux:如何在Linux里使用xargs命令

xargs命令有两个要点。第一,你必须列出目标文件。第二,你必须指定对每个文件需要执行的命令或脚本。

这篇教程会涉及三个应用场景,xargs命令被用来处理分布在不同目录下的文件:

  1. 计算所有文件的行数
  2. 打印指定文件的第一行
  3. 对每个文件执行一个自定义脚本

请看下面这个叫xargstest的目录(用tree命令以及-i和-f选项显示了目录树结构,这样可以避免缩进显示而且每个文件都会带有完整路径):

$ tree -if xargstest/
Linux:如何在Linux里使用xargs命令
Linux:如何在Linux里使用xargs命令

这六个文件的内容分别如下:

Linux:如何在Linux里使用xargs命令
Linux:如何在Linux里使用xargs命令

这个xargstest目录,以及它包含的子目录和文件将用在下面的例子中。

场景1:计算所有文件的行数

就像之前提到的,使用xargs命令的第一个要点是一个用来运行命令或脚本的文件列表。我们可以用find命令来确定和列出目标文件。选项-name ‘file??’指定了xargstest目录下那些名字以”file”开头并跟随两个任意字符的文件才是匹配的。这个搜索默认是递归的,意思是find命令会在xargstest和它的子目录下搜索匹配的文件。

$ find xargstest/ -name 'file??'

xargstest/dir3/file3B
xargstest/dir3/file3A
xargstest/dir1/file1A
xargstest/dir1/file1B
xargstest/dir2/file2B
xargstest/dir2/file2A

我们可以通过管道把结果发给sort命令让文件名按顺序排列:

$ find xargstest/ -name 'file??' | sort

xargstest/dir1/file1A
xargstest/dir1/file1B
xargstest/dir2/file2A
xargstest/dir2/file2B
xargstest/dir3/file3A
xargstest/dir3/file3B

然后我们需要第二个要素,就是需要执行的命令。我们使用带有-l选项的wc命令来计算每个文件包含的换行符数目(会在输出的每一行的前面打印出来):

$ find xargstest/ -name 'file??' | sort | xargs wc -l

 1 xargstest/dir1/file1A
 2 xargstest/dir1/file1B
 3 xargstest/dir2/file2A
 4 xargstest/dir2/file2B
 5 xargstest/dir3/file3A
 6 xargstest/dir3/file3B
21 total

可以看到,不用对每个文件手动执行一次wc -l命令,而xargs命令可以让你在一步里完成所有操作。那些之前看起来无法完成的任务,例如单独处理数百个文件,现在可以相当轻松地完成了。

场景2:打印指定文件的第一行

既然你已经有一些使用xargs命令的基础,你可以自由选择执行什么命令。有时,你也许希望只对一部分文件执行操作而忽略其他的。在这种情况下,你可以使用find命令的-name选项以及?通配符(匹配任意单个字符)来选中特定文件并通过管道输出给xargs命令。举个例子,如果你想打印以“B”字符结尾的文件而忽略以“A”结尾的文件的第一行,可以使用下面的find、xargs和head命令组合来完成(head -n1会打印一个文件的第一行):

$ find xargstest/ -name 'file?B' | sort | xargs head -n1

==> xargstest/dir1/file1B <==
one
==> xargstest/dir2/file2B <==
one
==> xargstest/dir3/file3B <==
one

你将看到只有以“B”结尾的文件会被处理,而所有以“A”结尾的文件都被忽略了。

场景3:对每个文件执行一个自定义脚本

最后,你也许希望对一些文件执行一个自定义脚本(例如Bash、Python或是Perl)。要做到这一点,只要简单地用你的自定义脚本名字替换掉之前例子中的wc和head命令就好了:

$ find xargstest/ -name 'file??' | xargs myscript.sh

自定义脚本myscript.sh需要写成接受一个文件名作为参数并处理这个文件。上面的命令将为find命令找到的每个文件分别调用脚本。

注意一下上面的例子中的文件名并没有包含空格。通常来说,在Linux环境下操作没有空格的文件名会舒服很多。如果你实在是需要处理名字中带有空格的文件,上边的命令就不能用了,需要稍微处理一下来让它可以被接受。这可以通过find命令的-print0选项(它会打印完整的文件名到标准输出,并以空字符结尾),以及xargs命令的-0选项(它会以空字符作为字符串结束标记)来实现,就像下面的例子:

$ find xargstest/ -name 'file*' -print0 | xargs -0 myscript.sh

注意一下,-name选项所跟的参数已经改为'file*',意思是所有以"file"开头而结尾可以是任意字符的文件都会被选中。

总结

在看完这篇教程后你应该会理解xargs命令的作用,以及如何应用到自己的工作中。很快你就可以有时间享受这个命令所带来的高效率,而不用把你的时间耗费在一些重复的任务上了。想了解更详细的信息以及更多的选项,你可以在终端中输入'man xargs'命令来查看xargs的文档。


via: http://xmodulo.com/xargs-command-linux.html

作者:Joshua Reed 译者:zpl1025 校对:Caroline

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

来源:https://linux.cn/article-4212-1.html

Linux:使用 utmpdump 监控 CentOS 用户登录历史

保留、维护和分析日志(如某个特定时期内发生过的,或正在发生的帐号事件),是Linux系统管理员最基础和最重要的任务之一。对于用户管理,检查用户的登入和登出日志(不管是失败的,还是成功的)可以让我们对任何潜在的安全隐患或未经授权使用系统的情况保持警惕。例如,工作时间之外或放假期间的来自未知IP地址或帐号的远程登录应当发出红色警报。

Linux:使用 utmpdump 监控 CentOS 用户登录历史
Linux:使用 utmpdump 监控 CentOS 用户登录历史

在CentOS系统上,用户登录历史存储在以下这些文件中:

  • /var/run/utmp(用于记录当前打开的会话)被who和w工具用来记录当前有谁登录以及他们正在做什么,而uptime用来记录系统启动时间。
  • /var/log/wtmp (用于存储系统连接历史记录)被last工具用来记录最后登录的用户的列表。
  • /var/log/btmp(记录失败的登录尝试)被lastb工具用来记录最后失败的登录尝试的列表。

在本文中,我将介绍如何使用utmpdump,这个小程序来自sysvinit-tools包,可以用于转储二进制日志文件到文本格式的文件以便检查。此工具默认在CentOS 6和7系列上可用。utmpdump收集到的信息比先前提到过的工具的输出要更全面,这让它成为一个胜任该工作的很不错的工具。除此之外,utmpdump可以用于修改utmp或wtmp。如果你想要修复二进制日志中的任何损坏条目,它会很有用(LCTT 译注:我怎么觉得这像是做坏事的前奏?)。

Utmpdump的使用及其输出说明

正如我们之前提到的,这些日志文件,与我们大多数人熟悉的其它日志相比(如/var/log/messages,/var/log/cron,/var/log/maillog),是以二进制格式存储的,因而我们不能使用像less或more这样的文件命令来查看它们的内容。所以,utmpdump的出现拯救了世界。

为了要显示/var/run/utmp的内容,请运行以下命令:

# utmpdump /var/run/utmp

同样要显示/var/log/wtmp的内容:

# utmpdump /var/log/wtmp | tail -15
Linux:使用 utmpdump 监控 CentOS 用户登录历史
Linux:使用 utmpdump 监控 CentOS 用户登录历史

最后,对于/var/log/btmp:

# utmpdump /var/log/btmp

正如你所能看到的,三种情况下的输出结果是一样的,除了utmp和btmp的记录是按时间排序,而wtmp的顺序是颠倒的这个原因外(LCTT 译注:此处原文有误,实际上都是按照时间顺序排列的)。

每个日志行格式化成了多列,说明如下。第一个字段显示了会话识别符,而第二个字段则是PID。第三个字段可以是以下值:–(表示运行等级改变或系统重启),bw(启动守候进程),数字(表示TTY编号),或者字符和数字(表示伪终端)。第四个字段可以为空或用户名、重启或运行级别。第五个字段是主TTY或PTY(伪终端),如果此信息可获得的话。第六个字段是远程主机名(如果是本地登录,该字段为空,运行级别信息除外,它会返回内核版本)。第七个字段是远程系统的IP地址(如果是本地登录,该字段为0.0.0.0)。如果没有提供DNS解析,第六和第七字段会显示相同的信息(远程系统的IP地址)。最后一个(第八)字段指明了该记录创建的日期和时间。

Utmpdump使用样例

下面提供了一些utmpdump的简单使用情况。

1、 检查8月18日到9月17日之间某个特定用户(如gacanepa)的登录次数。

# utmpdump /var/log/wtmp | grep gacanepa

如果你需要回顾先前日期的登录信息,你可以检查/var/log下的wtmp-YYYYMMDD(或wtmp.[1…N])和btmp-YYYYMMDD(或btmp.[1…N])文件,这些是由logrotate生成的旧wtmp和btmp的归档文件。

2、 统计来自IP地址192.168.0.101的登录次数。

# utmpdump /var/log/wtmp | grep 192.168.0.101

3、 显示失败的登录尝试。

# utmpdump /var/log/btmp

在/var/log/btmp输出中,每个日志行都与一个失败的登录尝试相关(如使用不正确的密码,或者一个不存在的用户ID)。上面图片中高亮部分显示了使用不存在的用户ID登录,这警告你有人尝试猜测常用帐号名来闯入系统。这在使用tty1的情况下是个极其严重的问题,因为这意味着某人对你机器上的终端具有访问权限(该检查一下谁拿到了进入你数据中心的钥匙了,也许吧?)

4、 显示每个用户会话的登入和登出信息

# utmpdump /var/log/wtmp

在/var/logwtmp中,一次新的登录事件的特征是,第一个字段为‘7’,第三个字段是一个终端编号(或伪终端id),第四个字段为用户名。相关的登出事件会在第一个字段显示‘8’,第二个字段显示与登录一样的PID,而终端编号字段空白。例如,仔细观察上面图片中PID 1463的行。

  • 在 [Fri Sep 19 11:57:40 2014 ART],TTY1上显示登录提示符。
  • 在 [Fri Sep 19 12:04:21 2014 ART],用户 root 登入。
  • 在 [Fri Sep 19 12:07:24 2014 ART],用户 root 登出。

旁注:第四个字段的LOGIN意味着出现了一次登录到第五字段指定的终端的提示。

到目前为止,我介绍一些有点琐碎的例子。你可以将utmpdump和其它一些文本处理工具,如awk、sed、grep或cut组合,来产生过滤和加强的输出。

例如,你可以使用以下命令来列出某个特定用户(如gacanepa)的所有登录事件,并发送输出结果到.csv文件,它可以用像LibreOffice Calc或Microsoft Excel之类的文字或工作簿应用程序打开查看。让我们只显示PID、用户名、IP地址和时间戳:

 # utmpdump /var/log/wtmp | grep -E "[7].*gacanepa" | awk -v OFS="," 'BEGIN {FS="] "}; {print $2,$4,$7,$8}' | sed -e 's/[//g' -e 's/]//g'

就像上面图片中三个高亮区域描绘的那样,过滤逻辑操作是由三个管道步骤组成的。第一步用于查找由用户gacanepa触发的登录事件([7]);第二步和第三部用于选择期望的字段,移除utmpdump输出的方括号并设置输出字段分隔符为逗号。

当然,如果你想要在以后打开来看,你需要重定向上面的命令输出到文件(添加“>[文件名].csv”到命令后面)。

Linux:使用 utmpdump 监控 CentOS 用户登录历史
Linux:使用 utmpdump 监控 CentOS 用户登录历史

在更为复杂的例子中,如果你想要知道在特定时间内哪些用户(在/etc/passwd中列出)没有登录,你可以从/etc/passwd中提取用户名,然后运行grep命令来获取/var/log/wtmp输出中对应用户的列表。就像你看到的那样,有着无限可能。

在进行总结之前,让我们简要地展示一下utmpdump的另外一种使用情况:修改utmp或wtmp。由于这些都是二进制日志文件,你不能像编辑文件一样来编辑它们。取而代之是,你可以将其内容输出成为文本格式,并修改文本输出内容,然后将修改后的内容导入回二进制日志中。如下:

# utmpdump /var/log/utmp > tmp_output
<使用文本编辑器修改 tmp_output>
# utmpdump -r tmp_output > /var/log/utmp

这在你想要移除或修复二进制日志中的任何伪造条目时很有用。

下面小结一下,utmpdump从utmp、wtmp和btmp日志文件或轮循的旧归档文件来读取详细的登录事件,来补充如who,w,uptime,last,lastb之类的标准工具的不足,这也使得它成为一个很棒的工具。

你可以随意添加评论以加强本帖的含金量。


via: http://xmodulo.com/2014/09/monitor-user-login-history-centos-utmpdump.html

作者:Gabriel Cánepa 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-4213-1.html

Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机

利用当代神奇设备来重温80年代的黄金记忆。

你需要以下硬件

  • 一台树莓派以及一张4GBSD卡
  • 一台支持HDMI的LCD显示屏
  • 游戏手柄或者…
  • 一个JAMMA街机游戏机外壳机箱
  • J-Pac或者I-Pac

80年代有太多难忘的记忆;冷战结束,Quatro碳酸饮料,Korg Polysix合成器,以及Commodore 64家用电脑。但对于某些年轻人来说,这些都没有街机游戏机那样有说服力,或那种甜蜜的叛逆。笼罩着烟味和此起彼伏的8比特音效,它们就是在挤出来的时间里去探索的洞穴:50分钱和一个游戏币能让你消耗整个午餐时间,在这些游戏上磨练着你的技能:小蜜蜂,城市大金刚,蜈蚣,行星射击,吃豆小姐,火凤凰,R-Rype,大金刚,雷霆计划,铁手套,街头霸王,超越赛车,防卫者争战…噢,这个列表太长了。

这些游戏,以及玩这些游戏的街机机器,仍然像30年前那样有吸引力。不像年轻时候那样,现在可以不用装一兜零钱就能玩了,最终让你超越那些有钱的孩子以及他们无休止的‘继续游戏’。所以是时候打造一个你自己的基于Linux的街机游戏机了,然后挑战一下过去的最高分。

我们将会包括所有的步骤,来将一个便宜的街机游戏机器外壳变成一台Linux驱动的多平台复古游戏系统。但是这并不意味着你就一定要搭建一个同样的系统。比如说,你可以放弃那个又大又重还有潜在致癌性外壳的箱子本身,而是将内部控制核心装进一个旧游戏主机或同等大小的盒子里。或者说,你也可以简单地放弃小巧的树莓派,而将系统的大脑换成一台更强劲的Linux主机。举个例子,它可以作为运行SteamOS的一个理想平台,用来玩那些更优秀的现代街机游戏。

在之后的几个页面里,我们将搭建一台基于树莓派的街机游戏机,你应该也能从其中发现很多点子应用到你自己的项目上,即使它们和我们这个项目不太一样。然后因为我们是用无比强大的MAME来做这件事情,你几乎可以让它在任意平台上运行。

Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机
Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机

我们是在B+型号出来以前完成的这个项目。它应该也可以同样工作在更新的主板上,你应该不用一个带电源的USB Hub也可以

声明

强调一下,我们捣腾的电子器件可能会让你受到电击。请确保你做的任何改动都是有资质的电子工程师帮你检查过的。我们也不会深入讨论如何获取游戏,但是有很多合法的资源,例如基于MAME模拟器的老游戏,以及较新的商业游戏。

第一步:街机机柜

街机机柜本身就是最大的挑战。我们在eBay上淘了个二手的90年代初的双人泡泡龙游戏机。然后花了£220装在一台旅行车后面送过来。类似这种机柜的价格并不确定。我们看到过很多在£100以内的。而另一方面,还有很多人愿意花数千块钱去买原版侧面贴纸完整的机器。

决定买一个街机机柜,主要有两个考虑。第一个是它的体积:这东西又大又重。又占地方,而且需要至少两个人才能搬动。如果你不缺钱的话,还可以买DIY机柜或者全新的小一点的,例如适合摆在桌子上的那种。然后,酒柜也能很合适。

Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机
Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机

这种机柜可能很便宜,但是他们都很重。不要一个人去搬。一些更古老的机器可能还会需要一点小关怀,例如重新喷个漆以及一些修理工作

除了获得更加真实的游戏体验以外,购买原版的街机机柜的一个绝佳理由是可以使用原版的控制器。从eBay上买到的大多数机器都支持两个人同时玩,有两个摇杆以及每个玩家各自的一些按钮,再加上玩家一和玩家二的选择按钮。为了兼容更多游戏,我们建议您找一台每个玩家都有6个按键的型号,这个是通用配置。也许你还想看看支持超过两位玩家的控制台,或者有空间放其他游戏控制器的,比如说街机轨迹球(类似疯狂弹珠这种游戏需要的),或者一个旋钮(打砖块)。这些待会都可以轻松装上去,因为有现成的现代USB设备。

控制器是第二考虑的,而且我们认为是最重要的,因为要通过它把你的摇动和拍打转变成游戏里的动作。当你准备买一个机柜时需要考虑一种叫JAMMA的东西,它是日本娱乐机械制造商协会(Japan Amusement Machinery Manufacturers Association)的缩写。JAMMA是街机游戏机里的行业标准,定义了包含游戏芯片的电路板和游戏控制器的连接方式,以及投币机制。它是一个连接两个玩家的摇杆和按钮的所有线缆的接口电路,把它们统一到一个标准的连接头。JAMMA就是这个连接头的大小以及引脚定义,这就意味着不管你安装的主板是什么,按钮和控制器都将会连接到相同功能接口,所以街机的主人只需要再更换下机柜上的外观图片,就可以招揽新玩家了。

但是首先,提醒一下:JAMMA连接头上带有12V电压供电,通常由大多数街机里都有的电源模块供给。为了避免意外短路或是不小心掉个螺丝刀什么的造成损坏,我们完全切断了这个供电。在本教程后面的任何阶段,我们也不会用到这个连接头上的任何电源脚。

Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机
Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机

第二步:J-PAC

有一点非常方便,你可以买到这样一种设备,连接街机机柜里的JAMMA接头和电脑的USB端口,将机柜上的摇杆和按键动作都转换成(可配置的)键盘命令,它们可以在Linux里用来控制任何想玩的游戏。这个设备就叫J-Pac(www.ultimarc.com/jpac.html – 大概£54)。

它最大的特点不是它的连接性;而是它处理和转换输入信号的方式,因为它比标准的USB手柄强太多太多了。每一个输入都有自己独立的中断,而且没有限制同时按下或按住的按钮或摇杆方向的数量。这对于类似街头霸王的游戏来说非常关键,因为他们依赖于同时迅速按下的组合键,而且用来对那些发飙后按下自己所有按键的不良对手发出致命一击时也必不可少。许多其他控制器,特别是那些生成键盘输入的,受到了他们所采用的USB控制器的同时六个输入的限制,以及一堆的Alt,Shift和Ctrl键的特殊处理的限制。J-Pac还可以接入倾角传感器,甚至某些投币装置,不用预先配置就可以在Linux下工作了。

另外的选择是一个类似的叫I-Pac的设备。它做了和J-Pac相同的事情,只不过不支持JAMMA接头。这意味着你不能把JAMMA控制器接上去,但同时也就是说你可以设计你自己的控制器布局,再把每个控制接到I-Pac上去。这对第一个项目来说也许有点小难,但是这却是许多街机迷们选择的方式,特别是他们想设计一个支持四个玩家的控制板的时候,或者是一个整合许多不同类型控制的面板的时候。我们采用的方式并不是我们推荐必须要做的,我们改造了一个输入有问题的二手X-Arcade Tankstick控制面板,换上了新的摇杆和按钮,再接到新的JAMMA接口,这样有一个非常好的地方就是可以用便宜的价格(£8)买到所有用到的线材包括电路板边缘插头。

Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机
Linux:给那些怀旧的游戏骨灰粉丝们:自制一台树莓派街机

上图是我们已经装到机柜上的J-Pac。右边的蓝色和红色导线接到我们的机柜上额外的1号和2号玩家按钮

不管你选择的是I-Pac或是J-Pac,它们产生的按键都是MAME的默认值。也就是说运行模拟器之后不需要手动调整输入。例如玩家1,会默认将键盘方向键映射成上下左右,以及将左边的Ctrl,左边的ALT,空格和左边的Shift键映射到按钮1-4。但是真正实用的功能是,对于我们来说,是双键快捷方式。当按下并按住玩家1按钮后,就可以通过把玩家1的摇杆拉到下的位置发出用来暂停游戏的P按键,推到上的位置调整音量,以及推到右的位置来进入MAME自己的设置界面。这些特殊组合键设计的很巧妙,不会对正常玩游戏带来任何干扰,因为他们只有在按住玩家1按钮后才会生效,然后可以让你正在运行游戏的时候也能做任何需要的事情。例如,你可以完全地重新配置MAME,使用它自己的菜单,在玩游戏的时候改变输入绑定和灵敏度。

最后,按住玩家1按钮然后按下玩家2按钮就可以退出MAME,如果你使用了启动菜单或MAME管理器的话就很有用了,因为他们会自动启动游戏,然后你就可以用最快的速度开始玩另一个游戏了。

对于显示屏我们采取了比较保守的方式,拿掉了街机原装的笨重的而且已经坏掉的CRT,换成一个低成本的LCD显示器。这样做有很多好处。首先,这个显示器有HDMI接口,这样他就可以轻易地直接连接到树莓派或是现代的显卡上。第二,你也不用去设定驱动街机屏幕所需要的低频率刷新模式,也不需要驱动它的专用图形硬件。第三,这也是最安全的方式,因为街机屏幕往往在机身背后没有保护措施,让很高的电压离你的手只有几英寸的距离。也不是说你完全不能用CRT,如果那就是你追求的体验的话 – 这也是获得所追求的游戏体验的最真实的方式,但是我们在软件里充分细调了CRT模拟部分,我们对输出已经很满意了,而且不需要用那个古老的CRT更是让我们高兴。

你也许还需要考虑用一个老式的4:3长宽比的LCD,而不是那种宽屏的现代产品,因为4:3模式用来玩竖屏或横屏的游戏更实用。比如说玩竖屏的射击游戏,例如雷电,如果使用宽屏显示器的话,会在屏幕两边都有一个黑条。这些黑条一般会用来显示一些游戏指引,或者你也可以把屏幕翻转90度,这样就可以用上每个像素了,但这却不实用,除非你只玩竖屏游戏或者有一个容易操作的旋转支座。

装载显示屏也很重要。如果你拿掉了CRT的话,没有现成的地方安装LCD。我们的方式是买了一些中密度纤维板(MDF)并切割成适合原来摆放CRT的地方。固定以好,我们把一个便宜的VESA支座放在中间。VESA底座可以用来挂载大多数屏幕,大的或小的。最后,因为我们的机柜前面有烟玻璃,我们必须保证亮度和对比度都设置的足够高。

来源:https://linux.cn/article-4214-1.html

Linux:Ansible :一个配置管理和IT自动化工具

Linux:Ansible :一个配置管理和IT自动化工具
Linux:Ansible :一个配置管理和IT自动化工具

今天我来谈谈 ansible,一个由 Python 编写的强大的配置管理解决方案。尽管市面上已经有很多可供选择的配置管理解决方案,但他们各有优劣,而 ansible 的特点就在于它的简洁。让 ansible 在主流的配置管理系统中与众不同的一点便是,它并不需要你在想要配置的每个节点上安装自己的组件。同时提供的一个优点在于,如果需要的话,你可以在不止一个地方控制你的整个基础架构。最后一点是它的正确性,或许这里有些争议,但是我认为在大多数时候这仍然可以作为它的一个优点。说得足够多了,让我们来着手在 RHEL/CentOS 和基于 Debian/Ubuntu 的系统中安装和配置 Ansible。

准备工作

  1. 发行版:RHEL/CentOS/Debian/Ubuntu Linux
  2. Jinja2:Python 的一个对设计师友好的现代模板语言
  3. PyYAML:Python 的一个 YAML 编码/反编码函数库
  4. paramiko:纯 Python 编写的 SSHv2 协议函数库 (译者注:原文对函数库名有拼写错误)
  5. httplib2:一个功能全面的 HTTP 客户端函数库
  6. 本文中列出的绝大部分操作已经假设你将在 bash 或者其他任何现代的 shell 中以 root 用户执行。

Ansible 如何工作

Ansible 工具并不使用守护进程,它也不需要任何额外的自定义安全架构,因此它的部署可以说是十分容易。你需要的全部东西便是 SSH 客户端和服务器了。

 +-----------------+                    +---------------+
 |安装了 Ansible 的|       SSH          | 文件服务器1   |
 |Linux/Unix 工作站|<------------------>| 数据库服务器2 | 在本地或远程
 +-----------------+       模块         | 代理服务器3   | 数据中心的
    192.168.1.100                       +---------------+ Unix/Linux 服务器

其中:

  1. 192.168.1.100 – 在你本地的工作站或服务器上安装 Ansible。
  2. 文件服务器1到代理服务器3 – 使用 192.168.1.100 和 Ansible 来自动管理所有的服务器。
  3. SSH – 在 192.168.1.100 和本地/远程的服务器之间设置 SSH 密钥。

Ansible 安装教程

ansible 的安装轻而易举,许多发行版的第三方软件仓库中都有现成的软件包,可以直接安装。其他简单的安装方法包括使用 pip 安装它,或者从 github 里获取最新的版本。若想使用你的软件包管理器安装,在基于 RHEL/CentOS Linux 的系统里你很可能需要 EPEL 仓库

在基于 RHEL/CentOS Linux 的系统中安装 ansible

输入如下 yum 命令:

$ sudo yum install ansible

在基于 Debian/Ubuntu Linux 的系统中安装 ansible

输入如下 apt-get 命令:

$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible

使用 pip 安装 ansible

pip 命令是一个安装和管理 Python 软件包的工具,比如它能管理 Python Package Index 中的那些软件包。如下方式在 Linux 和类 Unix 系统中通用:

$ sudo pip install ansible

从源代码安装最新版本的 ansible

你可以通过如下命令从 github 中安装最新版本:

$ cd ~
$ git clone git://github.com/ansible/ansible.git
$ cd ./ansible
$ source ./hacking/env-setup

当你从一个 git checkout 中运行 ansible 的时候,请记住你每次用它之前都需要设置你的环境,或者你可以把这个设置过程加入你的 bash rc 文件中:

# 加入 BASH RC
$ echo "export ANSIBLE_HOSTS=~/ansible_hosts" >> ~/.bashrc
$ echo "source ~/ansible/hacking/env-setup" >> ~/.bashrc

ansible 的 hosts 文件包括了一系列它能操作的主机。默认情况下 ansible 通过路径 /etc/ansible/hosts 查找 hosts 文件,不过这个行为也是可以更改的,这样当你想操作不止一个 ansible 或者针对不同的数据中心的不同客户操作的时候也是很方便的。你可以通过命令行参数 -i 指定 hosts 文件:

$ ansible all -m shell -a "hostname" --ask-pass -i /etc/some/other/dir/ansible_hosts

不过我更倾向于使用一个环境变量,这可以在你想要通过 source 一个不同的文件来切换工作目标的时候起到作用。这里的环境变量是 $ANSIBLE_HOSTS,可以这样设置:

$ export ANSIBLE_HOSTS=~/ansible_hosts

一旦所有需要的组件都已经安装完毕,而且你也准备好了你的 hosts 文件,你就可以来试一试它了。为了快速测试,这里我把 127.0.0.1 写到了 ansible 的 hosts 文件里:

$ echo "127.0.0.1" > ~/ansible_hosts

现在来测试一个简单的 ping:

$ ansible all -m ping

或者提示 ssh 密码:

$ ansible all -m ping --ask-pass

我在刚开始的设置中遇到过几次问题,因此这里强烈推荐为 ansible 设置 SSH 公钥认证。不过在刚刚的测试中我们使用了 –ask-pass,在一些机器上你会需要安装 sshpass 或者像这样指定 -c paramiko:

$ ansible all -m ping --ask-pass -c paramiko

当然你也可以安装 sshpass,然而 sshpass 并不总是在标准的仓库中提供,因此 paramiko 可能更为简单。

来源:https://linux.cn/article-4215-1.html

Linux:安装完Ubuntu14.10后要做的7件事

1.看看有哪些新东西

虽然Ubuntu 14.10并没有带来特别重大的新功能,但是依然有值得期待的地方,Mozilla Firefox, Thunderbird,LibreOffice都升级到了新的版本,或许你可以看下他们与之前的版本有什么不同。

Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

2.自定义你的桌面

每一个新版本的Ubuntu发布都会带来新的壁纸,你可以试下这些新的壁纸,并将自己喜欢的设置为桌面。也可以根据自己的喜好设置窗口菜单的位置,是否隐藏unity边栏,开机是否自动登录等等。

Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

3.安装显卡驱动

Ubuntu默认的显卡驱动虽然可以让你的计算机显示毫无问题,但是要想发挥显卡的全部性能,就需要安装专有驱动了,别紧张,你只需要在软件和更新里的驱动列表选择合适的驱动安装即可。

Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

4.安装音视频解码器

由于版权原因,Ubuntu并不会直接内置一些音视频解码器,这些需要用户独立安装,你可以在软件中心或者通过下载软件包来安装解码器。

 Ubuntu restricted extras

5.安装flash支持

Firefox浏览器默认是没有flash支持的所以为了能够在线观看视频则需要安装flash软件,在软件中心搜索flash安装即可。

Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

6.设置你的隐私

由于Ubuntu默认会提供在线的搜索结果,同时也会提交一些信息到服务器上,所以对于比较注重隐私的小伙伴则可以在设置里取消提交系统使用信息,同时也可以设置在Dash主页里不显示最近实用的内容(包括文档,图片,音乐等)。

Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

7.安装常用应用

下面是一些常用应用的推荐方案:

  • 视频播放:VLC
  • 游戏客户端:Steam
  • 图片编辑:Gimp
  • 浏览器:Chrome/Chromium
  • 音乐播放器:深度音乐播放器
  • 下载工具:Uget
  • 输入法:搜狗拼音输入法for Linux
Linux:安装完Ubuntu14.10后要做的7件事
Linux:安装完Ubuntu14.10后要做的7件事

经过了以上的步骤,我们就可以愉快的玩耍Ubuntu了。

来源:http://muzi.info/2014/2393/7-things-ubuntu-14-10.html

Linux:在Linux中使用Openswan搭建站点到站点的IPsec VPN 隧道

虚拟私有网络(VPN)隧道是通过Internet隧道技术将两个不同地理位置的网络安全的连接起来的技术。当两个网络是使用私有IP地址的私有局域网络时,它们之间是不能相互访问的,这时使用隧道技术就可以使得两个子网内的主机进行通讯。例如,VPN隧道技术经常被用于大型机构中不同办公区域子网的连接。

有时,使用VPN隧道仅仅是因为它很安全。服务提供商与公司会使用这样一种方式架设网络,他们将重要的服务器(如,数据库,VoIP,银行服务器)放置到一个子网内,仅仅让有权限的用户通过VPN隧道进行访问。如果需要搭建一个安全的VPN隧道,通常会选用IPsec,因为IPsec VPN隧道被多重安全层所保护。

Linux:在Linux中使用Openswan搭建站点到站点的IPsec VPN 隧道
Linux:在Linux中使用Openswan搭建站点到站点的IPsec VPN 隧道

这篇指导文章将会告诉你如何构建站点到站点的 VPN隧道。

拓扑结构

这边指导文章将按照以下的拓扑结构来构建一个IPsec 隧道。

安装软件包以及准备VPN服务器

一般情况下,你仅能管理A点,但是根据需求,你可能需要同时管理A点与B点。我们从安装Openswan软件开始。

基于Red Hat的系统(CentOS,Fedora,或RHEL):

# yum install openswan lsof

在基于Debian的系统(Debian,Ubuntu或Linux Mint):

# apt-get install openswan

现在禁用VPN的重定向功能,如果有服务器,可以执行下列命令:

# for vpn in /proc/sys/net/ipv4/conf/*;
# do echo 0 > $vpn/accept_redirects;
# echo 0 > $vpn/send_redirects;
# done

接下来,允许IP转发并且禁重定向功能。

 # vim /etc/sysctl.conf

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

重加载 /etc/sysctl.conf文件:

 # sysctl -p

在防火墙中启用所需的端口,并保证不与系统当前的规则冲突。

# iptables -A INPUT -p udp --dport 500 -j ACCEPT
# iptables -A INPUT -p tcp --dport 4500 -j ACCEPT
# iptables -A INPUT -p udp --dport 4500 -j ACCEPT

最后,我们为NAT创建防火墙规则。

 # iptables -t nat -A POSTROUTING -s site-A-private-subnet -d site-B-private-subnet -j SNAT --to site-A-Public-IP

请确保上述防火墙规则是持久有效的(LCTT 译注:你可以save这些规则或加到启动脚本中)。

注意:

  • 你可以使用MASQUERAD替代SNAT(iptables)。理论上说它也能正常工作,但是有可能会与VPS发生冲突,所以我仍然建议使用SNAT。
  • 如果你同时在管理B点,那么在B点也设置同样的规则。
  • 直连路由则不需要SNAT。

准备配置文件

我们将要用来配置的第一个文件是ipsec.conf。不论你将要配置哪一台服务器,总是将你这端的服务器看成是左边的,而将远端的看作是右边的。以下配置是在站点A的VPN服务器做的。

# vim /etc/ipsec.conf

## general configuration parameters ##
config setup
        plutodebug=all
        plutostderrlog=/var/log/pluto.log
        protostack=netkey
        nat_traversal=yes
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/16
        ## disable opportunistic encryption in Red Hat ##
        oe=off
## disable opportunistic encryption in Debian ##
## Note: this is a separate declaration statement ##
include /etc/ipsec.d/examples/no_oe.conf
## connection definition in Red Hat ##
conn demo-connection-redhat
        authby=secret
        auto=start
        ike=3des-md5
        ## phase 1 ##
        keyexchange=ike
        ## phase 2 ##
        phase2=esp
        phase2alg=3des-md5
        compress=no
        pfs=yes
        type=tunnel
        left=
        leftsourceip=
        leftsubnet=/netmask
        ## for direct routing ##
        leftsubnet=/32
        leftnexthop=%defaultroute
        right=
        rightsubnet=/netmask
## connection definition in Debian ##
conn demo-connection-debian
        authby=secret
        auto=start
        ## phase 1 ##
        keyexchange=ike
        ## phase 2 ##
        esp=3des-md5
        pfs=yes
        type=tunnel
        left=
        leftsourceip=
        leftsubnet=/netmask
        ## for direct routing ##
        leftsubnet=/32
        leftnexthop=%defaultroute
        right=
        rightsubnet=/netmask

有许多方式实现身份验证。这里使用预共享密钥,并将它添加到文件 /etc/ipsec.secrets。

 # vim /etc/ipsec.secrets

siteA-public-IP  siteB-public-IP:  PSK  "pre-shared-key"
## in case of multiple sites ##
siteA-public-IP  siteC-public-IP:  PSK  "corresponding-pre-shared-key"

来源:https://linux.cn/article-4224-1.html

Linux:Linux 有问必答:在 Linux 如何更改文本文件的字符编码

问题:在我的 Linux 系统中有一个编码为 iso-8859-1 的字幕文件,其中部分字符无法正常显示,我想把文本改为 utf8 编码。在 Linux 中, 有没有一个好的工具来转换文本文件的字符编码?

正如我们所知道的那样,电脑只能够处理低级的二进制值,并不能直接处理字符。当一个文本文件被存储时,文件中的每一个字符都被映射成二进制值,实际存储在硬盘中的正是这些“二进制值”。之后当程序打开文本文件时,所有二进制值都被读入并映射回原始的可读字符。只有当所有需要访问这个文件的程序都能够“理解”它的编码,即二进制值到字符的映射时,这个“保存和打开”的过程才能很好地完成,这也确保了可理解数据的往返过程。

如果不同的程序使用不同的编码来处理同一个文件,源文件中的特殊字符就无法正常显示。这里的特殊字符指的是非英文字母的字符,例如带重音的字符(比如 ñ,á,ü)。

然后问题就来了: 1)我们如何确定一个确定的文本文件使用的是什么字符编码? 2)我们如何把文件转换成已选择的字符编码?

Linux:Linux 有问必答:在 Linux 如何更改文本文件的字符编码
Linux:Linux 有问必答:在 Linux 如何更改文本文件的字符编码

步骤一

为了确定文件的字符编码,我们使用一个名为 “file” 的命令行工具。因为 file 命令是一个标准的 UNIX 程序,所以我们可以在所有现代的 Linux 发行版中找到它。

运行下面的命令:

$ file --mime-encoding filename

步骤二

下一步是查看你的 Linux 系统所支持的文件编码种类。为此,我们使用名为 iconv 的工具及 “-l” 选项(L 的小写)来列出所有当前支持的编码。

$ iconv -l

iconv 工具是 GNU libc 库组成部分,因此它在所有 Linux 发行版中都是开箱即用的。

步骤三

在我们在我们的 Linux 系统所支持的编码里面选定了目标编码之后,运行下面的命令来完成编码转换:

$ iconv -f old_encoding -t new_encoding filename

例如,把 iso-8859-1 编码转换为 utf-8 编码:

$ iconv -f iso-8859-1 -t utf-8 input.txt

了解了我们演示的如何使用这些工具之后,你可以像下面这样修复一个受损的字幕文件:

Linux:Linux 有问必答:在 Linux 如何更改文本文件的字符编码
Linux:Linux 有问必答:在 Linux 如何更改文本文件的字符编码

via: http://ask.xmodulo.com/change-character-encoding-text-file-linux.html

译者:wangjiezhe 校对:wxy

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

来源:https://linux.cn/article-4225-1.html

Linux:Linux有问必答:如何修复“sshd error: could not load host key”

问题:当我尝试SSH到一台远程服务器时,SSH客户端登陆失败并提示“Connection closed by X.X.X.X”。在SSH服务器那端,我看到这样的错误消息:“sshd error: could not load host key.”。这发生了什么问题,我怎样才能修复该错误?

该SSH连接错误的详细症状如下。

SSH客户端方面:当你尝试SSH到一台远程主机时,你没有看见登录屏幕,你的SSH连接就立即关闭,并提示此消息:“Connection closed by X.X.X.X”。

SSH服务器方面:在系统日志中,你看到如下错误消息(如,在Debian/Ubuntu上,/var/log/auth.log)。

Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_rsa_key
Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_dsa_key
Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Oct 16 08:59:45 openstack sshd[1214]: fatal: No supported key exchange algorithms [preauth]

导致该问题的根源是,sshd守护进程不知怎么地不能加载SSH主机密钥了。

当OpenSSH服务器第一次安装到Linux系统时,SSH主机密钥应该会自动生成以供后续使用。如果,不管怎样,密钥生成过程没有成功完成,那就会导致这样的SSH登录问题。

Linux:Linux有问必答:如何修复“sshd error: could not load host key”
Linux:Linux有问必答:如何修复“sshd error: could not load host key”

让我们检查能否在相应的地方找到SSH主机密钥。

$ ls -al /etc/ssh/ssh*key

如果SSH主机密钥在那里找不到,或者它们的大小被截断成为0(就像上面那样),你需要从头开始重新生成主机密钥。

重新生成SSH主机密钥

在Debian、Ubuntu或其衍生版上,你可以使用dpkg-reconfigure工具来重新生成SSH主机密钥,过程如下:

$ sudo rm -r /etc/ssh/ssh*key
$ sudo dpkg-reconfigure openssh-server

在CentOS、RHEL或Fedora上,你所要做的是,删除现存(有问题的)密钥,然后重启sshd服务。

$ sudo rm -r /etc/ssh/ssh*key
$ sudo systemctl restart sshd

另外一个重新生成SSH主机密钥的方式是,使用ssh-keygen命令来手动生成。

$ sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
$ sudo ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
$ sudo ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
Linux:Linux有问必答:如何修复“sshd error: could not load host key”
Linux:Linux有问必答:如何修复“sshd error: could not load host key”

在生成新的SSH主机密钥后,确保它们能在/etc/ssh目录中找到。此时,不必重启sshd服务。

 $ ls -al /etc/ssh/ssh*key

现在,再试试SSH到SSH服务器吧,看看问题是否已经离你而去了。


via: http://ask.xmodulo.com/sshd-error-could-not-load-host-key.html

译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-4226-1.html

Linux:Nginx PageSpeed模块配置和使用

Google Pagespeed在作为一个Nginx的模块在研发这么久之后仍是beta版本,着实有点尴尬,不过也证明了该项目是成功的,最起码它仍在迭代,实际上在使用中,我们也碰到一些非模块本身的问题,譬如当它基于反向代理时模板的寻址,图片的URL重写…为此不得不对其做一些配置让它不是看起来多了一个协议,而是真正的能对页面的细节进行优化,最大限度的压榨服务器的的性能提高用户访问速度..

Linux:Nginx PageSpeed模块配置和使用
Linux:Nginx PageSpeed模块配置和使用

在实际使用中,它能够带来什么

    1、优化缓存并整合应用程序的数据和逻辑    2、优化往返请求,降低请求开销,降低响应页面大小    3、对CSS Javascript 进行合并,这里相对来说要慎用(需要前期测试)    4、DNS预加载,延时加载图片等过滤器的支持(赞)    5、等等(少说多做)

 

首先是我的目录结构

    ###其他目录不作解释,source 目录即所有源码包的路径###
    [root@ipython software]# ls /software/
    mysql nginx php readme.txt sharelib source var_temp
    ###库文件的支持###
    [root@ipython software]# ls /software/sharelib/
    curl freetype gd google-libunwind google-perftools libiconv libjpeg libmcrypt libpng libtool libxml2 mhash ncurses openssl pcre zlib
    Nginx版本:
    [root@ipython software]# curl -I 127.0.0.1
    HTTP/1.1 200 OK
    Server: nginx/1.7.5
    Date: Fri, 07 Nov 2014 14:26:25 GMT
    Content-Type: text/html
    Connection: keep-alive
    Vary: Accept-Encoding

 

下载地址和参考地址(墙内就不建议点了):

ngx-pagespeed for github

[root@ipython source]# wget https://github.com/pagespeed/ngx_pagespeed/archive/release-1.9.32.1-beta.zip

 ngx-pagespeed optimization library

[root@ipython source]# wget https://dl.google.com/dl/page-speed/psol/1.9.32.1.tar.gz

ngx-pagespeed official

http://ngxpagespeed.com/ngx_pagespeed_example/

GoogleDevelopers

https://developers.google.com/speed/docs/mod_pagespeed/build_ngx_pagespeed_from_source

 

开始编译Ngx-pagespeed

    ###解开程序包--我在写这篇文章的时候,它似乎已经又更新了...建议参考的同学使用最新版###
    [root@ipython source]# unzip release-1.9.32.1-beta
    [root@ipython source]# cd ngx_pagespeed-release-1.9.32.1-beta/
    ##将pagespeed 的优化库解压至当前目录##
    [root@ipython ngx_pagespeed-release-1.9.32.1-beta]# tar zxf ../1.9.32.1.tar.gz -C ./
    ##此刻你的目录路径应该是这样的##
    [root@ipython ngx_pagespeed-release-1.9.32.1-beta]# ls
    config cpp_feature LICENSE psol README.md scripts src test
    ##重新编译nginx##
    [root@ipython ngx_pagespeed-release-1.9.32.1-beta]# cd ../nginx-1.7.5/
    ###请基于你自己的编译参数加上最后一条 --add-module ,切勿直接复制粘贴,因为我的环境是基于自己弄的一键包来演示的(如果你也需要?)###
    [root@ipython nginx-1.7.5]# ./configure --prefix=/software/nginx --user=nginx --group=nginx --add-module=../ngx_pagespeed-release-1.9.32.1-beta
    ##预配置结束后执行##
    [root@ipython nginx-1.7.5]# make
    ##如果你是全新安装,在预配置结束后make install,如果是重新编译,你可以这样##
    [root@ipython nginx-1.7.5]# mv /software/nginx/sbin/nginx /software/nginx/sbin/nginx.bak
    [root@ipython nginx-1.7.5]# cp objs/nginx /software/nginx/sbin/
    [root@ipython nginx-1.7.5]# kill -USR2 `cat /software/nginx/nginx.pid`
    [root@ipython nginx-1.7.5]# kill -QUIT `cat /software/nginx/nginx.pid.oldbin`

 

让常用的配置开启Pagespeed

    ##注意那条include##
    [root@ipython nginx-1.7.5]# vi /software/nginx/conf/nginx.conf
    server
    {
    listen 80;
    server_name 127.0.0.1;
    include pagespeed.conf;
    ...我省略了好多行
    #新增配置文件,配置后面再解释#
    [root@ipython nginx-1.7.5]# cat /software/nginx/conf/pagespeed.conf
    pagespeed on;
    pagespeed FileCachePath /software/var_temp/nginx/pagespeed/;
    ##重启nginx|reload也可以##
    [root@ipython nginx-1.7.5]# service nginx restart
    Stopping nginx: [ OK ]
    Starting nginx: [1107/230146:INFO:google_message_handler.cc(35)] No threading detected. Own threads: 1 Rewrite, 1 Expensive Rewrite.
    [ OK ]
    ##看看http头 和前面是不是不一样了##
    [root@ipython nginx-1.7.5]# curl -I 127.0.0.1
    HTTP/1.1 200 OK
    Server: nginx/1.7.5
    Content-Type: text/html
    Connection: keep-alive
    Vary: Accept-Encoding
    Date: Fri, 07 Nov 2014 15:03:29 GMT
    X-Page-Speed: 1.9.32.1-4238
    Cache-Control: max-age=0, no-cache
    ##临时关闭pagespeed##
    [root@ipython nginx-1.7.5]# curl -I 127.0.0.1?ModPagespeed=off
    HTTP/1.1 200 OK
    Server: nginx/1.7.5
    Date: Fri, 07 Nov 2014 15:04:56 GMT
    Content-Type: text/html
    Connection: keep-alive
    Vary: Accept-Encoding

 

一个示例配置文件

    [root@ipython nginx-1.7.5]# cat /software/nginx/conf/pagespeed.conf
    # 启用ngx_pagespeed
    pagespeed on;
    pagespeed FileCachePath /software/var_temp/nginx/pagespeed/;
    # 禁用CoreFilters
    pagespeed RewriteLevel PassThrough;
    # 启用压缩空白过滤器
    pagespeed EnableFilters collapse_whitespace;
    # 启用JavaScript库卸载
    pagespeed EnableFilters canonicalize_javascript_libraries;
    # 把多个CSS文件合并成一个CSS文件
    pagespeed EnableFilters combine_css;
    # 把多个JavaScript文件合并成一个JavaScript文件
    pagespeed EnableFilters combine_javascript;
    # 删除带默认属性的标签
    pagespeed EnableFilters elide_attributes;
    # 改善资源的可缓存性
    pagespeed EnableFilters extend_cache;
    # 更换被导入文件的@import,精简CSS文件
    pagespeed EnableFilters flatten_css_imports;
    pagespeed CssFlattenMaxBytes 5120;
    # 延时加载客户端看不见的图片
    pagespeed EnableFilters lazyload_images;
    # 启用JavaScript缩小机制
    pagespeed EnableFilters rewrite_javascript;
    # 启用图片优化机制
    pagespeed EnableFilters rewrite_images;
    # 预解析DNS查询
    pagespeed EnableFilters insert_dns_prefetch;
    # 重写CSS,首先加载渲染页面的CSS规则
    pagespeed EnableFilters prioritize_critical_css;
    # Example 禁止pagespeed 处理/ipython/目录
    pagespeed Disallow "*/ipython/*";

 

来源:http://www.ipython.me/centos/nginx-pagespeed-module-config.html

Linux:在 Ubuntu 14.10/14.04/13.10 上安装 LEMP 服务和 phpMyAdmin

LEMP是一个操作系统和几个开源软件包的合称。缩写LEMP来自 Linux,Nginx(发音是 engine-x)HTTP服务器, MySQL数据库,和 PHP/ Perl/ Python的首字母。

在这篇教程里,让我们看一下如何在 Ubuntu 14.10 上安装 Nginx,MySQL 或 MariaDB,PHP 和 phpMyAdmin。

安装Nginx

Nginx (发音是engine-x)是一个免费的、开源的、高性能HTTP服务器和反向代理,也可以用作IMAP/POP3代理服务器,它是由Igor Sysoev开发。

要安装Nginx,在你的终端里输入下面的命令:

注意:如果你的系统里已经安装了apache2,先卸载掉以避免冲突。要卸载apache,运行下面的命令:

sudo apt-get purge apache2*
sudo apt-get autoremove -y

现在,用下面的命令安装nginx:

sudo apt-get install nginx

用下面的命令启用Nginx服务:

sudo service nginx start

测试 nginx

打开你的浏览器访问http://IP地址/或者http://localhost/。将可以看到类似下面的截图。

配置 Nginx

用任意文本编辑器打开文件/etc/nginx/nginx.conf

sudo nano /etc/nginx/nginx.conf

设置 worker_processes(例如,你系统里CPU数目)。查看CPU数目,可以使用命令“lscpu”。在我这里是“1”。所以我把这个值设为1。

worker_processes 1;

重启 Nginx 服务:

sudo service nginx restart

默认虚拟主机(服务器模块)定义在文件/etc/nginx/sites-available/default里。

用任意文本编辑器打开文件/etc/nginx/sites-available/default。

sudo nano /etc/nginx/sites-available/default

在Server区域里,按如下设置服务器FQDN或IP地址。确保你增加了index.php这一行。

[...]
server {
      listen 80 default_server;
      listen [::]:80 default_server ipv6only=on;
      root /usr/share/nginx/html;
      index index.php index.html index.htm;
      # Make site accessible from http://localhost/
      server_name server.unixmen.local;
[...]

这里面

  • listen 80; –> 监听ipv4端口
  • listen [::]:80 default_server ipv6only=on; –> 监听ipv6宽口
  • root /usr/share/nginx/html; –> 文件根目录
  • server_name server.unixmen.local; –> 服务器FQDN

现在,向下滚动找到区域#location ~ .php$。去掉注释并按如下修改:

 location ~ .php$ {
         try_files $uri =404;   ---------> Add this line
         fastcgi_split_path_info ^(.+.php)(/.+)$;
         #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
         #
         #       # With php5-cgi alone:
         #       fastcgi_pass 127.0.0.1:9000;
         #       # With php5-fpm:
         fastcgi_pass unix:/var/run/php5-fpm.sock;
         fastcgi_index index.php;
         include fastcgi.conf;
    }

这里面,我增加了额外一行‘try_files $uri =404;’用于避免0day漏洞。

保存文件并退出。

测试 nginx 配置

使用下面的命令测试nginx配置是否存在语法错误:

sudo nginx -t

典型输出:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

最后重启nginx服务

sudo service nginx restart

来源:https://linux.cn/article-4228-1.html

Linux:GitHub秘籍 : git 篇

本秘籍收录了一些Git和Github非常酷同时又少有人知的功能。灵感来自于Zach Holman在2012年Aloha Ruby Conference和2013年WDCNZ上所做的演讲:Git and GitHub Secrets(slides)和More Git and GitHub Secrets(slides)。

Read this in other languages: English한국어日本語简体中文.

前一部分请看:http://linux.cn/article-4229-1.html 

Linux:GitHub秘籍 : git 篇
Linux:GitHub秘籍 : git 篇

前一个分支

快速检出上一个分支:

$ git checkout -
# Switched to branch 'master'
$ git checkout -
# Switched to branch 'next'
$ git checkout -
# Switched to branch 'master'

进一步了解 Git 分支.

Stripspace命令

Git Stripspace命令可以:

  • 去掉行尾空白符
  • 多个空行压缩成一行
  • 必要时在文件末尾增加一个空行

使用此命令时必须传入一个文件,像这样:

$ git stripspace < README.md

进一步了解 Git stripspace 命令.

检出Pull Requests

Pull Request是一种GitHub上可以通过以下多种方式在本地被检索的特别分支:

检索某个分支并临时储存在本地的FETCH_HEAD中以便快速查看更改(diff)以及合并(merge):

$ git fetch origin refs/pull/[PR-Number]/head

通过refspec获取所有的Pull Request为本地分支:

$ git fetch origin '+refs/pull/*/head:refs/remotes/origin/pr/*'

或在仓库的.git/config中加入下列设置来自动获取远程仓库中的Pull Request

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:tiimgreen/github-cheat-sheet.git
[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:tiimgreen/github-cheat-sheet.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

对基于派生库的Pull Request,可以通过先checkout代表此Pull Request的远端分支再由此分支建立一个本地分支:

$ git checkout pr/42 pr-42

进一步了解如何检出pull request到本地.

提交空改动 :trollface:

可以使用--allow-empty选项强制创建一个没有任何改动的提交:

$ git commit -m "Big-ass commit" --allow-empty

这样做在如下几种情况下是有意义的:

  • 标记一批工作或一个新功能的开始。
  • 记录你对项目进行了跟代码无关的改动。
  • 跟使用你仓库的其他人交流。
  • 作为仓库的第一次提交,因为第一次提交日后是不能被rebase的: git commit -m "init repo" --allow-empty.

更直观的Git Status

在命令行输入如下命令:

$ git status

可以看到:

Linux:GitHub秘籍 : git 篇
Linux:GitHub秘籍 : git 篇

加上-sb选项:

$ git status -sb

这回得到:

Linux:GitHub秘籍 : git 篇
Linux:GitHub秘籍 : git 篇

进一步了解 Git status 命令.

更直观的Git Log

输入如下命令:

$ git log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

可以看到:

Linux:GitHub秘籍 : git 篇
Linux:GitHub秘籍 : git 篇
%Creset' --abbrev-commit --date=relative" />

这要归功于Palesz在stackoverflow的回答。

这个命令可以被用作别名,详细做法见这里

进一步了解 Git log 命令.

Git查询

Git查询运行你在之前的所有提交信息里进行搜索,找到其中和搜索条件相匹配的最近的一条。

$ git show :/query

这里 query (区别大小写)是你想要搜索的词语, 这条命令会找到包含这个词语的最后那个提交并显示变动详情。

$ git show :/typo
Linux:GitHub秘籍 : git 篇
Linux:GitHub秘籍 : git 篇
  • 按 q 键退出命令。*

合并分支

输入命令:

$ git branch --merged

这会显示所有已经合并到你当前分支的分支列表。

相反地:

$ git branch --no-merged

会显示所有还没有合并到你当前分支的分支列表。

进一步了解 Git branch 命令.

来源:http://snowdream86.gitbooks.io/github-cheat-sheet/content/zh/index.html

Linux:想玩路由器吗?使用 Quagga 将你的 CentOS 变成 OSPF 路由器

Quagga是一个开源路由软件套件,可以将Linux变成支持如RIP、OSPF、BGP和IS-IS等主要路由协议的路由器。它具有对IPv4和IPv6的完整支持,并支持路由/前缀过滤。Quagga可以是你生命中的救星,以防你的生产路由器一旦宕机,而你没有备用的设备而只能等待更换。通过适当的配置,Quagga甚至可以作为生产路由器。

Linux:想玩路由器吗?使用 Quagga 将你的 CentOS 变成 OSPF 路由器
Linux:想玩路由器吗?使用 Quagga 将你的 CentOS 变成 OSPF 路由器

本教程中,我们将连接假设之间具有专线连接的两个分支机构网络(例如,192.168.1.0/24和172.17.1.0/24)。

Linux:想玩路由器吗?使用 Quagga 将你的 CentOS 变成 OSPF 路由器
Linux:想玩路由器吗?使用 Quagga 将你的 CentOS 变成 OSPF 路由器

我们的CentOS位于所述专用链路的两端。两台主机名分别设置为“site-A-RTR”和“site-B-RTR’。下面是IP地址的详细信息。

  • Site-A: 192.168.1.0/24
  • Site-B: 172.16.1.0/24
  • 两个 Linux 路由器之间的对等网络: 10.10.10.0/30

Quagga包括了几个协同工作的守护进程。在本教程中,我们将重点建立以下守护进程。

  1. Zebra: 核心守护进程,负责内核接口和静态路由。
  2. Ospfd: IPv4 OSPF 守护进程。

在CentOS上安装Quagga

我们使用yum安装Quagga。

# yum install quagga

在CentOS7,SELinux默认会阻止quagga将配置文件写到/usr/sbin/zebra。这个SELinux策略会干扰我们接下来要介绍的安装过程,所以我们要禁用此策略。对于这一点,无论是关闭SELinux(这里不推荐),还是如下启用“zebrawriteconfig”都可以。如果你使用的是CentOS 6的请跳过此步骤。

# setsebool -P zebra_write_config 1

如果没有做这个修改,在我们尝试在Quagga命令行中保存配置的时候看到如下错误。

Can't open configuration file /etc/quagga/zebra.conf.OS1Uu5.

安装完Quagga后,我们要配置必要的对等IP地址,并更新OSPF设置。Quagga自带了一个命令行称为vtysh。vtysh里面用到的Quagga命令与主要的路由器厂商如思科和Juniper是相似的。

步骤 1: 配置 Zebra

我们首先创建Zebra配置文件,并启用Zebra守护进程。

# cp /usr/share/doc/quagga-XXXXX/zebra.conf.sample /etc/quagga/zebra.conf
# service zebra start
# chkconfig zebra on

启动vtysh命令行:

# vtysh

首先,我们为Zebra配置日志文件。输入下面的命令进入vtysh的全局配置模式:

site-A-RTR# configure terminal

指定日志文件位置,接着退出模式:

site-A-RTR(config)# log file /var/log/quagga/quagga.log
site-A-RTR(config)# exit

永久保存配置:

site-A-RTR# write

接下来,我们要确定可用的接口并按需配置它们的IP地址。

site-A-RTR# show interface

Interface eth0 is up, line protocol detection is disabled
. . . . .
Interface eth1 is up, line protocol detection is disabled
. . . . .

配置eth0参数:

site-A-RTR# configure terminal
site-A-RTR(config)# interface eth0
site-A-RTR(config-if)# ip address 10.10.10.1/30
site-A-RTR(config-if)# description to-site-B
site-A-RTR(config-if)# no shutdown

继续配置eth1参数:

site-A-RTR(config)# interface eth1
site-A-RTR(config-if)# ip address 192.168.1.1/24
site-A-RTR(config-if)# description to-site-A-LAN
site-A-RTR(config-if)# no shutdown

现在验证配置:

site-A-RTR(config-if)# do show interface

Interface eth0 is up, line protocol detection is disabled
. . . . .
  inet 10.10.10.1/30 broadcast 10.10.10.3
. . . . .
Interface eth1 is up, line protocol detection is disabled
. . . . .
  inet 192.168.1.1/24 broadcast 192.168.1.255
. . . . .

site-A-RTR(config-if)# do show interface description

Interface      Status  Protocol  Description
eth0           up      unknown   to-site-B
eth1           up      unknown   to-site-A-LAN

永久保存配置:

site-A-RTR(config-if)# do write

在site-B上重复上面配置IP地址的步骤。

如果一切顺利,你应该可以在site-A的服务器上ping通site-B上的对等IP地址10.10.10.2了。

注意:一旦Zebra的守护进程启动了,在vtysh命令行中的任何改变都会立即生效。因此没有必要在更改配置后重启Zebra守护进程。

来源:https://linux.cn/article-4232-1.html

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

在公司的发展中,保证服务器的可扩展性对于扩大企业的市场需要具有重要作用,因此,这对架构师提出了一定的要求。Octivi联合创始人兼软件架构师Antoni Orfin将向你介绍一个非常简单的架构,使用HAProxy、PHP、Redis和MySQL就能支撑每周10亿请求。同时,你还能了解项目未来的横向扩展途径及常见的模式。

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

状态

  • 服务器
    • 3个应用程序节点
    • 2个MySQL+1个备份
    • 2个Redis
  • 应用程序
    • 应用程序每周处理10亿请求
    • 峰值700请求/秒的单Symfony2实例(平均工作日约550请求/秒)
    • 平均响应时间30毫秒
    • Varnish,每秒请求超过1.2万次(压力测试过程中获得)
  • 数据存储
    • Redis储存了1.6亿记录,数据体积大约100GB,同时它是我们的主要数据存储
    • MySQL储存了3亿记录,数据体积大约300GB,通常情况下它作为三级缓存层

平台

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
  • 监视:
    • Icinga
    • Collectd
  • 应用程序
    • HAProxy + Keepalived
    • Varnish
    • PHP(PHP-FPM)+ Symfony2 Framework
  • 数据存储
    • MySQL(主从配置),使用HAProxy做负载均衡
    • Redis (主从配置)

背景

大约1年前,一个朋友找到我并提出了一个苛刻的要求:它们是一个飞速发展的电子商务初创公司,而当时已经准备向国际发展。介于那个时候他们仍然是一个创业公司,初始解决方案必须符合所谓的成本效益,因此也就无法在服务器上投入更多的资金。遗留系统使用了标准的LAMP堆栈,因此他们拥有一个强力的PHP开发团队。如果必须引入新技术的话,那么这些技术必须足够简单,不会存在太多架构上的复杂性;那么,他们当下的技术团队就可以对应用进行长期的维护。

为了满足他们扩展到下一个市场的需求,架构师必须使用可扩展理念进行设计。首先,我们审视了他们的基础设施:

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

老系统使用了单模块化设计思路,底层是一些基于PHP的Web应用程序。这个初创公司有许多所谓的前端网站,它们大多都使用了独立的数据库,并共享了一些支撑业务逻辑的通用代码。毫不客气的说,长期维护这种应用程序绝对是一个噩梦:因为随着业务的发展,有些代码必须被重写,这样的话,修改某个网站将不可避免导致业务逻辑上的不一致,这样一来,他们不得不在所有Web应用程序上做相同的修改。

通常情况下,这该归结于项目管理问题,管理员必须对横跨多个代码库的那些代码负责。基于这个观点,整改第一步就是提取核心的业务关键功能,并将之拆分为独立的服务(这也是本文的一个重点部分),也就是所谓的面向服务架构,在整个系统内遵循“separation of concern”原则。每个服务只负责一个业务逻辑,同时也要明确更高等级的业务功能。举个形象的例子也就是,这个系统可能是个搜索引擎、一个销售系统等。

前端网站通过REST API与服务交互,响应则基于JSON格式。为了简单起见,我们没有选择SOAP,一个开发者比较无爱的协议,因为谁都不愿意解析一堆的XML。

提取一些不会经常处理的服务,比如身份验证和会话管理。这是非常必要的一个环节,因为它们的处理等级比较高。前端网站负责这个部分,只有它们可以识别用户。这样一来我们可以保持服务的足够简单,在处理扩展和代码相关问题时都具有巨大的优势,可谓各司其职,完美无缺。

带来的好处:

  • 独立子系统(服务)可以便捷的在不同团队中开发,开发者互不干涉,效率理所当然提升。
  • 身份验证和会话不会通过它们来管理,因此它们造成的扩展问题不翼而飞。
  • 业务逻辑被区分,不同的前端网站不会再存在功能冗余。
  • 显著地提高了服务的可用性。 

共生的缺点:

为系统管理员带来更大的工作量。鉴于服务都使用了独立的基础设施,这将给管理员带来更多需要关注的地方。

很难保持向后兼容。在一年的维护之后,API方法中发生了数不尽的变化。因此问题发生了,它们必将破坏向后兼容,因为每个网站的代码都可能发生变化,还可能存在许多技术人员同时修改一个网站的情况……然而,一年后,所有方法匹配的仍然是项目开始时建立的文档。

应用程序层

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

着眼请求工作流,第一层是应用程序。HAProxy负载均衡器、Varnish和Symfony2应用程序都在这一层。来自前端网站的请求首先会传递给HAProxy,随后负载均衡器将把他分给不同的节点。

应用程序节点配置

  • Xeon E5-1620@3.60GHz,64GB RAM,SATA
  • Varnish
  • Apache2
  • PHP 5.4.X(PHP-FPM),使用APC字节码缓存

我们购买了3个这样的服务器,N+1冗余配置的active-active模式,备份服务器同样处理请求。因为性能不是首要因素,我们为每个节点配置独立的Varnish以降低缓存hit,同时也避免了单点故障(SPOF)。在这个项目中,我们更重视可用性。因为一个前端网站服务器中使用了Apache 2,我们保留了这个堆栈。这样一来,管理员不会困扰于太多新加入的技术。

Symfony2应用程序

应用程序本身基于Symfony2建立,这是一个PHP全堆栈框架,提供了大量加速开发的组件。作为基于复杂框架的典型REST服务可能受到很多人质疑,这里为你细说:

  • 对 PHP/Symfony 开发者友好。客户端IT团队由PHP开发者组成,添加新技术将意味必须招聘新的开发者,因为业务系统必须做长时间的维护。
  • 清晰的项目结构。 PHP/Symfony虽然从来都不是必需品,但却是许多项目的默认选择。引入新的开发者将非常方便,因为对他们来说代码非常友好。
  • 许多现成的组件。遵循DRY思想……没有人愿意花力气去做重复的工作,我们也不例外。我们使用了大量的Symfony2 Console Component,这个框架非常有利于做CLI命令,以及应用程序性能分析(debug工具栏)、记录器等。

在选用Symfony2之前,我们做了大量的性能测试以保证应用程序可以支撑计划流量。我们制定了概念验证,并使用JMeter执行,我们得到了让人满意的结果——每秒700请求时响应时间可以控制在50毫秒。这些测试给了我们足够的信心,让我们坚信,即使Symfony2这样复杂的框架也可以得到理想的性能。

应用程序分析与监控

我们使用Symfony2工具来监视应用程序,在收集指定方法执行时间上表现的非常不错,特别是那些与第三方网络服务交互的操作。这样一来,我们可以发现架构中潜在的弱点,找出应用程序中最耗时的部分。

冗长的日志同样是不可缺少的一部分,我们使用PHP Monolog库把这些日志处理成优雅的log-lines,便于开发者和管理员理解。这里需要注意的是尽可能多地添加细节,越详细越好,我们使用了不同的日志等级:

  • Debug,可能会发生的事情。比如,请求信息在调用前会传送给一个外部Web服务;事情发生后从API调用响应。
  • Error,当错误发生时请求流并未被终止,比如第三方API的错误响应。
  • Critical,应用程序崩溃的瞬间。

因此,你可以清晰地了解Error和Critical信息。而在开发/测试环境中,Debug信息同样被记录。同时,日志被存储在不同的文件中,也就是Monolog库下的“channels”。系统中有一个主日志文件,记录了所有应用程序级错误,以及各个channel的短日志,从单独的文件中记录了来自各个channel的详细日志。

扩展性

扩展平台的应用程序层并不困难,HAProxy性能并不会在短时间耗尽,唯一需要考虑的就是如何冗余以避免单点故障。因此,当下需要做的只是添加下一个应用程序节点。

数据层

我们使用Redis和MySQL存储所有的数据,MySQL更多作为三级缓存层,而Redis则是系统的主要数据存储。

Redis

在系统设计时,我们基于以下几点来选择满足计划需求的数据库:

  • 在存储大量数据时不会影响性能,大约2.5亿记录
  • 通常情况下多是基于特定资源的简单GET请求,没有查找及复杂的SELECT操作
  • 在单请求时尽可能多的获得资源以降低延时

在经过一些调查后,我们决定使用Redis 

  • 大部分我们执行的操作都具有 O(1)或O(N)复杂性, N是需要检索键的数量,这意味着keyspace大小并不会影响性能。
  • 通常情况下会使用MGET命令行同时检索100个以上的键,这样可以尽可能的避免网络延时,而不是在循环中做多重GET操作。 

我们当下拥有两个Redis服务器,使用主从复制模式。这两个节点的配置相同,都是Xeon E5-2650v2@2.60GHz,128GB,SSD。内存限制被设置为100GB,通常情况下使用率都是100%。

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

在应用程序并没有耗尽单个Redis服务器的所有资源时,从节点主要作作备份使用,用以保证高有效性。如果主节点宕机,我们可以快速的将应用程序切换到从节点。在维护和服务器迁移时,复制同样被执行——转换一个服务器非常简单。

你可能会猜想当Redis资源被一直耗尽时的情景,所有的键都是持久化类型,大约占90% keyspace,剩余资源被全部被用于TTL过期缓存。当下,keyspace已经被分为两个部分:一个是TTL集(缓存),另一个则是用于持久化数据。感谢“volatile-lru”最大化内存设置的可行性,最不经常使用缓存键会被移除。如此一来,系统就可以一直保持单Redis实例同时执行两个操作——主存储和通用缓存。

使用这个模式必须一直监视“期满”键的数量:

db.redis1:6379> info keyspace
# Keyspace
db0:keys=16XXXXXXX,expires=11XXXXXX,avg_ttl=0

“期满”键数量越接近0情况越危险,这个时候管理员就需要考虑适当的分片或者是增加内存。

我们如何进行监控?这里使用Icinga check,仪表盘会显示数字是否会达到临界点,我们还使用了Redis来可视化“丢失键”的比率。

Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
Linux:使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求

在一年后,我们已经爱上了Redis,它从未让我们失望,这一年系统从未发生任何宕机情况。

MySQL

在Redis之外,我们还使用了传统RDBMS——MySQL。但是区别于他人,我们通常使用它作为三级缓存层。我们使用MySQL存储一些不会经常使用对象以降低Redis的资源使用率,因此它们被放到了硬盘上。这里没有什么可说道的地方,我们只是尽可能地让其保持简单。我们使用了两个MySQL服务器,配置是Xeon E5-1620@3.60GHz,64GB RAM,SSD。两个服务器使用本地、异步的主-主复制。此外,我们使用一个单独的从节点作为备份。

MySQL的高可用性

在应用程序中,数据库永远是最难的瓶颈。当前,这里还不需要考虑横向扩展操作,我们多是纵向扩展Redis和MySQL服务器。当下这个策略还存在一定的发展空间,Redis运行在一个126GB内存的服务器上,扩展到256GB也并不困难。当然,这样的服务器也存在劣势,比如快照,又或是是简单的启动——Redis服务器启动需要很长的时间。

在纵向扩展失效后进行的必然是横向扩展,值得高兴的是,项目开始时我们就为数据准备了一个易于分片的结构:

在Redis中,我们为记录使用了4个“heavy”类型。基于数据类型,它们可以分片到4个服务器上。我们避免使用哈希分片,而是选择基于记录类型分片。这种情况下,我们仍然可以运行MGET,它始终在一种类型键上执行。

在MySQL上,结构化的表格非常易于向另一台服务器上迁移——同样基于记录类型(表格)。当然,一旦基于记录类型的分片不再奏效,我们将转移至哈希。

学到的知识 

  • 不要随便共享你的数据库给别人用。有一次,一个前端网站希望将会话处理切换到Redis,所以就直接连接了一个,它耗尽了Redis的缓存空间,以至于应用程序再也不能保存下一个缓存键了。所有的缓存应该在 MySQL 的结果集占用大量开销时才进行存储。
  • 日志越详细越好。如果log-lines中没有足够的信息,快速Debug问题定位将成为难点。如此一来,你不得不等待一个又一个问题发生,直到找到根结所在。
  • 架构中使用复杂的框架并不意味着低性能。许多人惊讶我们使用全堆栈框架来支撑如此流量应用程序,其秘诀在于更聪明的使用工具,否则即使是Node.js也可能变得很慢。选择一个提供良好开发环境的技术,没有人期望使用一堆不友好的工具,这将降低开发团队士气。

来源:http://www.csdn.net/article/2014-08-14/2821203