<?php

Currently browsing linux

通过shell+crontab实现自动分割nginx日志

最近有几个朋友问这个事情,干脆写出来吧。。
nginx自身不能按天分割日志,因此还是自己动手来吧~
本文提供的这个脚本会把当前的log文件打包为当前日期为文件名的tgz包,并保存到指定目录。

首先把下面的脚本copy保存为/root/daily_logs.sh

#! /bin/bash

nginx_app=/home/nginx/sbin/nginx #设置nginx的目录
logs_dir=/data/logs/ #log目录
bak_dir=/data/logs/bak/ #log备份目录

#先把现有的log文件挪到备份目录临时存放
cd $logs_dir
echo "moving logs"
/bin/mv *.log $bak_dir
sleep 3

#重建nginx log
echo "rebuild logs"
echo "$nginx_app -s reopen"
$nginx_app -s reopen

#按天打包log文件
echo "begining of tar"
cd $bak_dir
/bin/tar czf `date +%Y%m%d`.tgz *.log

#删除备份目录的临时文件
echo "rm logs"
rm -f *.log
echo "done"

并添加执行权限:

chmod +x /root/daily_logs.sh

然后增加crontab,这里以每晚0点执行为例:

[root@localhost ~]# crontab -e
0 0 * * * /root/daily-task.sh > /dev/null 2>&1

保存后退出,以后就可以自动分割nginx的日志啦~

收工。。

linux下根据/proc/stat计算CPU使用情况算法详解

本文是介绍在Linux/unix下如何根据/proc/stat文件的信息计算得到CPU使用率。大多情况下自己做系统监控时都会用到这个文件

首先找来一段扫盲文字“在linux下,CPU利用率分为用户态,系统态和空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行时间。在内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同。系统里定义了一个常数HZ,代表每秒种最小时间间隔的数目。这样jiffies的单位就是1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。 CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。”

下面我们看一下/proc/stat 的内容结构

/bin/cat /proc/stat
cpu  3783155 5336 947214 78774537 115679 6 89497 0
cpu0 871159 806 194940 19851524 8176 0 2221 0
cpu1 918820 1900 203290 19794976 7834 1 1980 0
cpu2 922359 882 213789 19715943 61418 2 14503 0
cpu3 1070815 1747 335193 19412092 38250 1 70791 0
intr 284814153 209329067 3 0 0 4 0 0 0 1 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 252 0 0 0 0 0 0 0 2664133 0 0 0 0 0 0 0 72820689 0 0 0 0 0
ctxt 1591477835
btime 1268412588
processes 1346557
procs_running 1
procs_blocked 1

咋一看去相当的晕,完全不知从何下手。有关文件格式的介绍可以参考:http://www.linuxhowtos.org/System/procstat.htm
下面对输出信息做解释:

CPU时间=user+system+nice+idle+iowait+irq+softirq
“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。

“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
“btime”给出了从系统启动到现在为止的时间,单位为秒。
“processes (total_forks) 自系统启动以来所创建的任务的个数目。
“procs_running”:当前运行队列的任务的数目。
“procs_blocked”:当前被阻塞的任务的数目。
那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:

[code lang="code"]
cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100
[/code]

以下用分别用bash和perl做的一个cpu利用率的计算:
原作者注:以下代码则采用公式为:
[code lang="code"]
total_0USER[0]+NICE[0]+SYSTEM[0]+IDLE[0]+IOWAIT[0]+IRQ[0]+SOFTIRQ[0] total_1=USER[1]+NICE[1]+SYSTEM[1]+IDLE[1]+IOWAIT[1]+IRQ[1]+SOFTIRQ[1] cpu usage=(IDLE[0]-IDLE[1]) / (total_0-total_1) * 100
[/code]

bash 代码:

#!/bin/sh
##echo user nice system idle iowait irq softirq
CPULOG_1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
SYS_IDLE_1=$(echo $CPULOG_1 | awk '{print $4}')
Total_1=$(echo $CPULOG_1 | awk '{print $1+$2+$3+$4+$5+$6+$7}')

sleep 5

