从Python和launchd启动osascript
这是我这个小程序的主要内容
有一个Python脚本,它会检查某个文件夹里是否有新的电影文件,并相应地更新一个sqlite3数据库,这样就可以把文件排队等待处理。这个脚本每分钟运行一次,使用launchctl来启动。
还有另一个Python脚本,它负责实际处理文件,使用HandBrake的命令行界面来转换文件。同样也是每分钟运行一次,使用launchctl。
在第二个脚本中,一旦转换完成,我想启动一个AppleScript,将文件导入到iTunes,并添加一些特定的信息。
所以,流程是:新的电影文件在文件夹中 -> 文件被排队 -> 文件被转换 -> 文件被导入到iTunes。
我遇到的问题是关于AppleScript的部分。如果我通过终端运行我的第二个Python脚本(负责转换和导入的那个),一切都很顺利。文件被转换后,AppleScript会把它导入到iTunes。但如果是launchctl来启动这个脚本,似乎就跳过了AppleScript的部分。
这是Python中与AppleScript相关的代码
import subprocess, shlex
cmd = "/usr/bin/osascript /Users/alexis/Developer/Media/import_iTunes.scpt '{0}' ".format(file)
subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
还有AppleScript的部分(我为了简化去掉了一些内容)
on run argv
set newTrackPath to posix file (item 1 of argv)
tell application "iTunes"
activate
set newTrack to add newTrackPath
end tell
end run
我尝试过使用subprocess.call(cmd)、os.system(cmd)和subprocess.Popen(cmd)。
问题似乎是,当这个Python脚本是通过launchctl启动时,无法从Python中启动osascript。
有没有人能解释一下或者提供解决办法?
谢谢
1 个回答
你想知道launchd
是以哪个用户身份运行Python脚本的吧?我猜你是以当前用户的身份在运行它;如果不是,那你应该这样做。
你的shlex
代码有点多余,而且不太安全(比如,当你尝试导入I Wanna Be Bobby's Girl.mp3
时会发生什么)。直接把参数列表组装起来就行了。
你的Python代码没有等子进程完成,也没有检查它的返回代码,所以如果出现错误,你根本不会知道。你需要解决这个问题:如果你知道子进程出错的原因,排查问题会容易得多。
如果你不关心AppleScript的输出,可以直接使用check_call
这个方便的函数,如果AppleScript失败,它会抛出一个异常:
subprocess.check_call(["/usr/bin/osascript",
"/Users/alexis/Developer/Media/import_iTunes.scpt", file])
(或者,如果你真的有理由直接使用Popen
,并且为了“简单”省略了相关代码,麻烦把它展示出来,这样我们才能看到你到底在做什么。)
你可能还想调整一下你的launchd
XML,这样你的Python脚本的错误输出就能写入一个文件,方便查看。