子进程间歇性 returns 为空

subprocess intermittently returns empty

我是 运行 python3 中的一个子进程,在 Mac OS 上从本地目录中保存的大量图像中检索 EXIF 图像数据。

代码间歇性工作。 Ruffly 每 3 次调用子进程 returns 字节对象(正如预期的那样),只是它是空的 b''。

故障并非特定于任何特定图像文件(更改)。

我尝试了两个版本的代码,一个是调用 Popen.wait(..) 的地方(例如在下面查找纬度),另一个是立即调用 .communicate() 的地方(例如查找下面的经度)。

print('.......========.......')
try:
    cmdLat = "mdls \"" + imagePath + "\" | grep Latitude | awk '{print }'"
    subprocess = Popen(cmdLat, shell=True, stdout=PIPE)
    Popen.wait(subprocess)
    lat = subprocess.communicate()[0]
    latFloat = float(lat.decode())
except Exception as e:
    print("Failed finding latitude, exception:", e)
    print("lat value: ", lat)

try:
    cmdLon = "mdls \"" + imagePath + "\" | grep Longitude | awk '{print }'"
    lon = (Popen(cmdLon, shell=True, stdout=PIPE).communicate()[0])
    lonFloat = float(lon.decode())
except Exception as e:
    print("Failed finding longitude, exception:", e)
    print("lon value: ", lat)

尝试 1 结果:

.......========.......
IMG_0149.JPG has been successful
.......========.......
IMG_0161.JPG has been successful
.......========.......
IMG_0377.JPG has been successful
.......========.......
Failed finding latitude, exception: could not convert string to float:
lat value:  b''
Failed finding longitude, exception: could not convert string to float:
lon value:  b''

尝试 2 结果:

.......========.......
IMG_0149.JPG has been successful
.......========.......
IMG_0161.JPG has been successful
.......========.......
IMG_0377.JPG has been successful
.......========.......
IMG_0007.JPG has been successful
.......========.......
Failed finding lattitude, exception: could not convert string to float:
lat value:  b''
Failed finding longitude, exception: could not convert string to float:
lon value:  b''

可能是您引用文件名的方式导致了问题,也可能是 Michael Butscher 建议的时间问题。我试过自己写一个解决方案,发现我的大部分图片都没有坐标。

这是我的解决方案,请告诉我它是否适合您。请注意,对于那些没有坐标的图片,lat=="(null)"lon="(null)"。对于那些确实有坐标的,latlon 将是浮点数。

#!/usr/bin/env python3
import pathlib
import subprocess

def main():
    """ Entry """
    for pic_file in pathlib.Path('.').glob('*.jpg'):
        print('-' * 72)
        print(pic_file)
        command = ['mdls',
                   '-name', 'kMDItemLatitude',
                   '-name', 'kMDItemLongitude',
                   str(pic_file)]
        output = subprocess.check_output(command, encoding='utf-8')
        # Sample output
        #    kMDItemLatitude  = (null)
        #    kMDItemLongitude = (null)
        # or
        #    kMDItemLatitude  = 46.75725833333333
        #    kMDItemLongitude = -71.28605666666667        
        print(output)

        # Parse the output
        lines = output.splitlines()
        values = [line.split()[-1] for line in lines]
        print(values)

        # Convert to float
        try:
            lat, lon = [float(value) for value in values]
        except ValueError:
            lat, lon = values

        print('Latitude =', lat)
        print('Logitude =', lon)


if __name__ == '__main__':
    main()

备注

  • 我不使用 grepawk 命令,因为我想自己解析这些值
  • 通常,subprocess 函数的输出将是 return 原始字节数组,我使用 encoding='utf-8' 将其转换为 Python 3 个字符串。