文章目录
- 1 传入的参数是一个 数组 而不是字符串。 import subprocess return_code=subprocess.run([‘ls’,’-al’,’.’]) print(return_code) /home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py总用量 20drwxrwxr-x 3 topeet topeet 4096 8月 11 01:00 .drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea-rw-rw-r– 1 topeet topeet 504 7月 27 07:35 main.py-rwxrwxr-x 1 topeet topeet 2533 8月 11 01:00 test.pyCompletedProcess(args=['ls', '-al', '.'], returncode=0) 2 执行返回的结果是一个CompletedProcess对象
- import subprocess return_code=subprocess.run([‘ls’,’-al’,’.’],stdout=subprocess.DEVNULL) print(return_code) (base) topeet@ubuntu:~/test/python$ python test.pyCompletedProcess(args=['ls', '-al', '.'], returncode=0) 2 输出结果就仅有 Python 程序运行出的结果。
- import subprocess useless_cat_call=subprocess.run([‘cat’],stdout=subprocess.PIPE,text=True,input=”Hello”) print(useless_cat_call.stdout) /home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.pyHello stdout=subprocess.PIPE 告诉 Python,重定向 Shell 命令的输出,并且这部分输出可以被后面的 Python 程序所调用。 text=True 告诉 Python,将 shell 命令的执行的 stdout 和 stderr 当成字符串. 默认是当成 bytes. input="Hello from the other side" 告诉 Python,shell 命令的输入参数.
- 1 当 shell 的执行出现任何问题,都会抛出一个异常。 import subprocess failed_command=subprocess.run([‘false’],text=True) print(“The exit code was: %d” % failed_command.returncode) /home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.pyThe exit code was: 1
- 核心控制参数 args 作用:指定要执行的命令,支持列表(推荐)或字符串形式。 注意:列表形式可避免命令注入风险;字符串形式必须设置 shell=True。 subprocess.run([“ls”, “-l”]) # 安全方式(列表)[1,3] subprocess.run(“ls -l”, shell=True) # 字符串需配合 shell=True[5] shell 作用:是否通过系统 Shell(如 /bin/sh或 cmd.exe)执行命令。 风险:shell=True可能引发安全漏洞(如执行恶意输入),非必要不启用 适用场景:需 Shell 特性(如通配符 *、管道 |)时使用。 timeout 作用:设置命令超时时间(秒),超时抛出 TimeoutExpired异常。 示例: try: subprocess.run([“sleep”, “10”], timeout=5) except TimeoutExpired: print(“命令超时!”) # 5秒后中断[3,6] 输入/输出处理参数 stdin、stdout、stderr 作用:控制子进程的标准流,可选值: subprocess.PIPE:捕获数据流(通过 result.stdout访问) subprocess.DEVNULL:丢弃输出(类似 /dev/null)。 文件对象:重定向到文件。 示例: result = subprocess.run([“ls”], stdout=subprocess.PIPE, stderr=subprocess.PIPE) capture_output 作用:简化输出捕获(等价于设置 stdout=PIPE, stderr=PIPE)。 冲突:不可与 stdout/stderr同时使用 input 作用:向子进程的 stdin 传递数据,需配合 stdin=PIPE(自动启用)。 数据类型: text=True时:字符串(如 input="Hello") 默认:字节流(如 input=b"Hello")。 text/ encoding 作用:控制输入/输出的文本模式: text=True:输入/输出自动转为字符串(等价于 universal_newlines=True) encoding="utf-8":指定编解码方式(如处理中文)。 执行环境参数 cwd 作用:设置子进程的工作目录。 示例: subprocess.run([“pwd”], cwd=”/tmp”) # 输出 “/tmp env 作用:自定义环境变量(字典形式),默认继承父进程环境。 示例: env = {“PATH”: “/usr/bin”, “MY_VAR”: “test”} subprocess.run([“echo”, “$MY_VAR”], env=env, shell=True)[4](@ref) 异常与状态处理 check 作用:若子进程返回非零退出码,抛出 CalledProcessError异常。 示例: try: subprocess.run([“false”], check=True) # 总是失败的命令 except CalledProcessError as e: print(f”错误码: {e.returncode}, 错误: {e.stderr}”) 返回值 CompletedProcess 属性: returncode:退出状态码(0 表示成功)。 stdout/stderr:捕获的输出(文本或字节流)。 args:执行的命令 方法: check_returncode():非零退出码时抛出异常。 最佳实践总结 安全优先: 使用列表传参(如 ["ls", "-l"]),避免 shell=True除非必要 输出处理: 需捕获输出时,用 capture_output=True+ text=True简化代码。 异常管理: 关键命令添加 check=True+ try/except确保失败可追溯 跨平台注意: Windows 部分命令(如 dir)需 shell=True 性能优化: 避免频繁调用高开销命令(如反复启动 Shell)
- subprocess.run 可以看成是 subprocess.Popen 一个简化抽象。
- 1.默认情况下, subprocess.Popen 不会中暂停 Python 程序本身的运行(异步)2.但是如果你非得同前面两种方式一样,同步运行,你可以加上 .wait() 方法。3.当我们仍然处在异步的状况,通过 poll() 来轮询,知道shell 命令是否运行结束与否?当放回结果为 None,则表示程序还在运行,否者会返回一个状态码。 如果想, 指定输入参数 ,则需要通过 communicate() 方法。 import subprocess useless_cat_call=subprocess.Popen([‘cat’],stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE,text=True) output,errors=useless_cat_call.communicate(input=”hello”) useless_cat_call.wait() print(output) print(errors) /home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.pyhello 到此这篇关于浅谈Python调用Shell脚本的三种常用方式的文章就介绍到这了,更多相关Python调用Shell脚本内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Python调用shell命令常用方法(4种) python调用shell的方法 python调用bash shell脚本方法 node.js调用脚本(python/shell)和系统命令 Python代码调用执行shell踩坑解决
目录
- 一、通过 Python 来调用 Shell 脚本的三种常用方式
- os.system
- subprocess.run(推荐)
- 1 、 能够相当方便的控制 shell 命令的输入和输出
- 2 、忽略shell 脚本执行的结果
- 3 、指定 shell 命令的输入参数(通过 input 参数来传入)
- 4 、开启 shell 命令的执行校验
- 5、subprocess.run方法参数的介绍
- subprocess.Popen
- 1 、subprocess.Popen能够提供更大的灵活性。
- 2 、subprocess.Popen的使用与注意
三种方式的优缺点
| os.system | subprocess.run | subprocess.Popen | |
|---|---|---|---|
| 是否需要解析参数 | no | yes | yes |
| 同步执行(等待Shell执行结果) | yes | yes | no |
| 能够获得 shell 的输入和输出 | no | yes | yes |
| Shell 执行结果返回值 | return value | object | object |
import os
return_code=os.system('ls -al .')
print(return_code)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
总用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:56 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r– 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2442 8月 11 00:56 test.py
0
也会将Shell语句的输出输出到的 Python的命令控制台中。
但是 Python 的能够获取的返回值,是数字,0 代表 Shell 语句/脚本的执行成功,否则表示Shell执行的状态值。
适用于不需要详细的返回信息的 shell 脚本
传入 Shell 命令的参数,都是完整的 String。
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
总用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:56 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r– 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2442 8月 11 00:56 test.py
0
也会将Shell语句的输出输出到的 Python的命令控制台中。
但是 Python 的能够获取的返回值,是数字,0 代表 Shell 语句/脚本的执行成功,否则表示Shell执行的状态值。
适用于不需要详细的返回信息的 shell 脚本
传入 Shell 命令的参数,都是完整的 String。
- 1 传入的参数是一个 数组 而不是字符串。
import subprocess
return_code=subprocess.run(['ls','-al','.'])
print(return_code)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
总用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 01:00 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r– 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2533 8月 11 01:00 test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
- 2 执行返回的结果是一个CompletedProcess对象
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
总用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 01:00 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r– 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2533 8月 11 01:00 test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
import subprocess
return_code=subprocess.run(['ls','-al','.'],stdout=subprocess.DEVNULL)
print(return_code)
(base) topeet@ubuntu:~/test/python$ python test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
- 2 输出结果就仅有 Python 程序运行出的结果。
(base) topeet@ubuntu:~/test/python$ python test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
import subprocess
useless_cat_call=subprocess.run(['cat'],stdout=subprocess.PIPE,text=True,input="Hello")
print(useless_cat_call.stdout)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
Hello
- stdout=subprocess.PIPE 告诉 Python,重定向 Shell 命令的输出,并且这部分输出可以被后面的 Python 程序所调用。
- text=True 告诉 Python,将 shell 命令的执行的 stdout 和 stderr 当成字符串. 默认是当成 bytes.
- input="Hello from the other side" 告诉 Python,shell 命令的输入参数.
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
Hello
- stdout=subprocess.PIPE 告诉 Python,重定向 Shell 命令的输出,并且这部分输出可以被后面的 Python 程序所调用。
- text=True 告诉 Python,将 shell 命令的执行的 stdout 和 stderr 当成字符串. 默认是当成 bytes.
- input="Hello from the other side" 告诉 Python,shell 命令的输入参数.
- 1 当 shell 的执行出现任何问题,都会抛出一个异常。
import subprocess
failed_command=subprocess.run(['false'],text=True)
print("The exit code was: %d" % failed_command.returncode)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
The exit code was: 1
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
The exit code was: 1
核心控制参数
- args
- 作用:指定要执行的命令,支持列表(推荐)或字符串形式。
- 注意:列表形式可避免命令注入风险;字符串形式必须设置 shell=True。
subprocess.run(["ls", "-l"]) # 安全方式(列表)[1,3]
subprocess.run("ls -l", shell=True) # 字符串需配合 shell=True[5]
- shell
- 作用:是否通过系统 Shell(如 /bin/sh或 cmd.exe)执行命令。
- 风险:shell=True可能引发安全漏洞(如执行恶意输入),非必要不启用
- 适用场景:需 Shell 特性(如通配符 *、管道 |)时使用。
- timeout
- 作用:设置命令超时时间(秒),超时抛出 TimeoutExpired异常。
- 示例:
try:
subprocess.run(["sleep", "10"], timeout=5)
except TimeoutExpired:
print("命令超时!") # 5秒后中断[3,6]
输入/输出处理参数
- stdin、stdout、stderr
- 作用:控制子进程的标准流,可选值:
- subprocess.PIPE:捕获数据流(通过 result.stdout访问)
- subprocess.DEVNULL:丢弃输出(类似 /dev/null)。
- 文件对象:重定向到文件。
- 示例:
result = subprocess.run(["ls"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- capture_output
- 作用:简化输出捕获(等价于设置 stdout=PIPE, stderr=PIPE)。
- 冲突:不可与 stdout/stderr同时使用
- input
- 作用:向子进程的 stdin 传递数据,需配合 stdin=PIPE(自动启用)。
- 数据类型:
- text=True时:字符串(如 input="Hello")
- 默认:字节流(如 input=b"Hello")。
- text/ encoding
- 作用:控制输入/输出的文本模式:
- text=True:输入/输出自动转为字符串(等价于 universal_newlines=True)
- encoding="utf-8":指定编解码方式(如处理中文)。
执行环境参数
- cwd
- 作用:设置子进程的工作目录。
- 示例:
subprocess.run(["pwd"], cwd="/tmp") # 输出 "/tmp
- env
- 作用:自定义环境变量(字典形式),默认继承父进程环境。
- 示例:
env = {"PATH": "/usr/bin", "MY_VAR": "test"}
subprocess.run(["echo", "$MY_VAR"], env=env, shell=True)[4](@ref)
异常与状态处理
- check
- 作用:若子进程返回非零退出码,抛出 CalledProcessError异常。
- 示例:
try:
subprocess.run(["false"], check=True) # 总是失败的命令
except CalledProcessError as e:
print(f"错误码: {e.returncode}, 错误: {e.stderr}")
- 返回值 CompletedProcess
- 属性:
- returncode:退出状态码(0 表示成功)。
- stdout/stderr:捕获的输出(文本或字节流)。
- args:执行的命令
- 方法:
- check_returncode():非零退出码时抛出异常。
最佳实践总结
- 安全优先:
- 使用列表传参(如 ["ls", "-l"]),避免 shell=True除非必要
- 输出处理:
- 需捕获输出时,用 capture_output=True+ text=True简化代码。
- 异常管理:
- 关键命令添加 check=True+ try/except确保失败可追溯
- 跨平台注意:
- Windows 部分命令(如 dir)需 shell=True
- 性能优化:
- 避免频繁调用高开销命令(如反复启动 Shell)
subprocess.run 可以看成是 subprocess.Popen 一个简化抽象。
1.默认情况下, subprocess.Popen 不会中暂停 Python 程序本身的运行(异步)
2.但是如果你非得同前面两种方式一样,同步运行,你可以加上 .wait() 方法。
3.当我们仍然处在异步的状况,通过 poll() 来轮询,知道shell 命令是否运行结束与否?当放回结果为 None,则表示程序还在运行,否者会返回一个状态码。
1.默认情况下, subprocess.Popen 不会中暂停 Python 程序本身的运行(异步)
2.但是如果你非得同前面两种方式一样,同步运行,你可以加上 .wait() 方法。
3.当我们仍然处在异步的状况,通过 poll() 来轮询,知道shell 命令是否运行结束与否?当放回结果为 None,则表示程序还在运行,否者会返回一个状态码。
如果想, 指定输入参数 ,则需要通过 communicate() 方法。
import subprocess useless_cat_call=subprocess.Popen(['cat'],stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE,text=True) output,errors=useless_cat_call.communicate(input="hello") useless_cat_call.wait() print(output) print(errors)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
hello
到此这篇关于浅谈Python调用Shell脚本的三种常用方式的文章就介绍到这了,更多相关Python调用Shell脚本内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Python调用shell命令常用方法(4种)
- python调用shell的方法
- python调用bash shell脚本方法
- node.js调用脚本(python/shell)和系统命令
- Python代码调用执行shell踩坑解决