简体   繁体   English

如何等待 osascript 产生结果

[英]How to wait for osascript to produce a result

sometimes my AppleScript code seems to fail, on other machines is works.有时我的 AppleScript 代码似乎失败,在其他机器上是有效的。

I run this AppleScript code as heredoc from inside a shell script.我从 shell 脚本中将这个 AppleScript 代码作为 heredoc 运行。 The shell script is a postinstall script run by a pkg installer and runs as root: 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 "................................."

Sometimes the targeted app bundle gets a tag, sometimes not.有时目标应用程序包会获得标签,有时不会。 If I uncomment the last sleep in my code sample, then everything works as expected.如果我取消注释代码示例中的最后一个睡眠,那么一切都会按预期工作。

Even on 2 different VMs we have the tag always created on one VM and failing to create on the other.即使在 2 个不同的虚拟机上,我们也总是在一个虚拟机上创建标签,而在另一个虚拟机上创建失败。

Is there a proper way to wait for the result of the add tag operation and then proceed with the script?是否有适当的方法等待添加标签操作的结果,然后继续执行脚本? Or is the sleep 10 command a reliable solution to have it run on dozens or event hundreds of Macs without failing on even a few?或者 sleep 10 命令是否是一个可靠的解决方案,可以让它在数十台或数百台 Mac 上运行而不会在少数几台上失败?

kind regards,亲切的问候,

Robert罗伯特

First, it's always good idea to avoid scripting the Finder (a busy app that can produce odd delays and errors in scripts).首先,最好避免编写 Finder 脚本(一个繁忙的应用程序,可能会在脚本中产生奇怪的延迟和错误)。 Since you're using AppleScriptObjC anyway, you can get the URL you need from NSWorkspace.由于您无论如何都在使用 AppleScriptObjC,因此您可以从 NSWorkspace 获得所需的 URL。 Then all you need to do is add a repeat/check/delay loop that looks to see if the tag has been added.然后您需要做的就是添加一个重复/检查/延迟循环,以查看是否已添加标签。

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:

I fixed one (potential) error in your script;我修复了您脚本中的一个(潜在)错误; see the text comment inline.见内联文本注释。

This assumes that you are only adding a single tag.这假设您只添加一个标签。 If you want to add (and check) for multiple tags, you'll need to complexity checkTag:forURL .如果要添加(并检查)多个标签,则需要复杂性checkTag:forURL Also, I haven't done much with error handling (any case where for some reason adding the tag fails) except toss up an alert.此外,除了发出警报外,我还没有做太多错误处理(任何情况下由于某种原因添加标签失败)。 I used a contingent repeat loop to keep it from going on infinitely on failure, but you may want it to fail silently, or do something else at that point.我使用了一个条件重复循环来防止它在失败时无限循环,但你可能希望它静默失败,或者在那时做其他事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM