您的位置:首页 > 运维架构 > Shell

Python 和 bash shell脚本(python和shell, python中文件操作, python中目录操作)

2013-04-18 21:46 1021 查看
转自:/article/11641524.html

作为一个初学shell的程序员来说,使用shell的一些命令调用,比如就写几行,做一些自动化的操作,简单又实用,但是涉及逻辑控制和

字符串处理时,看到那if/fi,case/esac……还有古离古怪的布尔判断……还有复杂而又名字很响而且很老资格的sed、awk……我就想,

在没有非要在shell中写的命令的时候,干嘛不用python呢?

当真有非要在shell中写的命令的时候, shell和python合起来也很HI呀,想想1K行的shell和1K行的python读起来、写起来、调试起来、维护起来有什么区别。

QUOTE:

应用python编写shell脚本

今天同事叫我编写一个shell脚本。话说,虽然我受*nix的影响甚深,但是对于*nix里随处可见的sh脚本却是讨厌之极。为什么讨厌呢?首先 是因为sh脚本那莫名其妙的语法,感觉就像随写随扔的程序,完全没有任何美感可言。其次是sh脚本的处理能力还是比较弱的,在文本处理、XML处理还有网 络编程方面,基本上都要借助于perl,awk等一堆程序。我对这些程序也是不大喜欢的,况且学习第三方软件总要时间,还不如都用python好了。

那,python可以做shell脚本吗? 首先介绍一个函数:

os.system(command)

这个函数可以调用shell运行命令行command并且返回它的返回值。试一下在python的解释器里输入os.system(”ls -l”),就可以看到”ls”列出了当前目录下的文件。可以说,通过这个函数,python就拥有了shell的所有能力。呵呵。。不过,通常这条命令不 需要用到。因为shell常用的那些命令在python中通常有对应而且同样简洁的写法。

shell中最常用的是ls命令,python对应的写法是:os.listdir(dirname),这个函数返回字符串列表,里面是所有的文件名,不过不包含”.”和”..”。如果要遍历整个目录的话就会比较复杂一点。我们等下再说吧。先在解释器里试一下:

>>> os.listdir(”/”)

[’tmp’, ‘misc’, ‘opt’, ‘root’, ‘.autorelabel’, ’sbin’, ’srv’, ‘.autofsck’, ‘mnt’, ‘usr’, ‘var’, ‘etc’, ’selinux’, ‘lib’, ‘net’, ‘lost+found’, ’sys’, ‘media’, ‘dev’, ‘proc’, ‘boot’, ‘home’, ‘bin’]

就像这样,接下去所有命令都可以在python的解释器里直接运行观看结果。

对应于cp命令的是:shutil.copy(src,dest),这个函数有两个参数,参数src是指源文件的名字,参数dest则是目标文件或 者目标目录的名字。 如果dest是一个目录名,就会在那个目录下创建一个相同名字的文件。与shutil.copy函数相类似的是 shutil.copy2(src,dest),不过copy2还会复制最后存取时间和最后更新时间。

不过,shell的cp命令还可以复制目录,python的shutil.copy却不行,第一个参数只能是一个文件。这怎么办?其 实,python还有个shutil.copytree(src,dst[,symlinks]) 。参数多了一个symlinks,它是一个布尔值,如果是True的话就创建符号链接。

移动或者重命名文件和目录呢?估计被聪明的朋友猜到了,shutil.move(src,dst),呵呵。。与mv命令类似,如果src和dst在 同一个文件系统上,shutil.move只是简单改一下名字,如果src和dst在不同的文件系统上,shutil.move会先把src复制到 dst,然后删除src文件。看到现在,大多数朋友应该已经对python的能力有点眉目了,接下来我就列个表,介绍一下其它的函数:

os.chdir(dirname)

把当前工作目录切换到dirname下

os.getcwd()

返回当前的工作目录路径

os.chroot(dirname)

把dirname作为进程的根目录。和*nix下的chroot命令类似

os.chmod(path,mode)

更改path的权限位。mode可以是以下值(使用or)的组合:

os.S_ISUID

os.S_ISGID

os.S_ENFMT

os.S_ISVTX

os.S_IREAD

os.S_IWRITE

os.S_IEXEC

os.S_IRWXU

os.S_IRUSR

os.S_IWUSR

os.S_IXUSR

os.S_IRWXG

os.S_IRGRP

os.S_IWGRP

os.S_IXGRP

os.S_IRWXO

os.S_IROTH

os.S_IWOTH

os.S_IXOTH

具体它们是什么含义,就不仔细说了,基本上就是R代表读,W代表写,X代表执行权限。USR代表用户,GRP代表组,OTH代表其它。

意思大概如下所示:

os.chmod(path,mode) 这个方法应该很简单,只需要2个参数,一个是路径,一个是说明路径的模式,下面列出了这个用法中可以使用的一些常用的模式:

stat.S_ISUID: Set user ID on execution. 不常用

stat.S_ISGID: Set group ID on execution. 不常用

stat.S_ENFMT: Record locking enforced. 不常用

stat.S_ISVTX: Save text image after execution. 在执行之后保存文字和图片

stat.S_IREAD: Read by owner. 对于拥有者读的权限

stat.S_IWRITE: Write by owner. 对于拥有者写的权限

stat.S_IEXEC: Execute by owner. 对于拥有者执行的权限

stat.S_IRWXU: Read, write, and execute by owner. 对于拥有者读写执行的权限

stat.S_IRUSR: Read by owner. 对于拥有者读的权限

stat.S_IWUSR: Write by owner. 对于拥有者写的权限

stat.S_IXUSR: Execute by owner. 对于拥有者执行的权限

stat.S_IRWXG: Read, write, and execute by group. 对于同组的人读写执行的权限

stat.S_IRGRP: Read by group. 对于同组读的权限

stat.S_IWGRP: Write by group. 对于同组写的权限

stat.S_IXGRP: Execute by group. 对于同组执行的权限

stat.S_IRWXO: Read, write, and execute by others. 对于其他组读写执行的权限

stat.S_IROTH: Read by others. 对于其他组读的权限

stat.S_IWOTH: Write by others. 对于其他组写的权限

stat.S_IXOTH: Execute by others. 对于其他组执行的权限

语法:

os.chmod(path, mode);

参数:

path: This is the path for which mode would be set.
mode: This may take one of the above mentioned values or bitwise ORed combinations of them:

示例1:

[python] view
plaincopy

#!/usr/bin/python

import os, sys, stat

# Assuming /tmp/foo.txt exists, Set a file execute by the group.

os.chmod("/tmp/foo.txt", stat.S_IXGRP)

# Set a file write by others.

os.chmod("/tmp/foo.txt", stat.S_IWOTH)

print "Changed mode successfully!!"

This produces following result:

Changed mode successfully!!

os.chmod("/tmp/foo.txt", stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO) # mode:777

os.chown(path,uid,gid)

改变文件的属主。uid和gid为-1的时候不改变原来的属主。

os.link(src,dst)

创建硬连接

os.mkdir(path,[mode])

创建目录。mode的意义参见os.chmod(),默认是0777

os.makedirs(path,[mode])

和os.mkdir()类似,不过会先创建不存在的父目录。

os.readlink(path)

返回path这个符号链接所指向的路径

os.remove(path)

删除文件,不能用于删除目录

os.rmdir(path)

删除文件夹,不能用于删除文件

os.symlink(src,dst)

创建符号链接

shutil.rmtree(path[,ignore_errors[,onerror]])

删除文件夹

介绍了这么多,其实只要查一下os和shutil两个模块的文档就有了,呵呵。。真正编写shell脚本的时候还需要注意:

1.环境变量。python的环境变量保存在os.environ这个字典里,可以用普通字典的方法修改它,使用system启动其它程序的时候会自动被继承。比如:

os.environ[”fish”]=”nothing”

不过也要注意,环境变量的值只能是字符串。和shell有些不同的是,python没有export环境变量这个概念。为什么没有呢?因为python没有必要有:-)

2.os.path这个模块里包含了很多关于路径名处理的函数。在shell里路径名处理好像不是很重要,但是在python里经常需要用到。最常用的两个是分离和合并目录名和文件名:

os.path.split(path) -> (dirname,basename)

这个函数会把一个路径分离为两部分,比如:os.path.split(”/foo/bar.dat”)会返回(”/foo”,”bar.dat”)

os.path.join(dirname,basename)

这个函数会把目录名和文件名组合成一个完整的路径名,比如:os.path.join(”/foo”,”bar.dat”)会返回”/foo/bar.dat”。这个函数和os.path.split()刚好相反。

还有这些函数:

os.path.abspath(path)

把path转成绝对路径

os.path.expanduser(path)

把path中包含的”~”和”~user”转换成用户目录

os.path.expandvars(path)

根据环境变量的值替换path中包含的”$name”和”${name}”,比如环境变量FISH=nothing,那os.path.expandvars(”$FISH/abc”)会返回”nothing/abc”

os.path.normpath(path)

去掉path中包含的”.”和”..”

os.path.splitext(path)

把path分离成基本名和扩展名。比如:os.path.splitext(”/foo/bar.tar.bz2″)返回(’/foo/bar.tar’, ‘.bz2′)。要注意它和os.path.split()的区别

3.在os模块有一个很好用的函数叫os.stat()没有介绍,因为os.path模块里包含了一组和它具有同样功能的函数,但是名字更好记一点。

os.path.exists(path)

判断文件或者目录是否存在

os.path.isfile(path)

判断path所指向的是否是一个普通文件,而不是目录

os.path.isdir(path)

判断path所指向的是否是一个目录,而不是普通文件

os.path.islink(path)

判断path所指向的是否是一个符号链接

os.path.ismount(path)

判断path所指向的是否是一个挂接点(mount point)

os.path.getatime(path)

返回path所指向的文件或者目录的最后存取时间。

os.path.getmtime(path)

返回path所指向的文件或者目录的最后修改时间

os.path.getctime(path)

返回path所指向的文件的创建时间

os.path.getsize(path)

返回path所指向的文件的大小

4.应用python编写shell脚本经常要用到os,shutil,glob(正则表达式的文件名),tempfile(临时文 件),pwd(操作/etc/passwd文件),grp(操作/etc/group文件),commands(取得一个命令的输出)。前面两个已经基本 上介绍完了,后面几个很简单,看一下文档就可以了。

5.sys.argv是一个列表,保存了python程序的命令行参数。其中sys.argv[0]是程序本身的名字。

