Search code examples
bashgnu-parallel

Howto do floating point compasiosn in an if-statement within a GNU parallel block?


I want to run a batch process in parallel. For this I pipe a list to parallel. When I've an if-statement, that compares two floating point numbers (taken form here), the code doesn't run anymore. How can this be solved.

LIMIT=25

ps | parallel -j2 '   
    echo "Do stuff for {} to determine NUM"    
    NUM=33.3333 # set to demonstrate

    if (( $(echo "$NUM > $LIMIT" | bc -l) )); then
        echo "react..."
    fi

    echo "Do stuff..."
    '

Prints:

Do stuff for \ \ PID\ TTY\ \ \ \ \ \ \ \ \ \ TIME\ CMD to determine NUM
Do stuff...
(standard_in) 2: syntax error
#... snipp

Solution

  • While GNU Parallel is designed to deal correctly with commands spanning multiple lines, I personally find that hard to read. I prefer using a function:

    doit() {
      arg="$1"
      echo "Do stuff for $a to determine NUM"    
      NUM=33.3333 # set to demonstrate
    
      if (( $(echo "$NUM > $LIMIT" | bc -l) )); then
          echo "react..."
      fi
    
      echo "Do stuff..."
    }
    export -f doit
    
    LIMIT=25
    export LIMIT
    
    ps | parallel -j2 doit
    

    Instead of the exports you can use env_parallel:

    ps | env_parallel -j2 doit
    

    If your environment is too big, use env_parallel --session before starting:

    #!/bin/bash
    
    env_parallel --session
    
    # Define functions and variables _after_ running --session
    doit() {
      [...]
    }
    LIMIT=25
    
    ps | env_parallel -j2 doit