一、Python如何处理重定向

1. 解释linux重定向

Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。

                                                          --by 百度百科

2、简练linux重定向

标准输入、标准输出和错误输出

[root@python ~]# cat     #从键盘标准输入,然后打印在屏幕上。"Hello world!!!"  "Hello world!!!"         #ctrl+d结束键盘的输入[root@python ~]# cat < /etc/hosts    #从文件标准输入,然后打印在屏幕上127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

3、Python实现Linux重定向

在python的sys模块中有三个方法可以实现linux下重定向,那么我们接下来一起去学习下:

导入sys模块:import sys

查看sys模块的三个方法分别是sys.stdin、sys.stdout、sys.stderr

查看使用的帮助信息,具体的去了解用法和功能

In [2]: sys.stdin?Type:       fileString Form:
', mode 'r' at 0x7f9b0f1ae0c0>Docstring:file(name[, mode[, buffering]]) -> file objectOpen a file.  The mode can be 'r', 'w' or 'a' for reading (default),writing or appending.  The file will be created if it doesn't existwhen opened for writing or appending; it will be truncated whenopened for writing.  Add a 'b' to the mode for binary files.Add a '+' to the mode to allow simultaneous reading and writing.If the buffering argument is given, 0 means unbuffered, 1 means linebuffered, and larger numbers specify the buffer size.  The preferred wayto open a file is with the builtin open() function.Add a 'U' to mode to open the file for input with universal newlinesupport.  Any line ending in the input file will be seen as a '\n'in Python.  Also, a file so opened gains the attribute 'newlines';the value for this attribute is one of None (no newline read yet),'\r', '\n', '\r\n' or a tuple containing all the newline types seen.'U' cannot be combined with 'w' or '+' mode.

打开一个文件,有三种模式分别是read、write、append,而默认的方式是以read的模式进行打开一个文件。如果这个文件不存在它将要被创建;

当以write的模式打开这个文件的时候,它将被truncated;

增加一个b是以二进制文件的模式;增加一个+这种模式允许同时读和写。等等

[root@python lianxi]# python f1.py "Hello world!!!""Hello world!!!"[root@python lianxi]# python f1.py < /etc/hosts127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

代码如下:

[root@python lianxi]# cat f1.py #!/usr/bin/env pythonimport sysf = sys.stdinprint f.read(),

4、文件对象的方法

4.1介绍python中打开文件的几种常用方法:

方法1:

>>> fp = file('/etc/passwd','r')>>> data = fp.read()>>> fp.close()
>>> fp = open('/etc/passwd','r')>>> data = fp.read()>>> fp.close()

方法2:

>>> with open('/etc/hosts','r') as fd:...         data = fd.read()

这两种的区别就在于:方法1打开文件后要关闭文件,而方法2打开文件后不需要关闭文件。

4.2文件对象的方法:

fp.read()、fp.readline()、fp.readlines()、fp.write()、fp.close()

Python解释器中查看使用说明

对象fp 方法read(): 返回值为string

In [14]: fp.read?Type:       builtin_function_or_methodString Form:
Docstring:read([size]) -> read at most size bytes, returned as a string.If the size argument is negative or omitted, read until EOF is reached.Notice that when in non-blocking mode, less data than what was requestedmay be returned, even if no size parameter was given.

>>> fp = open('/etc/hosts','r')>>> print fp.read()    #不带参数,表示一次性读完127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6>>> print fp.read()>>>
>>> fp = open('/etc/hosts','r')>>> print fp.read(50)    #带参数,表示每次仅读的字节大小,这样节省内存的开销127.0.0.1   localhost localhost.localdomain localh>>> print fp.read(50)ost4 localhost4.localdomain4::1         localhost>>> print fp.read(50) localhost.localdomain localhost6 localhost6.local>>> print fp.read(50)domain6>>> print fp.read(50)>>> print fp.read(50)

---------------------------------华丽分割线---------------------------------

对象fp 方法readline(): 返回值为string

In [17]: fp.readline?Type:       builtin_function_or_methodString Form:
Docstring:readline([size]) -> next line from the file, as a string.Retain newline.  A non-negative size argument limits the maximumnumber of bytes to return (an incomplete line may be returned then).Return an empty string at EOF.
>>> fp = open('/etc/hosts','r')>>> print fp.readline()    #不带参数表示每次仅读一行,按行读取127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4>>> print fp.readline()::1         localhost localhost.localdomain localhost6 localhost6.localdomain6>>> print fp.readline()

---------------------------------华丽分割线---------------------------------

对象fp 方法readlines(): 返回值为list,每行为list的一个元素

