2017-09-20 64 views
0

已经编写了下面的脚本来删除文件夹中与“keep”期间中的日期不匹配的文件。例如。删除部分与此名称匹配的文件。Python子流程脚本失败

该命令在shell中起作用,但在子流程调用时失败。

/bin/rm /home/backups/!(*"20170920"*|*"20170919"*|*"20170918"*|*"20170917"*|*"20170916"*|*"20170915"*|*"20170914"*) 
#!/usr/bin/env python 
from datetime import datetime 
from datetime import timedelta 
import subprocess 

### Editable Variables 
keepdays=7 
location="/home/backups" 

count=0 
date_string='' 
for count in range(0,keepdays): 
    if(date_string!=""): 
     date_string+="|" 
    keepdate = (datetime.now() - timedelta(days=count)).strftime("%Y%m%d") 
    date_string+="*\""+keepdate+"\"*" 

full_cmd="/bin/rm "+location+"/!("+date_string+")" 
subprocess.call([full_cmd], shell=True) 

这是脚本返回什么:

#./test.py 

/bin/rm /home/backups/!(*"20170920"*|*"20170919"*|*"20170918"*|*"20170917"*|*"20170916"*|*"20170915"*|*"20170914"*) 
/bin/sh: 1: Syntax error: "(" unexpected 

Python版本是Python的2.7.12

+0

当您从shell/terminal运行命令时,您正在使用bash的globs扩展和其他替换。但是,Python依靠'/ bin/sh'(而不是'/ bin/bash')来运行代码。 – hjpotter92

回答

0

正如@hjpotter说,子进程将使用/bin/sh作为默认的shell,它不支持你想要做的那种globbing。见official documentation。您可以在使用executable参数更改为subprocess.call()有更合适的壳(/bin/bash/bin/zsh为例):subprocess.call([full_cmd], executable="/bin/bash", shell=True)

,但你可以有很多更好的Python本身提供的,则不需要调用一个子进程删除文件:

#!/usr/bin/env python 
from datetime import datetime 
from datetime import timedelta 
import re 
import os 
import os.path 

### Editable Variables 
keepdays=7 
location="/home/backups" 

now = datetime.now() 
keeppatterns = set((now - timedelta(days=count)).strftime("%Y%m%d") for count in range(0, keepdays)) 

for filename in os.listdir(location): 
    dates = set(re.findall(r"\d{8}", filename)) 
    if not dates or dates.isdisjoint(keeppatterns): 
     abs_path = os.path.join(location, filename) 
     print("I am about to remove", abs_path) 
     # uncomment the line below when you are sure it won't delete any valuable file 
     #os.path.delete(abs_path) 
+0

感谢您的回复。 我尝试了子进程中仍然抛出错误的可执行文件arg,但您的替换脚本完美运行! – Jemson