mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-22 05:57:54 +00:00
parallel: Better error message if Text::CSV is not installed.
This commit is contained in:
parent
77e9f59abb
commit
e40d44c517
25
NEWS
25
NEWS
|
@ -8,21 +8,30 @@ New in this release:
|
||||||
|
|
||||||
News about GNU Parallel:
|
News about GNU Parallel:
|
||||||
|
|
||||||
* Distributed Task Processing with GNU Parallel https://www.youtube.com/watch?v=usbMLggdMgc
|
* Distributed Task Processing with GNU Parallel
|
||||||
|
https://www.youtube.com/watch?v=usbMLggdMgc
|
||||||
|
|
||||||
* GNU Parallel workflow for many small, independent runs https://docs.csc.fi/support/tutorials/many/
|
* GNU Parallel workflow for many small, independent runs
|
||||||
|
https://docs.csc.fi/support/tutorials/many/
|
||||||
|
|
||||||
* Copy a File To Multiple Directories With A Single Command on Linux https://www.linuxfordevices.com/tutorials/linux/copy-file-to-multiple-directories-with-one-command
|
* Copy a File To Multiple Directories With A Single Command on Linux
|
||||||
|
https://www.linuxfordevices.com/tutorials/linux/copy-file-to-multiple-directories-with-one-command
|
||||||
|
|
||||||
* Behind The Scenes: The Power Of Simple Command Line Tools At Cloud Scale https://blog.gdeltproject.org/behind-the-scenes-the-power-of-simple-command-line-tools-at-cloud-scale/
|
* Behind The Scenes: The Power Of Simple Command Line Tools At Cloud
|
||||||
|
Scale
|
||||||
|
https://blog.gdeltproject.org/behind-the-scenes-the-power-of-simple-command-line-tools-at-cloud-scale/
|
||||||
|
|
||||||
* Run lz4 compression in parallel using GNU parallel https://www.openguru.com/2022/09/
|
* Run lz4 compression in parallel using GNU parallel
|
||||||
|
https://www.openguru.com/2022/09/
|
||||||
|
|
||||||
* Xargs / Parallel With Code Examples https://www.folkstalk.com/2022/09/xargs-parallel-with-code-examples.html
|
* Xargs / Parallel With Code Examples
|
||||||
|
https://www.folkstalk.com/2022/09/xargs-parallel-with-code-examples.html
|
||||||
|
|
||||||
* Parallel processing on a single node with GNU Parallel https://www3.cs.stonybrook.edu/~cse416/Section01/Slides/SeaWulfIntro_CSE416_09222022.pdf
|
* Parallel processing on a single node with GNU Parallel
|
||||||
|
https://www3.cs.stonybrook.edu/~cse416/Section01/Slides/SeaWulfIntro_CSE416_09222022.pdf
|
||||||
|
|
||||||
* Using GNU parallel painlessly -- from basics to bioinformatics job orchestration https://www.youtube.com/watch?v=qypUdm-IE9c
|
* Using GNU parallel painlessly -- from basics to bioinformatics job
|
||||||
|
orchestration https://www.youtube.com/watch?v=qypUdm-IE9c
|
||||||
|
|
||||||
|
|
||||||
20220922
|
20220922
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
Quote of the month:
|
Quote of the month:
|
||||||
|
|
||||||
|
[GNU Parallel] is the most amazing tool ever invented for bioinformatics!
|
||||||
|
-- Istvan Albert https://www.ialbert.me/
|
||||||
|
|
||||||
Got around to using GNU parallel for the first time from a suggestion by @jdwasmuth ... now I'm wishing I started using this years ago
|
Got around to using GNU parallel for the first time from a suggestion by @jdwasmuth ... now I'm wishing I started using this years ago
|
||||||
-- Stefan Gavriliuc @GavriliucStefan@twitter
|
-- Stefan Gavriliuc @GavriliucStefan@twitter
|
||||||
|
|
||||||
|
|
51
src/parallel
51
src/parallel
|
@ -2278,7 +2278,11 @@ sub parse_options(@) {
|
||||||
if(defined $opt::tmuxpane) { $opt::tmux = $opt::tmuxpane; }
|
if(defined $opt::tmuxpane) { $opt::tmux = $opt::tmuxpane; }
|
||||||
if(defined $opt::colsep) { $Global::trim = 'lr'; }
|
if(defined $opt::colsep) { $Global::trim = 'lr'; }
|
||||||
if(defined $opt::csv) {
|
if(defined $opt::csv) {
|
||||||
$Global::use{"Text::CSV"} ||= eval "use Text::CSV; 1;";
|
if(not $Global::use{"Text::CSV"} ||= eval "use Text::CSV; 1;") {
|
||||||
|
::error("The perl module Text::CSV is not installed.");
|
||||||
|
::error("Try installing libtext-csv-perl or perl-Text-CSV.");
|
||||||
|
wait_and_exit(255);
|
||||||
|
}
|
||||||
$opt::colsep = defined $opt::colsep ? $opt::colsep : ",";
|
$opt::colsep = defined $opt::colsep ? $opt::colsep : ",";
|
||||||
my $csv_setting = { binary => 1, sep_char => $opt::colsep };
|
my $csv_setting = { binary => 1, sep_char => $opt::colsep };
|
||||||
my $sep = $csv_setting->{sep_char};
|
my $sep = $csv_setting->{sep_char};
|
||||||
|
@ -2698,7 +2702,7 @@ sub check_invalid_option_combinations() {
|
||||||
|
|
||||||
sub init_globals() {
|
sub init_globals() {
|
||||||
# Defaults:
|
# Defaults:
|
||||||
$Global::version = 20221022;
|
$Global::version = 20221115;
|
||||||
$Global::progname = 'parallel';
|
$Global::progname = 'parallel';
|
||||||
$::name = "GNU Parallel";
|
$::name = "GNU Parallel";
|
||||||
$Global::infinity = 2**31;
|
$Global::infinity = 2**31;
|
||||||
|
@ -3551,18 +3555,18 @@ sub shell_quote_scalar_default($) {
|
||||||
# $string = string to be quoted
|
# $string = string to be quoted
|
||||||
# Returns:
|
# Returns:
|
||||||
# $shell_quoted = string quoted as needed by the shell
|
# $shell_quoted = string quoted as needed by the shell
|
||||||
my $s = $_[0];
|
local $_ = $_[0];
|
||||||
if($s =~ /[^-_.+a-z0-9\/]/i) {
|
if(/[^-_.+a-z0-9\/]/i) {
|
||||||
$s =~ s/'/'"'"'/g; # "-quote single quotes
|
s/'/'"'"'/g; # "-quote '-quotes
|
||||||
$s = "'$s'"; # '-quote entire string
|
$_ = "'$_'"; # '-quote entire string
|
||||||
$s =~ s/^''//; # Remove unneeded '' at ends
|
s/^''//; # Remove unneeded '' at ends
|
||||||
$s =~ s/''$//; # (faster than s/^''|''$//g)
|
s/''$//; # (faster than s/^''|''$//g)
|
||||||
return $s;
|
return $_;
|
||||||
} elsif ($s eq "") {
|
} elsif ($_ eq "") {
|
||||||
return "''";
|
return "''";
|
||||||
} else {
|
} else {
|
||||||
# No quoting needed
|
# No quoting needed
|
||||||
return $s;
|
return $_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13152,19 +13156,22 @@ sub real_max_length() {
|
||||||
sub find_max($) {
|
sub find_max($) {
|
||||||
my $string = shift;
|
my $string = shift;
|
||||||
# This is slow on Cygwin, so give Cygwin users a warning
|
# This is slow on Cygwin, so give Cygwin users a warning
|
||||||
if($^O eq "cygwin") {
|
if($^O eq "cygwin" or $^O eq "msys") {
|
||||||
::warning("Finding the maximal command line length. ".
|
::warning("Finding the maximal command line length. ".
|
||||||
"This may take up to 1 minute.")
|
"This may take up to 1 minute.")
|
||||||
}
|
}
|
||||||
# Use an upper bound of 100 MB if the shell allows for infinite
|
# Use an upper bound of 100 MB if the shell allows for infinite
|
||||||
# long lengths
|
# long lengths
|
||||||
my $upper = 100_000_000;
|
my $upper = 100_000_000;
|
||||||
|
my $lower;
|
||||||
# 1000 is supported everywhere, so the search can start anywhere 1..999
|
# 1000 is supported everywhere, so the search can start anywhere 1..999
|
||||||
# 324 makes the search much faster on Cygwin, so let us use that
|
# 324 makes the search much faster on Cygwin, so let us use that
|
||||||
my $len = 324;
|
my $len = 324;
|
||||||
do {
|
do {
|
||||||
if($len > $upper) { return $len };
|
if($len > $upper) { return $len };
|
||||||
|
$lower = $len;
|
||||||
$len *= 16;
|
$len *= 16;
|
||||||
|
::debug("init", "Maxlen: $lower<$len<$upper(".($upper-$lower)."): ");
|
||||||
} while (is_acceptable_command_line_length($len,$string));
|
} while (is_acceptable_command_line_length($len,$string));
|
||||||
# Then search for the actual max length between
|
# Then search for the actual max length between
|
||||||
# last successful length ($len/16) and upper bound
|
# last successful length ($len/16) and upper bound
|
||||||
|
@ -13190,23 +13197,7 @@ sub binary_find_max($$$) {
|
||||||
# Guessing too high is cheap. Guessing too low is expensive.
|
# Guessing too high is cheap. Guessing too low is expensive.
|
||||||
my $split = ($^O eq "cygwin" or $^O eq "msys") ? 0.93 : 0.5;
|
my $split = ($^O eq "cygwin" or $^O eq "msys") ? 0.93 : 0.5;
|
||||||
my $middle = int (($upper-$lower)*$split + $lower);
|
my $middle = int (($upper-$lower)*$split + $lower);
|
||||||
::debug("init", "Maxlen: $lower<$middle<$upper: ");
|
::debug("init", "Maxlen: $lower<$middle<$upper(".($upper-$lower)."): ");
|
||||||
if (is_acceptable_command_line_length($middle,$string)) {
|
|
||||||
return binary_find_max($middle,$upper,$string);
|
|
||||||
} else {
|
|
||||||
return binary_find_max($lower,$middle,$string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub _binary_find_max($$$) {
|
|
||||||
# Given a lower and upper bound find the max (length or args) of a
|
|
||||||
# command line
|
|
||||||
# Returns:
|
|
||||||
# number of chars on the longest command line allowed
|
|
||||||
my ($lower, $upper, $string) = (@_);
|
|
||||||
if($lower == $upper or $lower == $upper-1) { return $lower; }
|
|
||||||
my $middle = int (($upper-$lower)/2 + $lower);
|
|
||||||
::debug("init", "Maxlen: $lower<$middle<$upper: ");
|
|
||||||
if (is_acceptable_command_line_length($middle,$string)) {
|
if (is_acceptable_command_line_length($middle,$string)) {
|
||||||
return binary_find_max($middle,$upper,$string);
|
return binary_find_max($middle,$upper,$string);
|
||||||
} else {
|
} else {
|
||||||
|
@ -13232,7 +13223,7 @@ sub _binary_find_max($$$) {
|
||||||
# Force using non-built-in command
|
# Force using non-built-in command
|
||||||
$prg ||= ::which("echo");
|
$prg ||= ::which("echo");
|
||||||
::qqx("$prg ".${string}x(($len-1-length $prg)/length $string));
|
::qqx("$prg ".${string}x(($len-1-length $prg)/length $string));
|
||||||
::debug("init", "$len=$? ");
|
::debug("init", "$len=$?\n");
|
||||||
return not $?;
|
return not $?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -988,15 +988,15 @@ B<env_parallel>
|
||||||
Show the estimated number of seconds before finishing.
|
Show the estimated number of seconds before finishing.
|
||||||
|
|
||||||
This forces GNU B<parallel> to read all jobs before starting to find
|
This forces GNU B<parallel> to read all jobs before starting to find
|
||||||
the number of jobs. GNU B<parallel> normally only reads the next job
|
the number of jobs (unless you use B<--total-jobs>). GNU B<parallel>
|
||||||
to run.
|
normally only reads the next job to run.
|
||||||
|
|
||||||
The estimate is based on the runtime of finished jobs, so the first
|
The estimate is based on the runtime of finished jobs, so the first
|
||||||
estimate will only be shown when the first job has finished.
|
estimate will only be shown when the first job has finished.
|
||||||
|
|
||||||
Implies B<--progress>.
|
Implies B<--progress>.
|
||||||
|
|
||||||
See also: B<--bar> B<--progress>
|
See also: B<--bar> B<--progress> B<--total-jobs>
|
||||||
|
|
||||||
|
|
||||||
=item B<--fg>
|
=item B<--fg>
|
||||||
|
@ -1028,6 +1028,9 @@ Beware: If the fifo is never opened for reading, the job will block forever:
|
||||||
seq 1000000 | parallel --fifo echo This will block
|
seq 1000000 | parallel --fifo echo This will block
|
||||||
seq 1000000 | parallel --fifo 'echo This will not block < {}'
|
seq 1000000 | parallel --fifo 'echo This will not block < {}'
|
||||||
|
|
||||||
|
By using B<--fifo> instead of B<--cat> you may save I/O as B<--cat>
|
||||||
|
will write to a temporary file, whereas B<--fifo> will not.
|
||||||
|
|
||||||
Implies B<--pipe> unless B<--pipe-part> is used.
|
Implies B<--pipe> unless B<--pipe-part> is used.
|
||||||
|
|
||||||
See also: B<--cat> B<--pipe> B<--pipe-part>
|
See also: B<--cat> B<--pipe> B<--pipe-part>
|
||||||
|
@ -1203,11 +1206,11 @@ Example:
|
||||||
|
|
||||||
=item Z<> --halt now,fail=1
|
=item Z<> --halt now,fail=1
|
||||||
|
|
||||||
exit when the first job fails. Kill running jobs.
|
exit when a job has failed. Kill running jobs.
|
||||||
|
|
||||||
=item Z<> --halt soon,fail=3
|
=item Z<> --halt soon,fail=3
|
||||||
|
|
||||||
exit when 3 jobs fail, but wait for running jobs to complete.
|
exit when 3 jobs have failed, but wait for running jobs to complete.
|
||||||
|
|
||||||
=item Z<> --halt soon,fail=3%
|
=item Z<> --halt soon,fail=3%
|
||||||
|
|
||||||
|
@ -1215,11 +1218,11 @@ exit when 3% of the jobs have failed, but wait for running jobs to complete.
|
||||||
|
|
||||||
=item Z<> --halt now,success=1
|
=item Z<> --halt now,success=1
|
||||||
|
|
||||||
exit when a job succeeds. Kill running jobs.
|
exit when a job has succeeded. Kill running jobs.
|
||||||
|
|
||||||
=item Z<> --halt soon,success=3
|
=item Z<> --halt soon,success=3
|
||||||
|
|
||||||
exit when 3 jobs succeeds, but wait for running jobs to complete.
|
exit when 3 jobs have succeeded, but wait for running jobs to complete.
|
||||||
|
|
||||||
=item Z<> --halt now,success=3%
|
=item Z<> --halt now,success=3%
|
||||||
|
|
||||||
|
@ -1227,11 +1230,11 @@ exit when 3% of the jobs have succeeded. Kill running jobs.
|
||||||
|
|
||||||
=item Z<> --halt now,done=1
|
=item Z<> --halt now,done=1
|
||||||
|
|
||||||
exit when one of the jobs finishes. Kill running jobs.
|
exit when a job has finished. Kill running jobs.
|
||||||
|
|
||||||
=item Z<> --halt soon,done=3
|
=item Z<> --halt soon,done=3
|
||||||
|
|
||||||
exit when 3 jobs finishes, but wait for running jobs to complete.
|
exit when 3 jobs have finished, but wait for running jobs to complete.
|
||||||
|
|
||||||
=item Z<> --halt now,done=3%
|
=item Z<> --halt now,done=3%
|
||||||
|
|
||||||
|
@ -1340,6 +1343,8 @@ See also: B<{}>
|
||||||
|
|
||||||
=item B<--joblog> I<logfile>
|
=item B<--joblog> I<logfile>
|
||||||
|
|
||||||
|
=item B<--jl> I<logfile>
|
||||||
|
|
||||||
Logfile for executed jobs.
|
Logfile for executed jobs.
|
||||||
|
|
||||||
Save a list of the executed jobs to I<logfile> in the following TAB
|
Save a list of the executed jobs to I<logfile> in the following TAB
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
par_csv_not_installed() {
|
||||||
|
echo '### Give error if CSV.pm is not installed when using --csv'
|
||||||
|
sudo parallel mv {} {}.hidden ::: /usr/share/perl5/Text/CSV.pm
|
||||||
|
stdout parallel --csv echo ::: this should give an error
|
||||||
|
sudo parallel mv {}.hidden {} ::: /usr/share/perl5/Text/CSV.pm
|
||||||
|
}
|
||||||
|
|
||||||
par_sem_dir() {
|
par_sem_dir() {
|
||||||
echo '### bug #58985: sem stall if .parallel/semaphores is chmod 0'
|
echo '### bug #58985: sem stall if .parallel/semaphores is chmod 0'
|
||||||
chmod 0 ~/.parallel/semaphores
|
chmod 0 ~/.parallel/semaphores
|
||||||
|
|
|
@ -5,6 +5,9 @@ par_bug56403 3 job3cjob3d
|
||||||
par_bug56403 1 job1a
|
par_bug56403 1 job1a
|
||||||
par_bug56403 1 job1b
|
par_bug56403 1 job1b
|
||||||
par_bug56403 2 job2cjob2d
|
par_bug56403 2 job2cjob2d
|
||||||
|
par_csv_not_installed ### Give error if CSV.pm is not installed when using --csv
|
||||||
|
par_csv_not_installed parallel: Error: The perl module Text::CSV is not installed.
|
||||||
|
par_csv_not_installed parallel: Error: Try installing libtext-csv-perl or perl-Text-CSV.
|
||||||
par_delay_Xauto TODO: --retries for those that fail and --sshdelay
|
par_delay_Xauto TODO: --retries for those that fail and --sshdelay
|
||||||
par_delay_Xauto ### bug #58911: --delay Xauto
|
par_delay_Xauto ### bug #58911: --delay Xauto
|
||||||
par_delay_Xauto 0
|
par_delay_Xauto 0
|
||||||
|
|
Loading…
Reference in a new issue