diff --git a/AX_SYS_PERLSHARPBANG.m4 b/AX_SYS_PERLSHARPBANG.m4 new file mode 100644 index 0000000..9f4a87b --- /dev/null +++ b/AX_SYS_PERLSHARPBANG.m4 @@ -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 +# +# 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 a/configure.ac b/configure.ac index 3770d7f..070e56e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,16 @@ AC_INIT([parallel],[20231122],[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 a/src/Makefile.am b/src/Makefile.am index c113c4f..bf72a65 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,9 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -bin_SCRIPTS = parallel sql niceload parcat parset parsort \ +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 \ @@ -47,6 +49,12 @@ HTML_FILES = parallel.html env_parallel.html sem.html sql.html \ 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 = $(MAN_FILES) diff --git a/src/niceload b/src/niceload index 3085b87..3cbaf98 100755 --- a/src/niceload +++ b/src/niceload @@ -150,11 +150,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 = @@ -169,7 +166,7 @@ exit($::exitstatus); 'hpux' => $sysv, 'linux' => $sysv, 'mirbsd' => $bsd, - 'msys' => $msys, + 'msys' => $sysv, 'MSWin32' => $sysv, 'netbsd' => $bsd, 'nto' => $sysv, @@ -593,7 +590,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 a/src/parallel b/src/parallel index b2dba64..ea03de0 100755 --- a/src/parallel +++ b/src/parallel @@ -934,7 +934,7 @@ sub cat_partial($@) { } }); return "<". Q($file) . - " perl -e '$script' @start_len |"; + " $^X -e '$script' @start_len |"; } sub column_perlexpr($$$) { @@ -7489,7 +7489,7 @@ sub limit($) { ((tmp=$(tempfile); LANG=C iostat -x 1 2 > $tmp; mv $tmp $io_file) /dev/null & ); - 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; } @@ -7514,7 +7514,7 @@ sub limit($) { ps ax -o state,command | grep -E '^[DOR].[^[]' | wc -l | - perl -ne 'exit ('$limit' < $_)'; + !.$^X.q! -ne 'exit ('$limit' < $_)'; }; load %s !, @@ -7787,7 +7787,7 @@ sub loadavg($) { # 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 @@ -7805,14 +7805,14 @@ sub loadavg($) { # 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"; @@ -7841,7 +7841,7 @@ sub loadavg($) { 'MSWin32' => $sysv, ); print `$ps{$^O}`; - }); + ]); # The command is too long for csh, so base64_wrap the command $Global::loadavg_cmd = $self->hexwrap($ps); } @@ -8785,7 +8785,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; } @@ -9503,19 +9503,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); } } @@ -9887,7 +9887,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; @@ -9927,7 +9927,7 @@ sub total_failed($) { # It has been measured on: # AMD 6376: 4095 # ppar -a big --pipepart --block -1 --test $1 --fifo 'cat {} >/dev/null'; - $script = "perl -e '". + $script = "$^X -e '". (::spacefree (0, q{ ($s,$c,$f) = @ARGV; @@ -10034,7 +10034,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 > 60800 ? 60800 : $left))){ # $left -= $read; syswrite(STDOUT,$buf); @@ -10063,7 +10063,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',\"". @@ -10183,7 +10183,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)); } @@ -10434,7 +10434,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; @@ -10830,7 +10830,7 @@ sub start($) { my $bash = ::shell_quote_scalar_default( "testfun() { rm $name; }; export -f testfun; ". - "perl -MIPC::Open3 -e ". + "$^X -MIPC::Open3 -e ". ::Q(::Q($script)) ); my $redefine_eval; @@ -11081,7 +11081,7 @@ 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 >> ]. + " $^X".q[ -e 'while($t++<3){ print $ARGV[0],"\n" }' $?h/$status >> ]. ::Q($tmpfifo)."&". "echo $title; echo \007Job finished at: `date`;sleep 10" ). @@ -11089,7 +11089,7 @@ sub interactive_start($) { # 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; }. + "; exec $^X ".q{-e '$/="/";$_=<>;$c=<>;unlink $ARGV; }; q{/(\d+)h/ and exit($1);exit$c' }.::Q($tmpfifo); } }