提示:本文写于 2013 年,文中使用的 Python 版本、代码及 Linux 环境均基于当时的实际开发环境,请结合文章发布时间阅读。
今天在写一个 Linux 下自动备份指定目录中所有目录的脚本时,遇到了一个问题。
因为我需要备份的是目录,所以首先需要判断扫描到的文件是不是目录。
但是,当我使用:
os.path.isdir()
进行判断的时候,发现所有文件返回的结果都是 False。
刚开始的时候,我以为可能是系统兼容性的问题。
进一步测试之后发现,使用:
os.path.isfile()
这些文件同样返回 False。
这时候基本可以确定,不是系统的问题,而是程序本身的写法有问题。
代码如下:
#!/usr/bin/env python
# a python script to auto backup a directory's file by Hito
import os
Directory = raw_input(
"Please enter directory you want to backup:"
)
dirs = os.listdir(Directory)
for filename in dirs:
if os.path.isdir(filename):
os.system(
"tar czvf " +
filename +
".tar.gz " +
filename
)
问题出在哪里?
经过仔细排查,发现问题出在:
os.listdir(Directory)
这里。
os.listdir() 返回的只是指定目录中的文件名,而不是这些文件的完整路径。
例如,如果:
Directory = /home/hito/backup
目录下面有:
test
www
data
那么:
dirs=os.listdir(Directory)
得到的实际上只是:
test
www
data
而不是:
/home/hito/backup/test
/home/hito/backup/www
/home/hito/backup/data
所以,在下面的代码中:
os.path.isdir(filename)
Python 实际上是在当前工作目录中查找:
test
www
data
而这些目录并不一定存在于当前工作目录,因此自然会返回 False。
进一步测试也可以发现,如果直接传入目录的完整路径:
os.path.isdir("/home/hito/backup/test")就可以正常返回 True。
这里的问题并不是 isdir() 本身不能处理相对路径,而是:
filename只是os.listdir()返回的文件名,它并不是我们刚才输入的Directory下面的完整路径。
使用 os.path.join()
那么这个备份脚本应该怎么修改呢?Python 提供了一个非常方便的:
os.path.join()
函数。
它可以自动把目录和文件名组合成完整路径,也不用自己手动拼接字符串,更不用担心路径之间多出或者少了 /。
所以,备份脚本可以这样修改:
#!/usr/bin/env python
# a python script to auto backup a directory's file by Hito
import os
Directory = raw_input(
"Please enter directory you want to backup:"
)
dirs = os.listdir(Directory)
for filename in dirs:
fulldirfile = os.path.join(
Directory,
filename
)
if os.path.isdir(fulldirfile):
os.system(
"tar czvf " +
fulldirfile +
".tar.gz " +
fulldirfile
)
这样:
os.path.join(Directory, filename)
得到的就是对应文件或者目录的完整路径。
再通过:
os.path.isdir(fulldirfile)
进行判断,就可以正确识别指定目录下的子目录了。
这个问题虽然比较简单,但是在使用 os.listdir() 的时候还是需要注意:
它返回的是目录中的名称,而不是带有目录路径的完整文件名。
所以,在需要进一步判断或者操作这些文件的时候,通常还需要把原来的目录路径和文件名组合起来。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。