Skip navigation.

极湖

无不用其“极”

Posts tagged with "Linux"

grep命令的基本用法

,

grep命令主要用于在文件中查找特定的字符串。

[主要选项]

-l, --files-with-matches 仅输出在其中找到字符串的文件名
-r, 检索对象包含子目录(递归)
-v, --invert-match 查找不包含指定字符串的文件
-e, 实现 OR 的检索(同时包含多个字符串)

[使用例]

在邮件处理日志文件/var/log/maillog中查找包含“Access denied”的行并输出至屏幕
# grep 'Access denied' /var/log/maillog

与以上例子相反,查找不包含“Access denied”的行并输出至屏幕
# grep -v 'Access denied' /var/log/maillog

在/etc/passwd中查找包含“false”或“nologin”的行并输出至屏幕
# grep -e false -e nologin /etc/passwd

在当前目录下查找所有以“string”开头的文件并输出文件名
# grep -r -l '^string' *

用qmHandle删除qmail消息队列中的特定邮件

,

qmHandle 是一个Perl程序,用来处理qmail的消息队列。比起 qmail-qread 和 qmail-qstat,qmHandle有更多的特性。

在qmHandle的基础上,作了一个小程序,用来删除包含指定字符串的邮件。

程序如下:
#!/usr/local/bin/perl
use strict;

use vars qw(%Config);

$Config{qmHandle_cmd} = '/var/local/src/qmHandle';
$Config{msg_file} = '/home/ou/qmScript/message_id_list.txt';
$Config{log_file} = '/home/ou/qmScript/log/delete_qmail_msg.' . &get_date() . '.log';

$Config{match_pattern} = '\nTo:\s(.*)\@bad.domain\n';

&main();

sub main()
{
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
    &write_log("---------- ". &get_time() . " start delete messages ----------\n");

&analyze_and_delete_msgs();

    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
    &write_log("---------- ". &get_time() . " end delete messages ----------\n");
}

#-------------------------------------------------------------------
sub analyze_and_delete_msgs()
{
# 执行命令“qmHandle -l -N”结果输出到文件
system("$Config{qmHandle_cmd} -l -N > $Config{msg_file}");
if (-e $Config{msg_file}) {
# 从文件读取消息ID
open (MSG_LIST, $Config{msg_file}) || die "couldn't open $Config{msg_file}!";

while (<MSG_LIST>) {
    my ($msg_id, $msg_info) = split(/\s/, $_);
# 根据消息ID分析邮件内容
my $read_cmd = "$Config{qmHandle_cmd} -m$msg_id";
&write_log("$read_cmd\n");
    my $msg_txt = `$read_cmd`;
if( $msg_txt =~ /$Config{match_pattern}/ ) {
# 文件内容匹配指定正则表达式的情况下,删除该邮件,并写log
my $del_cmd = "$Config{qmHandle_cmd} -d$msg_id";
system("$Config{qmHandle_cmd} -d$msg_id");
&write_log("message: $msg_id deleted\n");
    } else {
    # 文件内容匹配指定正则表达式的情况下,写log
&write_log("# message: $msg_id does not match\n");
}
}

close(MSG_LIST);
}

}

#-------------------------------------------------------------------
sub get_date()
{
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
return sprintf("%04d%02d%02d", $year + 1900, $mon +1, $mday);
}

#-------------------------------------------------------------------
sub get_time()
{
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
return sprintf("%02d:%02d:%02d", $hour, $min, $sec);
}

#-------------------------------------------------------------------
sub write_log($)
{
    my ($log_msg) = @_;

    open(LOG, ">>$Config{log_file}") || die("Cannot open $Config{log_file}\n");
    print LOG $log_msg;
    close(LOG);
}

以上程序,优点是可以实现复杂条件的删除,缺点是执行速度比较慢。

删除送往特定域名的邮件,有一个更快更好的方法:设置alias本地接收并丢弃邮件

$ echo '#' > /var/qmail/alias/.qmail-baddomain-default

$ vi /var/qmail/control/virtualdomains
(追加)
bad.domain.name:alias-baddomain

$ vi /var/qmail/control/smtproutes
(追加)
bad.domain.name:127.0.0.1

$ /var/qmail/bin/qmail-tcpok
$ kill -HUP qmail-sendのPID


还有一个方法:直接删除queue下面的文件
1) 停止qmail

2) 删除queue下面的消息文件
# cd /var/qmail/queue/mess
# find ./ -type f -exec grep "^To: addr@bad.domain" {} \; -print -exec rm {} \;


3) 执行queue-fix
# ./queue-fix -i /var/qmail/queue

4) 启动qmail

用正则表达式识别中英文

, , ,

包含正则表达式的命令如下:

iconv -f gbk -t utf-8 query_list |egrep -e "^[a-z0-9]*$"

以上这个命令的详细解释,请看车东的Blog

Linux下一次删除所有空目录的方法

, ,

方法一:用 Perl 实现

程序
#!/usr/bin/perl
use File::Find;
finddepth(sub{rmdir},'.')


命令
perl -MFile::Find -e"finddepth(sub{rmdir},'.')"


方法二:用 Shell Script 实现

find -depth -type d -empty -exec rmdir {} \;

以上方法来自:http://duramecho.com/ComputerPrograms/DeleteEmptyDirectories/index.html

qmail + ezmlm 实现ML之间的邮件互送

,

本人管理的服务器之一,用 qmail + ezmlm 管理邮件列表,最近,遇到一个问题: 在本地的邮件列表之间,不能互送邮件。

具体一点,问题如下:

建了两个邮件列表:
listA
listB

已在listA的成员中加入listB,也就是说,给listA@mailserver发的邮件,希望同时发给listB@mailserver。

问题是,给listA@mailserver发的邮件,listB@mailserver没有收到。

listB@mailserver不能收信可以理解,因为这样做容易导致邮件发送的死循环。

不过,在特殊情况下,还是想实现这个功能。

通过分析log,终于解决这个问题。

原因:

Dec 26 13:26:43 toryo qmail: 1167107203.510103 starting delivery 3367666: msg 227983 to local listB@maildomain
Dec 26 13:26:43 toryo qmail: 1167107203.582077 delivery 3367666: success: Precedence:_junk_-_message_ignored/did_0+0+1/

解决办法:

① 修改listA的设置
# cd /var/qmail/alias/listA
# vi headeradd
(修改)
----------------------------------
Precedence: bulk
----------------------------------

----------------------------------
Precedence:
----------------------------------

② 修改listB的设置
# cd /var/qmail/alias/listB
# vi sublist
(追加)
----------------------------------
listA@mailserver
----------------------------------

# vi editor
(修改)
----------------------------------
|/usr/local/bin/ezmlm/ezmlm-reject '/var/qmail/alias/listB'
----------------------------------

----------------------------------
|/usr/local/bin/ezmlm/ezmlm-reject -T '/var/qmail/alias/listB'
----------------------------------

补充:
以上设定,如果不是特殊需要,不推荐这样做。

另外,如果单独给listB@mailserver发信,会发不出去。错误信息如下:

ezmlm-send: fatal: this message is not from my parent list

因为邮件不是来自父列表,所以拒绝转发给列表中的地址。这又是个问题。

【收藏】Bash的快捷键

,

Ctrl + A : 光标移到行首。
Ctrl + E : 光标移到行尾。
Ctrl + L : 清屏。
Ctrl + U : 清除光标前至行首间的所有内容。
Ctrl + H : 同 backspace 键相同。
Ctrl + R : 搜索之前打过的命令。
Ctrl + C : 杀死当前进程。
Ctrl + D : 退出当前 Shell。
Ctrl + Z : 把当前进程转到后台运行,使用' fg '命令恢复。
Ctrl + W : 移除光标前的一个单词
Ctrl + K : 清除光标后至行尾的内容。
Ctrl + T : 交换光标位置前的两个字符。
Esc + T : 交换光标位置前的两个单词。
Alt + F : 在当前行把光标向前移一个单词。
Alt + B : 在当前行把光标向后移一个单词。
Tab : 自动补完命令。

转自 Slashdot/Digg中文翻译

/var/log/lastlog有1.2TB?

无意间在一个Linux服务器上发现一个问题:

# cd /var/log
# ls -la lastlog

-r-------- 1 root root 1254130450140 Dec 7 15:42 lastlog

# df -khP /var
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol04 4.0G 571M 3.2G 15% /var

lastlog文件居然有1.2TB,而/var分区才7.2G,怪事!

查看内核版本:
# uname -a
Linux pltest0 2.6.9-5.ELsmp #1 SMP Wed Jan 5 19:29:47 EST 2005 x86_64 x86_64 x86_64 GNU/Linux

初步猜想这是64位Linux系统的Bug。上网查了一下,证实了这样的想法,并且得到如下的解决办法:

升级相关的软件包。

(1) 删除/var/log/lastlog。
(2) 安装或升级以下软件包:

audit-libs-1.0.12-1.EL4.x86_64.rpm
shadow-utils-4.0.3-60.RHEL4.1AX.x86_64.rpm

[原创]用gzip压缩log文件的Perl程序

, ,

