如何实现$ RANDOM之类的“生成器”?

$RANDOM每次访问时,特殊变量都有一个新值。在这方面,它使人联想到某些语言中的“生成器”对象。

有没有办法实现这样的事情zsh

我尝试使用命名管道进行此操作,但是我没有找到一种在不终止“ generator”进程的情况下以受控方式从fifo提取项目的方法。例如:

% mkfifo /tmp/ints
% (index=0
   while ( true )
   do
       echo $index
       index=$(( index + 1 ))
   done) > /tmp/ints &
[1] 16309
% head -1 /tmp/ints
0
[1]  + broken pipe  ( index=0 ; while ( true; ); do; echo $index; index=$(( ...

还有其他方法可以在zsh中实现这种生成器类型的对象吗?


编辑:这不起作用:

#!/usr/bin/env zsh

FIFO=/tmp/fifo-$$
mkfifo $FIFO
INDEX=0
while true; do echo $(( ++INDEX )) > $FIFO; done &
cat $FIFO

如果将以上内容放入脚本中并运行,则输出很少会出现预期的单行

1

通常,它通常由几个整数组成;例如

1
2
3
4
5

生产的数量从一次运行到下一次运行有所不同。

编辑2:正如jimmij所指出的,更改echo/bin/echo可以解决问题。

斯蒂芬·查泽拉斯(Stephane Chazelas)

ksh93有一些通常用于这类事情的学科。使用zsh,您可以劫持动态命名目录功能

例如定义:

zsh_directory_name() {
  case $1 in
    (n)
      case $2 in
        (incr) reply=($((++incr)))
      esac
  esac
}

然后,您可以使用每次~[incr]将其递增$incr

$ echo ~[incr]
1
$ echo ~[incr] ~[incr]
2 3

您的方法失败了,因为in中head -1 /tmp/ints,head打开fifo,读取一个完整的缓冲区,打印一行,然后将其关闭一旦关闭,书写端就会看到折断的管道。

相反,您可以执行以下操作:

$ fifo=~/.generators/incr
$ (umask  077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ seq infinity > $fifo &
$ exec 3< $fifo
$ IFS= read -rneu3
1
$ IFS= read -rneu3
2

在那里,我们使读取端在fd 3上保持打开状态,并一次read读取一个字节,而不是一个完整的缓冲区,以确保只读取一行(直到换行符)。

或者,您可以执行以下操作:

$ fifo=~/.generators/incr
$ (umask  077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ while true; do echo $((++incr)) > $fifo; done &
$ cat $fifo
1
$ cat $fifo
2

那个时候,我们为每个值实例化一个管道。这样就可以返回包含任意行数的数据。

但是,在那种情况下,一旦cat打开fifo,echo循环echo就不会被阻塞,因此cat读取内容并关闭管道时会导致运行更多(导致下一个echo实例化新管道)。

解决方法可能是增加一些延迟,例如通过运行echo@jimmij建议的外部操作或添加一些延迟sleep,但这仍然不是很可靠,或者您可以在每个之后重新创建命名管道echo

while 
  mkfifo $fifo &&
  echo $((++incr)) > $fifo &&
  rm -f $fifo
do : nothing
done &

仍然留下不存在管道的短窗口(在unlink()done byrmmknod()done by之间mkfifo)导致cat失败,以及非常短的窗口,其中管道已实例化但没有进程将再次向其写入(在write()and之间)close()通过完成echo),导致cat返回什么,短窗已命名管道仍然存在,但任何事都不能打开它写(的close()所做echounlink()将完成的rm),其中cat将挂起。

您可以通过执行以下操作来删除其中一些窗口

fifo=~/.generators/incr
(
  umask  077
  mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo &&
  while
    mkfifo $fifo.new &&
    {
      mv $fifo.new $fifo &&
      echo $((++incr))
    } > $fifo
  do : nothing
  done
) &

这样,唯一的问题是,如果您同时运行多只猫(它们在我们的写循环准备好打开以进行写操作之前都打开了fifo),在这种情况下,它们将共享echo输出。

我也建议不要在世界可写目录中创建固定名称,世界可读的fifos(或与此有关的任何文件),例如,/tmp除非它是公开给系统上所有用户的服务。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何实现简单的ID生成器?

来自分类Dev

如何在 Rails 中实现条码生成器

来自分类Dev

如何嵌套生成器

来自分类Dev

如何在生成器上使用random.shuffle()?蟒蛇

来自分类Dev

C ++ 11类<random>的发行版如何转换基础生成器?

来自分类Dev

如何在生成器上使用random.shuffle()?Python

来自分类Dev

Java-实现随机向量生成器,该生成器生成正态分布的数字

来自分类Dev

MyBatis生成器-生成映射器实现

来自分类Dev

如何发布yomen生成器?

来自分类Dev

如何获得模型的空生成器?

来自分类Dev

如何从生成器读取tarfile?

来自分类Dev

Java随机生成器如何工作?

来自分类Dev

Python递归生成器如何工作?

来自分类Dev

如何提高数据生成器的效率?

来自分类Dev

如何正确锁定异步生成器?

来自分类Dev

如何扩展laravels查询生成器?

来自分类Dev

如何获得模型的空生成器?

来自分类Dev

如何删除???? 来自dompdf生成器

来自分类Dev

如何创建平台生成器?

来自分类Dev

如何调试 .zip 生成器算法?

来自分类Dev

如何使用生成器填充列?

来自分类Dev

如何在Scheme(Racket或ChezScheme)中实现Python样式的生成器?

来自分类Dev

线性同余生成器LCG如何在c中实现模数2 ^ 64

来自分类Dev

Java-如何在Netbeans gui生成器中将代码实现到GUI中?

来自分类Dev

如何在RWeka中实现备份令牌生成器开关?

来自分类Dev

如何在Lucene / Solr中正确实现我的自定义令牌生成器?

来自分类Dev

如何在这个质数生成器中实现一系列数字?

来自分类Dev

如何为一种热编码实现生成器功能

来自分类Dev

在Python中使用生成器函数实现长除法

Related 相关文章

热门标签

归档