それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

AirMac(airport)を再起動する方法。

久しぶりにAirMacExpressを使おうと電源を入れた。

再起動できないのでフリーズしたときどうするかなぁって考えてた。Apple製品は内部的に同じOSXを使ってるだろうしSSH経由でログインして・・・って調べるのがあまりに面倒だ

airmac(airport)の再起動は専用アプリからできる。

いちいち電源抜きに行くの面倒だったんだよねぇ。

f:id:takuya_1st:20160107005904p:plain

右クリックしてみたり、あれこれ試してたけど、メニューバーにあったんだ。メニューバー非表示にしてたからハマったわ

f:id:takuya_1st:20160107021553p:plain

brew で opencv3 を入れる

画像処理をしようと思い立った、類似画像検索というか、画像の差分をみて特定のシーンを探すようなものを試みたい。

opencvosx に入れる

brew install opencv3

ただし、gcc までインストールされちゃっていつ終わることやら。。。

brew install opencv3 --without-numpy

numpy なかったら大変だろうけど、そのうち入れるとして、パパッと入れるならこっちのほうが早そう

link する

brew link opencv3 --force

opencv3 はkeg only だったのでリンクする

python2 ようにインストールされたので使ってみる

takuya@~$ python
Python 2.7.11 (default, Dec 25 2015, 03:11:22)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
c>>> cv2.__version__
'3.1.0'
>>>

できた。

python3 で使うときは brew install 時に with-python3 も付ける

numpy は brew で入れてた

使ってみる

import cv2

src_img = cv2.imread('/Users/takuya/Desktop/IMG_0061.jpg',0)
canny_edges = cv2.Canny(src_img,100,200)

cv2.imwrite("out.jpg", canny_edges)

できあがり

f:id:takuya_1st:20160106192654j:plain:w600

python3 でやるときは

インストールオプションにpyhton3 を付記すると、python3 ようにモジュールが作られてリンクされる。

brew install opencv3 --without-numpy --with-python3
brew link opencv3 --force

参考資料

Mac OS X で OpenCV 3 + Python 2/3 の開発環境を整備する方法 - 意識低い開発者のBlog

brew でインストールされる依存関係をみる

homebrew でinstall 実行したら、gcc まで入ってきて。。。

brew deps --tree opencv3 
homebrew/science/opencv3 (required dependencies)
└── :python3
├── cmake
│   └── sphinx-doc
├── pkg-config
├── jpeg
├── libpng
│   └── xz
├── libtiff
│   └── jpeg
├── eigen
│   └── cmake
│       └── sphinx-doc
├── openexr
│   ├── pkg-config
│   └── ilmbase
└── homebrew/python/numpy
    ├── :python3
    └── :gcc

なるほど、ツリー形式でみると分かりやすい

bundlerを使い始めた時に詰まったので調べた。

bundle 最初に知ること

bundler で出来ることを最初に知ることが必要

bunder はプロジェクトで使ってるgem を一覧するためのもの。

bundler は 必要なgem をインストールしてくれる

bundler は、自作ライブラリのgem化が出来る

bundler は、プロジェクトに必要なGemを「プロジェクト毎」にインストール出来る

bundler は、共有gem とプロジェクトで足りないものをインストール出来る。

つまり、bundler を使うことで、「必要なGem」の一覧を管理することが出来る。

このことにより、デプロイ先に開発元と同じgem環境を再現することができる

bundler 始め方

ディレクトリにGemFileを作成する。

もしくは、コマンドラインで bundle init とする

基本的な流れやで

sudo apt install ruby-bundler
mkdir プロジェクト
cd プロジェクト
bundle init 
bundle config set --local path 'vendor/bundle'
echo gem "nokogiri" >> GemFile
bundle install 

なにか追加したいときは、マニュアルで編集するか

vim GemFile
bundle install

または、bundle add する

bundle add sqlite3

プロジェクトの中にインストールする場合(2023-08-10追記)

bundle コマンド導入後なら、次をコピペすれば、プロジェクトごとに分離したbundler 環境を作れる。

mkdir my-project
cd my-project

bundle init
bundle config set --local path 'vendor/bundle'
bundle config set --local disable_shared_gems true
bundle add sqlite3

プロジェクト内部でruby を実行するとき

bundle 経由で実行する

bundle exec ruby sample.rb

sample.rb ではrequire するだけでいい。

# in sample.rb 
require 'sqlite3'

つぎに GemFile の書きかた。その0。

はじめに、source を書く。

source "https://rubygems.org"

これにより、gemをどこから探すか指定することが出来る。

自作レポジトリも指定できる。

source "https://rubygems.org"
source "https://takuya.example.org"

作成方法はgem generate_indexなどでググれば出てくる。

 GemFile の書きかた1

GemFileには、必要なGemを書いていく。

gem "nokogiri"
gem "pry"
gem "sequel"

GemFile の書き方2

必要なgem ファイルは、グループ分けすることが出来る

gem "nokogiri"
group :development do 
     gem "pry"
group :test do 
 gem "shoulda"
end

グループ分けしておくと、便利なことがある。

  1. デプロイ先で無駄なインストールしなくて便利だ
  2. bundle.require でグループ毎にreuqire 出来て便利。

GemFile の書き方3

バージョンを指定することが出来る

gem "nokogiri", ">= 1.4.2"

バージョン指定の方法は ruby require や gem install で用いられるものと同じだと思えばイイ。

bundler が使うファイル。

  • GemFile  使う(依存する)gemの一覧
  • GemFile.lock (実際に使ってる)gemとそのバージョン一覧

おもに GemFile が使われる。

GemFile.lockがBundlerで実際にインストールされたバージョンの一覧。

lock ファイルの記述を優先してインストールすることになる

lockファイルの扱い

gem file lock 記述を優先してインストールを再現される。が、、困った現象が起きた経験がある。

Bundlerが windows バイナリをOSXに入れようとしてて驚愕。OSXCygwinのバイナリ入れたら動かんだろう?でもインストールしてた。それがlockファイル。

Windowsバイナリでトラブルったのでgemfile.lock は細かく管理したい時に用途を限ることにした。バージョンやバイナリを詳細設定するときに限る。

Windows(開発)→Linux(デプロイ)のときは、全く役に立たないし、lockは消して構わない。gemfile.lock があるせいで、lockファイルはゴミ

bundler を使ったrequie 

bundle install のやり方が分かったら、次に bundler を使ったrequire を覚えておく

require 'bundler'
Bundler.setup
require 'nokogiri'

はい、これでOK

Gem を何処に入れるのか

bundler が良く分からない理由はコレだと思う。

  1. bundler にgem 環境を プロジェクト毎に作らせる
  2. bundler にシステム環境へgemをインストールさせる。

この2パターンがあってですね。システム環境やユーザー環境のGEM_HOMEかプロジェクト環境を選ぶことが出来るわけ。

個人で使う分には、プロジェクト環境よりシステム環境やユーザー環境利用が幾分に楽。

disable shared gems = 1

共有のgem をdisabledにして、プロジェクト内にgem 環境をゼロから作る。

bundle install vendor/bundle --disable-shared-gems

この場合、システム環境のgemは全て無視される

または、.bundle/config にかく

echo  BUNDLE_DISABLE_SHARED_GEMS: '1' >> .bundle/config

これで、bundleはプロジェクト環境に全てのgemをインストールする。

  BUNDLE_DISABLE_SHARED_GEMSの功罪

bundle が良く分からない現代魔法になってるのは、shared_gems にあるとおもう。

 BUNDLE_DISABLE_SHARED_GEMS: '1'

システム環境のgemを使いたい時は、 BUNDLE_DISABLE_SHARED_GEMS: '1'を消す

一年くらい使っててbundle でプロジェクト毎にパッケージをインストールするのは無駄と思うようになった。

pry とか mysql2 とかいくつもインストールしてんだわ。

システムの libxml 環境変わったのに古いbundleがlib指してて反って面倒だったり。システム全体のgem 使って欲しい場面のほうが多かった。 とくに開発環境だと時間の無駄が多いので必要ない気がする。

デプロイ先なら  BUNDLE_DISABLE_SHARED_GEMS: '1' をした方がいいかも。

つまり、BUNDLE_DISABLE_SHARED_GEMSがあると同じgemをいくつもインストールするので、ちょっとイラッとする。

bundleの手軽さが死ぬきがする。bundleのよさは git clone ; bundle install ; ですぐ使えることだと思うんだ。

bundle の設定

bundle/config の上書き関係

たとえば、BUNDLE_DISABLE_SHARED_GEMSの設定は次の箇所で指定される。

~/.bundle/config
PROJECT/.bundle/config
bundle install --disable-shared-gems

の順番で、ユーザ → プロジェクト → コマンド実行時になる。

 bundle install は何処に入るのか

  1. bunele install は なにも設定をしなければ system のgem が使われる
  2. bundle install はなにも設定ををしなければ system の gem にインストールされる
  3. bundle install は gem listall の自動化になる。

ただし、BUNDLE_PATHが環境変数にあったり、disable-shared-gemsが指定されていればこの限りではない。

なので、油断してるとシステム環境にインストールされちゃったり、プロジェクト環境にインストールされちゃうので注意が必要

私の場合、rbenv 環境にgem がインストールされないと思って悩んでいたら

ユーザー環境にデフォルト設定が会った。 ~/.bundle/config に disable-shared-gemsが設定されていた。はぁ。。。

bundle list で bundleされた一覧を見る

rbenv やrubygems が管理してるgemに任せるのが楽だった。

takuya@~$ bundle config
Settings are listed in order of priority. The top value will be used.
bundle install

個人環境なら vendor/bundle 使うとかえって面倒かもね。 使わなくなったら

gem uninstall hogehoge
gem cleanup 

で消しちゃってもいいしrbenv環境ごとポイッ

個人のrbenv環境で使うなら、何も設定せずにbundle install 叩いてたほうが圧倒的に楽だと思った

同じファイルをいくつもシステムに持つのダルいしコンパイルオプション考えるの面倒だしさ 自分のプロジェクトってだいたい同じようなgem使ってるじゃん?大きく違うバージョンや環境でもない限り vendor  使う必要ないと思った。

gem のソースを追いかけるために、locate や mdfind して同じファイルが大量に来るのも気持ち悪い・・・

強制的にsystem に入れる方法

bundle install --system 

ただ、既存のlock やconfigがあるとうまく動かない

vendor/bundle を使う方法

bundle install vendor/bundle --disable-shared-gems

これは、shared-gem(さっき言及した、システム全体gem)を拒否して、vendor/bundle にゼロからgem 空間を構築する 必要なgems の全てがvendor/bundleに入ります。

path / disable-shared-gems はワンセットになってるので消しちゃうとちょっと面倒なことに

手元の環境で、vendor/bundle 使うと、ここが不便でいや何だけど。

bundle の設定

現在のbundler の設定は bundle config で確認できる

$ bundle config
Settings are listed in order of priority. The top value will be used.

bundle の設定は、プロジェクトとHOME_PATHの2つをマージして使う

~/.bundle/config
PROJECT_HOME/.bundle/config

の2つのymlをマージすることになる。

たとえば、bundle install nokogiriにビルドオプションを与えたい時

bundle config --global  build.nokogiri -- \
 --with-xml2-dir=`brew --prefix libxml2`\
 --with-xslt-dir=`brew --prefix libxslt`

とする。

全てのbundle install nokogiri に設定したいときは ~/.bundle/config に書く。

> cat  ~/.bundle/config
---
BUNDLE_BUILD__NOKOGIRI: "--with-xml2-dir=/usr/local/opt/libxml2 --with-xslt-dir=/usr/local/opt/libxslt"

*1

.bundle/config の設定項目

設定項目には次のようなものがある。

  • BUNDLE_PATH
  • BUNDLE_FROZEN
  • BUNDLE_WITHOUT
  • BUNDLE_BIN
  • BUNDLE_GEMFILE
  • BUNDLE_SSL_CA_CERT
  • BUNDLE_SSL_CLIENT_CERT
  • BUNDLE_CACHE_PATH
  • BUNDLE_DISABLE_MULTISOURCE
  • BUNDLE_IGNORE_MESSAGES

設定は、同名の環境変数でも上書きされる。 環境変数のほうが楽かも?

環境変数を使う場合

BUNDLE_BIN="vendor/bundle/bin" bundle install 

また、config を指定する時だけ、次のような読み替えが許されるっぽい

BUNDLE_PATH => path
BUNDLE_BIN => bin

設定ファイルとコマンドオプションは同じ設定項目を意味する。

BUNDLE_BIN: "./bin"
bundle config --global bin "./bin"

デプロイ

bundle が真価を発揮するのはここ。

bundle install --deployment

このコマンドで、GemFile.lock で指定されている必要なパッケージを取ってくる  GemFile はユーザー指定 Gemfile.lock は bundle が調べて必要だと判別した全て。

ちなみに、そういうのはネットから取ってこれない場合のために

gem package 

すると vendor/cache に貯めておいてくれるので git vendor/cache でもしとけばいいけど、、OS超えてまでまず動かないと思うしやらないと思う。

bundle install --deployment --path=vendor/bundle

で環境の再現ということで。

vendor/bundle に入れた場合

bundle exec nokogiri
bundle exec 

手元の環境で、vendor/bundle 使うと、ここが不便でいや何だけど。

その他の話題

bundle コマンドを補完したい

brew install ruby-completion
brew install bundler-completion

などと、補完もいっぱいある

2023-08-10

更新。

参考資料

http://bundler.io/v0.9/bundle_install.html

https://gist.github.com/kozy4324/5719555

http://stackoverflow.com/questions/8104370/what-does-it-mean-bundle-disable-shared-gems-1

http://xxxcaqui.hatenablog.com/entry/2013/02/11/013421

http://ruby.studio-kingdom.com/bundler/gemfile

*1:HOME_PATH を --global というのはセンスが無いと思った --user にして欲しい --global は etcを期待してしまうハマった

ruby で[] のブラケットが入った文字列を扱うととてもめんどくさい。

面倒くさいんですよ。

ファイル名に [] ブラケットが混ざるととても扱いが面倒くさい。

以下の様なファイル構造があるとする。

takuya@~/Desktop$ tree '[資料]授業資料'
[資料]授業資料
└── a
    └── b

たとえば、globする場合

>> Dir.glob '[資料]授業資料/*'
=> []

glob の マッチの文法に、[set] が含まれるので、どうしようもない。

たとえば、exec するばあい

takuya@~/Desktop$ irb
>>
>> cmd = "ls '[資料]授業資料' '[資料]授業資料-01' "
ls: cannot access '[資料]授業資料-01': No such file or directory>> cmd
=> "'mv [資料]授業資料' '[資料]授業資料-01' "
>> exec cmd
sh: [資料]授業資料: command not found

mv だけダメなんですよ。

ls なら出来る。

>> cmd = "ls -l '[資料]授業資料' "
=> "ls -l '[資料]授業資料' "
>> exec cmd
total 0
drwxr-xr-x 3 takuya staff 102  8  9 00:15 a

shellwords でエスケープするともうメチャクチャ

utf-8 の日本語全てがエスケープされちゃいましたよ。もうどうしろというのか

>> cmd = 'mv ' + Shellwords.escape('[資料]授業資料') + '  ' + Shellwords.escape('[資料]授業資料-01')
=> "mv \\[\\資\\料\\]\\授\\業\\資\\料  \\[\\資\\料\\]\\授\\業\\資\\料-01"
>> print cmd
mv \[\資\料\]\授\業\資\料  \[\資\料\]\授\業\資\料-01=> nil

結論:逐次置換しかかない

Stackoverflowとかも一応見てみたけれど、逐次置換するしか無いっぽいぞ。

Rubyのこのあたりの文字コードと、文字列の扱いは本当にひどいと思う。

このように、ファイルに含まれるglob文字列を展開する必要がありそうだ

file_name.gsub( %r'[\{\}\[\]\*\?\\]' ) {|c| '\\'+c }

あーめんどくさい

OSXのiCloud のアカウント設定を消去する

iCloud アカウントが連日ロックされています。

なぜか、私だって知りたい。私のicloud アカウントが毎朝ロックされています。

もう、面倒なので、メインのメールアドレスを変更してアカウントをしばらくちょっと違う状態にした。

