Служба xinetd вызывает скрипт Python (не выполняется должным образом)

Я прочитал это:

Вы можете использовать xinetd, чтобы добавить службу, запускающую ваш скрипт Python. Стандартный ввод и вывод будут передаваться по сети на нужный порт, поэтому вам не нужно модифицировать ваши скрипты (методы ввода/raw_input и печати будут работать нормально).

В результате я использую специальную службу xinet для запуска script.py, когда установлено TCP-соединение с адресом 192.168.240.37:65123. Поведение не соответствует желаемому/ожидаемому.

/root/script.py

#! /usr/bin/python
my_name = raw_input("Enter your name: ")
print my_name
quit()

/etc/xinetd.d/netunique-сервер

service netunique
{
    disable         = no
    id              = netunique-server
    type            = unlisted
    wait            = no
    socket_type     = stream
    protocol        = tcp
    user            = root
    server          = /usr/bin/python
    server_args     = /root/script.py
    port            = 65123
    flags           = IPv4 REUSE
    bind            = 192.168.240.37
}

статус systemctl xinetd

Nov 11 21:24:00 netunique.ourhome.com xinetd[2161]: xinetd Version 2.3.15 started with libwrap loadavg labeled-ne... in.
Nov 11 21:24:00 netunique.ourhome.com xinetd[2161]: Started working: 1 available service

telnet 192.168.240.37 65123 (ожидаемое поведение)

[root@netunique xinetd.d]# telnet 192.168.240.37 65123
Trying 192.168.240.37...
Connected to 192.168.240.37.
Escape character is '^]'.
Enter your name: John Smith          <-- I type name after prompt here
John Smith                           <-- Script prints entry back to screen
Connection closed by foreign host.   <-- Script does its quit()   

telnet 192.168.240.37 65123 (фактическое поведение)

[root@netunique xinetd.d]# telnet 192.168.240.37 65123
Trying 192.168.240.37...
Connected to 192.168.240.37.
Escape character is '^]'.
<blank>                              <-- no prompt as expected
John Smith                           <-- I enter some data and hit Enter
Enter your name: John Smith          <-- Hard to tell exactly what happened here
Connection closed by foreign host.   <-- Hard to tell exactly what happened here
[root@netunique xinetd.d]# 

Когда я говорю «трудно точно сказать, что здесь произошло», я имею в виду, что трудно сказать, является ли в приведенном выше выводе «Джон Смит», который появляется после приглашения «Введите ваше имя:», результатом оператора печати и жесткого чтобы узнать, является ли «Соединение закрыто внешним хостом» результатом оператора quit().

nc 192.168.240.37 65123 (фактическое поведение)

[root@netunique xinetd.d]# nc 192.168.240.37 65123
<blank>                              <-- no prompt as expected
John Smith                           <-- I enter some data and hit Enter
Enter your name: John Smith          <-- Hard to tell exactly what happened here
                                     <-- Nothing happened here, I hit Enter
                                     <-- I hit Enter again
Ncat: Broken pipe.                   <-- This is the end result

Как видите, у меня очень похожее поведение с netcat.


person Dan    schedule 12.11.2017    source источник
comment
Если я удалю raw_input из своего скрипта и просто вставлю: print 'hello world', это сработает просто отлично. Кажется, не нравится файл raw_input. Не уверен, почему.   -  person Dan    schedule 12.11.2017
comment
Я думаю, что процесс XINETD вызывает script.py, и команды внутри скрипта возвращаются пользователю через сетевое соединение. Когда эти команды включают raw_input, это требует взаимодействия с пользователем, только сетевой сокет на стороне клиента принадлежит telnet, это не процесс python, поэтому он, вероятно, не знает, как интерпретировать или иным образом обрабатывать запрос raw_input. Так что он просто висит там, а не отображает текст. Хотя telnet для IP:port может выполнять сценарий (задачи на сервере), я не уверен, что это можно использовать для интерактивного сценария.   -  person Dan    schedule 14.11.2017
comment
По сути, клиентская сторона — это «telnet», а серверная — «python», поэтому, когда python отправляет raw_input обратно в telnet, telnet не знает, что с ним делать. Вот что я думаю, происходит. Обычно telnet-клиент, разговаривающий с telnet-сервером, является интерактивным, но telnet-клиент, разговаривающий с python-скриптом, вероятно, нет.   -  person Dan    schedule 14.11.2017
comment
Вы знаете, ваша ситуация очень похожа на stackoverflow .com/questions/7193738/ Возможно, когда вы открываете соединение с xinted, вам нужно отправить вступительную строку, чтобы запустить скрипт. Не могли бы вы попробовать свой вариант telnet, а затем нажать Enter. Есть ли возможность ввести данные после того, как появится подсказка, или она просто умирает.   -  person Jeff Richards    schedule 14.11.2017
comment
Переосмысление: интерпретатор Python на стороне сервера обрабатывает команду raw_input, где выполняется скрипт, а не на стороне клиента. Клиент должен вводить данные только через соединение. Да, кажется, я не могу запустить скрипт. Нажатие ввода после открытия соединения telnet приводит к его отключению (см. telnet 192.168.240.37 65123 (фактическое поведение) выше). Я попытался напечатать строку с \n в конце, никаких улучшений. Я пробовал таймер сна до и после приглашения raw_input, никаких улучшений. Судя по присланной вами ссылке, кажется, что серверная часть Кайла настроена по-другому (сокеты). Может моя проблема...   -  person Dan    schedule 14.11.2017
comment
Проблема: отсутствие у меня функциональности программирования сокетов. Я нашел этот пост: mail.python.org/pipermail/python -list/2007-July/423659.html   -  person Dan    schedule 14.11.2017
comment
Хорошая работа, чтобы понять это!   -  person Jeff Richards    schedule 14.11.2017


Ответы (1)


Настоящая проблема для меня, по-видимому, заключается в том, что я не разбираюсь в программировании сокетов. Я нашел этот пост в Интернете по запросу «xinetd python no data» (https://mail.python.org/pipermail/python-list/2007-July/423659.html), который помог мне, по крайней мере, заставить мои вещи работать, и немного проиллюстрировал на примере, как программирование сокетов на самом деле работает. Решение ниже, я удалил raw_input из исходного скрипта и заменил его концепциями из поста.

/root/script.py (исходный)

#! /usr/bin/python
my_name = raw_input("Enter your name: ")
print my_name
quit()

/root/script.py (измененный и рабочий)

#! /usr/bin/python
import sys
print "Enter your name:"                
sys.stdout.flush()
my_name = sys.stdin.readline().strip()
print "Your name is %s" % my_name
sys.stdout.flush()
quit()

telnet 192.168.240.37 65123 (фактическое поведение - работает)

[root@netunique ~]# telnet 192.168.240.37 65123
Trying 192.168.240.37...
Connected to 192.168.240.37.
Escape character is '^]'.
Enter your name:
Bob Smith
Your name is Bob Smith
Connection closed by foreign host.
person Dan    schedule 14.11.2017
comment
Ключевым моментом, благодаря которому это работает, является sys.stdout.flush(). Без него ОС на стороне сервера просто буферизует текст на случай, если вы захотите отправить еще. Он «сбросит» его в сеть, когда вы явно укажете ему об этом или неявно укажете, отправив \n. - person Ralph Bolton; 05.12.2017
comment
использование Python print добавляет новую строку, не так ли? - person Benni; 27.09.2019