Python中的system vs call vs popen

时间:2018-02-09 16:08:07

标签: python subprocess system-calls

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)

2 个答案:

答案 0 :(得分: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值转换为当前的值。

答案 1 :(得分: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])