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
0I 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 环境变量 小发现
1Linux 下普通用户 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
0Applying 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
把 -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
7Apache/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 就可以了。
