使用 ASObjC Runner 中止 Applescript 中的 shell 脚本命令 [英] Using ASObjC Runner to abort a shell script command in Applescript
问题描述
我的 AppleScript 中有 ASObjC Runner 代码显示进度do shell script
运行后的窗口.如何让进度窗口上的按钮杀死 shell 脚本?
I've got ASObjC Runner code in my AppleScript that shows a progress window once a do shell script
is run. How do I make the button on the progress window kill the shell script?
这是我的代码示例:
tell application "ASObjC Runner"
reset progress
set properties of progress window to {button title:"Abort", button visible:true, indeterminate:true}
activate
show progress
end tell
set shellOut to do shell script "blahblahblah"
display dialog shellOut
tell application "ASObjC Runner" to hide progress
tell application "ASObjC Runner" to quit
推荐答案
答案有几个部分:
异步
do shell script
:通常情况下,do shell script
只会在shell命令完成后返回,这意味着你不能作用于外壳内的进程.但是,您可以通过 do shell script 命令以异步执行="nofollow">背景它执行的shell命令,即
Asynchronous
do shell script
: normally,do shell script
only returns after the shell command has completed, which means you cannot act on the processes inside the shell. However, you can get ado shell script
command to execute asynchronously by backgrounding the shell command it executes, i.e.
do shell script "some_command &> /target/output &"
- 在启动 shell 命令后将立即返回.由于它不会返回命令的输出,因此您必须自己捕获它,例如在文件中(或者如果不需要,则重定向到 /dev/null
).如果在命令后附加 echo $!
,do shell script
将返回后台进程的 PID.基本上,做
– which will return immediately after launching the shell command. As it will not return the command’s output, you have to catch that yourself, for instance in a file (or redirect to /dev/null
if you don’t need it). If you append echo $!
to the command, do shell script
will return the PID of the background process. Basically, do
set thePID to do shell script "some_command &> /target/output & echo $!"
参见 Apple 的技术说明 TN2065.停止该进程是一个简单的事情,做 do shell script "kill " &PID
.
see Apple’s Technical Note TN2065. Stopping that process is then a simple matter of doing do shell script "kill " & thePID
.
连接ASObjC Runner的进度对话框只是轮询它的按钮被按下
属性并在<代码>真代码>:
Hooking into ASObjC Runner’s progress dialog is just a matter of polling its button was pressed
property and breaking on 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 命令异步运行.最好的办法是使用您检索到的 PID 来检查 ps
以检查进程是否仍在运行,即
Deciding when your shell script is done to dismiss the progress dialog: that is the interesting part, as the shell command operates asynchronously. Your best bet is to shell out to ps
with the PID you retrieved to check if the process is still running, i.e.
if (do shell script "ps -o comm= -p " & thePID & "; exit 0") is ""
当进程不再运行时将返回true
.
will return true
when the process is not running anymore.
留下以下代码:
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 命令的输出,则必须将其重定向到文件并在完成后读出该文件的内容,如上所述.
If you need to capture the output of your background shell command, you will have to redirect it to file and read out that file’s content when done, as noted above.
这篇关于使用 ASObjC Runner 中止 Applescript 中的 shell 脚本命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!