如何等待osascript产生结果

时间:2020-07-10 11:44:32

标签: bash macos applescript osascript pkgbuild

有时候我的AppleScript代码似乎失败了,在其他机器上也可以使用。

我从外壳程序脚本中以heredoc的形式运行此AppleScript代码。 Shell脚本是由pkg安装程序运行的后安装脚本,并以root身份运行:

#!/bin/sh
set -x
logfile="/Library/Logs/EZEEP Connector Installer.log"

LogMessage()
{
  echo $(date) $1 >> "${logfile}"
}

LogMessage "................................."
LogMessage "Installer postinstall started ..."
LogMessage "................................."

# set file system tag 'Printing' on app bundle:
/usr/bin/osascript <<'EOD'
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

on addTags:tagList forPath:posixPath -- add to existing tags
    set aURL to current application's |NSURL|'s fileURLWithPath:posixPath -- make URL
    #display dialog aURL as string
    -- get existing tags
    
    set {theResult, theTags} to aURL's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
    if theTags is not missing value then -- add new tags
        set tagList to (theTags as list) & tagList
        set tagList to (current application's NSOrderedSet's orderedSetWithArray:tagList)'s allObjects() -- delete any duplicates
    end if
    aURL's setResourceValue:tagList forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
    
end addTags:forPath:

tell application "Finder"
    set thePath to (POSIX path of (application file id "com.thinprint.ezeep.Connector" as alias))
    
    my addTags:{"Printing"} forPath:thePath
end tell
EOD

#sleep 10


sudo -u ${USER} /usr/bin/osascript -e 'tell application "/Applications/ezeep Connector.app" to launch'

LogMessage "................................."
LogMessage " Installer postinstall finished ."
LogMessage "................................."

有时,目标应用程序捆绑包会获得标签,有时没有。如果我取消注释代码示例中的最后一次睡眠,那么一切都会按预期进行。

即使在2个不同的VM上,我们也总是在一个VM上创建标签,而在另一个VM上却创建失败。

是否有适当的方法等待添加标记操作的结果,然后继续执行脚本?还是sleep 10命令是一种可靠的解决方案,可以使其在数十台或几百台Mac上运行而不会在几台Mac上失败?

亲切的问候,

罗伯特

1 个答案:

答案 0 :(得分:0)

首先,避免编写Finder脚本(一个繁忙的应用程序,可能会在脚本中产生奇怪的延迟和错误)始终是个好主意。由于无论如何都在使用AppleScriptObjC,因此可以从NSWorkspace获取所需的URL。然后,您需要做的就是添加一个重复/检查/延迟循环,以查看是否已添加标签。

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set theURL to my findAppURLFromID:"com.thinprint.ezeep.Connector"
my addTags:{"Printing"} forURL:theURL
my checkTag:"Printing" forURL:theURL

(* get app package URL from NSWorkspace *)
on findAppURLFromID:appID
    set sharedWorkspace to (current application's NSWorkspace's sharedWorkspace)
    set appURL to sharedWorkspace's URLForApplicationWithBundleIdentifier:appID
    return appURL
end findAppURLFromID:

(* altered to accept URL directly *)
on addTags:tagList forURL:aURL
    set {theResult, theTags} to aURL's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
    if theTags is not missing value then
        set tagList to (theTags as list) & tagList
    end if
    (*
        I moved the following statement out of the 'if' block. This would not be
        called if the package file has no tags, so the script would feed an unaltered
        AppleScript list to 'setResourceValue:forKey:error'. That may work, dunno
        but better to put everything into the correct object format
    *)
    set tagList to (current application's NSOrderedSet's orderedSetWithArray:tagList)'s allObjects() -- delete any duplicates
    aURL's setResourceValue:tagList forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
end addTags:forURL:

(* checks every half second to see if the list of tags contains "Printing" *)
on checkTag:tagName forURL:aURL
    repeat 120 times
        set {theResult, theTags} to aURL's getResourceValue:(reference) forKey:(current application's NSURLTagNamesKey) |error|:(missing value)
        set tagList to (theTags as list)
        if tagList contains "Printing" then return
        delay 0.5
    end repeat
    display alert "tagging timed out after 1 minute"
end checkTag:forURL:

我修复了脚本中的一个(潜在)错误;请查看文字注释。

这假设您仅添加了一个标签。如果要添加(并检查)多个标签,则需要设置复杂度checkTag:forURL。另外,除了抛出警报之外,我在错误处理(由于某种原因添加标签失败的任何情况下)方面没有做太多事情。我使用了一个偶然的重复循环来防止它在失败时无限进行,但是您可能希望它无声地失败,或者在那时候做其他事情。