将进程的标准输出重定向到其自己的标准输入

伊扎克·范·东根

我在考虑Haskell中的自引用列表-例如,您可能具有以下脚本fibonacci.hs

#!/usr/bin/env runghc

fibs :: [Integer]
fibs = 1:1:(zipWith (+) fibs $ tail fibs)

main :: IO ()
main = do
    mapM_ print $ take 50 fibs

因为文件名扩展名是如此相似(xp相距遥远),所以我认为在shell脚本中必须有类似的东西,将进程的stdout附加到其自己的stdin。我所能想到的是fibonacci.sh

#!/usr/bin/env sh

{ echo 1; echo 1; } > fibonaccis

tail -f fibonaccis |
    python3 -c 'if True: # dummy to fix indentation
        b = int(input())
        for _ in range(48):
            a, b = b, int(input())
            print(a + b)' >> fibonaccis

cat fibonaccis

但是,我发现必须将所有内容都写入文件有点不满意。显然,这是一个玩具示例,具有更优化的已知算法,但是如果我只想生成第1000个斐波那契数,该怎么办?这样就不必保留Python脚本在消耗掉它们之后编写的stdout行。

那么,有没有更好的方法使用文件来执行此操作,或者理想情况下,仅使用重定向就可以在没有文件的情况下执行此操作?还是这无疑是一个可怕的主意?可以使用命名管道完成此操作吗?

无论我尝试搜索什么,都想出了将一个流程的stdout附加到另一个流程的stdin的方法,这个我已经很熟悉了。双向管道似乎也不是我想要的。

我知道一个事实,即需要采取一些谨慎措施,以确保该过程不会过于宽松地缓冲其I / O。

库萨兰达

正如Mathew Gunther在他的答案中指出的那样,可以使用命名管道(“ fifo”)来获取脚本以读取其自身的输出。

#!/bin/bash

# Create pipe and arrange to remove it when done.
mkfifo mypipe
trap 'rm -f mypipe' EXIT

# Just to start off the sequence. Note that this
# needs to be a background process to avoid
# blocking, as there is nobody reading from the
# pipe yet.
echo '0 1' >mypipe &

# Numbers to produce. Note that the produced numbers
# will overflow at n=93.
n=48

# Read the two numbers from the pipe and put the
# last of these back together with the next number
# in the sequence:
while [ "$n" -gt 0 ] && read a b; do
        c=$(( a + b ))
        printf '%d %d\n' "$b" "$c" >&3

        # Also print the "b" number as output.
        printf '%d\n' "$b"

        n=$(( n - 1 ))
done <mypipe 3>mypipe

我使用一个额外的文件描述符在循环中写入管道,只是为了能够像往常一样将生成的数字序列输出到标准输出流(并且不会超载此目的标准错误流)。

如果你想用这种方法使用Python代码,你可能会做得

#!/bin/bash

mkfifo mypipe
trap 'rm -f mypipe' EXIT

printf '%d\n%d\n' 0 1 >mypipe &

python3 -c 'if True: # dummy to fix indentation
    b = int(input())
    for _ in range(48):
        a, b = b, int(input())
        print(a + b)' <mypipe >mypipe

您会注意到,此脚本没有任何输出,这是因为我们将Python代码的输出用作其自己的输入。为了在终端中获得一些输出,我们将在上面的shell循环中执行类似的操作(写入标准输出以外的内容):

#!/bin/bash

mkfifo mypipe
trap 'rm -f mypipe' EXIT

printf '%d\n%d\n' 0 1 >mypipe &

python3 -c '
import sys
b = int(input())
for _ in range(48):
    a, b = b, int(input())
    print(a + b)
    print(b, file=sys.stderr)' <mypipe >mypipe

在这里,我(绝对)使用标准错误流向终端中的用户提供实际结果。如果像我在第一个变体中执行shell循环一样(将输出通过新的文件描述符处理到管道),这样做会变得更加整洁,但是我对Python的知识却严重缺乏。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将标准输入重定向到标准输出

将标准输出重定向到文件

将错误重定向到标准输出

将标准输入重定向到标准输入

将标准输入重定向到文件

如何将标准输出重定向到标准错误

重定向标准输入和标准输出?

让子进程将printf正确地重定向到标准输出

将标准输出重定向到标准错误,但也保留在标准输出中

将输出重定向到标准输出而不是文件

Windows cmd输出重定向到标准输入(>&0)

C - 将标准输入/输出重定向到单个双向文件描述符

Python。将标准输出重定向到套接字

如何将Jmeter标准输出重定向到文件

Bash将标准输出重定向到功能

将标准输出重定向到 Jinja 变量

将标准输入(读取主机)重定向到Powershell脚本

将脚本标准输入重定向到后台文件

在 VBS 中重定向到标准输出

在 bash 脚本中重定向标准输入和标准输出

重定向标准输出和标准输入-Java

.NET应用程序如何重定向其自己的标准输入流?

将一个命令的标准错误重定向到另一命令的标准输入

将tty重定向到标准

使用带有标准输入和标准输出重定向的 2 进程管道时如何避免标准输入上的重复输入

将可读对象标准输出进程重定向到节点中的文件

如何将命令的标准输出和标准输入都重定向到一行中的文本文件?

重定向当前正在运行的 python 进程的标准输出

为什么`>`重定向不能捕获替代进程的标准输出?