我在考虑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] 删除。
我来说两句