Последовательная очередь FIFO для командной строки linux

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

  1. Очередь должна выполнять команды по одной за раз, то есть никакие две команды не могут выполняться одновременно.
  2. У меня нет списка команд раньше времени. Они будут приходить с веб-запросов, которые получает мой веб-сервер. Это означает, что очередь может быть пустой в течение длительного времени, и одновременно может поступить 10 запросов.
  3. Мой веб-сервер может выполнять только системные вызовы оболочки, поэтому эта программа / решение должно вызываться из командной строки.
  4. У меня только одна машина, поэтому она не может и не должна распределять работу между несколькими машинами.

Первоначально я думал, что at Команда может делать то, что я хочу, но единственное, что она не выполняет команды последовательно.

Я думаю о реализации моего собственного решения в Python с этими частями:

  1. Иметь специальный каталог с файлом блокировки
  2. Команды в очереди хранятся в виде отдельных файлов с именем файла, содержащим увеличивающийся идентификатор последовательности или метку времени или что-то подобное, что я назову "командные файлы"
  3. Написать скрипт на Python, используя fcntl модуль в файле блокировки, чтобы убедиться, что запущен только 1 экземпляр скрипта
  4. Скрипт будет следить за каталогом для любых файлов и выполнять команды оболочки в файлах в порядке имени файла
  5. Когда в каталоге больше нет "командных файлов", скрипт разблокирует файл блокировки и завершит работу.
  6. Когда мой веб-сервер хочет поставить в очередь задания, он добавит новый "командный файл" и вызовет мой скрипт на python
  7. Скрипт python проверит, запущен ли другой экземпляр. Если да, то завершите работу, что позволит другому экземпляру обрабатывать вновь помещенный в очередь "командный файл". Если нет, тогда заблокируйте файл блокировки и начните выполнять "командные файлы" в порядке

Похоже, это будет работать? Единственное условие гонки, с которым я не знаю, как справиться, - это когда первый экземпляр скрипта проверяет каталог и видит, что он пуст, и перед тем, как разблокировать файл блокировки, новая команда ставится в очередь и вызывается новый экземпляр скрипта., И этот новый скрипт завершится, когда увидит, что файл заблокирован. Затем оригинальный скрипт разблокирует файл и завершит работу.

Есть ли что-то, что уже делает это, поэтому мне не нужно реализовывать это самому?

2 ответа

Решение

Используйте именованную трубу, иначе FIFO:

mkfifo /tmp/shellpipe

Запустите процесс оболочки, чьи данные поступают из канала:

/bin/sh < /tmp/shellpipe

Когда веб-сервер хочет выполнить команду, он записывает ее в канал.

sprintf(cmdbuf, "echo '%s' > /tmp/shellpipe", command);
system(cmdbuf);

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

Другие вопросы по тегам