【问题标题】:AppleScript - wait for do shell script doneAppleScript - 等待完成 shell 脚本
【发布时间】:2020-03-21 01:57:22
【问题描述】:

我编写了一个命令行工具来从 IMDB 获取电影信息。它在 JavaScript 中,称为 movinfo。我在 AppleScript 中运行它:

tell application "System Events"
    set movT to "Back-to-the-future"
    set exportPath to "export PATH=$PATH:/usr/local/bin:;"
    set oriInfo to do shell script exportPath & "movinfo " & quoted form of movT
    return oriInfo
end tell

效果很好。但有时 movinfo 需要很长时间才能从 Internet 获取信息。所以我想添加一个函数来检查获取是否完成。我首先尝试“忽略...结束忽略”结构:

tell application "System Events"
    ignoring application responses
        set movT to "Back-to-the-future"
        set exportPath to "export PATH=$PATH:/usr/local/bin:;"
        set oriInfo to do shell script exportPath & "movinfo " & quoted form of movT
    end ignoring
end tell

tell application "System Events"
    repeat 30 times
        try
            return oriInfo
            exit repeat
        on error
            delay 1
        end try
    end repeat
    do shell script "killall System\\ Events"
end tell

但这不起作用。也许我可以使用命令行工具来完成这项工作。但是我真的不太了解 JavaScript 和 CLI。我想在 AppleScript 中执行此操作。 希望有人能告诉我代码有什么问题,或者如何在 AS 中执行此操作?

【问题讨论】:

  • 您的整个系统事件代码毫无意义。 do shell script 属于标准(脚本)添加并且不发送 Apple 事件。 AppleScript 的基本设计是同步的,因为常规编译的脚本没有运行循环。而且do shell script 应该是同步运行的。显然 javascript 是异步的,所以可以管理时间。
  • @vadian,谢谢,我在谷歌上搜索了一些关于同步和异步之间的差异。它们对我来说是新知识。
  • 同步意味着代码在单个线程上串行执行。异步意味着代码在多个线程上并发执行。

标签: applescript


【解决方案1】:

请注意,我没有 movinfo 实用程序(您忽略了提供链接),因此我无法对此进行测试,但它应该可以按面值计算。

首先(正如 vadian 在 cmets 中指出的那样)你不需要系统事件告诉你使用它们的块,所以我已经对其进行了重组。这里的技巧是分离 movinfo 实用程序,使其作为独立于脚本的进程运行,将电影信息写入位于~/movieInfo.txt 的文件中。然后脚本从do shell script 中恢复进程 pid,并等待实用程序结束,使用系统事件来测试具有该 pid 的进程是否仍在运行。当过程结束时, 该脚本将文件中的信息读回oriInfo 变量。有关 unix 技巧的问题,请参阅:Technote 2065

-- set output file path
set movieInfoFile to POSIX path of (path to home folder from user domain) & "movieInfo.txt"

set movT to "Back-to-the-future"
set exportPath to "export PATH=$PATH:/usr/local/bin:;"
-- run and detach utility, returning its process id
set procID to do shell script exportPath & "movinfo " & quoted form of movT & " &> " & movieInfoFile & " & echo $!"

repeat 30 times
    tell application "System Events"
        -- test if pid is still active
        set isStillRunning to count of (every process whose unix id is procID)
    end tell
    if isStillRunning = 0 then
        --not active, so proceed
        exit repeat
    else
        delay 1
    end if
end repeat

-- pull info from file 
set fp to open for access movieInfoFile
set oriInfo to read fp
close access fp

【讨论】:

  • 很好的信息。我搜索了“macos 上进程的 unix id”。在 Google 中找不到任何有用的东西。在终端顶部命令的输出屏幕上,我看到诸如“PID”、“PPID”、“UID”之类的词。它们看起来不像unix id。但我会继续测试你的代码。
  • PID 是进程 ID,系统事件将其称为 unix id。 PPID 是父进程(产生您正在查看的进程的进程)的进程 ID。 UID 是用户 ID(拥有该进程的用户的 ID)。在您习惯之前,这一切都非常令人困惑。
猜你喜欢
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多