Executing System Commands in Python

 
Executing system commands in Python can be done using the os and subprocess modules. These modules allow you to run shell commands from within your Python code, which can be useful for tasks such as file handling, system administration, and automation.

https://www.digitalocean.com/community/tutorials/python-system-command-os-subprocess-call 

Python System Command

While making a program in python, you may need to exeucte some shell commands for your program. For example, if you use Pycharm IDE, you may notice that there is option to share your project on github. And you probably know that file transferring is done by git, which is operated using command line. So, Pycharm executes some shell commands in background to do it. However, In this tutorial we will learn some basics about executing shell commands from your python code.

Python os.system() function

We can execute system command by using os.system() function. According to the official document, it has been said that

This is implemented by calling the Standard C function system(), and has the same limitations.

However, if command generates any output, it is sent to the interpreter standard output stream. Using this command is not recommended. In the following code we will try to know the version of git using the system command git --version.

 
import os

cmd = "git --version" returned_value = os.system(cmd) # returns the exit code in unix print('returned value:', returned_value)

The following output found in ubuntu 16.04 where git is installed already.

 
git version 2.14.2
returned value: 0

Notice that we are not printing the git version command output to console, it’s being printed because console is the standard output stream here.

Python subprocess.call() Function

In the previous section, we saw that os.system() function works fine. But it’s not recommended way to execute shell commands. We will use Python subprocess module to execute system commands. We can run shell commands by using subprocess.call() function. See the following code which is equivalent to the previous code.

 
import subprocess

cmd = "git --version"

returned_value = subprocess.call(cmd, shell=True)  # returns the exit code in unix
print('returned value:', returned_value)

And the output will be same also.Python System Command

Python subprocess.check_output() function

So far, we executed the system commands with the help of python. But we could not manipulate the output produced by those commands. Using subprocess.check_output() function we can store the output in a variable.

 
import subprocess

cmd = "date"

# returns output as byte string
returned_output = subprocess.check_output(cmd)

# using decode() function to convert byte string to string
print('Current date is:', returned_output.decode("utf-8"))

It will produce output like the following

 
Current date is: Thu Oct  5 16:31:41 IST 2017

So, in the above sections we have discussed about basic ideas about executing python system command. But there is no limit in learning. If you wish, you can learn more about Python System command using subprocess module from official documentation.

 

 

在Python中,os和subprocess模块都可以用于执行系统命令,但它们有一些重要的区别。

os模块

os.system() 是os模块中最基础的方法之一。它用于在子进程中执行系统命令,并返回命令的退出状态码。使用os.system()时,Python会创建一个子进程来执行命令,父进程会等待子进程完成后再继续执行。

import os
os.system('ls -l')
 
os.popen() 方法则用于打开一个管道,通过该管道可以与子进程进行通信。它返回一个文件对象,可以读取或写入子进程的标准输入输出。
import os
p = os.popen('ls -l')
output = p.read()
p.close()
print(output)
 

subprocess模块

subprocess 模块是在Python 2.4中引入的,用于替代os.system、os.spawn、os.popen等方法。它提供了更强大的功能和更灵活的接口。

subprocess.run() 是推荐使用的方法,它可以执行命令并返回一个CompletedProcess实例,包含命令的返回码、输出和错误信息。

import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
 
subprocess.Popen() 提供了更底层的接口,可以更灵活地控制子进程的输入输出和执行过程。
import subprocess
p = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
output, error = p.communicate()
print(output.decode())
 

主要区别

  1. 功能和灵活性:subprocess模块提供了更强大的功能和更灵活的接口,可以更好地控制子进程的执行和输入输出。而os模块的方法相对简单,功能有限。

  2. 返回值:os.system() 只返回命令的退出状态码,而subprocess.run() 可以返回命令的输出、错误信息和退出状态码。

  3. 安全性:subprocess模块可以避免shell注入攻击,因为它可以直接传递命令和参数,而不需要通过shell解释。

总的来说,subprocess 模块是执行系统命令的更好选择,特别是在需要处理命令输出或错误信息的情况下。

 
 

Python subprocess中’shell=True’的实际含义

  • 将 ​shell=True​ 传递给 ​subprocess.run​ 时,Python 会通过操作系统的 ​shell​(Linux 通常为 ​​/bin/sh,Windows 通常为 ​cmd.exe)来解析并执行传入的命令字符串。此时可以把命令写成一个字符串,由 shell 负责分词、解析重定向、管道、通配符等;

  • 若 ​shell=False​(默认),命令应以参数列表形式传入,且不会经过 shell 解析。

 

在本文中,我们将介绍Python subprocess模块中’shell=True’参数的实际含义。subprocess模块是Python中用于执行外部命令的标准库之一。它允许我们在Python程序中启动新的进程,与其进行交互,并获取其输出。

在使用subprocess模块时,常常会遇到’shell=True’参数。这个参数的作用是告诉subprocess模块在执行命令时使用shell来解释命令。换句话说,使用’shell=True’参数时,你可以像在命令行中一样执行命令,包括使用管道、重定向、通配符等shell特性。让我们通过一些示例来理解’shell=True’的实际含义。

 

示例2: 使用管道和重定向

接下来,让我们看一个复杂一点的示例。假设我们需要执行一个包含管道和重定向的命令,比如统计一个文件中行数并将结果保存到另一个文件。在没有’shell=True’参数的情况下,我们可以这样使用subprocess模块来实现:

import subprocess

with open('input.txt', 'r') as file:
    result = subprocess.run(['wc', '-l'], input=file.read().encode(), capture_output=True)
    with open('output.txt', 'w') as output_file:
        output_file.write(result.stdout.decode())
Python
 

这段代码会读取文件’input.txt’的内容并将其作为命令’wc -l’的输入,然后将结果写入文件’output.txt’。

而如果我们添加’shell=True’参数,代码如下所示:

import subprocess

result = subprocess.run('wc -l < input.txt > output.txt', capture_output=True, shell=True)
Python
 

这次我们将整个命令’wc -l < input.txt > output.txt’作为一个字符串传递给subprocess.run()函数,并设置’shell=True’。这样一来,我们可以直接使用管道和重定向符号来完成命令的操作,而不需要将其拆分为列表形式。

通过这个示例可以看出,使用’shell=True’参数可以更方便地处理包含管道、重定向等shell特性的命令。

示例3: 使用通配符

最后,让我们看一个使用通配符的示例。假设我们需要执行一个命令,统计指定目录下所有文件的行数。在没有’shell=True’参数的情况下,我们可以这样使用subprocess模块来实现:

import subprocess

result = subprocess.run(['wc', '-l', 'path/to/files/*'], capture_output=True)
print(result.stdout.decode())
Python
 

这段代码会执行命令’wc -l path/to/files/‘,’‘代表通配符,可以匹配指定目录下的所有文件。

而如果我们添加’shell=True’参数,代码如下所示:

import subprocess

result = subprocess.run('wc -l path/to/files/*', capture_output=True, shell=True)
print(result.stdout.decode())
Python
 

这次我们可以直接将命令’wc -l path/to/files/*’作为一个字符串传递给subprocess.run()函数,并设置’shell=True’。这样一来,可以直接使用通配符,而无需将其放入列表中。

通过这个示例可以看出,使用’shell=True’参数可以更方便地在命令中使用通配符和其他shell扩展。

 

三、PEXPECT库

 

pexpect是一个第三方库,用于自动控制和交互外部程序,尤其适用于需要模拟用户输入的场景。它可以用来控制交互式应用程序,如ssh、ftp等。

 

 

1、安装pexpect

 

 

首先,你需要安装pexpect库,可以使用pip来安装:

 

 

pip install pexpect

 

 

 

2、使用pexpect

 

 

下面是一个使用pexpect控制ssh登录的示例:

 

 

import pexpect

 

child = pexpect.spawn('ssh user@hostname')

child.expect('password:')

child.sendline('your_password')

child.expect('$')

child.sendline('ls -l')

child.expect('$')

print(child.before.decode())

child.close()

 

 

在这个示例中,pexpect.spawn启动了一个ssh进程,并通过expect函数等待密码提示,随后使用sendline函数发送密码。之后,程序等待shell提示符,并发送ls -l命令,最后打印输出结果。

 

 

3、处理多种情况

 

 

pexpect还可以处理多种情况,通过使用expect的正则表达式功能,可以等待多个不同的提示符或输出。

 

 

import pexpect

 

child = pexpect.spawn('ftp hostname')

index = child.expect(['Name .*:', 'Unknown host'])

if index == 0:

child.sendline('username')

child.expect('Password:')

child.sendline('password')

child.expect('ftp>')

child.sendline('ls')

child.expect('ftp>')

print(child.before.decode())

else:

print("Unknown host")

child.close()

 

 

在这个示例中,pexpect等待两个可能的输出:“Name .*:”或“Unknown host”。如果匹配第一个提示符,程序继续登录ftp服务器;否则,打印“Unknown host”并退出。

posted on 2025-10-24 10:18  ENGINEER-F  阅读(8)  评论(0)    收藏  举报