我如何在Python中命名一个外部命令,就好像我把它写在一个<unk>或命令中?
当前回答
经过一些研究,我有下面的代码,这对我来说非常好,它基本上在实时打印了标准输出和标准错误。
stdout_result = 1
stderr_result = 1
def stdout_thread(pipe):
global stdout_result
while True:
out = pipe.stdout.read(1)
stdout_result = pipe.poll()
if out == '' and stdout_result is not None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
def stderr_thread(pipe):
global stderr_result
while True:
err = pipe.stderr.read(1)
stderr_result = pipe.poll()
if err == '' and stderr_result is not None:
break
if err != '':
sys.stdout.write(err)
sys.stdout.flush()
def exec_command(command, cwd=None):
if cwd is not None:
print '[' + ' '.join(command) + '] in ' + cwd
else:
print '[' + ' '.join(command) + ']'
p = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
)
out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,))
err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,))
err_thread.start()
out_thread.start()
out_thread.join()
err_thread.join()
return stdout_result + stderr_result
其他回答
下面是如何呼叫外部程序的概述,包括其优点和缺点:
os.system 将命令和论点转移到您的系统的阴道. 这很好,因为您实际上可以以这种方式同时运行多个命令,并设置管道和输入/输出重定向。 例如: os.system(“some_command < input_file♰ another_command > output_file”) 但是,虽然这是方便的,您必须手动处理阴道字符的逃避,如空间,和
副过程模块应该是你所使用的。
最后,请注意,对于你通过的所有方法,最终命令将由丝带执行,你负责逃避它。 有严重的安全影响,如果你通过的丝带的任何部分不能完全信任。 例如,如果用户进入某些 / 任何部分的丝带. 如果你不确定,只使用这些方法的连续。
print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()
想象一下,用户输入了一些“我的妈妈不喜欢我&rm -rf /”可以删除整个文件系统。
在Linux中,如果您想打电话给一个将独立执行的外部命令(在Python脚本结束后将继续运行),您可以使用一个简单的字符串作为任务插槽或命令中的命令。
例如,Task Spooler:
import os
os.system('ts <your-command>')
關於Task Spooler(TS)的評論:
您可以设置要运行的竞争对手过程的数量(“插槽”)与: ts -S <插槽的号码> 安装 ts 不需要管理特权. 您可以从源头下载并编写一个简单的创建,将其添加到您的路径,并完成。
我会推荐下面的“运行”方法,它会帮助我们获得标准输出、标准错误和输出状态作为词典;这个词典的呼叫者可以通过“运行”方法阅读词典返回,以了解过程的实际状态。
def run (cmd):
print "+ DEBUG exec({0})".format(cmd)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
(out, err) = p.communicate()
ret = p.wait()
out = filter(None, out.split('\n'))
err = filter(None, err.split('\n'))
ret = True if ret == 0 else False
return dict({'output': out, 'error': err, 'status': ret})
#end
最多案例:
在大多数情况下,一个短片的代码,如此,是你将需要的一切:
import subprocess
import shlex
source = "test.txt"
destination = "test_copy.txt"
base = "cp {source} {destination}'"
cmd = base.format(source=source, destination=destination)
subprocess.check_call(shlex.split(cmd))
它是干净和简单的。
subprocess.check_call 以论点运行命令,等待命令完成。 shlex.split 使用 shell-like syntax 分割行 cmd
其他案例:
如果这不适用于某些特定的命令,最有可能你有一个问题与命令线的解释器. 操作系统选择了默认一个不适合你的程序类型或可能没有找到适当的一个在系统可执行的路径。
例子:
使用Unix系统上的转向操作器
input_1 = "input_1.txt"
input_2 = "input_2.txt"
output = "merged.txt"
base_command = "/bin/bash -c 'cat {input} >> {output}'"
base_command.format(input_1, output=output)
subprocess.check_call(shlex.split(base_command))
base_command.format(input_2, output=output)
subprocess.check_call(shlex.split(base_command))
正如《Python Zen: Explicit is better than implicit》中所说的那样。
因此,如果使用 Python >=3.6 函数,它会看起来像这样:
import subprocess
import shlex
def run_command(cmd_interpreter: str, command: str) -> None:
base_command = f"{cmd_interpreter} -c '{command}'"
subprocess.check_call(shlex.split(base_command)
更新:
subprocess.run 是关于 Python 3.5 的推荐方法,如果您的代码不需要与以前的 Python 版本保持兼容性。
下面是文档的一些例子。
运行一个过程:
>>> subprocess.run(["ls", "-l"]) # Doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
上一篇: 失败的跑步:
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
捕获输出:
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
原始答案:
我建议尝试发送,这是一个子过程的插槽,其目的是取代旧的模块和功能。
使用 README 的例子:
>>> r = envoy.run('git config', data='data to pipe in', timeout=2)
>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''
周围的管道也:
>>> r = envoy.run('uptime | pbcopy')
>>> r.command
'pbcopy'
>>> r.status_code
0
>>> r.history
[<Response 'uptime'>]