CPULOG_2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
SYS_IDLE_2=$(echo $CPULOG_2 | awk '{print $4}')
Total_2=$(echo $CPULOG_2 | awk '{print $1+$2+$3+$4+$5+$6+$7}') 

SYS_IDLE=`expr $SYS_IDLE_2 - $SYS_IDLE_1`

Total=`expr $Total_2 - $Total_1`
SYS_USAGE=`expr $SYS_IDLE/$Total*100 |bc -l`

SYS_Rate=`expr 100-$SYS_USAGE |bc -l`

Disp_SYS_Rate=`expr "scale=3; $SYS_Rate/1" |bc`
echo $Disp_SYS_Rate%

perl 代码:

#!/usr/bin/perl
use warnings;

$SLEEPTIME=5;

if (-e "/tmp/stat") {
	unlink "/tmp/stat";
}
open (JIFF_TMP, ">>/tmp/stat") || die "Can't open /proc/stat file!\n";
open (JIFF, "/proc/stat") || die "Can't open /proc/stat file!\n";
@jiff_0=<JIFF>;
print JIFF_TMP $jiff_0[0] ;
close (JIFF);

sleep $SLEEPTIME;

open (JIFF, "/proc/stat") || die "Can't open /proc/stat file!\n";  @jiff_1=<JIFF>;
print JIFF_TMP $jiff_1[0];
close (JIFF);
close (JIFF_TMP);

@USER=`awk '{print \$2}' "/tmp/stat"`;
@NICE=`awk '{print \$3}' "/tmp/stat"`;
@SYSTEM=`awk '{print \$4}' "/tmp/stat"`;
@IDLE=`awk '{print \$5}' "/tmp/stat"`;
@IOWAIT=`awk '{print \$6}' "/tmp/stat"`;
@IRQ=`awk '{print \$7}' "/tmp/stat"`;
@SOFTIRQ=`awk '{print \$8}' "/tmp/stat"`;

$JIFF_0=$USER[0]+$NICE[0]+$SYSTEM[0]+$IDLE[0]+$IOWAIT[0]+$IRQ[0]+$SOFTIRQ[0];
$JIFF_1=$USER[1]+$NICE[1]+$SYSTEM[1]+$IDLE[1]+$IOWAIT[1]+$IRQ[1]+$SOFTIRQ[1];
$SYS_IDLE=($IDLE[0]-$IDLE[1]) / ($JIFF_0-$JIFF_1) * 100;  $SYS_USAGE=100 - $SYS_IDLE;

printf ("The CPU usage is %1.2f%%\n",$SYS_USAGE);

参考原文:http://server.51cto.com/sCollege-188250.htm

一个简单的由perl实现的端口监控脚本,邮件通知+手机短信通知

先说一下原理,1,根据端口的响应时间来判断是否宕掉;2,如果宕掉了就发一封邮件到指定邮箱(注意:需要用到sendmail, 要安装配置好)
另一个,如果需要手机短信通知。其实不需要搞什么飞信接口了,直接去注册一个139邮箱,免费的邮件到达短信通知,包括邮件内容的! 如果不想用139邮箱,也可以选择qq邮箱的短信通知服务。或其他服务商,任你选择了。

#!/usr/bin/perl -X

use IO::Socket;

##############################
# Constant define (configure)
##############################
# mail config
use constant MAIL_ADDR          => ('to'=>'zhys9@139.com', 'from'=>'nginx.org@gmail.com');
# common config
use constant MD5SUM_FILE        => '/tmp/__monitor_md5sum_hash';
# apache
use constant WEBSERVER_PORT        => 80;
use constant WEBSERVER_HOSTS     => ('localhost');
# mysql
use constant MYSQL_PORT         => 3306;
use constant MYSQL_HOSTS      => ('localhost');
# memcache
use constant PHPFCGI_PORT      => 9000;
use constant PHPFCGI_HOSTS   => ('localhost');

##############################
# Server port is alive check
##############################
sub check_server_alive {
    my($server, $port) = @_;

    $sock = IO::Socket::INET->new(PeerAddr=>$server, PeerPort=>$port, Proto=>'tcp', Timeout=>1);
    if (!$sock){
        return 0;
    }
    $sock->close();
    return 1;
}

