在Python中执行Shell命令并获取其结果,通常可以使用subprocess模块。这个模块允许我们启动新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回码。下面是一个详细的示例,展示了如何使用subprocess.run()函数来执行Shell命令并获取其输出。

1. 示例一:使用subprocess.run()执行ls命令并获取结果

这个示例将执行ls命令(在Unix/Linux/macOS系统上列出当前目录下的文件和文件夹),并捕获命令的输出和返回码。

import subprocess  

# 定义要执行的命令
command = ['ls', '-l'] # 使用列表形式,更安全,可以避免shell注入攻击 # 执行命令
# capture_output=True 参数表示捕获命令的输出(stdout和stderr)
# text=True 参数表示将输出作为文本处理(Python 3.7+),之前版本使用universal_newlines=True
result = subprocess.run(command, capture_output=True, text=True) # 获取命令的标准输出
stdout = result.stdout # 获取命令的错误输出(如果有的话)
stderr = result.stderr # 获取命令的返回码
returncode = result.returncode # 打印结果
print(f"标准输出:\n{stdout}")
if stderr:
print(f"错误输出:\n{stderr}")
print(f"返回码: {returncode}") # 注意:如果命令成功执行,returncode通常为0;非0值表示有错误发生

注意事项

(1)安全性:本例中使用命令列表而非字符串来避免shell注入攻击。当命令和参数以列表形式提供时,Python会直接将它们传递给系统,不会通过shell解释,从而减少了安全风险。

(2)文本与字节capture_output=Truetext=True(或universal_newlines=True,在旧版本中)的组合使得输出以文本(字符串)形式返回,而不是字节。这对于处理文本数据很方便,但如果我们需要处理二进制数据(如图像或视频文件),则可能需要以字节形式捕获输出。

(3)错误处理:通过检查returncode可以判断命令是否成功执行。如果returncode不为0,则可能需要根据stderr中的信息来诊断问题。

(4)跨平台兼容性:本示例中的ls -l命令是Unix/Linux/macOS系统特有的。在Windows系统上,我们可能需要执行不同的命令(如dir),并可能需要调整命令的调用方式(例如,使用shell=True,但请注意这会增加安全风险)。

(5)性能考虑:频繁地启动外部进程可能会降低程序的性能。如果可能,尽量在Python内部解决问题,或者考虑使用多线程/多进程来并行处理外部命令的调用。

2. 示例二:使用subprocess.run()函数来执行Shell命令

以下是一个更详细的代码示例,它展示了如何在Python中使用subprocess.run()函数来执行Shell命令(在这个例子中是ls -l),并处理可能出现的各种情况,包括成功执行、命令不存在、以及捕获标准输出和错误输出。

请注意,这个示例假设我们在一个Unix/Linux/macOS系统上运行,因为ls -l是这些系统的命令。如果我们在Windows上,我们可能需要替换为dir命令,并可能需要调整shell参数的使用(尽管通常建议避免使用shell=True以避免安全风险)。

import subprocess  

def run_command(command):
"""
执行给定的命令并返回其输出和返回码。 参数:
- command: 要执行的命令,作为列表传递(例如 ['ls', '-l']),以避免shell注入。 返回:
- output: 命令的标准输出(如果有的话)。
- error: 命令的错误输出(如果有的话)。
- returncode: 命令的返回码。
"""
try:
# 使用subprocess.run()执行命令
# capture_output=True表示捕获stdout和stderr
# text=True表示将输出作为文本处理(Python 3.7+)
result = subprocess.run(command, capture_output=True, text=True, check=True)
# 如果命令成功执行(没有异常),则返回其输出和返回码
return result.stdout, None, result.returncode
except subprocess.CalledProcessError as e:
# 如果命令执行失败(返回码非0),则捕获CalledProcessError异常
# 并返回错误输出、标准输出(如果有的话)和返回码
return None, e.stderr, e.returncode
except Exception as e:
# 捕获其他可能的异常(虽然在这个简单的例子中可能不太常见)
return None, f"An unexpected error occurred: {e}", None # 定义要执行的命令
command = ['ls', '-l'] # 执行命令并获取结果
output, error, returncode = run_command(command) # 根据返回的结果打印相应的信息
if output:
print("标准输出:")
print(output)
if error:
print("错误输出:")
print(error)
if returncode is not None:
print(f"返回码: {returncode}")
if returncode == 0:
print("命令成功执行。")
else:
print("命令执行失败。")

在这个示例中,run_command函数封装了subprocess.run()的调用,并处理了几种可能的情况:

(1)命令成功执行(返回码为0):返回标准输出、None作为错误输出,以及返回码。

(2)命令执行失败(返回码非0):捕获subprocess.CalledProcessError异常,并返回None作为标准输出、错误输出,以及返回码。

(3)其他异常情况:捕获并返回一条错误消息和None作为返回码(虽然在这个特定的例子中,由于subprocess.run()通常只抛出CalledProcessError,所以这部分可能不会被执行)。

请注意,subprocess.run()check=True参数会在命令返回非零退出码时自动抛出CalledProcessError异常,这使得我们可以在try-except块中捕获它。然而,在这个示例中,我选择了显式地捕获异常,以便能够更灵活地处理输出和返回码。如果我们只想在命令失败时抛出异常,并且不关心错误处理的具体细节,那么可以在调用subprocess.run()时设置check=True,并让Python的默认异常处理机制来处理它。

3. shell编程及shell命令

3.1 Shell编程

Shell编程是指使用Shell(也称为命令行解释器或命令行界面)作为编程语言来编写脚本的过程。Shell是Unix/Linux/macOS等类Unix操作系统中的一个特殊程序,它为用户提供了一个与操作系统交互的环境。Shell脚本是一系列Shell命令的集合,这些命令被编写在文本文件中,并通过Shell解释器执行,以实现自动化任务、批处理文件、管理系统资源等目的。

Shell脚本具有跨平台性,因为它们主要依赖于Shell的功能和命令,而这些在大多数类Unix系统中都是相似的。然而,不同的Shell(如Bash、Zsh、Fish等)可能有自己的特性和扩展,因此编写的脚本可能需要针对特定的Shell进行适配。

Shell编程通常包括变量定义、条件判断、循环控制、函数调用等编程元素,但与传统编程语言相比,Shell脚本的语法相对简单且灵活。

3.2 Shell命令

Shell命令是用户在Shell环境中输入的指令,用于执行各种操作,如文件管理、程序执行、系统管理等。Shell命令可以是Shell内置的,也可以是系统上的外部程序。

(1)内置命令:由Shell本身提供的命令,这些命令在Shell启动时就已经加载到内存中,因此执行速度较快。内置命令不依赖于系统上的其他程序,因此它们在系统启动时就已经可用。常见的内置命令包括cd(改变目录)、echo(显示信息)、exit(退出Shell)等。

(2)外部命令:也称为文件系统命令,这些命令是系统上独立的程序,通常位于/bin/usr/bin/sbin/usr/sbin等目录下。当Shell需要执行这些命令时,它会查找这些目录来找到对应的程序并执行。常见的外部命令包括ls(列出目录内容)、cp(复制文件或目录)、mv(移动或重命名文件或目录)等。

Shell命令可以通过管道(|)、重定向(><>>)、命令替换(command$(command))等机制进行组合,以实现更复杂的操作。例如,ls -l | grep '^d'命令会列出当前目录下所有目录的详细信息(ls -l列出详细信息,grep '^d'筛选出以d开头的行,即目录)。

Shell编程和Shell命令是Unix/Linux/macOS等系统用户日常工作中不可或缺的工具,它们能够极大地提高用户的工作效率,并帮助用户自动化地完成各种任务。

3.3 如何使用Shell编程

使用Shell编程主要涉及到编写Shell脚本,这些脚本包含了一系列的Shell命令,通过Shell解释器执行以实现特定的功能。以下是使用Shell编程的基本步骤:

3.3.1 选择Shell

首先,我们需要确定使用哪种Shell。常见的Shell有Bash(Bourne Again SHell,大多数Linux发行版的默认Shell)、Zsh(Z Shell,具有许多增强特性和更好的用户体验)、Fish(Friendly Interactive SHell,以用户友好和易于学习而著称)等。对于初学者来说,Bash是一个很好的起点,因为它广泛可用且文档丰富。

3.3.2 编写Shell脚本

Shell脚本通常保存在以.sh为扩展名的文件中。我们可以使用任何文本编辑器来编写Shell脚本,比如nanovimemacs或简单的echo和重定向。

以下是一个简单的Shell脚本示例,它打印出“Hello, World!”:

#!/bin/bash
# 这是一个简单的Shell脚本示例
echo "Hello, World!"

在脚本的第一行,#!/bin/bash被称为shebang,它告诉系统这个脚本应该使用哪个解释器来执行。在这个例子中,它指定了Bash。

3.3.3 保存脚本

将我们的脚本保存到文件中,例如hello.sh

3.3.4 赋予执行权限

在Linux或macOS上,我们需要给脚本文件赋予执行权限,以便能够直接运行它。我们可以使用chmod命令来做到这一点:

bash复制代码

chmod +x hello.sh

这个命令会给hello.sh文件添加执行权限。

3.3.5 运行脚本

现在,我们可以通过以下两种方式之一来运行我们的脚本:

直接通过脚本的路径和名称(如果脚本具有执行权限):

bash复制代码

./hello.sh

注意,我们需要使用./来指定脚本位于当前目录下。

使用Shell解释器来执行脚本(无论脚本是否具有执行权限):

bash复制代码

bash hello.sh

这个命令会告诉Bash解释器来执行hello.sh脚本中的命令。

