os.system
os.system(cmd)
可以直接使用Shell命令,并回显。
subprocess
subprocess
模块允许启动一个新的进程,并连接到输入/输出/错误管道,从而获取返回值。
常用的方法有
run
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
参数 | 注释 |
---|---|
args |
必须使用数组的方式,所以经常使用shlex.split() 来切割命令 |
stdin |
标准输入 |
input |
使用字节传递输入,如果text为True则可以为字符串 |
stdout |
标准输出 |
stderr |
标准错误输出 |
capture_output |
是否获取返回值 |
shell |
执行指定的shell指令, args可以直接为字符串 |
cwd |
指定运行的目录 |
timeout |
超时后杀死子进程并抛出 TimeoutExpired 异常 |
check |
进程以非零码退出时,抛出 CalledProcessError 异常 |
encoding |
指定编码,此时input可以为字符串 |
errors |
输出文本 |
text |
以 input 和 errors 输出文本 |
env |
dict 类型,提供环境变量 |
universal_newlines |
等同于 text 参数,输出字符串,否则输出字节 |
例如:
subprocess.run(shlex.split("tmux new-session -s TireFire_{} -n Main -c {} -d".format(hostname, cwd)))
此时只是启动一个新进程执行,并没有捕获输出
subprocess.run(shell.split("ls -la"), capture_output=True, encoding='utf-8')
这样就可以再返回值里面获得stdout
了
更简单的方式是使用subprocess.getoutput
getoutput
subprocess.getoutput(cmd)
例子:
uid = subprocess.getoutput("id -u")
if uid != "0":
print("must be run with root permissions")
Popen
subprocess.Popen
是基础API命令,可以控制的地方也相对多一些
当stdin=subprocess.PIPE
的时候, 可以通过proc.stdout
获取内容
proc.wait()
等待进程结束
比如需要同时输出屏幕和文件的时候
import subprocess, sys
proc = subprocess.Popen(shell,
shell=True,
stdout=subprocess.PIPE if output else None,
stderr=subprocess.STDOUT if output else None,
universal_newlines=True)
if output:
for line in proc.stdout:
sys.stdout.write(line)
output.write(line)
proc.wait()
在权限不足的时候如何使用 sudo
这个分两种情况,一种是直接执行,另外一种是希望后台另起进程执行。参考这篇文章
直接执行
subprocess.run(shlex.split(f"sudo -S {shell}"),
shell=False)
这样就会提示需要 sudo 密码
后台执行
passwd = getpass("Please enter your password: ")
passwd_proc = subprocess.Popen(shlex.split(
f"echo {passwd}"), stdout=subprocess.PIPE)
subprocess.Popen(shlex.split(f"sudo -S {shell}" if sudo else shell),
shell=False,
stdin=passwd_proc.stdout,
stdout=output, stderr=output)
这种方式稍微绕一下,但是效果很好。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 365433079@qq.com