patternMinor
Perl script for finding all unowned files and directories on Unix
Viewed 0 times
scriptunixallperlunownedfilesforfindinganddirectories
Problem
(Originally posted on Stack Overflow)
Following my findings and suggestions in my other post How to exclude a list of full directory paths in find command on Solaris, I have decided to write a Perl version of this script and see how I could optimize it to run faster than a native find command. So far, the results are impressive!
The purpose of this script is to report all unowned files and directories on a Unix system for audit compliance. The script has to accept a list of directories and files to exclude (either by full path or wildcard name), and must take as little processing power as possible. It is meant to be run on hundreds of Unix systems that we (the company I work for) support, and has be able to run on all those Unix systems (multiple OS, multiple platforms: AIX, HP-UX, Solaris and Linux) without us having to install or upgrade anything first. In other words, it has to run with standard libraries and binaries we can expect on all systems.
I have not yet made the script argument-aware, so all arguments are hard-coded in the script. I plan on having the following arguments in the end and will probably use getopts to do it:
Here is the source I have done so far:
```
#! /usr/bin/perl
use strict;
use File::Find;
# Full paths of directories to prune
my @exclude_dirs = ('/dev','/proc','/home');
# Basenames or wildcard names of directories I want to prune
my $exclude_dirs_wildcard = '.svn';
# Full paths of files I want to ignore
my @exclude_files = ('/tmp/test/dir3/.svn/svn_file1.txt','/tmp/test/dir3/.svn/svn_file2.txt');
# Basenames of wildcard names of files I wa
Following my findings and suggestions in my other post How to exclude a list of full directory paths in find command on Solaris, I have decided to write a Perl version of this script and see how I could optimize it to run faster than a native find command. So far, the results are impressive!
The purpose of this script is to report all unowned files and directories on a Unix system for audit compliance. The script has to accept a list of directories and files to exclude (either by full path or wildcard name), and must take as little processing power as possible. It is meant to be run on hundreds of Unix systems that we (the company I work for) support, and has be able to run on all those Unix systems (multiple OS, multiple platforms: AIX, HP-UX, Solaris and Linux) without us having to install or upgrade anything first. In other words, it has to run with standard libraries and binaries we can expect on all systems.
I have not yet made the script argument-aware, so all arguments are hard-coded in the script. I plan on having the following arguments in the end and will probably use getopts to do it:
-d = comma delimited list of directories to exclude by path name
-w = comma delimited list of directories to exclude by basename or wildcard
-f = comma delimited list of files to exclude by path name
-i = comma delimited list of files to exclude by basename or wildcard
-t:list|count = Defines the type of output I want to see (list of all findinds, or summary with count per directory)Here is the source I have done so far:
```
#! /usr/bin/perl
use strict;
use File::Find;
# Full paths of directories to prune
my @exclude_dirs = ('/dev','/proc','/home');
# Basenames or wildcard names of directories I want to prune
my $exclude_dirs_wildcard = '.svn';
# Full paths of files I want to ignore
my @exclude_files = ('/tmp/test/dir3/.svn/svn_file1.txt','/tmp/test/dir3/.svn/svn_file2.txt');
# Basenames of wildcard names of files I wa
Solution
Overall it looks clean and simple. Good job. Here are some things I noticed:
- You should use
use warningsfor production level code. It's odd that you usestrictbut notwarnings.
List::UtilorList::MoreUtilsshould have a suitable replacement for yourin_array()function if you're interested or have it installed on all your systems.
- If you're using a Perl version >= 5.10, you can replace
in_arraywith the smart match operator~~.
- Don't let your exclude lists get too big as storing them in an array an iterating through them is an O(n) operation. A hash lookup may be faster for large lists and would de-dup for you automatically.
- Using
&before calling asubis pretty much deprecated. Just call it directly.
- The shebang line
/usr/bin/env perlis more portable than/usr/bin/perl
- You
statyour file$nameover and over for all your various tests.stat()it once, save the results, then re-use those results for all your tests. Remember that all tests like -d, -l and -f arestat()calls internally. Read up on the Perlstatcall and all the fields to help determine how to re-create the -d, -l, and -f checks against the returned data.
Context
StackExchange Code Review Q#5545, answer score: 5
Revisions (0)
No revisions yet.