Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

カテゴリー: shell script

ステージマネージャのON_OFF

Posted on 11月 15, 2024 by Takaaki Naganoya

macOS 13で搭載された「ステージマネージャ」機能のオン/オフを行うAppleScriptです。

ステージマネージャは、最前面のアプリのウィンドウだけを表示するようにする仕組みで、iPadOSに搭載されたものがそのままmacOSにも搭載されました。ドラッグ&ドロップをこのステージマネージャに対して行えるのと、表示ウィンドウを最前面のものだけに切り替えるものです。

つまり、マルチウィンドウのGUIに不慣れなユーザーのために用意された機能です。Windowsユーザー向けに用意した、ともいえるでしょう。

このステージマネージャのOn/Offを行います。動作内容はご覧のとおり、単にshellコマンドを呼び出しているだけです。現在オンになっているかどうかも、defaults readコマンドで同様に実行できることでしょう。


▲真っ先にオフにして、二度とオンにすることはなかったステージマネージャ(画面左端)


▲元に戻ると安心します

AppleScript名:ステージマネージャのON_OFF
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/11/15
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set aBool to true
stageManagerControl(aBool) of me

delay 5

set aBool to false
stageManagerControl(aBool) of me

on stageManagerControl(aBool as boolean)
  set sText to "defaults write com.apple.WindowManager GloballyEnabled -bool " & (aBool as string)
  
do shell script sText
end stageManagerControl

★Click Here to Open This Script 

Posted in shell script System | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

マウントしたディスクイメージから元のdmgファイルのパスを取得

Posted on 10月 16, 2024 by Takaaki Naganoya

マウント中のディスクイメージ(.dmg)ファイルのパスを求めるAppleScriptです。

macOS 13.7.1上で作成し、15.1上でも動作確認していますが、それほど込み入った機能は使っていないので、OSバージョン依存はないことでしょう。

実際に、オープンソースのPDFビューワー「Skim」の各バージョンのdmgファイルをダウンロードして、sdef(AppleScript用語説明)ファイルを収集してバージョンごとの変化を追う作業を行なったときに、バージョン判定を行うために元のdmgファイルのパスを求める処理を行なったものです。


▲マウントしたディスクイメージ(Skim)


▲マウント元のディスクイメージファイル


▲マウントしたディスクイメージからパス情報を取得することで、一部ファイルを取り出してコピーする際にバージョン情報を反映させた

AppleScript名:マウントしたディスクイメージから元のdmgファイルのパスを取得.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2024/10/16
—
–  Copyright © 2024 Piyomaru Software, All Rights Reserved
—

use AppleScript
use framework "Foundation"
use scripting additions

set dName to "Skim"

–Disk Imageのマウントを確認
tell application "Finder"
  set dexRes to (get exists of disk dName)
end tell
if dexRes = false then error "指定のディスクイメージ「" & dName & "」はマウントされていません。" –マウントされていなかった

set aRes to getMountedDiskImageInfo("image-path : ") of me
–> "/Users/me/Downloads/Skim-1.4.6.dmg"

on getMountedDiskImageInfo(targMark)
  try
    set aRes to do shell script "hdiutil info"
  on error
    return false
  end try
  
  
set aResList to paragraphs of aRes
  
repeat with i in aResList
    set j to contents of i
    
if j begins with targMark then
      set aOff to offset of targMark in j
      
set aLen to length of targMark
      
set aRes to text (aLen + 1) thru -1 of j
      
return aRes
    end if
  end repeat
  
return false
end getMountedDiskImageInfo

★Click Here to Open This Script 

Posted in drive File path shell script | Tagged 13.0savvy 14.0savvy 15.0savvy | Leave a comment

ディスプレイをスリープ状態にして処理続行

Posted on 12月 3, 2023 by Takaaki Naganoya

特定のディスプレイのみ消灯して処理続行、という処理を行なってみたかったのですが、いろいろ調べた結果、すべてのディスプレイを消灯する方法しか見つかりませんでした。

それでも、寝る前に電子書籍1冊分のデータをPDFにすべて書き出して連結する、といったAppleScriptを実行するのに、ディスプレイをあらかじめスリープ状態にしたあとで、処理終了後にコンピュータごとsleepにしてもよさそうです。

1000ページ分の電子書籍のPages書類をすべてPDFに書き出して、ファイル名順に連結してもM1 Mac miniで7分ぐらいで処理できるので、この程度の処理だとディスプレイを消して処理する意義はそれほどないのかもしれませんけれども。

AppleScript名:ディスプレイをスリープ状態にして処理続行.scpt
do shell script "pmset displaysleepnow"
beep 10

★Click Here to Open This Script 

Posted in shell script System | Leave a comment

Keynoteの表の選択中のセルのデータをDeepLで翻訳して書き戻す

Posted on 1月 31, 2023 by Takaaki Naganoya

Keynoteの最前面の書類中の、現在表示中のスライドの表の選択中のセル中のテキストを取得してDeepLのREST APIを呼び出して指定言語に翻訳し、表のセルに翻訳後のテキストを書き戻すAppleScriptです。

DeepLのREST API呼び出しのためには、DeepL SE社のWebサイトで「DeepL API Free」(無料コース)か「DeepL API Pro」プランにサインアップして、API Keyを取得して、プログラムリスト中に記入したうえで実行してください。


▲実行前。Keynote書類上の表の翻訳対象のセルを選択して実行


▲実行後。Keynote書類上の表の翻訳対象のセルをに翻訳後の内容をストア

実際に使ってみると、けっこう翻訳に時間がかかるのと、一度翻訳した同じフレーズを再度翻訳させるのはコストがかかるため、ローカルに「翻訳キャッシュ」を作って、翻訳ずみの内容を再翻訳しないように工夫する必要がありそうです。

AppleScript名:Keynoteの表の選択中のセルのデータをDeepLで翻訳して書き戻す.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2023/01/30
—
–  Copyright © 2023 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property NSString : a reference to current application’s NSString
property NSCountedSet : a reference to current application’s NSCountedSet
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

set myAPIKey to "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
set myTargLang to "EN" –翻訳ターゲット言語

set aTableDat to returnSelectedTableCellDataOnCurrentSlide() of me
–> {"プロパティ項目", "データ型", "読み/書き", "内容(サンプル)", "説明"}

set nList to {}
repeat with i in aTableDat
  set j to contents of i
  
set tRes to translateWithDeepL(j, myAPIKey, myTargLang) of me
  
set the end of nList to tRes
end repeat

–表に翻訳した内容を書き戻す
storeSelectedTableCellDataOnCurrentSlide(nList) of me

on storeSelectedTableCellDataOnCurrentSlide(sList)
  tell application "Keynote"
    tell front document
      tell current slide
        try
          set theTable to first table whose class of selection range is range
        on error
          return false –何も選択されてなかった場合
        end try
        
        
tell theTable
          set cList to every cell of selection range
          
if (length of cList) is not equal to (length of sList) then error
          
          
set aCount to 1
          
repeat with i in cList
            set j to contents of i
            
tell j
              set value of it to (contents of item aCount of sList)
            end tell
            
set aCount to aCount + 1
          end repeat
        end tell
      end tell
    end tell
  end tell
end storeSelectedTableCellDataOnCurrentSlide

on returnSelectedTableCellDataOnCurrentSlide()
  tell application "Keynote"
    tell front document
      tell current slide
        try
          set theTable to first table whose class of selection range is range
        on error
          return false –何も選択されてなかった場合
        end try
        
        
tell theTable
          set vList to value of every cell of selection range
          
set cCount to count of column of selection range
          
set rCount to count of row of selection range
          
          
–複数行選択されていた場合にはエラーを返すなどの処理の布石
          
return vList
        end tell
      end tell
    end tell
  end tell
end returnSelectedTableCellDataOnCurrentSlide

–DeepLのAPIを呼び出して翻訳する
on translateWithDeepL(myText, myAPIKey, myTargLang)
  set sText to "curl -X POST ’https://api-free.deepl.com/v2/translate’ -H ’Authorization: DeepL-Auth-Key " & myAPIKey & "’ -d ’text=" & myText & "’ -d ’target_lang=" & myTargLang & "’"
  