##############################
# Send notice mail
##############################
sub send_mail {
    my ($subject, $content) = @_;;
    my %mailaddr = MAIL_ADDR;

    open(MAIL, "|/usr/sbin/sendmail -t");

    ## Mail Header
    print MAIL "To: $mailaddr{'to'}\n";
    print MAIL "From: $mailaddr{'from'}\n";
    print MAIL "Subject: $subject\n\n";

    ## Mail Body
    print MAIL "$content\n";

    close(MAIL);

}

##############################
# Check server alive main
##############################
sub monitor_main {
    # check apache
    foreach $item (WEBSERVER_HOSTS) {
        if (!check_server_alive($item, WEBSERVER_PORT)) {
            send_mail("$item web server is down", "$item web server is down. please timely restoration");
        }
    }
    # check mysql
    foreach $item (MYSQL_HOSTS) {
        if (!check_server_alive($item, MYSQL_PORT)) {
        print("mysql is down.");
            send_mail("$item mysql server is down", "$item mysql server is down. please timely restoration");
        }
    }
    # check fast-cgi
    foreach $item (PHPFCGI_HOSTS) {
        if (!check_server_alive($item, PHPFCGI_PORT)) {
            send_mail("$item fast-cgi is down", "$item fast-cgi is down. please timely restoration");
        }
    }
}

##############################
# Main running
##############################

monitor_main();

本脚本参考文档:
http://blog.csdn.net/re_think/archive/2009/06/25/4296833.aspx
perl发送邮件:http://www.cyberciti.biz/faq/sending-mail-with-perl-mail-script/

系统监控配置之cacti+rrdtool+netsnmp

一,安装rrdtool 官网: http://oss.oetiker.ch/rrdtool/

/usr/bin/wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.2.tar.gz
/bin/tar xzf rrdtool-1.4.2.tar.gz
cd rrdtool-1.4.2
./configure --prefix=/home/rrdtool

提示以下warning信息:
configure: WARNING:
—————————————————————————-
* I found a copy of pkgconfig, but there is no pangocairo.pc file around.
  You may want to set the PKG_CONFIG_PATH variable to point to its
  location.
—————————————————————————-

configure: WARNING:
—————————————————————————-
* I could not find a working copy of pangocairo. Check config.log for hints on why
  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
  so that compiler and the linker can find libpango-1.0 and its header files. If
  you have not installed pangocairo, you can get it either from its original home on

     http://ftp.gnome.org/pub/GNOME/sources/pango/1.17

  You can find also find an archive copy on

     http://oss.oetiker.ch/rrdtool/pub/libs

  The last tested version of pangocairo is 1.17.

       LIBS=-lm  -lglib-2.0 
   LDFLAGS= -L/lib64   
  CPPFLAGS= -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include 

—————————————————————————-
               
checking for xmlParseFile in -lxml2… yes
checking libxml/parser.h usability… yes
checking libxml/parser.h presence… yes
checking for libxml/parser.h… yes
configure: error: Please fix the library issues listed above and try again.

信息表明缺了pango的头文件,因此要先安装pango-devel

/usr/bin/yum install pango-devel

接下来重新编译

./configure --prefix=/home/rrdtool

这次编译通过:
Config is DONE!

make && make install

做一个软连接

/bin/ln -s /home/rrdtool/bin/* /usr/local/bin/
cd ..

这样就完成了rrdtool的安装,

 

二,安装net-snmp 官网: http://www.net-snmp.org/

先下载net-snmp的最新版本5.5

/usr/bin/wget http://downloads.sourceforge.net/project/net-snmp/net-snmp/5.5/net-snmp-5.5.tar.gz?use_mirror=nchc
/bin/tar xzf net-snmp-5.5.tar.gz
cd net-snmp-5.5
./configure #一切按照默认值来编译(默认安装到/usr/loca/)
make && make install

运行以下snmpget,检查是否安装成功

/usr/loca/bin/snmpget

我这里就遇到了问题,提示信息是:
/usr/local/bin/snmpget: error while loading shared libraries: libnetsnmp.so.20: cannot open shared object file: No such file or directory
先通过ldd查看snmpget需要加载哪些库

[root@test_server net-snmp-5.5]# /usr/bin/ldd /usr/local/bin/snmpget
        libnetsnmp.so.20 => not found
        libcrypto.so.6 => /lib64/libcrypto.so.6 (0×0000003c1fc00000)
        libc.so.6 => /lib64/libc.so.6 (0×0000003c1d000000)
        libdl.so.2 => /lib64/libdl.so.2 (0×0000003c1d400000)
        libz.so.1 => /usr/lib64/libz.so.1 (0×0000003c1ec00000)
        /lib64/ld-linux-x86-64.so.2 (0×0000003c1cc00000)
可见需要加载的库文件大都放在/lib64/下的;
再查一下libnetsnmp.so.20是在什么位置

/usr/bin/whereis libnetsnmp.so.20
libnetsnmp.so: /usr/local/lib/libnetsnmp.so /usr/local/lib/libnetsnmp.so.20

ok, 至此我们就知道怎么解决问题了:

/bin/ln -s /usr/local/lib/libnetsnmp.so.20 /lib64/libnetsnmp.so.20

再执行一次snmpget

/usr/local/bin/snmpget
Created directory: /var/net-snmp
Created directory: /var/net-snmp/mib_indexes
No hostname specified.
USAGE: snmpget [OPTIONS] AGENT OID [OID]...

  Version:  5.5
  Web:      <a href="http://www.net-snmp.org/">http://www.net-snmp.org/</a>
  Email:    <a href="mailto:net-snmp-coders@lists.sourceforge.net">net-snmp-coders@lists.sourceforge.net</a>

OPTIONS:
  -h, --help            display this help message
...

一切OK

三, 安装cacti 官网: http://www.cacti.net/
值得注意的是cacti的环境需求:
RRDTool 1.0.49 or 1.2.x or greater
MySQL 4.1.x or 5.x or greater
PHP 4.3.6 or greater, 5.x greater highly recommended for advanced features
A Web Server e.g. Apache or IIS

先确认是否满足,然后:

cd ..
/usr/bin/wget http://www.cacti.net/downloads/cacti-0.8.7e.tar.gz
/bin/tar xzf cacti-0.8.7e.tar.gz
/bin/mv cacti-0.8.7e cacti

然后就可以把cacti转移到web目录下

/bin/mv cacti /data/htdocs/cacti
cd /data/htdocs/cacti
/home/mysql/bin/mysql cacti &lt; cacti.sql #导入数据库结构
/bin/chown www:www -R .
/bin/vi include/config.php

修改数据库连接信息:
$database_default = “cacti”;
$database_hostname = “localhost”;
$database_username = “root”;
$database_password = “”;
$database_port = “3306″;

增加后台任务,每两分钟搜集一次数据

*/5 * * * * /usr/local/bin/php /usr/local/apche2/htdocs/cacti/poller.php > /dev/null 2>&1

接下来就从前台访问cacti的安装目录
http://zhys9.com/cacti/install/
按照以下图片中的标红提示完成配置

1

2

3
最后通过默认账号密码: admin/admin 登录,然后系统会提示修改密码;

 

接下来的事情就只是用了 ;)

nginx为目录增加auth_basic认证

之前几次配置一直失败,刚才闲来无事试了下。。居然成功了!记录一下

由于nginx的auth_basic认证采用的是与apache兼容密码文件,因此需要用到apache的htpasswd用以生成密码文件。

首先且到root, 安装httpd (如果已经安装的,可以跳过)

/usr/bin/yum install httpd

安装完毕之后就可以先找一下htpasswd的位置

/usr/bin/whereis htpasswd
htpasswd: /usr/bin/htpasswd /usr/share/man/man1/htpasswd.1.gz

可以看到路径是 /usr/bin/htpasswd

接下来就生成密码文件并添加一个用户(master)吧

/usr/bin/htpasswd -c /home/nginx/conf/authdb master

会得到以下提示信息
New password:
输入密码之后,系统会要求再次输入密码。确认之后即添加完毕。

然后就是修改nginx的配置文件,在需要使用auth_basic添加配置;
例如需要在 http://zhys9.com/secret/ 目录使用;

/bin/vi /home/nginx/conf/nginx.conf

找到zhys9.com对应的server段

增加一个location段

location /secret/
{
    auth_basic  "Secret Garden.";
    auth_basic_user_file  /home/nginx/conf/authdb;
}

保存退出之后,要记得reload一下nginx

/home/nginx/sbin/nginx -s reload

ok, 访问http://zhys9.com/secret/ 看看是否生效了?

centos下的ncftpd安装配置添、加用户

本来在测试机上一直都是用rz和sz上传下载文件的,但是遇到大批量时就感觉非常麻烦。。或者是用rsync? 其实也是不错的选择,只是有没有不需要主机权限的方式呢?

没错,就是ftp啦。。 目前公司用的比较多的是ncftpd所以这里也选择它了。下面进入安装阶段:

wget ftp://ftp.ncftp.com/ncftpd/2.8.6/ncftpd-2.8.6-linux-x86_64-export.tar.gz
tar xzf ncftpd-2.8.6-linux-x86_64-export.tar.gz
cd ncftpd-2.8.6
#安装到/home/ncftpd/ 并指定端口为11121
./install_ncftpd.pl --prefix=/home/ncftpd --port=11121

接下来是配置:

修改一下ftp用户登录认证相关的设置

vi /home/ncftpd/etc/ncftpd/domain.cf

77行修改为:server-type=non-anonymous-only
114行修改为:passwd=/home/ncftpd/passwd.db

以交互式增加一个用户:

/home/ncftpd/sbin/ncftpd_passwd -f /home/ncftpd/passwd.db -A

根据SHELL的提示信息很方便就可以增加ftp用户了。如果只是自己使用的话整个过程需要注意的就只是以下几项:
Short user name     (账号名)
Password    (密码)
UID    (uid,我用的是99)
GIDs    (gid,我用的也是99)
Home directory    (ftp用户登录后的默认目录,访问权限被限定到此目录之下)
Shell    (ftp用户可以使用的Shell,出于安全考虑最好还是使用 /sbin/nologin)

值得注意一点是uid和gid,我这里使用的都是99即nobody;

最后重启一下ncftpd:

/home/ncftpd/sbin/restart_ncftpd

现在就可以用ftp客户端连接了(记得要用端口11121喔),一切看上去都是那么简单。

centos下nginx+php+mysql的自动安装SHELL

今天安装了一下新的测试环境,因为不想反复输入命令。。也就有了本文章。

打算找一找自动安装的脚本,一键安装自然是追求自动化的崇高追求。。gg后发现真的有不少,于是找了一个看了看,没错!是我要的。

因为安装目录、配置方面有些不同于是拿来修改一下就可以方便使用了~

修改后的脚本:lnmp-auto-install

安装目录是:
nginx: /home/nginx
php: /home/php
mysql: /home/mysql
eaccelerator: /home/eaccelerator

至于版本号就不说了吧,基本都是比较新的稳定版本了。

启动nginx:  /etc/init.d/nginx start
启动php-fpm: /home/nginx/sbin/php-fpm start
启动mysql: /etc/init.d/mysql start

感谢原作者Licess’s,以及提供镜像下载的vpser

Linux下恢复被误删除的文件

