Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 524 forks source link

-e on symlink doesn't always succeed? #376

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#1211 (status was 'resolved')

Searchable as RT1211$

p5pRT commented 24 years ago

From @vlbrown

Try this little script​:

  #!/usr/bin/perl  
  `touch ./foo`;   symlink ("./foo"\, "./foolink");   print `ls -l ./foo ./foolink`;  
  if (-e "./foo") {   print "1​: file ./foo exists\n";   }   if (-l "./foo") {   print "1​: file ./foo is a link\n";   }   if (-e "./foolink") {   print "1​: file ./foolink exists\n";   }   if (-l "./foolink") {   print "1​: file ./foolink is a link\n";   }  
  `touch tmp/foo`;   symlink ("tmp/foo"\, "tmp/foolink");   print `ls -l tmp/foo tmp/foolink`;  
  if (-e "tmp/foo") {   print "2​: file tmp/foo exists\n";   }   if (-l "tmp/foo") {   print "2​: file tmp/foo is a link\n";   }   if (-e "tmp/foolink") {   print "2​: file tmp/foolink exists\n";   }   if (-l "tmp/foolink") {   print "2​: file tmp/foolink is a link\n";   } This prints​:

  -rw-rw-r-- 1 vlb noodle 0 Aug 12 17​:16 ./foo   lrwxrwxrwx 1 vlb noodle 3 Aug 12 16​:53 ./foolink -> foo   1​: file ./foo exists   1​: file ./foolink exists   1​: file ./foolink is a link   -rw-rw-r-- 1 vlb noodle 0 Aug 12 17​:16 tmp/foo   lrwxrwxrwx 1 vlb noodle 7 Aug 12 17​:04 tmp/foolink -> tmp/foo   2​: file tmp/foo exists   2​: file tmp/foolink is a link

I should see   2​: file tmp/foolink exists

When I use   if (-e "symlink") or   if (-e "./symlink") and "symlink" is a symbolic link\, I get success

When I try to test a path\, such as   if (-e "tmp/symlink") I get failure. However   if (-l "tmp/symlink") succeeds.

If -l returns success\, then the file (a link) must also exist; but under certain circumstances\, -e fails.

Perl Info ``` Site configuration information for perl 5.00502: Configured by rdm at Sun Feb 7 16:25:31 PST 1999. Summary of my perl5 (5.0 patchlevel 5 subversion 2) configuration: Platform: osname=freebsd, osvers=2.2.8-release, archname=i386-freebsd uname='freebsd cfcl.com 2.2.8-release freebsd 2.2.8-release #0: fri jan 15 18:39:18 pst 1999 rdm@cfcl.com:usrsrcsyscompilefreebie i386 ' hint=recommended, useposix=true, d_sigaction=define usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cc', optimize='-O', gccversion=2.7.2.1 cppflags='-I/usr/local/include' ccflags ='-I/usr/local/include' stdchar='char', d_stdstdio=undef, usevfork=true intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='ld', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /usr/lib libs=-ldb -lm -lc -lcrypt libc=/usr/lib/libc.so.3.1, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-DPIC -fpic', lddlflags='-Bshareable -L/usr/local/lib' Locally applied patches: @INC for perl 5.00502: /usr/local/lib/perl5/5.00502/i386-freebsd /usr/local/lib/perl5/5.00502 /usr/local/lib/perl5/site_perl/5.005/i386-freebsd /usr/local/lib/perl5/site_perl/5.005 . Environment for perl 5.00502: HOME=/home/vlb LANG (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/vlb/bin:/usr/local/bin:/usr/local/nib:/usr/bin:/bin:/etc:/sbin:/usr/sbin:/usr/local/games:/usr/games:.:/home/rdm/bin:/home/vlb/projex/ptf/bin PERL_BADLANG (unset) SHELL=/ulb/tcsh ```
p5pRT commented 24 years ago

From @mjdominus

\-rw\-rw\-r\-\-  1 vlb  noodle  0 Aug 12 17​:16 tmp/foo
lrwxrwxrwx  1 vlb  noodle  7 Aug 12 17​:04 tmp/foolink \-> tmp/foo
2​: file tmp/foo exists
2​: file tmp/foolink is a link

I should see 2​: file tmp/foolink exists

The bug is in you\, not in Perl. Try

  cat tmp/foolink

and your OS will tell you the same thing​:

  plover% ls -l tmp/*   -rw-r--r-- 1 mjd users 0 Aug 12 20​:53 tmp/foo   lrwxrwxrwx 1 mjd users 7 Aug 12 20​:53 tmp/foolink -> tmp/foo   plover​:/tmp/vbd% cat tmp/foo   plover​:/tmp/vbd% cat tmp/foolink   cat​: tmp/foolink​: No such file or directory

That is because tmp/foolink here refers to the nonexistent file tmp/tmp/foo.

If -l returns success\, then the file (a link) must also exist; but under certain circumstances\, -e fails.

-e tests the existence of the *file that is linked to*\, not the existence of the link itself. Thus -e on a dangling symlink will return false.

p5pRT commented 24 years ago

From @vanstyn

In \199908130018\.RAA08993@​cfcl\.com\, Vicki Brown writes​: :This prints​: : : -rw-rw-r-- 1 vlb noodle 0 Aug 12 17​:16 ./foo : lrwxrwxrwx 1 vlb noodle 3 Aug 12 16​:53 ./foolink -> foo : 1​: file ./foo exists : 1​: file ./foolink exists : 1​: file ./foolink is a link : -rw-rw-r-- 1 vlb noodle 0 Aug 12 17​:16 tmp/foo : lrwxrwxrwx 1 vlb noodle 7 Aug 12 17​:04 tmp/foolink -> tmp/foo : 2​: file tmp/foo exists : 2​: file tmp/foolink is a link

That should be 'tmp/foolink -> foo'. The symlink works relative to foolink\, not relative to your current directory.

Note that you can check for the existence of the symlink itself with​:   lstat "tmp/foolink";   if (-e _) {   print "tmp/foolink exists\n";   }

Hugo

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Vicki Brown \vlb@​cfcl\.com writes​:

If -l returns success\, then the file (a link) must also exist; but under certain circumstances\, -e fails.

This is actually useful for finding broken links.

-- Nick Ing-Simmons \nik@​tiuk\.ti\.com Via\, but not speaking for​: Texas Instruments Ltd.

p5pRT commented 24 years ago

From @vlbrown

At 20​:55 -0400 08/12/1999\, Mark-Jason Dominus wrote​:

-e tests the existence of the *file that is linked to*\, not the existence of the link itself. Thus -e on a dangling symlink will return false.

Ahhhh. A subtlety not clear from the docs. -- --   |\ _\,\,\,---\,\,_ Vicki Brown \vlb@​cfcl\.com ZZZzz /\,`.-'`' -. ;-;;\,_ Journeyman Sourceror​: Scripts & Philtres   |\,4- ) )-\,_. \,\ ( `'-' P.O. Box 1269 San Bruno CA 94066   '---''(_/--' `-'\_) http​://www.cfcl.com/~vlb http​://www.macperl.com