--- /dev/null   2018-10-04 17:34:38.000000000 +0200
+++ a/AX_SYS_PERLSHARPBANG.m4   2018-10-04 17:10:05.042511300 +0200
@@ -0,0 +1,138 @@
+# ===========================================================================
+#   https://www.gnu.org/software/autoconf-archive/ax_sys_perlsharpbang.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_SYS_PERLSHARPBANG
+#
+# DESCRIPTION
+#
+#   Determine how the perl interpreter is located by the OS kernel and make
+#   substitution variable PERL_SHEBANG available. Does AC_PATH_PROG to find
+#   the path to perl. As a side-effect, that sets PERLINTERP and makes it
+#   available as a substitution variable.
+#
+#   Note: The macro allows for the possibility (expected to be seldom used)
+#   of an explicit user override (the "user" being the operator executing
+#   the final 'configure' script, in this context) by making the option
+#   argument like:
+#
+#     --with-perl-shebang='#! /my/funky/perlpath' # OR
+#     --with-perl-shebang='/my/funky/perlpath'  # we just throw away the #! anyway
+#                                               # bec it must be absent in Makefile
+#
+#   Rationale: The are various ways of starting an interpreter on different
+#   *nix-like systems. Many use the simple
+#
+#     #!/usr/bin/perl
+#
+#   but it could be instead
+#
+#     #!/usr/local/bin/perl
+#
+#   and there is even the possibility that the user wants
+#
+#     #!/usr/bin/env perl
+#
+#   to find whichever perl comes first in the current $PATH. This is
+#   preferred by some of us because we run multiple perl installations on
+#   the same box. Adjusting our $PATH then allows us to set precedence over
+#   other perls, even whatever the "house" version is.
+#
+#   Users on very non-unix systems like MS Windows do not have a kernel that
+#   does this kind of thing from the first line of script files, but instead
+#   the perl on their machine is started and merely notices whatever comes
+#   after the interpreter path on this first line of the script (options
+#   like "-w").
+#
+#   Acknowledgement: this macro was in part inspired by Dean Povey's
+#   AC_PROG_PERL_VERSION.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Soren Andersen <somian@pobox.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 14
+
+AC_DEFUN([AX_SYS_PERLSHARPBANG],[dnl
+
+   AC_PATH_PROG(PERLINTERP,perl,perl)
+   ac_cv_path_perlinterp="$PERLINTERP"
+   _sHpB='#!'
+
+   AC_ARG_WITH(perl-shebang,
+                AS_HELP_STRING([--with-perl-shebang],
+           [override what perl thinks is the way for the kernel to start it (seldom needed)]dnl
+                          ),
+               [opt_perl_shebang="$withval"]dnl
+                           ,dnl
+               [opt_perl_shebang="not_set"]dnl
+    )dnl
+
+   AC_CACHE_CHECK([whether explicit instead of detected sharpbang is to be used],
+                  ax_cv_opt_perl_shebang,
+                 [ case "$opt_perl_shebang" in
+                     not_set  ) ax_cv_opt_perl_shebang=''
+                              ;;
+                        *     )
+       ax_cv_opt_perl_shebang=`echo "$opt_perl_shebang" | sed -e's|^#!\s*\(.*\)$|\1|'`
+                   esac
+                 ]dnl
+    )dnl
+
+   if test "A$ax_cv_opt_perl_shebang" != "A"
+     then
+       ac_cv_sys_kernshrpbang_perl="$ax_cv_opt_perl_shebang"
+       PERL_SHEBANG="$ac_cv_sys_kernshrpbang_perl"
+       AC_SUBST(PERL_SHEBANG)dnl
+       AC_MSG_NOTICE([OK - PERL_SHEBANG is $_sHpB$PERL_SHEBANG.])
+
+# Automatic detection of sharpbang formula starts here
+     else dnl
+
+   _somian_shbangperl=`$PERLINTERP -V:startperl`
+   negclass="[[^']]"; dnl
+ must leave this comment:  m4 will remove the outer brackets for us, heheh
+   AC_CACHE_CHECK([for kernel sharpbang invocation to start perl],
+                 ac_cv_sys_kernshrpbang_perl,
+       [_somian_kspb_perl=`echo "$_somian_shbangperl" | sed -ne"s|.*='\($negclass*\)';$|\1|p"`
+       if test "x$_somian_kspb_perl" == x
+         then _somian_ksbp_warn_empty='durnit'
+         else
+         case "A$_somian_kspb_perl" in
+                A#!*perl* )
+           ac_cv_sys_kernshrpbang_perl=`echo "$_somian_kspb_perl" | sed -e's|#!\(.*\)$|\1|'`
+                       ;;
+                    A*    )  _somian_ksbp_warn_defau='trouble'
+                             ac_cv_sys_kernshrpbang_perl="$PERLINTERP"
+         esac
+       fi
+])dnl Done with testing sharpbang
+
+# The above prints Checking ... result message to user.
+   PERL_SHEBANG="$ac_cv_sys_kernshrpbang_perl"
+   AC_SUBST(PERL_SHEBANG)
+    if test A${_somian_ksbp_warn_empty+set} == Aset
+      then   AC_MSG_WARN([dnl
+In last check, doing $PERLINTERP -V:startperl yielded empty result! That should not happen.])
+    fi
+# Inform user after printing result value
+    if test A${_somian_ksbp_warn_defau+set} == Aset
+      then AC_MSG_NOTICE([Maybe Not good -])
+          AC_MSG_WARN([dnl
+In last check perl's Config query did not work so we bunted: $_sHpB$PERLINTERP])
+      else AC_MSG_NOTICE([OK Good result - ])
+          AC_MSG_NOTICE([dnl
+In last check we got a proper-looking answer from perl's Config: $_somian_shbangperl])
+dnl Done with user info messages
+    fi
+dnl Outer loop checked for user override term here
+  fi dnl
+
+])dnl EOMACRO DEF
diff --git old/configure.ac 001/configure.ac
index 8672d83..76c7405 100644
--- old/configure.ac
+++ 001/configure.ac
@@ -1,4 +1,16 @@
 AC_INIT([parallel], [20200322], [bug-parallel@gnu.org])
+
+# on MSys2 prefer msys to native programs, especially perl
+# native windows perl does not work for the time being
+case "`uname -s`" in
+    MSYS*|MINGW*)
+        PATH="/usr/bin:$PATH"
+        export PATH
+        ;;
+esac
+
+AX_SYS_PERLSHARPBANG
+
 AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_FILES([
diff --git old/src/Makefile.am 001/src/Makefile.am
index 20e5bd0..8f0c78a 100644
--- old/src/Makefile.am
+++ 001/src/Makefile.am
@@ -1,4 +1,6 @@
-bin_SCRIPTS = parallel sql niceload parcat parset env_parallel	\
+PERL_BINS = parallel sql niceload parcat parset
+
+bin_SCRIPTS = $(PERL_BINS) env_parallel		        \
 	env_parallel.ash env_parallel.bash env_parallel.csh	\
 	env_parallel.dash env_parallel.fish env_parallel.ksh	\
 	env_parallel.mksh env_parallel.pdksh env_parallel.sh	\
@@ -7,6 +9,12 @@ bin_SCRIPTS = parallel sql niceload parcat parset env_parallel	\
 install-exec-hook:
 	rm $(DESTDIR)$(bindir)/sem || true
 	$(LN_S) parallel $(DESTDIR)$(bindir)/sem
+	@cd $(DESTDIR)$(bindir); \
+	for bin in $(PERL_BINS); do \
+	    mv $$bin "$$bin".tmp; \
+	    sed '1s|.*|#!$(PERL_SHEBANG)|' "$$bin".tmp > $$bin; \
+	    rm -f "$$bin".tmp; \
+	done
 
 if DOCUMENTATION
 man_MANS = parallel.1 env_parallel.1 sem.1 sql.1 niceload.1	\
diff --git old/src/niceload 001/src/niceload
index b17ceef..2667fff 100644
--- old/src/niceload
+++ 001/src/niceload
@@ -148,11 +148,8 @@ exit($::exitstatus);
 
        	if(not %pid_parentpid_cmd) {
 	    # Filter for SysV-style `ps`
-	    my $sysv = q( ps -ef | perl -ane '1..1 and /^(.*)CO?MM?A?N?D/ and $s=length $1;).
+	    my $sysv = q( ps -ef | ).$^X.q( -ane '1..1 and /^(.*)CO?MM?A?N?D/ and $s=length $1;).
 		q(s/^.{$s}//; print "@F[1,2] $_"' );
-	    # Crazy msys: ' is not accepted on the cmd line, but " are treated as '
-	    my $msys = q( ps -ef | perl -ane "1..1 and /^(.*)CO?MM?A?N?D/ and $s=length $1;).
-		q(s/^.{$s}//; print qq{@F[1,2] $_}" );
 	    # BSD-style `ps`
 	    my $bsd = q(ps -o pid,ppid,command -ax);
 	    %pid_parentpid_cmd =
@@ -167,7 +164,7 @@ exit($::exitstatus);
 	     'hpux' => $sysv,
 	     'linux' => $sysv,
 	     'mirbsd' => $bsd,
-	     'msys' => $msys,
+	     'msys' => $sysv,
 	     'MSWin32' => $sysv,
 	     'netbsd' => $bsd,
 	     'nto' => $sysv,
@@ -591,7 +588,7 @@ sub netsensor_script {
 	    $self->{'remedian'} = (sort @{$rref->[2]})[$#{$rref->[2]}/2];
 	}
     };
-    return "perl -e ".shell_quote_scalar($perlscript)." $hops";
+    return "$^X -e ".shell_quote_scalar($perlscript)." $hops";
 }
 
 
diff --git old/src/parallel 001/src/parallel
index fd61160..d53bd0c 100644
--- old/src/parallel
+++ 001/src/parallel
@@ -444,7 +444,7 @@ sub cat_partial {
 	     }
 	 });
     return "<". Q($file) .
-	" perl -e '$script' @start_len |";
+	" $^X -e '$script' @start_len |";
 }
 
 sub spreadstdin {
@@ -5560,7 +5557,7 @@ sub limit {
 	         (tmp=$(tempfile);
 	         LANG=C iostat -x 1 2 > $tmp;
 	         mv $tmp $io_file) &
-	         perl -e '-e $ARGV[0] or exit(1);
+	         !.$^X.q! -e '-e $ARGV[0] or exit(1);
                    for(reverse <>) {
                      /Device:/ and last;
                      /(\S+)$/ and $max = $max > $1 ? $max : $1; }
@@ -5587,7 +5584,7 @@ sub limit {
 	     	 ps ax -o state,command |
 	     	     grep -E '^[DOR].[^[]' |
 	     	     wc -l |
-	     	 perl -ne 'exit ('$limit' < $_)';
+                     !.$^X.q! -ne 'exit ('$limit' < $_)';
 	     };
 	     export -f load;
 	     load %s;
@@ -5841,7 +5838,7 @@ sub loadavg_too_high {
 	    # aix => "ps -ae -o state,command" # state wrong
 	    # bsd => "ps ax -o state,command"
 	    # sysv => "ps -ef -o s -o comm"
-	    # cygwin => perl -ne 'close STDERR; /Name/ and print"\n"; \
+	    # cygwin => $^X -ne 'close STDERR; /Name/ and print"\n"; \
 	    #    /(Name|Pid|Ppid|State):\s+(\S+)/ and print "$2\t";' /proc/*/status |
 	    #    awk '{print $2,$1}'
 	    # dec_osf => bsd
@@ -5859,14 +5856,14 @@ sub loadavg_too_high {
 	    # svr5 => sysv
 	    # ultrix => ps -ax | awk '{print $3,$5}'
 	    # unixware => ps -el|awk '{print $2,$14,$15}'
-	    my $ps = ::spacefree(1,q{
+	    my $ps = ::spacefree(1,q[
 		$sysv="ps -ef -o s -o comm";
 		$sysv2="ps -ef -o state -o comm";
 		$bsd="ps ax -o state,command";
 		# Treat threads as processes
 		$bsd2="ps axH -o state,command";
 		$psel="ps -el|awk '{ print \$2,\$14,\$15 }'";
-		$cygwin=q{ perl -ne 'close STDERR; /Name/ and print"\n";
+		$cygwin=q{ ].$^X.q[ -ne 'close STDERR; /Name/ and print"\n";
                     /(Name|Pid|Ppid|State):\s+(\S+)/ and print "$2\t";' /proc/*/status |
                     awk '{print $2,$1}' };
 		$dummy="echo S COMMAND;echo R dummy";
@@ -5894,7 +5891,7 @@ sub loadavg_too_high {
 		    'ultrix' => "ps -ax | awk '{print \$3,\$5}'",
 		    );
 		print `$ps{$^O}`;
-	    });
+            ]);
 	    # The command is too long for csh, so base64_wrap the command
 	    $cmd = Job::base64_wrap($ps);
 	}
@@ -6794,7 +6794,7 @@ sub sct_hpux() {
     $cpu->{'cores'} ||=
         ::qqx(qq{ /usr/bin/mpsched -s 2>&1 | grep 'Locality Domain Count' | awk '{ print \$4 }'});
     $cpu->{'threads'} ||=
-        ::qqx(qq{ /usr/bin/mpsched -s 2>&1 | perl -ne '/Processor Count\\D+(\\d+)/ and print "\$1"'});
+        ::qqx(qq{ /usr/bin/mpsched -s 2>&1 | $^X -ne '/Processor Count\\D+(\\d+)/ and print "\$1"'});
     return $cpu;
 }
 
@@ -7522,19 +7522,19 @@ sub empty_input_wrapper {
 		exit ($?&127 ? 128+($?&127) : 1+$?>>8)
 	    }
 		  });
-    ::debug("run",'Empty wrap: perl -e '.::Q($script)."\n");
+    ::debug("run",'Empty wrap: $^X -e '.::Q($script)."\n");
     if($Global::cshell
        and
        length $command > 499) {
 	# csh does not like words longer than 1000 (499 quoted)
-	# $command = "perl -e '".base64_zip_eval()."' ".
+	# $command = "$^X -e '".base64_zip_eval()."' ".
 	# join" ",string_zip_base64(
 	#         'exec "'.::perl_quote_scalar($command).'"');
-        return 'perl -e '.::Q($script)." ".
+        return '$^X -e '.::Q($script)." ".
 	    base64_wrap("exec \"$Global::shell\",'-c',\"".
 				   ::perl_quote_scalar($command).'"');
     } else {
-	return 'perl -e '.::Q($script)." ".
+	return '$^X -e '.::Q($script)." ".
 	    $Global::shell." -c ".::Q($command);
     }
 }
@@ -7827,7 +7827,7 @@ sub total_failed {
 	# Command to remove files and dirs (given as args) without
 	# affecting the exit value in $?/$status.
 	if(not $script) {
-	    $script = "perl -e '".
+	    $script = "$^X -e '".
 		::spacefree(0,q{
 		    $bash=shift;
 		    $csh=shift;
@@ -7861,7 +7861,7 @@ sub total_failed {
 	    # * cat > fifo
 	    # * waitpid to get the exit code from $command
 	    # * be less than 1000 chars long
-	    $script = "perl -e '".
+	    $script = "$^X -e '".
 		(::spacefree
 		 (0, q{
 		     ($s,$c,$f) = @ARGV;
@@ -7963,7 +7960,7 @@ sub wrapped {
 	$command = $self->sshlogin_wrap($command);
 	if(@Global::cat_prepends) {
 	    # --pipepart: prepend:
-	    # < /tmp/foo perl -e 'while(@ARGV) {
+	    # < /tmp/foo $^X -e 'while(@ARGV) {
 	    #   sysseek(STDIN,shift,0) || die; $left = shift;
 	    #   while($read = sysread(STDIN,$buf, ($left > 131072 ? 131072 : $left))){
 	    #     $left -= $read; syswrite(STDOUT,$buf);
@@ -7989,7 +7986,7 @@ sub wrapped {
 	   and
 	   length $command > 499) {
 	    # csh does not like words longer than 1000 (499 quoted)
-	    # $command = "perl -e '".base64_zip_eval()."' ".
+	    # $command = "$^X -e '".base64_zip_eval()."' ".
 	    # join" ",string_zip_base64(
 	    #         'exec "'.::perl_quote_scalar($command).'"');
 	    $command = base64_wrap("exec \"$Global::shell\",'-c',\"".
@@ -8111,7 +8108,7 @@ sub base64_wrap {
     #   $shell_command = shell command that runs $eval_string
     my $eval_string = shift;
     return
-	"perl -e ".
+	"$^X -e ".
 	::Q(base64_zip_eval())." ".
 	join" ",::shell_quote(string_zip_base64($eval_string));
 }
@@ -8312,7 +8312,7 @@ sub sshlogin_wrap {
 		    # csh does not deal well with $ENV with \n
 		    $self->{'sshlogin_wrap'}{$command} = base64_wrap($perl_code);
 		} else {
-		    $self->{'sshlogin_wrap'}{$command} = "perl -e ".::Q($perl_code);
+		    $self->{'sshlogin_wrap'}{$command} = "$^X -e ".::Q($perl_code);
 		}
 	    } else {
 		$self->{'sshlogin_wrap'}{$command} = $command;
@@ -8329,7 +8329,7 @@ sub sshlogin_wrap {
 	    my $remote_command = $pwd.$envset.$bashfuncset.
 		'@ARGV="'.::perl_quote_scalar($command).'";'.
 		monitor_parent_sshd_script();
-	    $quoted_remote_command = "perl -e ". ::Q($remote_command);
+	    $quoted_remote_command = "$^X -e ". ::Q($remote_command);
 	    my $dq_remote_command = ::Q($quoted_remote_command);
 	    if(length $dq_remote_command > 999
 	       or
@@ -8339,7 +8339,7 @@ sub sshlogin_wrap {
 		# csh does not deal well with > 1000 chars in one word
 		# csh does not deal well with $ENV with \n
 		$quoted_remote_command =
-		    "perl -e ". ::Q(::Q(base64_zip_eval()))." ".
+		    "$^X -e ". ::Q(::Q(base64_zip_eval()))." ".
 		    join" ",::shell_quote(::shell_quote(string_zip_base64($remote_command)));
 	    } else {
 		$quoted_remote_command = $dq_remote_command;
@@ -8664,7 +8664,7 @@ sub start {
 	my $bash =
 	    ::shell_quote_scalar_default(
 	    "testfun() { rm $name; }; export -f testfun; ".
-	    "perl -MIPC::Open3 -e ".
+	    "$^X -MIPC::Open3 -e ".
 	    ::shell_quote_scalar_default($script)
 	    );
 	# Redirect STDERR temporarily,
@@ -8876,14 +8876,14 @@ sub interactive_start {
 	    (
 	     "(".$actual_command.');'.
 	     # The triple print is needed - otherwise the testsuite fails
-	     q[ perl -e 'while($t++<3){ print $ARGV[0],"\n" }' $?h/$status >> ].$tmpfifo."&".
+	     " $^X".q[ -e 'while($t++<3){ print $ARGV[0],"\n" }' $?h/$status >> ].$tmpfifo."&".
 	     "echo $title; echo \007Job finished at: `date`;sleep 10"
 	    ).
 	    # Run outside tmux
 	    # Read a / separated line: 0h/2 for csh, 2/0 for bash.
 	    # If csh the first will be 0h, so use the second as exit value.
 	    # Otherwise just use the first value as exit value.
-	    q{; exec perl -e '$/="/";$_=<>;$c=<>;unlink $ARGV; /(\d+)h/ and exit($1);exit$c' }.$tmpfifo;
+	    "; exec $^X ".q{-e '$/="/";$_=<>;$c=<>;unlink $ARGV; /(\d+)h/ and exit($1);exit$c' }.$tmpfifo;
     }
 }
 
