Назад | Перейти на главную страницу

Как обработать переменную среды, разделенную пробелами, с помощью xargs

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

$ echo -e 1 2 3 4 | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed

Вот результат этой команды:

1 2 3 4 is the number being processed

Почему кажется, что max-args игнорируется? Затем я попытался явно установить разделитель, что дает лучшие результаты:

$ echo -e 1 2 3 4 | xargs -d " " --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
1 is the number being processed
2 is the number being processed
3 is the number being processed
4
 is the number being processed

Что делает xargs, когда обрабатывает 4-й аргумент?

После некоторых поисков мне удалось почти получить то, что я хочу. Аргументы обрабатываются правильно, но параллелизм не работает (проверено другой командой, не показанной здесь):

$ echo -e 1 2 3 4 | xargs -n 1 | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
1 is the number being processed
2 is the number being processed
3 is the number being processed
4 is the number being processed

Что мне не хватает?

Делает

echo -e 1 2 3 4 | sed -e 's/\s\+/\n/g' | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed

выполнить задачу? Результат кажется правильным:

1 is the number being processed
2 is the number being processed
3 is the number being processed
4 is the number being processed

Я тоже пробовал заменить echo с участием sleep чтобы подтвердить, что он выполняется параллельно, и он:

echo -e 1 2 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 | sed -e 's/\s\+/\n/g' | xargs --max-procs=20 --max-args=1 --replace=% sleep 1

Некоторые другие способы, возможно, более простые, также с -n, -max-args:

echo -n "foo bar baz" | tr ' ' '\n' | xargs -n 1 echo    # With \n, no need for -0
echo -n "foo bar baz" | tr ' ' '\0' | xargs -0 -n 1 echo # Using null character
echo -n "foo bar baz" | xargs -d ' ' -n 1 echo           # Telling to xargs the delimiter
  • Где конечно echo может быть любой командой, какой захотите.
  • Смотрите также -L параметр и -d '\n' (если строки с пробелами).
  • Процесс выигрывает параллельно с --max-procs или, может быть, лучше с parallel.