因此,您希望记录进程或子进程的stdout和stderr(单独),如果您没有记录任何内容,则输出与您在终端中看到的不同.
看起来很简单没有?不幸的是,看起来可能无法为这个问题编写一个通用的解决方案,这个解决方案适用于任何给定的流程......
管道重定向是一种分离stdout和stderr的方法,允许您单独记录它们.不幸的是,如果将stdout/err更改为管道,则进程可能会检测到管道不是tty(因为它没有宽度/高度,波特率等)并且可能会相应地更改其行为.为什么改变行为?好吧,一些开发人员利用终端的功能,如果您要写入文件,这些功能没有意义.例如,加载条通常要求将终端光标移回到行的开头,并使用新长度的条覆盖前一个加载条.颜色和字体粗细也可以显示在终端中,但是在平面ASCII文件中它们不能.如果您要将这样的程序的stdout直接写入文件,那么该输出将包含所有终端ANSI转义码,而不是正确格式化的输出.因此,开发人员在向stdout/err写入任何内容之前会执行某种"isatty"检查,因此如果该检查返回false,它可以为文件提供更简单的输出.
这里通常的解决方案是通过使用pty来欺骗这些程序,使管道实际上是ttys - 一个也具有宽度,高度等的双向管道.你将进程的所有输入/输出重定向到这个pty,这就是欺骗进程思考它与真实终端的对话(你可以直接将其记录到文件中).唯一的问题是,通过对stdout和stderr使用单个pty,我们现在无法再区分这两者.
所以你可能想为每个管道尝试不同的pty - 一个用于stdin,一个用于stdout,一个用于stderr.虽然这将在50%的时间内工作,但不幸的是,许多进程会执行额外的重定向检查,以确保stdout和stderr(/ dev/tty000x)的输出路径相同.如果它们不是,则必须有重定向,因此它们会给你相同的行为,就好像你没有pty管道stderr和stdout一样.
您可能认为这种过度检查重定向并不常见,但不幸的是它实际上非常普遍,因为许多程序重用其他代码进行检查,就像在OSX中找到的这些代码一样:
我认为找到解决方案的最佳方式是挑战.如果任何人都可以运行以下脚本(理想情况下通过Python,但此时我将采取任何措施),以便单独记录stdout和stderr,并且你设法欺骗它认为它是通过tty执行的,你解决了问题:)
#!/usr/bin/python
import os
import sys
if sys.stdout.isatty() and sys.stderr.isatty() and os.ttyname(sys.stdout.fileno()) == os.ttyname(sys.stderr.fileno()):
sys.stdout.write("This is a")
sys.stderr.write("real tty :)")
else:
sys.stdout.write("You cant fool me!")
sys.stdout.flush()
sys.stderr.flush()
Run Code Online (Sandbox Code Playgroud)
请注意,解决方案应该适用于任何进程,而不仅仅是此代码.覆盖sys/os模块并使用LD_PRELOAD是击败挑战的非常有趣的方法,但它们并没有解决问题的核心:)
我试图在Python中找到一种方法来运行其他程序:
这是我到目前为止所得到的...方法1:
def method1(command):
## subprocess.communicate() will give us the stdout and stderr sepurately,
## but we will have to wait until the end of command execution to print anything.
## This means if the child process hangs, we will never know....
proc=subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable='/bin/bash')
stdout, stderr = proc.communicate() # record both, but no way to print stdout/stderr in real-time
print ' ######### REAL-TIME ######### '
######## Not Possible
print ' ########## RESULTS ########## …
Run Code Online (Sandbox Code Playgroud) 在这次新的更新中,Neo4j的核心发生了很多变化,这真的令人兴奋.
之前的Neo4j版本缺少的一件事是让用户使用网络界面的能力.好吧,他们可以使用它,如果你不介意他们能删除所有内容,或者你不介意让整个数据库只读给所有人,包括你自己.
现在3.x中有解决方法吗?我发现你已经对网络界面做了一些非常棒的改进(在所有会议和YouTube视频中似乎已经在雷达下飞行) - 但是我不能让我的用户使用任何这个真棒,因为他们可能match (n) detach delete (n)
.
谢谢!:)
我想向数组添加一个值(如果尚未存在)。到目前为止,我的代码看起来像这样(请注意r.names和{name}都是数组和[1] + [2] = [1,2]
):
MERGE (r:resource {hash:{hash}})
ON CREATE SET r.names = {name}
ON MATCH SET r.names = r.names + {name}
Run Code Online (Sandbox Code Playgroud)
但是显然,如果{name}
已经在r.names
,它将再次被添加。{name}
仅在r.names
尚未包含的情况下如何添加?
现在许多浏览器都支持使用HTML5的FileReader读取本地文件,这为超出"数据库前端"的网站打开了大门,这些脚本可以对本地数据执行一些有用的操作,而无需先将其发送到服务器.
在上传前预处理图像和视频,FileReader的一个大应用是将数据从某种磁盘表(CSV,TSV等)加载到浏览器中进行操作 - 可能用于D3.js中的绘图或分析或在WebGL中创建景观.
问题是,StackOverflow和其他站点上的大多数示例都使用FileReader的.readAsText()属性,该属性在返回结果之前将整个文件读入RAM.
要在不将数据加载到RAM的情况下读取文件,需要使用.readAsArrayBuffer(),这个SO帖子是最接近我能得到一个好答案的:
然而,这个特定问题有点过于具体,而且说实话,我可以尝试好几天让解决方案更加通用,然后空手而归,因为我不明白块大小的重要性或为什么Uint8Array是用过的.使用用户可定义的行分隔符逐行读取文件的更一般问题的解决方案(理想情况下使用.split(),因为它也接受正则表达式),然后按行执行某些操作(例如将其打印到console.log)是理想的.
neo4j ×2
pty ×2
python ×2
tty ×2
cypher ×1
filereader ×1
html5 ×1
javascript ×1
linux ×1
pexpect ×1
subprocess ×1
unix ×1