【问题标题】:Python's subprocess.Popen() causes strange indentation of outputPython 的 subprocess.Popen() 导致输出的奇怪缩进
【发布时间】:2021-10-26 16:56:24
【问题描述】:

我有几行代码从 gpsmon gpsd 命令行实用程序(作为子进程生成)收集 NMEA 语句,并从外部无线电收集一些内部 GPS 位置数据。我不希望用户在运行代码时在终端中看到 gpsmon 输出,所以我将其重定向 /dev/null 如下:

cmd = "gpsmon -n 10.3.1.254:2947 -l output.txt"
gpsmonitor_cmd = subprocess.Popen(cmd.split(),stdout = subprocess.DEVNULL)

按照这段代码,我从一个外部文件执行一个 C 二进制可执行文件,这也是一个子进程,以及它的输出重定向到 dev null。不过我很困惑,因为这个二进制文件的输出仍然出现在终端中。有问题的子流程调用:

process = subprocess.Popen(createBinaryCommand,stdout=subprocess.DEVNULL)   

当我运行代码时,二进制命令的输出如下所示:

Duration = 180.0 [sec]
                                                                    01   29.2   1.0  27629867.8   5.0
                                                                                                     02  279.0  22.1  29485316.6   3.1
                                                                                                                                      03   16.2  16.5  29757080.4   3.5
                                                                                                                                                                       04   58.0  48.8  30795329.9   1.9
                  05  222.1  32.8  28015547.1   2.5
                                                   06  307.9  21.2  30581471.1   3.2
                                                                                    07  209.8  81.7  31316191.8   1.5
                                                                                                                     08   75.1  43.6  29817969.2   2.1
                                                                                                                                                      09   59.0  75.3  32009836.6   1.5

非常奇怪的缩进。而当我运行没有代码sn-p的代码时:

cmd = "gpsmon -n 10.3.1.254:2947 -l output.txt"
gpsmonitor_cmd = subprocess.Popen(cmd.split(),stdout = subprocess.DEVNULL)

现在 C 二进制命令的输出看起来又正常了:

Duration = 180.0 [sec]
01   29.2   1.0  27629867.8   5.0
02  279.0  22.1  29485316.6   3.1
03   16.2  16.5  29757080.4   3.5
04   58.0  48.8  30795329.9   1.9
05  222.1  32.8  28015547.1   2.5
06  307.9  21.2  30581471.1   3.2
07  209.8  81.7  31316191.8   1.5
08   75.1  43.6  29817969.2   2.1
09   59.0  75.3  32009836.6   1.5
13  247.2  19.4  27856171.3   3.3
14  336.7  38.8  32242259.8   2.2
16  138.9  38.3  27297398.5   2.3
17  349.8   8.4  30063728.5   4.2
18  173.1  12.2  24256737.2   3.9
20  249.7  50.1  30679658.2   1.9
21   46.7   1.5  27617657.0   4.9

我假设这与产生的背靠背子进程及其输出重定向到 dev null 有关,但我无法弄清楚如何使输出看起来再次正常格式化。

【问题讨论】:

  • 并非所有输出都进入标准输出。有些东西被写入标准错误,有些东西被写入终端。要知道如何重定向您想要重定向的内容,您需要知道输出的每个组件是如何编写的。
  • 也就是说,当您说“代码 sn-p”时,您指的是究竟是什么?
  • (另外,你把这个标记为“linux”——但出于好奇,它是 真的 Linux,还是微软在 Windows 中的 Linux 兼容层?前者是可能,但意味着一些非常不寻常的终端设置)。
  • 与您的问题无关,顺便说一句,但cmd.split() 是不好的做法。最好将你的命令显式地写成一个列表 (cmd = ['gpsmon', '-n', '10.3.1.254:2947', '-l', 'output.txt'])——这样当你的输出文件名包含空格并且split() 决定将它分成多个参数时,你就不会搞砸了。
  • 我明白了,谢谢。这是我正在操作的 VS Code 终端。代码 sn-p 我的意思是执行 C 可执行文件的子进程调用,而不事先调用 gpsmon 的子进程

标签: python linux subprocess


【解决方案1】:

这种缩进意味着您只有换行符而没有回车,并且您正在渲染到一个配置为以 Windows 方式运行的终端。

在 UNIXy 系统上,换行符也将光标发送到左侧。在 Windowsy 系统上,它将光标向下移动,并且您需要回车将光标移动到左侧。


要告诉 UNIX 终端将换行符视为 回车符和换行符,您可以使用:

stty onlcr

【讨论】:

  • 所以这可能是由于此输出来自 VS Code 终端的事实造成的?
  • 我不希望 Microsoft 产品能够做到任何事情正确,所以当然。
  • 奇怪,我在普通的 Ubuntu 终端中运行它,但输出的格式仍然很奇怪。我可以通过在我打印的每个字符串的末尾添加一个回车来解决这个问题,但是为什么这是由子进程的产生引起的?
  • 取决于程序中的其他内容。是使用 curses 库,还是使用 TTY 设置做其他事情?
  • @ElliottGoldstein,TZ=UTC date --date=@1629938529.554690635 输出Thu 26 Aug 2021 12:42:09 AM UTC——这听起来对我来说是正确的。你觉得这个输出有什么问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
相关资源
最近更新 更多