功能:
1. 压缩目录下的所有log文件。(用正则表达式指定文件名格式)
2. 保留最近2天的log原文件。 (保留天数可根据需要修改)

程序:
#!/usr/bin/perl -w
#
# compress apache's log files by gzip
#
# 2006/12/06 created by ou
#
#
use Time::Local;
use strict;

my $log_dir = '/var/log/apache';
my $log_pattern = '^.*log.([0-9]{4})-([0-9]{2})-([0-9]{2})$';
my $keep_days = 2;

&compress_logs( $log_dir, $log_pattern );

sub compress_logs()
{
my ($log_dir, $log_pattern) = @_;

opendir(DIR, $log_dir) || die "Open dir $log_dir failed !";
my @all_files = grep !/^\.\.?$/, readdir DIR;

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
my $today_days = timelocal(0, 0, 0, $mday, $mon, $year+1900)/86400;

chdir($log_dir);

foreach(@all_files){
if( $_ =~ /$log_pattern/ ) {
my $log_file = "$log_dir/$_";
my $file_days = timelocal(0, 0, 0, $3, $2-1, $1)/86400;
if( ($today_days - $file_days) > $keep_days ) {
#print "gzip $log_file\n";
system("gzip $log_file");
} else {
#print "leave $log_file\n";
}
}
}
}

iptables 的基本设置步骤

,

在这儿整理一下iptables的基本设置步骤。

◆查看现在的设置

(1)查看全部设置
[root@server ~]# iptables -L
Chain FORWARD (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all -- anywhere anywhere

Chain INPUT (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain RH-Firewall-1-INPUT (2 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere icmp any
ACCEPT ipv6-crypt-- anywhere anywhere
ACCEPT ipv6-auth-- anywhere anywhere
ACCEPT udp -- anywhere 224.0.0.251 udp dpt:5353
ACCEPT udp -- anywhere anywhere udp dpt:ipp
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:smtp
ACCEPT udp -- anywhere anywhere state NEW udp dpt:snmp
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

(2)查看指定部分的设置+显示IP地址以及行号
[root@server ~]# iptables -L RH-Firewall-1-INPUT -n --line-numbers
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255
3 ACCEPT esp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT ah -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353
6 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:631
7 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
9 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
10 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:21
11 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:25
12 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 state NEW udp dpt:161
13 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited


◆追加设置

最下面一行的设置是全部拒绝,因此在前面追加新的设置
简单说明一下参数:

 -I :追加(插入)设置 (追加的位置在链名为 RH-Firewall-1-INPUT 的第12行)

 -p :指定协议(这次是tcp)

 -s :源IP地址(这次是全部)

 -d :目的IP地址(这次是全部)

 -j :数据包正确的情况下跳转目的地 (ACCEPT表示所在链让这个包通过)

 -m :通信连接的跟踪状态(NEW是新建连接)

 --destination-port :指定目标端口或端口范围

 以下命令用来在第12行追加 tcp/110(pop3)。
 源地址和目的地址是所有IP

[root@server postfix]# iptables -I RH-Firewall-1-INPUT 12 -p tcp -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT -m state --state NEW --destination-port 110

◆确认设置

[root@server ~]# iptables -L RH-Firewall-1-INPUT -n --line-numbers
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255
3 ACCEPT esp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT ah -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353
6 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:631
7 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
9 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
10 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:21
11 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:25
12 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:110
13 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 state NEW udp dpt:161
14 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited


第12行已经被追加。

◆保存设置

[root@server ~]# /etc/init.d/iptables save
保存防火墙的规则到 /etc/sysconfig/iptables 中 [ OK ]

这样,重启动的情况下,iptables的设置也不会消失了。

* 有关iptables 的设置,更多详细资料,请参考以下文章:
http://www.linuxmine.com/1611.html

恢复iptables的默认设置

, ,

来自: http://www.Unlinux.com

#
# reset the default policies in the filter table.
#
/usr/local/sbin/iptables -P INPUT ACCEPT
/usr/local/sbin/iptables -P FORWARD ACCEPT
/usr/local/sbin/iptables -P OUTPUT ACCEPT


#
# reset the default policies in the nat table.
#
/usr/local/sbin/iptables -t nat -P PREROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P POSTROUTING ACCEPT
/usr/local/sbin/iptables -t nat -P OUTPUT ACCEPT


#
# flush all the rules in the filter and nat tables.
#
/usr/local/sbin/iptables -F
/usr/local/sbin/iptables -t nat -F


#
# erase all chains that's not default in filter and nat table.
#
/usr/local/sbin/iptables -X
/usr/local/sbin/iptables -t nat -X'

January 2010
S M T W T F S
December 2009February 2010
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30