try
    set sRes to do shell script sText
  on error
    error
  end try
  
  
set jsonString to NSString’s stringWithString:sRes
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
set tRes to aJsonDict’s valueForKeyPath:"translations.text"
  
if tRes = missing value then
    set erMes to (aJsonDict’s valueForKey:"message") as string
    
error erMes
  else
    return contents of first item of (tRes as list)
  end if
end translateWithDeepL

★Click Here to Open This Script 

Posted in REST API shell script Text | Tagged 12.0savvy 13.0savvy | Leave a comment

macOS 11でメニューバークロックのアナログ/デジタル切り替え

Posted on 6月 17, 2021 by Takaaki Naganoya

macOS 11は、サブマシンで検証用に入れておいたぐらいでメインマシンはずーっとmacOS 10.14.6のままでした。M1 Macを導入したのでメイン環境をmacOS 11に移行。

いままで(macOS 10.14.6で)メニューから手軽に切り替えられていたメニューバークロックのアナログ/デジタル切り替え。ふだんは見やすいデジタル表示で、画面キャプチャする際にはアナログ表示に切り替えていました。

これが、macOS 11ではメニューから直接切り替えられないのがストレスで、すぐに切り替え方を調べてmacOS標準搭載のスクリプトメニューから切り替えられるようにしてみました。現在の設定値を読み取ってトグル動作(アナログ→デジタル、デジタル→アナログ)を行います。

–> Watch Demo movie

AppleScript名:macOS 11_メニューバークロックのアナログ_デジタルトグル切り替え.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2021/06/17
—
–  Copyright © 2021 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.7"
use framework "Foundation"
use scripting additions

set cRes to (do shell script "defaults read com.apple.menuextra.clock.plist IsAnalog") as integer as boolean
set newBool to (not cRes) as string
do shell script "defaults write com.apple.menuextra.clock.plist IsAnalog -bool " & newBool
do shell script "killall ControlCenter"

★Click Here to Open This Script 

Posted in shell script System | Tagged 11.0savvy | Leave a comment

githubの機能でMarkdownをhtmlに

Posted on 8月 9, 2020 by Takaaki Naganoya

githubのREST APIを呼び出して、Markdownファイルの内容をHTMLにレンダリングするAppleScriptです。


▲他のプログラムに処理部分を組み込んで表示させたところ(本ScriptはただHTMLレンダリングするだけで表示しません)

MacDownなどのアプリケーションでMarkdownファイルをオープンする方法とコードの行数はどっこいどっこいですが、MacDownを必要としないので、どこの環境でも(インターネット接続していれば)実行できます。

志の低さが目を覆わんばかりの出来で、実に少ない行数でレンダリングできるものの、Markdownをサーバーに送ってレンダリングしてもらうので、処理速度は遅いです。あるいは、githubのREST API処理サーバーにつねに負荷がかかっているとか。

AppleScript名:githubの機能でMarkdownをhtmlに.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/08/09
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set mdFile to choose file of type {"net.daringfireball.markdown"} with prompt "Choose Markdown"
set mdStr to (read mdFile as «class utf8») as text

do shell script "curl -X POST https://api.github.com/markdown/raw -H ’Content-Type: text/plain’ -d " & quoted form of mdStr
set aString to result

return aString

★Click Here to Open This Script 

Posted in Markdown shell script | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy | Leave a comment

CPUのバイトオーダーを取得

Posted on 7月 22, 2020 by Takaaki Naganoya

実行中のコンピュータ(多分Mac)のCPUのバイトオーダーを取得するAppleScriptです。

これまで、MacのCPUは68k(Big Endian)→PowerPC(Big Endian)→Intel(Little Endian)と来て、次はARM。

一応、IntelとArmは同じLittle Endianなので問題は少ないはずですが、ARM DTKをお持ちの方は試してコッソリ教えていただけるとありがたいです。

この情報がAppleScriptで取得できると何か「いいこと」があるかですが、別にメリットはありません。

ただ、CPUの名前が取得できると、処理速度を推測できてよいでしょう。Intel CPUに対してApple Silicon(ARM)がどの程度のパフォーマンスを発揮できるのか、実機が出てこないとわかりませんけれども。

PowerPCからIntelに変わったときには、先読みが深くなったためか(?)連番ファイルの処理で問題が出て、書き直しが必要になったことがありました。IntelからARMへの移行時には、iOS系のアプリケーションの操作を試みて問題が出たり、セキュリティ上の制限にひっかかったりすることでしょう。

AppleScript名:CPUのバイトオーダーを取得.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/07/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set bRes to getByteOrder() of me
–> true –Little Endian

on getByteOrder()
  set aRes to do shell script "sysctl -n hw.byteorder"
  
if aRes = "4321" then
    return false –Big Endian (PowerPC)
  else
    return true –Little Endian (Intel, Arm..maybe)
  end if
end getByteOrder

★Click Here to Open This Script 

Shane Stanleyからの投稿です。こっちの方がシンプルでいいですね。

AppleScript名:CPUのバイトオーダーを取得 v2.scptd
—
–  Created by: Shane Stanley
–  Created on: 2020/07/23
—

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set bRes to current application’s NSHostByteOrder() — 1 = little endian, 2 = big endian, 0 = unknown

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSHostByteOrder | Leave a comment

Finder上で「すべてのファイル名拡張子を表示」にチェックが入っているかを返す

Posted on 5月 19, 2020 by Takaaki Naganoya

Finderの環境設定で「すべてのファイル名拡張子を表示」にチェックが入っているかを確認するAppleScriptです。

iWorkアプリケーション(Keynote、Pages、Numbers)では、オープン中の書類名を返すときに、Finderの上記の環境設定の内容を反映して拡張子を含めたり、含めなかったりしつつ名称を返すという仕様。

「ファイル名単独で求めることなんてないでしょ?」と思いつつも、オープン中のドキュメントの存在確認を名称で行うため、けっこう左右されることになります。

AppleScript名:Finder上で「すべてのファイル名拡張子を表示」にチェックが入っているかを返す.scpt
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/19
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

set exRes to checkDisplayTheFileExtensionsInFinder() of me
–> true

on checkDisplayTheFileExtensionsInFinder()
  try
    set aRes to (do shell script "/usr/bin/defaults read NSGlobalDomain AppleShowAllExtensions") as integer
    
return aRes as boolean
  on error
    return false
  end try
end checkDisplayTheFileExtensionsInFinder

★Click Here to Open This Script 

Posted in file shell script | Tagged Finder Keynote Numbers Pages | 2 Comments

アラートダイアログ上にWebViewでGoogle Chartsを表示(Calendar Chart)

Posted on 5月 7, 2020 by Takaaki Naganoya

アラートダイアログ上にWkWebViewを配置し、Google Chartsを用いてCalendar Chartを表示するAppleScriptです。

自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で100日間のアクセス履歴を処理して7秒強ぐらいで描画が終了します。

調子に乗って300日分のアクセス履歴を処理したところ、表示まで1分ほどかかりました。あまり長い期間の描画を行わせるのは(このプログラムの書き方だと)向いていないと感じます。いまのところテストしただけで実用性は考えていませんが、この程度のグラフなら自前でNSImage上にボックスを描画して表示しても大した手間にはならないでしょう。


▲スクリプトエディタ上で実行したところ


▲Script Debugger上で実行したところ


▲スクリプトメニュー上で実行したところ

Safariのアクセス履歴は例によってsqliteのDatabaseにアクセスして取得していますが、AppleScriptのランタイム環境によっては、アクセス権限がないというメッセージが出てアクセスできないことがあります。ASObjC Explorer 4上では実行できませんでしたし、Switch Control上でも実行できません。

# 管理者権限つきで実行しても(with administrator privileges)実行できません → Switch Controlでも実行できるようになりました

最初に掲載したバージョンでは、グラフ化したときに表示月が1か月ズレるという問題がありました。

Google Chartsのドキュメントを確認したところ、

Note: JavaScript counts months starting at zero: January is 0, February is 1, and December is 11. If your calendar chart seems off by a month, this is why.

JavaScriptでMonthはJanuaryが0らしく、monthを-1する必要があるとdocumentに書かれていました。うわ、なにその仕様?(ーー;;;

AppleScript名:アラートダイアログ上にWebViewでGoogle Chartを表示(Calendar Charts)v1a.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/05/07
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSString : a reference to current application’s NSString
property NSButton : a reference to current application’s NSButton
property WKWebView : a reference to current application’s WKWebView
property WKUserScript : a reference to current application’s WKUserScript
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property WKUserContentController : a reference to current application’s WKUserContentController
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property returnCode : 0

script spd
  property aRes : {}
  
property bRes : {}
end script

–Calculate Safari access frequency for (parameter days)
set (aRes of spd) to calcMain(100) of safariHistLib

set (bRes of spd) to ""
repeat with i in (aRes of spd)
  set {item1, item2, item3} to parseByDelim(theName of (contents of i), "-") of me
  
set newLine to " [ new Date(" & (item1 as string) & ", " & ((item2 – 1) as string) & ", " & (item3 as string) & "), " & (numberOfTimes of i) & "]," & (string id 10)
  
set (bRes of spd) to (bRes of spd) & newLine
end repeat

set (bRes of spd) to text 1 thru -3 of (bRes of spd)

–Pie Chart Template HTML
set myStr to "<!DOCTYPE html>
<html lang=\"UTF-8\">
<head>
<div id=\"calendarchart\"></div>

<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>

<script type=\"text/javascript\">
// Load google charts
google.charts.load(’current’, {’packages’:[’calendar’]});
google.charts.setOnLoadCallback(drawChart);

// Draw the chart and set the chart values
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: ’date’, id: ’Date’ });
dataTable.addColumn({ type: ’number’, id: ’Web Access’ });
dataTable.addRows([
  %@
]);

var chart = new google.visualization.Calendar(document.getElementById(’calendar_basic’));

var options = {
title: \"Web Activity\",
height: 350,
};

chart.draw(dataTable, options);
}
</script>
</head>
<body>
  <div id=\"calendar_basic\" style=\"width: 1000px; height: 350px;\"></div>
</body>
</html>"

set aString to current application’s NSString’s stringWithFormat_(myStr, (bRes of spd)) as string

set paramObj to {myMessage:"Calendar Chart Test", mySubMessage:"This is a simple calendar chart using google charts", htmlStr:aString}
–my browseStrWebContents:paramObj–for debug
my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true

on browseStrWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set htmlString to (htmlStr of paramObj)
  
  
set aWidth to 1000
  
set aHeight to 300
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定HTML内のJavaScriptをFetch
  
set jsSource to pickUpFromToStr(htmlString, "<script type=\"text/javascript\">", "</script>") of me
  
  
set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
  
set userContentController to WKUserContentController’s alloc()’s init()
  
userContentController’s addUserScript:(userScript)
  
aConf’s setUserContentController:userContentController
  
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me))
  
aWebView’s loadHTMLString:htmlString baseURL:(bURL)
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
–its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aWebView
    
    
set myWindow to its |window|
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
–Stop Web View Action
  
set bURL to |NSURL|’s URLWithString:"about:blank"
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
if (my returnCode as number) = 1001 then error number -128
end browseStrWebContents:

on doModal:aParam
  set (my returnCode) to (aParam’s runModal()) as number
end doModal:

on viewDidLoad:aNotification
  return true
end viewDidLoad:

on fetchJSSourceString(aURL)
  set jsURL to |NSURL|’s URLWithString:aURL
  
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
return jsSourceString
end fetchJSSourceString

on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string)
  set a1Offset to offset of s1Str in aStr
  
if a1Offset = 0 then return false
  
set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr
  
set a2Offset to offset of s2Str in bStr
  
if a2Offset = 0 then return false
  
set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr
  
return cStr as string
end pickUpFromToStr

–リストを任意のデリミタ付きでテキストに
on retArrowText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retArrowText

on array2DToJSONArray(aList)
  set anArray to current application’s NSMutableArray’s arrayWithArray:aList
  
set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is
  
set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding)
  
return resString
end array2DToJSONArray

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

script safariHistLib
  property parent : AppleScript
  
use scripting additions
  
use framework "Foundation"
  
  
property |NSURL| : a reference to current application’s |NSURL|
  
  
script spd
    property sList : {}
    
property nList : {}
    
property sRes : {}
    
property dRes1 : {}
    
property dRes2 : {}
  end script
  
  
  
on calcMain(daysNum)
    set (dRes1 of spd) to dumpSafariHistoryFromDaysBefore(daysNum) of me
    
    
set (dRes2 of spd) to {}
    
repeat with i in (dRes1 of spd)
      copy (first item of i) as string to dStr
      
set convDstr to first item of (parseByDelim(dStr, {" "}) of me)
      
set the end of (dRes2 of spd) to convDstr
    end repeat
    
    
–日付ごとに登場頻度集計
    
set cRes to countItemsByItsAppearance2((dRes2 of spd)) of me
    
return cRes as list
  end calcMain
  
  
  
–NSArrayに入れたレコードを、指定の属性ラベルの値でソート
  
on sortRecListByLabel(aArray, aLabelStr as string, ascendF as boolean)
    –ソート
    
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
    
set sortDescArray to current application’s NSArray’s arrayWithObjects:sortDesc
    
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
    
    
–NSArrayからListに型変換して返す
    
set bList to (sortedArray) as list
    
return bList
  end sortRecListByLabel
  
  
  
on dumpSafariHistoryFromDaysBefore(daysBefore)
    –現在日時のn日前を求める
    
using terms from scripting additions
      set origDate to (current date) – (daysBefore * days)
    end using terms from
    
    
set dStr to convDateObjToStrWithFormat(origDate, "yyyy-MM-dd hh:mm:ss") of me
    
    
set aDBpath to "~/Library/Safari/History.db"
    
set pathString to current application’s NSString’s stringWithString:aDBpath
    
set newPath to pathString’s stringByExpandingTildeInPath()
    
    
set aText to "/usr/bin/sqlite3 " & newPath & " ’SELECT datetime(history_visits.visit_time+978307200, \"unixepoch\", \"localtime\"), history_visits.title || \" @ \" || substr(history_items.URL,1,max(length(history_items.URL)*(instr(history_items.URL,\" & \")=0),instr(history_items.URL,\" & \"))) as Info FROM history_visits INNER JOIN history_items ON history_items.id = history_visits.history_item where history_visits.visit_time>(julianday(\"" & dStr & "\")*86400-211845068000) ORDER BY visit_time ASC LIMIT 999999;’"
    
    
using terms from scripting additions
      set (sRes of spd) to do shell script aText
    end using terms from
    
    
set (sList of spd) to (paragraphs of (sRes of spd))
    
    
repeat with i in (sList of spd)
      set j to contents of i
      
      
–Parse each field
      
set j2 to parseByDelim(j, {"|", "@ "}) of me
      
      
set the end of (nList of spd) to j2
    end repeat
    
    
return (nList of spd)
  end dumpSafariHistoryFromDaysBefore
  
  
  
  
on parseByDelim(aData, aDelim)
    set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to aDelim
    
set dList to text items of aData
    
set AppleScript’s text item delimiters to curDelim
    
return dList
  end parseByDelim
  
  
  
–出現回数で集計
  
on countItemsByItsAppearance2(aList)
    set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
    
set bArray to current application’s NSMutableArray’s array()
    
set theEnumerator to aSet’s objectEnumerator()
    
    
repeat
      set aValue to theEnumerator’s nextObject()
      
if aValue is missing value then exit repeat
      
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"})
    end repeat
    
    
–出現回数(numberOfTimes)で降順ソート
    
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"theName" ascending:true
    
