Python: execute command line instructions

Introduction

In python, there are three commonly used ways to call an external command line (shell in linux, or cmd in windows) to execute instructions:

  • os.system(‘pwd’);
  • os.popen()
  • subprocess.Popen()

os.system

It is the most basic part of the os module, and other methods are generally derived from this method.

When each os.systeminstruction is executed, a sub-process will be created to execute the command on the system, and the execution result of the sub-process cannot affect the main process;

The above principle will lead to the failure to get the desired results when multiple command lines need to be executed, for example:

import os

os.system('cd /home/xxx/')
os.mkdir('1.txt')

After execution, you will find that the txt file is not created in the /home/xxx/ folder, but created locally, because multiple commands are independent.

In order to ensure that the system can execute multiple commands successfully, multiple commands need to os.systembe executed in one, but they need to be separated by special separators, such as:

import os

os.system('cd /home/xxx/ && mkdir 1.txt')
os.system('cd /home/xxx/ ; mkdir 1.txt')
  • The semicolon means that these commands will be executed sequentially;

  • && means to execute sequentially, and stop when encountering an execution error command;

  • || indicates that the command is executed sequentially, and stops when the command is successfully executed, and will not be executed later;

os.systemAnother disadvantage is that its return value is only 0 (success), 1,2. Other pwdinstructions will print out the execution result, but this result is printed internally, not in the form of a return value, and we can't get it at all. For example:

import os
a=os.system('pwd')
print(a)

output:

/home/ttss
0

If this problem is intolerable, consider usingos.popen()

os.popen

os.popen()It is to open a pipeline to execute the command, and write the execution result of the command to a file object as the return value.

Call format:

os.popen(command, mode, bufsize)

command is the command to be executed, and the latter two commands are optional;

mode, indicates the mode permission, r or w, the default is r;

bufsize, specifies the buffer size required by the file. 0 means no buffering, 1 means line buffering; other positive values ​​mean using the buffer of the parameter size, in bytes; negative values ​​mean using the system's default value. can use the default

import os

a=os.popen('pwd', 'r').readlines()
print a

# 输出:
# ['/et/ttss\n']

We can continue to operate on the returned file object.

There are two places to pay attention to here:

  • close the file object;
  • set blocking

The returned file object needs to be closed, so the standard way of writing is to use it in the with statementos.popen

with os.popen(command, 'r') as p:
    r = p.read()

There is no need to manually writep.close()

And the above method also has the advantage, that is, read()the characteristics of the use block the main process , and only after the child process has finished running can it continue to execute downward.

But this also brings a disadvantage, the main process will be completely stuck, and the main process will not readsucceed until the child process finishes running, and then continue to execute. So if the child process can never end, then the main process will always be stuck like this. . .

For example ping 127.0.0.1, the default is always executed, and then we:

import os

with os.popen('ping 127.0.0.1', 'r') as p:
        for i in p.readlines():
                print(i)
print('执行完成')

After execution, the foreground will be stuck all the time, and there will be no output, because the sub-process has not ended, so the main process will not get any return value. . . .

Except that this place is quite tricky, popen()it is still relatively easy to use, just pay attention to it yourself, and never execute commands that cannot be exited, or commands that need to enter interactive mode.

subprocess.Popen()

The most feature-rich way is generally recommended to use this.

But it is still not possible to output while the child process is executing.

Compared with the feeling os.popen(), the newly added functions are limited, that is, they can interact with the child process. If you don’t pursue this too much, then you can also choose to useos.popen()

The new functions of subprocess are:

  • wait(): Manually block the main process, wait for the child process to return, and then execute the following code;
from subprocess import Popen, PIPE

p = Popen('sleep 100', stdout=PIPE, shell=True)
p.wait()
print('End')
  • pid(): Return the PID of the child process;
from subprocess import Popen, PIPE
p = Popen('sleep 100', stdout=PIPE, shell=True)
print(p.pid)
  • poll(): Check whether the child process has been successfully executed, return None if it is not finished, and return a status code if it is finished.This is very useful
#-*- coding:utf-8 -*-

import time
from subprocess import Popen, PIPE

p = Popen('sleep 100', stdout=PIPE, shell=True)

while True:
    if p.poll() == None:
        print('程序执行中...')
        time.sleep(1)
    else:
        print('程序执行完毕, 状态码为:%s' % p.poll())
        break
  • returncode(): Returns the status code after the command is executed. p.poll()However, the returnCode is not refreshed in real time. It is not refreshed every time it is called, but it will be refreshed after it is explicitly executed once .

  • kill(): kill child process
from subprocess import Popen, PIPE

p = Popen('sleep 100', stdout=PIPE, shell=True)
print(p.pid)
p.kill()
  • terminal(): terminate the child process, kill()similar to
from subprocess import Popen, PIPE

p = Popen('sleep 100', stdout=PIPE, shell=True)
print(p.pid)
p.terminate()
  • communicate(): Used to interact with the child process, return a tuple, including stdout, stderr;
from subprocess import Popen, PIPE

p = Popen('cat', stdin=PIPE, stdout=PIPE, shell=True)
print(p.communicate('hello world'))
  • stdout.readlines(): read stdout, all at once
from subprocess import Popen, PIPE

p = Popen('ls /home', stdout=PIPE, shell=True)
for line in p.stdout.readlines():
    print(line)

references

  1. os.system function based on python
  2. os.popen() in python
  3. The python os.popen() method is well written
  4. Overview of os.system() and os.popen()
  5. subprocess.Popen() common method is great
  6. python – subprocess.Popen() multiprocess

Guess you like

Origin blog.csdn.net/wlh2220133699/article/details/131411260