1

В настоящее время я тестирую GNU параллельно, чтобы распределить команду сравнения по нескольким серверам, используя bash. В своей основной функции эта команда сравнения принимает два входа для сравнения (доступ к базе данных Oracle) и требует имя выходного файла через -o. Программа требует как минимум одно действие загрузки, сохранения или прямой загрузки.

compare -o cmp.input1.input2.dat Input1 Input2

У меня есть несколько тысяч этих входных пар и я создаю файл со всеми комбинациями, чтобы каждая строка содержала имя выходного файла и идентификаторы базы данных, требуемые программой.

#test_parallel
-o cmp.input1.input2.dat Input1 Input2
-o cmp.input1.input3.dat Input1 Input3
-o cmp.input2.input3.dat Input2 Input3
[...]

и выполнить команду с использованием параллельного интерфейса, однако выполнить команду сравнения не удалось

parallel -a test_parallel "compare {}"
ERROR: No action specified for results (load, save or direct upload)
usage: compare [-u][-o <file>] query target

используя режим --dryrun вот что параллельно выполняет:

compare -o\ cmp.input1.input2.dat\ Input1\ Input2

По какой-то причине я не понимаю, пробел не обрабатывается корректно программой сравнения. Выполнение этой команды в bash приводит к точно так же сообщению об ошибке. Удаление экранирования после флага -o (я мог бы переместить -o в параллельную команду) приводит к ошибке "слишком много аргументов". Удаление всех escape-кодов запускает команду, как и ожидалось.

Можно ли сказать параллель не печатать escape при вызове команды? Я не вижу ничего в документации, кроме того, что это ожидаемое поведение по умолчанию, как указано в parallel --shellquote

1 ответ1

2

GNU Parallel обрабатывает ввод как один аргумент и заключает его в кавычки, чтобы вы могли безопасно использовать такие имена файлов, как:

My brother's 12" records costs 30$ each.txt

В вашем случае вы хотите, чтобы аргумент был проанализирован оболочкой, поэтому пробелы не будут заключены в кавычки:

parallel -a test_parallel eval compare {}

Или вы можете разделить на пространство:

parallel --colsep ' ' -a test_parallel compare {1} {2} {3} {4}

Но так как вы хотите сравнить все со всеми, вы можете сделать это более элегантно:

parallel cmp -o ../out/cmp.{1}.{2} {1} {2} ::: Input* ::: Input*

Это позволит сравнить все входные данные * со всеми входными данными *. С помощью --results вы можете получить хорошо структурированные результаты в директории :

parallel --results out/ cmp {1} {2} ::: Input* ::: Input*

Но если вы хотите пропустить запуск cmp InputY InputX после того, как вы уже запустили cmd InputX InputY то вы можете сделать это:

parallel --results out/ cmp {=1' $arg[1] ge $arg[2] and $job->skip();' =} {2} ::: Input* ::: Input*

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .