Search code examples
bashgnu-parallel

Why GNU parallel used with exported Bash function with an argument enclosed in <> leads to "No such file or directory"?


Scenario:

$ doit () { echo $1; } ; export -f doit ; doit "<xxx>"
<xxx>

$ doit () { echo $1; } ; export -f doit ; parallel doit "<xxx>" ::: 1
/usr/bin/bash: line 1: xxx: No such file or directory

Why GNU parallel used with exported Bash function (doit) with an argument enclosed in <> (<xxx>) leads to No such file or directory?

How to fix?


Solution

  • As noted by @user24246119, the problem is: <xxx> is interpreted as a shell redirection.
    Remember that parallel, without any {} occurrence in the commands, will place the argument at the end of the command.

    So the command executed by parallel is doit <xxx> 1 in this case (xxx is a file use as stdin, and 1 a file for stdout).
    You can see that a file 1 is created if you execute your command while the file xxx exists.

    You have different possibilities to solve this issue, e.g.:

    • use 2 levels of quoting: parallel doit '"<xxx>"' ::: 1
    • let parallel quote it automatically (only works for simple commands like this case): parallel -q doit '<xxx>' ::: 1
    • or if you string is stored in a variable x=<xxx>, you can escape it with ${x@Q}: parallel doit "${x@Q}" ::: 1