4

【Python】sys&os&subprocess

 3 years ago
source link: https://www.guofei.site/2018/06/05/sysos.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【Python】sys&os&subprocess

2018年06月05日

Author: Guofei

文章归类: Python语法 ,文章编号: 1204


版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2018/06/05/sysos.html

Edit

sys

sys.argv # 是一个由str组成的list,包含所有的命令行参数.
# 例如 python abc.py a c,那么 sys.argv= ['abc.py', 'a', 'c']

sys.stdout, sys.stdin sys.stderr # 分别表示标准输入输出,错误输出的文件对象.
sys.stdin.readline()  # 从标准输入读一行
sys.stdout.write("a") # 屏幕输出a

sys.exit(exit_code) # 退出程序
sys.modules # 是一个dictionary,表示系统中所有可用的module
sys.version # python 版本
sys.platform # 操作系统环境.
# Linux (2.x and 3.x): 'linux2'; Windows: 'win32'; Windows/Cygwin 'cygwin'; Mac OS X : 'darwin'; OS/2: 'os2'; OS/2 EMX: 'os2emx'; RiscOS: 'riscos'; AtheOS: 'atheos'

import sys
sys.path # 是一个list,指明所有查找module,package的路径.
sys.path.append('E:\\MyPython') # 把目录添加到path,这样就可以 import 了

观察引用计数的小程序

import sys

a='abc'
print(id(a))
print(sys.getrefcount(a))
b='abc'
id(b)
print(sys.getrefcount(a))

OS

增删改

os.chdir(path) # 把path设定为当前目录,例如os.chdir('d:\\outlook') 注意windows下用到转义
os.getcwd() # 获得当前工作目录
os.listdir(path) # 返回指定目录下所有文件和目录名

os.mkdir(path) # 新建目录,父目录必须存在的,否则报错。目录存在时也报错
os.makedirs(path) # 新建目录(递归创建,所以没有父目录也可以)。目录存在时报错

os.rmdir(path) # 删除目录。前提是目录为空,否则报错
os.remove(path) # 删除文件

os.rename(oldname,newname) #更改文件名。因为参数可以带路径,所以也可以用来移动到其它文件夹

特殊常量

os.curdir  # 当前目录 '.'
os.pardir  # 上一级目录 '..'
os.sep  # 路径分隔符 win下是'\\' Linux 下为'/'
os.linesep  # 终止符 win下是'\r\n',Linux 下为 '\n'
os.name  # 当前操作系统 ('posix','nt','mac','os2','ce','java')

os.path

可以用来编写平台无关的程序


os.path.isfile(path) # 如果 path 是文件且存在,返回 True
os.path.isdir(path) # 如果 path 是路径且存在,返回 True
os.path.exists(path) # 判断路径是否存在
os.path.islink(path) # 是否是符号链接(快捷方式)
os.path.ismount(path) # 是否是挂载点

os.path.dirname(path) # 返回path中的路径部分
os.path.basename(path) # 返回path中的文件名部分
os.path.split(path) # 返回一个tuple,分离目录名和文件名
os.path.join(path,name) # 把path和name合成
os.path.splitext(path) # 返回一个tuple,分别是含目录的文件名和扩展名


os.path.getsize(path) # 返回文件大小


a = os.path.getatime('E:\\pathname\\filename.txt')  # 浮点数时间, 最新访问时间
b = os.path.getctime('E:\\pathname\\filename.txt')  # 浮点数时间, 创建时间
c = os.path.getmtime('E:\\pathname\\filename.txt')  # 浮点数时间, 修改时间
import time
time.gmtime(a) # 转化为格林威治时间
time.localtime(a)  # 转化为当地时间


# 用os.path
os.path.abspath("1.txt") == os.path.join(os.getcwd(), "1.txt")
os.path.split(os.getcwd()) # 用于分开一个目录名称中的目录部分和文件名称部分。
os.path.join(os.getcwd(), os.pardir, 'a', 'a.doc') # 全成路径名称.
os.pardir 表示当前平台下上一级目录的字符 ..
os.path.getctime("/root/1.txt")  返回1.txt的ctime(创建时间)时间戳
os.path.exists(os.getcwd()) 判断文件是否存在
os.path.expanduser('~/dir') 把~扩展成用户根目录
os.path.expandvars('$PATH') 扩展环境变量PATH
os.path.isfile(os.getcwd()) 判断是否是文件名,1是0否
os.path.isdir('c:\Python26\temp') 判断是否是目录,1是0否
os.path.islink('/home/huaying/111.sql') 是否是符号连接 windows下不可用
os.path.ismout(os.getcwd()) 是否是文件系统安装点 windows下不可用
os.path.samefile(os.getcwd(), '/home/huaying') 看看两个文件名是不是指的是同一个文件

os.environ # 一个dictionary 包含环境变量的映射关系 os.environ["HOME"] 可以得到环境变量HOME的值

os.getegid() # 得到有效组id  os.getgid() 得到组id
os.getuid() # 得到用户id  os.geteuid() 得到有效用户id
os.setegid os.setegid() os.seteuid() os.setuid()
os.getgruops() # 得到用户组名称列表
os.getlogin() # 得到用户登录名称
os.getenv # 得到环境变量
os.putenv # 设置环境变量
os.umask # 设置umask
os.system(cmd) 利用系统调用,运行cmd命令
操作举例:

