В Linux, как я могу запустить процесс, к которому я могу вернуться позже, чтобы дать команду после отсоединения

268
XCritics

В настоящее время я занимаюсь разработкой приложения для хостинга серверов (в основном для себя / в целях обучения), и все отлично работает, а что нет, я не знаю, как многие из вас знакомы с Counter-Strike в целом, но я запускаю свой сервер и все все в порядке, но я отсоединяюсь от него (это все написано в Node.js), поэтому я не могу использовать screenили ничего, но в принципе, если бы я хотел изменить уровень на сервере, я мог бы напечатать changelevel de_dust2или что-то, если я должен был запустить сервер вручную, но так как я отсоединен, я не могу дать этому процессу никаких команд.

Я читал о FIFO и использовании Unix-сокетов, но все, что мне кажется, это отозвалось эхом, я не уверен, что не понял FIFO, но думал, что смогу

mkfifo /tmp/server echo "./startserver"> / tmp / server &

а потом, если бы я хотел

echo "changelevel de_dust2" > /tmp/server

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

0

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

0
Dmitry Grigoryev

You must make sure your "daemon" process reads from the pipe.

mkfifo /tmp/server ./startserver < /tmp/server & sleep 10000 > /tmp/server & 

Later on, whatever you write to /tmp/server/ appears on startserver's standard input, for example:

echo "changelevel de_dust2" > /tmp/server 

Note: the sleep command is necessary to keep the pipe open, because each echo command will try to close it when it ends, possibly terminating startserver.

Спасибо за ваш ответ, `startserver` - это длительный процесс, поэтому он не останавливается, пока я не скажу, что когда я набираю` startserver </ tmp / server`, он просто зависает, тогда я должен нажать CTRL + C из это и ничего не происходит. Что я делаю неправильно? XCritics 8 лет назад 0
Добавлена ​​команда `sleep`, чтобы открыть канал в начале. Это должно помочь. Возможно, вам придется увеличить задержку или заменить ее на `cat`, чтобы труба оставалась открытой всегда. Dmitry Grigoryev 8 лет назад 0
Круто, это сработало! Но почему это работает? XCritics 8 лет назад 0
Когда `startserver` пытается прочитать из своего STDIN, он блокируется, пока кто-то не пишет в канал. Команда `sleep 10000> / tmp / server` ничего не записывает, но открывает канал для записи, чего достаточно, чтобы разблокировать процесс. Dmitry Grigoryev 8 лет назад 1
0
mikky

Three ways come to my mind. As long as the daemon process uses stdin/out it shouldn't be a problem to communicate with it.

  1. if you use screen, tmux, or similar solution, you do not have to detach the server. You can safely keep it "attached" to the console and detach the screen itself.

  2. you can use /proc/N/fd/ for communication as long as you have proper rights, where N is the deamon's PID, fd0 is usually the stdin and fd1 is stdout of the N process.

  3. your approach with a named pipe (FIFO) is correct in essence but you're doing it only half-right. What you did was changing the stdout of the process to the pipe, meaning that all that is printed to the stdout by the daemon gets written to the pipe from where you can extract it by, say, cat. The pipe is half-duplex meaning it can only connect one input with one output. What you need are two pipes, one for input, one for output. Then whatever you send to the daemon via one pipe will get there while the response goes via the other pipe back to another program that will read the pipe.

Assume there are two pipes pin and pout. You run:

daemon < pin >pout

Then you must run something like

cat pout & cat > pin

in order to communicate. This is a bad example, it can have race conditions since it's asynchronous but I hope you get the idea.

Возможно ли это сделать с помощью сокетов Unix? XCritics 8 лет назад 0
Да. Но до тех пор, пока вы хотите использовать простые консольные команды, вам нужно будет обернуть их в какой-нибудь метод с поддержкой сокетов, такой как BSD netcat (nc), и, если вы используете Bash, вы также должны держать хотя бы одну запасную трубу под рукой. поскольку, насколько мне известно, Bash не может создать двусторонний IPC-канал в виде сокета. Таким образом, команды будут выглядеть следующим образом: `daemon <pin | nc -lU socket> pin` и интерфейс слушателя / команды будет выглядеть как `nc -U socket`. Настройте параметры nc так, чтобы он оставался в живых после EOF, EOL и т. д. mikky 8 лет назад 0

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