제가 아는 한, 다음과 같이 입력하면...
python -i
...파이썬 인터프리터는 이제 stdin에서 읽고 다음과 같이 작동합니다.
>>> print "Hello"
Hello
이렇게 하면 동일한 작업을 수행하기를 원합니다.
echo 'print "Hello"' > /proc/$(pidof python)/fd/0
그러나 이것은 출력입니다(실제 빈 줄).
>>> print "Hello"
<empyline>
print "Hello"\n
제가 보기엔 그냥 쓰기 만 stdout
하고 해석하지는 않는 것 같아요 . 왜 작동하지 않나요? 작동하게 하려면 어떻게 해야 합니까?
답변1
액세스는 프로세스의 파일 설명자 0에 액세스하지 않습니다./proc/PID/fd/0
PID, 액세스하는 파일PID파일 설명자 0에서 열립니다. 이는 미묘한 차이이지만 중요한 차이입니다. 파일 설명자는 프로세스와 파일 간의 연결입니다. 파일 설명자에 쓰면 파일이 열린 방식에 관계없이 파일에 기록됩니다.
일반 파일인 경우 해당 파일에 쓰면 파일이 수정됩니다. 데이터는 반드시 프로세스가 다음에 읽는 데이터는 아닙니다. 프로세스가 파일을 읽는 데 사용하는 파일 설명자에 연결된 위치에 따라 다릅니다. 프로세스가 열리면 다른 프로세스와 동일한 파일을 가져오지만 파일 위치는 독립적입니다./proc/PID/fd/0
/proc/PID/fd/0
파이프인 경우 파이프에 쓰면 데이터가 파이프의 버퍼에 추가됩니다. 이 경우 파이프에서 읽는 프로세스가 데이터를 읽습니다./proc/PID/fd/0
터미널인 경우 터미널에 쓰십시오./proc/PID/fd/0
산출터미널의 데이터. 터미널 파일은 양방향입니다. 파일에 쓰면 출력 데이터가 생성됩니다. 즉, 터미널은 텍스트를 표시합니다. 즉, 터미널에서 입력 데이터를 읽으면 사용자 입력이 전송됩니다.
Python은 터미널에서 읽고 쓸 수 있습니다. 을 실행하면 터미널 echo 'print "Hello"' > /proc/$(pidof python)/fd/0
에 쓰는 것입니다 . print "Hello"
터미널에 print "Hello"
메시지가 표시됩니다. Python 프로세스에는 아무것도 표시되지 않으며 여전히 입력을 기다리고 있습니다.
Python 프로세스에 입력을 제공하려면 터미널이 이를 수행하도록 해야 합니다. 바라보다크라식의 답변이를 수행하는 방법을 알아보십시오.
답변2
보내다이런 방식으로 쉘/인터프리터를 입력하면 문제가 발생하기 쉽고 안정적인 방식으로 작업하기가 어렵습니다.
올바른 방법은 소켓을 사용하는 것입니다. 그래서 소켓이 발명되었습니다. 명령줄에서 ncat
nc
또는 socat
Python 프로세스를 간단한 소켓에 바인딩하여 이 작업을 수행할 수 있습니다. 또는 포트에 바인딩하고 소켓에서 해석되는 명령을 수신하는 간단한 Python 애플리케이션을 작성하세요.
소켓은 로컬일 수 있으며 웹 인터페이스에 노출되지 않을 수 있습니다.
질문예, python
명령줄에서 시작하면 일반적으로 셸에 연결되고 터미널에 연결되며 실제로 볼 수 있습니다.
$ ls -al /proc/PID/fd
lrwxrwxrwx 1 USER GROUP 0 Aug 1 00:00 0 -> /dev/pty1
따라서 Python에 쓸 때 실제로는 단순한 파일이 아닌 커널 장치인 의사 터미널 stdin
에 쓰는 것입니다 . not을 pty
사용하므로 화면 에 출력이 표시되지만 생성된 프로세스로 전송되지는 않습니다( ).ioctl
read
write
python
시도 중인 내용을 복제하는 한 가지 방법은 fifo
또는 를 사용하는 것입니다 named pipe
.
# make pipe
$ mkfifo python_i.pipe
# start python interactive with pipe input
# Will print to pty output unless redirected
$ python -i < python_i.pipe &
# keep pipe open
$ sleep infinity > python_i.pipe &
# interact with the interpreter
$ echo "print \"hello\"" >> python_i.pipe
screen
입력을 사용할 수도 있습니다
# start screen
$ screen -dmS python python
# send command to input
$ screen -S python -X 'print \"hello\"'
# view output
$ screen -S python -x
답변3
무엇을 기반으로 구축할 것인가자일스는 말한다, 터미널에 연결된 프로세스의 표준 입력에 쓰려면 실제로 정보를 터미널로 보내야 합니다. 그러나 터미널은 입력과 출력의 형태로 작동하기 때문에 쓰기를 할 때 터미널은 "화면"이 아닌 그 안에서 실행 중인 프로세스에 쓰기를 원한다는 것을 알 수 있는 방법이 없습니다.
그러나 Linux에는 (터미널 I/O 제어 - 터미널 입력 시뮬레이션)이라는 ioctl 요청을 통해 사용자 입력을 시뮬레이션하는 비posix 방법이 있습니다. TIOCSTI
이를 통해 사용자가 문자를 입력한 것처럼 터미널에 문자를 보낼 수 있습니다.
기반으로이것답변: 다음을 통해 이 작업을 수행할 수 있습니다.
import fcntl, sys, termios
tty_path = sys.argv[1]
with open(tty_path, 'wb') as tty_fd:
for line in sys.stdin.buffer:
for byte in line:
fcntl.ioctl(tty_fd, termios.TIOCSTI, bytes([byte]))
일부 외부 리소스: