I need help with this program. As a part of my project I need to create a directory. I was using the system function to do this, but later was told that Perl has a builtin called mkdir.
I'm on Ubuntu 10.04. The problem is mkdir
does not seem to work as needed.
It creates the directory but the permissions are different. Here is my function that creates the directory:
sub createDir {
my ($dir,$perm) = @_;
unless(-d $dir) {
mkdir $dir,$perm or die "$!";
}
}
and I call it in many parts of my program as:
createDir('.today','0755');
the directory .today gets created but the problem is with permissions,
it does not have the 0755
permission.
What am I doing wrong?
My Perl details are:
$perl -v This is perl, v5.8.8 built for x86_64-linux-thread-multi
You are passing the permission as a string. mkdir
expects it to be numeric. But an octal number inside a string is interpreted as a decimal. So '0755'
is being interpreted as decimal 755
and is being used by mkdir
.
To fix this you can call the subroutine passing it numeric permission:
createDir('.today',0755);
Alternatively you can use make use of the oct
function to convert the octal string into a numeric value.
Subroutine call remains the same:
createDir('.today','0755');
but its definition changes to use the oct
function as:
mkdir $dir,oct($perm) or die "$!";
After you fix codeaddict's string versus number issue and note tchrist's umask issue you should call chmod on the new directory after creating it if you need specific permissions.
I usually call mkdir without the mask and then chmod the directory to the permissions I want.
Check these from the shell:
$ perldoc -f mkdir
$ perldoc -f chmod
$ perldoc -f unmask
You can also set the umask to zero before calling mkdir, you'd need to do it this way if you need to create the directory with the correct permissions atomically. Something like this is probably what you're looking for:
sub createDir {
my ($dir, $perm) = @_;
if(!-d $dir) {
my $old = umask(0);
mkdir($dir, $perm) or die "$!";
umask($old);
}
else {
chmod($dir, $perm);
}
}
The second argument to mkdir
is not the creation mode. It is a mask which will be &
ed with ~umask
to determine the creation mode. If you specify an argument of 0755 and your umask is 027, then 0755 &~ 0027 == 0750
. Make sure to keep everything in octal, not decimal.
There are also constants for these things available via use POSIX qw[ :sys_stat_h ]
, such as S_IRWXU
, S_IWGRP
, and S_ISVTX
, but those may be more trouble than they're worth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With