python学习笔记07:系统命令&环境变量

1. 使用subprocess.Popen()

调用命令:

import subprocess  
proc=subprocess.Popen(  
    'ls .vim*',            # 待执行的命令  
    shell=True,            # 使用shell  
    cwd='/home/g00444054', # 到这个目录去执行命令  
    stderr=subprocess.PIPE,# 执行命令后的报错信息送到pipe(默认打印到stderr)  
                           # 可以通过p.stderr访问该pipe内容;  
    stdout=subprocess.PIPE,# 执行命令后的输出信息送到pipe(默认打印到stdout)  
                           # 可以通过p.stdout访问该pipe内容  
)  

等待子进程结束;

使用wait()等待子进程结束,有可能导致死锁,不建议使用wait(), 建议使用communicate()

print(proc.returncode) # 如果为None,表示子进程还未结束
p.wait() # 等待子进程结束,但PIPE太大时它可能导致死锁。
~~print(proc.returncode) # 为0,表示子进程正常退出 ~~

建议使用communicate()等待子进程结束,不会死锁。

print(proc.returncode) # 如果None,表示子进程还未结束  
b_stdout, b_stderr = proc.communicate() # 等待子进程结束,返回bytes  
print(proc.returncode) # 为0,表示子进程正常退出  

查看命令的标准输出:

# b_stdout是二进制str, 需要decode, windows下使用gbk  
for s_line in b_stdout.decode('gbk').strip().split('\n'):  
    print(s_line)  
.viminfo  
.vimrc  
  
.vim  
plugin  
syntax  

查看命令的标准错误

for s_line in b_stderr.decode('gbk').strip().split('\n')  
    print(s_line)  
#如果cmd改成dir .vimx*,s_line就是:  
#找不到文件  

另外, 在proc.communicate()前可以通过proc.stdout/proc.stderr来获取stdout和stderr, 但proc.communicate()后会报告io buffer已经关闭了(它们是被当作io对象来访问的).

for b_line in proc.stdout:   
    print(b_line.decode('gbk').strip())  
  
for b_line in proc.stderr:  
    print(b_line.decode('gbk').strip())  

2. 使用os.system和os.popen

os.system(cmd)可以得到cmd的返回值(即shell的exit值),而不是命令的输出

>>> value = os.system('ls') #会在Termianl打印命令的输出
file0 dir0
file1 dir1
>>> value #value得到的是命令的返回值,即shell的exit值,而不是命令的输出;
0

os.popen()可以得到命令的输出,返回执行后的信息对象, 通过管道将结果返回;
语法: os.popen(command, [, mode, buffering])
参数1:command :调用的命令;
参数2:mode :返回file对象的模式,默认为"r",只读模式;
参数3:buffering:缓冲区大小,默认-1,无限制;

>>> pipeline = os.popen('ls')
>>> for line in pipeline.readlines():
...     print(line.strip())
...
dir0
dir1
file0
file1

3. 获取系统平台名

Windows对应'nt',Limux/Unix对应'posix';

>>> os.name
'posix'

4. 获取用户名

>>> import getpass
>>> getpass.getuser()
'g004440**'

5. 操作环境变量

5.1. os.environ

>>> import os
>>> type(os.environ)
<class 'os._Environ'>
>>>
>>> for k, v in os.environ.items(): # 可以把os.environ当作dict访问
...     print('{k:<10} = {v}'.format(k=k, v=v))
...
LANG= C
USER= g004440**
HOME= /home/g004440**
...
>>> os.environ['USER'] # 直接通过key查变量值
'g004440**'
>>> os.environ.get('USER') # 使用get()通过key查变量值
'g004440**'
>>> os.environ['CELL_CNT'] # 查不存在的key会报错
KeyError: 'CELL_CNT'
>>> os.environ.get('CELL_CNT', 0) # 通过get()指定返回值,默认为None
0
>>> os.environ['CELL_CNT'] = str(99) # 通过赋值运算修改或添加环境变量,int会报错
>>> os.environ['CELL_CNT'] # CELL_CNT环境变量已经添加
'99'
>>> os.environ.get('CELL_CNT', 0) # 使用get()也可以得到
'99'

5.2. os.getenv()、os.putenv()

注意:通过putenv()设置的环境变量,使用getenv()无法获取,使用os.environ[]也无法获取(即没有修改os.environ的值),它只能是默默地修改了环境变量?
os.getenv(key, default=None) 获取环境变量
os.putenv(name, value, /) 设置环境变量name=value,value必须是str、bytes或os.PathLike obj,不能是int
 
>>> import os
>>> os.getenv('USER') # 获取环境变量'USER'
'g004440**'
>>> os.getenv('CELL_CNT', 0) # 获取不存在的环境变量,指定返回值
0
>>> os.putenv('CELL_CNT', str(99))
>>> os.getenv('CELL_CNT', 0) # putenv()设置的key,不能使用getenv()获得
0
>>> os.environ.get('CELL_CNT', 0) # os.environ也没有改变
0

6. 修改python搜索模块的路径集

sys.path是一个list,内容为python搜索模块的路径;

  1. 临时修改:可以在python程序中修改sys.path: sys.path.append('xxx'),但程序退出后这个修改会消失。
  2. 固定修改:如果要永久地修改sys.path,需要设置PYTHONPATH这个环境变量,不同路径使用冒号分开;
>>> import sys
>>> [print(f'"{x}"') for x in sys.path]
""
"/data/XX/code/lib/python"
"/software/xx/lib/python3.6"

7. 标准输入、标准输出、标准错误

7.1. sys.stdin()

sys.stdin.readline()与input()的区别

>>> import sys
>>> s0 = input('Enter string 0: ') # python2中是raw_input()
Enter string 0: abc # 获取用户输入
>>> s0 # input()函数会去掉换行符
'abc'
>>>
>>> s1 = sys.stdin.readline() # 这里不能给str参数,它的参数是str长度;
abc
>>> s1 # 会将换行符一并获取
'abc\n'
>>> s2 = sys.stdin.readline()[:-1] # 切片,去掉最后一个元素
abc
>>> s2 # s2结尾没有换行符,已经去掉;
'abc'

7.2. sys.stdout()

sys.stdout.write()与print()的区别
>>> import sys
>>> print('abc')
abc
>>> n = sys.stdout.write('abc'+'\n') # 函数返回string的长度
abc
>>> n
4
>>> n= sys.stdout.write('abc' + os.lineseq) # 打印后加换行
abc
>>> os.linesep
'\n'
os.linesep获取当前平台的行终止符,str类型,Windows使用'\r\n',Linux使用'\n',Mac使用'\r'

使用sys.stdout.flush(),把写缓冲区的内容冲到标准输出,不然不能实时显示内容

>>> import sys, time
>>> for i in range(5):
...     for j in range(5):
...         time.sleep(0.5)
...         print('*', end='')
...         sys.stdout.flush() # flush write buffers,在print后使用
...     print('')
...
*****
*****
*****
*****
*****

7.3. sys.stderr()

可以把print的内容输出到标准输出

>>> import sys
>>> print('abc', sys.stderr)
abc <_io.TextIOWrapper name='<stderr>' mode='w' encoding='ANSI_X3.4-1968'>
posted @ 2020-07-03 10:45  编程驴子  阅读(331)  评论(0编辑  收藏  举报