コミュニティでの投票について

コミュニティでの投票について解説した記事を公開しました。

Apple ID の不正利用を確認する方法

Apple ID の使い方や不正利用を確認する方法についてご紹介しています。

しばらく返答が寄せられていないようです。 再度ディスカッションを開始するには、新たに質問してください。

AppleScriptでTerminalにKeystrokeが送信できない

Catalina 10.15.7 AppleScriptで、TerminalにKeyStrokeが送信できません。

「スクリプトエディタにはキー操作の送信は許可されません」となります。」

スクリプトは、こんな感じです

on run

tell application "Terminal"

do script "cd カレントパス" & in front window

do script "./パールスクリプト.pl" in front window

end tell

tell application "System Events"

tell process "Terminal"

activate

keystroke "c" using {control down}

end tell

end tell

end run


「パールスクリプト.pl」は、標準入力から「control+c」が来るまでひたすら待つと言うスクリプトなのですが、

「tell application process "Terminal"」としても、同じエラーでした。

よきアドバイスをお願いします。

MacBook Pro 16″, macOS 10.15

投稿日 2021/06/27 10:53

返信
スレッドに付いたマーク ランキングトップの返信

投稿日 2021/06/27 15:00

> スクリプトエディタにはキー操作の送信は許可されません」となります


AccessibilityにScript Editorを加える必要があります。



また、いつ頃からだったか覚えていませんが、tell processは使えなくなっています。(間違っていたら指摘をお願いします>識者の方々

System Eventsは、それが呼び出された時、アクティブになっているアプリに作用します。


on run
	tell application "Terminal"
		activate
		do script "sleep 100"
	end tell
	delay 1
	tell application "System Events"
		keystroke "c" using {control down}
	end tell
end run


返信: 12
スレッドに付いたマーク ランキングトップの返信

2021/06/27 15:00 yoshi.merveille への返信

> スクリプトエディタにはキー操作の送信は許可されません」となります


AccessibilityにScript Editorを加える必要があります。



また、いつ頃からだったか覚えていませんが、tell processは使えなくなっています。(間違っていたら指摘をお願いします>識者の方々

System Eventsは、それが呼び出された時、アクティブになっているアプリに作用します。


on run
	tell application "Terminal"
		activate
		do script "sleep 100"
	end tell
	delay 1
	tell application "System Events"
		keystroke "c" using {control down}
	end tell
end run


2021/06/29 00:02 hohokihai への返信

hohokihai さんによる書き込み:

一応、tell application processは機能しているのかな?でも、いまいち使い所がよく分かりません。ネストの位置も。


こんな感じでどうでしょうか?(Mojave や High Sierra ではこれで大丈夫です)


on run
    tell application "Terminal"
        # 省略
    end tell
    tell application "System Events"
        tell application process "Terminal"
            set frontmost to true -- Terminal を最前面に
            keystroke "c" using {control down}
            delay 1
        end tell
    end tell
end run


あと、do shell script については、Technical Note TN2065 に書いてあるように、tell ブロック外か tell me 内に置いてみるとか。


on run
    tell application "Terminal"
        # 省略
    end tell
    tell application "System Events"
        tell application process "Terminal"
            set frontmost to true -- Terminal を最前面に
            keystroke "c" using {control down}
            delay 1
        end tell
        tell me to do shell script "echo 1" -- A案
    end tell
    do shell script "echo 2" -- B案
end run


ご参考

Technical Note TN2065 > Does it make a difference which application I tell to do shell script?


2021/06/30 11:20 yoshi.merveille への返信

プログラムの実行時間と実行時のCPU時間を計測する、timeコマンドというものがあり、開発時によく使われます。

AppleScriptの記述を色々と変えながら、時間を計測してみるのも良いかと思います。


"open"コマンドにより、もう一つTerminalを立ち上げてそちらでコマンドを実行し、最初からあるTerminalで計測します。

timeコマンドを使っている際に、killallしてしまうと、計測画面まで閉じられてしまうのでこれは使えません。


open -g -n -a Terminal
time osascript Untitled.scpt


先ずは、Untitled.scptを作って計測を試みましたが、うまく動きませんでした。


Untitled.scpt:

on run
	tell application "Terminal" --後から立ち上げたTerminalが呼ばれる
		activate
		do script "sleep 100" in front window
	end tell
	delay 1
	tell application "System Events"
		tell application process "Terminal" --最初に立ち上げたTerminalが呼ばれる
			set frontmost to true
			keystroke "c" using {control down}
		end tell
	end tell
end run


次に、Untitled2.scptとUntitled3.scptを作って計測してみました。


Untitled2.scpt:

on run
	tell application "Terminal"
		activate
		do script "sleep 100" in front window
	end tell
	delay 1
	tell application "Terminal"
		activate
	end tell
	tell application "System Events"
		keystroke "c" using {control down}
	end tell
	delay 1
	tell application "Terminal"
		quit
	end tell
end run


Untitled3.scpt:

on getProcList(appName)
	set myList to {}
	tell application "System Events"
		set myList to unix id of every process whose name ends with appName
	end tell
	return myList
end getProcList
on run
	set myProc to end of getProcList("Terminal")
	tell application "Terminal"
		activate
		do script "sleep 100" in front window
	end tell
	delay 1
	tell application "System Events"
		set frontmost of every process whose unix id is myProc to true
		keystroke "c" using {control down}
	end tell
	delay 1
	tell application "System Events"
		set frontmost of every process whose unix id is myProc to true
		keystroke "q" using {command down}
	end tell
end run



プロセスのリストを得る方法は、やはり時間が掛かってしまうようです。しかし、どれが正解かに拘らず、色んなパターンを考えるのが上達のコツだと思っていますので、自由にやって下さいませ。

2021/06/27 17:24 hohokihai への返信

ありがとうございました。解決です。

ただ、ScriptEditor上ではうまく行くのですが、「スクリプト.app」をaccessbilityに登録して実行しても、

エラーは出ませんがKeyStrokeを拾ってくれません。

tell application "Terminal"

activate

delay 0.5

tell application "System Events"

delay 0.5

keystroke "c" using {control down}  <--エラーは出ませんが、パールスクリプトにCtrl+cが届きません

tell application process "Terminal"

set pid to unix id

do shell script "kill -9 " & (pid as string)

end tell

end tell

end tell


以上です。ありがとうございました。

2021/06/27 18:56 hohokihai への返信

ありがとうございます。解決しました。

Ctrl+c を子プロセスのパールスクリプトが拾うまでに、次のコマンド(do shell script "kill -9")が動いていたようです。


tell application "Terminal"

activate

tell application "System Events"

keystroke "c" using {control down}

delay 1        <---これで、Terminalの"kill -9"が追い越さなくなりました。

tell application process "Terminal"

set pid to unix id

do shell script "kill -9 " & (pid as string)

end tell

end tell

end tell


ありがとうございました。


2021/06/28 15:22 yoshi.merveille への返信

本筋とは外れますが、tell application processについてです。


tell application "Terminal"
	activate
	do script "sleep 100"
end tell
delay 1 --この間にDesktopをクリックしてFinderをactiveにする
tell application "System Events"
	tell application process "Terminal"
		keystroke "c" using {control down} --これは実行されない
	end tell
	delay 1
	tell application process "Terminal"
		do shell script "killall Terminal" --これは実行される
	end tell
end tell


一応、tell application processは機能しているのかな?でも、いまいち使い所がよく分かりません。ネストの位置も。


tell application "Terminal"
	activate
	do script "sleep 100"
end tell
delay 1 --この間にDesktopをクリックしてFinderをactiveにする
tell application "System Events"
	keystroke "c" using {control down} --これは実行されない
end tell
delay 1
tell application "Terminal"
	do shell script "killall Terminal" --これは実行される
end tell


これでも動作は同じ。スクリプトなので行数は少ない方がいいし。どう思われますか?

2021/06/28 15:56 hohokihai への返信

ありがとうございます。

「ネスト」が問題ですか、ご助言ありがとうございます。

理解不足ですが、別の(知らない人?)が「Terminal」を複数起動していたらと思って、こうしました。

正しいかどうかは、まったくわかりません。


on processNames(apName)

set myList to {}

tell application "System Events"

set myList to name of (application processes) whose name contains apName #whose background only is false

end tell

return myList

end processNames

on run

tell application "Terminal"

do script "./パール.pl" in front window

end tell

repeat with proc in processNames("Terminal")

tell application proc

activate

tell application "System Events"

keystroke "c" using {control down}

delay 1

tell application process proc

set pid to unix id

do shell script "kill -9 " & (pid as string)

end tell

end tell

end tell

end repeat

end run


ありがとうございました。



2021/06/29 11:07 Hiro__S への返信

度々、ありがとうございます。

ネストと「tell process」が駄目(?)だと言うことですね。

でも「tell process」でないと「unix id」が取れないんです。

で、こうしました。


repeat with proc in processNames("Terminal")

tell application proc

activate

tell application "System Events"

keystroke "c" using {control down}

delay 1

end tell

do shell script "killall " & proc

end tell

end repeat


でも、これだと「repeat」の意味がなくなるのかな、と。


2021/06/29 16:10 hohokihai への返信

ありがとうございます。

B案にします。


Hiro.Sさんの

>"set frontmost to true"を入れると、Terminalプロセスの呼び出しが意味を持ちますね!

>"do shell script"は、"so for optimal results always put do shell script calls outside of any tell block"とのことで、B案に賛成です。

が、私のスキル(スクリプトをモノマネで書く程度)では理解できません。


お手数かけました。

ありがとうございました。


2021/06/27 18:40 yoshi.merveille への返信

> 「スクリプト.app」をaccessbilityに登録して実行しても、

> エラーは出ませんがKeyStrokeを拾ってくれません。


こちらでは、KeyStroke実行してくれますけど...



ちなみに、accessbilityのチェックを外すとエラーが出ます。



AppleScriptでTerminalにKeystrokeが送信できない

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple ID を使ってご参加ください。