python执行shell并获取结果的更多相关文章

  1. python执行shell获取硬件参数写入mysql

    最近要获取服务器各种参数,包括cpu.内存.磁盘.型号等信息.试用了Hyperic HQ.Nagios和Snmp,它们功能都挺强大的,但是于需求不是太符,亦或者太heavy. 于是乎想到用python ...

  2. python执行系统命令后获取返回值的几种方式集合

    python执行系统命令后获取返回值的几种方式集合 今天小编就为大家分享一篇python执行系统命令后获取返回值的几种方式集合,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧 第一种情 ...

  3. 利用python执行shell脚本 并动态传参 及subprocess基本使用

    最近工作需求中 有遇到这个情况  在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法   最后还是选择了subprocess这个python标准库 su ...

  4. 关于使用java执行shell脚本获取centos的硬盘序列号和mac地址

    1.获取硬盘序列号: 新建shell脚本文件: identifier.sh, 内容为: diskdata=`fdisk -l` diskleft=${diskdata#*"identifie ...

  5. python 执行shell命令

    1.os模块中的os.system()这个函数来执行shell命令 1 2 3 >>> os.system('ls') anaconda-ks.cfg  install.log  i ...

  6. python执行系统命令后获取返回值

    import os, subprocess # os.system('dir') #执行系统命令,没有获取返回值,windows下中文乱码 # result = os.popen('dir') #执行 ...

  7. python执行shell命令

    1 os.system 可以返回运行shell命令状态,同时会在终端输出运行结果 例如 ipython中运行如下命令,返回运行状态status os.system('cat /etc/passwdqc ...

  8. python执行shell实时输出

    1.使用readline可以实现 import subprocess def run_shell(shell): cmd = subprocess.Popen(shell, stdin=subproc ...

  9. python 执行shell

    一.import os ex: 1.os.system('ls') ----并不能得到返回值 2.output = os.popen('ls') res = output.read() ----能得到 ...

  10. Python记录-python执行shell命令

    # coding=UTF-8 import os def distcp(): nncheck = os.system('lsof -i:8020') dncheck = os.system('lsof ...

随机推荐

  1. C语言:渔夫捕鱼算法问题

    题目:渔夫捕鱼 A,B,C,D,E五个渔夫夜间合伙捕鱼,,第二天清A先醒来,他把鱼均分五份,把多余的一条扔回湖中,便拿了自己的一份回家了,B醒来后,也把鱼均分五份,把多余的一条扔回湖中,便拿了自己的一 ...

  2. 用 C 语言开发一门编程语言 — 语法解析器

    目录 文章目录 目录 前文列表 编程语言的本质 词法分析 语法分析 使用 MPC 解析器组合库 安装 快速入门 实现波兰表达式的语法解析 波兰表达式 正则表达式 代码实现 前文列表 <用 C 语 ...

  3. Springboot 项目集成 PageOffice V6 最简单代码

    本文描述了PageOffice产品在Springboot项目中如何集成调用.(本示例使用了Thymeleaf模板引擎) 新建Springboot项目:pageoffice6-springboot2-s ...

  4. webapi创建WCF WebService+WCF WebService远程服务调用

    首先需要引入soapcore包 这个包提供了所需的类和soap终结点中间件. 引入这个这个包之后,我们需要定义提供的服务. 这里我写了一个用于查询省份面积的服务. 省份信息服务 /// <sum ...

  5. 微信开发者工具拉取gitlab远程代码报Pull failed原因分析:

    可能出现的原因: 本地主机上没有安装node node下载地址: 1 https://nodejs.org/zh-cn/download/ 没有保存gitlab的用户名和密码

  6. Smart - Luogu —— 智能的洛谷

    @ 目录 安装 Stylus 谷歌 Edge 安装 Smart - Luogu 使用 尾声 安装 Stylus link 点击推荐下载,获取 crx 文件 谷歌 先点击右上角三个点,再点击扩展程序,然 ...

  7. RBD与Cephfs

    目录 1. RBD 1. RBD特性 2. 创建rbd池并使用 2.1 创建rbd 2.2 创建用户 2.3 下发用户key与ceph.conf 2.4 客户端查看pool 2.5 创建rbd块 2. ...

  8. Android OpenMAX(一)漫谈

    在开始正式的学习前,我们先来聊一聊Android音视频开发中的一些问题.感受与想法.(有一点要事先说明,我的问题与答案.想法并不一定正确,请读者带着审慎的思考来阅读,后续的文章也是一样,希望读者边阅读 ...

  9. 震惊!docker镜像还有这些知识,你都知道吗?----镜像(二)

    镜像查看 查看镜像 [root@hmm-docker ~]# docker images REPOSITORY#镜像仓库 TAG #标签 IMAGE ID#镜像id CREATED #创建时间 SIZ ...

  10. P7897

    problem && blog 第一道正经的 Ynoi,特此写篇题解纪念一下. Algorithm 1 可以想到 \(O(nm)\) 的 DP. 我们定义 \(dp_u\) 为 \(u ...