通过回声管道将python变量(字符串)传递给bash命令[重复]

Posted

技术标签:

【中文标题】通过回声管道将python变量(字符串)传递给bash命令[重复]【英文标题】:passing python variable (string) to bash command through echo pipe [duplicate] 【发布时间】:2017-07-16 01:49:36 【问题描述】:

我在将 python 中的字符串(python 变量)作为输入传递给命令行 (bash) 上的序列对齐程序 (muscle) 时遇到问题。 muscle 可以从命令行获取标准输入,例如;

~# echo -e ">1\nATTTCTCT\n>2\nATTTCTCC" | muscle

MUSCLE v3.8.31 by Robert C. Edgar

http://www.drive5.com/muscle
This software is donated to the public domain.
Please cite: Edgar, R.C. Nucleic Acids Res 32(5), 1792-97.

- 2 seqs, max length 8, avg  length 8
00:00:00     22 MB(2%)  Iter   1  100.00%  K-mer dist pass 1
00:00:00     22 MB(2%)  Iter   1  100.00%  K-mer dist pass 2
00:00:00     23 MB(2%)  Iter   1  100.00%  Align node       
00:00:00     23 MB(2%)  Iter   1  100.00%  Root alignment
>1
ATTTCTCT
>2
ATTTCTCC

我追求的是这种 fasta 对齐方式(最后 4 行) - 您可以重定向肌肉的输出(echo -e ">1\nATTTCTCT\n>2\nATTTCTCC" | muscle > out.file 以获得我需要进行下游处理的 fasta 对齐方式。但要到达那里,我必须通过 'muscle' FASTA 序列字符串,我认为最好通过echo 在 bash 中完成。

因此,该脚本需要两个 multiFASTA 文件,并根据每个文件的 id 列表对每个 FASTA 序列进行配对 - 这是有效的(尽管我意识到这可能不是最有效的方法 - 我是新手蟒蛇用户)。然后我需要在计算距离/差异之前对齐muscle 中的每个集合。

这是我目前所拥有的:

#! /env/python
from pairwise_distances import K2Pdistance
import pairwise_distances
import subprocess
from subprocess import call
import os     

fasta1=['']
for line in open('test1.fasta'):
    if not line.startswith('>'):
         fasta1.append(line.strip())

fasta2=['']
for line in open('test2.fasta'):
    if not line.startswith('>'):
         fasta2.append(line.strip())

for l1, l2 in zip(open('test1.list'), open ('test2.list')):
 try:
   a=fasta1[int(l1)]
 except IndexError,e:  
   a="GGG"

 try:
   b=fasta2[int(l2)]
 except (IndexError):
   b="CCC"

 temp_align=str(">1"+'\n'+a+'\n'+">2"+'\n'+b) 

 first=subprocess.check_output(['echo','-e',temp_align])
 print first
 subprocess.call(['bash','muscle'], stdin=first.stdout)
 print second

 #new=K2Pdistance(outfast1,outfast2) 
 #subprocess.Popen(['bash','muscle'], stdin=subprocess.check_output(['echo','-e',temp_align], stdout=subprocess.PIPE).std.out)`

“temp_align”变量是我想传递给肌肉的——它是组合每个 multiFASTA 文件中的适当 fasta 序列的结果,对于 ids/list 上的每个循环,它的格式类似于 FASTA 文件。

这个问题是我可以echo FASTA 字符串,但我似乎无法通过标准输入“管道”到肌肉......我得到的主要错误是:AttributeError: 'str' object has no attribute 'stdout'

~#python Beta3.py 
>1
ATCGACTACT
>2
ATCGCGCTACT

Traceback (most recent call last):
  File "Beta3.py", line 38, in <module>
    subprocess.call(['bash','muscle'], stdin=first.stdout)
AttributeError: 'str' object has no attribute 'stdout'

子进程或其他命令行模块可以将字符串作为标准输入吗?如果不是,我不确定我如何回声然后进入肌肉...... 任何其他想法将不胜感激。我尝试了这个线程unix.stackexchange的几个选项

但还没有运气。

编辑:以下是一些示例文件:

~# cat test1.fasta 
>1
ATCGACTACT
>2
ACTCAGTCA
>3
TTCACAGGG
~# cat test2.fasta 
>1
ATCGCGCTACT
>2
GGCGTCAGTCA
>3
TTCAACCCCAGGG
~# cat test1.list 
1
2
3
~# cat test2.list 
1
3
2

编辑 2:上一篇文章是相关的,但我的问题是关于链接两个 bash 命令,该命令以一个作为字符串的 python 变量开头......然后,理想情况下,将第二个命令的标准输出捕获回一个 python 变量...我不太明白如何将该帖子上的答案翻译成针对我的特定问题的解决方案...我想我不完全理解发帖人试图做什么。

【问题讨论】:

first 是一个字符串,要将其发送到命令请参见:***.com/a/165662/7311767 为什么是subprocess.call(['bash','muscle'], stdin=first.stdout) 而不仅仅是subprocess.call(['muscle'], stdin=first.stdout) 它没有任何区别(字符串错误仍然存​​在),但我猜那里不需要'bash'。 subprocess.check_output 的结果是一个字符串(执行的子进程的标准输出)。您想使用 subprocess.call 或提供类似对象的字符串作为标准输入参数,这应该可以简化事情。 这个问题已经作为副本关闭了,所以我不能提供完整的答案,但是 BioPython 有一个包装器用于muscle 进行多序列比对,请参阅教程中的Chapter 6.4.2。 【参考方案1】:

看来你想和muscle进程通信,那么你需要一个PIPE,用这个

(out, err) = subprocess.Popen(['muscle'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate(temp_align)
print out

【讨论】:

啊。我现在明白了。非常感谢您的帮助。

以上是关于通过回声管道将python变量(字符串)传递给bash命令[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将 FILE * 从 Python / ctypes 传递给函数

Makefile将变量传递给bash脚本

如何将变量传递给 azure devops 管道中的 SqlAzureDacpacDeployment@1 任务

无法将环境变量传递给 azure 管道 yaml 中的 powershell 脚本(非内联)

如何将 Azure 管道变量传递给 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?

如何能够将变量传递给 gitlab ci 管道中的规则?