在Clojure计划中,您如何从标准输出 读取 ?我想这样做,或将标准输出传递给我创建的输入流。 Clojure中的标准输出是 java.io.PrintWriter 。
我有一份Samza工作,由Clojure计划开始。还有一个我可以远程连接的nrepl服务器。在连接之后,我需要能够进入和尾部标准输出(作业写出他们的输出)。
1)根据此SO question,with-out-str
(请参阅here)让我们暂时将*out*
绑定到 java .io.StringWriter ),以便您执行的代码写入字符串。但这不允许我利用现有的*out*
。
2)如果你看一下 clojure.java.shell (参见here),它会获得JVM的Runtime和exec的进程。从该过程中,您可以获得其标准输出流。但同样,这不是我正在寻找的默认标准(*out*
)。
3)这SO question接近我正在尝试做的事情。但同样,我正在连接到现有流程,并希望减少其标准输出。
这在Clojure中是否可行(见here)?有人解决了这个吗?
答案 0 :(得分:1)
进程输出不是发布订阅模型,因此当进程将字符放入其输出缓冲区时,实际上只有一个进程将其从该缓冲区中拉出。如果你有一个由shell启动的程序,那么shell会在读取它的输出并将其写入终端(或者读取并忽略它)时进行处理。如果您在启动它的过程之后附加了您的进程并开始尝试获取数据,那么您很可能无法获得任何内容,因为父进程将首先获取它。我刚从两个终端尝试过这个:
1号航站楼:
cat
2号航站楼:
ps -ef | grep cat
tail -f /proc/24547/fd/2
1号航站楼:
hello
2号航站楼: <没什么>
字符串"你好"打印到终端1,启动它的过程。
如果没有人阅读输出,那么很有诱惑力,那么它将会让我获得"。虽然听起来不错,但它遇到的问题是这些是固定大小的缓冲区,因此只要输出缓冲区已满,尝试写入它的进程就会阻塞(完全无法运行),直到有人读取输出以解除阻塞它。
一般的解决方案是将稍后想要尾随的进程传递给tee
命令,该命令将输出写入文件,将其传递给读取它的任何内容。
command-to-watch arg1 arg2 | tee logfile.potentially-huge
虽然如果你走这条路线,你应该在磁盘填充之前旋转日志文件。确保使用此命令
清空日志文件echo > logfile.potentially-huge
或使用您的程序对文件进行truncate
调用。简单地删除文件将从日志目录中删除它的名称而不删除它,它将无声地继续增加占用磁盘空间,新文件将永远不会输出。
这就是我们构建日志库的原因,例如log4j(在90年代)和syslog(在80年代)。
如果你仍然想要对此疯狂,请转向tmux,它可以做任何事情,并改变人们处理文本的方式。一目了然,你应该改变其他过程创建输出的方式,以便更容易获得。