用Python来模拟shell

#!/usr/bin/python
import os, sys
cmd = sys.stdin.readline()
while cmd:
    os.system(cmd)
    cmd = sys.stdin.readline()

os.walk(path)

for root,dirs,files in os.walk("D:\py\d1218"):
    pass


path_walker=os.walk("D:\py\d1218", topdown=True) # 返回一个generator
# (1)参数top表示需要遍历的顶级目录的路径。
# (2)参数topdown的默认值是“True”表示首先返回顶级目录下的文件,然后再遍历子目录中的文件。当topdown的值为"False"时,表示先遍历子目录中的文件,然后再返回顶级目录下的文件。
# (3)参数onerror默认值为"None",表示忽略文件遍历时的错误。如果不为空,则提供一个自定义函数提示错误信息后继续遍历或抛出异常中止遍历。

for top, dirs, nondirs in path_walker:
    pass
# top是一个str,是当前遍历的目录(绝对目录)
# dirs是一个list,是当前遍历的目录下面的目录
# nondirs是一个list,是当前遍历的目录下面的文件名

运行CMD命令

import os
# os.system("ipconfig")
p=os.popen('ipconfig')
print(p.read())
tar = tarfile.open('rt-polaritydata.tar.gz', "r:gz")
tar.extractall(path='temp')
tar.close()

subprocess

os.system 在使用上有一定的局限性,可以用 subprocess 来代替

1. subprocess.call

返回args执行完毕后的 return code

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) # 返回int
# 参数args描述了子进程中需要执行的命令
# cmd = ['ls', '-l']
# cmd = ['exit 1']
# ret = subprocess.call(cmd)
# shell=True时,可以把文本分解成多条命令执行。不安全,所以尽量使shell=False。PS:windows下,False似乎会出错

stdout和stderr

注意不要为stdout和stderr参数赋值subprocess.PIPE,如果子进程输出量较多会造成死锁,这两个参数可以赋值为subprocess.STDOUT打印到屏幕或者赋值为一个文件对象将输出写入文件

//test.py
import subprocess as sp
sp.call('python run.py', shell = True, stdin=open('fake_input', 'r'), stdout=open('result', 'w'))
//run.py
i = int(raw_input("Input a number:"))
print("You input number:", i)

CalledProcessError的使用

import subprocess
try:
    res = subprocess.check_call(['ls', '('])
    print('res:', res)
except subprocess.CalledProcessError as exc:
    print('returncode:', exc.returncode)
    print('cmd:', exc.cmd)
    print('output:', exc.output)

2. subprocess.check_call

  • 如果args执行之后的 return code 为0,那么 check_all 返回0;
  • 如果 returncode 不为 0,那么没有返回值,而是raise出来一个 <CalledProcessError>
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) # 返回int
cmd1 = ['exit 1'] # 将会报错
ret = subprocess.check_call(cmd2, shell=True)

3. subprocess.check_output

  • 把命令的输出作为字符串返回,
  • 如果 returncode 不为 0, 那么将raise一个 <CalledProcessError>
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False) # 返回str,内容是命令所输出的字符串

4. subprocess.Popen

Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block)

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) # 返回一个对象,可以对这个对象继续操作
# args 字符串或列表
# bufsize 0:无缓冲。正整数:缓冲大小。负:系统默认缓冲(一般是全缓冲)
# shell Unix下,相当于args前面添加了'/bin/sh' '-c'  windows下,相当于添加'cmd.exe /c'
# env 设置环境变量
# universal_newlines 各种换行符统一处理成'\n'

Popen中封装的其他函数:

  1. Popen.poll():检查子进程的状态,查看子进程是否结束
  2. Popen.wait():等待子进程的结束
  3. Popen.communicate(input=None):与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。
  4. Popen.send_signal(signal):向子进程发送信号
  5. Popen.terminate():停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程
  6. Popen.kill():杀死子进程
  7. Popen.stdin:如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令;否则返回None
  8. Popen.stdout:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令;否则返回None
  9. Popen.stderr:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令;否则返回None
  10. Popen.pid:获取子进程的进程ID
  11. Popen.returncode:获取进程的返回值。如果进程还没有结束,返回None

psutil

import psutil
import os

info = psutil.virtual_memory()
print('内存使用:',psutil.Process(os.getpid()).memory_info().rss/1024/2014, 'M')
print('总内存:',info.total/1024/2014, 'M')
print('内存占比:',info.percent)
print('cpu个数:',psutil.cpu_count())


psutil.cpu_stats()
psutil.cpu_count()
psutil.disk_partitions()

psutil.boot_time()

# 线程
psutil.pids()
psutil.pid_exists(pid=15144)

查看单个变量的内存

sys.getsizeof(a)/1024/1024 # 除完以后单位是 M
whos


globals() # 命名空间
locals() # 命名空间
# 在函数外部时,globals() 和 locals() 一样

参考文献

https://blog.csdn.net/yuchen1986/article/details/22059873
https://www.cnblogs.com/zhoug2020/p/5079407.html


您的支持将鼓励我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK