Shell

從命名管道獲取標準輸入

  • November 2, 2021

我想要做的是在終端視窗中執行 python 並從命名管道重定向它的標準輸入。然後我在另一個終端中寫入命名管道,並在 python 上執行該命令。

1號航站樓:

mkfifo p1
python < p1

2號航站樓:

echo -n "print \"Hello World\"" > p1

會發生什麼 - python 列印Hello World並退出。我想要做的是讓 python 執行以執行下一個命令。我如何在外殼中執行此操作?

你需要

  • 即使它的標準輸入不是終端,也以互動方式執行 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³ 手動打開和關閉 fd。

{
 echo ... >&3
 ...
 ...
} 3> p1

¹ fd 3 將由子程序繼承,並且(在 ksh93 中設置 close-on-exec 標誌除外)在這些程序中執行的其他命令(如果有)。

² 當然也適用於非內置命令。對於非內置函式,shell 不需要保存和恢復 fd 1,因為重定向只在被派生來執行命令的子程序中執行。對於外部命令,除了在自動執行此操作的 ksh93 中,您實際上可能想要關閉該 fd 3,以便它不會洩露給它們以及它們最終可能產生的後台程序(cmd >&3 3>&-)。

³ 請注意,在這種情況下,ksh93 不會在該 fd 3 上設置 close-on-exec 標誌。

引用自:https://unix.stackexchange.com/questions/72962