【问题标题】:How to wait for osascript to produce a result如何等待 osascript 产生结果
【发布时间】:2020-10-31 03:44:04
【问题描述】:

有时我的 AppleScript 代码似乎失败了,但在其他机器上可以正常工作。

我在 shell 脚本中将这个 AppleScript 代码作为 heredoc 运行。 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 个不同的虚拟机上,我们也总是在一个虚拟机上创建标签,而在另一个虚拟机上创建失败。

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

亲切的问候,

罗伯特

【问题讨论】:

    标签: bash macos applescript osascript pkgbuild


    【解决方案1】:

    首先,最好避免编写 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。此外,除了发出警报外,我对错误处理(任何由于某种原因添加标签失败的情况)做的不多。我使用了一个条件重复循环来防止它在失败时无限执行,但您可能希望它静默失败,或者在此时执行其他操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      相关资源
      最近更新 更多