parallel: --(n)onall and --sshdelay fixed.
[parallel.git] / testsuite / tests-to-run / parallel-local-0.3s.sh
blobde757ce8c176c951c88bc8a9074f14a5e1573a5d
1 #!/bin/bash
3 # Simple jobs that never fails
4 # Each should be taking 0.3-1s and be possible to run in parallel
5 # I.e.: No race conditions, no logins
7 stdsort() {
8 "$@" 2>&1 | LC_ALL=C sort;
10 export -f stdsort
12 # Test amount of parallelization
13 # parallel --shuf --jl /tmp/myjl -j1 'export JOBS={1};'bash tests-to-run/parallel-local-0.3s.sh ::: {1..16} ::: {1..5}
15 par_opt_gnu() {
16 echo '### Test --tollef'
17 stdout parallel -k --tollef echo -- 1 2 3 ::: a b c | LC_ALL=C sort
19 echo '### Test --tollef --gnu'
20 stdout parallel -k --tollef --gnu echo ::: 1 2 3 -- a b c
22 echo '### Test --gnu'
23 parallel -k --gnu echo ::: 1 2 3 -- a b c
26 par_colsep_default() {
27 echo "bug #37956: --colsep does not default to '\t' as specified in the man page."
28 printf "A\tB\n1\tone" | parallel --header : echo {B} {A}
31 par_tmux_command_not_found() {
32 echo '### PARALLEL_TMUX not found'
33 PARALLEL_TMUX=not-existing parallel --tmux echo ::: 1
36 par_echo_jobseq() {
37 echo '### bug #44995: parallel echo {#} ::: 1 2 ::: 1 2'
39 parallel -k echo {#} ::: 1 2 ::: 1 2
42 par_no_joblog_with_dryrun() {
43 echo 'bug #46016: --joblog should not log when --dryrun'
45 parallel --dryrun --joblog - echo ::: Only_this
48 par_tagstring_with_d() {
49 echo 'bug #47002: --tagstring with -d \n\n'
51 (seq 3; echo; seq 4) |
52 parallel -k -d '\n\n' --tagstring {%} echo ABC';'echo
55 par_xargs_nul_char_in_input() {
56 echo 'bug #47290: xargs: Warning: a NUL character occurred in the input'
58 perl -e 'print "foo\0not printed"' | parallel echo
61 par_maxproc() {
62 echo '### Test --max-procs and -P: Number of processes'
64 seq 1 10 | parallel -k --max-procs +0 echo max proc
65 seq 1 10 | parallel -k -P 200% echo 200% proc
68 par_maxchar_s() {
69 echo '### Test --max-chars and -s: Max number of chars in a line'
71 (echo line 1;echo line 1;echo line 2) | parallel -k --max-chars 25 -X echo
72 (echo line 1;echo line 1;echo line 2) | parallel -k -s 25 -X echo
75 par_no_run_if_empty() {
76 echo '### Test --no-run-if-empty and -r: This should give no output'
78 echo " " | parallel -r echo
79 echo " " | parallel --no-run-if-empty echo
82 par_help() {
83 echo '### Test --help and -h: Help output (just check we get the same amount of lines)'
85 echo Output from -h and --help
86 parallel -h | wc -l
87 parallel --help | wc -l
90 par_version() {
91 echo '### Test --version: Version output (just check we get the same amount of lines)'
93 parallel --version | wc -l
96 par_verbose_t() {
97 echo '### Test --verbose and -t'
99 (echo b; echo c; echo f) | parallel -k -t echo {}ar 2>&1 >/dev/null
100 (echo b; echo c; echo f) | parallel -k --verbose echo {}ar 2>&1 >/dev/null
103 par_show_limits() {
104 echo '### Test --show-limits'
106 (echo b; echo c; echo f) | parallel -k --show-limits echo {}ar
107 (echo b; echo c; echo f) | parallel -j1 -kX --show-limits -s 100 echo {}ar
108 echo "### BUG: empty lines with --show-limit"
109 echo | stdout parallel --show-limits
110 ) | perl -pe 's/131\d\d\d/131xxx/'
113 par_test_zero_args() {
114 echo '### Test 0-arguments'
116 seq 1 2 | parallel -k -n0 echo n0
117 seq 1 2 | parallel -k -L0 echo L0
118 seq 1 2 | parallel -k -N0 echo N0
121 par_l0_is_l1() {
122 echo '### Because of --tollef -l, then -l0 == -l1, sorry'
124 seq 1 2 | parallel -k -l0 echo l0
127 par_replace_replacementstring() {
128 echo '### Test replace {}'
130 seq 1 2 | parallel -k -N0 echo replace {} curlies
133 par_arguments_on_cmdline() {
134 echo '### Test arguments on commandline'
136 parallel -k -N0 echo args on cmdline ::: 1 2
139 par_nice_locally() {
140 echo '### Test --nice locally'
142 parallel --nice 1 -vv 'PAR=a bash -c "echo \$PAR {}"' ::: b
145 par_disk_full() {
146 echo '### Disk full'
148 SMALLDISK=${SMALLDISK:-/mnt/ram}
149 export SMALLDISK
151 cd /tmp
152 sudo umount -l smalldisk.img
153 dd if=/dev/zero of=smalldisk.img bs=100k count=1k
154 yes|mkfs smalldisk.img
155 sudo mkdir -p /mnt/ram
156 sudo mount smalldisk.img /mnt/ram
157 sudo chmod 777 /mnt/ram
158 ) >/dev/null 2>/dev/null
160 cat /dev/zero >$SMALLDISK/out
161 parallel --tmpdir $SMALLDISK echo ::: OK
163 rm $SMALLDISK/out
165 sudo umount -l /tmp/smalldisk.img
168 par_delimiter() {
169 echo '### Test --delimiter and -d: Delimiter instead of newline'
171 echo '# Yes there is supposed to be an extra newline for -d N'
172 echo line 1Nline 2Nline 3 | parallel -k -d N echo This is
173 echo line 1Nline 2Nline 3 | parallel -k --delimiter N echo This is
174 printf "delimiter NUL line 1\0line 2\0line 3" | parallel -k -d '\0' echo
175 printf "delimiter TAB line 1\tline 2\tline 3" | parallel -k --delimiter '\t' echo
178 par_argfile() {
179 echo '### Test -a and --arg-file: Read input from file instead of stdin'
181 seq 1 10 >/tmp/parallel_$$-1; parallel -k -a /tmp/parallel_$$-1 echo; rm /tmp/parallel_$$-1
182 seq 1 10 >/tmp/parallel_$$-2; parallel -k --arg-file /tmp/parallel_$$-2 echo; rm /tmp/parallel_$$-2
185 par_pipe_unneeded_procs() {
186 echo '### Test bug #34241: --pipe should not spawn unneeded processes'
187 seq 3 | parallel -j30 --pipe --block-size 10 cat\;echo o 2> >(grep -Ev 'Warning: Starting|Warning: Consider')
190 par_results_arg_256() {
191 echo '### bug #42089: --results with arg > 256 chars (should be 1 char shorter)'
192 parallel --results parallel_test_dir echo ::: 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
193 ls parallel_test_dir/1/
194 rm -rf parallel_test_dir
197 par_pipe_to_func() {
198 echo '### bug #45998: --pipe to function broken'
200 myfunc() { echo $1; cat; }
201 export -f myfunc
202 echo pipefunc OK | parallel --pipe myfunc {#}
203 echo pipefunc and more OK | parallel --pipe 'myfunc {#};echo and more OK'
206 par_pipepart_roundrobin() {
207 echo '### bug #45769: --round-robin --pipepart gives wrong results'
209 seq 10000 >/tmp/seq10000
210 parallel -j2 --pipepart -a /tmp/seq10000 --block 14 --round-robin wc | wc -l
211 rm /tmp/seq10000
214 par_pipepart_header() {
215 echo '### bug #44614: --pipepart --header off by one'
217 seq 10 >/tmp/parallel_44616
218 parallel --pipepart -a /tmp/parallel_44616 -k --block 5 'echo foo; cat'
219 parallel --pipepart -a /tmp/parallel_44616 -k --block 2 --regexp --recend 3'\n' 'echo foo; cat'
220 rm /tmp/parallel_44616
223 par_quote() {
224 echo '### Test -q'
225 parallel -kq perl -e '$ARGV[0]=~/^\S+\s+\S+$/ and print $ARGV[0],"\n"' ::: "a b" c "d e f" g "h i"
227 echo '### Test -q {#}'
228 parallel -kq echo {#} ::: a b
229 parallel -kq echo {\#} ::: a b
230 parallel -kq echo {\\#} ::: a b
233 par_read_from_stdin() {
234 echo '### Test empty line as input'
235 echo | parallel echo empty input line
237 echo '### Tests if (cat | sh) works'
238 perl -e 'for(1..25) {print "echo a $_; echo b $_\n"}' | parallel 2>&1 | sort
240 echo '### Test if xargs-mode works'
241 perl -e 'for(1..25) {print "a $_\nb $_\n"}' | parallel echo 2>&1 | sort
244 par_total_from_joblog() {
245 echo 'bug #47086: [PATCH] Initialize total_completed from joblog'
246 rm -f /tmp/parallel-47086
247 parallel -j1 --joblog /tmp/parallel-47086 --halt now,fail=1 echo '{= $_=$Global::total_completed =};exit {}' ::: 0 0 0 1 0 0
248 parallel -j1 --joblog /tmp/parallel-47086 --halt now,fail=1 --resume echo '{= $_=$Global::total_completed =};exit {}' ::: 0 0 0 1 0 0
251 par_xapply() {
252 echo '### Test bug #43284: {%} and {#} with --xapply'
253 parallel --xapply 'echo {1} {#} {%} {2}' ::: a ::: b
254 parallel -N2 'echo {%}' ::: a b
256 echo '### bug #47501: --xapply for some input sources'
257 # Wrapping does not work yet
258 parallel -k echo ::: a b c aWRAP :::+ aa bb cc ::: A B :::+ AA BB AAwrap
261 par_exit_val() {
262 echo '### Test bug #45619: "--halt" erroneous error exit code (should give 0)'
263 seq 10 | parallel --halt now,fail=1 true
264 echo $?
266 echo '### Test exit val - true'
267 echo true | parallel
268 echo $?
270 echo '### Test exit val - false'
271 echo false | parallel
272 echo $?
275 par_long_cmd_mem_use() {
276 echo '### Test long commands do not take up all memory'
278 seq 1 100 |
279 parallel -j0 -qv perl -e '$r=rand(shift); for($f = 0; $f < $r; $f++){ $a = "a"x100 } print shift,"\n"' 10000 2>/dev/null |
280 sort
283 par_test_L_context_replace() {
284 echo '### Test -N context replace'
286 seq 19 | parallel -k -N 10 echo a{}b
288 echo '### Test -L context replace'
290 seq 19 | parallel -k -L 10 echo a{}b
293 par_test_r_with_pipe() {
294 echo '### Test of -r with --pipe - the first should give an empty line. The second should not.'
296 echo | parallel -j2 -N1 --pipe cat | wc -l
297 echo | parallel -r -j2 -N1 --pipe cat | wc -l
300 par_test_tty() {
301 echo '### Test --tty'
303 seq 0.1 0.1 0.5 | parallel -j1 --tty tty\;sleep
306 par_no_command_given() {
307 echo '### Test bugfix if no command given'
309 (echo echo; seq 1 5; perl -e 'print "z"x1000000'; seq 12 15) |
310 stdout parallel -j1 -km -s 10
314 par_inefficient_L() {
315 echo "bug #37325: Inefficiency of --pipe -L"
317 seq 2000 | parallel -k --pipe --block 1k -L 4 wc\;echo FOO | uniq
320 par_pipe_record_size_in_lines() {
321 echo "bug #34958: --pipe with record size measured in lines"
323 seq 10 | parallel -k --pipe -L 4 cat\;echo bug 34958-1
324 seq 10 | parallel -k --pipe -l 4 cat\;echo bug 34958-2
327 par_pipe_no_command() {
328 echo '### --pipe without command'
330 seq -w 10 | stdout parallel --pipe
333 par_expansion_in_colsep() {
334 echo '### bug #36260: {n} expansion in --colsep files fails for empty fields if all following fields are also empty'
336 echo A,B,, | parallel --colsep , echo {1}{3}{2}
339 par_extglob() {
340 bash -O extglob -c '. `which env_parallel.bash`;
341 _longopt () {
342 case "$prev" in
343 --+([-a-z0-9_]))
344 echo foo;;
345 esac;
347 env_parallel echo ::: env_parallel 2>&1
351 par_tricolonplus() {
352 echo '### bug #48745: :::+ bug'
354 parallel -k echo ::: 11 22 33 ::::+ <(seq 3) <(seq 21 23) ::: a b c :::+ aa bb cc
355 parallel -k echo :::: <(seq 3) <(seq 21 23) :::+ a b c ::: aa bb cc
356 parallel -k echo :::: <(seq 3) :::: <(seq 21 23) :::+ a b c ::: aa bb cc
359 par_colsep_0() {
360 echo 'bug --colsep 0'
362 parallel --colsep 0 echo {2} ::: a0OK0c
363 parallel --header : --colsep 0 echo {ok} ::: A0ok0B a0OK0b
366 par_empty() {
367 echo "bug #:"
369 parallel echo ::: true
372 par_empty_line() {
373 echo '### Test bug: empty line for | sh with -k'
374 (echo echo a ; echo ; echo echo b) | parallel -k
377 par_append_joblog() {
378 echo '### can you append to a joblog using +'
379 parallel --joblog /tmp/parallel_append_joblog echo ::: 1
380 parallel --joblog +/tmp/parallel_append_joblog echo ::: 1
381 wc -l /tmp/parallel_append_joblog
384 par_file_ending_in_newline() {
385 echo '### Hans found a bug giving unitialized variable'
386 echo >/tmp/parallel_f1
387 echo >/tmp/parallel_f2'
389 echo /tmp/parallel_f1 /tmp/parallel_f2 |
390 stdout parallel -kv --delimiter ' ' gzip
391 rm /tmp/parallel_f*
394 par_python_children() {
395 echo '### bug #49970: Python child process dies if --env is used'
396 fu() { echo joe; }
397 export -f fu
398 echo foo | stdout parallel --env fu python -c \
399 \""import os; f = os.popen('uname -p'); output = f.read(); rc = f.close()"\"
402 par_pipepart_block_bigger_2G() {
403 echo '### Test that --pipepart can have blocks > 2GB'
404 tmp=$(mktemp)
405 echo foo >$tmp
406 parallel --pipepart -a $tmp --block 3G wc
407 rm $tmp
410 par_retries_replacement_string() {
411 tmp=$(mktemp)
412 parallel --retries {//} "echo {/} >>$tmp;exit {/}" ::: 1/11 2/22 3/33
413 sort $tmp
414 rm $tmp
417 par_tee() {
418 export PARALLEL='-k --tee --pipe --tag'
419 seq 1000000 | parallel 'echo {%};LC_ALL=C wc' ::: {1..5} ::: {a..b}
420 seq 300000 | parallel 'grep {1} | LC_ALL=C wc {2}' ::: {1..5} ::: -l -c
423 par_tagstring_pipe() {
424 echo 'bug #50228: --pipe --tagstring broken'
425 seq 3000 | parallel -j4 --pipe -N1000 -k --tagstring {%} LC_ALL=C wc
428 par_link_files_as_only_arg() {
429 echo 'bug #50685: single ::::+ does not work'
430 parallel -k echo ::::+ <(seq 10) <(seq 3) <(seq 4)
433 par_basic_halt() {
434 cpuburn=$(tempfile)
435 cpuburn2=$(tempfile)
436 (echo '#!/usr/bin/perl'
437 echo "eval{setpriority(0,0,9)}; while(1){}") > $cpuburn
438 chmod 700 $cpuburn
439 cp -a $cpuburn $cpuburn2
441 parallel -j4 --halt 2 ::: 'sleep 1' $cpuburn false;
442 killall $(basename $cpuburn) 2>/dev/null &&
443 echo ERROR: cpuburn should already have been killed
444 parallel -j4 --halt -2 ::: 'sleep 1' $cpuburn2 true;
445 killall $(basename $cpuburn2) 2>/dev/null &&
446 echo ERROR: cpuburn2 should already have been killed
447 rm $cpuburn $cpuburn2
449 parallel --halt error echo ::: should not print
450 parallel --halt soon echo ::: should not print
451 parallel --halt now echo ::: should not print
454 par_newline_in_command() {
455 echo Command with newline and positional replacement strings
456 parallel "
457 echo {1
458 } {2}
459 " ::: O ::: K
462 par_wd_3dot_local() {
463 echo 'bug #45993: --wd ... should also work when run locally'
466 parallel --wd /bi 'pwd; echo $OLDPWD; echo' ::: fail
467 parallel --wd /bin 'pwd; echo $OLDPWD; echo' ::: OK
468 parallel --wd / 'pwd; echo $OLDPWD; echo' ::: OK
469 parallel --wd /tmp 'pwd; echo $OLDPWD; echo' ::: OK
470 parallel --wd ... 'pwd; echo $OLDPWD; echo' ::: OK
471 parallel --wd . 'pwd; echo $OLDPWD; echo' ::: OK
473 perl -pe 's:/mnt/4tb::; s:/home/tange:~:;' |
474 perl -pe 's:parallel./:parallel/:;' |
475 perl -pe 's/'`hostname`'/hostname/g; s/\d+/0/g'
478 par_X_eta_div_zero() {
479 echo '### bug #34422: parallel -X --eta crashes with div by zero'
481 # We do not care how long it took
482 seq 2 | stdout parallel -X --eta echo |
483 grep -E -v 'ETA:.*AVG' |
484 perl -pe 's/\d+/0/g' |
485 perl -pe 's/Comp.* to complete//' |
486 perl -ne '/../ and print'
489 par_parcat_args_stdin() {
490 echo 'bug #51690: parcat: read args from stdin'
491 tmp1=$(tempfile)
492 tmp2=$(tempfile)
493 echo OK1 > $tmp1
494 echo OK2 > $tmp2
495 (echo $tmp1
496 echo $tmp2) | parcat | sort
497 rm $tmp1 $tmp2
500 par_parcat_rm() {
501 echo 'bug #51691: parcat --rm remove fifo when opened'
502 tmp1=$(tempfile)
503 echo OK1 > $tmp1
504 parcat --rm $tmp1
505 rm $tmp1 2>/dev/null || echo OK file removed
508 par_linebuffer_files() {
509 echo '### bug #48658: --linebuffer --files'
511 stdout parallel --files --linebuffer 'sleep .1;seq {};sleep .1' ::: {1..10} | wc -l
514 par_halt_one_job() {
515 echo '# Halt soon if there is a single job'
516 echo should run 0 1 = job 1 2
517 parallel -j1 --halt now,fail=1 'echo {#};exit {}' ::: 0 1 0
518 echo should run 1 = job 1
519 parallel -j1 --halt now,fail=1 'echo {#};exit {}' ::: 1 0 1
520 echo should run 0 1 = job 1 2
521 parallel -j1 --halt soon,fail=1 'echo {#};exit {}' ::: 0 1 0
522 echo should run 1 = job 1
523 parallel -j1 --halt soon,fail=1 'echo {#};exit {}' ::: 1 0 1
526 par_blocking_redir() {
528 echo 'bug #52740: Bash redirection with process substitution blocks'
529 echo Test stdout
530 echo 3 | parallel seq > >(echo stdout;wc) 2> >(echo stderr >&2; wc >&2)
531 echo Test stderr
532 echo nOfilE | parallel ls > >(echo stdout;wc) 2> >(echo stderr >&2; wc >&2)
533 ) 2>&1 | LC_ALL=C sort
536 par_pipepart_recend_recstart() {
537 echo 'bug #52343: --recend/--recstart does wrong thing with --pipepart'
538 tmp1=$(tempfile)
539 seq 10 > $tmp1
540 parallel -k --pipepart -a $tmp1 --recend '\n' --recstart '6' --block 1 'echo a; cat'
541 parallel -k --pipe < $tmp1 --recend '\n' --recstart '6' --block 1 'echo a; cat'
542 rm $tmp1 2>/dev/null
545 par_pipe_tag_v() {
546 echo 'pipe with --tag -v'
547 seq 3 | parallel -v --pipe --tagstring foo cat
548 # This should only give the filename
549 seq 3 | parallel -v --pipe --tagstring foo --files cat |
550 perl -pe 's:/tmp/par.*.par:/tmp/tmpfile.par:'
553 par_dryrun_append_joblog() {
554 echo '--dry-run should not append to joblog'
555 rm -f /tmp/jl.$$
556 parallel -k --jl /tmp/jl.$$ echo ::: 1 2 3
557 parallel --dryrun -k --jl +/tmp/jl.$$ echo ::: 1 2 3 4
558 # Job 4 should not show up: 3 lines + header = 4
559 wc -l < /tmp/jl.$$
562 par_0_no_newline() {
563 echo 'A single zero without \n should not be ignored'
564 echo -n 0 | parallel echo
567 par_csv() {
568 (echo '"col1""x3""","new'
569 echo 'line col2","new2'
570 echo 'line col3",col 4') |
571 parallel --csv echo {1}-{2}-{3}-{4}
572 echo '"2""x3"" board","Value with ,",Column 3' |
573 parallel --csv echo {1}-{2}-{3}
576 par_csv_pipe() {
577 echo 'Only pass full records to tail'
578 echo 'Too small block size'
579 perl -e 'for $b(1..10) {
580 print join",", map {"\"$_\n$_\""} $b*1000..$b*1000+1000;
581 print "\n"
582 }' |
583 stdout parallel --pipe --csv -k --block 10k tail -n1 |
584 sort -n
586 echo 'More records in single block'
587 perl -e 'for $b(1..10) {
588 print join",", map {"\"$_\n$_\""} $b*1000..$b*1000+1000;
589 print "\n"
590 }' |
591 stdout parallel --pipe --csv -k --block 100k tail -n1 |
592 sort -n
595 par_slow_pipe_regexp() {
596 echo "### bug #53718: --pipe --regexp -N blocks"
597 echo This should take a few ms, but took more than 2 hours
598 seq 54000 80000 |
599 parallel -N1000 --regexp --pipe --recstart 4 --recend 5 -k wc
600 echo "### These should give same output"
601 seq 54000 80000 |
602 parallel -N1000 --regexp --pipe --recstart 4 --recend 5 -k cat |
603 md5sum
604 seq 54000 80000 | md5sum
607 par_results() {
608 echo "### --results test.csv"
609 parallel -k --results /tmp/$$.csv echo ::: a b c
610 rm /tmp/$$.csv
613 par_testquote() {
614 testquote() {
615 printf '"#&/\n()*=?'"'" |
616 PARALLEL_SHELL=$1 parallel -0 echo
618 export -f testquote
619 parallel --tag -k testquote ::: ash bash csh dash fdsh fish fizsh ksh ksh93 mksh posh rbash rc rzsh sash sh static-sh tcsh yash zsh
622 par_locale_quoting() {
623 echo "### quoting in different locales"
624 printf '\243`/tmp/test\243`\n'
625 printf '\243`/tmp/test\243`\n' | LC_ALL=zh_HK.big5hkscs xargs echo '$LC_ALL'
626 # LC_ALL should be zh_HK.big5hkscs, but that makes quoting hard.
627 printf '\243`/tmp/test\243`\n' | LC_ALL=zh_HK.big5hkscs parallel -v echo '$LC_ALL'
630 par_PARALLEL_ENV() {
631 echo '### PARALLEL_ENV as variable'
632 PARALLEL_ENV="v='OK as variable'" parallel {} '$v' ::: echo
633 PARALLEL_ENV=$(mktemp)
634 echo '### PARALLEL_ENV as file'
635 echo "v='OK as file'" > $PARALLEL_ENV
636 PARALLEL_ENV="$PARALLEL_ENV" parallel {} '$v' ::: echo
637 echo '### PARALLEL_ENV as fifo'
638 rm $PARALLEL_ENV
639 mkfifo $PARALLEL_ENV
640 # () needed to avoid [1]+ Done
641 (echo "v='OK as fifo'" > $PARALLEL_ENV &) 2>/dev/null
642 PARALLEL_ENV="$PARALLEL_ENV" parallel {} '$v' ::: echo
643 rm $PARALLEL_ENV
646 par_pipe_recend() {
647 echo 'bug #54328: --pipe --recend '' blocks'
648 seq 3 | parallel -k --pipe --regexp --recend '' -n 1 xxd
649 seq 3 | parallel -k --pipe --recend '' -n 1 xxd
652 par_perlexpr_with_newline() {
653 echo 'Perl expression spanning 2 lines'
654 mkdir -p tmp
655 cd tmp
656 touch "Dad's \"famous\" 1' pizza"
657 # Important with newline in perl expression:
658 parallel mv {} '{= $a=pQ($_); $b=$_;
659 $_=qx{date -r "$a" +%FT%T}; chomp; $_="$_ $b" =}' \
660 ::: "Dad's \"famous\" 1' pizza"
661 rm *"Dad's \"famous\" 1' pizza"
664 par_empty_command() {
665 echo 'bug #54647: parset ignores empty lines'
666 # really due to this. Should give an empty line due to -v:
667 parallel -v :::: <(echo)
668 . `which env_parallel.bash`
669 parset a,b,c :::: <(echo echo A; echo; echo echo C)
670 echo Empty: $b
671 parset a,b,c :::: <(echo echo A; echo echo B; echo echo C)
672 echo B: $b
675 par_empty_input_on_stdin() {
676 echo 'https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=910470'
677 echo 'This should give no output'
678 true | stdout parallel --shuf echo
681 par_tee_too_many_args() {
682 echo '### Fail if there are more arguments than --jobs'
683 seq 11 | parallel -k --tag --pipe -j4 --tee grep {} ::: {1..4}
684 seq 11 | parallel -k --tag --pipe -j4 --tee grep {} ::: {1..5}
687 par_space_envvar() {
688 echo "### bug: --gnu was ignored if env var started with space: PARALLEL=' --gnu'"
689 export PARALLEL=" -v" && parallel echo ::: 'space in envvar OK'
692 par_pipe_N1_regexp() {
693 echo 'bug #55131: --regexp --recstart hangs'
694 echo "These should give the same"
695 printf 'begin\n%send\n' '' a b c |
696 parallel -kN1 --recstart 'begin\n' --pipe --regexp echo JOB{#}\;cat\;echo END
697 printf 'begin\n%send\n' '' a b c |
698 parallel -kN1 --recstart 'begin\n' --pipe echo JOB{#}\;cat\;echo END
701 par_sem_quote() {
702 echo '### sem --quote should not add empty argument'
703 sem --id sem_quote --fg --quote -v echo
706 par_halt_on_error_division_by_zero() {
707 echo '### --halt-on-error soon,fail=100% with no input should not give division by zero'
708 stdout parallel --halt-on-error soon,fail=100% echo </dev/null
709 echo $?
712 par_wd_dotdotdot() {
713 echo '### parallel --wd ... should clean up'
714 parallel --wd ... 'pwd;true' ::: foo | parallel ls 2>/dev/null
715 echo $? == 1
716 echo '### $OLDPWD should be the dir in which parallel starts'
717 cd /tmp
718 parallel --wd ... 'echo $OLDPWD' ::: foo
721 par_fish() {
722 echo '### https://github.com/fish-shell/fish-shell/issues/5582'
723 echo OK | stdout fish -c 'parallel --pipe cat'
726 par_jobslot_jobnumber_pipe() {
727 echo '### Test bug #43376: {%} and {#} with --pipe'
728 echo foo | parallel -q --pipe -k echo {#}
729 echo foo | parallel --pipe -k echo {%}
730 echo foo | parallel -q --pipe -k echo {%}
731 echo foo | parallel --pipe -k echo {#}
734 par_replacement_string_as_part_of_command() {
735 echo '### {} as part of the command'
736 echo p /bin/ls | parallel l{= s/p/s/ =}
737 echo /bin/ls-p | parallel --colsep '-' l{=2 s/p/s/ =} {1}
738 echo s /bin/ls | parallel l{}
739 echo /bin/ls | parallel ls {}
740 echo ls /bin/ls | parallel {}
741 echo ls /bin/ls | parallel
744 par_japanese_chars_in_replacement_string() {
745 echo '### bug #43817: Some JP char cause problems in positional replacement strings'
746 parallel -k echo ::: '�<�>' '�<1 $_=2�>' 'ワ'
747 parallel -k echo {1} ::: '�<�>' '�<1 $_=2�>' 'ワ'
748 parallel -Xj1 echo ::: '�<�>' '�<1 $_=2�>' 'ワ'
749 parallel -Xj1 echo {1} ::: '�<�>' '�<1 $_=2�>' 'ワ'
752 par_rpl_that_is_substring_of_longer_rpl() {
753 echo '### --rpl % that is a substring of longer --rpl %D'
754 parallel --rpl '{+.} s:.*\.::' --rpl '%' \
755 --rpl '%D $_=::shell_quote(::dirname($_));' \
756 --rpl '%B s:.*/::;s:\.[^/.]+$::;' \
757 --rpl '%E s:.*\.::' \
758 'echo {}=%;echo %D={//};echo %B={/.};echo %E={+.};echo %D/%B.%E={}' ::: a.b/c.d/e.f
761 par_unquote_replacement_string() {
762 echo '### Can part of the replacement string be unquoted using uq()?'
763 parallel echo '{}{=uq()=}' ::: '`echo foo`'
766 par_delimiter_space() {
767 echo '### Does space as delimiter work?'
768 parallel -k -d " " echo ::: "1 done"
771 par_recend_not_regexp() {
772 echo '### bug #56558: --rrs with --recend that is not regexp'
773 echo 'a+b' | parallel -k --pipe --rrs --recend '+' -N1 'cat;echo end'
776 par_profile() {
777 echo '### Test -J profile, -J /dir/profile, -J ./profile'
778 echo --tag > testprofile_local
779 parallel -J ./testprofile_local echo ::: local
780 rm testprofile_local
781 echo --tag > testprofile_abs
782 parallel -J `pwd`/testprofile_abs echo ::: abs
783 rm testprofile_abs
784 echo --tag > ~/.parallel/testprofile_config
785 parallel -J testprofile_config echo ::: config
786 rm ~/.parallel/testprofile_config
789 par_cr_newline_header() {
790 echo '### --header : should set named replacement string if input line ends in \r\n'
791 printf "foo\r\nbar\r\n" |
792 parallel --colsep , --header : echo {foo}
795 par_plus_slot_replacement() {
796 echo '### show {slot}'
797 parallel -k --plus echo '{slot}=$PARALLEL_JOBSLOT={%}' ::: A B C
800 export -f $(compgen -A function | grep par_)
801 compgen -A function | grep par_ | LC_ALL=C sort |
802 parallel --timeout 1000% -j6 --tag -k --joblog /tmp/jl-`basename $0` '{} 2>&1' |
803 perl -pe 's:/usr/bin:/bin:g'