내가 원하는 것은 터미널 창에서 Python을 실행하고 명명된 파이프에서 표준 입력을 리디렉션하는 것입니다. 그런 다음 다른 터미널의 명명된 파이프에 쓰고 Python에서 명령을 실행합니다.
터미널 1:
mkfifo p1
python < p1
NO2. 터미널:
echo -n "print \"Hello World\"" > p1
무슨 일이 일어나는가 - 파이썬이 인쇄 Hello World
하고 종료됩니다. 내가 원하는 것은 Python을 계속 실행하여 다음 명령을 받아들이는 것입니다. 쉘에서 이 작업을 어떻게 수행합니까?
답변1
당신은해야합니다
- 표준 입력이 터미널이 아니더라도 Python을 대화형으로 실행하려면 다음을 사용하십시오.
python -i
- 파이프의 쓰기 끝을 열어 두십시오. 그렇지 않으면 Python이 EOF를 감지하고 종료됩니다.
그래서:
python -i < p1
그리고 다른 곳에서는:
# open p1 on fd 3 of the shell process¹ for instance so stdout is
# left untouched in case you still want to write messages there.
exec 3> p1
# write something on fd 3. For instance with ksh/zsh's print
# builtin:
print -u3 '1j*1j'
# or for commands such as echo that can only print things
# on stdout (fd 1), duplicate that fd 3 to their fd 1:
echo '1j*1j' >&3 # short for 1>&3
# after echo (a builtin² in virtually all shells) returns, fd 1
# is restored to what it was before, but fd 3 remains open on
# the writing end of the pipe, so python still doesn't see EOF
# there.
echo normal message on stdout
echo 1+1 >&3 # more instructions for python
...
# and when done, close that file descriptor so python sees the EOF
# (assuming that fd 3 was the only file descriptor left open on
# the writing end of that pipe):
exec 3>&-
exec
특히 스크립트에서는 3를 사용하여 fd를 수동으로 열고 닫는 대신 전체 명령 그룹을 리디렉션할 수 있습니다 .
{
echo ... >&3
...
...
} 3> p1
¹ fd 3은 하위 프로세스 및 (ksh93에 close-on-exec 플래그가 설정된 경우 제외) 해당 프로세스에서 실행되는 다른 명령(있는 경우)에 의해 상속됩니다.
² 물론 이는 내장되지 않은 명령에도 적용됩니다. 내장되지 않은 프로그램의 경우 명령을 실행하기 위해 분기된 하위 프로세스에서만 리디렉션이 수행되므로 쉘은 fd 1을 저장하고 복원할 필요가 없습니다. 이 작업을 자동으로 수행하는 ksh93 이외의 외부 명령의 경우 실제로 fd 3을 꺼서 누출되지 않고 결국 백그라운드 프로세스가 생성될 수 있습니다( cmd >&3 3>&-
).
³ 이 경우 ksh93은 fd 3에 close-on-exec 플래그를 설정하지 않습니다.
답변2
이를 사용하여 tail -f
쓰기 후에 fifo를 열어 둘 수 있습니다.echo
tail -n1 -f p1 | python
이것이 작동하는 이유
python
에서 읽기 p1
파일의 끝에 도달하면 읽기가 중지됩니다. 이는 파일이 명명된 파이프인 경우에도 파일 읽기에 대한 일반적인 동작입니다. (follow) 플래그 tail
가 있는 파일은 -f
파일 끝에 도달한 후에도 계속 읽습니다.
답변3
전체 프로그램을 한 번에 보내야 합니다.
run을 호출하면 python < p1
쉘은 Python을 호출하기 전에 입력을 기다립니다. 즉, Python은 실행을 시작하지도 않습니다.별말씀을요전체 데이터 스트림이 셸에서 읽힐 때까지 전체가 python
.
대신 실행하더라도 python -u p1
(즉, 버퍼링되지 않고 file 에서 읽는 경우 p1
) python
파일을 실행하기 전에 전체 파일을 읽으려는 시도가 이루어집니다.
이 실험을 시도해 보세요.
터미널 1:
mkfifo p1
python < p1
NO2. 터미널:
cat > p1
print "Hello World"
print "Hello World"
여러 줄을 보낼 수 있지만 1학기의 Python은 아무 작업도 수행하지 않는다는 것을 알 수 있습니다. 이제 ctrl+를 누르세요 D. 전체 프로그램이 즉시 실행됩니다.
요약하자면, Python이 파이프에서 데이터를 읽도록 하려면 전체 프로그램을 보내야 합니다. 이런 식으로 Python을 대화식으로 사용할 수 없습니다.
답변4
또 다른 해결책이 있습니다. 터미널 1:
alec@MacBook-Air ~/hello $ rm -f my.fifo; mkfifo my.fifo
alec@MacBook-Air ~/hello $ cat my.fifo
command1
command2
...
alec@MacBook-Air ~/hello $
NO2. 터미널:
alec@MacBook-Air ~/hello $ cat > my.fifo
command1
command2
...
alec@MacBook-Air ~/hello $
터미널 2에 명령을 입력하고 터미널 1에 해당 명령이 나타나는지 확인합니다. 예를 들어 터미널 1의 출력을 다른 프로세스로 파이프할 수 있습니다 cat my.fifo | node ...
. 완료되면 stdin
Ctrl-D를 사용하여 터미널 2를 닫습니다. my.fifo
그러면 닫히고 cat
터미널 1의 명령이 종료됩니다.