【问题标题】:subprocess.call using cygwin instead of cmd on Windowssubprocess.call 在 Windows 上使用 cygwin 而不是 cmd
【发布时间】:2015-09-22 03:35:31
【问题描述】:

我在 Windows 7 上编程,在我的一个 Python 项目中我需要调用 bedtools,它仅适用于 Windows 上的 Cygwin。我是 Cygwin 的新手,安装了默认版本 + bedtools 所需的一切,然后使用 Cygwin 通过使用 make 来安装 bedtools,如 installation instructions 中所述。

$ tar -zxvf BEDTools.tar.gz
$ cd BEDTools-<version>
$ make

当我使用 Cygwin 终端像下面这样手动调用它时,它可以正常工作并且输出文件包含正确的结果。

bedtools_exe_path intersect -a gene_bed_file -b snp_bed_file -wa -wb > output_file

但是当我在我的程序中使用subprocess.call 时,它似乎使用的是 Windows cmd 而不是 Cygwin,这不起作用。

arguments = [bedtools_exe_path, 'intersect', '-a', gene_bed_file, '-b',
             snp_bed_file, '-wa', '-wb', '>', output_file]
return_code = suprocess.call(arguments)

导致没有输出文件并且返回码为3221225781


arguments = [bedtools_exe_path, 'intersect', '-a', gene_bed_file, '-b',
             snp_bed_file, '-wa', '-wb', '>', output_file]
return_code = suprocess.call(arguments, shell=True)

导致一个空的输出文件和3221225781的返回码。


cygwin_bash_path = 'D:/Cygwin/bin/bash.exe'
arguments = [cygwin_bash_path, bedtools_exe_path, 'intersect', '-a', gene_bed_file, '-b',
             snp_bed_file, '-wa', '-wb', '>', output_file]
return_code = suprocess.call(arguments)

导致没有输出文件,返回码为126

D:/BEDTools/bin/bedtools.exe: D:/BEDTools/bin/bedtools.exe: cannot execute binary file

arguments = [cygwin_bash_path, bedtools_exe_path, 'intersect', '-a', gene_bed_file, '-b',
             snp_bed_file, '-wa', '-wb', '>', output_file]
return_code = suprocess.call(arguments, shell=True)

导致一个空的输出文件,126 的返回码和

D:/BEDTools/bin/bedtools.exe: D:/BEDTools/bin/bedtools.exe: cannot execute binary file

有什么想法可以让它工作吗?

【问题讨论】:

  • 试试pastebin.com/Q4DZcpA7。您不能将 '&gt;' 与 shell=False 一起使用。 126 表示权限问题或文件不可执行
  • 如果你想将 stderr 重定向到文件也使用check_call(arguments,stdout=f,stderr=sunprocess.STDOUT)
  • 感谢您的快速评论,不幸的是它产生了与上一个示例相同的结果(空输出文件,返回代码 126,bedtools.exe:无法执行二进制文件)。为什么我不能使用'&gt;'?编辑:添加 stderr=subprocess:STDOUT 时,输出文件不为空,而仅包含 bedtools.exe: cannot execute binary file 行。
  • 你是从 cygwin 运行这个吗?您的输出文件是空的,因为代码错误所以输出是通过 stderr 而不是 stdout
  • 我在 PyCharm 中运行代码。

标签: python windows cmd cygwin subprocess


【解决方案1】:

假设您想从 Windows 运行 Linux 命令。您可以将 Linux 安装到 VM 中并通过 ssh(Windows 上的 Putty/plink)运行命令:

#!/usr/bin/env python
import subprocess

cmd = [r'C:\path\to\plink.exe', '-ssh', 'user@vm_host', '/path/to/bedtools']
with open('output', 'wb', 0) as file:
    subprocess.check_call(cmd, stdout=file)

Cygwin 提供run 命令,允许直接运行命令:

cmd = [r'C:\cygwin\path\to\run.exe', '-p', '/path/to/', 'bedtools', 
        '-wait', 'arg1', 'arg2']

注意:在这两种情况下,Python 脚本都是从 Windows 运行的。 bedtools 在这里是 Linux 或 Cygwin(非 Windows)命令,因此您应该提供 POSIX 路径。

【讨论】:

  • @J.F.Sebastian 我在几个变体中使用了第二个,但它仍然不起作用。 cmd = [cygwin_run_path, bedtools_exe_path, 'intersect', '-a', gene_bed_file, '-b', 'snp_bed_file', '-wa', '-wb'] 导致 return_code 0,我可以看到控制台闪烁一毫秒,但输出文件仍然是空的,其他一切都导致返回代码 1。如果可能的话,我宁愿不安装 VM。
  • @eryksun 将其作为列表或字符串传递会得到相同的结果,我尝试了每一个建议。由于我使用在 cygwin 终端中使用的相同路径格式并且它在那里工作,因此路径应该不是问题。
  • @eryksun:man run。你可以使用this question as a reference
  • @MarkusH: 你能运行别的什么吗,例如echo hello world而不是bedtools,看看文件中是否有hello world
  • 正如我所说,我尝试了几种变体,-wait 不起作用。使用 echo hello world 的 cygwin 终端可以工作,通过 Windows 控制台使用 run 执行相同操作会产生一个空文件,而其他命令也不能以这种方式工作。它在我的程序中也不起作用。
【解决方案2】:

以下工作没有问题。 " 不需要转义。

argument = 'sh -c \"' + bedtools_exe_path + ' intersect -a ' + gene_bed_file + 
           ' -b ' + snp_bed_file + ' -wa -wb\"'

with open(output_file, 'w') as file:
    subprocess.call(argument, stdout=file)

也可以使用以下方法:

argument = 'bash -c \"' + bedtools_exe_path + ' intersect -a ' + gene_bed_file + 
           ' -b ' + snp_bed_file + ' -wa -wb\"'

with open(output_file, 'w') as file:
    subprocess.call(argument, stdout=file)

与:

bedtools_exe_path = 'D:/BEDTools/bin/bedtools.exe'
gene_bed_file = 'output/gene.csv'
snp_bed_file = 'output/snps.csv'
output_file = 'output/intersect_gene_snp.bed'

使用 cygwin bash.exe (D:/Cygwin/bin/bash.exe) 的路径而不是 bashsh 不起作用。

谢谢 eryksun、Padraic Cunningham 和 J.F. Sebastian。

【讨论】:

  • 您可以写:'sh -c "{} intersect -a {} -b {} -wa -wb"'.format(*map(pipes.quote, [bedtools_exe_path, gene_bed_file, snp_bed_file])) 以支持带有空格(或其他 sh 的元字符)的 POSIX 路径。
猜你喜欢
  • 2015-08-13
  • 1970-01-01
  • 2012-11-11
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 2019-10-23
相关资源
最近更新 更多