parallel: Implemented {= $arg[1] and $job->skip() =}.

This commit is contained in:
Ole Tange 2015-08-11 00:25:37 +02:00
parent 4ac1b6200f
commit 2e6a701f96
7 changed files with 61 additions and 17 deletions

View file

@ -232,10 +232,18 @@ New in this release:
* <<kontaktet 2015-06-22 Afventer svar fra journal>> GNU Parallel was used (unfortunately with wrong citation) in: TADSim: Discrete Event-Based Performance Prediction for Temperature-Accelerated Dynamics http://vruehle.de/publications/2015c.pdf * <<kontaktet 2015-06-22 Afventer svar fra journal>> GNU Parallel was used (unfortunately with wrong citation) in: TADSim: Discrete Event-Based Performance Prediction for Temperature-Accelerated Dynamics http://vruehle.de/publications/2015c.pdf
* << Update forventet juni Rachel har lige svaret >> GNU Parallel was used in: SISRS: Site Identification from Short Read Sequences https://github.com/rachelss/SISRS/ * A composite genome approach to identify phylogenetically informative data from next-generation sequencing http://www.biomedcentral.com/content/pdf/s12859-015-0632-y.pdf
* SpeedSeq: ultra-fast personal genome analysis and interpretation http://www.nature.com/nmeth/journal/vaop/ncurrent/full/nmeth.3505.html
* Who actually reads the code? http://www.fsf.org/blogs/community/who-actually-reads-the-code
* Distribution des traitements avec GNU Parallel http://blog.inovia-conseil.fr/?p=226#4 * Distribution des traitements avec GNU Parallel http://blog.inovia-conseil.fr/?p=226#4
* Эксперимент по проверке, читают ли код открытых проектов http://www.opennet.ru/opennews/art.shtml?num=42718
* 多核心主機搭配 GNU parallel http://blog.zeroplex.tw/2015/08/gnu-parallel.html
* Bug fixes and man page updates. * Bug fixes and man page updates.
GNU Parallel - For people who live life in the parallel lane. GNU Parallel - For people who live life in the parallel lane.

View file

