0

如何执行 shell 命令,可以像 bash 命令行中的普通命令一样复杂,在执行后获取该命令的输出和 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 或其他奇怪的方式来更改目录时,这将不起作用。

我需要一本能容纳的字典{'cwd': '<NEW PATH>', 'result': '<COMMAND OUTPUT>'}

4

3 回答 3

1

如果您使用subprocess.Popen,您应该获得一个管道对象,您可以communicate()将其用于命令输出并用于.pid()获取进程 ID。如果您找不到通过 pid 获取进程当前工作目录的方法,我会感到非常惊讶......

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

于 2012-06-15T09:53:11.577 回答
1

要获得带有最终 cwd 的任意 shell 命令的输出(假设 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]))
于 2013-07-25T21:23:29.807 回答
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
    }

更新:这里是更好的实现(使用 pwd 的最后一行,不要使用 stderr)

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)
    }
于 2012-06-15T10:37:59.687 回答