不能光说不练,接下来我们就编写一个用于复制文件的简单脚本。前两天叫我写脚本的同事有个几万个文件的目录,他想复制这些文件到其它的目录,又不能 直接复制目录本身。他试了一下”cp src/* dest/”结果报了一个命令行太长的错误,让我帮他写一个脚本。操起python来:

import sys,os.path,shutil

for f in os.listdir(sys.argv[1]):

shutil.copy(os.path.join(sys.argv[1],f),sys.argv[2])

再试一下linuxapp版里的帖子——把一个文件夹下的所有文件重命名成10001~10999。可以这样写:

import os.path,sys

dirname=sys.argv[1]

i=10001

for f in os.listdir(dirname):

src=os.path.join(dirname,f)

if os.path.isdir(src):

continue

os.rename(src,str(i))

i+=1

Python文件及文件夹的一些操作


Python文件及文件夹的一些操作

python中对文件、文件夹的操作需要涉及到os模块和shutil模块。

创建文件:

1) os.mknod("test.txt") 创建空文件

2)open("test.txt",w) 直接打开一个文件,如果文件不存在则创建文件

创建目录:

os.mkdir("file") 创建目录

复制文件:

shutil.copyfile("oldfile","newfile") oldfile和newfile都只能是文件

shutil.copy("oldfile","newfile") oldfile只能是文件夹,newfile可以是文件,也可以是目标目录

复制文件夹:

shutil.copytree("olddir","newdir") olddir和newdir都只能是目录,且newdir必须不存在

重命名文件(目录)

os.rename("oldname","newname") 文件或目录都是使用这条命令

移动文件(目录)

shutil.move("oldpos","newpos")

删除文件

os.remove("file")

删除目录

os.rmdir("dir") 只能删除空目录

shutil.rmtree("dir") 空目录、有内容的目录都可以删

转换目录

os.chdir("path") 换路径

判断目标

os.path.exists("goal") 判断目标是否存在

os.path.isdir("goal") 判断目标是否目录

os.path.isfile("goal") 判断目标是否文件

注意事项:


python os.rename问题

弄了半天os.rename,如果将文件重命名为已经存在的文件名称时会出现WindowsError: [Error 183]错误。

WindowsError: [Error 2]错误则是因为当前工作目录不是path指定的目录,也就是说getcwd与path不同,可以使用os.chdir更改当前目录或者使用os.path.join()变为绝对路径。

今天用Python写一段代码,用了语句os.chdir( setup_dir )来进到setup_dir目录里面去了,后来要删掉目录setup_dir一直删除不成功,觉得很奇怪,返回值是 [Error 5]

后来才知道原来是用了os.chdir( setup_dir )后setup_dir被占用导致无法删除,一定要将当前目录设为原本的目录,可以使用os.chdir( sys.path[0] ).

所以使用os.chdir()需谨慎,用后要还原!

os模块的函数rename()可以对文件或者目录进行重命名。

下面演示文件重命名操作。

如果当前目录存在名为myfile.txt的文件,则重命名为myfile_rename.txt.

import os

li = os.listdir(".") #返回当前目录的文件列表

print li #打印出当前目录包含的文件

if myfile.txt in li:

os.rename("myfile.txt", "myfile_rename.txt")

上面例子中是修改文件名,但是文件还是统一类型, 文件的后缀名没变,有的时候需要将一种类型的文件改成另一种类型的文件这是就得利用rename()和字符串查找的函数。

示例如下:将后缀名为“html”格式的文件改成“htm”格式的文件

import os

files = os.listdir(".")

for filename in files:

pos = filename.find(".")

if filename[pos+1:] == "html" :

newname = filename[:pos+1] +"htm"

os.rename(filename, newname)

以上过程还可以通过splitext()来实现,splitext()用于将文件名和后缀名分隔开。

import os

files = os.listdir(".")

for filename in files :

li = os.path.splitext(filename) #返回文件名和后缀名组成的列表

if li[1] == "html":

newname = li[0] + "htm"

os.rename(filename, newname)

路径的匹配可以使用glob模块,返回符合给定匹配条件的文件列表。例如上面的例子需要判断文件后缀是否是“html”类型,可以使用glob()直接进行匹配:
glob.glob(“*.html”)


Python获取当前程序绝对路径和目录

Python获取脚本路径:

在写脚本的时候经常需要获取到当前脚本的执行目录:

[python] view
plaincopy

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

import os

#主模块

if __name__ == '__main__':

fl = os.path.abspath(sys.argv[0]) #获取脚本的绝对路径,sys.argv[0]即本身

print fl

cdir = os.path.dirname(fl) #获取脚本的目录路径

print cdir

pwd=os.getcwd() #获取用户所在目录

print pwd

#非主模块

print

print __file__ #当前模块

print os.path.realpath(__file__) #获取当前运行模块的绝对路径

print os.path.dirname(os.path.realpath(__file__)) #获取当前模块所在目录

执行:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: