2017-09-20 62 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