Reputation: 133
if (!-d $logsDir) {
print "LOGSDIR: [$logsDir] does not exist\n";
}
else {
print "LOGSDIR: [$logsDir] exists\n";
}
I am passing the following value to $logsDir
from command line and getting the following output
LOGSDIR: [c:\temp><] exists
I do have C:\temp
. I know temp><
is not a valid folder name on windows. But shouldn't -d
give me the correct answer saying that this directory does not exist?
thanks
Thanks for the edit and the answer. Here is the modified code and output, it still doesn't work.
use strict;
use warnings;
my $logsDir = $ARGV[0];
if (-d $logsDir) {
print "$logsDir exists";
} else {
print "$logsDir does not exist!";
}
__END__
Results
>perl test60.pl c:\temp
c:\temp exists
>perl test60.pl c:\temp^<^>
c:\temp<> exists
Thanks to melporne, I also tried this
C:\Users\XXXX>dir C:\temp
Volume in drive C is System
Volume Serial Number is XXXX
Directory of C:\temp
09/16/2019 12:07 AM <DIR> .
09/16/2019 12:07 AM <DIR> ..
07/03/2019 11:50 PM 765 abcd.txt
07/04/2019 12:24 AM 765 efgh.txt
07/04/2019 12:41 AM 765 efgh.txt
and so on
C:\Users\XXXX>dir C:\temp^<^>
Volume in drive C is System
Volume Serial Number is XXXX
Directory of C:\
09/16/2019 12:07 AM <DIR> Temp
09/15/2019 05:33 PM <DIR> temp1
11/19/2018 06:06 PM <DIR> Temp;
09/15/2019 12:31 AM <DIR> temparchive
0 File(s) 0 bytes
4 Dir(s) yyyyyyyyyyy bytes free
I do have the above folders, so it looks like it is treating it as temp*. The above result is exactly similar to this
C:\Users\XXXX>dir C:\temp*
Volume in drive C is System
Volume Serial Number is XXXX
Directory of C:\
09/16/2019 12:07 AM <DIR> Temp
09/15/2019 05:33 PM <DIR> temp1
11/19/2018 06:06 PM <DIR> Temp;
09/15/2019 12:31 AM <DIR> temparchive
0 File(s) 0 bytes
4 Dir(s) yyyyyyyyyyy bytes free
Upvotes: 2
Views: 448
Reputation: 556
In windows, if you try to rename(or add) a folder with '<' or '>' character you will get error -
A filename cannot contain any of the following characters: \ / : * ? " < > |
So a file or folder is not supposed to contain these characters. I tried to do multiple runs on my machine similar the program mentioned by you-
1. .\directoryexist.pl c:\Perl64 <-- Exist
2. .\directoryexist.pl c:\Perl64<> <-- Exist
3. .\directoryexist.pl c:\Perl64^<>^ <-- Exist
Now the same thing with double quotes-
4. .\directoryexist.pl "c:\Perl64" <-- Exist
4. .\directoryexist.pl "c:\Perl64<>" <-- Exist
5. .\directoryexist.pl "c:\Perl64^<^>" <-- Not Exist
Now I looked at the answer here - How can I add greater than and less than into a batch file variable which contains the great explanation of this behavior.
Basically the gist is-
Adding '^' before '<' sets the value of "c:\Perl64^<^>" to "c:\Perl64<>" without any affect. When we used double quotes around our input it is taken as it is conataing '^' hence giving the output 'not exist'.
Now, As I mentioned before you cannot have certain character in names. So, when you are checking the existence of "c:\Perk64<>" it is converted to (I hope, but right now I do not have any proof for support) "c:\Perl64" which exist.
Upvotes: 0
Reputation: 85767
The problem lies deeper than Perl. I wrote the following C code to compare:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s NAME\n", argv[0]);
return EXIT_FAILURE;
}
const char *name = argv[1];
struct stat st;
if (stat(name, &st) == 0) {
printf("stat(%s): success\n", name);
switch (st.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFREG: printf("regular file\n"); break;
default: printf("unknown?\n"); break;
}
return EXIT_SUCCESS;
}
printf("stat(%s): error: %s\n", name, strerror(errno));
return EXIT_FAILURE;
}
(Perl's -d
operator is just sugar around a stat
call.)
I compiled it using the (MinGW) gcc that comes with Strawberry Perl:
gcc -Wall -Wextra -pedantic prog.c -o prog
It gives the same results:
C:\***>.\prog "C:\temp<>"
stat(C:\temp<>): success
directory
Thinking that it might be a quirk with the MinGW libraries, I tried the built-in dir
command:
dir "C:\temp<>"
Curiously it doesn't fail, but it lists C:\
(not C:\temp<>
) and shows only the Temp
entry, not the rest of C:\
.
I'm not sure what's going on here.
Upvotes: 2
Reputation: 214
try this
if (-d $logsDir) {
print "$logsDir exists";
} else {
print "$logsDir does not exist!";
}
Upvotes: 0