2012-06-15 187 views
0

如何执行shell命令,可以像bash命令行中的普通命令那样复杂,在执行后获取该命令和pwd的输出?如何执行shell命令在Python中的命令后获取输出和pwd

我用这样的功能:

import subprocess as sub 

def execv(command, path): 
    p = sub.Popen(['/bin/bash', '-c', command], 
        stdout=sub.PIPE, stderr=sub.STDOUT, cwd=path) 
    return p.stdout.read()[:-1] 

我检查,如果用户使用cd命令,但是当用户使用符号连接到CD或其他奇怪的方式来改变目录,将无法正常工作。

,我需要如果您使用subprocess.Popen持有{'cwd': '<NEW PATH>', 'result': '<COMMAND OUTPUT>'}

回答

0

我标准输出重定向到pwd命令的标准错误。如果stdout是空的和stderr不是一个路径,然后stderr是命令的错误

import subprocess as sub 

def execv(command, path): 
    command = 'cd %s && %s && pwd 1>&2' % (path, command) 
    proc = sub.Popen(['/bin/bash', '-c', command], 
        stdout=sub.PIPE, stderr=sub.PIPE) 
    stderr = proc.stderr.read()[:-1] 
    stdout = proc.stdout.read()[:-1] 
    if stdout == '' and not os.path.exists(stderr): 
     raise Exception(stderr) 
    return { 
     "cwd": stderr, 
     "stdout": stdout 
    } 

UPDATE:这里是更好的FPGA实现(使用最后一行的PWD和不使用标准错误)

def execv(command, path): 
    command = 'cd %s && %s 2>&1;pwd' % (path, command) 
    proc = sub.Popen(['/bin/bash', '-c', command], 
        env={'TERM':'linux'}, 
        stdout=sub.PIPE) 
    stdout = proc.stdout.read() 
    if len(stdout) > 1 and stdout[-1] == '\n': 
     stdout = stdout[:-1] 
    lines = stdout.split('\n') 
    cwd = lines[-1] 
    stdout = '\n'.join(lines[:-1]) 
    return { 
     "cwd": cwd, 
     "stdout": man_to_ansi(stdout) 
    } 
1

一本字典,你应该得到一个管道对象,你可以communicate()该命令的输出,并使用.pid()获取进程的ID。我会真的感到惊讶,如果你不能找到一个方法来获得由pid进程的当前工作目录...

例如为:http://www.cyberciti.biz/tips/linux-report-current-working-directory-of-process.html

+0

我试试吧,还有的/ proc//cwd目录,代码需要检查,它可以使用'ls'或'file'(和解析结果)来做到这一点,但是当代码执行那些命令时cwd不再可读,因为过程结束了。因此,您需要在执行命令后添加睡眠命令。更好的是只是运行pwd。 – jcubic

1

为了得到一个任意shell命令的输出,其最终CWD(假设在CWD不换行):

from subprocess import check_output 

def command_output_and_cwd(command, path): 
    lines = check_output(command + "; pwd", shell=True, cwd=path).splitlines() 
    return dict(cwd=lines[-1], stdout=b"\n".join(lines[:-1]))