答案有几个部分:
异步do shell script
:通常do shell script
只在 shell 命令完成后返回,这意味着你不能对 shell 内的进程进行操作。但是,您可以通过后台do shell script
执行它执行的shell命令来获得一个异步执行的命令,即
do shell script "some_command &> /target/output &"
– 将在启动 shell 命令后立即返回。由于它不会返回命令的输出,因此您必须自己捕获它,例如在文件中(或者/dev/null
如果您不需要它,则重定向到)。如果追加echo $!
到命令,do shell script
将返回后台进程的PID。基本上,做
set thePID to do shell script "some_command &> /target/output & echo $!"
请参阅Apple 的技术说明 TN2065。停止该过程是一件简单的事情do shell script "kill " & thePID
。
挂钩ASObjC Runner的进度对话框只需轮询其button was pressed
属性并继续true
:
repeat until (button was pressed of progress window)
delay 0.5
end repeat
if (button was pressed of progress window) then do shell script "kill " & thePID
决定何时完成 shell 脚本以关闭进度对话框:这是有趣的部分,因为 shell 命令是异步操作的。您最好的选择是ps
使用您检索到的 PID 来检查进程是否仍在运行,即
if (do shell script "ps -o comm= -p " & thePID & "; exit 0") is ""
true
当进程不再运行时将返回。
剩下的代码如下:
tell application "ASObjC Runner"
reset progress
set properties of progress window to {button title:"Abort", button visible:true, indeterminate:true}
activate
show progress
try -- so we can cancel the dialog display on error
set thePID to do shell script "blahblahblah &> /file/descriptor & echo $!"
repeat until (button was pressed of progress window)
tell me to if (do shell script "ps -o comm= -p " & thePID & "; exit 0") is "" then exit repeat
delay 0.5 -- higher values will make dismissing the dialog less responsive
end repeat
if (button was pressed of progress window) then tell me to do shell script "kill " & thePID
end try
hide progress
quit
end tell
如果您需要捕获后台 shell 命令的输出,则必须将其重定向到文件并在完成后读出该文件的内容,如上所述。