【问题标题】:python subprocess call with pipe, shell=True not working使用管道的python子进程调用,shell = True不工作
【发布时间】:2014-07-30 18:57:56
【问题描述】:

我正在尝试从我的 python 脚本中执行子进程调用,将文件中的回车符和换行符替换为空格,然后将其保存回文件本身。我已经验证这可行:

cat file.txt | tr '\r\n' ' ' > file.txt

因此尝试在 python 中做同样的事情。我的电话是这样的:

formatCommand = "cat " + fileName + " | tr '\\r\\n' ' ' > " + fileName
print(formatCommand)    #this showed me that the command above is being passed
subprocess.call(formatCommand, shell=True)

文件没有像我期望的那样成功删除换行符,而是最终为空。

我曾就类似问题咨询过this post,但解决方案是使用我已经使用的 shell=True,并且重定向使 Popen 更加复杂。此外,我不明白为什么它不适用于 shell=True。

【问题讨论】:

  • 你为什么首先使用这个?您在 shell 管道中尝试做的事情在 Python 中同样简单……
  • 当我直接从 bash shell 执行此操作时,这实际上会为我生成一个空文件。
  • 你说得对……我完全可以打一个替换电话。但是,现在我只是好奇为什么它不起作用,所以我会继续提问。
  • @taronish4:dano 是对的。问题是您的 tr 调用是错误的,无论是从 shell 还是从 Python;与你使用subprocess无关。
  • 另外,作为旁注:您应该考虑使用str.format% 而不是串联,尤其是当您到处都有这样的引号时。原始字符串也可能有所帮助。例如,这不是更具可读性(更明显正确)吗? r"cat {} | tr '\r\n' ' ' > {}".format(fileName, fileName)

标签: python bash shell subprocess


【解决方案1】:

您的 shell 命令中存在竞争条件。管道中的第一个命令是cat file.txt,第二个命令是tr '\r\n' ' ' > file.txt。两个命令同时并行运行。第一个命令从file.txt 读取,第二个命令截断file.txt 然后写入它。如果截断发生在第一个命令从文件中读取之前,那么文件将为空。

【讨论】:

  • 注意:重定向 > file.txt 是由 shell before tr 命令甚至运行完成的。我不知道cat 是否会在这里看到非空的file.txt
  • 整个tr 命令(包括重定向)与cat 命令并行完成。所以cat 命令有可能输出一些东西,即使文件小于管道缓冲区,在tr 重定向发生之前完成。例如echo test > foo.txt; cat foo.txt | tr t T $(sleep 1) > foo.txt; cat foo.txt 可能会打印TesT
猜你喜欢
  • 2014-10-17
  • 2017-02-18
  • 2017-02-09
  • 2017-03-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 2013-06-19
  • 2023-03-20
相关资源
最近更新 更多