我如何在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
其他回答
Invoke 是一个 Python (2.7 和 3.4+) 任务执行工具和图书馆. 它提供清洁,高级别的 API 运行 Shell 命令:
>>> from invoke import run
>>> cmd = "pip install -r requirements.txt"
>>> result = run(cmd, hide=True, warn=True)
>>> print(result.ok)
True
>>> print(result.stdout.splitlines()[-1])
Successfully installed invocations-0.13.0 pep8-1.5.7 spec-1.3.1
我会建议使用子过程模块而不是os.system,因为它会让您逃脱,因此更安全。
subprocess.call(['ping', 'localhost'])
在Python中呼叫外部命令
一个简单的方式来呼叫一个外部命令是使用os.system(...). 这个功能返回命令的输出值. 但缺点是我们不会得到 stdout 和 stderr。
ret = os.system('some_cmd.sh')
if ret != 0 :
print 'some_cmd.sh execution returned failure'
在背景下在Python中呼叫外部命令
subprocess.Popen 提供更多的灵活性运行一个外部命令而不是使用 os.system. 我们可以在背景下启动一个命令,等待它完成。
proc = subprocess.Popen(["./some_cmd.sh"], stdout=subprocess.PIPE)
print 'waiting for ' + str(proc.pid)
proc.wait()
print 'some_cmd.sh execution finished'
(out, err) = proc.communicate()
print 'some_cmd.sh output : ' + out
在背景下在Python中呼叫一个长期运行的外部命令,并在一段时间后停止
我们甚至可以在背景下开始一个漫长的运行过程,使用subprocess.Popen,并在任务完成后一次杀死它。
proc = subprocess.Popen(["./some_long_run_cmd.sh"], stdout=subprocess.PIPE)
# Do something else
# Now some_long_run_cmd.sh exeuction is no longer needed, so kill it
os.system('kill -15 ' + str(proc.pid))
print 'Output : ' proc.communicate()[0]
我写了一本小图书馆来帮助这个使用案例:
HTTPS://pypi.org/project/citizenshell/
可以使用安装
pip install citizenshell
然后使用如下:
from citizenshell import sh
assert sh("echo Hello World") == "Hello World"
您可以将标准输出与标准错误分开,并以以下方式提取输出代码:
result = sh(">&2 echo error && echo output && exit 13")
assert result.stdout() == ["output"]
assert result.stderr() == ["error"]
assert result.exit_code() == 13
而且很酷的是,在开始处理输出之前,你不需要等待底层的裂缝出发:
for line in sh("for i in 1 2 3 4; do echo -n 'It is '; date +%H:%M:%S; sleep 1; done", wait=False)
print ">>>", line + "!"
将按行按行按行按行按行按行按行按行按行。
>>> It is 14:24:52!
>>> It is 14:24:53!
>>> It is 14:24:54!
>>> It is 14:24:55!
更多例子可以找到 https://github.com/meuter/citizenshell
苏丹是一个最近为此而设计的包,它提供了管理用户特权和添加有用的错误消息的一些好处。
from sultan.api import Sultan
with Sultan.load(sudo=True, hostname="myserver.com") as sultan:
sultan.yum("install -y tree").run()
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从终端/命令行调用VS代码编辑器
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 查看PS命令的全部输出