しかし、メールアドレス変更後のOSXiCloud ログインで詰まる。メッチャ詰まる。

システム環境設定でicloud 設定をしても詰まる。メールアドレス変更後の iCloud アカウント設定オカシイ。

ずっとフリーズして、システム環境設定が応答なしになる。参った。

待ってられないので、設定まるまる削除する

icloud 関係の設定で関係がありそうな、ファイルを消して、エラーにしてしまえば、初期設定されるだろう。と予測。

それで、~/Library/ を探してたら mobileme 関連の plist があってソコにAppleIDが書いてあった。

~/Library/Preferences/MobileMeAccounts.plist

とりあえず、消せば、何かしらエラー初期化されるだろうと思って消したらビンゴ。

ちょっと適当な解決策だけど、目的を達成するには十分だった。

iCloud アカウント設定は、iPhone(Mac)を探すや、Keychainsが絡むので、アカウント変更は、思いつきでやっっちゃうと痛い目を見ることを学んだ。

SlideShareのスライド画像をまるっと保存してオフラインで見る。

slideshare 最近厳しい

slideshare がlinkedin になってから色々と厳しかったり、PDFをちょとお電波の届かないところで参照資料に出そうと思っても、不便すぎる

世の中100%オンラインと限らないんで。。。

表示しているJPGを手作業でキャッシュする

自作のブラウザで、JPG画像をキャッシュしてPDFに焼き直す

#!/usr/bin/env ruby 
#

require 'prawn'
require 'mechanize'
require 'open-uri'

m = Mechanize.new
m.get ARGV.shift

list =  m.page.search('//img[@class="slide_image"]/@data-full').map{|e| e.text() }


Prawn::Document.generate(( m.page.title.to_s+ ".pdf") ,:page_layout => :landscape, :page_size=>"A4") do 
  list.each{|image_url|
    image( open(image_url), :fit=>[800, 450] ) #フィットサイズはあとで考えたほうが。。。。
  }

end

prawn つかうと多少画像サイズが合わないので、サイズの微調整が面倒ですね。16:9スライドや4:3スライドを判別しないといけない。

面倒なときは、まるっとキャッシュしして、convert コマンドやpdftkにかけちゃったほうがいいかもね。

参考資料

http://takuya-1st.hatenablog.jp/entry/2015/01/18/223308

http://mechanize.rubyforge.org/Mechanize/Download.html

http://prawnpdf.org/docs/0.11.1/Prawn/Images.html

https://github.com/chou3ib1/slideshare-download-disabled-pdf

自作ブラウザとかキャッシュとか、そういう曖昧な表記は、規約云々が面倒だから、mechanize はブラウザ です!

ruby で mysql と sequel でぱぱっとアクセス

active record めんどくさいし

めんどうだし、遅いんですよ。SQLわかってれば、ActiveRecordってメッド生やすの面倒だし、オブジェクト作ったり手続きが面倒だったんで。

ruby で mysql2 を使ったアクセス

BestGem でダウンロード数を比較したらhttp://bestgems.org/search?q=mysql mysql2 がトリプルスコアで圧倒的だったので。これを使うことにした。

gem install mysql2

mysql2 の利用

使い方は、大変シンプル

  • client(connection)
  • Statement
  • Result

という王道の三本セット

require 'mysql2'

client = Mysql2::Client.new(host:"192.168.2.5", username:"takuya", password: "*********", database:"my_Db")
ret = client.query("select * from sample order by id desc limit 10 ");
ret.each{|row |
         p row
}
mysql2 で prepare ステートメント

mysql2公式に載ってた。

statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
result1 = statement.execute(1)
result2 = statement.execute(2)

名前付きbindをするのは、無理そう

トランザクション

自分で管理。

client.query("begin");
client.query("select * from sample order by id desc limit 10 ");
client.query("commit");

潔くていいし、低レベルレイヤなのでわかりやすいっすね。

sequel を使ってもう少しだけ抽象化

ruby のDBアクセスで、もう一つの定番はSequel

sequel はバックエンドにMysql2 を使える。いいね。

sequel 使うなら、ActiveRecord使えばいんだろうけどさ、rails 関連ってググラビリティの性能が悪いので、あまり好きじゃない。php 波にカオス。

gem install sequel

基本的な使いかた

require 'sequel'
require 'logger'


db = Sequel.connect('mysql2://takuya:**pass**@192.168.100.1/takuya_db',:loggers => [Logger.new($stdout)])
res =  db[:tablename]

res.each{|e|
 p e
}

ポイントは、 eachで回すまでクエリを発行しないところ。

sequel でトランザクション

トランザクションは、ブロックを渡す。これRubyっぽい。気に入った

db = Sequel.connect('mysql2://takuya:**pass**@192.168.100.1/takuya_db',:loggers => [Logger.new($stdout)])
db.transaction do 
  table =  db[:address]
  names.each{|e| 
    table.insert(e) 
  }
end

insert ・ update はハッシュ値で指定できて便利

データを突っ込むときは、ハッシュ値ベースで放り込めるので、オブジェクトあれば便利なんだろうけど、とりあえずファイルの値をつっこみたいとか、手作業でぱぱっと入れたいとかそういう時にすごく重宝するわこれ。

sequel で prepare

そのうち調べる。

ちょっと面倒なんだけどね。ハッシュのキーとバリューがあればできる。

参考資料

http://sequel.jeremyevans.net/

mac osx で無線LANをオンオフと指定SSIDに接続するコマンド

