# 导读

在编程开发过程中,有时候难免会需要调用系统下的 Shell 命令来辅助完成一些相关的操作,那么在 Python 编程开发中如何才能调用系统下的shell呢?

以下提到的方法均适合调用 windows 下的 shell 命令,也适合调用 Linux 下的 shell 命令操作。

# os 模块

## system( ) 方法

说明:system( )方法会创建子进程并将指定命令传至其(shell)运行,最终返回执行后的效果(与正常执行类似)。

```python
>>> os.system('echo "hello world!"') # 调用shell下的 echo 命令
hello world!
0
>>> os.system('ls -lh') # 查看目录下文件的相关信息
total 4.0K
drwxr-xr-x 2 root root 4.0K Aug 3 14:04 test
-rw-r--r-- 1 root root 0 Aug 3 14:05 wechat.txt
0
>>>
```

## popen( ) 方法

说明:该方法返回的是一个类文件对象,并不会实时输出执行效果,如果需要读出其内容,只需使用 `read( )` 或 `readlines( )` 方法即可完成。

常见调用:

```python
a = os.popen("commands").read()
b = os.popen("commands").readlines()
```

当需要得到外部shell程序的输出结果时,本方法非常有用。

演示:

```python
>>> os.popen('ls') # 返回一个对象

>>> os.popen('ls').read() # 读取对象内容
'test\nwechat.txt\n'
>>>
>>> a = os.popen('pwd') # 获取当前工作路径
>>> a

>>> a.readlines() # 读取内容
['/root/abc\n']
>>>
```

注:其 `\n` 是由于换行引起的。

# commands 模块

使用commands模块的getoutput方法,这种方法同popend的区别在于popen返回的是一个类文件对象,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
主要方法:

> - commands.getstatusoutput(“cmd”) # 返回(status, output)
> - commands.getoutput("cmd") # 只返回输出结果
> - commands.getstatus("file") # 返回ls -ld file的执行结果字符串,调用了getoutput,不建议使用此方法

实例演示:

```python
>>> import commands
>>> commands.getstatusoutput('ls -lt') # 返回(status, output)
(0, 'total 5900\n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.sh\n-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log')
>>> commands.getoutput('ls -lt') # 返回命令的输出结果(貌似和Shell命令的输出格式不同哈~)
'total 5900\n-rwxr-xr-x 1 long long 23 Jan 5 21:34 hello.sh\n-rw-r--r-- 1 long long 147 Jan 5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log'
>>> commands.getstatus('log') # 调用commands.getoutput中的命令对'log'文件进行相同的操作
'-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log'
>>>
```

# subprocess模块

根据Python官方文档说明,subprocess模块是用于取代上面这些模块。

有一个用Python实现的并行ssh工具—`mssh`,代码很简短,不过很有意思,它在线程中调用subprocess启动子进程来执行。

实例演示:

```python
>>> from subprocess import call # 导入模块
>>> call(["ls", "-l"]) # 调用
total 4
drwxr-xr-x 2 root root 4096 Aug 3 14:04 test
-rw-r--r-- 1 root root 0 Aug 3 14:05 wechat.txt
0
>>>
```

**subprocess** 与 **system( )** 相比的优势是它更灵活(你可以得到标准输出,标准错误,“真正”的状态代码,更好的错误处理,等..),也是未来灵活运用的一个发展趋势。

# 相关技术文档

下面是对于文中所涉及的内容的python官方文档:

> 1. [os的exec方法族以及system方法](http://docs.python.org/lib/os-process.html)
> 2. [popen()方法使用介绍](http://docs.python.org/lib/os-newstreams.html)
> 3. [subprocess使用介绍](http://docs.python.org/lib/node528.html)
> 4. [关于使用subprocess 替代老的方法](http://docs.python.org/library/subprocess.html#replacing-older-functions-with-the-subprocess-module)

最后修改:2021 年 04 月 03 日
如果觉得我的文章对你有用,请随意赞赏