小编J.J*_*J.J的帖子

你可以愚弄isatty并分别记录stdout和stderr吗?

问题

因此,您希望记录进程或子进程的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中找到的这些代码一样:

http://src.gnu-darwin.org/src/bin/stty/util.c

挑战

我认为找到解决方案的最佳方式是挑战.如果任何人都可以运行以下脚本(理想情况下通过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 unix linux tty pty

35
推荐指数
2
解决办法
2013
查看次数

运行命令并像在终端中一样近乎实时地获取它的stdout,stderr

我试图在Python中找到一种方法来运行其他程序:

  1. 正在运行的程序的stdout和stderr可以单独记录.
  2. 正在运行的程序的stdout和stderr可以近乎实时地查看,这样如果子进程挂起,用户就可以看到.(即我们不会在将stdout/stderr打印到用户之前等待执行完成)
  3. 奖励标准:正在运行的程序不知道它是通过python运行的,因此不会做意想不到的事情(比如chunk它的输出而不是实时打印,或退出因为它需要终端查看其输出) .这个小标准几乎意味着我们需要使用我认为的pty.

这是我到目前为止所得到的...方法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)

python subprocess tty pexpect pty

15
推荐指数
1
解决办法
3702
查看次数

对Neo4j 3.0中的读写数据库进行只读Web访问

在这次新的更新中,Neo4j的核心发生了很多变化,这真的令人兴奋.

之前的Neo4j版本缺少的一件事是让用户使用网络界面的能力.好吧,他们可以使用它,如果你不介意他们能删除所有内容,或者你不介意让整个数据库只读给所有人,包括你自己.

现在3.x中有解决方法吗?我发现你已经对网络界面做了一些非常棒的改进(在所有会议和YouTube视频中似乎已经在雷达下飞行) - 但是我不能让我的用户使用任何这个真棒,因为他们可能match (n) detach delete (n).

谢谢!:)

neo4j

11
推荐指数
1
解决办法
534
查看次数

向数组中添加值(如果还不存在)

我想向数组添加一个值(如果尚未存在)。到目前为止,我的代码看起来像这样(请注意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尚未包含的情况下如何添加?

neo4j cypher

4
推荐指数
1
解决办法
890
查看次数

逐行读取FileReader对象,而不将整个文件加载到RAM中

现在许多浏览器都支持使用HTML5的FileReader读取本地文件,这为超出"数据库前端"的网站打开了大门,这些脚本可以对本地数据执行一些有用的操作,而无需先将其发送到服务器.

在上传前预处理图像和视频,FileReader的一个大应用是将数据从某种磁盘表(CSV,TSV等)加载到浏览器中进行操作 - 可能用于D3.js中的绘图或分析或在WebGL中创建景观.

问题是,StackOverflow和其他站点上的大多数示例都使用FileReader的.readAsText()属性,该属性在返回结果之前将整个文件读入RAM.

javascript:如何逐行解析FileReader对象

要在不将数据加载到RAM的情况下读取文件,需要使用.readAsArrayBuffer(),这个SO帖子是最接近我能得到一个好答案的:

大文件上的filereader api

然而,这个特定问题有点过于具体,而且说实话,我可以尝试好几天让解决方案更加通用,然后空手而归,因为我不明白块大小的重要性或为什么Uint8Array是用过的.使用用户可定义的行分隔符逐行读取文件的更一般问题的解决方案(理想情况下使用.split(),因为它也接受正则表达式),然后按行执行某些操作(例如将其打印到console.log)是理想的.

javascript html5 filereader

1
推荐指数
1
解决办法
1462
查看次数

标签 统计

neo4j ×2

pty ×2

python ×2

tty ×2

cypher ×1

filereader ×1

html5 ×1

javascript ×1

linux ×1

pexpect ×1

subprocess ×1

unix ×1