Linux / Bash, как запланировать команды в очереди FIFO?

11279
Andrei

Я хочу, чтобы возможность планировать команды для запуска в очереди FIFO. Я не хочу, чтобы они запускались в указанное время в будущем, как в случае с командой «at». Я хочу, чтобы они начали работать сейчас, но не одновременно. Следующая запланированная команда в очереди должна быть выполнена только после завершения выполнения первой команды. В качестве альтернативы было бы неплохо, если бы я мог указать максимальное количество команд из очереди, которые могли бы выполняться одновременно; например, если максимальное число одновременных команд равно 2, то только не более 2 команд, запланированных в очереди, будут взяты из очереди способом FIFO для выполнения, при этом следующая команда в оставшейся очереди запускается только тогда, когда одна из в настоящее время 2 выполняющиеся команды заканчиваются.

Я слышал, что Task-Spooler может сделать что-то подобное, но этот пакет, похоже, не очень хорошо поддерживается / протестирован и не входит в стандартные репозитории Ubuntu (Ubuntu - то, что я использую). Если это лучшая альтернатива, дайте мне знать, и я буду использовать диспетчер задач, в противном случае мне будет интересно узнать, каков наилучший, самый простой, проверенный, не содержащий ошибок, канонический способ сделать такое с bash.

ОБНОВИТЬ:

Простые решения, такие как; или && из bash не работают. Мне нужно запланировать эти команды из внешней программы, когда происходит событие. Я просто не хочу, чтобы сотни экземпляров моей команды выполнялись одновременно, поэтому мне нужна очередь. Есть внешняя программа, которая будет запускать события, где я могу запускать свои собственные команды. Я хочу обрабатывать ВСЕ инициируемые события, я не хочу пропустить ни одного события, но я также не хочу, чтобы моя система зависала, поэтому я хочу, чтобы очередь обрабатывала мои команды, запущенные из внешней программы.

7
Я нашел эту ссылку, где они обсуждают параллель gnu с семафором и делают некоторые комментарии относительно диспетчера задач. Это может быть полезно: http://unix.stackexchange.com/questions/168978/limit-maximum-number-of-concurrent-scp-processes-running-on-a-host 8 лет назад 0

6 ответов на вопрос

16
Andrei

Task Spooler:

http://vicerveza.homeunix.net/~viric/soft/ts/

https://launchpad.net/ubuntu/+source/task-spooler/0.7.3-1

Does the trick very well. Hopefully it will be included in Ubuntu's package repos.

Это теперь, с 15.10, в репозитории Ubuntu. `apt-get install task-spooler` ovolve 8 лет назад 0
Обратите внимание, что при установке через репозиторий Ubuntu, команда переименовывается из `ts` в` tsp`. Mitja 7 лет назад 0
4
Hennes

использование ;

Например:
ls ; touch test ; ls

Это будет список каталога. Только после lsзапуска он запустится, touch testчто создаст файл с именем test. И только после этого будет запущена следующая команда. (В этом случае другой, lsкоторый покажет старое содержимое и вновь созданный файл).

Подобные команды есть ||и &&.

; всегда будет запускать следующую команду.

&&будет запускаться только следующая команда, если первый возвращенный успех.
Пример:rm -rf *.mp3 && echo "Success! All MP3s deleted!"

||Следующая команда будет выполняться только в том случае, если первая команда вернула ошибочное (ненулевое) возвращаемое значение. Пример: rm -rf *.mp3 || echo "Error! Some files could not be deleted! Check permissions!"

Если вы хотите выполнить команду в фоновом режиме, добавьте амперсанд ( &).
Пример:
make bzimage &
mp3blaster sound.mp3
make mytestsoftware ; ls ; firefox ; make clean

Запустит две команды в фоновом режиме (в этом случае сборка ядра, которая займет некоторое время, и программа для воспроизведения музыки). И на переднем плане он запускает другую задачу компиляции и, как только она будет завершена, ls, firefox и make clean (все последовательно)

Для получения дополнительной информации см. man bash


[Изменить после комментария]