bArray’s sortUsingDescriptors:{theDesc}
    
    
return bArray
  end countItemsByItsAppearance2
  
  
  
on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string)
    set aDF to current application’s NSDateFormatter’s alloc()’s init()
    
    
set aLoc to current application’s NSLocale’s currentLocale()
    
set aLocStr to (aLoc’s localeIdentifier()) as string
    
    
aDF’s setLocale:(current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr)
    
aDF’s setDateFormat:aFormatStr
    
set dRes to (aDF’s stringFromDate:aDateO) as string
    
return dRes
  end convDateObjToStrWithFormat
  
end script

★Click Here to Open This Script 

Posted in JavaScript shell script Sort | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSButton NSRunningApplication NSString NSURL NSURLRequest NSUTF8StringEncoding Safari WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

指定アプリケーションを指定言語環境で再起動

Posted on 4月 30, 2020 by Takaaki Naganoya

指定アプリケーションを、現在のユーザーアカウントで指定可能な言語環境を指定して再起動するAppleScriptです。

Xcodeにこのような機能があり、そのような処理を行える可能性について思い至っていました。shell commandについてはEdama2さんから教えていただきました。あー、やっぱりこういう感じなんですね。

次に、言語コードを求める方法ですが、調べても全言語の言語コードを求める方法が見当たらなかったので(これは、探し方が足りないだけ)、現在のユーザーアカウントで指定可能な言語コードを求める方法に落ち着きました。

本Scriptを実行すると、指定アプリケーションを起動する言語コードを選択。

処理するアプリケーションを選択。choose applicationコマンドが活躍するのはとても珍しいケースです。

英語(English)を指定した場合。

フランス語(French)を指定した場合。

日本語(Japanese)を指定した場合。

個人的には、英語環境でアプリケーションを動かしつつ、執筆用のアプリケーション(Keynote)だけ日本語環境で動かすことができて、些細なコマンドの呼称を確認する必要がなくていい感じです。あれ? 日本語環境でターゲットのアプリケーションだけ英語環境を指定して起動すればいいんじゃ????

AppleScript名:指定アプリケーションを指定言語環境で再起動
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/04/30
–  Special Thanks to : Edama2
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
–  
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set aLocList to (current application’s NSLocale’s preferredLanguages()) as list

set targLanguage to choose from list aLocList
set anApp to choose application

set apFile to POSIX path of (path to anApp)
tell anApp to quit

set sText to "open -n -a " & quoted form of apFile & " –args -AppleLanguages ’(\"" & targLanguage & "\")’"
do shell script sText

★Click Here to Open This Script 

Posted in Language Locale shell script | Tagged 10.13savvy 10.14savvy 10.15savvy | 3 Comments

Safariの履歴を読み込んでBest 10を求める。「その他」計算機能つき

Posted on 4月 29, 2020 by Takaaki Naganoya

Safariの閲覧履歴のdatabaseにアクセスして、domain単位でベスト10を求めるAppleScriptです。

自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で10日間のアクセス履歴を処理して0.8秒程度です。

以前のSafariではplistでヒストリを管理していましたが、気づいたらSqliteのDBで管理するように変わっていたので(Safari 10あたりで?)、よろしく抽出して加工してみました。おそらく、最低限の情報のみ抽出することで現状の半分ぐらいの処理時間で処理できるようになるとは思うのですが、汎用性を持たせるために現状のレベルにまとめています。

計算結果が当たり前すぎて予想よりはるかに面白くなかったので、そのことに逆に驚きました。

AppleScript名:Safariの履歴を読み込んでBest 10を求める。「その他」計算機能つき.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/04/29
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.7" — (10.13) or later
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|

script spd
  property sList : {}
  
property nList : {}
  
property sRes : {}
end script

set aRes to calcSafariHistoryBest10Domain(10) of me
–> {{theName:"piyocast.com", numberOfTimes:1100}, {theName:"www.youtube.com", numberOfTimes:710}, {theName:"twitter.com", numberOfTimes:354}, {theName:"www.google.com", numberOfTimes:331}, {theName:"syosetu.com", numberOfTimes:199}, {theName:"github.com", numberOfTimes:140}, {theName:"developer.apple.com", numberOfTimes:139}, {theName:"appstoreconnect.apple.com", numberOfTimes:121}, {theName:"xxxxxxxxxxxxx", numberOfTimes:106}, {theName:"Other", numberOfTimes:847}}

on calcSafariHistoryBest10Domain(daysBefore)
  –現在日時のn日前を求める
  
set origDate to (current date) – (daysBefore * days)
  
set dStr to convDateObjToStrWithFormat(origDate, "yyyy-MM-dd hh:mm:ss") of me
  
  
set aDBpath to "~/Library/Safari/History.db"
  
set pathString to current application’s NSString’s stringWithString:aDBpath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set aText to "sqlite3 " & newPath & " ’SELECT datetime(history_visits.visit_time+978307200, \"unixepoch\", \"localtime\"), history_visits.title || \" @ \" || substr(history_items.URL,1,max(length(history_items.URL)*(instr(history_items.URL,\" & \")=0),instr(history_items.URL,\" & \"))) as Info FROM history_visits INNER JOIN history_items ON history_items.id = history_visits.history_item where history_visits.visit_time>(julianday(\"" & dStr & "\")*86400-211845068000) ORDER BY visit_time ASC LIMIT 999999;’"
  
set (sRes of spd) to do shell script aText
  
  
set (sList of spd) to (paragraphs of (sRes of spd))
  
  
set (nList of spd) to {}
  
  
repeat with i in (sList of spd)
    set j to contents of i
    
    
–Parse each field
    
set j2 to parseByDelim(j, {"|", "@ "}) of me
    
    
–Calculate URL’s domain only
    
set j3 to contents of last item of j2
    
set aURL to (|NSURL|’s URLWithString:j3)
    
    
if aURL = missing value then
      set j4 to ""
    else
      set j4 to (aURL’s |host|()) as string
    end if
    
    
set the end of (nList of spd) to j4
  end repeat
  
  
–登場頻度でURLを集計
  
set aList to countItemsByItsAppearance((nList of spd)) of me
  
  
  
–Best 10の計算のために10位以下をまとめる
  
set best9 to items 1 thru 9 of aList
  
set best10 to items 10 thru -1 of aList
  
  
set otherTimes to 0
  
repeat with i in best10
    set otherTimes to otherTimes + (numberOfTimes of i)
  end repeat
  
  
set the end of best9 to {theName:"Other", numberOfTimes:otherTimes}
  
return best9
end calcSafariHistoryBest10Domain

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

–出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to current application’s NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string)
  set aDF to current application’s NSDateFormatter’s alloc()’s init()
  
  
set aLoc to current application’s NSLocale’s currentLocale()
  
set aLocStr to (aLoc’s localeIdentifier()) as string
  
  
aDF’s setLocale:(current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr)
  
aDF’s setDateFormat:aFormatStr
  
set dRes to (aDF’s stringFromDate:aDateO) as string
  
return dRes
end convDateObjToStrWithFormat

★Click Here to Open This Script 

Posted in shell script | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

Xcode上で作成したアプリケーション上でDark Mode検出

Posted on 4月 22, 2020 by Takaaki Naganoya

Xcode上で作成したAppleScriptアプリケーションでDark Modeの検出を行いたいときに、NSAppearance’s currentAppearance()で取得したら、正しくModeの検出が行えませんでした。同じコードをスクリプトエディタ/Script Debugger上で動かした場合には正しくModeの判定が行えているのですが。

そこで、System Eventsの機能を用いてMode判定を行うように処理を書き換えたりしてみたのですが、Mac App Storeに出すアプリケーションでこの処理を記述していたら、これを理由にリジェクトされてしまいました。

仕方なく解決策を探してみたところ、macOS 10.13用に書いたshell scriptによる迂回処理を、そのまま他のOSバージョンでも動かせばよいのではないかと気づき、結局そこに落ち着きました。

AppleScript名:Dark Modeの検出(Xcode上でも正しく判定)
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/04/22
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set apRes to retLightOrDark() of me
–> true (Dark), false (Light)

