使用os.system进行多行命令

时间:2016-02-03 00:25:19

标签: python

我正在尝试从python文件运行shell代码以将另一个python文件提交到计算集群。 shell代码如下:

#BSUB -J Proc[1]
#BSUB -e ~/logs/proc.%I.%J.err
#BSUB -o ~/logs/proc.%I.%J.out
#BSUB -R "span[hosts=1]"
#BSUB -n 1
python main.py

但是当我从python中运行它时,我无法让它工作:

from os import system
system('bsub -n 1 < #BSUB -J Proc[1];#BSUB -e ~/logs/proc.%I.%J.err;#BSUB -o ~/logs/proc.%I.%J.out;#BSUB -R "span[hosts=1]";#BSUB -n 1;python main.py')

我在这里做错了吗?

2 个答案:

答案 0 :(得分:2)

如果我理解正确,所有#BSUB内容都应该作为输入提供给bsub命令的文本; bsub在本地运行,然后在计算节点上为您运行这些命令。

在这种情况下,你不能这样做:

bsub -n 1 < #BSUB -J Proc[1];#BSUB -e ~/logs/proc.%I.%J.err;#BSUB -o ~/logs/proc.%I.%J.out;#BSUB -R "span[hosts=1]";#BSUB -n 1;python main.py

由shell解释为&#34;运行bsub -n 1并从名为OH CRAP的文件中读取一个评论开始,现在我们不需要阅读文件!&# 34;

你可以使用MOAR HACKERY解决这个问题(使用echo或者这里的字符串会对shell执行产生更多不必要的依赖)。但是,如果您想提供stdin输入,那么最好的解决方案是使用功能更强大的工具the subprocess module

# Open a process (no shell wrapper) that we can feed stdin to
proc = subprocess.Popen(['bsub', '-n', '1'], stdin=subprocess.PIPE)

# Feed the command series you needed to stdin, then wait for process to complete
# Per Michael Closson, can't use semi-colons, bsub requires newlines
proc.communicate(b'''#BSUB -J Proc[1]
#BSUB -e ~/logs/proc.%I.%J.err
#BSUB -o ~/logs/proc.%I.%J.out
#BSUB -R "span[hosts=1]"
#BSUB -n 1
python main.py
''')

# Assuming the exit code is meaningful, check it here
if proc.returncode != 0:
    # Handle a failed process launch here

这样可以完全避免shell启动(删除需要处理注释字符的问题,以及处理shell元字符的所有其他问题),并明确更明确地说明本地运行的内容({{1什么是在bsub -n 1会话中运行的命令(bsub)。

答案 1 :(得分:1)

#BSUB指令由bsub二进制文件解析,它不支持;作为分隔符。您需要使用换行符。这对我有用。

#!/usr/bin/python
import subprocess;

# Open a process (no shell wrapper) that we can feed stdin to
proc = subprocess.Popen(['bsub', '-n', '1'], stdin=subprocess.PIPE)

# Feed the command series you needed to stdin, then wait for process to complete
input="""#!/bin/sh
#BSUB -J mysleep
sleep 101
"""
proc.communicate(input);

***显然我从@ShadowRanger获得了python代码。 +1他的答案。如果在评论中支持python代码,我会将此作为对他答案的评论发布。