Python中的system vs call vs popen

问题描述 投票:1回答:2
cmd = 'touch -d '+date_in+' '+images_dir+'/'+photo_name
os.system(cmd)

不行

subprocess.call(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])

不行

subprocess.Popen(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])

作品!

为什么?前两种情况我错过了什么?

pi@raspberrypi:~ $ python --version
Python 2.7.13

实际代码段:

try:
    response = urllib2.urlopen(url)
    if(response.getcode() == 200):
        photo_file = response.read()
        with open(images_dir+'/'+photo_name,'wb') as output:
            output.write(photo_file)
            #cmd = 'touch -d '+date_in+' '+images_dir+'/'+photo_name
            #subprocess.Popen(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])
            subprocess.check_call(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])
        with open(images_dir+'/captions/'+photo_name+'.txt','wb') as output:
            output.write(photo_title)
    else:
        print 'Download error'
except Exception as message:
    print 'URL open exception {}'.format(message)
python subprocess system-calls
2个回答
0
投票

现在很清楚:

with open(images_dir+'/'+photo_name,'wb') as output:
    output.write(photo_file)
    #cmd = 'touch -d '+date_in+' '+images_dir+'/'+photo_name
    #subprocess.Popen(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])
    subprocess.check_call(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])

我的假设是:你仍然在with区块,所以如果执行check_callsystem,它结束,然后文件关闭,再次设置日期并破坏touch的努力。

使用Popen,进程在后台执行,因此当它执行时,文件已经关闭(好吧,实际上它是竞争条件,不能保证)

我建议:

with open(images_dir+'/'+photo_name,'wb') as output:
    output.write(photo_file)
subprocess.check_call(['touch','-d','{}'.format(date_in),'{}'.format(images_dir+'/'+photo_name)])

因此,当您调用check_call时,文件已正确关闭

写得好:

fullpath = os.path.join(images_dir,photo_name)
with open(fullpath ,'wb') as output:
    output.write(photo_file)
# we're outside the with block, note the de-indentation
subprocess.check_call(['touch','-d','{}'.format(date_in),fullpath])

2
投票

我根本不会使用touch;改用os.utime

import os

try:
    response = urllib2.urlopen(url)
except Exception as message:
    print 'URL open exception {}'.format(message)
else:
    if response.getcode() == 200:
        photo_file = response.read()
        f = os.path.join(images_dir, photo_name)
        with open(f,'wb') as output:
            output.write(photo_file)
        os.utime(f, (date_in, date_in))

        f = os.path.join(images_dir, 'captions', photo_name + '.txt')    
        with open(f, 'wb') as output:
            output.write(photo_title)
    else:
        print 'Download error'

请注意,os.utime的日期/时间参数必须是整数UNIX时间戳;你需要将你的date_in值从当前的任何值转换。

© www.soinside.com 2019 - 2024. All rights reserved.