作为一个多用户、多任务的操作系统,linux下的文件一旦被删除,是难以恢复的。尽管删除命令只是在文件节点中作删除标记,并不真正清除文件内容,但 是其他用户和一些有写盘动作的进程会很快覆盖这些数据。不过,对于家庭单机使用的linux,或者误删文件后及时补救,还是可以恢复的。

  1、Ext2文件系统结构的简单介绍

  在linux所用的Ext2文件系统中,文件是以块为单位存储的,默认情况下每个块的大小是1K,不同的块以块号区分。每个文件还有一个节点, 节点中包含有文件所有者,读写权限,文件类型等信息。对于一个小于12个块的文件,在节点中直接存储文件数据块的块号。如果文件大于12个块,那么节点在 12个块号之后存储一个间接块的块号,在这个间接块号所对应的块中,存储有256个文件数据块的块号(Ext2fs中每个块号占用4字节,这样一个块中所 能存储的块号就是1024/4=256)。如果有更大的文件,那么还会在节点中出现二级间接块和**间接块。

  2、恢复被误删文件的方法

  大多数linux发行版都提供一个debugfs工具,可以用来对Ext2文件系统进行编辑操作。不过在使用这个工具之前,还有一些工作要做。

  首先以只读方式重新挂载被误删的文件所在分区。使用如下命令:(假设文件在/usr分区)

  mount –r –n –o remount /usr -r表示只读方式挂载;-n表示不写入/etc/mtab,如果是恢复/etc上的文件,就加上这个参数。如果系统说xxx partion busy,可以用fuser命令查看一下是哪些进程使用这个分区上的文件:

  fuser –v –m /usr

  如果没有什么重要的进程,用以下命令停掉它们:

  fuser -k –v –m /usr

  然后就可以重新挂载这些文件系统了。

  如果是把所有的文件统一安装在一个大的/分区当中,可以在boot提示符下用linux single进入单用户模式,尽量减少系统进程向硬盘写入数据的机会,要不干脆把硬盘挂在别的机器上。另外,恢复出来的数据不要写到/上面,避免破坏那些 有用的数据。如果机器上有dos/windows,可以写到这些分区上面:

  mount –r –n /dev/hda1 /mnt/had

  然后就可以执行debugfs:(假设linux在 /dev/hda5)

  #debugfs /dev/hda5

  就会出现debugfs提示符debugfs:

  使用lsdel命令可以列出很多被删除的文件的信息:

  debugfs:lsdel

  debugfs: 2692 deleted inodes found.

  Inode Owner Mode Size Blocks Time deleted

  164821 0 100600 8192 1/ 1 Sun May 13 19:22:46 2001

  …………………………………………………………

  36137 0 100644 4 1/ 1 Tue Apr 24 10:11:15 2001

  196829 0 100644 149500 38/ 38 Mon May 27 13:52:04 2001

  debugfs:

  列出的文件有很多(这里找到2692个),第一字段是文件节点号,第二字段是文件所有者,第三字段是读写权限,接下来是文件大小,占用块数,删除时间。

然后就可以根据文件大小和删除日期判断那些是我们需要的。比如我们要恢复节点是196829的文件:

  可以先看看文件数据状态:

  debugfs:stat <196829>

  Inode: 196829 Type: regular Mode: 0644 Flags: 0×0 Version: 1

  User: 0 Group: 0 Size: 149500

  File ACL: 0 Directory ACL: 0

  Links: 0 Blockcount: 38

  Fragment: Address: 0 Number: 0 Size: 0

  ctime: 0×31a9a574 — Mon May 27 13:52:04 2001

  atime: 0×31a21dd1 — Tue May 21 20:47:29 2001

  mtime: 0×313bf4d7 — Tue Mar 5 08:01:27 2001

  dtime: 0×31a9a574 — Mon May 27 13:52:04 2001

  BLOCKS:

  594810 594811 594814 594815 594816 594817 ………………………………….

  TOTAL: 38

  然后就可以用dump指令恢复文件:

  debugfs:dump <196829> /mnt/hda/01.sav

  这样就把文件恢复出来了。退出debugfs:

  debugfs:quit

  另一种方法是手工编辑inode:

  debugfs:mi <196829>

  Mode [0100644]

  User ID [0]

  Group ID [0]

  Size [149500]

  Creation time [0x31a9a574]

  Modification time [0x31a9a574]

  Access time [0x31a21dd1]

  Deletion time [0x31a9a574] 0

  Link count [0] 1

  Block count [38]

  File flags [0x0]

  Reserved1 [0]

  File acl [0]

  Directory acl [0]

  Fragment address [0]

  Fragment number [0]

  Fragment size [0]

  Direct Block #0 [594810]

  …………………………….

  Triple Indirect Block [0]

  使用mi指令后每次显示一行信息以供编辑,其它行可以直接按回车表示确认,把deletion time改成0(未删除),Link count改成1。改好后退出debugfs:

  debugfs:quit

  然后用fsck检查/dev/hda5

  fsck /dev/hda5

  程序会说找到丢失的数据块,放在lost+found里面。这个目录里的文件就是我们要的东东。