on retLightOrDark()
  try
    set sRes to (do shell script "defaults read -g AppleInterfaceStyle")
    
return (sRes = "Dark") as boolean
  on error
    return false
  end try
end retLightOrDark

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

mirroringの設定と解除

Posted on 3月 11, 2020 by Takaaki Naganoya

自分はディスプレイのミラーリング機能は日常的にあまり使っていません。実際にやってみたらどうだったのかをまとめてみました。

この手の処理をAppleScriptで書こうとしても、そのための命令が標準で内蔵されていないため、アプローチの方法はかぎられています。

 (1)思いっきりハードウェア寄りのプログラム(Cとかで書いた)を呼び出す
 (2)アクセシビリティ系の機能(GUI Scripting)を使ってシステム環境設定を操作する

の2つです。(2)は、画面上の要素の些細な変更によりプログラムを書き換える必要が出てくるうえに、信頼性が高くないので、あまりやりたくありません。もちろん、画面上の要素を検索しながら処理する方法もあるわけですが、それなりに(画面要素の検索に)時間がかかります。

そうなると、(1)を採用することになります。探すと………すぐにみつかりました。「mirror-displays」というコマンドラインアプリケーションです。ソースコードを読んでみると、CoreGraphics系の各種フレームワークを呼び出している、Objective-Cで書かれた(ほとんどCのコード)プログラムです。

これをスクリプトバンドルの中に入れて呼び出してみました。1回実行するとメインモニタの内容が他のモニタにミラーリングされます。もう1回実行すると、ミラーリングが解除されます。

–> Download mirroring_toggle (Script Bundle with executable command in its bundle)

mirrorコマンドのオプションには、「どのモニタをミラーリングさせるか」といった指定ができるようですが、試していないのでとくに凝った指定も何もしていません。

mirrorコマンドはmacOS 10.14でビルドして10.10以降をターゲットにしてみましたが、そこまで古い環境は手元に残っていないのでテストしていません。また、macOS 10.15のマシンには複数台のモニタをつないでいないので、macOS 10.15上でのテストも行っていません。

AppleScript名:mirroringの設定と解除
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/11
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

–https://github.com/hydra/mirror-displays
–バンドルの中に入れたmirrorコマンドをただ呼んでるだけ
set myPath to POSIX path of (path to me)
set comPath to myPath & "/Contents/Resources/mirror"
do shell script quoted form of comPath

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

使用中のMacの製品呼称を取得する v4

Posted on 3月 8, 2020 by Takaaki Naganoya

使用中のMacの製品呼称を取得するAppleScriptです。

ながらく、この手のルーチンを使い続けてきましたが、macOS 10.15でエラーが出るようになりました。

理由を確認してみたところ、パス名の一部がmacOS 10.15で変更になっていることがわかりました。

目下、Xcode上でアプリケーションを作成すると、ローカライズしたリソースのフォルダについては、「English.lproj」ではなく「en.lproj」と、言語コードが用いられるようになってきました。この、「English」と「en」の変更がOS内部のコンポーネントについても行われた「だけ」というのが理由のようです。

ちなみに、パス名を無意味に途中で切ってつなげているのは、Blog(HTML)やMarkDownのドキュメントに入れたときに、折り返しされずにレンダリング品質を下げる原因になる(行がそこだけ伸びるとか、ページ全体の文字サイズが強制的に小さくなるとか)ためです。

AppleScript名:使用中のMacの製品呼称を取得する v4.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/08
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set myInfo to retModelInfo() of me
–> "Mac mini (Late 2014)"

on retModelInfo()
  set v2 to system attribute "sys2"
  
— macOS 10.15.3 –> 15
  
  
if v2 < 15 then
    –macOS 10.14まで
    
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/English.lproj/SIMachineAttributes.plist"
  else
    –macOS 10.15以降
    
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/en.lproj/SIMachineAttributes.plist"
  end if
  
  
set aRec to retDictFromPlist(pListPath) of me
  
set hwName to (do shell script "sysctl -n hw.model")
  
–>  "Macmini7,1"
  
  
set aMachineRec to retRecordByLabel(aRec, hwName) of me
  
  
set aMachineRec2 to contents of first item of aMachineRec
  
return (marketingModel of _LOCALIZABLE_ of aMachineRec2)
end retModelInfo

on retDictFromPlist(aPath)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict as record
end retDictFromPlist

on retRecordByLabel(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKey:aKey
  
return aVal as list
end retRecordByLabel

on retRecordByKeyPath(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKeyPath:aKey
  
return aVal
end retRecordByKeyPath

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.15savvy NSDictionary NSString | Leave a comment

osascript系のAppleScriptランタイムを区別する

Posted on 1月 18, 2020 by Takaaki Naganoya

AppleScriptのランタイム環境が何であるかを区別できるようになりました。

それらのうち、/usr/bin/osascriptを呼び出しているランタイム環境について、さらに細分化して個別に識別するために、ランタイム環境そのものと親プロセスが何であるかをAppleScriptで調査してみました。

結論からいえば、親プロセスが「bash」ならTerminalからosascriptコマンドで起動されたと判断してよさそう。その他は、実行されたScriptの置かれているパスを求めて、macOS標準装備のScript Menuかアプリケーション内部のScript Menuかを見分けるぐらいでしょうか。

これを判定したプログラム自体は、別に技術的にすごいとか機密の塊とかいうことはなくて、「清書してなくて、きたない。無駄に長い。掲載されているプログラムを見ても何も感じない」ことから掲載していません。実験用のテストプログラムでも、ちょっと近年稀に見るぐらいひどい出来です。内容は、単にランタイムプログラムのプロセスIDを取得して、そのプロセスIDをもとにpsコマンドで親プロセスを求めて、コマンドからいろいろ情報を抜いてくるというだけのものです。

Script Menu

ランタイムのパラメータ:/usr/bin/osascript -P /Users/me/Library/Scripts/Finder/pTEST.scptd
親プロセス:/System/Library/Frameworks/Foundation.framework/Versions/C/XPCServices/com.apple.foundation.UserScriptService.xpc/Contents/MacOS/com.apple.foundation.UserScriptService

与えられているScriptが特定フォルダ(/Users/me/Library/Scripts/)以下にあるものかどうか、という識別は可能。ちょっと、根拠が弱そうです。

CotEditor内のScript Menu

ランタイムのパラメータ:/usr/bin/osascript -sd -T 14534 -P /Users/me/Library/Application Scripts/com.coteditor.CotEditor/010)M-pM^_M^MM^NM-pM^_M^SM^\AppleScriptM-cM^AM-(M-cM^AM^WM-cM^AM-&M-hM-'M-#M-iM^GM^H/0020)M-pM^_M^SM^\M-fM-'M^KM-fM^VM^GM-gM-"M-:M-hM-*M^MM-cM^AM^WM-cM^AM-&M-eM-.M^_M-hM-!M^LM-cM^AM^WM-cM^@M^AM-pM^_M^SM^DM-fM^VM-0M-hM-&M^OM-fM^[M-8M-iM-!M^^M-cM^AM-+M-gM-5M^PM-fM^^M^\M-cM^BM^RM-eM^GM-:M-eM^JM^[.@r.scpt
親プロセス:/System/Library/Frameworks/Foundation.framework/Versions/C/XPCServices/com.apple.foundation.UserScriptService.xpc/Contents/MacOS/com.apple.foundation.UserScriptService

親プロセスはScript Menuと同じですが、こちらも実行しているScriptのパスが/Users/me/Library/Application Scripts/com.coteditor.CotEditor/以下であること。これも、識別のための根拠が弱いです。

Terminal経由でosascriptコマンド実行

ランタイムのパラメータ:osascript /Users/me/Desktop/pTEST.scptd
親プロセス:-bash

これは、親プロセスが-bashであることから、明確に区別できます。Terminal.appではなくbashなんですね。

Terminal経由で/usr/bin/osascript(フルパス指定)でコマンド実行

ランタイムのパラメータ:/usr/bin/osascript /Users/me/Desktop/pTEST.scptd
親プロセス:-bash

フルパスで指定すると何か変わってくるかとも思いましたが、とくに変化はありませんでした。

Program AS Style runtime name Parent Process Name Script Path
Script Editor Script/Scriptd Script Editor
Script Editor Cocoa-AppleScript Applet CocoaApplet
Script Editor Applet applet
Script Debugger Script/Scriptd Script Debugger
Script Debugger Applet (Enhanced) FancyDroplet
ASOBjC Explorer 4 Script/Scriptd ASOBjC Explorer 4
Automator Workflow Automator
Automator Applet Application Stub
Script Menu Script/Scriptd osascript …com.apple.foundation.UserScriptService /Users/me/Library/Scripts/ ほか
CotEditor Script osascript …com.apple.foundation.UserScriptService /Users/me/Library/Application Scripts/com.coteditor.CotEditor/
Terminal.app (osascript) Script/Scriptd osascript bash
Posted in OSA shell script | Tagged 10.14savvy | Leave a comment

CotEditorの表示用フォント名を環境設定から取得する

Posted on 10月 15, 2019 by Takaaki Naganoya

CotEditorの環境設定値(plist)から表示用フォント名を取得するAppleScriptです。

本来であれば、CotEditorのwindowオブジェクト自体に属性値として表示用フォント名がついているのが(GUI側からWindowごとに表示フォントを指定できるので)理想的ですが、そういう機能は実装されていないので、無理やりplistから読み取ってみました。

CotEditorの表示用フォントは、環境設定で指定したものがデフォルトで用いられ、個別のウィンドウごとに任意のフォントを指定できるようになっています。本Scriptで取得できるのは、個別のウィンドウの設定値ではなく、環境設定値のほうです。

defaultsコマンドでplistを読むのはあまりおすすめできない方法ですが、できないよりはマシというところです。

まっさらな(macOSをインストールしたての)環境にCotEditorをインストールして一度も環境設定でフォントを指定していない環境だとエラーになる(項目が存在しない)ので、その場合に備えてエラートラップを仕掛けています。


▲環境設定から表示フォント名を取得して、各行をプロポーショナルフォント使用時の画面描画幅をもとにソートする処理を書いたときに利用

AppleScript名:CotEditorの表示用フォント名を環境設定から取得する
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/10/15
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set fName to getCotEditorFontName() of me
–> "HiraginoSans-W3"

–CotEditorのplistから表示用のフォント設定(PostScript名)を取得する
on getCotEditorFontName()
  try
    set fnRes to do shell script "defaults read com.coteditor.CotEditor | grep fontName"
  on error
    return "" –インストール後に表示フォントの環境設定を一度も行っていないときにはエラーになる
  end try
  
set fName to extractStrFromTo(fnRes, "= \"", "\";") of me
  
return fName
end getCotEditorFontName

–指定文字と終了文字に囲まれた内容を抽出
on extractStrFromTo(aParamStr, fromStr, toStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set anArray to current application’s NSMutableArray’s array()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    set {theResult, theKey} to theScanner’s scanUpToString:fromStr intoString:(reference)
    
theScanner’s scanString:fromStr intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:toStr intoString:(reference)
    
if theValue is missing value then set theValue to "" –>追加
    
theScanner’s scanString:toStr intoString:(missing value)
    
anArray’s addObject:theValue
  end repeat
  
  
if anArray’s |count|() is not equal to 1 then return ""
  
  
return first item of (anArray as list)
end extractStrFromTo

★Click Here to Open This Script 

hiro さんのコメントから、defaultsコマンドのオプション追加でずいぶんと簡潔に書けるようで、書き直しておきました。

AppleScript名:CotEditorの表示用フォント名を環境設定から取得する v2
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set fName to getCotEditorFontName() of me
–> "HiraginoSans-W3"

–CotEditorのplistから表示用のフォント設定(PostScript名)を取得する
on getCotEditorFontName()
  try
    set fnRes to do shell script "defaults read com.coteditor.CotEditor fontName"
  on error
    return "" –インストール後に表示フォントの環境設定を一度も行っていないときにはエラーになる
  end try
  
return fnRes
end getCotEditorFontName

★Click Here to Open This Script 

Posted in shell script | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy CotEditor NSMutableArray NSScanner | 3 Comments

CotEditorで編集中のMarkdown書類をPDFプレビュー

Posted on 6月 15, 2019 by Takaaki Naganoya

CotEditorで編集中のMarkdown書類を、MacDownでPDF書き出しして、Skimでオープンして表示するAppleScriptです。

CotEditorにMarkdownのプレビュー機能がついたらいいと思っている人は多いようですが、MarkdownはMarkdownで、方言は多いし標準がないし、1枚もののMarkdown書類だけ編集できればいいのか、本などのプロジェクト単位で編集とか、目次が作成できないとダメとか、リンクした画像の扱いをどうするのかとか、対応しようとすると「ほぼ別のソフトを作るのと同じ」ぐらい手間がかかりそうです(メンテナー様ご本人談)。

そこで、AppleScript経由で他のソフトを連携させてPDFプレビューさせてみました。これなら、誰にも迷惑をかけずに、今日この時点からすぐにMarkdownのプレビューが行えます(当然、HTML書き出ししてSafariでプレビューするバージョンははるかかなた昔に作ってあります)。

ただし、OS側の機能制限の問題で、CotEditor上のスクリプトメニューから実行はできません(GUI Scriptingの実行が許可されない)。OS側のスクリプトメニューに登録して実行する必要があります。

GUI Scriptingを利用してメニュー操作を行なっているため、システム環境設定で許可しておく必要があります。

本来であれば、PDFの書き出し先フォルダ(この場合は書き出しダイアログで、GUI Scirptingを用いてCommand-Dで指定して一律に場所指定が行えるデスクトップフォルダ)に同名のPDFが存在しないかどうかチェックし、存在すれば削除するといった処理が必要ですが、面倒だったのであらかじめMarkdown書類をUUIDにリネームしておくことで、書き出されたPDFも同じくUUIDのファイル名になるため、論理上はファイル名の衝突を回避できるため、削除処理を省略しています。

AppleScript名:🌏レンダリングしてPDFプレビュー
— Created 2019-06-15 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSUUID : a reference to current application’s NSUUID
property NSWorkspace : a reference to current application’s NSWorkspace

–オープン中のMarkdown書類を取得する
tell application "CotEditor"
  tell front document
    set cStyle to coloring style
    
if cStyle is not equal to "Markdown" then
      display dialog "編集中のファイルはMarkdown書類ではないようです。" buttons {"OK"} default button 1
      
return
    end if
    
    
set aPath to path
  end tell
end tell

–一時フォルダにMarkdown書類をコピー
set sPath to (path to temporary items)
tell application "Finder"
  set sRes to (duplicate ((POSIX file aPath) as alias) to folder sPath with replacing)
end tell

–コピーしたMarkdown書類をリネーム
set s1Res to sRes as alias
set aUUID to NSUUID’s UUID()’s UUIDString() as text –UUIDを作成する
tell application "Finder"
  set name of s1Res to (aUUID & ".md")
end tell

–Markdown書類をデスクトップにPDF書き出し
set pdfRes to exportFromMacDown(POSIX path of s1Res) of me

–PDF Viewerでオープン
tell application "Skim" –Preview.appでもOK
  activate
  
open pdfRes
end tell

–一時フォルダに書き出したMarkdown書類を削除
tell application "Finder"
  delete s1Res
end tell

–指定のMacDownファイル(alias)をデスクトップ上にPDFで書き出し
on exportFromMacDown(anAlias)
  set s1Text to paragraphs of (do shell script "ls ~/Desktop/*.pdf") –pdf書き出し前のファイル一覧
  
  
tell application "MacDown"
    open {anAlias}
  end tell
  
  
macDownForceSave() of me
  
  
tell application "MacDown"
    close every document without saving
  end tell
  
  
do shell script "sync" –ねんのため
  
  
set s2Text to paragraphs of (do shell script "ls ~/Desktop/*.pdf") –pdf書き出し後のファイル一覧
  
  
set dRes to getDiffBetweenLists(s1Text, s2Text) of me –デスクトップ上のPDFファイル名一覧の差分を取得
  
set d2Res to (addItems of dRes)
  
  
if length of d2Res ≥ 1 then
    return contents of first item of d2Res
  else
    error "Error in exporting PDF to desktop folder…."
  end if
end exportFromMacDown

on getDiffBetweenLists(aArray as list, bArray as list)
  set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分を削除する
  
allSet’s minusSet:duplicateSet
  
set resArray to (allSet’s allObjects()) as list
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aArray
  
set bSet to current application’s NSMutableSet’s setWithArray:resArray
  
aSet’s intersectSet:bSet –積集合
  
set addRes to aSet’s allObjects() as list
  
  
set cSet to current application’s NSMutableSet’s setWithArray:bArray
  
cSet’s intersectSet:bSet –積集合
  
set minusRes to cSet’s allObjects() as list
  
  
return {addItems:minusRes, minusItems:addRes}
end getDiffBetweenLists

–注意!! ここでGUI Scriptingを使用。バージョンが変わったときにメニュー階層などの変更があったら書き換え
on macDownForceSave()
  activate application "MacDown"
  
tell application "System Events"
    tell process "MacDown"
      — File > Export > PDF
      
click menu item 2 of menu 1 of menu item 14 of menu 1 of menu bar item 3 of menu bar 1
      
      
–Go to Desktop Folder
      
keystroke "d" using {command down}
      
      
–Save Button on Sheet
      
click button 1 of sheet 1 of window 1
    end tell
  end tell
end macDownForceSave

–Bundle IDからアプリケーションのPathを返す
on retAppAbusolutePathFromBundleID(aBundleID)
  set appPath to NSWorkspace’s sharedWorkspace()’s absolutePathForAppBundleWithIdentifier:aBundleID
  
if appPath = missing value then return false
  
return appPath as string
end retAppAbusolutePathFromBundleID

★Click Here to Open This Script 

Posted in file File path GUI Scripting Markdown PDF shell script | Tagged 10.11savvy 10.12savvy 10.13savvy CotEditor Finder MacDown NSUUID NSWorkspace Skim | Leave a comment

CPU Family Nameを取得する

Posted on 12月 3, 2018 by Takaaki Naganoya

実行中のMacのMachine ID(MacBookPro10,1など)からIntel CPUのFamily Name(Ivy Bridgeなど)を取得するAppleScriptです。

Macの各モデルの搭載CPUについては、MacTrackerを参照しました。

MacTrackerのデータをコピー&ペーストでNumbers上に製品データを作成し(手動)、

ユニーク化(重複データの除去)処理を行なって(ASで処理)、プログラム上に展開しました(手動)。

実用性とか意味については、とくに考えていません。Machine IDとCPU Family Nameのデータについてはplistに記述してプログラム外部に追い出して独自でメンテナンスできるようにしたほうがよいと思われます。

AppleScript名:CPU Family Nameを取得する.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2018/12/03
—
–  Copyright © 2018 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set macID to do shell script "sysctl -n hw.model" –get machine ID
–set macID to "MacBookPro99,1"–Error case

set myName to getIntelCoreProcessorFamilyName(macID) of me
—> "Ivy Bridge"

on getIntelCoreProcessorFamilyName(macID)
  –Machine ID & CPU Core Model Names (uniquefied)
  
set macList to {{"iMac4,1", "Yonah"}, {"iMac4,2", "Yonah"}, {"iMac5,2", "Merom"}, {"iMac5,1", "Merom"}, {"iMac6,1", "Merom"}, {"iMac7,1", "Merom"}, {"iMac8,1", "Penryn"}, {"iMac9,1", "Penryn"}, {"iMac10,1", "Wolfdale"}, {"iMac11,1", "Wolfdale, Lynnfield"}, {"iMac11,2", "Clarkdale"}, {"iMac11,3", "Clarkdale, Lynnfield"}, {"iMac12,1", "Sandy Bridge"}, {"iMac12,2", "Sandy Bridge"}, {"iMac13,1", "Ivy Bridge"}, {"iMac13,2", "Ivy Bridge"}, {"iMac14,1", "Haswell"}, {"iMac14,3", "Haswell"}, {"iMac14,2", "Haswell"}, {"iMac14,4", "Haswell"}, {"iMac15,1", "Haswell"}, {"iMac16,1", "Broadwell"}, {"iMac16,2", "Broadwell"}, {"iMac17,1", "Skylake"}, {"iMac18,1", "Kaby Lake"}, {"iMac18,2", "Kaby Lake"}, {"iMac18,3", "Kaby Lake"}, {"iMacPro1,1", "Skylake"}, {"Macmini1,1", "Yonah"}, {"Macmini2,1", "Merom"}, {"Macmini3,1", "Penryn"}, {"Macmini4,1", "Penryn"}, {"Macmini5,1", "Sandy Bridge"}, {"Macmini5,2", "Sandy Bridge"}, {"Macmini5,3", "Sandy Bridge"}, {"Macmini6,1", "Ivy Bridge"}, {"Macmini6,2", "Ivy Bridge"}, {"Macmini7,1", "Haswell"}, {"Macmini8,1", "Coffe Lake"}, {"MacPro1,1", "Woodcrest"}, {"MacPro2,1", "Clovertown"}, {"MacPro3,1", "Harpertown"}, {"MacPro4,1", "Bloomfield, Gainestown"}, {"MacPro5,1", "Bloomfield, Gulftown, Westmere"}, {"MacPro5,1", "Bloomfield, Westmere, Gulftown"}, {"MacPro6,1", "Ivy Bridge"}, {"MacBook1,1", "Yonah"}, {"MacBook2,1", "Merom"}, {"MacBook3,1", "Merom"}, {"MacBook4,1", "Penryn"}, {"MacBook5,1", "Penryn"}, {"MacBook5,2", "Penryn"}, {"MacBook6,1", "Penryn"}, {"MacBook7,1", "Penryn"}, {"MacBook8,1", "Broadwell"}, {"MacBook9,1", "Skylake"}, {"MacBook10,1", "Kaby Lake"}, {"MacBookAir1,1", "Merom"}, {"MacBookAir2,1", "Penryn"}, {"MacBookAir3,1", "Penryn"}, {"MacBookAir3,2", "Penryn"}, {"MacBookAir4,1", "Sandy Bridge"}, {"MacBookAir4,2", "Sandy Bridge"}, {"MacBookAir5,1", "Ivy Bridge"}, {"MacBookAir5,2", "Ivy Bridge"}, {"MacBookAir6,1", "Haswell"}, {"MacBookAir6,2", "Haswell"}, {"MacBookAir7,1", "Broadwell"}, {"MacBookAir7,2", "Broadwell"}, {"MacBookAir8,1", "Amber Lake Y"}, {"MacBookPro1,1", "Yonah"}, {"MacBookPro1,2", "Yonah"}, {"MacBookPro2,2", "Merom"}, {"MacBookPro2,1", "Merom"}, {"MacBookPro3,1", "Merom"}, {"MacBookPro4,1", "Penryn"}, {"MacBookPro5,1", "Penryn"}, {"MacBookPro5,2", "Penryn"}, {"MacBookPro5,5", "Penryn"}, {"MacBookPro5,4", "Penryn"}, {"MacBookPro5,3", "Penryn"}, {"MacBookPro7,1", "Penryn"}, {"MacBookPro6,2", "Arrandale"}, {"MacBookPro6,1", "Arrandale"}, {"MacBookPro8,1", "Sandy Bridge"}, {"MacBookPro8,2", "Sandy Bridge"}, {"MacBookPro8,3", "Sandy Bridge"}, {"MacBookPro9,2", "Ivy Bridge"}, {"MacBookPro9,1", "Ivy Bridge"}, {"MacBookPro10,1", "Ivy Bridge"}, {"MacBookPro10,2", "Ivy Bridge"}, {"MacBookPro11,1", "Haswell"}, {"MacBookPro11,2", "Haswell"}, {"MacBookPro11,3", "Haswell"}, {"MacBookPro12,1", "Broadwell"}, {"MacBookPro11,4", "Haswell"}, {"MacBookPro11,5", "Haswell"}, {"MacBookPro13,1", "Skylake"}, {"MacBookPro13,2", "Skylake"}, {"MacBookPro13,3", "Skylake"}, {"MacBookPro14,1", "Kaby Lake"}, {"MacBookPro14,2", "Kaby Lake"}, {"MacBookPro14,3", "Kaby Lake"}, {"MacBookPro15,2", "Coffee Lake"}, {"MacBookPro15,1", "Coffee Lake"}}
  
  
–2D List内の検索
  
set gList to searchInListByIndexItem(macList, 1, macID) of me
  
if gList = missing value or gList = {} then
    error "Error:" & macID & "is newer Machine than I expected in Dec 2018 or Older PowerPC Mac , may be"
  end if
  
  
set g2List to FlattenList(gList) of me –複数の結果が得られた場合に備える
  
return contents of second item of g2List
end getIntelCoreProcessorFamilyName

–2Dリストから、指定インデックスアイテムで、指定データが該当する最初のものを返す
on searchInListByIndexItem(aList as list, itemNum as integer, hitData as string)
  set setKey to current application’s NSMutableSet’s setWithArray:aList
  
  
if itemNum < 1 then return {}
  
set aPredicateStr to ("SELF[" & (itemNum – 1) as string) & "] == ’" & hitData & "’"
  
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicateStr
  
set aRes to (setKey’s filteredSetUsingPredicate:aPredicate)
  
set bRes to aRes’s allObjects()
  
  
set cRes to bRes as list of string or string –as anything
  
return cRes
end searchInListByIndexItem

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
on FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

★Click Here to Open This Script 

Posted in shell script System | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSMutableSet NSPredicate | Leave a comment

teratailの指定IDのユーザー情報を取得する_curl

Posted on 11月 27, 2018 by Takaaki Naganoya

プログラミング系質問サイトteratailのREST APIを呼び出して、指定ユーザー名の情報を取得するAppleScriptです。

TeratailのREST APIは、タグ、ユーザー、質問の3ジャンルの情報取得を行えるように整備されており、特定カテゴリ(タグで分類)の新規質問が投稿されたかどうかを定期的に確認するようなAppleScriptを作って運用することもできます(そこまでやっていないですけれども)。

REST API呼び出しにはNSURLConnectionからNSURLSessionに移行していますが、どうもNSURLSessionだと呼び出せない(AppleScriptからの呼び出し処理が完了しない)サービスがあったりするので、結局shellのcurlコマンドを呼び出すのが手短にすむケースが多いようです。

Teratailの場合も、NSURLSessionで呼び出せるAPIもあれば、結果が返ってこないAPIもあり、NSURLConnectionよりも使い勝手がよくないと感じています(個人の感想です)。

このあたり、将来的なmacOSのアップデートでNSURLConnectionが使えなくなる日が来るのかもしれませんが、curlコマンドを使うように集約するべきなのか、NSURLSessionで書き換えるべきなのか悩ましいところです。

AppleScript名:teratailの指定IDのユーザー情報を取得する_curl
— Created 2018-11-26 by Takaaki Naganoya
— 2018 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSURLSession : a reference to current application’s NSURLSession
property NSURLQueryItem : a reference to current application’s NSURLQueryItem
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSURLComponents : a reference to current application’s NSURLComponents
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSMutableURLRequest : a reference to current application’s NSMutableURLRequest
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property NSURLSessionConfiguration : a reference to current application’s NSURLSessionConfiguration

set aUserRes to searchOneUserByDisplayName("Piyomaru") of me
–> {meta:{limit:20, message:"success", hit_num:1, total_page:1, page:1}, users:{{score:43, photo:"https://teratail.storage.googleapis.com/uploads/avatars/u6/66639/MSIS21by_thumbnail.jpg", display_name:"Piyomaru"}}}

on searchOneUserByDisplayName(aName)
  set aRec to {q:aName}
  
set reqURLStr to "https://teratail.com/api/v1/users/search"
  
set bURL to retURLwithParams(reqURLStr, aRec) of me
  
  
set tmpData to (do shell script "curl -X GET \"" & bURL & "\"")
  
set jsonString to NSString’s stringWithString:tmpData
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
if aJsonDict = missing value then return false
  
return (aJsonDict as record)
end searchOneUserByDisplayName

on retURLwithParams(aBaseURL, aRec)
  set aDic to NSMutableDictionary’s dictionaryWithDictionary:aRec
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

★Click Here to Open This Script 

Posted in Network Record REST API shell script URL | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSJSONSerialization NSMutableDictionary NSString NSURL NSURLComponents NSURLQueryItem | 1 Comment

Terminal.appでコマンドを実行する

Posted on 8月 20, 2018 by Takaaki Naganoya

Terminal.appでコマンドを実行するAppleScriptです。

AppleScriptからshell commandを実行するならdo shell scriptコマンドを経由することが多いので、Terminal.appをコントロールしてshell commandを実行しているのは「よくわかっていない人」だけです。これをやるとMac App Storeで一発でリジェクトされる処理内容でもあります。

ただ、そうはいってもごくまれにTerminal.app上でshell commandを実行する必要に迫られて(10年に1度ぐらいの割合で)、仕方なくTerminal.appをコントロールすることになりますが、Windowの有無を確認してその場合に応じて書き方を若干変える必要があるのが面倒。なので、このようにサブルーチンにして使い回すのが一般的なやりかたです。

■本ルーチン使用例
・2つのPDFのテキストの指定ページの差分をVimdiffで表示する v2

この例のほかはssh経由でhostにログインしてコマンド実行したときぐらいで、この2例が「本当にTerminal.appを操作しないと処理できない例」で、ほかは99.9%do shell scriptコマンドで済みました。

ごくたまに、Terminalからパラメータを入力することだけを前提に作られている、出来のよろしくないCLIツールも存在します。

普通のCLIツールのように「フルパスを指定しても問題ない」のではなく、「フルパスでパス指定すると不具合を引き起こす」ことには腰を抜かしました。そういうものもあるので、実際にdo shell scriptコマンド経由で自分の望む機能を呼び出せるかは、試してみないと(試してみるまで)わかりません。機械学習系(画像の物体識別)でそういうものに遭遇しました。落とし穴としかいいようがありません。

AppleScript名:Terminal.appでコマンドを実行する
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aCom to "ps"
doComInTerminalWindow(aCom) of me

on doComInTerminalWindow(aCMD as string)
  using terms from application "Terminal"
    tell application id "com.apple.Terminal"
      activate
      
set wCount to count (every window whose visible is true)
      
      
if wCount = 0 then
        –ウィンドウが1枚も表示されていない場合
        
do script aCMD
      else
        –すでにウィンドウが表示されている場合
        
do script aCMD in front window
      end if
    end tell
  end using terms from
end doComInTerminalWindow

★Click Here to Open This Script 

Posted in shell script | Tagged 10.11savvy 10.12savvy 10.13savvy Terminal | Leave a comment

Post navigation

  • Older posts

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • CotEditorで2つの書類の行単位での差分検出
  • macOS 15, Sequoia
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Adobe AcrobatをAppleScriptから操作してPDF圧縮
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • AppleScriptによる並列処理
  • Cocoa Scripting Course 続刊計画
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • NaturalLanguage.frameworkでNLEmbeddingの処理が可能な言語をチェック
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • Keynote、Pages、Numbers Ver.14.0が登場
  • macOS 15 リモートApple Eventsにバグ?
  • デフォルトインストールされたフォント名を取得するAppleScript

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (189) 14.0savvy (141) 15.0savvy (120) CotEditor (66) Finder (51) iTunes (19) Keynote (116) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (54) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC