Python调用执行Linux系统命令(四种方法)

本文详细介绍了Python通过os模块的system和popen函数、commands模块以及subprocess模块调用Linux系统命令的四种方法,展示了如何实现与Linux系统的交互操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                Python调用执行Linux系统命令(四种方法)

Python作为一门脚本语言,胶水语言,自然是有它的胶水特性的,就比如Python和Linux系统的结合,比如,在使用Python编写自动化运维脚本的时候,总免不了需要和Linux系统交互,如,查询Linux系统内的某个文件,然后修改这个文件并运行它(假设有可运行权限)。

Python让人称道的其中一个地方就是它的类库非常齐全,这是真的不吹牛,只有你想不到,基本没有它没有的库,比如科学计算库numpy,pandas这些,或者与系统交互的库,os库,或者自动化测试的selenium库等等,到底Python有多少库我想可能Python创始人也可能不知道。(Python的社区太强大了!!!!!)那么,如果Python需要调用Linux系统命令,比如,ls,df,free,ps,这样的命令自然是需要与系统交互的专用库os结合了,还一种方法就是直接操纵进程的啦,那么,自然就是subprocess库啦。也就是说,我们想要Python能够调用Linux系统命令,也就是Python与Linux系统交互,要么需要使用os库,要么需要使用subprocess库啦还有一个不太常用的commands库~~~!!!@~~~~

Python的os模块,见名之意,opera system的意思是毫无疑问了。该模块是Python的内建模块,也可以说是内建库了,该模块内的函数自然也是内建函数了,我们要和系统命令交互,需要使用它的system(),popen()这两个函数,或者使用commands模块,或者使用subprocess模块,前面两个函数和commands模块是比较陈旧的,现在官方比较推荐也可以说强烈推荐的是subprocess模块。

(1) os.system(系统层面的直接调用),这个调用相当直接,且是同步进行的,程序需要阻塞并等待返回。返回值是依赖于系统的,直接返回系统的调用返回值,所以windows和linux是不一样的。

仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息

(2) os.popen(新开线程方式),可以看出,popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败时,close()返回系统返回值. 可见它获取返回值的方式和os.system不同

该方法不但执行命令还返回执行后的信息对象,好处在于:将返回的结果赋于一变量,便于程序的处理。

(3)  使用模块 commands( python3失效)

(4)  使用模块 subprocess(Python文档中目前全力推荐),直接调用命令,返回值即是系统返回。shell=True表示命令最终在shell中运行。Python文档中出于安全考虑,不建议使用shell=True。

import os
import commands
print('=============================ls')
os.system('ls -al /')
print('===========df')
df = os.popen('df -ah').read()
print(df)
print('=========================free')
a = commands.getoutput("free -mh")
print(a)

输出结果为:

=============================ls
total 28
dr-xr-xr-x.  17 root root  244 Jan 24 12:11 .
dr-xr-xr-x.  17 root root  244 Jan 24 12:11 ..
-rw-r--r--    1 root root    0 Jan 24 12:11 .autorelabel
lrwxrwxrwx.   1 root root    7 Jan 24 11:12 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 Jan 24 12:11 boot
drwxr-xr-x   19 root root 3320 Feb  1 09:29 dev
drwxr-xr-x. 138 root root 8192 Feb  1 09:29 etc
drwxr-xr-x.   2 root root    6 Nov  5  2016 home
lrwxrwxrwx.   1 root root    7 Jan 24 11:12 lib -> usr/lib
lrwxrwxrwx.   1 root root    9 Jan 24 11:12 lib64 -> usr/lib64
drwxr-xr-x.   2 root root    6 Nov  5  2016 media
drwxr-xr-x.   3 root root   19 Jan 24 11:34 mnt
drwxr-xr-x.   4 root root   34 Jan 24 11:58 opt
dr-xr-xr-x  229 root root    0 Feb  1 09:29 proc
dr-xr-x---.  11 root root 4096 Feb  1 09:30 root
drwxr-xr-x   39 root root 1200 Feb  1 09:29 run
lrwxrwxrwx.   1 root root    8 Jan 24 11:12 sbin -> usr/sbin
drwxr-xr-x.   2 root root    6 Nov  5  2016 srv
dr-xr-xr-x   13 root root    0 Feb  1 09:29 sys
drwxrwxrwt.  21 root root 4096 Feb  1 09:46 tmp
drwxr-xr-x.  13 root root  155 Jan 24 11:12 usr
drwxr-xr-x.  21 root root 4096 Jan 24 11:44 var
===========df
Filesystem      Size  Used Avail Use% Mounted on
rootfs             -     -     -    - /
sysfs              0     0     0    - /sys
proc               0     0     0    - /proc
devtmpfs        1.9G     0  1.9G   0% /dev
securityfs         0     0     0    - /sys/kernel/security
tmpfs           1.9G     0  1.9G   0% /dev/shm
devpts             0     0     0    - /dev/pts
tmpfs           1.9G  9.0M  1.9G   1% /run
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
cgroup             0     0     0    - /sys/fs/cgroup/systemd
pstore             0     0     0    - /sys/fs/pstore
cgroup             0     0     0    - /sys/fs/cgroup/pids
cgroup             0     0     0    - /sys/fs/cgroup/cpu,cpuacct
cgroup             0     0     0    - /sys/fs/cgroup/net_cls,net_prio
cgroup             0     0     0    - /sys/fs/cgroup/perf_event
cgroup             0     0     0    - /sys/fs/cgroup/freezer
cgroup             0     0     0    - /sys/fs/cgroup/memory
cgroup             0     0     0    - /sys/fs/cgroup/cpuset
cgroup             0     0     0    - /sys/fs/cgroup/hugetlb
cgroup             0     0     0    - /sys/fs/cgroup/blkio
cgroup             0     0     0    - /sys/fs/cgroup/devices
configfs           0     0     0    - /sys/kernel/config
/dev/sda6        70G  4.7G   66G   7% /
systemd-1          -     -     -    - /proc/sys/fs/binfmt_misc
debugfs            0     0     0    - /sys/kernel/debug
mqueue             0     0     0    - /dev/mqueue
hugetlbfs          0     0     0    - /dev/hugepages
nfsd               0     0     0    - /proc/fs/nfsd
/dev/sr0        4.3G  4.3G     0 100% /mnt/cdrom
/dev/sda3       5.0G   33M  5.0G   1% /home
/dev/sda2        20G  164M   20G   1% /var
/dev/sda1       497M  128M  370M  26% /boot
sunrpc             0     0     0    - /var/lib/nfs/rpc_pipefs
tmpfs           378M  4.0K  378M   1% /run/user/0
binfmt_misc        0     0     0    - /proc/sys/fs/binfmt_misc

=========================free
              total        used        free      shared  buff/cache   available
Mem:           3.7G        939M        1.8G        8.9M        1.0G        2.5G
Swap:          4.0G          0B        4.0G

以上是os模块的system方法,popen方法和commands库调用Linux库的方法。后续补充subprocess的调用Linux系统命令的方法。(人在外面没Python环境)

<think>嗯,用户现在的问题是如何使用Python的subprocess模块调用Linux命令并捕获输出结果。我需要仔细分析他们的需求,结合之前的回答和提供的引用来给出最佳解答。 首先,用户之前已经询问过类似的问题,我给出了四种方法,其中推荐使用subprocess模块。现在他们特别关注subprocess的具体使用,所以需要详细展开这部分。引用[1]、[2]、[3]、[4]、[5]都提到了subprocess的不同用法,比如run()、Popen(),还有如何处理输出和错误。 用户可能希望看到清晰的步骤和示例代码,特别是如何正确捕获stdout和stderr。之前的回答中提到了subprocess.run和Popen的区别,这里需要再次强调。同时,用户可能遇到的一些常见问题,比如实时输出处理、参数传递的安全性、错误处理等,都需要涵盖进去。 要注意用户可能对subprocess的参数不太熟悉,比如shell=True的安全隐患,或者text=True的作用。引用[4]提到了shell=True的安全性问题,需要在回答中提醒用户。另外,引用[5]中的实时输出处理是一个常见需求,应该给出示例,比如使用Popen逐行读取输出。 还要考虑代码示例的完整性和正确性,比如是否需要检查返回码,如何处理异常。引用[5]中的错误处理方式可以作为参考,比如捕获FileNotFoundError,并记录日志。 最后,要确保回答结构清晰,分步骤说明,并附上相关问题,帮助用户深入理解。可能需要比较不同方法,如run()和Popen()的适用场景,让用户根据需求选择合适的方法。</think>根据Python官方推荐标准和实际开发经验,以下是通过subprocess模块调用Linux命令并捕获输出的完整解决方案: ### 一、基础执行模式(推荐方案) ```python import subprocess # 基础调用示例 result = subprocess.run( ['ls', '-l', '/tmp'], # 命令参数列表 capture_output=True, # 自动捕获stdout/stderr text=True, # 自动转换二进制输出为字符串 check=True # 非零返回码触发异常[^1] ) print(f"命令输出:\n{result.stdout}") ``` ### 二、进阶功能实现 #### 1. 实时输出处理(适合长时间运行命令) ```python with subprocess.Popen( ['ping', '-c', '4', 'example.com'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) as proc: while True: output = proc.stdout.readline() if not output and proc.poll() is not None: break if output: print(output.strip()) if proc.returncode != 0: raise RuntimeError(f"命令执行失败,错误码: {proc.returncode}")[^5] ``` #### 2. 带超时控制的执行 ```python try: result = subprocess.run( ['sleep', '10'], timeout=5, # 设置5秒超时 capture_output=True, text=True ) except subprocess.TimeoutExpired: print("命令执行超时,强制终止") ``` #### 3. 环境变量控制 ```python custom_env = {'PATH': '/usr/local/bin:' + os.environ['PATH']} subprocess.run( ['myapp'], env=custom_env, # 自定义环境变量 capture_output=True ) ``` ### 三、最佳实践建议 1. **参数安全传递** 使用参数列表而非字符串拼接,避免注入风险: ```python # 危险写法(可能被注入) subprocess.run(f"ls {user_input}", shell=True) # 安全写法 subprocess.run(['ls', sanitized_input])[^4] ``` 2. **错误处理规范** ```python try: result = subprocess.run( ['grep', 'ERROR', 'log.txt'], capture_output=True, check=True ) except subprocess.CalledProcessError as e: print(f"命令失败,错误码: {e.returncode}") print(f"错误输出: {e.stderr}") ``` 3. **编码处理技巧** 处理二进制输出时指定编码: ```python result = subprocess.run( ['file', '-b', 'unknown.bin'], capture_output=True ) print(result.stdout.decode('utf-8', errors='replace')) ``` ### 四、方法对比 | 方法 | 适用场景 | 输出捕获 | 实时处理 | 异常控制 | |-------------------|--------------------------|---------|---------|---------| | run() | 简单命令执行 | ✅ | ❌ | ✅ | | Popen() | 持续输出/交互式命令 | ✅ | ✅ | ❌ | | check_output() | 仅需标准输出时 | ✅ | ❌ | ✅ |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚风_END

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值