基于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命令的是:py(src,dest),这个函数有两个参数,参数src是指源⽂件的名字,参数dest则是⽬标⽂件或者⽬标⽬录的名字。如果dest是⼀个⽬录名,就会在那个⽬录下创建⼀个相同名字的⽂件。与py函数相类似的是py2(src,dest),不过copy2还会复制最后存取时间和最后更新时间。
不过,shell的cp命令还可以复制⽬录,python的py却不⾏,第⼀个参数只能是⼀个⽂件。这怎么办?其实,python还有个pytree(src,dst[,symlinks]) 。参数多了⼀个symlinks,它是⼀个布尔值,如果是True的话就创建符号链接。
移动或者重命名⽂件和⽬录呢?估计被聪明的朋友猜到了,ve(src,dst),呵呵。。与mv命令类似,如果src和dst在同⼀个⽂件系统上,ve只是简单改⼀下名字,如果src和dst在不同的⽂件系统上,ve会先把src复制到dst,然后删除src⽂件。看到现在,⼤多数朋友应该已经对 python的能⼒有点眉⽬了,接下来我就列个表,介绍⼀下其它的函数:
python怎么读取py文件os.chdir(dirname)
把当前⼯作⽬录切换到dirname下
返回当前的⼯作⽬录路径
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.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()类似,不过会先创建不存在的⽗⽬录。
返回path这个符号链接所指向的路径
删除⽂件,不能⽤于删除⽬录
删除⽂件夹,不能⽤于删除⽂件
os.symlink(src,dst)
创建符号链接
<(path[,ignore_errors[,onerror]])
删除⽂件夹
介绍了这么多,其实只要查⼀下os和shutil两个模块的⽂档就有了,呵呵。。真正编写 shell脚本的时候还需要注意:
1.环境变量。python的环境变量保存在os.environ这个字典⾥,可以⽤普通字典的⽅法修改它,使⽤system启动其它程序的时候会⾃动被继承。⽐如:
不过也要注意,环境变量的值只能是字符串。和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转成绝对路径
panduser(path)
把path中包含的”~”和”~user”转换成⽤户⽬录
pandvars(path)
根据环境变量的值替换path中包含的”$name”和”${name}”,⽐如环境变量 FISH=nothing,那
pandvars(”$FISH/abc”)会返回”nothing/abc”
path(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模块⾥包含了⼀组和它具有同样功能的函数,但是名字更好记⼀点。
ists(path)
判断⽂件或者⽬录是否存在
os.path.isfile()
判断path所指向的是否是⼀个普通⽂件,⽽不是⽬录
os.path.isdir(path)
判断path所指向的是否是⼀个⽬录,⽽不是普通⽂件
os.path.islink(path)
判断path所指向的是否是⼀个符号链接
os.path.ismount(path)
判断path所指向的是否是⼀个挂接点(mount point)
atime(path)
返回path所指向的⽂件或者⽬录的最后存取时间。
ime(path)
返回path所指向的⽂件或者⽬录的最后修改时间
ime(path)
返回path所指向的⽂件的创建时间
size(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]):
再试⼀下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
i =1
os.chkdir(path) 转换到⽬录path 下。
os.system('md a') 可以直接创建⽬录。
os.name字符串指⽰你正在使⽤的平台。⽐如对于Windows,它是'nt',⽽对于Linux/Unix⽤户,它是'posix'。
● os.getcwd()函数得到当前⼯作⽬录,即当前Python脚本⼯作的⽬录路径。
● os.getenv()和os.putenv()函数分别⽤来读取和设置环境变量。
● os.listdir()返回指定⽬录下的所有⽂件和⽬录名。
● os.remove()函数⽤来删除⼀个⽂件。
● os.system()函数⽤来运⾏shell命令。
● os.linesep字符串给出当前平台使⽤的⾏终⽌符。例如,Windows使⽤'\r\n',Linux使⽤'\n'⽽Mac使⽤'\r'。
● os.path.split()函数返回⼀个路径的⽬录名和⽂件名。
>>> os.path.split('/home/swaroop/byte/')
('/home/swaroop/byte/code', '')
● os.path.isfile()和os.path.isdir()函数分别检验给出的路径是⼀个⽂件还是⽬录。类似地,ists()函数⽤来检验给出的路径是否真地存在。
⽂件重定向
已有PY⽂件new1.py ,在命令⾏下输⼊:new1& 可以将new1运⾏的结果输出到⽂件,这称为流重定向。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论