Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Question about rmtree & mkpath

Status
Not open for further replies.

whn

Programmer
Oct 14, 2007
265
0
0
US
In my code, there is one line like this:

Code:
mkpath($DIR, 0, 0777);

It does make the subdir with a mode 755. Why not 777?

In addition, I also have one line like this:

Code:
rmtree($DIR);

This line works fine on aix, redhat, suse. But not on windows. The error message I got on windows is:

Can't make directory mydir read+writeable: Bad file number at myperl.pl line 522.

Please note that line 522 is the line number of rmtree().

I have made sure the mode of the subdir to be removed by rmtree is 755 to the user who is running the perl code. Therefore, it should not be a permission problem.

Thank you for you help.
 
0777 is supposed to be the default for this module. Try
Code:
mkpath($DIR, 1);
and see what happens (the 1 is for verbose; it might give you more information)

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Read about umask here

You should turn up that command and also add
or die "can't do blah:$!\n";



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
I meant to say you should turn up verbose on that command.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Thank you all for your help. I did some further tests and still got puzzled.
So, let me show you my test codes first (named as tt.pl):

Code:
#! /usr/bin/perl

use strict;
use warnings;
use File::Path;

my $os = `uname -s`;
chomp($os);
$os = lc($os);

# The value of '$remote' is my unix homedir which is mounted 
# to a local unix server through vfs at the mount point '/mnt'
# and is mapped as 'Y:' drive on a local windows server
# The umask on my unix user account is set to '0022'.
my $remote = '/mnt';
my $tmpDir = '/temp';
my $baseDir = $remote.$tmpDir;
my $subDir = $baseDir.'/subDir';
if($os =~ /windows/) {
	$baseDir = 'Y:'.$tmpDir;
	$subDir = $baseDir.'/subDir4win';
}
print "\$os = $os, \$baseDir = $baseDir, \$subDir = $subDir\n";

if(! -d $baseDir || ! -w $baseDir) {
	print "Either '$baseDir' does not exist or it is not writable. Exit...\n";
	exit;

}
if(-d $subDir) {
	print "To remove subDir '$subDir'.\n";
	rmtree($subDir, 1) or warn "couldn't rmDir: $!\n"; [b]# This is line 32.[/b]
	if(! -d $subDir) {
		print "The subDir '$subDir' has been removed.\n";
	}
}
if(! -d $subDir) {
	print "Ready to make subDir '$subDir'.\n";
	mkpath($subDir, 1, 0777) or warn "couldn't mkDir: $!\n";
	if(-d $subDir) {
		print "The subDir '$subDir' has been created.\n";
	}
}

Below is the output from a test run on a linux box. Note that 'subdir' exists before the test run.
Code:
[COLOR=red]# ls -l /mnt/temp[/color]
total 0
drwxr-xr-x  2 nfsnobody nfsnobody 80 Apr 24 [b][COLOR=blue]11:59 subDir[/color][/b]
[COLOR=red]# whoami[/color]
root
[COLOR=red]# umask[/color]
0022
[COLOR=red]# ./tt.pl[/color]
$os = linux, $baseDir = /mnt/temp, $subDir = /mnt/temp/subDir
To remove subDir '/mnt/temp/subDir'.
rmdir /mnt/temp/subDir
The subDir '/mnt/temp/subDir' has been removed.
Ready to make subDir '/mnt/temp/subDir'.
mkdir /mnt/temp/subDir
The subDir '/mnt/temp/subDir' has been created.
[COLOR=red]# ls -l /mnt/temp[/color]
total 0
drwxr-xr-x  2 nfsnobody nfsnobody 80 Apr 24 [b][COLOR=blue]12:03 subDir[/color][/b]

As you can see here, the newly created 'subDir' is in a mode of 755, not 777 as expected.

Below is the output from a test run on a windows box. Note that 'subDir4win' does not exists before the test run.
Code:
[COLOR=red]Y:\test\perl>whoami[/color]
LCLE220\Administrator

[COLOR=red]Y:\test\perl>ls -l Y:/temp[/color]
total 0
drwxrwxrwx   1 S-1-22-1-60001  S-1-22-2-60001        0 Apr 24 12:03 subDir

[COLOR=red]Y:\test\perl>tt.pl[/color]
$os = windows_nt, $baseDir = Y:/temp, $subDir = Y:/temp/subDir4win
Ready to make subDir 'Y:/temp/subDir4win'.
mkdir Y:/temp/subDir4win
The subDir 'Y:/temp/subDir4win' has been created.

[COLOR=red]Y:\test\perl>ls -l Y:/temp[/color]
total 0
drwxrwxrwx   1 S-1-22-1-60001  S-1-22-2-60001        0 Apr 24 12:03 subDir
drwxrwxrwx   1 S-1-22-1-81815  S-1-22-2-43093        0 Apr 24 [b][COLOR=blue]12:13 subDir4win[/color][/b]

[COLOR=red]Y:\test\perl>tt.pl[/color]
$os = windows_nt, $baseDir = Y:/temp, $subDir = Y:/temp/subDir4win
To remove subDir 'Y:/temp/subDir4win'.
[b]Can't make directory Y:/temp/subDir4win read+writeable: Bad file number at Y:\test\perl\tt.pl line [COLOR=red]32[/color]
Can't make directory Y:/temp/subDir4win writeable:  at Y:\test\perl\tt.pl line [COLOR=red]32[/color][/b]
rmdir Y:/temp/subDir4win
The subDir 'Y:/temp/subDir4win' has been removed.
Ready to make subDir 'Y:/temp/subDir4win'.
mkdir Y:/temp/subDir4win
The subDir 'Y:/temp/subDir4win' has been created.

[COLOR=red]Y:\test\perl>ls -l Y:/temp[/color]
total 0
drwxrwxrwx   1 S-1-22-1-60001  S-1-22-2-60001        0 Apr 24 12:03 subDir
drwxrwxrwx   1 S-1-22-1-81815  S-1-22-2-43093        0 Apr 24 [b][COLOR=blue]12:17 subDir4win[/color][/b]

As you can see here, 'subDir4win' did get recreated! But why did I still get the error message?

And I have one more question about my test code. I had this problem many years ago and forgot how to solve it.
Code:
[COLOR=red]# uname -s[/color]
HP-UX
[COLOR=red]# perl -v[/color]

This is perl, v5.8.3 built for PA-RISC2.0-thread-multi-LP64
(with 8 registered patches, see perl -V for more detail)
......
......
[COLOR=red]# ./tt.pl[/color]
Can't locate strict.pm in @INC (@INC contains: ......

Thank you so much for your time and kind advices!!

 
I'm still looking over you code. But you showed that your umask is 0022. So when you create files as 777, you have to subtract the usmask from it to get what it will really be. I'm not sure if you can fool umask with 799, or if you just need to chmod it to 777.

As for the windows permissions, they are completely different than unix permissions. I don't know how it well it plays with a unix type of permission. How about just createing the directory, and if the OS is not windows then chmoding it to whatever you want?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Thank you, travs.

What about my last question: Can't locate strict.pm in @INC? Could you please me how to solve it?

In addition, I have noticed the following:

On windows, rmtree can ONLY remove an EMPTY dir, while on unix, rmtree will perform like the unix command 'rmdir -r'.

In addition, on windows, unlink() does not work. I have to use system("rm *") to remove the files. What a pain!
 
I have no problem using unlink in windows. I think you need to use glob if you are trying to unlink more than one file at a time or from the documentation unlink <*.bak>

I think you could just push the path of strict.pm into @INC.
push @INC, "/path/to/strict.pm";


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
I think I found the problem, at least partially.

The line below sets $basedir on Y: drive, which is a mount point.
Code:
$baseDir = 'Y:'.$tmpDir;
{/code]

Instead, the line below will work fine w/o any error messages:
[code]
$baseDir = 'C:'.$tmpDir;

It seems that unix can handle nfs mount drive ok while windows does not?
 
I have no problem handling mapped drives.. but I normally map them, use them, then unmap them all with in the script.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top