TL;DR
クリエイティブコーディング Advent Calendar 2016へ3本目の投稿です。
MacOSがBSD系UNIXであることを最大限活かすと、クリエィティブコーディングが少し楽になりますよ。
「oFでディレクトリ作るときはofDirectory::createDirectory(const string &dirPath, bool bRelativeToData=true, bool recursive=false)
…?」なんてやらなくて良いんです。
そう、いつもと同じようにmkdir
で良いんです。
たとえば…
- 日別にログファイルを整理したい → mv, date
- 書き出したファイルを圧縮したい → zip, tar
- 処理が終わったら通知を出したい → terminal-notifier, osascript
- 喋らせたい → say
- Web APIを叩いた結果が欲しい → curl, wget, jq
- 適当なアプリで開きたい → open
正直、osascript
でAppleScriptが叩ければ、すなわちMacOSのほとんどが制御できることになるので、
クリップボードを共有するなり、カーソルを動かすなり、音量を最大にするなり、他のアプリを前面に持ってくるなり、なんでもござれ。
こういったコマンドを駆使できるからクリエィティブコーディングは極力MacOSでやりたいと思っています。
参考までに、openFrameworksとMax/MSP、QuartzComposerからシェルを叩く方法をご紹介します。
w/ openFrameworks
ofSystem()を使う
もっとも簡単なのはofSystem
を使う方法。
ofSystem("say -v Kyoko こんにちは");
ちゃんとPIPEする
ofSystem()
では途中出力を受け取れないし、処理が終わるまでスレッドがブロックされるので、
BrettさんがGistに上げていた実装が参考になります。
//
// SysCommand.h
//
// Created by Brett Renfer on 2/22/12.
//
#pragma once
#include "ofThread.h"
class SysCommand : private ofThread
{
public:
ofEvent<string> commandComplete;
void callCommand( string command ){
cmd = command;
stopThread();
startThread();
}
// CALL THIS DIRECTLY FOR BLOCKING COMMAND
// thanks to: http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c
std::string exec(char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
private:
void threadedFunction(){
ofLog( OF_LOG_VERBOSE, "call "+cmd );
string result = exec( (char *) cmd.c_str() );
ofLog( OF_LOG_VERBOSE, "RESULT "+result );
stopThread();
ofNotifyEvent( commandComplete, result, this );
}
string cmd;
};
w/ Max/MSP
Bill氏の"shell"オブジェクトを使う
公式のフォーラムからダウンロードできます。
中身を見るとCからpthreadしてますね。
赤松先生の"aka.shell"を使う
赤松先生のWebよりダウンロードできます。
こちらはpopenでの実装ですが、よりメジャーなので参考になる記事がたくさん見つかります。
Qiitaに詳しい記事もありました。 → UnixコマンドをインタフェースとしたMax-外部アプリ間の連携方法
w/ Quartz Composer
CommandLineTool
デペロッパーライブラリから謹製のサンプルコードが手に入ります。
古いので、Xcodeで読み込んでから微修正が必要です。
日本語で書かれた参考記事がありました。 → UNIX Command – execute in Quartz Composer
ShellCommandパッチを使う
Kosada inc.が公開しているShellCommandパッチを使う方法もあります。
Kinemaからダウンロードできます。
まとめ
どのツール/フレームワークも外部コマンドを実行できる仕組みが複数あります。
それぐらい強力な連携なのですが、いずれも「とんでもない引数を渡してた!」「コマンドを絶対パスにしないと動かない!」といったリスク&あるあるがあったりしますので、心してお使いくださいませ。