http://www.perlmonks.org?node_id=1188911

pryrt has asked for the wisdom of the Perl Monks concerning the following question:

Regarding the executable-test -x, perlport says:

-x (or -X) determine if a file ends in one of the executable suffixes. -S is meaningless. (Win32)

Where are the "executable suffixes" defined for Win32 perl (strawberry, in my case)? If anything, I would have expected $ENV{PATHEXT}, because that's the closest related idea to "executable" on windows (or possibly the assoc and ftype and their underlying registry entries -- though that's more complicated). However, I've got ".pl" in my PATHEXT variable and properly associated in the registry, but -x "$0" results in a false value (undef). I also tried with a .js file, which is in the Windows-default PATHEXT, but it shows up as non-executable as well. I've experimentally found that .com, .exe, .bat, and .cmd all show up as executable... but none of the others in the default PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

--

context: after reading Re^2: how do i run a shell command without waiting for the output, I looked at Proc::Background, and saw that commands were "checked by appending `.exe' to the name in case the name was passed without the `.exe' suffix". Since ".exe" isn't the only extension dropped on Win32 (PATHEXT defines the extension-omission properties for Win32, and .bat is frequently untyped as well), I wanted to suggest a bugfix to allow any extension from PATHEXT: change the hardcoded push(@extensions, '.exe'); to push @extensions, split(/;/, $ENV{PATHEXT} || '.exe');. However, while testing my change against various extensions (explicit or omitted-but-implied), I found that Proc::Background wasn't getting as far as using the @extensions array, since -x was failing. I found the quoted perlport description that Win32 -x has a list of extensions, but I haven't found the official documentation for what that list is (and really, if there's any hardcoded list embedded in the perl ports to Win32, I disagree with them on the same grounds that I disagree with Proc::Background)

#!/usr/bin/env perl use warnings; use strict; use Proc::Background; print "$0 => ", (-x $0 || 0), $/; foreach ( qw(./com-hello.com ./com-hello ./c-hello.exe ./c-hello ./bat +-hello.bat ./bat-hello ./cmd-hello.cmd ./cmd-hello ./js-hello.js ./js +-hello C:/path-to/cpan-bugs/proc-bg/js-hello.js) ) { local $\ = $/; local $, = "\t"; print STDERR $_; my $p = Proc::Background->new($_); if(!defined $p) { print STDERR $_, "didn't run"; next; } print STDERR '-x: ', ( (-x $_) || 0); print STDERR 'pid: ', $p->pid; print STDERR 'alive: ', $p->alive; print STDERR 'wait: ', $p->wait; print STDERR 'start: ', $p->start_time; print STDERR 'end: ', $p->end_time; print STDERR ''; } foreach my $ext (split /;/, $ENV{PATHEXT}) { local $\ = $/; local $, = "\t"; open my $fh, '>', "x$ext" or die "x$ext $!"; close $fh; print STDERR "x$ext", ( (-x "x$ext") || 0); unlink $fh; } __END__
C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl => 0 ./com-hello.com -x: 1 pid: 7164 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./com-hello -x: 0 pid: 3488 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./c-hello.exe -x: 1 pid: 3576 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./c-hello -x: 0 pid: 5312 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./bat-hello.bat -x: 1 pid: 4816 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./bat-hello -x: 0 pid: 7972 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./cmd-hello.cmd -x: 1 pid: 668 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./cmd-hello -x: 0 pid: 6692 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./js-hello.js C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: cannot find absolute lo +cation of ./js-hello.js ./js-hello.js didn't run ./js-hello C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: cannot find absolute lo +cation of ./js-hello ./js-hello didn't run C:/path-to/cpan-bugs/proc-bg/js-hello.js looking for absolute: C:/path-to/cpan-bugs/proc-bg/js-hello.js C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: no executable program l +ocated at C:/path-to/cpan-bugs/proc-bg/js-hello.js C:/path-to/cpan-bugs/proc-bg/js-hello.js didn't run x.com 1 x.exe 1 x.bat 1 x.cmd 1 x.vbs 0 x.vbe 0 x.js 0 x.jse 0 x.wsf 0 x.wsh 0 x.msc 0 x.pl 0 x.COM 1 x.EXE 1 x.BAT 1 x.CMD 1 x.VBS 0 x.VBE 0 x.JS 0 x.JSE 0 x.WSF 0 x.WSH 0 x.MSC 0 C:\path-to\cpan-bugs\proc-bg\>echo %pathext% .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc;.pl;.COM;.EXE;.B +AT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

edit: add <readmore> tags...