我在考虑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行。
那么,是否有更好的方法来使用文件来完成这个任务,或者理想的情况下,只使用重定向就可以在没有文件的情况下做到这一点?或者这是一个非常糟糕的主意?也许用一个命名的管道就能做到这一点吗?
无论我试图搜索什么,都会想出一些方法将一个进程的标准附加到另一个进程的标准上,而我对此已经很熟悉了。双向管道似乎也不是我想要的。
我意识到,需要采取一些谨慎措施,以确保该过程不会过于宽松地缓冲其I/O。
发布于 2019-06-30 08:39:39
作为马修斯·冈瑟在他的回答中指出,命名管道("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我使用了一个额外的文件描述符来写入循环中的管道,这样就可以正常地将生成的数字序列输出到标准输出流(并且不会重载此目的的标准错误流)。
如果您想在此方法中使用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您会注意到,您没有从这个脚本中获得任何输出,这是因为我们使用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这里,我(ab-)使用标准错误流向终端中的用户提供实际结果。如果像第一个变体中的shell循环那样(通过一个新的文件描述符处理管道的输出),它会更整洁,但是我对Python的知识严重缺乏。
https://unix.stackexchange.com/questions/527501
复制相似问题