(←) предыдущая запись ; следующая запись (→)

Откуда у меня вообще взялось странное желание писать
echo cmd | bash

У нас часто возникает задача обработать много файлов одним и тем же способом. Писать многопоточный питоновский код довольно нетривиально и обычно незачем. Самый простой и надёжный способ загрузить все ядра сервера — написать однопоточную утилиту и запустить несколько процессов одновременно. Для этого есть удобная утилита GNU parallel [Tange 2011].

Ей на вход можно передать набор команд, а она их сама запустит в нужном числе процессов. Этакая очередь задач на минималках. Вдобавок ко всему, parallel ещё и распечатает результат так, будто все процессы были запущены последовательно (а не как в этих жутких примерах про race condition, где вывод параллельно запущенных программ перемешивается).

Сейчас мой любимый подход для распараллеливания вычислений выглядит так:

for FILENAME in $(find ./in/folder -xtype f); do
  echo ./process_data $FILENAME --ton-of-tricky-configs
done | parallel

Если надо запустить в один поток, меняете parallel на bash. Если хотите удостовериться, что правильно сформировали команды, просто убираете команду запуска. Или заменяете parallel на cat / head. Очень удобно!

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

ruby -e 'Dir.glob("folder/*.txt").each{|fn| bn = File.basename(fn, ".txt"); cmd = "mv #{fn} another_folder/#{bn.upcase}"; puts cmd }'  |  parallel
References:
  O. Tange (2011): GNU Parallel - The Command-Line Power Tool,
  ;login: The USENIX Magazine, February 2011:42-47.

Должен же я хоть раз в жизни процитировать тул, который так настойчиво об этом просит