無線LANをオンオフできたら便利だよね。

便利だよね?絶対便利!

OSX標準の無線LANのON/OFFは手数が多い。

とくにWifiの構成とか考えて頻繁にオンオフ繰り返しているとすごく手間。

f:id:takuya_1st:20151227013852p:plain

ターミナルからWiFiをオフ

networksetup -setairportpower en0 off

ターミナルからWiFiをオン

networksetup -setairportpower en0 on

周囲のSSIDを探す

airport  -s 

airport の場所

airport コマンドは 結構深い場所にあるので、使いやすい位置に持ってきておく。

alias airport=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport

ちなみに airport コマンドで wifi ssid から切断することもできる

sudo airport -z  # 切断

airport 使った切断は、sudo いるし再接続が面倒なのでnetworksetup 使ったほうがいいと思った

接続先のチャンネルを変える

11n 11ac など同一SSID複数チャンネル、複数周波数で展開されてる場合、また基地局が近くで同一SSIDで両方が拾える時、指定したチャンネル側につなぐ。

airport -c 11
チャンネルと、電波強度を確認する
airport -s 
           SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
                  xxxxxxxxxxxxxx 00:12:00:fb:00:b3 -82  40      N  -- WPA2(PSK/AES/AES)
                  xxxxxxxxxxxxxx 00:12:00:fb:00:b2 -54  6       N  -- WPA2(PSK/AES/AES)
                  xxxxxxxxxxxxxx 00:6f:00:88:00:34 -87  1       Y  JP WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)
                  Buffalo-G-5E5F 00:e1:00:6b:00:60 -84  1       Y  JP WPA(PSK/TKIP,AES/TKIP) WPA2(PSK/TKIP,AES/TKIP)
                    xxxxxxxxxxxx 00:1d:00:b4:00:81 -54  11      Y  -- WPA2(PSK/AES/AES)

RSSI<90 のときは確実につながると思う。CHANNEL>100のときは5GHz だったかな。

接続中のSSIDを確認
airport -I | /usr/bin/grep -ie '^\s*ssid'  | cut -d ":" -f 2

指定のSSIDに接続したい

networksetup -setairportnetwork en0 0001softbank 
networksetup -setairportnetwork en0 graphic password(pre-sharekey )

などととすることで、結構簡単にSSIDを扱える。

参考資料

blog.mattcrampton.comxc d• Managing WIFI connections using the Mac OSX...

pdftk が動かなくなってたので入れなおし

pdftk が動かない・・・

pdfを扱うのに欠かせないpdftk が動かない 10.11 からの問題らしい

バイナリを取得して/opt/に入れてたのが動かなかった。なので brew から tap した

brew から tap はgcc/gcj とか一杯インストールしてしまうので、頭の良い解決方法でなさそう。 なによりコンパイルエラーで地獄見る

pdftk を入れる方法

ここに詳しく出ていた

http://stackoverflow.com/questions/32505951/pdftk-server-on-os-x-10-11

OSX 10.11 用にパッケージをリビルドされて提供してくれてる。

バイナリの取得先も書いてあったし、継続して情報を追いかけてくれてて感謝。

2017-01-13 追記

El Capitan でインストールすると、セキュリティエラーだった。。。

https://www.pdflabs.com/tools/pdftk-server/

cask / brew を使うと・・・

ビルド地獄になってとってもお勧めできなかった。

gccから作るんだもん・・・コンパイル済みパッケージがcask/brewで提供されるのはまだ先なんだろうな。

takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ pdftk 1.pdf 2.pdf cat output  out.pdf
^C
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ which pdftk
/usr/local/bin/pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew info pdftk
Error: No available formula with the name "pdftk"
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew search pdftk
No formula found for "pdftk".
==> Searching pull requests...
Closed pull requests:
pdftk: 2.02 - a Handy Tool for Manipulating PDF Documents (https://github.com/Homebrew/homebrew/pull/25953)
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ ls -l $(which pdftk
> )
lrwxr-xr-x 1 takuya admin 28 10 16  2013 /usr/local/bin/pdftk -> /opt/pdflabs/pdftk/bin/pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ open /opt/pdflabs/pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew unlink pdftk
Error: No such keg: /usr/local/Cellar/pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ cask search pdftk
No Cask found for "pdftk".
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ rm /usr/local/bin/pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ which pdftk
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew search pdftk
No formula found for "pdftk".
==> Searching pull requests...
Closed pull requests:
pdftk: 2.02 - a Handy Tool for Manipulating PDF Documents (https://github.com/Homebrew/homebrew/pull/25953)
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew tap https://github.com/Homebrew/homebrew/pull/25953
Error: Invalid tap name
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew tap docmunch/pdftk
==> Tapping docmunch/pdftk
Cloning into '/usr/local/Library/Taps/docmunch/homebrew-pdftk'...
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
Checking connectivity... done.
Tapped 1 formula (29 files, 120K)
takuya@/private/tmp/docomo2015-12-0120151201-56837-stvrb1$ brew install pdftk
==> Installing pdftk from docmunch/homebrew-pdftk
==> Installing dependencies for docmunch/pdftk/pdftk: ecj, gcc
==> Installing docmunch/pdftk/pdftk dependency: ecj
==> Downloading ftp://sourceware.org/pub/java/ecj-4.9.jar
######################################################################## 100.0%
🍺  /usr/local/Cellar/ecj/4.9: 2 files, 1.6M, built in 6 seconds
==> Installing docmunch/pdftk/pdftk dependency: gcc
==> Downloading http://ftpmirror.gnu.org/gcc/gcc-5.2.0/gcc-5.2.0.tar.bz2
Already downloaded: /Library/Caches/Homebrew/gcc-5.2.0.tar.bz2

EvernoteクリッパーでWebページを見るのが恐ろしく快適

evernote clipper 便利です。

あまりに便利だけど、人に言葉で説明するのが面倒なので、メモを残しておきます。

Evernote Clipper には、「簡易版の記事」があります。これがクッソ便利。

複数ページを自動で取得してくれる。

日経何某だとかのサイトでは、ページが無駄に分かれていて、この記事あとで参照しようとクリッピングしてもページ単位に分かれて不便なんですね。

それ、Evernoteクリッパーで!!

Evernoteクリッパーは「2ページ目」「3ページ目」を取得できます。

使い方は簡単:スクロールするだけ

複数のページに分割されたWEBページを「簡易版の記事」で表示して、スクロール&スクロール。

すると、残りのページが自動的に読み込まれて読みやすく「1枚のノート」にまとまってくれる。

f:id:takuya_1st:20151225021145p:plain

保存する前にSpace連打

保存する前にスペース連打してページダウンをする。

スクロールすると「次のページ」をロード

最終ページに到達するまでスペースキー連打しておけばよろしい。

ちょっと困るのは、自動で次ページロードをしないところ。

時々、忘れるので困ります・・

これで、気になった記事を帰りの通勤電車で読めますね。

勤務中に気になった記事を読んでると作業時間がなくなるんので助かります。

まぁもとはClearlyだろうし、当たり前と言えば当たり前ですけど。

はてなブックマークがこの機能提供すると最強だったよねぇ。(遠い目

参考

https://evernote.com/clearly/

https://evernote.com/intl/jp/webclipper/

IMAP経由やラベル一覧でGmailでラベルが見えない(SPAM/Draftとか)

API 経由でGmailにアクセスしたんですよ。

Gmailのアクセスを調べてて、試しに、SPAMをまとめて削除しようと思ってたらSPAMラベルが見えない

iphoneAndroid からGmailにアクセスしたら、フォルダやラベルが見えない。

Gmailはラベル一覧とIMAPへのエクスポートと、アクセス方法に応じて設定が異なる。

ラベル一覧は可視・不可視設定がある。

Gmailのラベルは可視・不可視が選べるので、むかしむかしに設定した不可視に邪魔されることがある

f:id:takuya_1st:20151225015704p:plain

というわけで。

Gmailでラベルが見えないときは設定を疑えということでした。

bash のシェルスクリプト(関数)でオプション引数を扱う getopts 使い方サンプル

シェルスクリプトで引数オプションを使いたい

my_shell_script -a /usr/bin

みたいに、bashシェルスクリプトでも引数を扱いたい。

getopts を使えば引数が取れる

bash では getopts を使えば、引数の処理を簡単に行うことができて便利。ruby などでは optparseに相当するやつです。

はじめに getopt / getopts の違いについて

全ての初めに。

getoptsについて読む前に知っておかなくちゃいけないことがある。

getopts コマンドとシェルのビルトインの二種類がある。

名前 種類
getopts シェル組み込み
getopt コマンド・ファイル

Google検索はgetopt/getopts を区別しないで結果を出すので注意が必要でした。

今回、調べたのは getopts です。

getopt は/usr/bin にあるコマンドです。

/usr/bin/getopt は、BSDOSX)とGNUlinux )で挙動が異なるため、OSXLinuxでどちらでも使えるようにするため、gnu bash の組み込み関数を使うことにしました。

getopts はシェル組み込み関数です。

今回扱うのは、getoptsシェル組み込み関数です。

getopts の基本的な使い方

getopts の基本的な使い方 は次の通りです。

getopts "引数名" 変数名
使用例

使い方は簡単です。

getopts "a" opts

引数に -a を指定したら opts 変数に中身(a)が入る

複数オプションを入れる

複数書きたいときは、連続してアルファベットを続ける

getopts "abc" opts

オプションで使いたいアルファベットを複数続けて書くだけ。楽チン。

実際に使って試してみる。

適当に関数を作ってgetopts を使ってみます。

function my_func(){
  echo 引数=$1
  getopts "adh" opts
  echo getopts結果=$opts
}

my_func -a
実行結果
引数=-a
getopts結果=a
未知の引数の場合
my_func -b
実行結果
引数=-a
/Users/takuya/Desktop/test.sh: illegal option -- b
getopts結果=?

何も書かなくても未指定の引数にはエラーを出してくれる。便利!

シェルの言語がja_JPであれば

takuya@~$ my_func -x
-bash: 不正なオプションです -- x

エラーメッセージをローカライズして表示してくれる。いいね

エラー処理を自分でやる?

組み込みのエラー処理はいらないと思う場合、

illegal option –を無視するには

先頭にセミコロンを置く
getopts ":adh" opts

こうすると、エラーを自分でハンドリングできる。

複数オプション の例

先ほどの関数に複数オプションをつけてみると。。。

my_func -a -d
引数=-a -d
getopts結果=a

複数オプションは考慮されない。 (後述するが、複数回getoptsを呼び出すことで処理できる。)

オプションを指定しない場合

getopts を設定した関数へ、なにもオプションを指定せずに起動すると・・・

my_func
引数=
getopts結果=?

結果は ? になる。

そのため、"?“ を判定してヘルプを表示するようスクリプトを記述する。

”?”(未知=ヘルプ)などと覚えておけばいいでしょう。

-a オプションではなく、ただの引数を入れる

ハイフン付きのオプションでななく、よくある引数を入れてみるとどうなるか。

my_func aaaaaaaaa
引数=aaaaaaaaa
getopts結果=?

引数がない時と同じになる。

オプション引数を扱う。

オプション付き引数を入れる。つまり、オプションで引数を入れてみる。

my_func -a my_value

このように、設定値付きのオプションを使う、オプション引数を使う。

“a:” 文字+”:”でオプション引数

オプションに引数をつけるには、getopts で「:」を追加する

引数が一つのとき
getopts "a:" OPT
引数が二つのとき
getopts "a:b:c:" OPT
引数が三つのとき
getopts "a:b:c:" OPT
オプション付き引数を処理しない場合

オプション付き引数を処理しない場合は連続して文字を続けるだけ

getopts "abcdefg" OPT

オプション引数のサンプル

シェルスクリプトは次のように記述した $OPTARG にオプション引数が入る点が違う。

function my_func(){

  echo 引数=$@
  getopts ":a:" opts
  echo getopts結果=$opts
  echo $OPTARG

}
my_func -a aaaaaaaaa

実行結果は次の通り

引数=-a aaaaaaaaa
getopts結果=a
aaaaaaaaa

ポイントは、$OPTARG にオプションの引数が入る

複数オプションを使う

ここまでで、基本的な使い方がわかったので、実際にありそうなオプションを取り扱ってみたいと思う。

そのままでは複数オプションを扱えないので、複数回 getopts を使う。

複数回の getopts 呼び出し

先ほど、複数個のオプションを処理できないと書きましたが、getoptsを複数回呼び出せば、複数個のオプションを処理できます。

function my_func(){

  echo args=$@
  getopts ":a:b:" OPT
  echo $OPT
  echo $OPTARG

  getopts ":a:b:" OPT
  echo $OPT
  echo $OPTARG

}
my_func -a aaaaaaaaa -b bbbbbbbbbbbbb

このようにgetoptsを何回も処理したら

実行結果が次のようになる。

args=-a aaaaaaaaa -b bbbbbbbbbbbbb
a
aaaaaaaaa
b
bbbbbbbbbbbbb

ここでのポイントは。複数回getoptsを適用すれば、複数個のオプションに対応できる。という点

複数オプションをループで処理する

ここまできて、漸くネットで見かけるサンプルに近くなる。

function my_func(){

  echo args=$@

  while getopts ":a:b:" OPT ; do

    echo $OPT
    echo $OPTARG

  done

}
my_func -a aaaaaaaaa -b bbbbbbbbbbbbb

複数オプションを取得するには、なくなるまでwhileループを回すのが基本

実行結果
args=-a aaaaaaaaa -b bbbbbbbbbbbbb
a
aaaaaaaaa
b
bbbbbbbbbbbbb

while で処理するときは caseとともに使う。

function my_func(){

  echo args=$@

  while getopts ":a:b:" OPT ; do
    case $OPT
      a)  echo $OPT
           echo $OPTARG
           ;;
      b)  echo $OPT
           echo $OPTARG
           ;;
     esac
  done

}
my_func -a aaaaaaaaa -b bbbbbbbbbbbbb

これで、getopts を使える。

getopts と while + case を組み合わせて戦うことで、シェルスクリプトでもオプションと引数つきオプションを扱えることがわかった。

ただし、whileループで処理した場合引数なしには対応できない

while ループを記述したコマンドを オプションなしで起動すると・・・

my_func aaa
args=aaa
(getopts のwhile ループでは処理されない

引数が指定されてない時に注意が必要

ナニも引数が指定されない場合は、getoptsはシゴトをするが、exit(1) するのでwhile と相性が悪い

while に入れた時には、結果は空っぽになる。

“?” はどこいった?

ただし、"?“ はきちんと処理されている。 while が処理終了になるので、while 中の case に処理がこないだけ。

function my_func(){

  echo args=$@

  getopts ":a:b:" OPT
  echo $?
  echo opt=$OPT
}
my_func -a hoge
my_func
結果
args=-a hoge
0
opt=a
args=
1
opt=?

OPTには ? が入るが、コマンドの実行結果ステータスが 1 になるので whileから抜けてしまう。

なので、while getopt でオプションが全く指定されない場合の ?をwhile中で検出することが出来ない。

ここまでのまとめ

ここまでの実験でわかったことをまとめた。

  • getoptsはオプション・引数付きオプションを処理することができる。
  • getoptsは複数回起動すると複数のオプションを処理できる
  • getoptsは while と case 句を組み合わせて処理をする。
function my_func(){

  echo args=$@

  while getopts ":a:b:" OPT ; do

    case $OPT in
      a)
        echo -a の引数 $OPTARG
        ;;
      b)
        echo -b の引数 $OPTARG
        ;;
      : )
        echo "ここ"
        ;;
      \? )
        echo nothing matched
        ;;
    esac

  done

}
my_func  -a aaa
my_func
my_func -c ccc

while とともに使った場合

検出ができるのは、「不正なオプション」を渡した時に限られる、「オプションが全く未指定」は検出ができない。別途考えないとダメなようだ

注意: getoptsをfunction内で利用す場合

getopts 複数回よびだせる、そのときにどこまで処理したかを保存する。

どこまで処理したかは、変数 $OPTIND(オプションインデックス)に保存する。

そのため、getopts は OPTINDを使うので、function で使うときは、OPTIND をグローバル汚染させない注意が必要

function path() {

 local OPTIND OPTARG OPT ## ここ重要

  while getopts 'ha:d:' OPT ; do
    case $OPT in
      d)
        echo "-D entered"
        ;;
      a)
        echo "-A entered"
        ;;
      \?)
        ;;
    esac
  done
}

local OPTIND を書かないと、グローバル変数に値が入っちゃうので、getopts が含まれる関数を何度も呼び出せない。

local 宣言があるとき

function 内に local 宣言をちゃんと書いた場合・・・

function path() {

 local OPTIND OPTARG OPT

  while getopts 'ha:d:' OPT ; do
    case $OPT in
      a)
        echo "-A entered"
        ;;
    esac
  done
  echo end
}
### ここで関数の実行
path -a aaa
path -a aaa
path -a aaa

実行と結果

-A entered
end
-A entered
end
-A entered
end

local 宣言がないとき。

function path() {
# local 宣言をコメントアウト
#local OPTIND OPTARG OPT 

  while getopts 'ha:d:' OPT ; do
    case $OPT in
      a)
        echo "-A entered"
        ;;
    esac
  done
  echo end
}
path -a aaa
path -a aaa
path -a aaa

実行結果

-A entered
end
end
end

このようにlocal宣言がないと変数$OPTIND が作用して、オプションを取れなくなる。

1つのファイルでシェルスクリプトを記述するのなら問題ないのだけれど、関数を作って連続して使うなら変数を共有しない工夫が必要

getoptsをファイルで使う場合

getoptsをファイルで使う場合は、環境変数をexport しない限りファイル内部で完結するので、管理は難しくない。

my_script.sh
#!/usr/bin/env bash
  while getopts 'ha:d:' OPT ; do
    case $OPT in
      a)
        echo "-A entered"
        ;;
    esac
  done
  echo end

ファイルに記述した場合

my_script.sh -a aaaa
my_script.sh -a aaaa
my_script.sh -a aaaa

としてもOPTINDはファイルごとに確保されるため全然影響がなく、問題ない。

getopts まとめ

  • getopts はシェル組み込み関数(builtinコマンド)
  • getopts “abc” とかけば -a -b -c とオプションを作れる
  • 複数個のオプションを一度に処理するには getoptsを複数回呼び出し
  • 複数個のオプションを処理するには while + case を使う
  • オプション引数を使うには getopts “a:b:c"とする
  • エラー処理を自分でやるには getopts “:a” と先頭に「 : 」をつける
  • 関数内で getopts を使うときは local OPT をつける

参考資料

http://stackoverflow.com/questions/16654607/using-getopts-inside-a-bash-function

au-Wifi の提供がスマホに限定される?

au Wi-Fi SPOTマルチデバイスサービス」がリニューアル してた

ご利用方法と対象機種の変更に伴い、これまで提供してきた専用アプリ(au Wi-Fi接続ツール)では2016年2月1日よりマルチデバイスサービスをご利用いただけなくなります。

え、ちょっとまてよ。いまで、PCから無料で使えたのが使えなくなるってことですかね。

PCから au-Wifi つながらない阿鼻叫喚が待ってる。

ちょっとまだ追いきれてないんだけど

www.au.kddi.com

いままでは無料でWiFi接続ツールで使えるようにしたけど、これからはWi2を使ってくれヨロシクってことですね。

影響のある料金プラン

これらのプランでは、引き続き無料(ただし新規加入・変更は出来ない) - LTEフラット - LTEフラット(V)

通常はこれからは月額300円のプランが標準になる。

  • データ定額2/3/5/8/10/13
  • データ定額2(V)/3(V)/5(V)/8(V)/10(V)/13(V)
  • データ定額2(VK)/3(VK)/5(VK)/8(VK)/10(VK)/13(VK)
  • LTEフラット cp(f・2GB)
  • LTEフラット cp(1GB)
  • ジュニアスマートフォンプラン
  • シニアプラン
  • シニアプラン(V)

www.au.kddi.com

ということです。

影響のあるSSID

これからのプランでは次のSSIDが有料になる。

  • Wi2
  • Wi2_club
  • Wi2_free
  • wifi_square
  • Wi2premium
  • Wi2premium_club
  • UQ_Wi-Fi

ご利用条件|公衆無線LANサービスWi2 300

今まで使えたSSID

au_Wi-Fi」(WPA2)、「au_Wi-Fi2」(WPA2エンタープライズ)、「Wi2premium_club」(WPA2)、「Wi2_club」(WPA2)、「UQ_Wi-Fi」(WEP)、「Wi2premium」(暗号化なし)、「Wi2」(暗号化なし)、「wifi_square」(暗号化なし)

つまり、iOS/Android以外をau-WiFiから追い出すってことですね。

au_Wif2 がEAP-SIMだから、au-Wifiは消えていくんでしょうか。

まぁ速く言えば

いままでPC向けもau-wifi で提供したけど、スマホ以外は、wi2に丸投げするからよろしく。ってことですね。

これからはPCなどでWifi使いたきゃ300円(税抜)払え、Wi2よりは50円ほど安いぞってことですね。

au は良心的?

猶予期間を1年位あけてるのと、残存旧プランへの救済措置を作ってるのは、やっぱりau は良心的なキャリアだなぁと思うわけです。

こうやって徐々に値上げされていくんですね。

WiMAX1まきとりで、使えないau_WiFiを巻き取りつつ、インフラ更新をwi2に丸投げして、自社はau_WiFi2でSIM認証でガードかけていくのかな

5G見据えたらwifiはイラないってことなんでしょうねぇ。