In [18]: fp.readlines?Type:       builtin_function_or_methodString Form:
Docstring:readlines([size]) -> list of strings, each a line from the file.Call readline() repeatedly and return a list of the lines so read.The optional size argument, if given, is an approximate bound on thetotal number of bytes in the lines returned.
>>> fp = open('/etc/hosts','r')>>> print fp.readlines()['127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4\n', '::1         localhost localhost.localdomain localhost6 localhost6.localdomain6\n']

---------------------------------华丽分割线---------------------------------

用while循环对文件的每一行进行遍历

[root@python lianxi]# python f3.py 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6lines: 2#####代码如下#####[root@python lianxi]# cat f3.py fp = open('/etc/hosts','r')n = 0while True:    line = fp.readline()    if line:    	print line,    	n += 1    else:    	breakfp.close()print 'lines: %s' % n

用for循环对文件的每一行进行遍历

[root@python lianxi]# python f4.py root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltmail:x:8:12:mail:/var/spool/mail:/sbin/nologinuucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologinoperator:x:11:0:operator:/root:/sbin/nologingames:x:12:100:games:/usr/games:/sbin/nologingopher:x:13:30:gopher:/var/gopher:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologindbus:x:81:81:System message bus:/:/sbin/nologinvcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologinsaslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologinmysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bashntp:x:38:38::/etc/ntp:/sbin/nologingit:x:498:498:git version control:/home/git:/bin/bashallentuns:x:500:500::/home/allentuns:/bin/bash#####代码如下#####[root@python lianxi]# cat f4.py with open('/etc/passwd','r') as fd:    data = fd.readlines()for i in data:    print i,

5、Python模块sys的介绍

5.1 sys模块输出

[root@python lianxi]# python f5.py > /dev/nullstderr:hello world[root@python lianxi]# python f5.py 2> /dev/nullprint:hello world!!!stdout:hello world[root@python lianxi]# python f5.py > /dev/null 2>& 1[root@python lianxi]# [root@python lianxi]# cat f5.py import sysprint 'print:hello world!!!'sys.stdout.write('stdout:hello world\n')   sys.stderr.write('stderr:hello world\n')

博文一开始就介绍了sys模块的重定向,大家也知道sys.stdout是标准重定向,可以重定向到/dev/null空洞中;sys.stderr是错误重定向可以把屏幕上的错误输出重定向到 2> /dev/null中?那么问题来了,为什么print和strdout是一样的效果呢?

其实是这样的:print通常是调用一个stdout对象的write方法。print具有以下特征:

(1)print会先进行格式转换

(2)print会在自后加上换行符

结果不然,print还有另外一个强大的功能就是print结合sys.stdout和sys.stderr,接下来大家意洽来看

print结合stderr

[root@python lianxi]# python f6.py 2> /dev/null stdout,good[root@python lianxi]# cat f6.py import sysprint >> sys.stderr,'hello world!!!'sys.stdout.write('stdout,good\n')

二、Python简单wc命令统计

1、简单的wc命令

linux命令的实现[root@python lianxi]# wc /etc/hosts  2  10 158 /etc/hosts 2行 10单词 158字节 Python模块实现简单wc统计[root@python lianxi]# python f7.py < /etc/hosts2 10 158
from sys import stdindata = stdin.read()lines = data.count('\n')words = len(data.split())chars = len(data)print lines,words,chars

2、sys.argv使用

In [20]: sys.argv?Type:       listString Form:['/usr/bin/ipython']Length:     1Docstring:list() -> new empty listlist(iterable) -> new list initialized from iterable's items
list() -> 返回值为一个空的列表list(iterable) -> 从迭代的元素中返回到一个新的列表
[root@python lianxi]# python f8.py /etc/hostssys.argv:  ['f8.py', '/etc/hosts']127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6[root@python lianxi]# cat f8.py import sysprint 'sys.argv: ',sys.argvf = open(sys.argv[1])for i in f:    print i,

3、修改wc脚本能够接受参数

[root@python lianxi]# python wc.py /etc/hosts2 10 158[root@python lianxi]# cat wc.py from sys import argvwith open(argv[1]) as fd:    data = fd.read()    lines = data.count('\n')    words = len(data.split())    chars = len(data)    print '%(lines)s %(words)s %(chars)s' % locals()

三、Python实现真正的命令行参数wc

1、脚本能够实现的功能

(1)统计单个文件、多个文件的行数、单词数、字符数

(2)如果只有一个文件,那么显示结果汇总也就是合计;如果是多个文件显示汇总合计信息

(3)对传递的文件进行判断,是否为文件、文件是否存在等等情况

(4)支持选项,比如只统计多个文件的大小或总共有多少行都是可以的

(5)支持管道输入

2、python的wc脚本

#!/usr/bin/env python#coding:utf8#import os,sysfrom optparse import OptionParserparser = OptionParser()parser.add_option('-l','--lines',                        dest='lines',                        action='store_true',                        default=False,                        help='only count lines',                        )parser.add_option('-w','--words',                        dest='words',                        action='store_true',                        default=False,                        help='only count words',                        )parser.add_option('-c','--chars',                        dest='chars',                        action='store_true',                        default=False,                        help='only count chars',                        )options,args = parser.parse_args()def getCount(data):        lines = data.count('\n')        words = len(data.split())        chars = len(data)        return lines,words,chars        #print '%(lines)s %(words)s %(chars)s' % locals()def print_wc(lines,words,chars,fn):        if options.lines:                print lines,        if options.words:                print words,        if options.chars:                print chars,        print fnif not (options.lines or options.words or options.chars):    options.lines,options.words,options.chars = True, True, Trueif args:    total_lines,total_words,total_chars = 0, 0, 0    for fn in args:        if os.path.isfile(fn):            with open(fn) as fd:                data = fd.read()                lines,words,chars = getCount(data)                total_lines += lines                total_words += words                total_chars += chars                print_wc(lines,words,chars,fn)        elif os.path.isdir(fn):                tup = (sys.argv[0],fn)                sys.stderr.write('python %s : %s: Is a directory\n' % tup)        else:                tup = (sys.argv[0],fn)                print 'python %s : %s: No such file or directory' % tup    if len(args) > 1:                print_wc(total_lines,total_words,total_chars,'total')else:    fn = ''    data = sys.stdin.read()    lines,words,chars = getCount(data)    print_wc(lines,words,chars,fn)

脚本参数解释

OptionParse是python的一个模块,可以实现真正意义上的命令行参数-c/--chars:命令行选项dest:为选项定义变量名,值chars就是-c选项的命令default=False: chars的值为False 意思默认情况下命令不带-c选项help:选项解释说明部分

3、python脚本测试

[root@python lianxi]# python wc.py /etc/hosts2 10 158 /etc/hosts[root@python lianxi]# python wc.py /etc/hosts /etc/issue2 10 158 /etc/hosts3 9 47 /etc/issue5 19 205 total[root@python lianxi]# python wc.py /etc/hosts /etc/issue /etc/passwd2 10 158 /etc/hosts3 9 47 /etc/issue24 35 1093 /etc/passwd29 54 1298 total[root@python lianxi]# python wc.py /etc/hosts /etc/issue /etc/passwd -l2 /etc/hosts3 /etc/issue24 /etc/passwd29 total[root@python lianxi]# python wc.py /etc/hosts /etc/issue /etc/passwd -lw2 10 /etc/hosts3 9 /etc/issue24 35 /etc/passwd29 54 total[root@python lianxi]# python wc.py /etc/hosts /etc/issue /etc/passwd -lwc2 10 158 /etc/hosts3 9 47 /etc/issue24 35 1093 /etc/passwd29 54 1298 total[root@python lianxi]# python wc.py /etc/python wc.py : /etc/: Is a directory[root@python lianxi]# python wc.py /etc/nihaobucunzai.txtpython wc.py : /etc/nihaobucunzai.txt: No such file or directory[root@python lianxi]# python wc.py /etc/nihaobucunzai.txt > /dev/null [root@python lianxi]# python wc.py /etc/ 2> /dev/null

---------------------------------------------华丽分割线------------------------------------

更新时间 2015-02-05 这次更新我们就一起聊聊Python的hashlib模块和__name__的形式

一、Python的hashlib模块

1、hashlib模块和hashlib方法

Python模块hashlib;

hashlib对象的方法如下:

hashlib.md5     hashlib.new     hashlib.sha1    

hashlib.sha224  hashlib.sha256  hashlib.sha384  hashlib.sha512

导入hashlib模块是前提,然后才能使用对应的方法

import hashlib

(1)hashlib.new

In [9]: hashlib.new?Type:       functionString Form:
File:       /usr/lib64/python2.6/hashlib.pyDefinition: hashlib.new(name, string='', usedforsecurity=True)Docstring:new(name, string='') - Return a new hashing object using the named algorithm;optionally initialized with a string.

对应的返回值:返回一个新的hash对象使用指定的算法对一个字符串。

name:指定使用的算法,比如md5、sha1

string:对哪个字符串进行加密

>>> import hashlib>>> hashlib.new('md5',string='hello world!!!').hexdigest()		'f6835168c4823ac89c1bc97154a675a8'#hexdigest() 使加密后的结果以十六进制显示

(2)hashlib.md5

