繁体   English   中英

如何找出程序访问了哪些文件?

[英]How to find out which files the program has accessed?

(Ubuntu linux)我启动了一个程序,如何找到该程序访问了哪个文件和IO?

我知道有一些软件可以使人们在Windows中轻松获取此信息。

您可能会问两个问题之一:

1。

问:如何找出当前正在运行的程序打开了哪些文件?

答:在/proc/<pid>/fd查看。

2。

问:我想知道程序在运行时会打开哪些文件。

答:使用strace工具。 阅读其手册页和其他文档,以获取更多信息。

PS使用strace会减慢程序的执行速度,这一点值得注意。

lsof非常适合通过其PID查找程序的所有打开文件。 只需运行lsof -a -p即可。 它还可以显示打开的套接字。 手册页位于http://linux.die.net/man/8/lsof 除非它具有setuid到root权限并且可以被其他人执行,否则您可能必须以root用户身份运行lsof。

对于IO利用率,请尝试iotop。 iotop需要python,有关它的更多信息,请访问http://guichaz.free.fr/iotop/ 您应该能够使用apt-get安装这两个工具。

这两种工具都无法轻松地找到程序在启动后立即关闭后可能已访问的文件。 例如,对于许多在启动后读取配置文件的应用程序,会发生这种情况。 为了找到这类文件,我编写了一个实用程序,该程序以递归方式查找目录中所有在给定的最后几秒钟内创建,访问或修改的文件。 如果您不知道该程序可能在何处访问了文件,则可以从/搜索整个系统。如果您确实想对可能已访问的文件进行本地化,则可以运行chroot对其进行限制。 下面是该实用程序,我称它为tfind,并在perl中实现。 当不带参数运行时,将打印其用法。 使用它的一种方法是启动程序,几秒钟后运行“ tfind --atime 15 --ctime 15 --mtime 15 /”以查看在过去15秒钟内已访问,创建或修改的所有文件,然后然后删除那些已知可被其他程序访问的文件,例如/ var / log / messages。 其余文件可能是程序访问的文件。

#!/usr/bin/perl

# tfind - find files less than n seconds old
# usage: tfind [ --atime i --ctime j --mtime k ] path

use strict;
use warnings;
use File::Find;
use vars qw/*name/;
*name   = *File::Find::name;
use Getopt::Long;

my $prog = $0;
$prog =~ s,(?:[^\0]*/)*([^\0]+),$1,;
my $usage = "
$prog finds files in path that have been modified, changed or 
accessed within a given number of seconds. The bundled find
utilities only detect time changes to the nearest day.  However,
it can be useful for monitoring to find files modified, changed
or accessed  within shorter time periods.

Usage: $prog [ --help --atime i --ctime j --mtime k ] path

Options

 --atime i    true if file was accessed within the last i seconds,
                where i must be a postive integer or 0
 --ctime j    true if the files status was changed within the last
                j seconds, where j must be a positve integer or 0
 --mtime k    true if the files data was modified within the last
                k seconds, where k must be a positive integer or 0
 --help       shows this help screen

Examples

$prog --atime 2 dir      prints names of files  in dir accessed
                           within the last 2 seconds
$prog --ctime 600 dir    prints names of files in dir with status 
                           changes in the last 10 minutes
$prog --mtime 3600 dir   prints names of files in dir modified
                           within the last hour
$prog --atime 2 --ctime 600 --mtime 3600 dir   
                         prints names of files in dir meeting all
                           three conditions
";

my $opt_help    = '';
my $opt_atime   = '';
my $opt_mtime   = '';
my $opt_ctime   = '';

GetOptions (
  "help"        => \$opt_help,
  "atime=s"     => \$opt_atime,
  "ctime=s"     => \$opt_ctime,
  "mtime=s"     => \$opt_mtime );

if ($opt_help) {
  print "$usage\n";
  exit;
}

unless (@ARGV == 1) {
  print "$usage\n";
  exit;
}

my $path = shift;

my $atime_mark = 0;
my $ctime_mark = 0;
my $mtime_mark = 0;

($opt_atime,$atime_mark) = testoption("atime",$opt_atime);
($opt_ctime,$ctime_mark) = testoption("ctime",$opt_ctime);
($opt_mtime,$mtime_mark) = testoption("mtime",$opt_mtime);

my $findstr;

if (!$opt_atime && !$opt_ctime && !$opt_mtime) {
    exit;
} else {
    $findstr = '
find(\&wanted, $path);

sub wanted {
  my $start = time;
  my ($fsdev,$inode,$mode,$nlink,$uid,$gid,$devid,$size,
    $atime,$mtime,$ctime,$blksize,$blocks) = lstat $_;';

  } if (!$opt_atime && !$opt_ctime && $opt_mtime) {
        $findstr .= '
  if (($start - $mtime) < $mtime_mark) {
    print "$name\n";
  }
}
';
    } elsif ($opt_atime && !$opt_ctime && !$opt_mtime) {
        $findstr .= '
  if (($start - $atime) < $atime_mark) {
    print "$name\n";
  }
}
';
    } elsif (!$opt_atime && $opt_ctime && !$opt_mtime) {
        $findstr .= '
  if (($start - $ctime) < $ctime_mark) {
    print "$name\n";
  }
}
';
    } elsif ($opt_atime && !$opt_ctime && $opt_mtime) {
        $findstr .= '
  if ((($start - $atime) < $atime_mark) &&
      (($start - $mtime) < $mtime_mark)) {
    print "$name\n";
  }
}
';
    } elsif (!$opt_atime && $opt_ctime && $opt_mtime) {
        $findstr .= '
  if ((($start - $ctime) < $ctime_mark) &&
      (($start - $mtime) < $mtime_mark)) {
    print "$name\n";
  }
}
';
    } elsif ($opt_atime && $opt_ctime && !$opt_mtime) {
        $findstr .= '
  if ((($start - $atime) < $atime_mark) &&
      (($start - $ctime) < $ctime_mark)) {
    print "$name\n";
  }
}
';
    } elsif ($opt_atime && $opt_ctime && $opt_mtime) {
        $findstr .= '
  if ((($start - $atime) < $atime_mark) &&
      (($start - $ctime) < $ctime_mark) &&
      (($start - $mtime) < $mtime_mark)) {
    print "$name\n";
  }
}
';
    } else {
        print "$prog: logical error in options values:
  opt_atime = $opt_atime
  opt_ctime = $opt_ctime
  opt_mtime = $opt_mtime\n";
        exit 2;
  }

eval $findstr;

sub testoption {
  my $opt = $_[0];
  my $optarg = $_[1];
  my @out;

  if ($optarg || ($optarg =~ /^\s*[+-]?0\s*$/)) {
    $optarg = trim($optarg);
    if (($optarg =~ /^[+-]?\d+$/) && ($optarg >= 0)) {
      $out[0] = 1;
      $out[1] = $optarg;
      return @out;
    } else {
        print "$opt argument \"$optarg\" is not a positive integer or 0.\n";
        exit;
    }
  } else {
      $out[0] = 0;
      $out[1] = 0;
      return @out;
  }
}

sub trim {
    my @out = @_;
    for (@out) {
        s/^\s+//;
        s/\s+$//;
    }
    return wantarray ? @out : $out[0];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM