答えにはいくつかの部分があります。
非同期do shell script
:通常、do shell script
シェルコマンドが完了した後にのみ戻ります。つまり、シェル内のプロセスを操作することはできません。ただし、実行するシェルコマンドをバックグラウンドdo shell script
で実行することにより、非同期で実行するコマンドを取得できます。
do shell script "some_command &> /target/output &"
–これはシェルコマンドを起動した直後に戻ります。コマンドの出力は返されないため、たとえばファイルでそれを自分でキャッチする必要があります(または、/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
進行状況ダイアログを閉じるためにシェルスクリプトがいつ実行されるかを決定します。これは、シェルコマンドが非同期で動作するため、興味深い部分です。最善の策は、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
バックグラウンドシェルコマンドの出力をキャプチャする必要がある場合は、上記のように、ファイルにリダイレクトし、完了したらそのファイルのコンテンツを読み取る必要があります。