Как сделать сравнения с плавающей запятой в операторе if в параллельном блоке GNU?

Я хочу запустить пакетный процесс параллельно. Для этого я передаю список parallel. Когда у меня есть оператор if, который сравнивает два числа с плавающей запятой (взятые в форме ">здесь), код больше не запускается. Как это можно решить.

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..."
    '

Отпечатки:

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

person dani    schedule 02.06.2018    source источник
comment
Добавьте shebang, а затем вставьте туда свой скрипт: shellcheck.net   -  person Cyrus    schedule 02.06.2018
comment
В зависимости от того, что вы делаете, и накладных расходов на запуск внешних программ, таких как bc, может быть быстрее просто делать все последовательно на языке с надлежащей поддержкой операций с плавающей запятой.   -  person chepner    schedule 02.06.2018
comment
В моем реальном коде я вызываю внешнюю (последовательную) программу, которая работает 2-3 минуты (вместо echo "react..."). Нет ли способа сделать это? Нужно ли мне помещать параллельный материал в дополнительный сценарий оболочки?   -  person dani    schedule 02.06.2018
comment
Что вы на самом деле хотите сделать?   -  person Mark Setchell    schedule 03.06.2018
comment
Переместите LIMIT=25 ниже на 2 строки, может быть?   -  person Mark Setchell    schedule 03.06.2018


Ответы (2)


Хотя GNU Parallel предназначен для правильной работы с командами, занимающими несколько строк, лично мне это трудно читать. Я предпочитаю использовать функцию:

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

Вместо экспорта вы можете использовать env_parallel:

ps | env_parallel -j2 doit

Если ваша среда слишком велика, используйте env_parallel --session перед запуском:

#!/bin/bash

env_parallel --session

# Define functions and variables _after_ running --session
doit() {
  [...]
}
LIMIT=25

ps | env_parallel -j2 doit
person Ole Tange    schedule 03.06.2018

LIMIT не установлен внутри параллельной оболочки. Запуск echo "$NUM > $LIMIT" | bc -l расширяется до echo "123 > " | bc -l, что приводит к синтаксической ошибке, о которой сообщает bc. Вам нужно экспортировать/передавать/помещать это значение в оболочку, запускаемую изнутри parallel. Попробуй это:

LIMIT=25
ps | parallel -j2 '   
    LIMIT="'"$LIMIT"'"
    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..."
    '

Или лучше использовать env_parallel, разработанный для таких проблем.

Примечание: GNU parallel был разработан для параллельного выполнения заданий с использованием одного или нескольких компьютеры. Для сценариев, работающих на одном компьютере, лучше использовать команду xargs, которая более доступна (поэтому вам не нужно устанавливать какой-либо пакет каждый раз, когда вы перемещаете свой сценарий на другой компьютер).

person KamilCuk    schedule 02.06.2018
comment
Re: примечание. Взгляните на --embed (от 20180322). - person Ole Tange; 03.06.2018