---
title: "Python 调用 Shell 命令"
date: 2019-10-30T17:44:22+08:00
lastmod: 2019-11-03T17:12:00+08:00
tags: ["python", "shell"]
categories: ["python"]
---

## os
- 阻塞，返回shell执行参数命令的状态,即成功返回0
    ```python
    os.system('cat /proc/cpuinfo')
    ```
- 阻塞，返回file read的对象，对该对象进行 read() 可以获取shell执行参数命令的结果，即标准输出
    ```python
    os.popen('cat /proc/cpuinfo')
    ```

## commands
- 阻塞，返回参数指定的系统文件的详细属性
    ```python
    commands.getstatus('/proc/cputinfo')
    ```
- 阻塞，返回shell执行参数命令的结果
    ```python
    commands.getoutput('cat /proc/cpuinfo')
    ```
- 阻塞，返回shell状态和shell输出的元组(status, output)
    ```python
    commands.getstatusoutput('cat /proc/cpuinfo')
    ```

## subprocess
- 阻塞，返回shell状态，禁用 PIPE 参数
    ```python
    subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
    ```
- 阻塞，shell 执行成功返回0, 否则无返回，并抛出包含shell错误状态的 CalledProcessError 异常，禁用PIPE参数
    ```python
    subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
    ```
- 阻塞，shell 执行成功返回shell结果，否则无返回，并抛出包含shell错误状态的 CalledProcessError 异常，禁用PIPE参数
    ```python
    subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
    ```

## Pope
- 不阻塞，返回Popen对象
```python
subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
```
- subprocess 参数:
    - args: 字符串或列表（*nix 下第一项视为命令，后面是命令参数）
    - bufsize: 默认 0 不缓冲，1 行缓冲，其他正数表示缓冲大小，负数表示使用系统默认全缓冲
    - stdin stdout stderr: subprocess.PIPE 表示管道操作，subprocess.STDOUT 表示输出到标准输出
    - preexec_fn: *nix 下子进程被执行前调用
    - shell: True 时表示指定命令在shell里解释执行
    - subprocess.PIPE: 用于stdin、stdout 和 stderr ，表示创建并写入一个管道
    - subprocess.STDOUT: 用于 stderr，表示标准错误重定向到标准输出
- Popen 对象属性:
    - Popen.poll(): 检查子进程是否结束，0 表示退出
    - Popen.wait(): 等待子进程结束，注意子进程是否写管道
    - Popen.communicate(input=None): 与子进程交互，字符串数据发送到stdin，并从stdout和stderr读数据，知道EOF，等待子进程结束。注意读写stdin、stdout或stderr时要给定PIPE参数。返回元组(stdoutdata, stderrdata)。
    - Popen.send_signal(signal): 给子进程发送信号
    - Popen.terminate(): 停止子进程
    - Popen.kill(): 杀死子进程
    - Popen.stdin Popen.stdout Popen.stderr: PIPE参数时为文件对象，否则None
    - Popen.pid: 子进程的进程号
    - Popen.returncode    None表示子进程没终止，负数-N表示子进程被N号信号终止

