Linux

grep 归档日志的好办法

0

归档的日志文件,想要从中找出匹配的数据,我最近才知道有更好的办法。

先说说我以前的笨方法:

* 先解压 bz2 文件到纯文本

* 再 grep 这个文本

* 完成后再删除这个纯文本

整个过程很麻烦。

 

有位高手告诉我更简单的办法:

bzcat debug_log.bz2 | grep ‘pattern’ > result.txt

这个是一边解压一边 grep,不用创建新文件,不太占 IO。

试了下,效果还不错,可以同时处理好几个,系统负载也不高。

使用 rsync 备份多台服务器

0

今天对服务器备份的脚本进行了重构,把配置参数独立成文件,使用 PHP 代替不熟悉的 shell,理顺了思路,分享一下。

【环境】

一共3台服务器,server-1 和 server-2 是线上生产环境,backup-server 是专门用于备份的服务器。

【目的】

定期把 server-1 和 server-2 的 user 目录下的所有文件同步到 backup-server 的指定目录下。

【前提】

backup-server 上有一个用户 backup,他用 ssh-keygen 生成公钥,传到 server-1 和 server-2,这样 backup 用户登录这 2 台线上服务器时不再需要密码。

[backup@backup-server rsync]$ ssh-keygen -t rsa -b 1024

在 ~/.ssh/ 下生成 id_rsa 和 id_rsa.pub,分别是私钥和公钥。

把 id_rsa 重命名成 identity,chmod 600。

把 id_rsa.pub 复制到 server-1 的 /home/user/.ssh/ 目录下,把内容追加到 authorized_keys 文件中,注意此文件也要 chmod 600。

server-2 也如此操作。

之后,backup 用户可以随意 ssh user@server-1 和 ssh user@server-2,不会再问密码。

【功能列表】
* 根据配置文件的 serverName,生成 shell 命令
* 判断是否为唯一 rsync 进程,如果有正在执行的进程,则不执行任何操作
* 确认没有重复进程之后,执行 rsync 命令同步文件,并输出进度信息到 logs 目录
* php 的程序只输出 shell 命令,确认无误后用管道输出给 bash 来运行

【使用方法】
[backup@backup-server rsync]$ /usr/bin/php /home/backup/script/rsync/rsync_web.php server-1 | sh

【详情】

根据 server-1 这个关键字,找到对应的配置信息。

根据一些列规则,生成一串管道命令,输出如下所示:

rsync_process_num=$(ps ax | grep ‘rsync’ | grep -v ‘grep’ | grep ‘server-1′ | grep ‘bwlimit’ | wc -l) && test $rsync_process_num -lt 1 && /usr/bin/nohup /usr/bin/rsync –links –delete –recursive –itemize-changes –progress –exclude-from=/home/backup/script/rsync/conf/exclude.server-1.conf –bwlimit=110 user@server-1:/home/user/* /home/backup/server-1/home/user/ >> /home/backup/script/rsync/logs/rsync_web.server-1.log 2>&1 &

对比“功能列表”,可以看明白这一串命令都在干嘛。

【SVN】

具体的代码,我提交到了 googlecode,欢迎指正:http://leakon.googlecode.com/svn/trunk/server/script/rsync/

 

sudo: sorry, you must have a tty to run sudo

0

I was recently working on a Perl script that would SSH to another server and run a sudo command on the remote server that was failing. The error that was received is below.

Error: sudo: sorry, you must have a tty to run sudo

The reason for this is an update along the way with sudo locked it down further by adding the below line to /etc/sudoers configuration file.

Defaults requiretty

To allow a remote script to login and run a command via sudo simply comment out that line as shown below.

# Commented out so remote script can login and run a command without a tty
# Defaults requiretty

I would suggest making a comment in the sudoers file along with the actual script that is running just in case there is another systems administrator that is tasked with working on this server at a later date. Now when your script runs it will not throw that error and should be able to run the remote command that was initially required.

su 环境变量 小发现

1

Linux 下普通用户 su 成 root 后,环境变量以及路径等都还使用原用户的,比如没法直接执行 ifconfig,必须要用 /sbin/ifconfig。

今天受 wangjun 提醒,原来 su – 可以解决问题,直接切换到 root 目录下,环境变量也一并切换。

记录一下,顺便谢谢 wangjun。

VMware CentOS 网络中断

0

有时候在 VMware 下的 CentOS 无法访问外网,现象是可以 ping 通 IP 地址,但没法 ping 域名,最开始以为 DNS 的问题,实际上没那么复杂。

只要在 Edit -> Virutal Network Editor -> Nat -> Restart 即可。

可能是我这个 6.5 版本的 VMware 的 Nat 有问题吧。

唉,上次就搞了半天没发现问题,重启我的电脑后才好的。这次遇到问题突然忘了怎么解决,运气好,试了下重启 Nat 服务。

记下来备忘。

memcache PECL bug fix

0

使用 memcache 的过程中,遇到一个奇怪的问题,在 CentOS 环境下,PHP 的 memcache 扩展创建的客户端对象,在 delete 一个 key 的时候报错:

[25-Nov-2009 13:57:04] PHP Notice:  Memcache::delete(): Server 192.168.10.131 (tcp 11211) failed with: CLIENT_ERROR bad command line format.  Usage: delete <key> [noreply]

可是在 Windows 环境下,用的人家编译好的 php_memcache-cvs-20090703-5.3-VC6-x86.dll (20KB) 却没问题!

在 Google 上找了半天,终于在 PHP 官方手册的评论中发现了线索:

http://php.net/manual/en/function.memcache-delete.php

请看 10-Nov-2009 11:17 这条,简短翻译一下:

memcache 这个 PECL 扩展的 2.2.5 稳定版本有一个错误,导致在向 memcached 1.4.3 调用 delete 方法时返回 false。

用 -vvv 模式运行 memcached 将显示出为什么 delete 调用失败:

CLIENT_ERROR bad command line format.  Usage: delete <key> [noreply]

简单修改一下,在这个 PECL 扩展的 memcache.c 这个文件的 1494 行的 mmc_delete() 函数中。把 command_len 修改为下面这样:

command_len = spprintf(&command, 0, “delete %s”, key);

去掉了弃用的第 3 个参数,然后 delete 就可以工作了。希望这个可以帮到你!

再提示一下改动前的代码:

//  command_len = spprintf(&command, 0, “delete %s %d”, key, time);

修改完成后,重新编译出 memcache.so 即可。

Subversion neon 诡异配置 一波三折

1

今天发现前几天装的 subversion 居然没法通过 http 协议访问版本库!

Subversion 出现 svn: Unrecognized URL scheme for ‘http://…..’  这样的错误提示。

检查 svn 客户端是否支持 http 协议,只需查看版本号:

shell> svn –version

看看输出是否有如下输出:

* ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.
- handles ‘http’ scheme
- handles ‘https’ scheme

如果有,恭喜了,不用继续耽误您时间了。如果没有,后面告诉你怎么让它有。

我的 subversion 版本是 1.6.5,本来我看了 INSTALL 文件,预先编译了 neon,用的是最新的 0.29.0,然后指定了 neon 的路径。编译了 3 次,慢死了,结果还是没有,真邪门了。

后来 google 搜啊搜,注意到一个细节,说 configure 的时候,neon 配置出错,不会终止配置进程,只是给出几行提示信息,然后继续……

我重新 configure,看看 neon 的输出,居然看到下面几行:

checking neon library version… 0.29.0
You have neon version 0.29.0,
but Subversion needs neon 0.28.4.

An appropriate version of neon could not be found, so libsvn_ra_neon
will not be built.  If you want to build libsvn_ra_neon, please either
install neon 0.28.4 on this system

or

get neon 0.28.4 from:
http://www.webdav.org/neon/neon-0.28.4.tar.gz
unpack the archive using tar/gunzip and rename the resulting
directory from ./neon-0.28.4/ to ./neon/

no suitable neon found

提示的意思是必须安装 0.28.4 版本的 neon,更高的版本都不行!

到此问题明朗,重新安装 0.28.4 版本的 neon ,然后重新编译 subversion 即可。

最后,我的 svn 也支持 http 和 https 协议啦!

iptables 防火墙 firewall COMMIT Linux

0

Applying iptables firewall rules: iptables-restore: line 20 failed [FAILED]

修改防火墙配置,然后重启 iptables,结果得到上面这个错误提示。

配置文件 20 行是一个 COMMIT,不是这行的问题。

跟内核有关系,但不要轻易重新编译内核,搞不好系统就没法用了。

找到上面问题原因,有其他方法可以解决的。

看了国外的一个论坛,有个人说是 -m 这个选项造成的。

因为当前系统内核中缺少一个 module,而 -m 这个选项刚好要加载这个 module。

这个 module 是 xt_state。

当然,重新编译 kernel,加上这个 module 可以解决问题,但我不敢,因为不会……

我可以不用 -m 这个选项。

其实我就是要求开放 22 和 80 这 2 个端口,其他的一律拒绝。

之前导致报错的写法:

-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT

-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT

把 -m state –state NEW -m tcp 这段去掉:

-A INPUT -p tcp –dport 22 -j ACCEPT
-A INPUT -p tcp –dport 80 -j ACCEPT

删除那个 -m state –state NEW 的意思是匹配状态,当新连接创建时应用过滤条件。

我估计这个是为了提升性能吧,连接创建时如果不匹配规则,就拒绝掉后续的请求,一旦连接建立,就不用对后续的包进行再次过滤检查。

如果是这样,我觉得可以接受,无非是服务器负载高一点而已,对流量小的网站来说没什么影响。等流量大了再研究编译内核吧。

SSL negotiation failed: SSL error: parse tlsext

7

Apache/Subversion: SSL negotiation failed: SSL error: parse tlsext

在 CentOS 下配置 Apache + SSL + Subversion,一切都搞定后,提交原始代码到版本库,结果总是中途断掉,得到标题给出的提示。

查了下,是因为 TLSv1 协议的问题,不知是 openssl 的 bug 还是 subversion 的 bug,总之无法正常工作。

修改 Apache 配置文件,屏蔽掉 TLSv1 加密方式:

SSLProtocol -ALL +SSLv3

SSLProtocol +ALL -SSLv2 -TLSv1

SSLProtocol all -TLSv1

反正只要没有 TLSv1 就能正常工作,经测试,暂时还未发现新问题。

libsvn_subr-1.so.0: undefined symbol: sqlite3_open_v2

0

安装 subversion 到 CentOS 服务器上,编译了 OpenSSL、Apache 和 SQLite,subversion 也编译完了,用 httpd -t 查看 Apache 配置文件的时候报出错误:

httpd: Syntax error on line 106 of /xxx/yyy/apache2/conf/httpd.conf: Cannot load /xxx/yyy/apache2/modules/mod_dav_svn.so into server: /xxx/yyy/subversion/lib/libsvn_subr-1.so.0: undefined symbol: sqlite3_open_v2

一下就晕了,在 Google 查不到几条信息,也都没说到点上,不过还算有些启发。

之前在本地 VMware 的 CentOS 上测试过,安装很顺利,这回失败,肯定跟 64 位服务器有关。

换了多种 subversion 的编译参数,反复编译了几次,问题依旧。

后来学会了用 ldd 查看链接库的依赖:

shell> ldd /xxx/yyy/subversion/lib/libsvn_subr-1.so.0

libaprutil-1.so.0 => /xxx/yyy/apr-util/lib/libaprutil-1.so.0 (0x00002b4613bf5000)

libexpat.so.0 => /lib64/libexpat.so.0 (0x00002b4613e22000)

libapr-1.so.0 => /usr/lib64/libapr-1.so.0 (0x00002b4614044000)

libuuid.so.1 => /lib64/libuuid.so.1 (0x00002b461426c000)

librt.so.1 => /lib64/librt.so.1 (0x00002b4614470000)

libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00002b4614679000)

libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b46148b2000)

libdl.so.2 => /lib64/libdl.so.2 (0x00002b4614acd000)

libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0 (0x00002b4614cd1000)

libc.so.6 => /lib64/libc.so.6 (0x00002b4614f2c000)

/lib64/ld-linux-x86-64.so.2 (0x00002b461376e000)

看到 libsqlite3.so.0 依赖的是用的系统自带的 64 位的 sqlite 链接库,这个链接库应该是没有定义 “sqlite3_open_v2”,因此 mod_dav_svn.so 是无法加载到 apache 中的。

虽然找到了有价值的线索,但让我开始更为迷惑,为什么 libsvn_subr-1.so.0 会依赖系统的库文件,不是我指定的 sqlite 的库文件地址呢?

又查看了 subversion 源码中附带的 INSTALL 说明文件,文中提及了 sqlite 的 3 种关联方式。

我指定了 sqlite 的安装路径,是第 1 种方式,但应该是使用 32 位方式编译的(不知道怎么设置强制 64 位编译),subversion 会忽略。

文中的第 2 种方式,把 sqlite3.c 复制到 subversion 的源码路径下:

/xxx/yyy/src/subversion-1.6.5/sqlite-amalgamation/sqlite3.c

然后重新编译,完成后再看 libsvn_subr-1.so.0 的依赖,发现它已经不再依赖外部 sqlite 。

这样 subversion 的安装问题就解决了。

顺便再记录一下 64 位系统中安装其他软件时遇到的问题如何解决。

安装 apache 需要 zlib 和 openssl,如果用普通方式编译这 2 个软件,则 apache 编译出错:

“relocation R_X86_64_32 against `a local symbol’ can not be used when making a shared object; recompile with -fPIC”

解决问题的方法,是在这 2 个软件进行 configure 之后,修改 Makefile 文件,找到 CFLAGS,加上 -fPIC 参数,如下:

CFLAGS=”-O3 -fPIC”

注意,这只是个例子,可能参数列表不一样,只要加入 -fPIC 就可以了。

Go to Top