в псевдокоде, что-то вроде этого?

 Программа run_queue:  В то время как (истина) { Wait_for_a_signal ();  Пока (очередь не пустая) { запустить следующую команду из очереди. удалить эту команду из очереди. // Если команды были добавлены в очередь во время выполнения, то // очередь не пустая, продолжаем обрабатывать их все. } // Очередь теперь пуста, возвращаясь к wait_for_a_signal } 
//  // Wait forever on commands and add them to a queue // Signal run_quueu when something gets added. // program add_to_queue() { While(true) { Wait_for_event(); Append command to queue signal run_queue }  } 
Как уточняется в моем вопросе: простые решения, как; или && из bash не работают. Мне нужно запланировать эти команды из внешней программы, когда происходит событие. Я просто не хочу, чтобы сотни экземпляров моей команды выполнялись одновременно, поэтому мне нужна очередь. Andrei 11 лет назад 0
Ах. Да, это немного меняет. :-) Как вы обнаруживаете событие? Кто-то нажимает на кнопку (настоящую веб-версию)? Является ли сценарий обертки вариант? (if (button_pressed &&! script_running) run_my_script. script: установить запуск сценария флага, команду run, сбросить флаг) Hennes 11 лет назад 0
Программа является внешней и будет вызывать событие, в которое я могу добавить свою собственную команду, и в основном я хочу обрабатывать ВСЕ инициируемые события, я не хочу пропустить ни одного события, просто я также не хочу, чтобы моя система зависала, вот почему я хочу, чтобы очередь обрабатывала мои команды, запускаемые внешней программой. Andrei 11 лет назад 0
Добавлен псевдокод. add_to_queue () можно изменить для нескольких очередей. Но ... Если вы собираетесь потратить столько усилий, то лучше подготовить что-то заранее. Hennes 11 лет назад 0
Ну, я сам программист, поэтому я мог бы написать свое собственное решение; возможно, мой вопрос вводил в заблуждение. Так как я хочу запустить это на Pogoplug, я надеялся, что было что-то похожее на команду «at», которая бы сделала то, что я хотел. Единственная часть вопроса «bash» касалась моих надежд на то, что такое решение может быть найдено как можно ближе к оболочке (чтобы быть недорогим, надежным / протестированным и легко доступным практически во всех системах Linux). Andrei 11 лет назад 0
2
terdon

The easiest way would be to simply run the commands sequentially:

cmd1; cmd2; cmd3; cmdN 

If you want the next command to run only if the previous command exited successfully, use &&:

cmd1 && cmd2 && cmd3 && cmdN 

That is the only bash native way I know of doing what you want. If you need job control (setting a number of parallel jobs etc), you could try installing a queue manager such as TORQUE but that seems like overkill if all you want to do is launch jobs sequentially.

Обновлено мой вопрос: простые решения, как; или && из bash не работают. Мне нужно запланировать эти команды из внешней программы, когда происходит событие. Я просто не хочу, чтобы сотни экземпляров моей команды выполнялись одновременно, поэтому мне нужна очередь. Andrei 11 лет назад 0
Взгляните на TORQUE тогда, вы также можете написать что-нибудь. Возможно сочетание `pgrep foo | wc` рассчитывать запущенные процессы и действовать соответственно. terdon 11 лет назад 0
1
psusi

You are looking for at's twin brother: batch. It uses the same daemon but instead of scheduling a specific time, the jobs are queued and will be run whenever the system load average is low.

Но я хочу иметь точный контроль над этим, я не хочу, чтобы партия решала за меня. Диспетчер задач, кажется, может выполнять свою работу, но эта программа немного неясна. Andrei 11 лет назад 0
0
mpy

Помимо специализированных систем массового обслуживания (таких как Sun Grid Engine ), которые вы также можете использовать локально на одной машине и которые предлагают десятки возможностей, вы можете использовать что-то вроде

 command1 && command2 && command3 

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

Обновлено мой вопрос: простые решения, как; или && из bash не работают. Мне нужно запланировать эти команды из внешней программы, когда происходит событие. Я просто не хочу, чтобы сотни экземпляров моей команды выполнялись одновременно, поэтому мне нужна очередь. Andrei 11 лет назад 0
0
Bogdan Dumitru

I went on the same route searching, trying out task-spooler and so on. The best of the best is this:

GNU Parallel --semaphore --fg It also has -j for parallel jobs.

Этот ответ будет более полезным, если вы объясните, что делает эта команда, и причина использования этих опций / флагов. Anthony Geoghegan 8 лет назад 0

Похожие вопросы