Safariを定刻に自動操作するアプレットについて

MBA(Sierra)にて、AppleScriptで書いた、Safariを自動操作するアプレットを、Terminalからcrontabで定刻に実行しています。

ただし、自動実行において問題がありますので、解決方法を教えていただければと思います。


先ず、ログイン状態では、定刻にアプレットが、即ちSafariが自動操作されます。

一方、該アプレット内では、一連のSafari操作完了後に、次の定刻でも自動操作が行える様に、一定時間後にMBAが自動復旧する設定を行なった後に、スリープモードへ移行しています。

その後、スリープモードから定時にMBAは自動復旧するのですが、そのままのログアウト状態(つまりログイン画面のまま)では、crontabにより該アプレットが定刻に実行されたりされなかったりします。


しかし、実行されない原因の切り分けも出来ていません。

例えば、スリープモードから復旧した時点でネットワーク接続が確立されていないことがあるために、Safari実行、即ちアプレット完遂に失敗しているのかどうかさえ分かっていません。

どのようにして、原因の切り分けを行えば宜しいでしょうか

MacBook Air (13-inch Mid 2013), macOS Sierra (10.12.1), Safari 10.0.1

投稿日 2016/10/26 22:04

返信
返信: 24

2016/11/16 05:30 Hiro__S への返信

> あれ?動きませんか?当方 (OS X 10.6.8) では動きますよ。

失礼しました。 -S を見逃してました。m(_ _)m


> ただ、ログアウトさえしなければ、こんな面倒なことをしなくても良いと思います。というか、スリープしたのになぜログアウトするのかが分からないんですよね...。

実際のところは69+さんしかわかりませんが、スリープからの復帰時にパスワードを必要する設定にしていて、そのパスワードが必要な状況(ログイン済みだがスクリーンがロックされている状態)をログアウトの状態と混同されているのではと解釈してます。

2016/11/16 06:47 ToMi への返信

なるほど。これでやっと分かりました。ToMi さんすごい!


スリープが解除され、パスワードを入力するダイアログが表示されてる裏で、スクリプトが実行さるのも確認できました (OS X 10.6.8 で launchd)。また、そのまま放っておくと、システム環境設定の設定とは関係なく、30秒程度でディスプレイのみがスリープします。


この挙動が Sierra で変更された?ということなんですね。多分...。launchd を試してダメだったら、スリープ解除時にパスワードを要求しないようにするしかないのでしょうかね。

2016/11/16 08:42 ToMi への返信

Piyomaruさま、ni_kiさま、ToMiさま、Hiro.Sさま、ご回答、ありがとうございました。


すみませんが、まとめて返答させていただきます。

おっしゃる通りスリープ復帰時にパスワード要求する設定にしています。

私もスリープだけで、ログアウトしているつもりはなかった(というか勿論ログアウトはしていない)のですが、

sudo コマンドを使っていることから、確かに混同しているように思われますよね。


ではなぜsudoコマンドをかませているかと言いますと、EL Capitanでは(曲がりなりにも)動いていたのに、Sierraにしてから動かなくなったため、スリープ復帰時のパスワード要求画面の裏でスクリプト実行するには、root権限が必要になったのかと思ったからです。


よって、ターミナルにてcron実行するときにも、

$ sudo crontab -e

などとしておりました。


つまりOSに依らず云々というのは、Sierraでの変更(?)に、どう対処したら良いのでしょうか?という位の意味でした。

分かりにくくてすみませんでした。

2016/11/16 08:54 Hiro__S への返信

Hiro.Sさま、ご回答、ありがとうございました。


分かりにくくて重ね重ね、すみません。

私はSierraでは、スリープ復帰後、30秒程度での画面オフと同時に、Mac自身も再びスリープに入ってしまうように思っています。

なぜかと言いますと、その時点でスクリプト実行が途切れてしまっていますので(画面オフだけですと、途切れない筈ですよね?)。

勿論、システム設定で「ディスプレイがオフのときにコンピュータを自動でスリープさせない(電源アダプタ)」設定にしていても、です。


ご教授の通り、launchd を試してみたいと思いますが、同居人がいるためパスワード要求は外せないので、ダメだった時は、また考えます。


2016/11/16 09:31 69_Plus への返信

とりあえず気になったところだけ。

よって、ターミナルにてcron実行するときにも、

$ sudo crontab -e

などとしておりました。

「sudo crontab〜」と「crontab〜」では行われる内容が異なります。

「crontab〜」の場合はそのユーザのcrontabデータを取り扱い、そこに記述された内容はそのユーザとして実行されます。それに対し、「sudo〜」の場合はrootユーザのcrontabデータを取り扱うことになり、そこに記述された内容はrootユーザのコマンドとして実行されます。したがって後者の場合はそのコマンドやスクリプト内で明確に指定しない限り特定のユーザ(ログイン中のユーザ等)と紐づけられることはありません。


なお、launchd で取り扱うものにはLaunchAgentとLaunchDaemonの2種類がありますが、以下のように振り分けられていて、Daemonは起動からシャットダウンまで有効ですがAgentはユーザがログインしているときのみ有効になります。(以下、man launchdより抜粋)

~/Library/LaunchAgents Per-user agents provided by the user.

/Library/LaunchAgents Per-user agents provided by the administrator.

/Library/LaunchDaemons System-wide daemons provided by the administrator.

/System/Library/LaunchAgents Per-user agents provided by Apple.

/System/Library/LaunchDaemons System-wide daemons provided by Apple.

ちなみに、/System以下への変更(追加・削除)はEl Capitan以降(SIPにより、基本的には)できなくなっています。

2016/11/16 09:46 69_Plus への返信

パスワード要求は外せない


スクリーンのロックはキーチェーン.app からも可能だと思うのでそれを使ってみるとか。また、スクリーンのロック中にアプレットの実行が止まる...ということなら、当該アプレットで AppNap を無効にしてみてはどうでしょうか?


Sierra 未導入なので未検証ですが、一応、ご参考まで。

2016/11/24 05:51 Hiro__S への返信

すみません。アプリケーション名を誤って書いてました。


誤: キーチェーン.app

正: キーチェーンアクセス.app


ーーーーー


さて、次の3点を確認してはどうでしょうか?


・App Nap

・GUI スクリプティング (Safari を操作するために使ってるなら)

・do JavaScript (使ってるなら)


まず、App Nap については、当方には環境がなく確認できませんが、過去にこれが原因でアプレットが期待どおりに動かない...というやり取りをしたことがあります。無効にして様子を見るのも悪くないかなと。


次に、GUI スクリプティングですが、スクリーンをロックした状態だと、当方 (Mac OS X 10.6.8 / Safari 5.1.10) でも動きません。おそらく Safari を最前面にできないからだと思います。もし、この仕組みを使ってるなら、諦めた方が良いかもしれません。


do JavaScript については、Safari 最新版では制限が加えられて、開発メニューから都度有効にする必要があるようですが、その操作を GUI スクリプティングでやってる場合は、スクリーンをロックした状態では動かないかもしれません。なので、予め有効になっているかを確認してみると良いでしょう。


ということで、スクリーンをロックした状態でアプレットが正常に動くかを確認してみてはどうでしょうか。で、期待どおりに動くなら、スリープから復帰した際の挙動を観察して問題点を探すと。

2016/11/24 07:17 Hiro__S への返信

Hiro.S さん、ありがとうございます。


確認ですが「スクリーンをロックした状態」というのは「画面スリープ」の真っ暗になった状態ではなく、パスワード待ちのロック画面のことですね?

こちらではロック画面ですと、その裏でSafariはスクリプトから操作できていましたが、真っ暗な画面スリープになった状態ですと操作できませんでした。


つまり「Sierra になってからはスリープから復旧後30秒程度でMacが再びスリープに入ってしまい、スクリプトが中断している」というのはどうやら私の思い込みで、やはりHiro.S さんがおっしゃっていました通り、従来通り、復旧後30秒程度で画面スリープに入ったため(GUIスクリプティングにより?)、スクリプトが中断していたというのが真相の様です。


実際、その後、ロックを解除すると(中断したところから)Safariの操作が再開されました。

間違った情報を流してすみませんでした。

それにしても、画面スリープ状態だとSafariが操作できなくなるとは思いつきませんでした。

そう言われれば、確かに思い当たる節はありましたが。


ちなみにここまでの状況を一応まとめておきますと次の通りです。

スリープからの自動復旧をスクリプトで設定した通りに、cron で実行指定した時刻の直前(数秒前)に復旧し、パスワードを要求するロック画面の裏でSafari操作スクリプトが実行されるが、30秒弱でMacが画面スリープに入ってしまうと、スクリプトが中断されてしまいます。

その後、手動で画面スリープを解除すると、中断したところからスクリプトが再開されます。


これから、Ampetamine でも打って、スリープ解除後(Wi-Fi接続をトリガーとして)5分程度、画面オフしないようにできないか試してみます。

2016/11/25 03:46 69_Plus への返信

確認ですが「スクリーンをロックした状態」というのは「画面スリープ」の真っ暗になった状態ではなく、パスワード待ちのロック画面のことですね?


あ〜、すみません。説明が足りませんでした。キーチェーンアクセス > メニューバー > ステータスメニューから「スクリーンをロック」した後の状態を示したつもりでした。つまり、画面スリープ、パスワード待ち、両方ともです。


重要なポイントとなりそうなので、試したことを詳しく説明しておきます。以下長文になりますがご勘弁を。


ーーーーー


下記は、画面スリープ及びパスワード待ちの画面で AppleScript の挙動を観察するために用いたスクリプトです。音が出た方が分かりやすいので iTunes をコントロールするものにしました。


概要

スクリプトを実行すると、30秒待機した後に、「iTunes で曲の再生を開始、30秒待機、再生を停止、1秒待機」の一連の動作をを3回繰り返します


下準備

  • iTunes を起動して適当なプレイリストを選択しておく
  • キーチェーンアクセスの環境設定で、「メニューバーに状況を表示」を ON にしておく


使い方

  1. スクリプトを実行
  2. キーチェーンアクセスのメニューバーのステータスメニューから「スクリーンをロック」
  3. 画面スリープのままにしたり、(キーボード操作等で) パスワード待ちの状態にしながら様子を観察


コードは通常スクリプトの「A」と GUI スクリプティングを使った「B」の2種類でこんな感じ。


A: 通常

on run my _delay(30) repeat 3 times my itunes_play() my _delay(30) my itunes_stop() my _delay(1) end repeat end run on itunes_play() tell application "iTunes" to play end itunes_play on itunes_stop() tell application "iTunes" to stop end itunes_stop on _delay(n) do shell script "sleep " & quoted form of (n as text) end _delay


B: GUI スクリプティング

on run my _delay(30) repeat 2 times my itunes_play() my _delay(30) my itunes_stop() my _delay(1) end repeat end run on itunes_play() tell application "iTunes" to stop tell application "System Events" tell process "iTunes" set frontmost to true # # iTunes > メニューバー > 制御 > 再生 をクリック # ・iTunes のバージョンにより異なる場合は適宜書き換える # ・画面スリープとパスワード待ちの場合は動かない? # click menu item 1 of menu 1 of menu bar item 6 of menu bar 1 end tell end tell end itunes_play on itunes_stop() tell application "System Events" tell process "iTunes" set frontmost to true # # iTunes > メニューバー > 制御 > 停止 をクリック # ・iTunes のバージョンにより異なる場合は適宜書き換える # ・画面スリープとパスワード待ちの場合は動かない? # click menu item 3 of menu 1 of menu bar item 6 of menu bar 1 end tell end tell end itunes_stop on _delay(n) do shell script "sleep " & quoted form of (n as text) end _delay


動作確認

  • Mac OS X 10.6.8
  • iTunes 11.3.1 (2)


ーーーーー


結果としては、「A」は画面スリープ、パスワード待ちのどちらでも問題なく動きました。


一方、「B」は、どちらの状態でも期待どおりに動作しませんでした。click が空振りしてるものと思われます。また、スクリプト動作中にパスワードを入力してロック画面を解除すると、次のループからは正常動作。これは 69+ さんがおっしゃったとおりかなと。


あと、通常どおり iTunes を手動で操作できる状態では「A」「B」どちらも正常に動きました。ま、これは当たり前ですね。


ーーーーー


それと、もし、以下の (キーチェーンアクセスからスクリーンをロックする) スクリプトが Sierra でも動くなら、

do shell script "python <<'EOF' # coding: utf-8 from Foundation import NSURL, NSBundle furl = NSURL.fileURLWithPath_( '/Applications/Utilities/Keychain Access.app/Contents/Resources/Keychain.menu/') bundle = NSBundle.bundleWithURL_(furl) keychain_extra = bundle.principalClass().alloc().init() keychain_extra._lockScreenMenuHit_(None) EOF"


こんな感じにすると、キーチェーンアクセスの手動での操作は不要となり、検証がしやすくなります。

on run my lockscreen() my _delay(30) repeat 3 times my itunes_play() my _delay(30) my itunes_stop() my _delay(1) end repeat end run on lockscreen() do shell script "python <<'EOF' # coding: utf-8 from Foundation import NSURL, NSBundle furl = NSURL.fileURLWithPath_( '/Applications/Utilities/Keychain Access.app/Contents/Resources/Keychain.menu/') bundle = NSBundle.bundleWithURL_(furl) keychain_extra = bundle.principalClass().alloc().init() keychain_extra._lockScreenMenuHit_(None) EOF" end lockscreen on itunes_play() tell application "iTunes" to play end itunes_play on itunes_stop() tell application "iTunes" to stop end itunes_stop on _delay(n) do shell script "sleep " & quoted form of (n as text) end _delay


動作確認

  • Mac OS X 10.6.8
  • iTunes 11.3.1 (2)
  • Python 2.6.1 / PyObjC 2.2b3 (Mac OS X 10.6.8 に最初から入ってるやつ)


なお、lockscreen() は下記を参考にしました。


AppleScriptであれこれする > キーチェーンの「スクリーンをロック」を実行する。lockScreen

http://memogakisouko.appspot.com/AppleScript.html


もし、これらのスクリプトを試す場合は、何があっても対処できるようにデータのバックアップ体制を整えてからにしてください。


以上、ご参考まで。

このスレッドはシステム、またはAppleコミュニティチームによってロックされました。 問題解決の参考になる情報であれば、どの投稿にでも投票いただけます。またコミュニティで他の回答を検索することもできます。

Safariを定刻に自動操作するアプレットについて

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