@ -794,7 +794,7 @@ sub options_hash {
"tollef" => \$opt::tollef, "tollef" => \$opt::tollef,
"gnu" => \$opt::gnu, "gnu" => \$opt::gnu,
"xapply" => \$opt::xapply, "xapply" => \$opt::xapply,
"bibtex" => \$opt::bibtex, "bibtex|citation" => \$opt::bibtex,
"wc|willcite|will-cite|nn|nonotice|no-notice" => \$opt::willcite, "wc|willcite|will-cite|nn|nonotice|no-notice" => \$opt::willcite,
# Termination and retries # Termination and retries
"halt-on-error|halt=s" => \$opt::halt, "halt-on-error|halt=s" => \$opt::halt,
@ -817,7 +817,7 @@ sub options_hash {
"help|h" => \$opt::help, "help|h" => \$opt::help,
"L=f" => \$opt::L, "L=f" => \$opt::L,
"max-lines|l:f" => \$opt::max_lines, "max-lines|l:f" => \$opt::max_lines,
"interactive|p" => \$opt::p, "interactive|p" => \$opt::interactive,
"verbose|t" => \$opt::verbose, "verbose|t" => \$opt::verbose,
"version|V" => \$opt::version, "version|V" => \$opt::version,
"minversion|min-version=i" => \$opt::minversion, "minversion|min-version=i" => \$opt::minversion,
@ -902,7 +902,7 @@ sub parse_options {
if(defined $opt::0) { $/ = "\0"; } if(defined $opt::0) { $/ = "\0"; }
if(defined $opt::d) { $/ = unquote_printf($opt::d) } if(defined $opt::d) { $/ = unquote_printf($opt::d) }
if(defined $opt::tagstring) { $opt::tagstring = unquote_printf($opt::tagstring); } if(defined $opt::tagstring) { $opt::tagstring = unquote_printf($opt::tagstring); }
if(defined $opt::p) { $Global::interactive = $opt::p; } if(defined $opt::interactive) { $Global::interactive = $opt::interactive; }
if(defined $opt::q) { $Global::quoting = 1; } if(defined $opt::q) { $Global::quoting = 1; }
if(defined $opt::r) { $Global::ignore_empty = 1; } if(defined $opt::r) { $Global::ignore_empty = 1; }
if(defined $opt::verbose) { $Global::stderr_verbose = 1; } if(defined $opt::verbose) { $Global::stderr_verbose = 1; }
@ -3172,8 +3172,15 @@ sub reaper {
$job or next; $job or next;
delete $Global::running{$stiff}; delete $Global::running{$stiff};
$Global::total_running--; $Global::total_running--;
$job->set_exitstatus($? >> 8); if($job->{'commandline'}{'skip'}) {
$job->set_exitsignal($? & 127); # $job->skip() was called
$job->set_exitstatus(-2);
$job->set_exitsignal(0);
} else {
$job->set_exitstatus($? >> 8);
$job->set_exitsignal($? & 127);
}
debug("run", "seq ",$job->seq()," died (", $job->exitstatus(), ")"); debug("run", "seq ",$job->seq()," died (", $job->exitstatus(), ")");
$job->set_endtime(::now()); $job->set_endtime(::now());
if($stiff == $Global::tty_taken) { if($stiff == $Global::tty_taken) {
@ -7042,8 +7049,12 @@ sub start {
my $command = $job->wrapped(); my $command = $job->wrapped();
my $pid; my $pid;
if($job->{'commandline'}{'skip'}) {
# $job->skip() was called
$command = "true";
}
if($Global::interactive or $Global::stderr_verbose) { if($Global::interactive or $Global::stderr_verbose) {
$command = interactive_start($command); $job->interactive_start();
} }
$job->openoutputfiles(); $job->openoutputfiles();
my($stdout_fh,$stderr_fh) = ($job->fh(1,"w"),$job->fh(2,"w")); my($stdout_fh,$stderr_fh) = ($job->fh(1,"w"),$job->fh(2,"w"));
@ -7121,7 +7132,8 @@ sub start {
} }
sub interactive_start { sub interactive_start {
my $command = shift; my $self = shift;
my $command = $self->wrapped();
if($Global::interactive) { if($Global::interactive) {
::status("$command ?..."); ::status("$command ?...");
open(my $tty_fh, "<", "/dev/tty") || ::die_bug("interactive-tty"); open(my $tty_fh, "<", "/dev/tty") || ::die_bug("interactive-tty");
@ -7129,12 +7141,11 @@ sub interactive_start {
close $tty_fh; close $tty_fh;
my $run_yes = ($answer =~ /^\s*y/i); my $run_yes = ($answer =~ /^\s*y/i);
if (not $run_yes) { if (not $run_yes) {
$command = "true"; # Run the command 'true' $self->{'commandline'}->skip();
} }
} else { } else {
print $Global::original_stderr "$command\n"; print $Global::original_stderr "$command\n";
} }
return $command;
} }
sub print_dryrun_and_verbose { sub print_dryrun_and_verbose {
@ -8101,8 +8112,8 @@ sub replaced {
{ {
my @target; my @target;
my $context_replace; my $context_replace;
my @arg;
my $perl_expressions_as_re; my $perl_expressions_as_re;
my @arg;
sub fish_out_words_containing_replacement_strings { sub fish_out_words_containing_replacement_strings {
my %word; my %word;
@ -8154,6 +8165,8 @@ sub replaced {
sub replace_placeholders { sub replace_placeholders {
# Replace foo{}bar with fooargbar # Replace foo{}bar with fooargbar
# Uses:
# @Arg::arg = arguments as strings to be use in {= =}
# Input: # Input:
# $targetref = command as shell words # $targetref = command as shell words
# $quote = should everything be quoted? # $quote = should everything be quoted?
@ -8178,7 +8191,8 @@ sub replaced {
# Fish out the words that have replacement strings in them # Fish out the words that have replacement strings in them
my @word = fish_out_words_containing_replacement_strings(); my @word = fish_out_words_containing_replacement_strings();
flatten_arg_list($self->{'arg_list'}); flatten_arg_list($self->{'arg_list'});
# Make it possible to use $arg[2] in {= =}
@Arg::arg = (undef, map { $_->orig() } @arg);
# Number of arguments - used for positional arguments # Number of arguments - used for positional arguments
my $n = $#arg+1; my $n = $#arg+1;
@ -8223,7 +8237,7 @@ sub replaced {
$normal_replace or last; $normal_replace or last;
} }
} }
@Arg::arg = ();
if($quote) { if($quote) {
@target = ::shell_quote(@target); @target = ::shell_quote(@target);
} }
@ -8242,6 +8256,12 @@ sub replaced {
} }
} }
sub skip {
# Skip this job
my $self = shift;
$self->{'skip'} = 1;
}
package CommandLineQueue; package CommandLineQueue;
@ -9427,6 +9447,6 @@ sub mkdir_or_die {
} }
# Keep perl -w happy # Keep perl -w happy
$opt::x = $Semaphore::timeout = $Semaphore::wait = $opt::x = $Semaphore::timeout = $Semaphore::wait =
$Job::file_descriptor_warning_printed = $Job::file_descriptor_warning_printed = $Global::envdef = @Arg::arg;
$Global::envdef = 0;

View file

@ -470,6 +470,8 @@ Implies B<--semaphore>.
=item B<--bibtex> =item B<--bibtex>
=item B<--citation>
Print the BibTeX entry for GNU B<parallel> and silence citation Print the BibTeX entry for GNU B<parallel> and silence citation
notice. notice.

View file

@ -24,7 +24,7 @@ echo '### Bug in --load';
nice parallel -k --load 30 sleep 0.1\;echo ::: 1 2 3 nice parallel -k --load 30 sleep 0.1\;echo ::: 1 2 3
echo '### Test --timeout' echo '### Test --timeout'
nice parallel -j0 -k --timeout 1 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 nice parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9
echo '### Test retired' echo '### Test retired'
stdout parallel -B foo stdout parallel -B foo

View file

@ -63,4 +63,9 @@ echo 'env in zsh'
export -f myfunc; export -f myfunc;
PARALLEL_SHELL=/usr/bin/zsh parallel --env myfunc myfunc ::: a PARALLEL_SHELL=/usr/bin/zsh parallel --env myfunc myfunc ::: a
echo 'bug #45692: Easy way of cancelling a job in {= =} and'
echo 'bug #45691: Accessing multiple arguments in {= =}'
parallel echo {= '$arg[1] eq 2 and $job->skip()' =} ::: {1..5}
EOF EOF

View file

@ -35,7 +35,7 @@ echo '### Bug in --load'; nice parallel -k --load 30 sleep 0.1\;echo ::: 1 2 3
3 3
echo '### Test --timeout' echo '### Test --timeout'
### Test --timeout ### Test --timeout
nice parallel -j0 -k --timeout 1 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9 nice parallel -j0 -k --timeout 2 echo {}\; sleep {}\; echo {} ::: 1.1 7.7 8.8 9.9
1.1 1.1
1.1 1.1
7.7 7.7

View file

@ -156,3 +156,12 @@ myfuncvar a
Function export as function Function export as function
myfunc() { echo myfunc $*; }; export -f myfunc; PARALLEL_SHELL=/usr/bin/zsh parallel --env myfunc myfunc ::: a myfunc() { echo myfunc $*; }; export -f myfunc; PARALLEL_SHELL=/usr/bin/zsh parallel --env myfunc myfunc ::: a
myfunc a myfunc a
echo 'bug #45692: Easy way of cancelling a job in {= =} and'
bug #45692: Easy way of cancelling a job in {= =} and
echo 'bug #45691: Accessing multiple arguments in {= =}'
bug #45691: Accessing multiple arguments in {= =}
parallel echo {= '$arg[1] eq 2 and $job->skip()' =} ::: {1..5}
1
3
4
5