>>>: m = hashlib.md5()>>>: m.update?	Type:       builtin_function_or_methodString Form:
Docstring:  Update this hash object's state with the provided string.

描述:在提供的字符串中更新这个hash对象的状态

特点:使用update更新hash对象。多次调用update和使用串联的参数一次调用update是等价的

接下来我们用个小例子来证明update的特点:

这种是多次update的效果>>> m = hashlib.md5()    #创建一个加密对象>>> m.update('aaabbb')     #更新字符串>>> m.hexdigest()              #显示加密后的结果'6547436690a26a399603a7096e876a2d'>>> m.update('cccddd')>>> m.hexdigest()'057cea2fc37aabd4a59462d3fd28c93b'整合update的所有字符串一次性md5,然后查看效果>>> m = hashlib.md5()>>> m.update('aaabbbcccddd')>>> m.hexdigest()'057cea2fc37aabd4a59462d3fd28c93b'呵呵,结果是一直的啊!!!哈哈哈

2、md5和sha1的适用场景

md5经常用来做用户密码的存储。而sha1则经常用作数字签名

>>> a = 'Hello , Allentuns'>>> print hashlib.md5(a).hexdigest()1490de1169f6e53f3d8aef43577f05cd>>> print hashlib.sha1(a).hexdigest()dcbaaae330347bfc35e31b0d0aff9a1440ea2716>>> print hashlib.sha224(a).hexdigest()d843643466a615d72a4f97e2693deefa41bf3f1f36f76add6ddceeba>>> print hashlib.sha256(a).hexdigest()44fe3dfd7a0a49647fb99625382e8af3167f8df662b833b7d33ff0409b538a5a>>> print hashlib.sha384(a).hexdigest()1757ad1e90f0cc7fcea80cae0942d2ff9f13b5f0c8d6b7d702b71c395a7d9da6f824fe81b7ddfa6e447d49cef8d44efc>>> print hashlib.sha512(a).hexdigest()2e8b0747918f492ede366c0774dd35794d2690b2fa79cd7ce8532a7b70f69afb55b9b3a68277f4a993b702dacc9f27610ce2257290d5c885f780722d76162b7f

二、Python求文件的大小

1、需求:传递一个参数(本地路径),然后计算路径下所有文件的大小,并单独显示最大的文件

#!/usr/bin/env python#coding:utf8#Author:Allentunsimport sys,osdict = {}for p,d,f in os.walk(sys.argv[1]):       for i in f:           path_file = os.path.join(p,i)	   size = os.path.getsize(path_file)	   dict[path_file] = size 	   by_size = sorted(dict.iteritems(), key = lambda asd:asd[1], reverse = True)print '%s\t\t\t%s' % ('path_to_path','filename')print '+'*50for i in by_size:	print '%s\t%s' % iprint '\n'print '+'*15 + 'Maximum file current path' + '+'*15max_size = by_size[0]filename =  max_size[0]size = max_size[1]/1024print '%s %sk' %(filename,size)

2、执行结果如下:

path_to_path			filename++++++++++++++++++++++++++++++++++++++++++++++++++/home/nihao	31697/home/allentuns/.viminfo	4988/home/allentuns/.bash_history	2686/home/allentuns/ssh.py	572/home/git/.ssh/known_hosts	395/home/allentuns/.ssh/known_hosts	394/home/allentuns/.bash_profile	215/home/allentuns/.bashrc	124/home/git/.bash_history	120/home/allentuns/ip.txt	117/home/allentuns/.profile	26/home/allentuns/.bash_logout	18+++++++++++++++Maximum file current path+++++++++++++++/home/nihao 30k

三、了解一下__name__

1、我们先看一个例子

[root@python lianxi]# cat f1.py    #只有一行代码print __name__
[root@python lianxi]# cat f2.py    #有两行代码import f1    #导入文件f1print __name__    #打印

接下来我们来看执行结果

[root@python lianxi]# cat f1.pyprint __name__[root@python lianxi]# cat f2.pyimport f1print __name__

结论:

(1)如果__name__是在当前直接引用的,那么执行的结果是__main__

(2)如果__name__是被其它python程序调用的,那么执行的结果是文件的名字

程序调用的特点:

import f1

在我们执行导入的时候,其实f1中的程序也被从头到尾的执行了一遍,有时候我们只是想用程序的一部分函数等,我们就必须采用一些特殊的方法也就是我们今天聊的话题:

[root@python lianxi]# python f1.pyf1: __main__[root@python lianxi]# python f2.pyf2: __main__[root@python lianxi]# cat f1.pyif __name__ == '__main__':	print 'f1:',__name__[root@python lianxi]# cat f2.pyimport f1print 'f2:',__name__

这样上面的问题就得到很好的解决。